287 return true; |
287 return true; |
288 } |
288 } |
289 |
289 |
290 |
290 |
291 |
291 |
292 static void processAvatar(const QContactWinCEEngine* /*engine*/, IItem* contact, const QVariantList& values, QContact& ret) |
292 static void processAvatar(const QContactWinCEEngine* engine, IItem* contact, const QVariantList& values, QContact& ret) |
293 { |
293 { |
|
294 Q_UNUSED(engine); |
|
295 Q_UNUSED(contact); |
|
296 |
294 QContactAvatar avatar; |
297 QContactAvatar avatar; |
295 |
298 QString imageUrl = values[0].toString(); |
296 QByteArray data; |
299 QString videoUrl = values[1].toString(); |
297 if (loadAvatarData(contact, &data)) { |
300 setIfNotEmpty(avatar, QContactAvatar::FieldImageUrl, values[0].toString()); |
298 if (!data.isEmpty()) { |
301 setIfNotEmpty(avatar, QContactAvatar::FieldVideoUrl, values[1].toString()); |
299 QPixmap pixmap; |
302 |
300 pixmap.loadFromData(data, "PNG"); |
|
301 //avatar.setPixmap(pixmap); |
|
302 } |
|
303 } |
|
304 |
|
305 if (values[0].toString().isEmpty()) { |
|
306 if (!data.isEmpty()) { |
|
307 QUrl url(QUrl::fromEncoded(data.toPercentEncoding())); |
|
308 url.setScheme("data"); |
|
309 avatar.setImageUrl(url.toString()); |
|
310 } |
|
311 } else { |
|
312 avatar.setImageUrl(values[0].toString()); |
|
313 } |
|
314 |
|
315 |
|
316 |
|
317 if (!avatar.isEmpty()) |
303 if (!avatar.isEmpty()) |
318 ret.saveDetail(&avatar); |
304 ret.saveDetail(&avatar); |
|
305 } |
|
306 |
|
307 static void processThumbnail(IItem* contact, QContact& ret) |
|
308 { |
|
309 QContactThumbnail thumbnail; |
|
310 |
|
311 QByteArray data; |
|
312 if (loadThumbnailData(contact, &data)) { |
|
313 if (!data.isEmpty()) { |
|
314 QImage image; |
|
315 image.loadFromData(data, "PNG"); |
|
316 thumbnail.setThumbnail(image); |
|
317 } |
|
318 } |
|
319 |
|
320 if (!thumbnail.isEmpty()) |
|
321 ret.saveDetail(&thumbnail); |
319 } |
322 } |
320 |
323 |
321 static void processAddress(const QContactWinCEEngine*, const QString& context, const QVariantList& values, QContact& ret) |
324 static void processAddress(const QContactWinCEEngine*, const QString& context, const QVariantList& values, QContact& ret) |
322 { |
325 { |
323 QContactAddress address; |
326 QContactAddress address; |
518 |
521 |
519 if (!family.isEmpty()) |
522 if (!family.isEmpty()) |
520 ret.saveDetail(&family); |
523 ret.saveDetail(&family); |
521 } |
524 } |
522 |
525 |
523 static void contactP2QTransforms(CEPROPID phoneMeta, CEPROPID emailMeta, CEPROPID avatarMeta, CEPROPID avatarTypeMeta, QHash<CEPROPID, PoomContactElement>& prophash, QVector<CEPROPID>& propids) |
526 static void contactP2QTransforms(CEPROPID phoneMeta, CEPROPID emailMeta, CEPROPID avatarImageMeta, CEPROPID avatarVideoMeta, QHash<CEPROPID, PoomContactElement>& prophash, QVector<CEPROPID>& propids) |
524 { |
527 { |
525 static QHash<CEPROPID, PoomContactElement> hash; |
528 static QHash<CEPROPID, PoomContactElement> hash; |
526 static QVector<CEPROPID> ids; |
529 static QVector<CEPROPID> ids; |
527 |
530 |
528 if (hash.count() == 0) { |
531 if (hash.count() == 0) { |
605 family.func = processFamily; |
608 family.func = processFamily; |
606 list.append(family); |
609 list.append(family); |
607 |
610 |
608 // Avatar |
611 // Avatar |
609 PoomContactElement avatar; |
612 PoomContactElement avatar; |
610 avatar.poom << avatarMeta << avatarTypeMeta; //PIMPR_PICTURE need to be handled inside the processAvatar() function separately. |
613 avatar.poom << avatarImageMeta << avatarVideoMeta; |
611 avatar.func = processAvatar; |
614 avatar.func = processAvatar; |
612 list.append(avatar); |
615 list.append(avatar); |
613 |
|
614 |
616 |
615 // XXX Unhandled: |
617 // XXX Unhandled: |
616 // |
618 // |
617 // PIMPR_ACCOUNT_NAME |
619 // PIMPR_ACCOUNT_NAME |
618 // PIMPR_CUSTOMERID |
620 // PIMPR_CUSTOMERID |
663 return true; |
665 return true; |
664 } |
666 } |
665 |
667 |
666 static bool processQAvatar(const QContactWinCEEngine* engine, IItem* contact, const QContactDetail& detail, QVector<CEPROPVAL>& props) |
668 static bool processQAvatar(const QContactWinCEEngine* engine, IItem* contact, const QContactDetail& detail, QVector<CEPROPVAL>& props) |
667 { |
669 { |
|
670 Q_UNUSED(contact); |
|
671 |
|
672 QContactAvatar avatar(detail); |
|
673 QUrl imageUrl = avatar.imageUrl(); |
|
674 QUrl videoUrl = avatar.videoUrl(); |
|
675 |
|
676 addIfNotEmpty(engine->metaAvatarImage(), detail.value(QContactAvatar::FieldImageUrl), props); |
|
677 addIfNotEmpty(engine->metaAvatarVideo(), detail.value(QContactAvatar::FieldVideoUrl), props); |
|
678 |
|
679 return true; |
|
680 } |
|
681 |
|
682 static bool processQThumbnail(const QContactWinCEEngine* engine, IItem* contact, const QContactDetail& detail, QVector<CEPROPVAL>& props) |
|
683 { |
668 Q_UNUSED(engine); |
684 Q_UNUSED(engine); |
669 Q_UNUSED(contact); |
|
670 Q_UNUSED(detail); |
|
671 Q_UNUSED(props); |
685 Q_UNUSED(props); |
672 //QString avatarData = detail.value(QContactAvatar::FieldImageUrl); |
686 |
673 //QPixmap avatarPixmap = detail.value<QPixmap>(QContactAvatar::FieldAvatarPixmap); |
687 QContactThumbnail thumbnail(detail); |
674 |
688 QImage thumbnailImage = thumbnail.thumbnail(); |
675 //FIXME:wince avatar should be processed as thumbnail |
689 |
676 //addIfNotEmpty(engine->metaAvatar(), avatarData, props); |
690 if (!thumbnailImage.isNull()) { |
677 |
691 QByteArray data; |
678 //if (!avatarPixmap.isNull()) { |
692 QBuffer buffer(&data); |
679 // QByteArray data; |
693 buffer.open(QIODevice::WriteOnly); |
680 // QBuffer buffer(&data); |
694 if (!thumbnailImage.save(&buffer, "PNG") || !saveThumbnailData(contact, data)) |
681 // buffer.open(QIODevice::WriteOnly); |
695 return false; |
682 // if (!avatarPixmap.save(&buffer, "PNG") || !saveAvatarData(contact, data)) |
696 } |
683 // return false; |
|
684 //} |
|
685 return true; |
697 return true; |
686 } |
698 } |
687 |
699 |
688 static bool processQFamily(const QContactWinCEEngine*, IItem* /*contact*/, const QContactDetail& detail, QVector<CEPROPVAL>& props) |
700 static bool processQFamily(const QContactWinCEEngine*, IItem* /*contact*/, const QContactDetail& detail, QVector<CEPROPVAL>& props) |
689 { |
701 { |
951 hash.insert(QContactNickname::DefinitionName, processQNickname); |
963 hash.insert(QContactNickname::DefinitionName, processQNickname); |
952 hash.insert(QContactOrganization::DefinitionName, processQOrganisation); |
964 hash.insert(QContactOrganization::DefinitionName, processQOrganisation); |
953 hash.insert(QContactUrl::DefinitionName, processQWebpage); |
965 hash.insert(QContactUrl::DefinitionName, processQWebpage); |
954 hash.insert(QContactFamily::DefinitionName, processQFamily); |
966 hash.insert(QContactFamily::DefinitionName, processQFamily); |
955 hash.insert(QContactAvatar::DefinitionName, processQAvatar); |
967 hash.insert(QContactAvatar::DefinitionName, processQAvatar); |
|
968 hash.insert(QContactThumbnail::DefinitionName, processQThumbnail); |
956 } |
969 } |
957 ret = hash; |
970 ret = hash; |
958 } |
971 } |
959 |
972 |
960 QContact QContactWinCEEngine::convertToQContact(IItem *contact) const |
973 QContact QContactWinCEEngine::convertToQContact(IItem *contact) const |
974 // Map information |
987 // Map information |
975 QHash<CEPROPID, PoomContactElement> hash; |
988 QHash<CEPROPID, PoomContactElement> hash; |
976 QVector<CEPROPID> props; |
989 QVector<CEPROPID> props; |
977 |
990 |
978 // Get our mapping tables |
991 // Get our mapping tables |
979 contactP2QTransforms(d->m_phonemeta, d->m_emailmeta, d->m_avatartypemeta, d->m_avatarmeta, hash, props); |
992 contactP2QTransforms(d->m_phonemeta, d->m_emailmeta, d->m_avatarImageMeta, d->m_avatarVideoMeta, hash, props); |
980 |
993 |
981 CEPROPVAL *propvals = 0; |
994 CEPROPVAL *propvals = 0; |
982 HRESULT hr = contact->GetProps(props.constData(), CEDB_ALLOWREALLOC, props.count(), &propvals, &cbSize, GetProcessHeap()); |
995 HRESULT hr = contact->GetProps(props.constData(), CEDB_ALLOWREALLOC, props.count(), &propvals, &cbSize, GetProcessHeap()); |
983 |
996 |
984 if (SUCCEEDED(hr)) { |
997 if (SUCCEEDED(hr)) { |
1012 valueHash.take(id); |
1025 valueHash.take(id); |
1013 } |
1026 } |
1014 } |
1027 } |
1015 HeapFree(GetProcessHeap(), 0, propvals); |
1028 HeapFree(GetProcessHeap(), 0, propvals); |
1016 } |
1029 } |
|
1030 |
|
1031 // convert thumbnail by special way. |
|
1032 processThumbnail(contact, ret); |
1017 |
1033 |
1018 // Synthesize the display label. |
1034 // Synthesize the display label. |
1019 QContactManager::Error error; |
1035 QContactManager::Error error; |
1020 QString synth = synthesizedDisplayLabel(ret, &error); |
1036 QString synth = synthesizedDisplayLabel(ret, &error); |
1021 setContactDisplayLabel(&ret, synth); |
1037 setContactDisplayLabel(&ret, synth); |
1410 case QContactFilter::ChangeLogFilter: |
1426 case QContactFilter::ChangeLogFilter: |
1411 //XXX Timestamp detail is not supported by WinCE backend |
1427 //XXX Timestamp detail is not supported by WinCE backend |
1412 break; |
1428 break; |
1413 |
1429 |
1414 case QContactFilter::ActionFilter: |
1430 case QContactFilter::ActionFilter: |
1415 { |
|
1416 // Find any matching actions, and do a union filter on their filter objects |
|
1417 QContactActionFilter af(filter); |
|
1418 QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion()); |
|
1419 |
|
1420 QString str; |
|
1421 QStringList strList; |
|
1422 for (int j = 0; j < descriptors.count(); j++) { |
|
1423 QContactAction* action = QContactAction::action(descriptors.at(j)); |
|
1424 |
|
1425 QContactFilter d = action->contactFilter(af.value()); |
|
1426 delete action; // clean up. |
|
1427 if (!QContactManagerEngine::validateActionFilter(d)) |
|
1428 return QString(); |
|
1429 |
|
1430 str = convertFilterToQueryString(d); |
|
1431 if (str.isEmpty()) |
|
1432 return QString(); |
|
1433 strList << str; |
|
1434 } |
|
1435 |
|
1436 if (!strList.isEmpty()) { |
|
1437 ret =QString("(%1)").arg(strList.join(" OR ")); |
|
1438 } |
|
1439 // Fall through to end |
|
1440 } |
|
1441 break; |
1431 break; |
1442 |
1432 |
1443 case QContactFilter::IntersectionFilter: |
1433 case QContactFilter::IntersectionFilter: |
1444 { |
1434 { |
1445 const QContactIntersectionFilter bf(filter); |
1435 const QContactIntersectionFilter bf(filter); |
1601 } else { |
1591 } else { |
1602 //Should we fail back to generic filtering here? |
1592 //Should we fail back to generic filtering here? |
1603 qDebug() << "Can't filter contacts with query string:" << query << ", HRESULT=" << HRESULT_CODE(hr); |
1593 qDebug() << "Can't filter contacts with query string:" << query << ", HRESULT=" << HRESULT_CODE(hr); |
1604 } |
1594 } |
1605 } |
1595 } |
|
1596 |
1606 //Fail back to generic filtering |
1597 //Fail back to generic filtering |
1607 return QContactManagerEngine::contactIds(filter, sortOrders, error); |
1598 QList<QContactLocalId> ids = contactIds(QContactFilter(), QList<QContactSortOrder>(), error); |
1608 } |
1599 QList<QContact> sorted; |
1609 |
1600 foreach(const QContactLocalId& id, ids) { |
1610 |
1601 QContact c = contact(id, QContactFetchHint(), error); |
|
1602 if (*error != QContactManager::NoError) |
|
1603 break; |
|
1604 if (QContactManagerEngine::testFilter(filter, c)) |
|
1605 QContactManagerEngine::addSorted(&sorted, c, sortOrders); |
|
1606 } |
|
1607 |
|
1608 /* Extract the ids */ |
|
1609 ids.clear(); |
|
1610 foreach(const QContact& c, sorted) |
|
1611 ids.append(c.localId()); |
|
1612 |
|
1613 return ids; |
|
1614 } |
|
1615 |
|
1616 |