diff -r 2b40d63a9c3d -r 90517678cc4f qtmobility/plugins/contacts/qtcontacts-tracker/qtrackercontactsaverequest.cpp --- a/qtmobility/plugins/contacts/qtcontacts-tracker/qtrackercontactsaverequest.cpp Fri Apr 16 15:51:22 2010 +0300 +++ b/qtmobility/plugins/contacts/qtcontacts-tracker/qtrackercontactsaverequest.cpp Mon May 03 13:18:40 2010 +0300 @@ -67,13 +67,15 @@ QMap errors; errors[0] = QContactManager::BadArgumentError; QContactSaveRequest* saveRequest = qobject_cast(req); - QContactManagerEngine::updateContactSaveRequest(saveRequest, contacts, QContactManager::BadArgumentError, - errors); + QContactManagerEngine::updateContactSaveRequest(saveRequest, contacts, QContactManager::BadArgumentError, errors, r->state()); return; } QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::ActiveState); + TrackerChangeListener *changeListener = new TrackerChangeListener(parent, this); + connect(changeListener, SIGNAL(contactsChanged(const QList &)),SLOT(onTrackerSignal(const QList &))); + connect(changeListener, SIGNAL(contactsAdded(const QList &)),SLOT(onTrackerSignal(const QList &))); // Save contacts with batch size /// @todo where to get reasonable batch size @@ -99,6 +101,8 @@ foreach (QContactLocalId id, addedIds) { pendingContactIds.remove(id); + // since if was OK, remove entry for error + errorsOfContactsFinished.remove(id2Index[id]); } if (pendingContactIds.count() == 0) { @@ -112,8 +116,8 @@ break; } } - QContactManagerEngine::updateContactSaveRequest(r, contactsFinished, error, errorsOfContactsFinished); - QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::FinishedState); + + QContactManagerEngine::updateContactSaveRequest(r, contactsFinished, error, errorsOfContactsFinished, QContactAbstractRequest::FinishedState); } } @@ -125,20 +129,21 @@ QSettings definitions(QSettings::IniFormat, QSettings::UserScope, "Nokia", "Trackerplugin"); QTrackerContactsLive cLive; RDFServicePtr service = cLive.service(); - bool isModified = false; foreach(QContact contact, contacts) { +/* + Validation is disabled because it blocks saving contacts parsed from vcards + TODO left the commented code while opaque (custom) details are under discussion as remainder QContactManager::Error error; - - // Ensure that the contact data is ok. This comes from QContactModelEngine if(!engine->validateContact(contact, error)) { contactsFinished << contact; errorsOfContactsFinished[errorCount++] = error; computeProgress(QList()); continue; } - +*/ Live ncoContact; + bool newContact = false; if(contact.localId() == 0) { // Save new contact. compute ID @@ -154,8 +159,8 @@ contact.setId(id); ncoContact->setContactUID(QString::number(m_lastUsedId)); ncoContact->setContentCreated(QDateTime::currentDateTime()); + newContact = true; } else { - isModified = true; ncoContact = service->liveNode(QUrl("contact:"+QString::number(contact.localId()))); /// @note Following needed in case we save new contact with given localId ncoContact->setContactUID(QString::number(contact.localId())); @@ -174,7 +179,7 @@ rdfContact.property() = LiteralValue(QString::number(contact.localId())); addTag(service, rdfContact, "addressbook"); - saveContactDetails( service, ncoContact, contact); + saveContactDetails( service, ncoContact, contact, newContact); // name & nickname - different way from other details cLive.setLiveContact(ncoContact); @@ -183,20 +188,11 @@ cLive.saveName(); } - // TODO add async signal handling of for transaction's commitFinished contactsFinished << contact; - errorsOfContactsFinished[errorCount++] = QContactManager::NoError; // TODO ask how to get error code from tracker + id2Index[contact.localId()] = errorCount; + // we fill error here - once response come that everything is OK, remove entry for this contact + errorsOfContactsFinished[errorCount++] = QContactManager::BadArgumentError; } - - TrackerChangeListener *changeListener = new TrackerChangeListener(this); - if (isModified) { - connect(changeListener, SIGNAL(contactsChanged(const QList &)), - SLOT(onTrackerSignal(const QList &))); - } else { - connect(changeListener, SIGNAL(contactsAdded(const QList &)), - SLOT(onTrackerSignal(const QList &))); - } - // remember to commit the transaction, otherwise all changes will be rolled back. cLive.commit(); } @@ -244,7 +240,8 @@ void QTrackerContactSaveRequest::saveContactDetails( RDFServicePtr service, Live& ncoContact, - const QContact& contact) + const QContact& contact, + bool newContact) { QStringList detailDefinitionsToSave = detailsDefinitionsInContact(contact); @@ -252,8 +249,10 @@ RDFVariable rdfPerson = RDFVariable::fromType(); rdfPerson.property() = LiteralValue(QString::number(contact.localId())); - // Delete all existing phone numbers - office and home - deletePhoneNumbers(service, rdfPerson); + if(not newContact) { + // Delete all existing phone numbers - office and home + deletePhoneNumbers(service, rdfPerson); + } foreach(QString definition, detailDefinitionsToSave) { @@ -268,9 +267,15 @@ QList workDetails; QList homeDetails; foreach(const QContactDetail& det, details) { + // details can be for both contexts, so check for both seperately if( det.contexts().contains(QContactDetail::ContextWork) ) { workDetails << det; - } else { + } + if( det.contexts().contains(QContactDetail::ContextHome)) { + homeDetails << det; + } + if( !det.contexts().contains(QContactDetail::ContextHome) + && !det.contexts().contains(QContactDetail::ContextWork)) { homeDetails << det; } } @@ -278,29 +283,29 @@ /* Save details */ if(definition == QContactPhoneNumber::DefinitionName) { if (!homeDetails.isEmpty()) { - savePhoneNumbers(service, rdfPerson, homeDetails); + savePhoneNumbers(service, rdfPerson, homeDetails, newContact); } if( !workDetails.isEmpty()) { - savePhoneNumbers(service, rdfAffiliation, workDetails); + savePhoneNumbers(service, rdfAffiliation, workDetails, newContact); } } else if(definition == QContactEmailAddress::DefinitionName) { if (!homeDetails.isEmpty()) - saveEmails(service, rdfPerson, homeDetails); + saveEmails(service, rdfPerson, homeDetails, newContact); if( !workDetails.isEmpty()) - saveEmails(service, rdfAffiliation, workDetails); + saveEmails(service, rdfAffiliation, workDetails, newContact); } else if(definition == QContactAddress::DefinitionName) { if (!homeDetails.isEmpty()) - saveAddresses(service, rdfPerson, homeDetails); + saveAddresses(service, rdfPerson, homeDetails, newContact); if( !workDetails.isEmpty()) - saveAddresses(service, rdfAffiliation, workDetails); + saveAddresses(service, rdfAffiliation, workDetails, newContact); } else if(definition == QContactUrl::DefinitionName) { if (!homeDetails.isEmpty()) - saveUrls(service, rdfPerson, homeDetails); + saveUrls(service, rdfPerson, homeDetails, newContact); if( !workDetails.isEmpty()) - saveUrls(service, rdfAffiliation, workDetails); + saveUrls(service, rdfAffiliation, workDetails, newContact); } else { // TODO refactor (bug: editing photo doesn't work) @@ -308,7 +313,7 @@ { definition = det.definitionName(); if(definition == QContactAvatar::DefinitionName) { - QUrl avatar = det.value(QContactAvatar::FieldAvatar); + QUrl avatar = det.value(QContactAvatar::FieldImageUrl); Live fdo = service->liveNode( avatar ); ncoContact->setPhoto(fdo); } @@ -347,7 +352,7 @@ * TODO this is temporary code for creating new, saving contacts need to handle only what was * changed. */ -void QTrackerContactSaveRequest::savePhoneNumbers(RDFServicePtr service, RDFVariable &var, const QList &details ) +void QTrackerContactSaveRequest::savePhoneNumbers(RDFServicePtr service, RDFVariable &var, const QList &details, bool newContact ) { RDFUpdate up; RDFVariable varForInsert = var.deepCopy(); @@ -364,6 +369,9 @@ // using RFC 3966 canonical URI form QUrl newPhone = QString("tel:%1").arg(value); Live ncoPhone = service->liveNode(newPhone); + if(not newContact) { + ncoPhone->remove(); + } QStringList subtypes = det.value(QContactPhoneNumber::FieldSubTypes); @@ -373,7 +381,7 @@ up.addInsertion(newPhone, rdf::type::iri(), nco::CarPhoneNumber::iri()); else if( subtypes.contains(QContactPhoneNumber::SubTypeBulletinBoardSystem)) up.addInsertion(newPhone, rdf::type::iri(), nco::BbsNumber::iri()); - else if( subtypes.contains(QContactPhoneNumber::SubTypeFacsimile)) + else if( subtypes.contains(QContactPhoneNumber::SubTypeFax)) up.addInsertion(newPhone, rdf::type::iri(), nco::FaxNumber::iri()); else if( subtypes.contains(QContactPhoneNumber::SubTypeModem)) up.addInsertion(newPhone, rdf::type::iri(), nco::ModemNumber::iri()); @@ -395,13 +403,15 @@ * TODO this is temporary code for creating new, saving contacts need to handle only what was * changed. */ -void QTrackerContactSaveRequest::saveEmails(RDFServicePtr service, RDFVariable &var, const QList &details ) +void QTrackerContactSaveRequest::saveEmails(RDFServicePtr service, RDFVariable &var, const QList &details, bool newContact ) { RDFUpdate up; RDFVariable varForInsert = var.deepCopy(); RDFVariable emails = var.property(); - // delete previous references - keep email IRIs - up.addDeletion(RDFVariableStatement(var, nco::hasEmailAddress::iri(), emails)); + if(not newContact) { + // delete previous references - keep email IRIs + up.addDeletion(RDFVariableStatement(var, nco::hasEmailAddress::iri(), emails)); + } foreach(const QContactDetail& det, details) { @@ -421,7 +431,7 @@ * TODO this is temporary code for creating new, saving contacts need to handle only what was * changed. */ -void QTrackerContactSaveRequest::saveUrls(RDFServicePtr service, RDFVariable &rdfContact, const QList &details ) +void QTrackerContactSaveRequest::saveUrls(RDFServicePtr service, RDFVariable &rdfContact, const QList &details, bool newContact ) { RDFUpdate up; RDFVariable varForInsert = rdfContact.deepCopy(); @@ -431,9 +441,11 @@ RDFVariable websiteUrls = rdfContact.property(); RDFVariable websiteUrlTypes = websiteUrls.property(); - up.addDeletion(RDFVariableStatement(rdfContact, nco::url::iri(), urls)); - up.addDeletion(RDFVariableStatement(rdfContact, nco::websiteUrl::iri(), websiteUrls)); - // first part - deleting previous before adding new again is to be removed + if(not newContact) { + // first part - deleting previous before adding new again is to be removed + up.addDeletion(RDFVariableStatement(rdfContact, nco::url::iri(), urls)); + up.addDeletion(RDFVariableStatement(rdfContact, nco::websiteUrl::iri(), websiteUrls)); + } // second part, write all urls foreach(const QContactDetail& det, details) @@ -456,14 +468,16 @@ * TODO this is temporary code for creating new, saving contacts need to handle only what was * changed. */ -void QTrackerContactSaveRequest::saveAddresses(RDFServicePtr service, RDFVariable &var, const QList &details ) +void QTrackerContactSaveRequest::saveAddresses(RDFServicePtr service, RDFVariable &var, const QList &details, bool newContact ) { RDFUpdate up; RDFVariable varForInsert = var.deepCopy(); RDFVariable addresses = var.property(); RDFVariable types = addresses.property(); - up.addDeletion(RDFVariableStatement(var, nco::hasPostalAddress::iri(), addresses)); - up.addDeletion(addresses, rdf::type::iri(), types); + if(not newContact) { + up.addDeletion(RDFVariableStatement(var, nco::hasPostalAddress::iri(), addresses)); + up.addDeletion(addresses, rdf::type::iri(), types); + } foreach(const QContactDetail& det, details) { QUrl newPostalAddress = ::tracker()->createLiveNode().uri();