|
1 /* |
|
2 * Copyright (c)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: ?Description |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <e32std.h> |
|
19 #include <exception> |
|
20 #include <e32base.h> |
|
21 #include <badesca.h> |
|
22 #include <AknIconUtils.h> |
|
23 #include <fbs.h> |
|
24 #include <bitdev.h> |
|
25 #include <QPixmap> |
|
26 #include <HbIcon> |
|
27 #include <QBitmap> |
|
28 #include <QDebug> |
|
29 |
|
30 #include "cadef.h" |
|
31 #include "caobjectadapter.h" |
|
32 #include "cainnerentry.h" |
|
33 #include "caentry_p.h" |
|
34 #include "cainnerquery.h" |
|
35 #include "caquery.h" |
|
36 #include "camenuiconutility.h" |
|
37 #include "canotifierfilter.h" |
|
38 #include "cainnernotifierfilter.h" |
|
39 |
|
40 static QImage::Format TDisplayMode2Format(TDisplayMode mode) |
|
41 { |
|
42 QImage::Format format; |
|
43 switch (mode) { |
|
44 case EGray2: |
|
45 format = QImage::Format_MonoLSB; |
|
46 break; |
|
47 case EColor256: |
|
48 case EGray256: |
|
49 format = QImage::Format_Indexed8; |
|
50 break; |
|
51 case EColor4K: |
|
52 format = QImage::Format_RGB444; |
|
53 break; |
|
54 case EColor64K: |
|
55 format = QImage::Format_RGB16; |
|
56 break; |
|
57 case EColor16M: |
|
58 format = QImage::Format_RGB888; |
|
59 break; |
|
60 case EColor16MU: |
|
61 format = QImage::Format_RGB32; |
|
62 break; |
|
63 case EColor16MA: |
|
64 format = QImage::Format_ARGB32; |
|
65 break; |
|
66 case EColor16MAP: |
|
67 format = QImage::Format_ARGB32_Premultiplied; |
|
68 break; |
|
69 default: |
|
70 format = QImage::Format_Invalid; |
|
71 break; |
|
72 } |
|
73 return format; |
|
74 } |
|
75 |
|
76 QPixmap fromSymbianCFbsBitmap(CFbsBitmap *aBitmap) |
|
77 { |
|
78 aBitmap->BeginDataAccess(); |
|
79 uchar *data = (uchar *)aBitmap->DataAddress(); |
|
80 TSize size = aBitmap->SizeInPixels(); |
|
81 TDisplayMode displayMode = aBitmap->DisplayMode(); |
|
82 |
|
83 // QImage format must match to bitmap format |
|
84 QImage image(data, size.iWidth, size.iHeight, TDisplayMode2Format(displayMode)); |
|
85 aBitmap->EndDataAccess(); |
|
86 |
|
87 // No data copying happens because image format matches native OpenVG format. |
|
88 // So QPixmap actually points to CFbsBitmap data. |
|
89 return QPixmap::fromImage(image); |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // |
|
94 // ----------------------------------------------------------------------------- |
|
95 void CaObjectAdapter::convertL(const CaEntry &fromEntry, |
|
96 CCaInnerEntry &toEntry) |
|
97 { |
|
98 toEntry.SetId(fromEntry.id()); |
|
99 |
|
100 toEntry.SetTextL(convertToDescriptor(fromEntry.text())); |
|
101 |
|
102 toEntry.SetDescriptionL(convertToDescriptor(fromEntry.description())); |
|
103 |
|
104 toEntry.SetEntryTypeNameL( |
|
105 convertToDescriptor(fromEntry.entryTypeName())); |
|
106 |
|
107 toEntry.SetFlags(static_cast<TUint>(fromEntry.flags())); |
|
108 |
|
109 toEntry.SetRole(static_cast<TUint>(fromEntry.role())); |
|
110 |
|
111 const CaIconDescription fromIconDescription = |
|
112 fromEntry.iconDescription(); |
|
113 |
|
114 toEntry.SetIconDataL( |
|
115 static_cast<TInt>(fromIconDescription.bitmapId()), |
|
116 static_cast<TInt>(fromIconDescription.maskId()), |
|
117 static_cast<TInt>(fromIconDescription.skinMajorId()), |
|
118 static_cast<TInt>(fromIconDescription.skinMinorId()), |
|
119 convertToDescriptor(fromIconDescription.filename())); |
|
120 |
|
121 const QMap<QString, QString> attributesMap = fromEntry.attributes(); |
|
122 |
|
123 foreach(QString key, attributesMap.keys()) { |
|
124 if (key == applicationUidAttributeName()) { |
|
125 const TInt32 uid = attributesMap.value(key).toInt(); |
|
126 toEntry.SetUid(uid); |
|
127 } else { |
|
128 toEntry.AddAttributeL( |
|
129 convertToDescriptor(key), |
|
130 convertToDescriptor(attributesMap.value(key))); |
|
131 } |
|
132 } |
|
133 } |
|
134 |
|
135 //---------------------------------------------------------------------------- |
|
136 // |
|
137 //---------------------------------------------------------------------------- |
|
138 void CaObjectAdapter::convertL(const CaQuery &fromQuery, |
|
139 CCaInnerQuery &toQuery) |
|
140 { |
|
141 toQuery.SetParentId(fromQuery.parentId()); |
|
142 |
|
143 toQuery.SetFlagsOn(static_cast<TUint>(fromQuery.flagsOn())); |
|
144 |
|
145 toQuery.SetFlagsOff(static_cast<TUint>(fromQuery.flagsOff())); |
|
146 |
|
147 toQuery.SetRole(static_cast<TInt>(fromQuery.entryRoles())); |
|
148 |
|
149 toQuery.SetCount(fromQuery.count()); |
|
150 |
|
151 const QStringList list = fromQuery.entryTypeNames(); |
|
152 |
|
153 CDesC16ArrayFlat *sourceList = |
|
154 new(ELeave)CDesC16ArrayFlat(KDefaultGranularity); |
|
155 CleanupStack::PushL(sourceList); |
|
156 |
|
157 foreach(const QString str, list) { |
|
158 sourceList->AppendL(convertToDescriptor(str)); |
|
159 } |
|
160 |
|
161 toQuery.SetEntryTypeNames(sourceList); |
|
162 |
|
163 CleanupStack::Pop(sourceList); |
|
164 |
|
165 // mapping sort enums |
|
166 SortAttribute sortAttr; |
|
167 Qt::SortOrder sortOrder; |
|
168 fromQuery.getSort(sortAttr, sortOrder); |
|
169 toQuery.SetSort(CaObjectAdapter::getSortCode(sortAttr, sortOrder)); |
|
170 } |
|
171 |
|
172 //---------------------------------------------------------------------------- |
|
173 // |
|
174 //---------------------------------------------------------------------------- |
|
175 void CaObjectAdapter::convert(const CCaInnerEntry &fromEntry, |
|
176 CaEntry &toEntry) |
|
177 { |
|
178 toEntry.setId(fromEntry.GetId()); |
|
179 |
|
180 toEntry.setText(convertToString(fromEntry.GetText())); |
|
181 |
|
182 toEntry.setDescription(convertToString(fromEntry.GetDescription())); |
|
183 toEntry.setEntryTypeName(convertToString(fromEntry.GetEntryTypeName())); |
|
184 |
|
185 toEntry.setFlags(static_cast<EntryFlag>(fromEntry.GetFlags())); |
|
186 |
|
187 // take care of converting icon attributes |
|
188 const CCaInnerEntry::TIconAttributes &icon = fromEntry.GetIcon(); |
|
189 |
|
190 CaIconDescription iconDescription; |
|
191 iconDescription.setId(icon.iId); |
|
192 iconDescription.setBitmapId(icon.iBitmapId); |
|
193 iconDescription.setMaskId(icon.iMaskId); |
|
194 iconDescription.setSkinMajorId(icon.iSkinMajorId); |
|
195 iconDescription.setSkinMinorId(icon.iSkinMinorId); |
|
196 iconDescription.setFilename(convertToString(icon.iFileName)); |
|
197 |
|
198 toEntry.setIconDescription(iconDescription); |
|
199 |
|
200 const RCaEntryAttrArray &attributesArray = fromEntry.GetAttributes(); |
|
201 |
|
202 if (toEntry.entryTypeName() == applicationEntryName() |
|
203 || toEntry.entryTypeName() == widgetEntryName()) { |
|
204 toEntry.setAttribute(applicationUidAttributeName(), |
|
205 QString::number(fromEntry.GetUid())); |
|
206 } |
|
207 |
|
208 const int attributesArrayCount = attributesArray.Count(); |
|
209 |
|
210 for (int i = 0; i < attributesArrayCount; ++i) { |
|
211 const CCaEntryAttribute *const attribute = attributesArray[i]; |
|
212 toEntry.setAttribute(convertToString(attribute->Name()), |
|
213 convertToString(attribute->Value())); |
|
214 } |
|
215 } |
|
216 |
|
217 //---------------------------------------------------------------------------- |
|
218 // !!! Warning: returns wrapper to internal QString representation which may |
|
219 // get invalid before returned TPtrC object gets out of scope |
|
220 //---------------------------------------------------------------------------- |
|
221 const TPtrC CaObjectAdapter::convertToDescriptor(const QString &string) |
|
222 { |
|
223 const TPtrC result(reinterpret_cast<const TUint16 *>(string.utf16())); |
|
224 return result; |
|
225 } |
|
226 |
|
227 //---------------------------------------------------------------------------- |
|
228 // |
|
229 //---------------------------------------------------------------------------- |
|
230 QString CaObjectAdapter::convertToString(const TDesC &des) |
|
231 { |
|
232 return QString::fromUtf16(des.Ptr(), des.Length()); |
|
233 } |
|
234 |
|
235 //---------------------------------------------------------------------------- |
|
236 // |
|
237 //---------------------------------------------------------------------------- |
|
238 void CaObjectAdapter::convertL(const CaNotifierFilter ¬ifierFilter, |
|
239 CCaInnerNotifierFilter &source) |
|
240 { |
|
241 source.SetParentId(static_cast<TInt>(notifierFilter.getParentId())); |
|
242 |
|
243 RArray<TInt> idsList; |
|
244 CleanupClosePushL(idsList); |
|
245 CaObjectAdapter::convertL(notifierFilter.getIds(), idsList); |
|
246 source.SetIdsL(idsList); |
|
247 |
|
248 CleanupStack::PopAndDestroy(&idsList); |
|
249 |
|
250 switch (notifierFilter.getEntryRole()) { |
|
251 case static_cast<TUint>(ItemEntryRole): |
|
252 source.SetEntryRole(EItemEntryRole); |
|
253 break; |
|
254 case static_cast<TUint>(GroupEntryRole): |
|
255 source.SetEntryRole(EGroupEntryRole); |
|
256 break; |
|
257 default: |
|
258 source.SetEntryRole(ENoneEntryRole); |
|
259 break; |
|
260 } |
|
261 CDesC16ArrayFlat *typeNames = new(ELeave) CDesC16ArrayFlat( |
|
262 KDefaultGranularity); |
|
263 CleanupStack::PushL(typeNames); |
|
264 |
|
265 const QStringList stringList = notifierFilter.getTypeNames(); |
|
266 |
|
267 foreach(QString str, stringList) { |
|
268 typeNames->AppendL(convertToDescriptor(str)); |
|
269 } |
|
270 |
|
271 source.SetTypeNames(typeNames); |
|
272 |
|
273 CleanupStack::Pop(typeNames); |
|
274 |
|
275 } |
|
276 //---------------------------------------------------------------------------- |
|
277 // |
|
278 //---------------------------------------------------------------------------- |
|
279 void CaObjectAdapter::convertL( |
|
280 const RPointerArray<CCaInnerEntry> &fromEntriesArray, |
|
281 QList<CaEntry *> &toEntryList) |
|
282 { |
|
283 for (int i = 0; i < fromEntriesArray.Count(); ++i) { |
|
284 CaEntry *const toEntry = new CaEntry( |
|
285 static_cast<EntryRole>(fromEntriesArray[i]->GetRole())); |
|
286 |
|
287 CaObjectAdapter::convert(*fromEntriesArray[i], *toEntry); |
|
288 |
|
289 toEntryList << toEntry; |
|
290 } |
|
291 } |
|
292 |
|
293 //---------------------------------------------------------------------------- |
|
294 // |
|
295 //---------------------------------------------------------------------------- |
|
296 void CaObjectAdapter::convertL(const QList<int> &entryIdList, |
|
297 RArray<TInt> &source) |
|
298 { |
|
299 foreach(int id, entryIdList) { |
|
300 source.AppendL(static_cast<TInt>(id)); |
|
301 } |
|
302 } |
|
303 |
|
304 //---------------------------------------------------------------------------- |
|
305 // |
|
306 //---------------------------------------------------------------------------- |
|
307 void CaObjectAdapter::convertL(const RArray<TInt> &innerEntryIdList, |
|
308 QList<int> &idList) |
|
309 { |
|
310 for (TInt i = 0; i < innerEntryIdList.Count(); ++i) { |
|
311 idList.append(innerEntryIdList[i]); |
|
312 } |
|
313 } |
|
314 |
|
315 //---------------------------------------------------------------------------- |
|
316 // |
|
317 //---------------------------------------------------------------------------- |
|
318 HbIcon CaObjectAdapter::makeIcon(const CaEntry &entry, const QSize &size) |
|
319 { |
|
320 |
|
321 HbIcon icon; |
|
322 TRAPD(leaveCode, icon = makeIconL(entry, size)); |
|
323 |
|
324 USE_QDEBUG_IF(leaveCode) << "CaObjectAdapter::makeIcon leaveCode:" |
|
325 << leaveCode; |
|
326 |
|
327 return icon; |
|
328 } |
|
329 |
|
330 //---------------------------------------------------------------------------- |
|
331 // |
|
332 //---------------------------------------------------------------------------- |
|
333 ErrorCode CaObjectAdapter::convertErrorCode(int internalErrorCode) |
|
334 { |
|
335 ErrorCode error(NoErrorCode); |
|
336 switch (internalErrorCode) { |
|
337 case KErrNone: |
|
338 error = NoErrorCode; |
|
339 break; |
|
340 case KErrNotFound: |
|
341 error = NotFoundErrorCode; |
|
342 break; |
|
343 case KErrNoMemory: |
|
344 error = OutOfMemoryErrorCode; |
|
345 break; |
|
346 case KErrArgument: |
|
347 error = BadArgumentErrorCode; |
|
348 break; |
|
349 default: |
|
350 error = UnknownErrorCode; |
|
351 break; |
|
352 } |
|
353 return error; |
|
354 } |
|
355 |
|
356 //---------------------------------------------------------------------------- |
|
357 // |
|
358 //---------------------------------------------------------------------------- |
|
359 const QString &CaObjectAdapter::applicationUidAttributeName() |
|
360 { |
|
361 const static QString name("application:uid"); |
|
362 return name; |
|
363 } |
|
364 |
|
365 //---------------------------------------------------------------------------- |
|
366 // |
|
367 //---------------------------------------------------------------------------- |
|
368 const QString &CaObjectAdapter::applicationEntryName() |
|
369 { |
|
370 const static QString name("application"); |
|
371 return name; |
|
372 } |
|
373 |
|
374 //---------------------------------------------------------------------------- |
|
375 // |
|
376 // ----------------------------------------------------------------------------- |
|
377 const QString &CaObjectAdapter::widgetEntryName() |
|
378 { |
|
379 const static QString name("widget"); |
|
380 return name; |
|
381 } |
|
382 |
|
383 // ----------------------------------------------------------------------------- |
|
384 // copying compressed bitmap |
|
385 //---------------------------------------------------------------------------- |
|
386 CFbsBitmap *CaObjectAdapter::copyBitmapLC(CFbsBitmap *input) |
|
387 { |
|
388 CFbsBitmap *bmp = new(ELeave) CFbsBitmap(); |
|
389 CleanupStack::PushL(bmp); |
|
390 bmp->Create(input->SizeInPixels(), input->DisplayMode()); |
|
391 |
|
392 CFbsBitmapDevice *bitmapDevice = CFbsBitmapDevice::NewL(bmp); |
|
393 CleanupStack::PushL(bitmapDevice); |
|
394 CFbsBitGc *bmpGc; |
|
395 bitmapDevice->CreateContext(bmpGc); |
|
396 bmpGc->BitBlt(TPoint(0,0), input); |
|
397 delete bmpGc; |
|
398 CleanupStack::PopAndDestroy(bitmapDevice); |
|
399 return bmp; |
|
400 } |
|
401 |
|
402 //---------------------------------------------------------------------------- |
|
403 // |
|
404 //---------------------------------------------------------------------------- |
|
405 HbIcon CaObjectAdapter::makeIconL(const CaEntry &entry, const QSize &size) |
|
406 { |
|
407 HbIcon icon; |
|
408 CCaInnerEntry *innerEntry = CCaInnerEntry::NewLC(); |
|
409 CaObjectAdapter::convertL(entry, *innerEntry); |
|
410 QString filename(entry.iconDescription().filename()); |
|
411 if (!filename.isEmpty()) { |
|
412 icon = HbIcon(filename); |
|
413 } |
|
414 //try to load symbian icon from multi-bitmap (mbm, mbg) |
|
415 if (icon.isNull() || !(icon.size().isValid())) { |
|
416 CAknIcon *aknIcon = CaMenuIconUtility::GetItemIcon(*innerEntry); |
|
417 QPixmap pixmap; |
|
418 if (aknIcon) { |
|
419 CleanupStack::PushL(aknIcon); |
|
420 |
|
421 //need to disable compression to properly convert the bitmap |
|
422 AknIconUtils::DisableCompression(aknIcon->Bitmap()); |
|
423 AknIconUtils::SetSize(aknIcon->Bitmap(), TSize(size.width(), |
|
424 size.height()), EAspectRatioPreservedAndUnusedSpaceRemoved); |
|
425 if (aknIcon->Bitmap()->Header().iCompression |
|
426 == ENoBitmapCompression) { |
|
427 pixmap = fromSymbianCFbsBitmap(aknIcon->Bitmap()); |
|
428 QPixmap mask = fromSymbianCFbsBitmap( |
|
429 aknIcon->Mask()); |
|
430 pixmap.setAlphaChannel(mask); |
|
431 } else { // we need special handling for icons in 9.2 (NGA) |
|
432 // let's hope that in future it will be in QT code |
|
433 CFbsBitmap *temp(NULL); |
|
434 temp = copyBitmapLC(aknIcon->Bitmap()); |
|
435 pixmap = fromSymbianCFbsBitmap(temp); |
|
436 CleanupStack::PopAndDestroy(); |
|
437 temp = copyBitmapLC(aknIcon->Mask()); |
|
438 QPixmap mask = fromSymbianCFbsBitmap(temp); |
|
439 CleanupStack::PopAndDestroy(); |
|
440 pixmap.setAlphaChannel(mask); |
|
441 } |
|
442 pixmap = pixmap.scaled(size, Qt::KeepAspectRatioByExpanding); |
|
443 CleanupStack::PopAndDestroy(aknIcon); |
|
444 icon = HbIcon(QIcon(pixmap)); |
|
445 } |
|
446 } |
|
447 CleanupStack::PopAndDestroy(innerEntry); |
|
448 return icon; |
|
449 } |
|
450 |
|
451 //---------------------------------------------------------------------------- |
|
452 // |
|
453 //---------------------------------------------------------------------------- |
|
454 void CaObjectAdapter::convert( |
|
455 CaNotifierPrivate::NotifierType src, |
|
456 CCaInnerNotifierFilter::TNotifierType &dest) |
|
457 { |
|
458 switch (src) { |
|
459 case CaNotifierPrivate::EntryChangedWithIdNotifierType: |
|
460 dest = CCaInnerNotifierFilter::EEntryChangedWithId; |
|
461 break; |
|
462 case CaNotifierPrivate::EntryChangedWithEntryNotifierType: |
|
463 dest = CCaInnerNotifierFilter::EEntryChangedWithEntry; |
|
464 break; |
|
465 case CaNotifierPrivate::EntryTouchedNotifierType: |
|
466 dest = CCaInnerNotifierFilter::EEntryTouched; |
|
467 break; |
|
468 case CaNotifierPrivate::GroupContentChangedNotifierType: |
|
469 dest = CCaInnerNotifierFilter::EGroupContentChanged; |
|
470 break; |
|
471 } |
|
472 } |
|
473 |
|
474 //---------------------------------------------------------------------------- |
|
475 // |
|
476 //---------------------------------------------------------------------------- |
|
477 void CaObjectAdapter::convert( |
|
478 TChangeType src, ChangeType &dest) |
|
479 { |
|
480 switch (src) { |
|
481 case EAddChangeType: |
|
482 dest = AddChangeType; |
|
483 break; |
|
484 case ERemoveChangeType: |
|
485 dest = RemoveChangeType; |
|
486 break; |
|
487 case EUpdateChangeType: |
|
488 dest = UpdateChangeType; |
|
489 break; |
|
490 } |
|
491 } |
|
492 |
|
493 CCaInnerQuery::TSortAttribute CaObjectAdapter::getSortCode( |
|
494 SortAttribute sortAttribute, Qt::SortOrder sortOrder) |
|
495 { |
|
496 CCaInnerQuery::TSortAttribute sortCode(CCaInnerQuery::Default); |
|
497 |
|
498 switch (sortAttribute) { |
|
499 case NameSortAttribute: { |
|
500 sortCode = (sortOrder == Qt::AscendingOrder) ? CCaInnerQuery::Name |
|
501 : CCaInnerQuery::NameDesc; |
|
502 break; |
|
503 } |
|
504 case CreatedTimestampSortAttribute: { |
|
505 sortCode = (sortOrder == Qt::AscendingOrder) |
|
506 ? CCaInnerQuery::CreatedTimestamp |
|
507 : CCaInnerQuery::CreatedTimestampDesc; |
|
508 break; |
|
509 } |
|
510 case MostUsedSortAttribute: { |
|
511 sortCode = (sortOrder == Qt::AscendingOrder) |
|
512 ? CCaInnerQuery::MostUsed : CCaInnerQuery::MostUsedDesc; |
|
513 break; |
|
514 } |
|
515 case LastUsedSortAttribute: { |
|
516 sortCode = (sortOrder == Qt::AscendingOrder) |
|
517 ? CCaInnerQuery::LastUsed : CCaInnerQuery::LastUsedDesc; |
|
518 break; |
|
519 } |
|
520 case DefaultSortAttribute: { |
|
521 sortCode = (sortOrder == Qt::AscendingOrder) |
|
522 ? CCaInnerQuery::Default : CCaInnerQuery::DefaultDesc; |
|
523 break; |
|
524 } |
|
525 } |
|
526 |
|
527 return sortCode; |
|
528 } |
|
529 |
|
530 //---------------------------------------------------------------------------- |
|
531 // |
|
532 //---------------------------------------------------------------------------- |
|
533 void CaObjectAdapter::setId(CaEntry &entry, |
|
534 int id) |
|
535 { |
|
536 entry.setId(id); |
|
537 } |