qtmobility/plugins/contacts/qtcontacts-tracker/qtrackercontactsaverequest.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    65 
    65 
    66     if(contacts.isEmpty()) {
    66     if(contacts.isEmpty()) {
    67         QMap<int, QContactManager::Error> errors; 
    67         QMap<int, QContactManager::Error> errors; 
    68         errors[0] = QContactManager::BadArgumentError;
    68         errors[0] = QContactManager::BadArgumentError;
    69         QContactSaveRequest* saveRequest = qobject_cast<QContactSaveRequest*>(req);
    69         QContactSaveRequest* saveRequest = qobject_cast<QContactSaveRequest*>(req);
    70         QContactManagerEngine::updateContactSaveRequest(saveRequest, contacts, QContactManager::BadArgumentError,
    70         QContactManagerEngine::updateContactSaveRequest(saveRequest, contacts, QContactManager::BadArgumentError, errors, r->state());
    71                                              errors);
       
    72         return;
    71         return;
    73     }
    72     }
    74 
    73 
    75     QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::ActiveState);
    74     QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::ActiveState);
    76 
    75 
       
    76     TrackerChangeListener *changeListener = new TrackerChangeListener(parent, this);
       
    77     connect(changeListener, SIGNAL(contactsChanged(const QList<QContactLocalId> &)),SLOT(onTrackerSignal(const QList<QContactLocalId> &)));
       
    78     connect(changeListener, SIGNAL(contactsAdded(const QList<QContactLocalId> &)),SLOT(onTrackerSignal(const QList<QContactLocalId> &)));
    77 
    79 
    78     // Save contacts with batch size
    80     // Save contacts with batch size
    79     /// @todo where to get reasonable batch size
    81     /// @todo where to get reasonable batch size
    80     int batchSize = 100;
    82     int batchSize = 100;
    81     for (int i = 0; i < contacts.size(); i+=batchSize) {
    83     for (int i = 0; i < contacts.size(); i+=batchSize) {
    97         return;
    99         return;
    98     }
   100     }
    99 
   101 
   100     foreach (QContactLocalId id, addedIds) {
   102     foreach (QContactLocalId id, addedIds) {
   101         pendingContactIds.remove(id);
   103         pendingContactIds.remove(id);
       
   104         // since if was OK, remove entry for error
       
   105         errorsOfContactsFinished.remove(id2Index[id]);
   102     }
   106     }
   103 
   107 
   104     if (pendingContactIds.count() == 0) {
   108     if (pendingContactIds.count() == 0) {
   105         // compute master error - part of qtcontacts api
   109         // compute master error - part of qtcontacts api
   106         QContactManager::Error error = QContactManager::NoError;
   110         QContactManager::Error error = QContactManager::NoError;
   110             {
   114             {
   111                 error = err;
   115                 error = err;
   112                 break;
   116                 break;
   113             }
   117             }
   114         }
   118         }
   115         QContactManagerEngine::updateContactSaveRequest(r, contactsFinished, error, errorsOfContactsFinished);
   119 
   116         QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::FinishedState);
   120         QContactManagerEngine::updateContactSaveRequest(r, contactsFinished, error, errorsOfContactsFinished, QContactAbstractRequest::FinishedState);
   117     }
   121     }
   118 }
   122 }
   119 
   123 
   120 void QTrackerContactSaveRequest::saveContacts(const QList<QContact> &contacts)
   124 void QTrackerContactSaveRequest::saveContacts(const QList<QContact> &contacts)
   121 {
   125 {
   123     Q_ASSERT(engine);
   127     Q_ASSERT(engine);
   124 
   128 
   125     QSettings definitions(QSettings::IniFormat, QSettings::UserScope, "Nokia", "Trackerplugin");
   129     QSettings definitions(QSettings::IniFormat, QSettings::UserScope, "Nokia", "Trackerplugin");
   126     QTrackerContactsLive cLive;
   130     QTrackerContactsLive cLive;
   127     RDFServicePtr service = cLive.service();
   131     RDFServicePtr service = cLive.service();
   128     bool isModified = false;
       
   129 
   132 
   130     foreach(QContact contact, contacts) {
   133     foreach(QContact contact, contacts) {
       
   134 /*
       
   135         Validation is disabled because it blocks saving contacts parsed from vcards
       
   136         TODO left the commented code while opaque (custom) details are under discussion as remainder
   131         QContactManager::Error error;
   137         QContactManager::Error error;
   132 
       
   133         // Ensure that the contact data is ok. This comes from QContactModelEngine
       
   134         if(!engine->validateContact(contact, error)) {
   138         if(!engine->validateContact(contact, error)) {
   135             contactsFinished << contact;
   139             contactsFinished << contact;
   136             errorsOfContactsFinished[errorCount++] =  error;
   140             errorsOfContactsFinished[errorCount++] =  error;
   137             computeProgress(QList<QContactLocalId>());
   141             computeProgress(QList<QContactLocalId>());
   138             continue;
   142             continue;
   139         }
   143         }
   140 
   144 */
   141         Live<nco::PersonContact> ncoContact;
   145         Live<nco::PersonContact> ncoContact;
       
   146         bool newContact = false;
   142 
   147 
   143         if(contact.localId() == 0) {
   148         if(contact.localId() == 0) {
   144             // Save new contact. compute ID
   149             // Save new contact. compute ID
   145             bool ok;
   150             bool ok;
   146             // what if both processes read in the same time and write at the same time, no increment
   151             // what if both processes read in the same time and write at the same time, no increment
   152             id.setLocalId(m_lastUsedId);
   157             id.setLocalId(m_lastUsedId);
   153             id.setManagerUri(engine->managerUri());
   158             id.setManagerUri(engine->managerUri());
   154             contact.setId(id);
   159             contact.setId(id);
   155             ncoContact->setContactUID(QString::number(m_lastUsedId));
   160             ncoContact->setContactUID(QString::number(m_lastUsedId));
   156             ncoContact->setContentCreated(QDateTime::currentDateTime());
   161             ncoContact->setContentCreated(QDateTime::currentDateTime());
       
   162             newContact = true;
   157         }  else {
   163         }  else {
   158             isModified = true;
       
   159             ncoContact = service->liveNode(QUrl("contact:"+QString::number(contact.localId())));
   164             ncoContact = service->liveNode(QUrl("contact:"+QString::number(contact.localId())));
   160             /// @note Following needed in case we save new contact with given localId
   165             /// @note Following needed in case we save new contact with given localId
   161             ncoContact->setContactUID(QString::number(contact.localId()));
   166             ncoContact->setContactUID(QString::number(contact.localId()));
   162             ncoContact->setContentLastModified(QDateTime::currentDateTime());
   167             ncoContact->setContentLastModified(QDateTime::currentDateTime());
   163         }
   168         }
   172         // this is important when returning contacts to sync team
   177         // this is important when returning contacts to sync team
   173         RDFVariable rdfContact = RDFVariable::fromType<nco::PersonContact>();
   178         RDFVariable rdfContact = RDFVariable::fromType<nco::PersonContact>();
   174         rdfContact.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   179         rdfContact.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   175         addTag(service, rdfContact, "addressbook");
   180         addTag(service, rdfContact, "addressbook");
   176 
   181 
   177         saveContactDetails( service, ncoContact, contact);
   182         saveContactDetails( service, ncoContact, contact, newContact);
   178 
   183 
   179         // name & nickname - different way from other details
   184         // name & nickname - different way from other details
   180         cLive.setLiveContact(ncoContact);
   185         cLive.setLiveContact(ncoContact);
   181         cLive.setQContact(contact);
   186         cLive.setQContact(contact);
   182         if( !contact.detail<QContactName>().isEmpty() || !contact.detail<QContactNickname>().isEmpty() ) {
   187         if( !contact.detail<QContactName>().isEmpty() || !contact.detail<QContactNickname>().isEmpty() ) {
   183             cLive.saveName();
   188             cLive.saveName();
   184         }
   189         }
   185 
   190 
   186         // TODO add async signal handling of for transaction's commitFinished
       
   187         contactsFinished << contact;
   191         contactsFinished << contact;
   188         errorsOfContactsFinished[errorCount++] =  QContactManager::NoError; // TODO ask how to get error code from tracker
   192         id2Index[contact.localId()] = errorCount;
   189     }
   193         // we fill error here - once response come that everything is OK, remove entry for this contact
   190 
   194         errorsOfContactsFinished[errorCount++] =  QContactManager::BadArgumentError;
   191     TrackerChangeListener *changeListener = new TrackerChangeListener(this);
   195     }
   192     if (isModified) {
       
   193         connect(changeListener, SIGNAL(contactsChanged(const QList<QContactLocalId> &)),
       
   194                 SLOT(onTrackerSignal(const QList<QContactLocalId> &)));
       
   195     } else {
       
   196         connect(changeListener, SIGNAL(contactsAdded(const QList<QContactLocalId> &)),
       
   197                 SLOT(onTrackerSignal(const QList<QContactLocalId> &)));
       
   198     }
       
   199 
       
   200     // remember to commit the transaction, otherwise all changes will be rolled back.
   196     // remember to commit the transaction, otherwise all changes will be rolled back.
   201     cLive.commit();
   197     cLive.commit();
   202 }
   198 }
   203 
   199 
   204 
   200 
   242     ncoContact->setHasAffiliation(ncoAffiliation);
   238     ncoContact->setHasAffiliation(ncoAffiliation);
   243 }
   239 }
   244 
   240 
   245 void QTrackerContactSaveRequest::saveContactDetails( RDFServicePtr service,
   241 void QTrackerContactSaveRequest::saveContactDetails( RDFServicePtr service,
   246                                                 Live<nco::PersonContact>& ncoContact,
   242                                                 Live<nco::PersonContact>& ncoContact,
   247                                                 const QContact& contact)
   243                                                 const QContact& contact,
       
   244                                                 bool newContact)
   248 {
   245 {
   249     QStringList detailDefinitionsToSave = detailsDefinitionsInContact(contact);
   246     QStringList detailDefinitionsToSave = detailsDefinitionsInContact(contact);
   250 
   247 
   251     // all the rest might need to save to PersonContact and to Affiliation contact
   248     // all the rest might need to save to PersonContact and to Affiliation contact
   252     RDFVariable rdfPerson = RDFVariable::fromType<nco::PersonContact>();
   249     RDFVariable rdfPerson = RDFVariable::fromType<nco::PersonContact>();
   253     rdfPerson.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   250     rdfPerson.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   254 
   251 
   255     // Delete all existing phone numbers - office and home
   252     if(not newContact) {
   256     deletePhoneNumbers(service, rdfPerson);
   253         // Delete all existing phone numbers - office and home
       
   254         deletePhoneNumbers(service, rdfPerson);
       
   255     }
   257 
   256 
   258     foreach(QString definition, detailDefinitionsToSave)
   257     foreach(QString definition, detailDefinitionsToSave)
   259     {
   258     {
   260         QList<QContactDetail> details = contact.details(definition);
   259         QList<QContactDetail> details = contact.details(definition);
   261         Q_ASSERT(!details.isEmpty());
   260         Q_ASSERT(!details.isEmpty());
   266         rdfPerson1.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   265         rdfPerson1.property<nco::contactUID>() = LiteralValue(QString::number(contact.localId()));
   267 
   266 
   268         QList<QContactDetail> workDetails;
   267         QList<QContactDetail> workDetails;
   269         QList<QContactDetail> homeDetails;
   268         QList<QContactDetail> homeDetails;
   270         foreach(const QContactDetail& det, details) {
   269         foreach(const QContactDetail& det, details) {
       
   270             // details can be for both contexts, so check for both seperately
   271             if( det.contexts().contains(QContactDetail::ContextWork) ) {
   271             if( det.contexts().contains(QContactDetail::ContextWork) ) {
   272                 workDetails << det;
   272                 workDetails << det;
   273             } else {
   273             }
       
   274             if( det.contexts().contains(QContactDetail::ContextHome)) {
       
   275                 homeDetails << det;
       
   276             }
       
   277             if( !det.contexts().contains(QContactDetail::ContextHome)
       
   278                 && !det.contexts().contains(QContactDetail::ContextWork)) {
   274                 homeDetails << det;
   279                 homeDetails << det;
   275             }
   280             }
   276         }
   281         }
   277 
   282 
   278         /* Save details */
   283         /* Save details */
   279         if(definition == QContactPhoneNumber::DefinitionName) {
   284         if(definition == QContactPhoneNumber::DefinitionName) {
   280             if (!homeDetails.isEmpty()) {
   285             if (!homeDetails.isEmpty()) {
   281                 savePhoneNumbers(service, rdfPerson, homeDetails);
   286                 savePhoneNumbers(service, rdfPerson, homeDetails, newContact);
   282             }
   287             }
   283             if( !workDetails.isEmpty()) {
   288             if( !workDetails.isEmpty()) {
   284                 savePhoneNumbers(service, rdfAffiliation, workDetails);
   289                 savePhoneNumbers(service, rdfAffiliation, workDetails, newContact);
   285             }
   290             }
   286         }
   291         }
   287         else if(definition == QContactEmailAddress::DefinitionName) {
   292         else if(definition == QContactEmailAddress::DefinitionName) {
   288             if (!homeDetails.isEmpty())
   293             if (!homeDetails.isEmpty())
   289                 saveEmails(service, rdfPerson, homeDetails);
   294                 saveEmails(service, rdfPerson, homeDetails, newContact);
   290             if( !workDetails.isEmpty())
   295             if( !workDetails.isEmpty())
   291                 saveEmails(service, rdfAffiliation, workDetails);
   296                 saveEmails(service, rdfAffiliation, workDetails, newContact);
   292         }
   297         }
   293         else if(definition == QContactAddress::DefinitionName) {
   298         else if(definition == QContactAddress::DefinitionName) {
   294             if (!homeDetails.isEmpty())
   299             if (!homeDetails.isEmpty())
   295                 saveAddresses(service, rdfPerson, homeDetails);
   300                 saveAddresses(service, rdfPerson, homeDetails, newContact);
   296             if( !workDetails.isEmpty())
   301             if( !workDetails.isEmpty())
   297                 saveAddresses(service, rdfAffiliation, workDetails);
   302                 saveAddresses(service, rdfAffiliation, workDetails, newContact);
   298         }
   303         }
   299         else if(definition == QContactUrl::DefinitionName) {
   304         else if(definition == QContactUrl::DefinitionName) {
   300             if (!homeDetails.isEmpty())
   305             if (!homeDetails.isEmpty())
   301                 saveUrls(service, rdfPerson, homeDetails);
   306                 saveUrls(service, rdfPerson, homeDetails, newContact);
   302             if( !workDetails.isEmpty())
   307             if( !workDetails.isEmpty())
   303                 saveUrls(service, rdfAffiliation, workDetails);
   308                 saveUrls(service, rdfAffiliation, workDetails, newContact);
   304         }
   309         }
   305         else {
   310         else {
   306             // TODO refactor (bug: editing photo doesn't work)
   311             // TODO refactor (bug: editing photo doesn't work)
   307             foreach(const QContactDetail &det, details )
   312             foreach(const QContactDetail &det, details )
   308             {
   313             {
   309                 definition = det.definitionName();
   314                 definition = det.definitionName();
   310                 if(definition == QContactAvatar::DefinitionName) {
   315                 if(definition == QContactAvatar::DefinitionName) {
   311                     QUrl avatar = det.value(QContactAvatar::FieldAvatar);
   316                     QUrl avatar = det.value(QContactAvatar::FieldImageUrl);
   312                     Live<nie::DataObject> fdo = service->liveNode( avatar );
   317                     Live<nie::DataObject> fdo = service->liveNode( avatar );
   313                     ncoContact->setPhoto(fdo);
   318                     ncoContact->setPhoto(fdo);
   314                 }
   319                 }
   315                 if(definition == QContactBirthday::DefinitionName) {
   320                 if(definition == QContactBirthday::DefinitionName) {
   316                     ncoContact->setBirthDate(QDateTime(det.variantValue(QContactBirthday::FieldBirthday).toDate(), QTime(), Qt::UTC));
   321                     ncoContact->setBirthDate(QDateTime(det.variantValue(QContactBirthday::FieldBirthday).toDate(), QTime(), Qt::UTC));
   345 /*!
   350 /*!
   346  * write all phone numbers on one query to tracker
   351  * write all phone numbers on one query to tracker
   347  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   352  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   348  * changed.
   353  * changed.
   349  */
   354  */
   350 void QTrackerContactSaveRequest::savePhoneNumbers(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details )
   355 void QTrackerContactSaveRequest::savePhoneNumbers(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details, bool newContact )
   351 {
   356 {
   352     RDFUpdate up;
   357     RDFUpdate up;
   353     RDFVariable varForInsert = var.deepCopy();
   358     RDFVariable varForInsert = var.deepCopy();
   354     foreach(const QContactDetail& det, details)
   359     foreach(const QContactDetail& det, details)
   355     {
   360     {
   362                                                         " ]"), "");
   367                                                         " ]"), "");
   363         // Temporary, because affiliation is still used - to be refactored next week to use Live nodes
   368         // Temporary, because affiliation is still used - to be refactored next week to use Live nodes
   364         // using RFC 3966 canonical URI form
   369         // using RFC 3966 canonical URI form
   365         QUrl newPhone = QString("tel:%1").arg(value);
   370         QUrl newPhone = QString("tel:%1").arg(value);
   366         Live<nco::PhoneNumber> ncoPhone = service->liveNode(newPhone);
   371         Live<nco::PhoneNumber> ncoPhone = service->liveNode(newPhone);
       
   372         if(not newContact) {
       
   373             ncoPhone->remove();
       
   374         }
   367 
   375 
   368         QStringList subtypes = det.value<QStringList>(QContactPhoneNumber::FieldSubTypes);
   376         QStringList subtypes = det.value<QStringList>(QContactPhoneNumber::FieldSubTypes);
   369 
   377 
   370         if( subtypes.contains(QContactPhoneNumber::SubTypeMobile))
   378         if( subtypes.contains(QContactPhoneNumber::SubTypeMobile))
   371             up.addInsertion(newPhone, rdf::type::iri(), nco::CellPhoneNumber::iri());
   379             up.addInsertion(newPhone, rdf::type::iri(), nco::CellPhoneNumber::iri());
   372         else if( subtypes.contains(QContactPhoneNumber::SubTypeCar))
   380         else if( subtypes.contains(QContactPhoneNumber::SubTypeCar))
   373             up.addInsertion(newPhone, rdf::type::iri(), nco::CarPhoneNumber::iri());
   381             up.addInsertion(newPhone, rdf::type::iri(), nco::CarPhoneNumber::iri());
   374         else if( subtypes.contains(QContactPhoneNumber::SubTypeBulletinBoardSystem))
   382         else if( subtypes.contains(QContactPhoneNumber::SubTypeBulletinBoardSystem))
   375             up.addInsertion(newPhone, rdf::type::iri(), nco::BbsNumber::iri());
   383             up.addInsertion(newPhone, rdf::type::iri(), nco::BbsNumber::iri());
   376         else if( subtypes.contains(QContactPhoneNumber::SubTypeFacsimile))
   384         else if( subtypes.contains(QContactPhoneNumber::SubTypeFax))
   377             up.addInsertion(newPhone, rdf::type::iri(), nco::FaxNumber::iri());
   385             up.addInsertion(newPhone, rdf::type::iri(), nco::FaxNumber::iri());
   378         else if( subtypes.contains(QContactPhoneNumber::SubTypeModem))
   386         else if( subtypes.contains(QContactPhoneNumber::SubTypeModem))
   379             up.addInsertion(newPhone, rdf::type::iri(), nco::ModemNumber::iri());
   387             up.addInsertion(newPhone, rdf::type::iri(), nco::ModemNumber::iri());
   380         else if( subtypes.contains(QContactPhoneNumber::SubTypePager))
   388         else if( subtypes.contains(QContactPhoneNumber::SubTypePager))
   381             up.addInsertion(newPhone, rdf::type::iri(), nco::PagerNumber::iri());
   389             up.addInsertion(newPhone, rdf::type::iri(), nco::PagerNumber::iri());
   393 /*!
   401 /*!
   394  * write all phone numbers on one query to tracker
   402  * write all phone numbers on one query to tracker
   395  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   403  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   396  * changed.
   404  * changed.
   397  */
   405  */
   398 void QTrackerContactSaveRequest::saveEmails(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details )
   406 void QTrackerContactSaveRequest::saveEmails(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details, bool newContact )
   399 {
   407 {
   400     RDFUpdate up;
   408     RDFUpdate up;
   401     RDFVariable varForInsert = var.deepCopy();
   409     RDFVariable varForInsert = var.deepCopy();
   402     RDFVariable emails = var.property<nco::hasEmailAddress>();
   410     RDFVariable emails = var.property<nco::hasEmailAddress>();
   403     // delete previous references - keep email IRIs
   411     if(not newContact) {
   404     up.addDeletion(RDFVariableStatement(var, nco::hasEmailAddress::iri(), emails));
   412         // delete previous references - keep email IRIs
       
   413         up.addDeletion(RDFVariableStatement(var, nco::hasEmailAddress::iri(), emails));
       
   414     }
   405 
   415 
   406     foreach(const QContactDetail& det, details)
   416     foreach(const QContactDetail& det, details)
   407     {
   417     {
   408         QString value = det.value(QContactEmailAddress::FieldEmailAddress);
   418         QString value = det.value(QContactEmailAddress::FieldEmailAddress);
   409         // Temporary, because affiliation is still used - to be refactored next week to use only Live nodes
   419         // Temporary, because affiliation is still used - to be refactored next week to use only Live nodes
   419 /*!
   429 /*!
   420  * write all Urls
   430  * write all Urls
   421  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   431  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   422  * changed.
   432  * changed.
   423  */
   433  */
   424 void QTrackerContactSaveRequest::saveUrls(RDFServicePtr service, RDFVariable &rdfContact, const QList<QContactDetail> &details )
   434 void QTrackerContactSaveRequest::saveUrls(RDFServicePtr service, RDFVariable &rdfContact, const QList<QContactDetail> &details, bool newContact )
   425 {
   435 {
   426     RDFUpdate up;
   436     RDFUpdate up;
   427     RDFVariable varForInsert = rdfContact.deepCopy();
   437     RDFVariable varForInsert = rdfContact.deepCopy();
   428     RDFVariable urls = rdfContact.property<nco::url>();
   438     RDFVariable urls = rdfContact.property<nco::url>();
   429     RDFVariable urltypes = urls.property<rdf::type>();
   439     RDFVariable urltypes = urls.property<rdf::type>();
   430 
   440 
   431     RDFVariable websiteUrls = rdfContact.property<nco::websiteUrl>();
   441     RDFVariable websiteUrls = rdfContact.property<nco::websiteUrl>();
   432     RDFVariable websiteUrlTypes = websiteUrls.property<rdf::type>();
   442     RDFVariable websiteUrlTypes = websiteUrls.property<rdf::type>();
   433 
   443 
   434     up.addDeletion(RDFVariableStatement(rdfContact, nco::url::iri(), urls));
   444     if(not newContact) {
   435     up.addDeletion(RDFVariableStatement(rdfContact, nco::websiteUrl::iri(), websiteUrls));
   445         // first part - deleting previous before adding new again is to be removed
   436     // first part - deleting previous before adding new again is to be removed
   446         up.addDeletion(RDFVariableStatement(rdfContact, nco::url::iri(), urls));
       
   447         up.addDeletion(RDFVariableStatement(rdfContact, nco::websiteUrl::iri(), websiteUrls));
       
   448     }
   437 
   449 
   438     // second part, write all urls
   450     // second part, write all urls
   439     foreach(const QContactDetail& det, details)
   451     foreach(const QContactDetail& det, details)
   440     {
   452     {
   441         QUrl newUrl(det.value(QContactUrl::FieldUrl));//::tracker()->createLiveNode().uri();
   453         QUrl newUrl(det.value(QContactUrl::FieldUrl));//::tracker()->createLiveNode().uri();
   454 /*!
   466 /*!
   455  * write all phone numbers on one query to tracker
   467  * write all phone numbers on one query to tracker
   456  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   468  * TODO this is temporary code for creating new, saving contacts need to handle only what was
   457  * changed.
   469  * changed.
   458  */
   470  */
   459 void QTrackerContactSaveRequest::saveAddresses(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details )
   471 void QTrackerContactSaveRequest::saveAddresses(RDFServicePtr service, RDFVariable &var, const QList<QContactDetail> &details, bool newContact )
   460 {
   472 {
   461     RDFUpdate up;
   473     RDFUpdate up;
   462     RDFVariable varForInsert = var.deepCopy();
   474     RDFVariable varForInsert = var.deepCopy();
   463     RDFVariable addresses = var.property<nco::hasPostalAddress>();
   475     RDFVariable addresses = var.property<nco::hasPostalAddress>();
   464     RDFVariable types = addresses.property<rdf::type>();
   476     RDFVariable types = addresses.property<rdf::type>();
   465     up.addDeletion(RDFVariableStatement(var, nco::hasPostalAddress::iri(), addresses));
   477     if(not newContact) {
   466     up.addDeletion(addresses, rdf::type::iri(), types);
   478         up.addDeletion(RDFVariableStatement(var, nco::hasPostalAddress::iri(), addresses));
       
   479         up.addDeletion(addresses, rdf::type::iri(), types);
       
   480     }
   467     foreach(const QContactDetail& det, details)
   481     foreach(const QContactDetail& det, details)
   468     {
   482     {
   469         QUrl newPostalAddress = ::tracker()->createLiveNode().uri();
   483         QUrl newPostalAddress = ::tracker()->createLiveNode().uri();
   470         // TODO     nco:DomesticDeliveryAddress, nco:InternationalDeliveryAddress, nco:ParcelDeliveryAddress
   484         // TODO     nco:DomesticDeliveryAddress, nco:InternationalDeliveryAddress, nco:ParcelDeliveryAddress
   471         up.addInsertion(newPostalAddress, rdf::type::iri(), nco::PostalAddress::iri());
   485         up.addInsertion(newPostalAddress, rdf::type::iri(), nco::PostalAddress::iri());