qtmobility/plugins/contacts/wince/contactconversions.cpp
changeset 5 453da2cfceef
parent 4 90517678cc4f
child 11 06b8e2af4411
equal deleted inserted replaced
4:90517678cc4f 5:453da2cfceef
   217         }
   217         }
   218     }
   218     }
   219     return false;
   219     return false;
   220 }
   220 }
   221 
   221 
   222 static bool loadAvatarData(IItem* contact, QByteArray* data)
   222 static bool loadThumbnailData(IItem* contact, QByteArray* data)
   223 {
   223 {
   224     HRESULT   hr;
   224     HRESULT   hr;
   225     SimpleComPointer<IStream>  pStream = NULL;
   225     SimpleComPointer<IStream>  pStream = NULL;
   226     ULONG     ulSize;
   226     ULONG     ulSize;
   227     // Extract the picture from the contact
   227     // Extract the picture from the contact
   257             
   257             
   258     }
   258     }
   259     return true;
   259     return true;
   260 }
   260 }
   261 
   261 
   262 static bool saveAvatarData(IItem* contact, const QByteArray& data)
   262 static bool saveThumbnailData(IItem* contact, const QByteArray& data)
   263 {
   263 {
   264     HRESULT   hr;
   264     HRESULT   hr;
   265     SimpleComPointer<IStream>  pStream = NULL;
   265     SimpleComPointer<IStream>  pStream = NULL;
   266 
   266 
   267     hr = contact->OpenProperty(PIMPR_PICTURE, GENERIC_WRITE, &pStream);
   267     hr = contact->OpenProperty(PIMPR_PICTURE, GENERIC_WRITE, &pStream);
   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