skins/AknSkins/src/AknsUtilsAppIcon.cpp
changeset 0 05e9090e2422
child 2 abcbdabaa4c5
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Extension to AknsUtils.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "AknsCppPreface.h"
       
    21 
       
    22 #include <apgcli.h>
       
    23 #include <AknIconUtils.h>
       
    24 
       
    25 #include <avkon.mbg>
       
    26 
       
    27 #include <AknsUtils.h>
       
    28 #include "AknsJavaUtils.h"
       
    29 
       
    30 #include <AknsItemData.h>
       
    31 #include "AknsAppSkinInstance.h"
       
    32 #include <AknsImageAttributeData.h>
       
    33 #include "AknsDebug.h"
       
    34 
       
    35 #include "AknInternalIconUtils.h"
       
    36 // ============================ MEMBER FUNCTIONS ===============================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // AknsUtils::CreateAppIconLC
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 AKNS_EXPORTED_METHOD(AknsUtils::CreateAppIconLC)
       
    43 EXPORT_C void AknsUtils::CreateAppIconLC(
       
    44     MAknsSkinInstance* aInstance, TUid aAppUid,
       
    45     TAknsAppIconType aType,
       
    46     CFbsBitmap*& aBitmap, CFbsBitmap*& aMask )
       
    47     {
       
    48     aBitmap = NULL;
       
    49     aMask = NULL;
       
    50 
       
    51     if (!aInstance)
       
    52         {
       
    53         User::Leave(KErrArgument);
       
    54         }
       
    55 
       
    56     TSize legacySize( 42, 29 );
       
    57     TInt bitmapIndex( 0 );
       
    58     TInt maskIndex( 1 );
       
    59     if( aType == EAknsAppIconTypeContext )
       
    60         {
       
    61         legacySize = TSize( 44, 44 );
       
    62         bitmapIndex = 2;
       
    63         maskIndex = 3;
       
    64         }
       
    65     else if( aType != EAknsAppIconTypeList )
       
    66         {
       
    67         User::Leave( KErrArgument );
       
    68         }
       
    69 
       
    70     // Make the forthcoming pushes safe (up to level 2)
       
    71     CleanupStack::PushL( static_cast<TAny*>(NULL) );
       
    72     CleanupStack::PushL( static_cast<TAny*>(NULL) );
       
    73     CleanupStack::Pop( 2 );
       
    74 
       
    75     // 1. Check if the icon has been configured.
       
    76     TInt ret = KErrNone;
       
    77     TBool configuredIcon = EFalse;
       
    78     //
       
    79     CAknsAppSkinInstance* apskin = static_cast<CAknsAppSkinInstance*>(aInstance);
       
    80     if ( apskin )
       
    81         {
       
    82         TInt config = apskin->IsIconConfiguredL( aAppUid );
       
    83         if ( config > 0 )
       
    84         configuredIcon = ETrue;
       
    85         }
       
    86 
       
    87     if ( !configuredIcon )
       
    88         {
       
    89         // 2. Skin-originating icon
       
    90         ret = GetAppIconFromSkin( aInstance, aAppUid, legacySize, aBitmap, aMask );
       
    91         if( ret == KErrNone )
       
    92             {
       
    93             // These pushes are safe
       
    94             CleanupStack::PushL( aBitmap ); // (1)
       
    95             CleanupStack::PushL( aMask ); // (2)
       
    96             return;
       
    97             }
       
    98         }
       
    99     // Cache connected apparc session for future reuse, if not already cached
       
   100     // This is done per appskininstance when necessary...
       
   101     if (!apskin->iCachedApaSession)
       
   102         {
       
   103         apskin->iCachedApaSession = new (ELeave) RApaLsSession;
       
   104         User::LeaveIfError(apskin->iCachedApaSession->Connect());
       
   105         }
       
   106 
       
   107     RApaLsSession* lsSession = apskin->iCachedApaSession;
       
   108 
       
   109     TBool forceDefaultIcon = EFalse;
       
   110 
       
   111     TApaAppInfo appInfo;
       
   112     TFileName filename;
       
   113     // 3. New appicon framework
       
   114     HBufC* filenameBuf = NULL;
       
   115     TBool javaIcon = EFalse;
       
   116     ret = lsSession->GetAppIcon( aAppUid, filenameBuf );
       
   117     if( filenameBuf )
       
   118         {
       
   119         filename.Copy( *filenameBuf );
       
   120         delete filenameBuf;
       
   121         }
       
   122     if( ret == KErrNone )
       
   123         {
       
   124         ret = lsSession->GetAppInfo( appInfo, aAppUid );
       
   125         }
       
   126     if( (ret==KErrNone) && (filename.Length()>2) &&
       
   127         (appInfo.iFullName.Length()>2) )
       
   128         {
       
   129         // Correct drive letter, if necessary
       
   130         if( appInfo.iFullName[1]==':' )
       
   131             {
       
   132             if( filename[1]==':' )
       
   133                 {
       
   134                 filename[0] = appInfo.iFullName[0];
       
   135                 }
       
   136             else if( filename[0]=='\\' )
       
   137                 {
       
   138                 filename.Insert( 0, appInfo.iFullName.Left(2) );
       
   139                 }
       
   140             }
       
   141 
       
   142         // check if the icon is java icon
       
   143         javaIcon = AknsJavaUtils::IsJavaIcon(filename);
       
   144 
       
   145         if( AknIconUtils::IsMifFile( filename ) )
       
   146             {
       
   147             // SVG icon
       
   148             // SVG always has only one icon
       
   149             bitmapIndex = 0;
       
   150             maskIndex = 1;
       
   151             AknIconUtils::ValidateLogicalAppIconId( filename,
       
   152                 bitmapIndex, maskIndex );
       
   153 
       
   154             if (javaIcon)
       
   155                 {
       
   156                 AknsJavaUtils::CreateIconLC(*lsSession, aAppUid, aBitmap,
       
   157                     aMask, bitmapIndex, maskIndex ); // aBitmap, aMask (2)
       
   158                 }
       
   159             else
       
   160                 {
       
   161                 AknIconUtils::CreateIconLC( aBitmap, aMask, filename,
       
   162                     bitmapIndex, maskIndex ); // aBitmap, aMask (2)
       
   163                 }
       
   164             AknInternalIconUtils::SetAppIcon(aBitmap); //icon case
       
   165             return;
       
   166             }
       
   167         else
       
   168             {
       
   169             // MBM icon
       
   170             AknIconUtils::ValidateLogicalAppIconId( filename,
       
   171                 bitmapIndex, maskIndex );
       
   172             TRAP( ret, AknIconUtils::CreateIconL( aBitmap, aMask, filename,
       
   173                 bitmapIndex, maskIndex ) );
       
   174             if( ret == KErrNone )
       
   175                 {
       
   176                 // These pushes are safe
       
   177                 CleanupStack::PushL( aBitmap ); // (1)
       
   178                 CleanupStack::PushL( aMask ); // (2)
       
   179                 }
       
   180             else
       
   181                 {
       
   182                 bitmapIndex = 0;
       
   183                 maskIndex = 1;
       
   184                 AknIconUtils::ValidateLogicalAppIconId( filename,
       
   185                     bitmapIndex, maskIndex );
       
   186                 AknIconUtils::CreateIconLC( aBitmap, aMask, filename,
       
   187                     bitmapIndex, maskIndex ); // aBitmap, aMask (2)
       
   188                 }
       
   189             AknInternalIconUtils::SetAppIcon(aBitmap); //icon case
       
   190             return;
       
   191             }
       
   192         }
       
   193     else if( ret!=KErrNotSupported )
       
   194         {
       
   195         // New framework, but no icon defined
       
   196         forceDefaultIcon = ETrue;
       
   197         }
       
   198 
       
   199     CApaMaskedBitmap* apaBmp = CApaMaskedBitmap::NewLC(); // apaBmp (1)
       
   200     // 3. Old (AIF-based) framework
       
   201     if( !forceDefaultIcon )
       
   202         {
       
   203         TInt apaErr = lsSession->GetAppIcon( aAppUid, legacySize, *apaBmp );
       
   204         // Use default icon if APPARC did not initialize icon bitmaps
       
   205         if( apaErr || (!apaBmp) || (!apaBmp->Mask()) ||
       
   206             (!apaBmp->Handle()) || (!apaBmp->Mask()->Handle()) )
       
   207             {
       
   208             forceDefaultIcon = ETrue;
       
   209             }
       
   210         }
       
   211 
       
   212     if( forceDefaultIcon )
       
   213         {
       
   214         // Default icon
       
   215         CleanupStack::PopAndDestroy( 1 ); // apaBmp (0)
       
   216         TAknsItemID iid = KAknsIIDQgnMenuUnknownLst;
       
   217         bitmapIndex = EMbmAvkonQgn_menu_unknown_lst;
       
   218         maskIndex = EMbmAvkonQgn_menu_unknown_lst_mask;
       
   219         if( aType == EAknsAppIconTypeContext )
       
   220             {
       
   221             iid = KAknsIIDQgnMenuUnknownCxt;
       
   222             bitmapIndex = EMbmAvkonQgn_menu_unknown_cxt;
       
   223             maskIndex = EMbmAvkonQgn_menu_unknown_cxt_mask;
       
   224             }
       
   225         AknsUtils::CreateIconLC( aInstance, iid, aBitmap, aMask,
       
   226             AknIconUtils::AvkonIconFileName(), bitmapIndex, maskIndex ); // aBitmap, aMask (2)
       
   227         }
       
   228     else
       
   229         {
       
   230         // AIF-based icon
       
   231         CFbsBitmap* iconOwnedBitmap = new (ELeave) CFbsBitmap();
       
   232         CleanupStack::PushL( iconOwnedBitmap ); // iob (3)
       
   233         CFbsBitmap* iconOwnedMask = new (ELeave) CFbsBitmap();
       
   234         CleanupStack::PushL( iconOwnedMask ); // iom (4)
       
   235         User::LeaveIfError(
       
   236             iconOwnedBitmap->Duplicate( apaBmp->Handle() ) );
       
   237         User::LeaveIfError(
       
   238             iconOwnedMask->Duplicate( apaBmp->Mask()->Handle() ) );
       
   239 
       
   240         CAknIcon* tmpIcon = CAknIcon::NewL();
       
   241         CleanupStack::Pop( 2 ); // iom, iob (2)
       
   242         CleanupStack::PopAndDestroy( 1 ); // apaBmp (0)
       
   243 
       
   244         // Ownership is transferred
       
   245         tmpIcon->SetBitmap( iconOwnedBitmap );
       
   246         tmpIcon->SetMask( iconOwnedMask );
       
   247         // Ownership of tmpIcon is transferred
       
   248         CAknIcon* appIcon = AknIconUtils::CreateIconL( tmpIcon );
       
   249 
       
   250         aBitmap = appIcon->Bitmap();
       
   251         aMask = appIcon->Mask();
       
   252         // Detach and delete
       
   253         appIcon->SetBitmap( NULL );
       
   254         appIcon->SetMask( NULL );
       
   255         delete appIcon;
       
   256 
       
   257         // These are both safe
       
   258         CleanupStack::PushL( aBitmap ); // (1)
       
   259         CleanupStack::PushL( aMask ); // (2)
       
   260         }
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // AknsUtils::OpenAppIconFile
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 AKNS_EXPORTED_METHOD(AknsUtils::OpenAppIconFile)
       
   268 EXPORT_C TInt AknsUtils::OpenAppIconFile(
       
   269     MAknsSkinInstance* /*aInstance*/, TUid /*aAppUid*/,
       
   270     TAknsAppIconType aType, RFile& /*aFile*/ )
       
   271     {
       
   272     if( aType != EAknsAppIconType3D )
       
   273         {
       
   274         return KErrArgument;
       
   275         }
       
   276 
       
   277     return KErrNotSupported;
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // AknsUtils::GetAppIcon
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 AKNS_EXPORTED_METHOD(AknsUtils::GetAppIcon)
       
   285 EXPORT_C TInt AknsUtils::GetAppIcon(
       
   286     MAknsSkinInstance* aInstance, TUid aAppUid, TSize aSize,
       
   287     CApaMaskedBitmap& aAppBitmap )
       
   288     {
       
   289     AKNS_TRACE_OBSOLETE("AknsUtils::GetAppIcon (4 param)");
       
   290 
       
   291     __ASSERT_DEBUG( aAppBitmap.Mask(),
       
   292         AKNS_DEBUG_PANIC( EAknsDPanicInvalidParameter ) );
       
   293 
       
   294     CFbsBitmap* bitmap = NULL;
       
   295     CFbsBitmap* mask = NULL;
       
   296 
       
   297     TInt ret = KErrNone;
       
   298     TBool configuredIcon = EFalse;
       
   299 
       
   300     if ( !configuredIcon )
       
   301         {
       
   302         ret = GetAppIconFromSkin( aInstance, aAppUid, aSize, bitmap, mask );
       
   303         if( ret == KErrNone )
       
   304             {
       
   305             if( bitmap && mask && bitmap->Handle() && mask->Handle() )
       
   306                 {
       
   307                 ret = aAppBitmap.Duplicate( bitmap->Handle() );
       
   308                 ret |= aAppBitmap.Mask()->Duplicate( mask->Handle() );
       
   309                 delete bitmap;
       
   310                 delete mask;
       
   311                 return ret;
       
   312                 }
       
   313             else
       
   314                 {
       
   315                 // Delete bitmaps and proceed
       
   316                 delete bitmap;
       
   317                 delete mask;
       
   318                 }
       
   319             }
       
   320         }
       
   321 
       
   322     RApaLsSession lsSession;
       
   323     ret = lsSession.Connect();
       
   324     if( ret == KErrNone )
       
   325         {
       
   326         ret = lsSession.GetAppIcon( aAppUid, aSize, aAppBitmap );
       
   327         lsSession.Close();
       
   328         if(ret == KErrNone) //icon case
       
   329         	AknInternalIconUtils::SetAppIcon(bitmap); //icon case
       
   330         }
       
   331 
       
   332     return ret;
       
   333     } //lint !e1746 GetAppIcon syntax
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // AknsUtils::GetAppIconFromSkin
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 TInt AknsUtils::GetAppIconFromSkin(
       
   340     MAknsSkinInstance* aInstance, TUid aAppUid, TSize aSize,
       
   341     CFbsBitmap*& aBitmap, CFbsBitmap*& aMask )
       
   342     {
       
   343     if( !aInstance )
       
   344         {
       
   345         return KErrNotSupported;
       
   346         }
       
   347 
       
   348     TAknsItemID iid;
       
   349     iid.Set( EAknsMajorAppIcon, aAppUid.iUid );
       
   350 
       
   351     TInt err( KErrNone );
       
   352     TAknsItemID iconIID;
       
   353     TRAP( err, ( iconIID = SelectBestAppIconBitmapL(
       
   354         aSize, aInstance, iid ) ) );
       
   355     if( err )
       
   356         {
       
   357         return err;
       
   358         }
       
   359 
       
   360     CFbsBitmap* bitmap = NULL;
       
   361     CFbsBitmap* mask = NULL;
       
   362     TRAPD( createErr,
       
   363         CreateIconL( aInstance, iconIID, bitmap, mask, KNullDesC, -1, -1 ) ); //lint !e645 Initialized
       
   364 
       
   365     if( createErr )
       
   366         {
       
   367         delete bitmap;
       
   368         delete mask;
       
   369         return createErr;
       
   370         }
       
   371 
       
   372     __ASSERT_DEBUG( bitmap && mask,
       
   373         AKNS_DEBUG_PANIC( EAknsDPanicNotInitialized ) );
       
   374 
       
   375 	AknInternalIconUtils::SetAppIcon(aBitmap); //icon case
       
   376     aBitmap = bitmap;
       
   377     aMask = mask;
       
   378 
       
   379     return KErrNone;
       
   380     } //lint !e1746 GetAppIcon syntax
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // AknsUtils::SelectBestAppIconBitmapL
       
   384 // -----------------------------------------------------------------------------
       
   385 //
       
   386 TAknsItemID AknsUtils::SelectBestAppIconBitmapL(
       
   387     const TSize& aSize,
       
   388     MAknsSkinInstance* aSkin,
       
   389     const TAknsItemID& aAppIconIID )
       
   390     {
       
   391     TAknsItemID iid;
       
   392     iid.Set( KAknsIIDNone );
       
   393     TInt i;
       
   394 
       
   395     CAknsImageTableItemData* iconData = static_cast<CAknsImageTableItemData*>(
       
   396         aSkin->CreateUncachedItemDataL( aAppIconIID, EAknsITImageTable ) );
       
   397     if( !iconData )
       
   398         {
       
   399         User::Leave( KErrNotFound );
       
   400         }
       
   401 
       
   402     CleanupStack::PushL( iconData );
       
   403 
       
   404     TInt numberOfIcons = iconData->NumberOfImages();
       
   405     RArray<TSize> sizeArray;
       
   406     for( i=0; i<numberOfIcons; i++ )
       
   407         {
       
   408         TBool defOwned = EFalse;
       
   409         CAknsImageItemDef* def =
       
   410             static_cast<CAknsImageItemDef*>(
       
   411             static_cast<CAknsAppSkinInstance*>(aSkin)->LookupDef(
       
   412             defOwned, iconData->ImageIID(i), EAknsITImage ) );
       
   413 
       
   414         TBool appendError = EFalse;
       
   415 
       
   416         if( def && def->Attributes() )
       
   417             {
       
   418             TSize imageSize = def->Attributes()->iSize;
       
   419             if( sizeArray.Append( imageSize ) != KErrNone )
       
   420                 {
       
   421                 appendError = ETrue;
       
   422                 }
       
   423             }
       
   424         else
       
   425             {
       
   426             appendError = ETrue;
       
   427             }
       
   428 
       
   429         if( defOwned )
       
   430             {
       
   431             delete def;
       
   432             def = NULL;
       
   433             }
       
   434 
       
   435         if( appendError )
       
   436             {
       
   437             sizeArray.Reset();
       
   438             User::Leave( KErrGeneral );
       
   439             }
       
   440         }
       
   441 
       
   442     CleanupStack::Pop( iconData );
       
   443 
       
   444     // First check for zero size (SVG) or the exact match
       
   445     TInt indexFound = -1;
       
   446     for( i=0; i<numberOfIcons; i++ )
       
   447         {
       
   448         if( (sizeArray[i].iWidth==aSize.iWidth) &&
       
   449             (sizeArray[i].iHeight==aSize.iHeight) )
       
   450             {
       
   451             AKNS_TRACE_INFO2("AknsUtils::SBAIB Found (exact) MBM appicon for %x %x", aAppIconIID.iMinor, aAppIconIID.iMajor );
       
   452             indexFound = i;
       
   453             // Do not break, (0,0) might still be there
       
   454             }
       
   455         else if( (sizeArray[i].iWidth==0) &&
       
   456             (sizeArray[i].iHeight==0) )
       
   457             {
       
   458             AKNS_TRACE_INFO2("AknsUtils::SBAIB Using SVG appicon for %x %x", aAppIconIID.iMinor, aAppIconIID.iMajor );
       
   459             indexFound = i;
       
   460             break;
       
   461             }
       
   462         }
       
   463 
       
   464     if( indexFound>-1 )
       
   465         {
       
   466         iid.Set( iconData->ImageIID( indexFound ) );
       
   467         sizeArray.Reset();
       
   468         delete iconData;
       
   469         return iid;
       
   470         }
       
   471 
       
   472     // Then the largest of smaller or (in terms of one dimension) equal icons
       
   473     TInt bestDSum = 0;
       
   474     TInt dSum;
       
   475     for( i=0; i<numberOfIcons; i++ )
       
   476         {
       
   477         if( (sizeArray[i].iWidth<=aSize.iWidth) &&
       
   478             (sizeArray[i].iHeight<=aSize.iHeight) )
       
   479             {
       
   480             dSum = sizeArray[i].iWidth + sizeArray[i].iHeight;
       
   481             if( dSum > bestDSum )
       
   482                 {
       
   483                 indexFound = i;
       
   484                 bestDSum = dSum;
       
   485                 }
       
   486             }
       
   487         }
       
   488 
       
   489     if( indexFound>-1 )
       
   490         {
       
   491         iid.Set( iconData->ImageIID( indexFound ) );
       
   492         sizeArray.Reset();
       
   493         delete iconData;
       
   494         return iid;
       
   495         }
       
   496 
       
   497     // Finally, the smallest absolute difference
       
   498     bestDSum = KMaxTInt;
       
   499     for( i=0; i<numberOfIcons; i++ )
       
   500         {
       
   501         dSum = ( sizeArray[i].iWidth * sizeArray[i].iHeight ) -
       
   502             (aSize.iWidth*aSize.iHeight);
       
   503         if( dSum < 0 )
       
   504             {
       
   505             dSum = 0-dSum;
       
   506             }
       
   507         if( dSum < bestDSum )
       
   508             {
       
   509             indexFound = i;
       
   510             bestDSum = dSum;
       
   511             }
       
   512         }
       
   513 
       
   514     if( indexFound>-1 )
       
   515         {
       
   516         iid.Set( iconData->ImageIID( indexFound ) );
       
   517         }
       
   518 
       
   519     sizeArray.Reset();
       
   520     delete iconData;
       
   521 
       
   522     if( indexFound<0 )
       
   523         {
       
   524         User::Leave( KErrNotFound );
       
   525         }
       
   526 
       
   527     return iid;
       
   528     }
       
   529 
       
   530 //  End of File