|
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 |