qtmobility/plugins/contacts/symbian/src/cntsymbianengine.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    72 #if QT_VERSION < QT_VERSION_CHECK(4, 6, 0)
    72 #if QT_VERSION < QT_VERSION_CHECK(4, 6, 0)
    73 #define QT_TRAP_THROWING QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION
    73 #define QT_TRAP_THROWING QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION
    74 #define QT_TRYCATCH_LEAVING QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE
    74 #define QT_TRYCATCH_LEAVING QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE
    75 #endif
    75 #endif
    76 
    76 
    77 CntSymbianEngine::CntSymbianEngine(const QMap<QString, QString>& parameters, QContactManager::Error& error)
    77 CntSymbianEngine::CntSymbianEngine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
    78 {
    78 {
    79     error = QContactManager::NoError;
    79     *error = QContactManager::NoError;
    80 
    80 
    81     m_dataBase = new CntSymbianDatabase(this, error);
    81     m_dataBase = new CntSymbianDatabase(this, error);
    82 
    82 
    83     //Database opened successfully
    83     //Database opened successfully
    84     if(error == QContactManager::NoError) {
    84     if(*error == QContactManager::NoError) {
    85         m_managerUri = QContactManager::buildUri(CNT_SYMBIAN_MANAGER_NAME, parameters);
    85         m_managerUri = QContactManager::buildUri(CNT_SYMBIAN_MANAGER_NAME, parameters);
    86         m_transformContact = new CntTransformContact;
    86         m_transformContact = new CntTransformContact;
    87 #ifdef SYMBIAN_BACKEND_USE_SQLITE
    87 #ifdef SYMBIAN_BACKEND_USE_SQLITE
    88         m_contactFilter    = new CntSymbianFilter(*this, *m_dataBase->contactDatabase(), *m_transformContact);
    88         m_contactFilter    = new CntSymbianFilter(*this, *m_dataBase->contactDatabase(), *m_transformContact);
    89 #else
    89 #else
   115     delete m_contactSorter;
   115     delete m_contactSorter;
   116     delete m_relationship;
   116     delete m_relationship;
   117     delete m_displayLabel;
   117     delete m_displayLabel;
   118 }
   118 }
   119 
   119 
   120 void CntSymbianEngine::deref()
       
   121 {
       
   122     delete this;
       
   123 }
       
   124 
       
   125 /*!
   120 /*!
   126  * Returns a list of the ids of contacts that match the supplied \a filter, sorted according to the given \a sortOrders.
   121  * Returns a list of the ids of contacts that match the supplied \a filter, sorted according to the given \a sortOrders.
   127  * Any error that occurs will be stored in \a error. Uses either the Symbian backend native filtering or in case of an
   122  * Any error that occurs will be stored in \a error. Uses either the Symbian backend native filtering or in case of an
   128  * unsupported filter, the generic (slow) filtering of QContactManagerEngine.
   123  * unsupported filter, the generic (slow) filtering of QContactManagerEngine.
   129  */
   124  */
   130 QList<QContactLocalId> CntSymbianEngine::contactIds(
   125 QList<QContactLocalId> CntSymbianEngine::contactIds(
   131         const QContactFilter& filter,
   126         const QContactFilter& filter,
   132         const QList<QContactSortOrder>& sortOrders,
   127         const QList<QContactSortOrder>& sortOrders,
   133         QContactManager::Error& error) const
   128         QContactManager::Error* error) const
   134 {
   129 {
   135     error = QContactManager::NoError;
   130     *error = QContactManager::NoError;
   136     QList<QContactLocalId> result;
   131     QList<QContactLocalId> result;
   137     
   132     
   138     
   133     
   139     if (filter.type() == QContactFilter::RelationshipFilter)
   134     if (filter.type() == QContactFilter::RelationshipFilter)
   140     {
   135     {
   141         QContactRelationshipFilter rf = static_cast<QContactRelationshipFilter>(filter);
   136         QContactRelationshipFilter rf = static_cast<QContactRelationshipFilter>(filter);
       
   137         // XXX enum changed classes - engine API will reflect this eventually
   142         QList<QContactRelationship> relationshipsList = relationships(
   138         QList<QContactRelationship> relationshipsList = relationships(
   143             rf.relationshipType(), rf.relatedContactId(), rf.relatedContactRole(), error);
   139             rf.relationshipType(), rf.relatedContactId(), rf.relatedContactRole(), error);
   144         if(error == QContactManager::NoError) {
   140         if(*error == QContactManager::NoError) {
   145             foreach(QContactRelationship r, relationshipsList) {
   141             foreach(const QContactRelationship& r, relationshipsList) {
   146                 if(rf.relatedContactRole() == QContactRelationshipFilter::First) {
   142                 if(rf.relatedContactRole() == QContactRelationship::First) {
   147                     result += r.second().localId();
   143                     result += r.second().localId();
   148                 } else if (rf.relatedContactRole() == QContactRelationshipFilter::Second) {
   144                 } else if (rf.relatedContactRole() == QContactRelationship::Second) {
   149                     result += r.first().localId();
   145                     result += r.first().localId();
   150                 } else if (rf.relatedContactRole() == QContactRelationshipFilter::Either) {
   146                 } else if (rf.relatedContactRole() == QContactRelationship::Either) {
   151                     result += r.first().localId();
   147                     result += r.first().localId();
   152                     result += r.second().localId();
   148                     result += r.second().localId();
   153                 }
   149                 }
   154             }
   150             }
       
   151             
       
   152             //slow sorting until it's supported in SQL requests
       
   153             result = slowSort(result, sortOrders, error);
   155         }
   154         }
   156     }
   155     }
   157     else
   156     else
   158     {
   157     {
   159         bool filterSupported(true);
   158         bool filterSupported(true);
   160         result = m_contactFilter->contacts(filter, sortOrders, filterSupported, error);
   159         result = m_contactFilter->contacts(filter, sortOrders, filterSupported, error);
   161         
       
   162         //slow sorting until it's supported in SQL requests
       
   163         result = slowSort(result, sortOrders, error);
       
   164             
   160             
   165 #ifdef SYMBIAN_BACKEND_USE_SQLITE
   161 #ifdef SYMBIAN_BACKEND_USE_SQLITE
   166     
   162     
   167         // Remove possible false positives
   163         // Remove possible false positives
   168         if(!filterSupported && error == QContactManager::NotSupportedError)
   164         if(!filterSupported && *error == QContactManager::NotSupportedError)
       
   165             {
   169             result = slowFilter(filter, result, error);
   166             result = slowFilter(filter, result, error);
   170 
   167             
       
   168             //slow sorting until it's supported in SQL requests
       
   169             result = slowSort(result, sortOrders, error);
       
   170             }
       
   171         
   171 #else
   172 #else
   172         // Remove possible false positives
   173         // Remove possible false positives
   173         if(!filterSupported && error == QContactManager::NoError)
   174         if(!filterSupported && *error == QContactManager::NoError)
   174             result = slowFilter(filter, result, error);
   175             result = slowFilter(filter, result, error);
   175         
   176         
   176         // Sort the matching contacts
   177         // Sort the matching contacts
   177         if(!sortOrders.isEmpty()&& error == QContactManager::NoError ) {
   178         if(!sortOrders.isEmpty()&& *error == QContactManager::NoError ) {
   178             if(m_contactSorter->sortOrderSupported(sortOrders)) {
   179             if(m_contactSorter->sortOrderSupported(sortOrders)) {
   179                 result = m_contactSorter->sort(result, sortOrders, error);
   180                 result = m_contactSorter->sort(result, sortOrders, error);
   180             } else {
   181             } else {
   181                 result = slowSort(result, sortOrders, error);
   182                 result = slowSort(result, sortOrders, error);
   182             }
   183             }
   184 #endif
   185 #endif
   185     }
   186     }
   186     return result;
   187     return result;
   187 }
   188 }
   188 
   189 
   189 QList<QContactLocalId> CntSymbianEngine::contactIds(const QList<QContactSortOrder>& sortOrders, QContactManager::Error& error) const
   190 #if 0
       
   191 // These functions are not used anymore - there is always a filter (which may be the default filter)
       
   192 QList<QContactLocalId> CntSymbianEngine::contactIds(const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const
   190 {
   193 {
   191     // Check if sorting is supported by backend
   194     // Check if sorting is supported by backend
   192     if(m_contactSorter->sortOrderSupported(sortOrders))
   195     if(m_contactSorter->sortOrderSupported(sortOrders))
   193         return m_contactSorter->contacts(sortOrders,error);
   196         return m_contactSorter->contacts(sortOrders,error);
   194 
   197 
   196     // Fall back to slow QContact-level sorting method.
   199     // Fall back to slow QContact-level sorting method.
   197 
   200 
   198     // Get unsorted contact ids
   201     // Get unsorted contact ids
   199     QList<QContactSortOrder> noSortOrders;
   202     QList<QContactSortOrder> noSortOrders;
   200     QList<QContactLocalId> unsortedIds = m_contactSorter->contacts(noSortOrders, error);
   203     QList<QContactLocalId> unsortedIds = m_contactSorter->contacts(noSortOrders, error);
   201     if (error != QContactManager::NoError)
   204     if (*error != QContactManager::NoError)
   202         return QList<QContactLocalId>();
   205         return QList<QContactLocalId>();
   203 
   206 
   204     // Sort contacts
   207     // Sort contacts
   205     return slowSort(unsortedIds, sortOrders, error);
   208     return slowSort(unsortedIds, sortOrders, error);
   206 }
   209 }
   207 
   210 
   208 QList<QContact> CntSymbianEngine::contacts(const QList<QContactSortOrder>& sortOrders, const QStringList& definitionRestrictions, QContactManager::Error& error) const
   211 QList<QContact> CntSymbianEngine::contacts(const QList<QContactSortOrder>& sortOrders, const QStringList& definitionRestrictions, QContactManager::Error* error) const
   209 {
   212 {
   210     error = QContactManager::NoError;
   213     *error = QContactManager::NoError;
   211     QList<QContact> contacts;
   214     QList<QContact> contacts;
   212     QList<QContactLocalId> contactIds = this->contactIds(sortOrders, error);
   215     QList<QContactLocalId> contactIds = this->contactIds(sortOrders, error);
   213     if (error == QContactManager::NoError ) {
   216     if (*error == QContactManager::NoError ) {
   214         foreach (QContactLocalId id, contactIds) {
   217         foreach (QContactLocalId id, contactIds) {
   215             QContact contact = this->contact(id, definitionRestrictions, error);
   218             QContact contact = this->contact(id, definitionRestrictions, error);
   216             if (error != QContactManager::NoError) {
   219             if (*error != QContactManager::NoError) {
   217                 return QList<QContact>(); // return empty list if error occurred
   220                 return QList<QContact>(); // return empty list if error occurred
   218             }
   221             }
   219             contacts.append(contact);
   222             contacts.append(contact);
   220         }
   223         }
   221     }
   224     }
   222     return contacts;
   225     return contacts;
   223 }
   226 }
   224 
   227 #endif
   225 QList<QContact> CntSymbianEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QStringList& definitionRestrictions, QContactManager::Error& error) const
   228 
   226 {
   229 QList<QContact> CntSymbianEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fh, QContactManager::Error* error) const
   227     error = QContactManager::NoError;
   230 {
       
   231     *error = QContactManager::NoError;
   228     QList<QContact> contacts;
   232     QList<QContact> contacts;
   229     QList<QContactLocalId> contactIds = this->contactIds(filter, sortOrders, error);
   233     QList<QContactLocalId> contactIds = this->contactIds(filter, sortOrders, error);
   230     if (error == QContactManager::NoError ) {
   234     if (*error == QContactManager::NoError ) {
   231         foreach (QContactLocalId id, contactIds) {
   235         foreach (QContactLocalId id, contactIds) {
   232             QContact contact = this->contact(id, definitionRestrictions, error);
   236             QContact contact = this->contact(id, fh, error);
   233             if (error != QContactManager::NoError) {
   237             if (*error != QContactManager::NoError) {
   234                 return QList<QContact>(); // return empty list if error occurred
   238                 return QList<QContact>(); // return empty list if error occurred
   235             }
   239             }
   236             contacts.append(contact);
   240             contacts.append(contact);
   237         }
   241         }
   238     }
   242     }
   245  * \param contactId The Id of the contact to be retrieved.
   249  * \param contactId The Id of the contact to be retrieved.
   246  * \param error Qt error code.
   250  * \param error Qt error code.
   247  * \return A QContact for the requested QContactLocalId value or 0 if the read
   251  * \return A QContact for the requested QContactLocalId value or 0 if the read
   248  *  operation was unsuccessful (e.g. contact not found).
   252  *  operation was unsuccessful (e.g. contact not found).
   249  */
   253  */
   250 QContact CntSymbianEngine::contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions, QContactManager::Error& error) const
   254 QContact CntSymbianEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
   251 {
   255 {
   252     QContact* contact = new QContact();
   256     QContact* contact = new QContact();
   253     TRAPD(err, *contact = fetchContactL(contactId, definitionRestrictions));
   257     TRAPD(err, *contact = fetchContactL(contactId, fetchHint.detailDefinitionsHint()));
   254     CntSymbianTransformError::transformError(err, error);
   258     CntSymbianTransformError::transformError(err, error);
   255 
   259 
   256     if(error == QContactManager::NoError) { 
   260     if(*error == QContactManager::NoError) {
   257         updateDisplayLabel(*contact);
   261         updateDisplayLabel(*contact);
   258         //check relationship only if there are no definition restrictions, otherwise
   262         //check relationship only if there are no definition restrictions, otherwise
   259         //skip this time expensive operation.       
   263         //skip this time expensive operation.       
   260         if( definitionRestrictions.isEmpty()) {
   264         if( (!fetchHint.optimizationHints() & QContactFetchHint::NoRelationships)) {
   261             QContactManager::Error relationshipError;
   265             QContactManager::Error relationshipError;
   262             QList<QContactRelationship> relationships = this->relationships(QString(), contact->id(), QContactRelationshipFilter::Either, relationshipError);
   266             // XXX can also consult fetchHint.relationships list
       
   267             QList<QContactRelationship> relationships = this->relationships(QString(), contact->id(), QContactRelationship::Either, &relationshipError);
   263             if (relationshipError != QContactManager::NoError &&
   268             if (relationshipError != QContactManager::NoError &&
   264                 relationshipError != QContactManager::DoesNotExistError) { // means that no relationships found
   269                 relationshipError != QContactManager::DoesNotExistError) { // means that no relationships found
   265                 error = relationshipError;
   270                 *error = relationshipError;
   266             }
   271             }
   267             QContactManagerEngine::setContactRelationships(contact, relationships);
   272             QContactManagerEngine::setContactRelationships(contact, relationships);
   268         }
   273         }
   269     }
   274     }
   270     return *QScopedPointer<QContact>(contact);
   275     return *QScopedPointer<QContact>(contact);
   271 }
   276 }
   272 
   277 
   273 bool CntSymbianEngine::saveContact(QContact* contact, QContactManager::Error& error)
   278 bool CntSymbianEngine::saveContact(QContact* contact, QContactManager::Error* error)
   274 {
   279 {
   275     QContactChangeSet changeSet;
   280     QContactChangeSet changeSet;
   276     TBool ret = doSaveContact(contact, changeSet, error);
   281     TBool ret = doSaveContact(contact, changeSet, error);
   277     changeSet.emitSignals(this);
   282     changeSet.emitSignals(this);
   278     return ret;
   283     return ret;
   279 }
   284 }
   280 
   285 
   281 /*! \reimp */
   286 /*! \reimp */
   282 bool CntSymbianEngine::saveContacts(QList<QContact> *contacts, QMap<int, QContactManager::Error> *errorMap, QContactManager::Error& error)
   287 bool CntSymbianEngine::saveContacts(QList<QContact> *contacts, QMap<int, QContactManager::Error> *errorMap, QContactManager::Error* error)
   283 {
   288 {
   284     error = QContactManager::NoError;
   289     *error = QContactManager::NoError;
   285     
   290     
   286     if (errorMap) {
   291     if (errorMap) {
   287         // if the errormap argument is null, we just don't do fine-grained reporting.            
   292         // if the errormap argument is null, we just don't do fine-grained reporting.            
   288         errorMap->clear();
   293         errorMap->clear();
   289     }    
   294     }    
   290     
   295     
   291     if (!contacts) {
   296     if (!contacts) {
   292         error = QContactManager::BadArgumentError;
   297         *error = QContactManager::BadArgumentError;
   293         return false;
   298         return false;
   294     }
   299     }
   295 
   300 
   296     QContactChangeSet changeSet;
   301     QContactChangeSet changeSet;
   297     for (int i = 0; i < contacts->count(); i++) {
   302     for (int i = 0; i < contacts->count(); i++) {
   298         QContact current = contacts->at(i);
   303         QContact current = contacts->at(i);
   299         QContactManager::Error functionError = QContactManager::NoError;
   304         QContactManager::Error functionError = QContactManager::NoError;
   300         if (!doSaveContact(&current, changeSet, functionError)) {
   305         if (!doSaveContact(&current, changeSet, &functionError)) {
   301             error = functionError;
   306             *error = functionError;
   302             if (errorMap) {
   307             if (errorMap) {
   303                 errorMap->insert(i, functionError);
   308                 errorMap->insert(i, functionError);
   304             }
   309             }
   305         } else {
   310         } else {
   306             (*contacts)[i] = current;
   311             (*contacts)[i] = current;
   307         }
   312         }
   308     }
   313     }
   309     changeSet.emitSignals(this);
   314     changeSet.emitSignals(this);
   310     return (error == QContactManager::NoError);
   315     return (*error == QContactManager::NoError);
   311 }
   316 }
   312 
   317 
   313 /*!
   318 /*!
   314  * Uses the generic filtering implementation of QContactManagerEngine to filter
   319  * Uses the generic filtering implementation of QContactManagerEngine to filter
   315  * contacts one-by-one. Really slow when filtering a lot of contacts because
   320  * contacts one-by-one. Really slow when filtering a lot of contacts because
   316  * every contact needs to be loaded from the database before filtering.
   321  * every contact needs to be loaded from the database before filtering.
   317  */
   322  */
   318 QList<QContactLocalId> CntSymbianEngine::slowFilter(
   323 QList<QContactLocalId> CntSymbianEngine::slowFilter(
   319         const QContactFilter& filter,
   324         const QContactFilter& filter,
   320         const QList<QContactLocalId>& contacts,
   325         const QList<QContactLocalId>& contacts,
   321         QContactManager::Error& error
   326         QContactManager::Error* error
   322         ) const
   327         ) const
   323 {
   328 {
   324     QList<QContactLocalId> result;
   329     QList<QContactLocalId> result;
   325     for (int i(0); i < contacts.count(); i++) {
   330     for (int i(0); i < contacts.count(); i++) {
   326         QContactLocalId id = contacts.at(i);
   331         QContactLocalId id = contacts.at(i);
   327 
   332 
   328         // Check if this is a false positive. If not, add to the result set.
   333         // Check if this is a false positive. If not, add to the result set.
   329         if(QContactManagerEngine::testFilter(filter, contact(id, QStringList(), error)))
   334         if(QContactManagerEngine::testFilter(filter, contact(id, QContactFetchHint(), error)))
   330             result << id;
   335             result << id;
   331     }
   336     }
   332     return result;
   337     return result;
   333 }
   338 }
   334 
   339 
   335 QList<QContactLocalId> CntSymbianEngine::slowSort(
   340 QList<QContactLocalId> CntSymbianEngine::slowSort(
   336         const QList<QContactLocalId>& contactIds,
   341         const QList<QContactLocalId>& contactIds,
   337         const QList<QContactSortOrder>& sortOrders,
   342         const QList<QContactSortOrder>& sortOrders,
   338         QContactManager::Error& error) const
   343         QContactManager::Error* error) const
   339 {
   344 {
   340     // Get unsorted contacts
   345     // Get unsorted contacts
   341     QList<QContact> unsortedContacts;
   346     QList<QContact> unsortedContacts;
   342     foreach (QContactLocalId id, contactIds) {
   347     foreach (QContactLocalId id, contactIds) {
   343         QContact c = contact(id, QStringList(), error);
   348         QContact c = contact(id, QContactFetchHint(), error);
   344         if (error != QContactManager::NoError)
   349         if (*error != QContactManager::NoError)
   345             return QList<QContactLocalId>();
   350             return QList<QContactLocalId>();
   346         unsortedContacts << c;
   351         unsortedContacts << c;
   347     }
   352     }
   348     return QContactManagerEngine::sortContacts(unsortedContacts, sortOrders);
   353     return QContactManagerEngine::sortContacts(unsortedContacts, sortOrders);
   349 }
   354 }
   350 
   355 
   351 bool CntSymbianEngine::doSaveContact(QContact* contact, QContactChangeSet& changeSet, QContactManager::Error& error)
   356 bool CntSymbianEngine::doSaveContact(QContact* contact, QContactChangeSet& changeSet, QContactManager::Error* error)
   352 {
   357 {
   353     bool ret = false;
   358     bool ret = false;
   354     if(contact && !validateContact(*contact, error))
   359     if(contact && !validateContact(*contact, error))
   355         return false;
   360         return false;
   356 
   361 
   362         QContactGuid guidDetail = static_cast<QContactGuid>(contact->details(QContactGuid::DefinitionName).at(0));
   367         QContactGuid guidDetail = static_cast<QContactGuid>(contact->details(QContactGuid::DefinitionName).at(0));
   363         guidFilter.setValue(guidDetail.guid());
   368         guidFilter.setValue(guidDetail.guid());
   364 
   369 
   365         QContactManager::Error err;
   370         QContactManager::Error err;
   366         QList<QContactLocalId> localIdList = contactIds(guidFilter,
   371         QList<QContactLocalId> localIdList = contactIds(guidFilter,
   367                 QList<QContactSortOrder>(), err);
   372                 QList<QContactSortOrder>(), &err);
   368         if (err == QContactManager::NoError && localIdList.count() > 0) {
   373         if (err == QContactManager::NoError && localIdList.count() > 0) {
   369             QScopedPointer<QContactId> contactId(new QContactId());
   374             QScopedPointer<QContactId> contactId(new QContactId());
   370             contactId->setLocalId(localIdList.at(0));
   375             contactId->setLocalId(localIdList.at(0));
   371             contactId->setManagerUri(m_managerUri);
   376             contactId->setManagerUri(m_managerUri);
   372             contact->setId(*contactId);
   377             contact->setId(*contactId);
   373         }
   378         }
   374     }
   379     }
   375 
   380 
   376     // Check parameters
   381     // Check parameters
   377     if(!contact) {
   382     if(!contact) {
   378         error = QContactManager::BadArgumentError;
   383         *error = QContactManager::BadArgumentError;
   379         ret = false;
   384         ret = false;
   380     // Update an existing contact
   385     // Update an existing contact
   381     } else if(contact->localId()) {
   386     } else if(contact->localId()) {
   382         if(contact->id().managerUri() == m_managerUri) {
   387         if(contact->id().managerUri() == m_managerUri) {
   383             ret = updateContact(*contact, changeSet, error);
   388             ret = updateContact(*contact, changeSet, error);
   384         } else {
   389         } else {
   385             error = QContactManager::BadArgumentError;
   390             *error = QContactManager::BadArgumentError;
   386             ret = false;
   391             ret = false;
   387         }
   392         }
   388     // Create new contact
   393     // Create new contact
   389     } else {
   394     } else {
   390         ret = addContact(*contact, changeSet, error);
   395         ret = addContact(*contact, changeSet, error);
   428  * \param contact The QContact to be saved.
   433  * \param contact The QContact to be saved.
   429  * \param id The Id of new contact
   434  * \param id The Id of new contact
   430  * \param qtError Qt error code.
   435  * \param qtError Qt error code.
   431  * \return Error status
   436  * \return Error status
   432  */
   437  */
   433 bool CntSymbianEngine::addContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error& qtError)
   438 bool CntSymbianEngine::addContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   434 {
   439 {
   435     // Attempt to persist contact, trapping errors
   440     // Attempt to persist contact, trapping errors
   436     int err(0);
   441     int err(0);
   437     QContactLocalId id(0);
   442     QContactLocalId id(0);
   438     TRAP(err, id = addContactL(contact));
   443     TRAP(err, id = addContactL(contact));
   439     if(err == KErrNone)
   444     if(err == KErrNone)
   440     {
   445     {
   441         changeSet.addedContacts().insert(id);
   446         changeSet.insertAddedContact(id);
   442         m_dataBase->appendContactEmitted(id);
   447         m_dataBase->appendContactEmitted(id);
   443     }
   448     }
   444     CntSymbianTransformError::transformError(err, qtError);
   449     CntSymbianTransformError::transformError(err, qtError);
   445 
   450 
   446     return (err==KErrNone);
   451     return (err==KErrNone);
   507  *
   512  *
   508  * \param contact The contact to update in the database.
   513  * \param contact The contact to update in the database.
   509  * \param qtError Qt error code.
   514  * \param qtError Qt error code.
   510  * \return Error status.
   515  * \return Error status.
   511  */
   516  */
   512 bool CntSymbianEngine::updateContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error& qtError)
   517 bool CntSymbianEngine::updateContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   513 {
   518 {
   514     int err(0);
   519     int err(0);
   515     TRAP(err, updateContactL(contact));
   520     TRAP(err, updateContactL(contact));
   516     if(err == KErrNone)
   521     if(err == KErrNone)
   517     {
   522     {
   518         //TODO: check what to do with groupsChanged
   523         //TODO: check what to do with groupsChanged
   519         changeSet.changedContacts().insert(contact.localId());
   524         changeSet.insertChangedContact(contact.localId());
   520         m_dataBase->appendContactEmitted(contact.localId());
   525         m_dataBase->appendContactEmitted(contact.localId());
   521     }
   526     }
   522     CntSymbianTransformError::transformError(err, qtError);
   527     CntSymbianTransformError::transformError(err, qtError);
   523     return (err==KErrNone);
   528     return (err==KErrNone);
   524 }
   529 }
   565  *
   570  *
   566  * \param contact The QContact to be removed.
   571  * \param contact The QContact to be removed.
   567  * \param qtError Qt error code.
   572  * \param qtError Qt error code.
   568  * \return Error status.
   573  * \return Error status.
   569  */
   574  */
   570 bool CntSymbianEngine::removeContact(const QContactLocalId &id, QContactChangeSet& changeSet, QContactManager::Error& qtError)
   575 bool CntSymbianEngine::removeContact(const QContactLocalId &id, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   571 {
   576 {
   572     // removeContactL() can't throw c++ exception
   577     // removeContactL() can't throw c++ exception
   573     TRAPD(err, removeContactL(id));
   578     TRAPD(err, removeContactL(id));
   574     if(err == KErrNone)
   579     if(err == KErrNone)
   575     {
   580     {
   576         //TODO: check what to do with groupsChanged?
   581         //TODO: check what to do with groupsChanged?
   577         changeSet.removedContacts().insert(id);
   582         changeSet.insertRemovedContact(id);
   578         m_dataBase->appendContactEmitted(id);
   583         m_dataBase->appendContactEmitted(id);
   579     }
   584     }
   580     CntSymbianTransformError::transformError(err, qtError);
   585     CntSymbianTransformError::transformError(err, qtError);
   581     return (err==KErrNone);
   586     return (err==KErrNone);
   582 }
   587 }
   611 #endif
   616 #endif
   612 
   617 
   613     return 0;
   618     return 0;
   614 }
   619 }
   615 
   620 
   616 bool CntSymbianEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error& error)
   621 bool CntSymbianEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error)
   617 {
   622 {
   618     QContactManager::Error err;
   623     QContactManager::Error err;
   619     QContactLocalId selfCntId = selfContactId(err); // err ignored
   624     QContactLocalId selfCntId = selfContactId(&err); // err ignored
   620     QContactChangeSet changeSet;
   625     QContactChangeSet changeSet;
   621     TBool ret = removeContact(contactId, changeSet, error);
   626     TBool ret = removeContact(contactId, changeSet, error);
   622     if (ret && contactId == selfCntId ) {
   627     if (ret && contactId == selfCntId ) {
   623         QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   628         QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   624         changeSet.oldAndNewSelfContactId() = ownCard;
   629         changeSet.setOldAndNewSelfContactId(ownCard);
   625     }
   630     }
   626     changeSet.emitSignals(this);
   631     changeSet.emitSignals(this);
   627     return ret;
   632     return ret;
   628 }
   633 }
   629 
   634 
   630 void CntSymbianEngine::updateDisplayLabel(QContact& contact) const
   635 void CntSymbianEngine::updateDisplayLabel(QContact& contact) const
   631 {
   636 {
   632     QContactManager::Error error(QContactManager::NoError);
   637     QContactManager::Error error(QContactManager::NoError);
   633     QString label = synthesizedDisplayLabel(contact, error);
   638     QString label = synthesizedDisplayLabel(contact, &error);
   634     if(error == QContactManager::NoError) {
   639     if(error == QContactManager::NoError) {
   635         contact = setContactDisplayLabel(label, contact);
   640         setContactDisplayLabel(&contact, label);
   636     }
   641     }
   637 }
   642 }
   638 
   643 
   639 bool CntSymbianEngine::removeContacts(QList<QContactLocalId> *contactIds, QMap<int, QContactManager::Error> *errorMap, QContactManager::Error& error)
   644 bool CntSymbianEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error> *errorMap, QContactManager::Error* error)
   640 {
   645 {
   641     error = QContactManager::NoError;
   646     *error = QContactManager::NoError;
   642     
   647     
   643     if (errorMap) {
   648     if (errorMap) {
   644         // if the errormap argument is null, we just don't do fine-grained reporting.            
   649         // if the errormap argument is null, we just don't do fine-grained reporting.            
   645         errorMap->clear();
   650         errorMap->clear();
   646     }    
   651     }
   647     
   652     
   648     if (!contactIds) {
   653     if (contactIds.count() == 0) {
   649         error = QContactManager::BadArgumentError;
   654         *error = QContactManager::BadArgumentError;
   650         return false;
   655         return false;
   651     }
   656     }
   652    
   657     
   653     QContactManager::Error err;
   658     QContactManager::Error err;
   654     QContactLocalId selfCntId = selfContactId(err); // err ignored
   659     QContactLocalId selfCntId = selfContactId(&err); // err ignored
   655 
   660 
   656     QContactChangeSet changeSet;
   661     QContactChangeSet changeSet;
   657     for (int i = 0; i < contactIds->count(); i++) {
   662     for (int i = 0; i < contactIds.count(); i++) {
   658         QContactLocalId current = contactIds->at(i);
   663         QContactLocalId current = contactIds.at(i);
   659         QContactManager::Error functionError = QContactManager::NoError;
   664         QContactManager::Error functionError = QContactManager::NoError;
   660         if (!removeContact(current, changeSet, functionError)) {
   665         if (!removeContact(current, changeSet, &functionError)) {
   661             error = functionError;
   666             *error = functionError;
   662             if (errorMap) {
   667             if (errorMap) {
   663                 errorMap->insert(i, functionError);
   668                 errorMap->insert(i, functionError);
   664             }
   669             }
   665         } else {
   670         } else {
   666             (*contactIds)[i] = 0;
       
   667             if (current == selfCntId ) {
   671             if (current == selfCntId ) {
   668                 QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   672                 QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   669                 changeSet.oldAndNewSelfContactId() = ownCard;
   673                 changeSet.setOldAndNewSelfContactId(ownCard);
   670             }
   674             }
   671         }
   675         }
   672     }
   676     }
   673     changeSet.emitSignals(this);
   677     changeSet.emitSignals(this);
   674     return (error == QContactManager::NoError);
   678     return (*error == QContactManager::NoError);
   675 }
   679 }
   676 
   680 
   677 /* relationships */
   681 /* relationships */
   678 
   682 
   679 QStringList CntSymbianEngine::supportedRelationshipTypes(const QString& contactType) const
   683 bool CntSymbianEngine::isRelationshipTypeSupported(const QString &relationshipType, const QString &contactType) const
   680 {
   684 {
   681     return m_relationship->supportedRelationshipTypes(contactType);
   685     return m_relationship->isRelationshipTypeSupported(relationshipType, contactType);
   682 }
   686 }
   683 
   687 
   684 QList<QContactRelationship> CntSymbianEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationshipFilter::Role role, QContactManager::Error& error) const
   688 QList<QContactRelationship> CntSymbianEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const
   685 {
   689 {
   686     //retrieve the relationships
   690     //retrieve the relationships
   687     return m_relationship->relationships(relationshipType, participantId, role, error);
   691     return m_relationship->relationships(relationshipType, participantId, role, error);
   688 }
   692 }
   689 
   693 
   690 bool CntSymbianEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error& error)
   694 bool CntSymbianEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error* error)
   691 {
   695 {
   692     //affected contacts
   696     //affected contacts
   693     QContactChangeSet changeSet;
   697     QContactChangeSet changeSet;
   694 
   698 
   695     //save the relationship
   699     //save the relationship
   696     bool returnValue = m_relationship->saveRelationship(&changeSet.addedRelationshipsContacts(), relationship, error);
   700     QSet<QContactLocalId> affectedContactIds;
       
   701     bool returnValue = m_relationship->saveRelationship(&affectedContactIds, relationship, error);
       
   702     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   697 
   703 
   698     //add contacts to the list that shouldn't be emitted
   704     //add contacts to the list that shouldn't be emitted
   699     m_dataBase->appendContactsEmitted(changeSet.addedRelationshipsContacts().toList());
   705     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   700 
   706 
   701     //emit signals
   707     //emit signals
   702     changeSet.emitSignals(this);
   708     changeSet.emitSignals(this);
   703 
   709 
   704     return returnValue;
   710     return returnValue;
   705 }
   711 }
   706 
   712 
   707 QList<QContactManager::Error> CntSymbianEngine::saveRelationships(QList<QContactRelationship>* relationships, QContactManager::Error& error)
   713 bool CntSymbianEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   708 {
   714 {
   709     //affected contacts
   715     //affected contacts
   710     QContactChangeSet changeSet;
   716     QContactChangeSet changeSet;
   711 
   717 
   712     //save the relationships
   718     //save the relationships
   713     QList<QContactManager::Error> returnValue = m_relationship->saveRelationships(&changeSet.addedRelationshipsContacts(), relationships, error);
   719     QSet<QContactLocalId> affectedContactIds;
       
   720     bool returnValue = m_relationship->saveRelationships(&affectedContactIds, relationships, errorMap, error);
       
   721     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   714 
   722 
   715     //add contacts to the list that shouldn't be emitted
   723     //add contacts to the list that shouldn't be emitted
   716     m_dataBase->appendContactsEmitted(changeSet.addedRelationshipsContacts().toList());
   724     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   717 
   725 
   718     //emit signals
   726     //emit signals
   719     changeSet.emitSignals(this);
   727     changeSet.emitSignals(this);
   720 
   728 
   721     return returnValue;
   729     return returnValue;
   722 }
   730 }
   723 
   731 
   724 bool CntSymbianEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error& error)
   732 bool CntSymbianEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error* error)
   725 {
   733 {
   726     //affected contacts
   734     //affected contacts
   727     QContactChangeSet changeSet;
   735     QContactChangeSet changeSet;
   728 
   736 
   729     //remove the relationship
   737     //remove the relationship
   730     bool returnValue = m_relationship->removeRelationship(&changeSet.removedRelationshipsContacts(), relationship, error);
   738     QSet<QContactLocalId> affectedContactIds;
       
   739     bool returnValue = m_relationship->removeRelationship(&affectedContactIds, relationship, error);
       
   740     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   731 
   741 
   732     //add contacts to the list that shouldn't be emitted
   742     //add contacts to the list that shouldn't be emitted
   733     m_dataBase->appendContactsEmitted(changeSet.removedRelationshipsContacts().toList());
   743     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   734 
   744 
   735     //emit signals
   745     //emit signals
   736     changeSet.emitSignals(this);
   746     changeSet.emitSignals(this);
   737 
   747 
   738     return returnValue;
   748     return returnValue;
   739 }
   749 }
   740 
   750 
   741 QList<QContactManager::Error> CntSymbianEngine::removeRelationships(const QList<QContactRelationship>& relationships, QContactManager::Error& error)
   751 bool CntSymbianEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   742 {
   752 {
   743     //affected contacts
   753     //affected contacts
   744     QContactChangeSet changeSet;
   754     QContactChangeSet changeSet;
   745 
   755 
   746     //remove the relationships
   756     //remove the relationships
   747     QList<QContactManager::Error> returnValue = m_relationship->removeRelationships(&changeSet.removedRelationshipsContacts(), relationships, error);
   757     QSet<QContactLocalId> affectedContactIds;
       
   758     bool returnValue = m_relationship->removeRelationships(&affectedContactIds, relationships, errorMap, error);
       
   759     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   748 
   760 
   749     //add contacts to the list that shouldn't be emitted
   761     //add contacts to the list that shouldn't be emitted
   750     m_dataBase->appendContactsEmitted(changeSet.removedRelationshipsContacts().toList());
   762     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   751 
   763 
   752     //emit signals
   764     //emit signals
   753     changeSet.emitSignals(this);
   765     changeSet.emitSignals(this);
   754 
   766 
   755     return returnValue;
   767     return returnValue;
   756 }
   768 }
   757 
   769 
   758 QMap<QString, QContactDetailDefinition> CntSymbianEngine::detailDefinitions(const QString& contactType, QContactManager::Error& error) const
   770 QMap<QString, QContactDetailDefinition> CntSymbianEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const
   759 {
   771 {
   760     // TODO: update for SIM contacts later
   772     // TODO: update for SIM contacts later
   761     if (contactType != QContactType::TypeContact && contactType != QContactType::TypeGroup) {
   773     if (contactType != QContactType::TypeContact && contactType != QContactType::TypeGroup) {
   762         error = QContactManager::InvalidContactTypeError;
   774         *error = QContactManager::InvalidContactTypeError;
   763         return QMap<QString, QContactDetailDefinition>();
   775         return QMap<QString, QContactDetailDefinition>();
   764     }
   776     }
   765 
   777 
   766     error = QContactManager::NoError;
   778     *error = QContactManager::NoError;
   767 
   779 
   768     // First get the default definitions
   780     // First get the default definitions
   769     QMap<QString, QMap<QString, QContactDetailDefinition> > schemaDefinitions = QContactManagerEngine::schemaDefinitions();
   781     QMap<QString, QMap<QString, QContactDetailDefinition> > schemaDefinitions = QContactManagerEngine::schemaDefinitions();
   770 
   782 
   771     // And then ask contact transformer to do the modifications required
   783     // And then ask contact transformer to do the modifications required
   816 {
   828 {
   817     return m_contactFilter->filterSupported(filter);
   829     return m_contactFilter->filterSupported(filter);
   818 }
   830 }
   819 
   831 
   820 /* Synthesise the display label of a contact */
   832 /* Synthesise the display label of a contact */
   821 QString CntSymbianEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error& error) const
   833 QString CntSymbianEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const
   822 {
   834 {
   823     error = QContactManager::NoError;
   835     *error = QContactManager::NoError;
   824     return m_displayLabel->synthesizedDisplayLabel(contact, error);
   836     return m_displayLabel->synthesizedDisplayLabel(contact, error);
   825 }
   837 }
   826 
   838 
   827 bool CntSymbianEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error& error)
   839 bool CntSymbianEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error* error)
   828 {
   840 {
   829     if (contactId <= 0) {
   841     if (contactId <= 0) {
   830         error = QContactManager::BadArgumentError;
   842         *error = QContactManager::BadArgumentError;
   831         return false;
   843         return false;
   832     }
   844     }
   833 
   845 
   834     TContactItemId id(contactId);
   846     TContactItemId id(contactId);
   835     CContactItem* symContact = 0;
   847     CContactItem* symContact = 0;
   840     delete symContact;
   852     delete symContact;
   841     CntSymbianTransformError::transformError(err, error);
   853     CntSymbianTransformError::transformError(err, error);
   842     return (err==KErrNone);
   854     return (err==KErrNone);
   843 }
   855 }
   844 
   856 
   845 QContactLocalId CntSymbianEngine::selfContactId(QContactManager::Error& error) const
   857 QContactLocalId CntSymbianEngine::selfContactId(QContactManager::Error* error) const
   846 {
   858 {
   847     error = QContactManager::NoError;
   859     *error = QContactManager::NoError;
   848     QContactLocalId id = 0;
   860     QContactLocalId id = 0;
   849 
   861 
   850     TContactItemId myCard = m_dataBase->contactDatabase()->OwnCardId();
   862     TContactItemId myCard = m_dataBase->contactDatabase()->OwnCardId();
   851     if (myCard < 0) {
   863     if (myCard < 0) {
   852     error = QContactManager::DoesNotExistError;
   864     *error = QContactManager::DoesNotExistError;
   853     }
   865     }
   854     else {
   866     else {
   855         id = myCard;
   867         id = myCard;
   856     }
   868     }
   857     return id;
   869     return id;
   955         case QContactAbstractRequest::ContactFetchRequest:
   967         case QContactAbstractRequest::ContactFetchRequest:
   956         {
   968         {
   957             QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest);
   969             QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest);
   958             QContactFilter filter = r->filter();
   970             QContactFilter filter = r->filter();
   959             QList<QContactSortOrder> sorting = r->sorting();
   971             QList<QContactSortOrder> sorting = r->sorting();
   960             QStringList defs = r->definitionRestrictions();
   972             QContactFetchHint fh = r->fetchHint();
   961 
   973 
   962             QContactManager::Error operationError;
   974             QContactManager::Error operationError;
   963             QList<QContact> requestedContacts = QContactManagerEngine::contacts(filter, sorting, defs, operationError);
   975             QList<QContact> requestedContacts = contacts(filter, sorting, fh, &operationError);
   964 
   976 
   965             // update the request with the results.
   977             // update the request with the results.
   966             if (!requestedContacts.isEmpty() || operationError != QContactManager::NoError)
   978             updateContactFetchRequest(r, requestedContacts, operationError, QContactAbstractRequest::FinishedState); // emit resultsAvailable()
   967                 updateContactFetchRequest(r, requestedContacts, operationError); // emit resultsAvailable()
       
   968             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
   969         }
   979         }
   970         break;
   980         break;
   971 
   981 
   972         case QContactAbstractRequest::ContactLocalIdFetchRequest:
   982         case QContactAbstractRequest::ContactLocalIdFetchRequest:
   973         {
   983         {
   974             QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest);
   984             QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest);
   975             QContactFilter filter = r->filter();
   985             QContactFilter filter = r->filter();
   976             QList<QContactSortOrder> sorting = r->sorting();
   986             QList<QContactSortOrder> sorting = r->sorting();
   977 
   987 
   978             QContactManager::Error operationError = QContactManager::NoError;
   988             QContactManager::Error operationError = QContactManager::NoError;
   979             QList<QContactLocalId> requestedContactIds = QContactManagerEngine::contactIds(filter, sorting, operationError);
   989             QList<QContactLocalId> requestedContactIds = contactIds(filter, sorting, &operationError);
   980 
   990 
   981             if (!requestedContactIds.isEmpty() || operationError != QContactManager::NoError)
   991             updateContactLocalIdFetchRequest(r, requestedContactIds, operationError, QContactAbstractRequest::FinishedState);
   982                 updateContactLocalIdFetchRequest(r, requestedContactIds, operationError); // emit resultsAvailable()
       
   983             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
   984         }
   992         }
   985         break;
   993         break;
   986 
   994 
   987         case QContactAbstractRequest::ContactSaveRequest:
   995         case QContactAbstractRequest::ContactSaveRequest:
   988         {
   996         {
   989             QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest);
   997             QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest);
   990             QList<QContact> contacts = r->contacts();
   998             QList<QContact> contacts = r->contacts();
   991 
   999 
   992             QContactManager::Error operationError = QContactManager::NoError;
  1000             QContactManager::Error operationError = QContactManager::NoError;
   993             QMap<int, QContactManager::Error> errorMap;
  1001             QMap<int, QContactManager::Error> errorMap;
   994             saveContacts(&contacts, &errorMap, operationError);
  1002             saveContacts(&contacts, &errorMap, &operationError);
   995 
  1003 
   996             updateContactSaveRequest(r, contacts, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
  1004             updateContactSaveRequest(r, contacts, operationError, errorMap, QContactAbstractRequest::FinishedState); // there will always be results of some form.  emit resultsAvailable().
   997             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
   998         }
  1005         }
   999         break;
  1006         break;
  1000 
  1007 
  1001         case QContactAbstractRequest::ContactRemoveRequest:
  1008         case QContactAbstractRequest::ContactRemoveRequest:
  1002         {
  1009         {
  1010             QList<QContactLocalId> contactsToRemove = r->contactIds();
  1017             QList<QContactLocalId> contactsToRemove = r->contactIds();
  1011             QMap<int, QContactManager::Error> errorMap;
  1018             QMap<int, QContactManager::Error> errorMap;
  1012 
  1019 
  1013             for (int i = 0; i < contactsToRemove.size(); i++) {
  1020             for (int i = 0; i < contactsToRemove.size(); i++) {
  1014                 QContactManager::Error tempError;
  1021                 QContactManager::Error tempError;
  1015                 removeContact(contactsToRemove.at(i), changeSet, tempError);
  1022                 removeContact(contactsToRemove.at(i), changeSet, &tempError);
  1016 
  1023 
       
  1024                 errorMap.insert(i, tempError);                
  1017                 if (tempError != QContactManager::NoError) {
  1025                 if (tempError != QContactManager::NoError) {
  1018                     errorMap.insert(i, tempError);
       
  1019                     operationError = tempError;
  1026                     operationError = tempError;
  1020                 }
  1027                 }
  1021             }
  1028             }
  1022 
  1029 
  1023             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
  1030             updateContactRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1024                 updateContactRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
       
  1025             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1026         }
  1031         }
  1027         break;
  1032         break;
  1028 
  1033 
  1029         case QContactAbstractRequest::DetailDefinitionFetchRequest:
  1034         case QContactAbstractRequest::DetailDefinitionFetchRequest:
  1030         {
  1035         {
  1032             QContactManager::Error operationError = QContactManager::NoError;
  1037             QContactManager::Error operationError = QContactManager::NoError;
  1033             QMap<int, QContactManager::Error> errorMap;
  1038             QMap<int, QContactManager::Error> errorMap;
  1034             QMap<QString, QContactDetailDefinition> requestedDefinitions;
  1039             QMap<QString, QContactDetailDefinition> requestedDefinitions;
  1035             QStringList names = r->definitionNames();
  1040             QStringList names = r->definitionNames();
  1036             if (names.isEmpty())
  1041             if (names.isEmpty())
  1037                 names = detailDefinitions(r->contactType(), operationError).keys(); // all definitions.
  1042                 names = detailDefinitions(r->contactType(), &operationError).keys(); // all definitions.
  1038 
  1043 
  1039             QContactManager::Error tempError;
  1044             QContactManager::Error tempError;
  1040             for (int i = 0; i < names.size(); i++) {
  1045             for (int i = 0; i < names.size(); i++) {
  1041                 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), tempError);
  1046                 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), &tempError);
  1042                 requestedDefinitions.insert(names.at(i), current);
  1047                 requestedDefinitions.insert(names.at(i), current);
  1043 
  1048 
       
  1049                 errorMap.insert(i, tempError);              
  1044                 if (tempError != QContactManager::NoError) {
  1050                 if (tempError != QContactManager::NoError) {
  1045                     errorMap.insert(i, tempError);
       
  1046                     operationError = tempError;
  1051                     operationError = tempError;
  1047                 }
  1052                 }
  1048             }
  1053             }
  1049 
  1054 
  1050             if (!errorMap.isEmpty() || !requestedDefinitions.isEmpty() || operationError != QContactManager::NoError)
  1055             updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1051                 updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap); // emit resultsAvailable()
       
  1052             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1053         }
  1056         }
  1054         break;
  1057         break;
  1055 
  1058 
  1056 // symbian engine currently does not support mutable definitions.
  1059         case QContactAbstractRequest::DetailDefinitionSaveRequest:
  1057 //
  1060         {
  1058 //        case QContactAbstractRequest::DetailDefinitionSaveRequest:
  1061             // symbian engine currently does not support mutable definitions.
  1059 //        {
  1062         }
  1060 //            QContactDetailDefinitionSaveRequest* r = static_cast<QContactDetailDefinitionSaveRequest*>(currentRequest);
  1063         break;
  1061 //            QContactManager::Error operationError = QContactManager::NoError;
  1064 
  1062 //            QMap<int, QContactManager::Error> errorMap;
  1065         case QContactAbstractRequest::DetailDefinitionRemoveRequest:
  1063 //            QList<QContactDetailDefinition> definitions = r->definitions();
  1066         {
  1064 //            QList<QContactDetailDefinition> savedDefinitions;
  1067             // symbian engine currently does not support mutable definitions.
  1065 //
  1068         }
  1066 //            QContactManager::Error tempError;
  1069         break;
  1067 //            for (int i = 0; i < definitions.size(); i++) {
       
  1068 //                QContactDetailDefinition current = definitions.at(i);
       
  1069 //                saveDetailDefinition(current, r->contactType(), changeSet, tempError);
       
  1070 //                savedDefinitions.append(current);
       
  1071 //
       
  1072 //                if (tempError != QContactManager::NoError) {
       
  1073 //                    errorMap.insert(i, tempError);
       
  1074 //                    operationError = tempError;
       
  1075 //                }
       
  1076 //            }
       
  1077 //
       
  1078 //            // update the request with the results.
       
  1079 //            updateDefinitionSaveRequest(r, savedDefinitions, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
       
  1080 //            updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1081 //        }
       
  1082 //        break;
       
  1083 //
       
  1084 //        case QContactAbstractRequest::DetailDefinitionRemoveRequest:
       
  1085 //        {
       
  1086 //            QContactDetailDefinitionRemoveRequest* r = static_cast<QContactDetailDefinitionRemoveRequest*>(currentRequest);
       
  1087 //            QStringList names = r->definitionNames();
       
  1088 //
       
  1089 //            QContactManager::Error operationError = QContactManager::NoError;
       
  1090 //            QMap<int, QContactManager::Error> errorMap;
       
  1091 //
       
  1092 //            for (int i = 0; i < names.size(); i++) {
       
  1093 //                QContactManager::Error tempError;
       
  1094 //                removeDetailDefinition(names.at(i), r->contactType(), changeSet, tempError);
       
  1095 //
       
  1096 //                if (tempError != QContactManager::NoError) {
       
  1097 //                    errorMap.insert(i, tempError);
       
  1098 //                    operationError = tempError;
       
  1099 //                }
       
  1100 //            }
       
  1101 //
       
  1102 //            // there are no results, so just update the status with the error.
       
  1103 //            if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
       
  1104 //                updateDefinitionRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
       
  1105 //            updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1106 //        }
       
  1107 //        break;
       
  1108 
  1070 
  1109         case QContactAbstractRequest::RelationshipFetchRequest:
  1071         case QContactAbstractRequest::RelationshipFetchRequest:
  1110         {
  1072         {
  1111             QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest);
  1073             QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest);
  1112             QContactManager::Error operationError = QContactManager::NoError;
  1074             QContactManager::Error operationError = QContactManager::NoError;
  1113             QList<QContactManager::Error> operationErrors;
  1075             QList<QContactManager::Error> operationErrors;
  1114             QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationshipFilter::Either, operationError);
  1076             QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationship::Either, &operationError);
  1115             QList<QContactRelationship> requestedRelationships;
  1077             QList<QContactRelationship> requestedRelationships;
  1116 
  1078 
  1117             // select the requested relationships.
  1079             // select the requested relationships.
  1118             for (int i = 0; i < allRelationships.size(); i++) {
  1080             for (int i = 0; i < allRelationships.size(); i++) {
  1119                 QContactRelationship currRel = allRelationships.at(i);
  1081                 QContactRelationship currRel = allRelationships.at(i);
  1125                     continue;
  1087                     continue;
  1126                 requestedRelationships.append(currRel);
  1088                 requestedRelationships.append(currRel);
  1127             }
  1089             }
  1128 
  1090 
  1129             // update the request with the results.
  1091             // update the request with the results.
  1130             if (!requestedRelationships.isEmpty() || operationError != QContactManager::NoError)
  1092             updateRelationshipFetchRequest(r, requestedRelationships, operationError, QContactAbstractRequest::FinishedState);
  1131                 updateRelationshipFetchRequest(r, requestedRelationships, operationError); // emit resultsAvailable()
       
  1132             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1133         }
  1093         }
  1134         break;
  1094         break;
  1135 
  1095 
  1136         case QContactAbstractRequest::RelationshipRemoveRequest:
  1096         case QContactAbstractRequest::RelationshipRemoveRequest:
  1137         {
  1097         {
  1138             QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest);
  1098             QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest);
  1139             QContactManager::Error operationError = QContactManager::NoError;
  1099             QContactManager::Error operationError = QContactManager::NoError;
  1140             QList<QContactRelationship> relationshipsToRemove = r->relationships();
  1100             QList<QContactRelationship> relationshipsToRemove = r->relationships();
  1141             QMap<int, QContactManager::Error> errorMap;
  1101             QMap<int, QContactManager::Error> errorMap;
  1142 
  1102 
  1143             bool foundMatch = false;
       
  1144             for (int i = 0; i < relationshipsToRemove.size(); i++) {
  1103             for (int i = 0; i < relationshipsToRemove.size(); i++) {
  1145                 QContactManager::Error tempError;
  1104                 QContactManager::Error tempError;
  1146                 removeRelationship(relationshipsToRemove.at(i), tempError);
  1105                 removeRelationship(relationshipsToRemove.at(i), &tempError);
  1147 
  1106 
       
  1107                 errorMap.insert(i, tempError);
  1148                 if (tempError != QContactManager::NoError) {
  1108                 if (tempError != QContactManager::NoError) {
  1149                     errorMap.insert(i, tempError);
       
  1150                     operationError = tempError;
  1109                     operationError = tempError;
  1151                 }
  1110                 }
  1152             }
  1111             }
  1153 
  1112 
  1154             if (foundMatch == false && operationError == QContactManager::NoError)
  1113             updateRelationshipRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1155                 operationError = QContactManager::DoesNotExistError;
       
  1156 
       
  1157             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
       
  1158                 updateRelationshipRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
       
  1159             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1160         }
  1114         }
  1161         break;
  1115         break;
  1162 
  1116 
  1163         case QContactAbstractRequest::RelationshipSaveRequest:
  1117         case QContactAbstractRequest::RelationshipSaveRequest:
  1164         {
  1118         {
  1169             QList<QContactRelationship> savedRelationships;
  1123             QList<QContactRelationship> savedRelationships;
  1170 
  1124 
  1171             QContactManager::Error tempError;
  1125             QContactManager::Error tempError;
  1172             for (int i = 0; i < requestRelationships.size(); i++) {
  1126             for (int i = 0; i < requestRelationships.size(); i++) {
  1173                 QContactRelationship current = requestRelationships.at(i);
  1127                 QContactRelationship current = requestRelationships.at(i);
  1174                 saveRelationship(&current, tempError);
  1128                 saveRelationship(&current, &tempError);
  1175                 savedRelationships.append(current);
  1129                 savedRelationships.append(current);
  1176 
  1130 
       
  1131                 errorMap.insert(i, tempError);
  1177                 if (tempError != QContactManager::NoError) {
  1132                 if (tempError != QContactManager::NoError) {
  1178                     errorMap.insert(i, tempError);
       
  1179                     operationError = tempError;
  1133                     operationError = tempError;
  1180                 }
  1134                 }
  1181             }
  1135             }
  1182 
  1136 
  1183             // update the request with the results.
  1137             // update the request with the results.
  1184             updateRelationshipSaveRequest(r, savedRelationships, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
  1138             updateRelationshipSaveRequest(r, savedRelationships, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1185             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1186         }
  1139         }
  1187         break;
  1140         break;
  1188 
  1141 
  1189         default: // unknown request type.
  1142         default: // unknown request type.
  1190         break;
  1143         break;
  1194     changeSet.emitSignals(this);
  1147     changeSet.emitSignals(this);
  1195 }
  1148 }
  1196 
  1149 
  1197 #ifndef PBK_UNIT_TEST
  1150 #ifndef PBK_UNIT_TEST
  1198 /* Factory lives here in the basement */
  1151 /* Factory lives here in the basement */
  1199 QContactManagerEngine* CntSymbianFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error& error)
  1152 QContactManagerEngine* CntSymbianFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
  1200 {
  1153 {
  1201     return new CntSymbianEngine(parameters, error);
  1154     return new CntSymbianEngine(parameters, error);
  1202 }
  1155 }
  1203 
  1156 
  1204 QString CntSymbianFactory::managerName() const
  1157 QString CntSymbianFactory::managerName() const