qtmobility/plugins/contacts/symbian/src/cntsymbianengine.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    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     : m_dataBase(0),
       
    79       m_managerUri(0),
       
    80       m_transformContact(0),
       
    81       m_contactFilter(0),
       
    82 #ifndef SYMBIAN_BACKEND_USE_SQLITE
       
    83       m_contactSorter(0),
       
    84 #endif
       
    85       m_relationship(0),
       
    86       m_displayLabel(0)
    78 {
    87 {
    79     *error = QContactManager::NoError;
    88     *error = QContactManager::NoError;
    80 
    89 
    81     m_dataBase = new CntSymbianDatabase(this, error);
    90     m_dataBase = new CntSymbianDatabase(this, error);
    82 
    91 
   353 }
   362 }
   354 
   363 
   355 /*!
   364 /*!
   356  * Private leaving implementation for contact()
   365  * Private leaving implementation for contact()
   357  */
   366  */
   358 QContact CntSymbianEngine::fetchContactL(const QContactLocalId &localId, const QStringList& definitionRestrictions) const
   367 QContact CntSymbianEngine::fetchContactL(const QContactLocalId &localId, const QStringList& detailDefinitionsHint) const
   359 {
   368 {
   360     // A contact with a zero id is not expected to exist.
   369     // A contact with a zero id is not expected to exist.
   361     // Symbian contact database uses id 0 internally as the id of the
   370     // Symbian contact database uses id 0 internally as the id of the
   362     // system template.
   371     // system template.
   363     if(localId == 0)
   372     if(localId == 0)
   364         User::Leave(KErrNotFound);
   373         User::Leave(KErrNotFound);
   365 
   374 
   366     // Read the contact from the CContactDatabase
   375     // Read the contact from the CContactDatabase
   367     CContactItem* contactItem = m_dataBase->contactDatabase()->ReadContactL(localId);
   376     CContactItem* contactItem(0);
       
   377     if (!detailDefinitionsHint.isEmpty()) {
       
   378         // Create a view definition with only the fields that map to the fetch hint
       
   379         CContactItemViewDef *viewDef = CContactItemViewDef::NewLC(
       
   380             CContactItemViewDef::EIncludeFields, CContactItemViewDef::EMaskHiddenFields);
       
   381         foreach (QString detailDefinitionHint, detailDefinitionsHint) {
       
   382             QList<TUid> uids = m_transformContact->itemFieldUidsL(detailDefinitionHint);
       
   383             foreach (TUid uid, uids) {
       
   384                 viewDef->AddL(uid);
       
   385             }
       
   386         }
       
   387         contactItem = m_dataBase->contactDatabase()->ReadContactL(localId, *viewDef);
       
   388         CleanupStack::PopAndDestroy(viewDef);
       
   389     } else {
       
   390         // The fetch hint does not contain detail definitions hint so get all
       
   391         // the contact item fields that are available
       
   392         contactItem = m_dataBase->contactDatabase()->ReadContactL(localId);
       
   393     }
   368     CleanupStack::PushL(contactItem);
   394     CleanupStack::PushL(contactItem);
   369 
   395 
   370     // Convert to a QContact
   396     // Convert to a QContact
   371     QContact contact = m_transformContact->transformContactL(*contactItem, definitionRestrictions);
   397     QContact contact = m_transformContact->transformContactL(*contactItem);
   372 
   398 
   373     // Transform details that are not available until the contact has been saved
   399     // Transform details that are not available until the contact has been saved
   374     m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   400     m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   375 
   401 
   376     CleanupStack::PopAndDestroy(contactItem);
   402     CleanupStack::PopAndDestroy(contactItem);
   390 {
   416 {
   391     // Attempt to persist contact, trapping errors
   417     // Attempt to persist contact, trapping errors
   392     int err(0);
   418     int err(0);
   393     QContactLocalId id(0);
   419     QContactLocalId id(0);
   394     TRAP(err, id = addContactL(contact));
   420     TRAP(err, id = addContactL(contact));
       
   421 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
   395     if(err == KErrNone)
   422     if(err == KErrNone)
   396     {
   423     {
   397         changeSet.insertAddedContact(id);
   424         changeSet.insertAddedContact(id);
   398         m_dataBase->appendContactEmitted(id);
   425         m_dataBase->appendContactEmitted(id);
   399     }
   426     }
       
   427 #endif
   400     CntSymbianTransformError::transformError(err, qtError);
   428     CntSymbianTransformError::transformError(err, qtError);
   401 
       
   402     return (err==KErrNone);
   429     return (err==KErrNone);
   403 }
   430 }
   404 
   431 
   405 /*!
   432 /*!
   406  * Private leaving implementation for addContact()
   433  * Private leaving implementation for addContact()
   416     if(contact.type() == QContactType::TypeContact)
   443     if(contact.type() == QContactType::TypeContact)
   417     {
   444     {
   418         // Create a new contact card.
   445         // Create a new contact card.
   419         CContactItem* contactItem = CContactCard::NewLC();
   446         CContactItem* contactItem = CContactCard::NewLC();
   420         m_transformContact->transformContactL(contact, *contactItem);
   447         m_transformContact->transformContactL(contact, *contactItem);
       
   448 
   421         // Add to the database
   449         // Add to the database
   422         id = m_dataBase->contactDatabase()->AddNewContactL(*contactItem);
   450         id = m_dataBase->contactDatabase()->AddNewContactL(*contactItem);
       
   451 
   423         // Reload contact item
   452         // Reload contact item
   424         CleanupStack::PopAndDestroy(contactItem);
   453         CleanupStack::PopAndDestroy(contactItem);
   425         contactItem = 0;
   454         contactItem = 0;
   426         contactItem = m_dataBase->contactDatabase()->ReadContactLC(id);
   455         contactItem = m_dataBase->contactDatabase()->ReadContactLC(id);
       
   456 
   427         // Transform details that are not available until the contact has been saved
   457         // Transform details that are not available until the contact has been saved
   428         m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   458         m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   429         CleanupStack::PopAndDestroy(contactItem);
   459         CleanupStack::PopAndDestroy(contactItem);
   430     }
   460     }
   431     //group contact
   461     //group contact
   443         CleanupStack::PopAndDestroy(contactItem);
   473         CleanupStack::PopAndDestroy(contactItem);
   444         contactItem = 0;
   474         contactItem = 0;
   445 
   475 
   446         //update contact, will add the fields to the already saved group
   476         //update contact, will add the fields to the already saved group
   447         updateContactL(contact);
   477         updateContactL(contact);
       
   478 
   448         // Transform details that are not available until the contact has been saved
   479         // Transform details that are not available until the contact has been saved
   449         contactItem = m_dataBase->contactDatabase()->ReadContactLC(id);
   480         contactItem = m_dataBase->contactDatabase()->ReadContactLC(id);
   450         m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   481         m_transformContact->transformPostSaveDetailsL(*contactItem, contact, *m_dataBase->contactDatabase(), m_managerUri);
   451 
       
   452         CleanupStack::PopAndDestroy(contactItem);
   482         CleanupStack::PopAndDestroy(contactItem);
   453     }
   483     }
   454     // Leave with an error
   484     // Leave with an error
   455     else
   485     else
   456     {
   486     {
   470  */
   500  */
   471 bool CntSymbianEngine::updateContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   501 bool CntSymbianEngine::updateContact(QContact& contact, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   472 {
   502 {
   473     int err(0);
   503     int err(0);
   474     TRAP(err, updateContactL(contact));
   504     TRAP(err, updateContactL(contact));
       
   505 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
   475     if(err == KErrNone)
   506     if(err == KErrNone)
   476     {
   507     {
   477         //TODO: check what to do with groupsChanged
   508         //TODO: check what to do with groupsChanged
   478         changeSet.insertChangedContact(contact.localId());
   509         changeSet.insertChangedContact(contact.localId());
   479         m_dataBase->appendContactEmitted(contact.localId());
   510         m_dataBase->appendContactEmitted(contact.localId());
   480     }
   511     }
       
   512 #endif
   481     CntSymbianTransformError::transformError(err, qtError);
   513     CntSymbianTransformError::transformError(err, qtError);
   482     return (err==KErrNone);
   514     return (err==KErrNone);
   483 }
   515 }
   484 
   516 
   485 /*!
   517 /*!
   535  */
   567  */
   536 bool CntSymbianEngine::removeContact(const QContactLocalId &id, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   568 bool CntSymbianEngine::removeContact(const QContactLocalId &id, QContactChangeSet& changeSet, QContactManager::Error* qtError)
   537 {
   569 {
   538     // removeContactL() can't throw c++ exception
   570     // removeContactL() can't throw c++ exception
   539     TRAPD(err, removeContactL(id));
   571     TRAPD(err, removeContactL(id));
       
   572 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
   540     if(err == KErrNone)
   573     if(err == KErrNone)
   541     {
   574     {
   542         //TODO: check what to do with groupsChanged?
   575         //TODO: check what to do with groupsChanged?
   543         changeSet.insertRemovedContact(id);
   576         changeSet.insertRemovedContact(id);
   544         m_dataBase->appendContactEmitted(id);
   577         m_dataBase->appendContactEmitted(id);
   545     }
   578     }
       
   579 #endif
   546     CntSymbianTransformError::transformError(err, qtError);
   580     CntSymbianTransformError::transformError(err, qtError);
   547     return (err==KErrNone);
   581     return (err==KErrNone);
   548 }
   582 }
   549 
   583 
   550 /*!
   584 /*!
   551  * Private leaving implementation for removeContact
   585  * Private leaving implementation for removeContact
   552  */
   586  */
   553 int CntSymbianEngine::removeContactL(QContactLocalId id)
   587 void CntSymbianEngine::removeContactL(QContactLocalId id)
   554 {
   588 {
   555     // A contact with a zero id is not expected to exist.
   589     // A contact with a zero id is not expected to exist.
   556     // Symbian contact database uses id 0 internally as the id of the
   590     // Symbian contact database uses id 0 internally as the id of the
   557     // system template.
   591     // system template.
   558     if(id == 0)
   592     if(id == 0)
   573     // 
   607     // 
   574     // Needles to say that this will have a major negative effect on performance!
   608     // Needles to say that this will have a major negative effect on performance!
   575     // TODO: A better solution must be found.
   609     // TODO: A better solution must be found.
   576     m_dataBase->contactDatabase()->CompactL();
   610     m_dataBase->contactDatabase()->CompactL();
   577 #endif
   611 #endif
   578 
       
   579     return 0;
       
   580 }
   612 }
   581 
   613 
   582 bool CntSymbianEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error)
   614 bool CntSymbianEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error)
   583 {
   615 {
   584     QContactManager::Error err;
   616     QContactManager::Error err;
   585     QContactLocalId selfCntId = selfContactId(&err); // err ignored
   617     QContactLocalId selfCntId = selfContactId(&err); // err ignored
   586     QContactChangeSet changeSet;
   618     QContactChangeSet changeSet;
   587     TBool ret = removeContact(contactId, changeSet, error);
   619     TBool ret = removeContact(contactId, changeSet, error);
       
   620 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
   588     if (ret && contactId == selfCntId ) {
   621     if (ret && contactId == selfCntId ) {
   589         QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   622         QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   590         changeSet.setOldAndNewSelfContactId(ownCard);
   623         changeSet.setOldAndNewSelfContactId(ownCard);
   591     }
   624     }
   592     changeSet.emitSignals(this);
   625     changeSet.emitSignals(this);
       
   626 #endif
   593     return ret;
   627     return ret;
   594 }
   628 }
   595 
   629 
   596 void CntSymbianEngine::updateDisplayLabel(QContact& contact) const
   630 void CntSymbianEngine::updateDisplayLabel(QContact& contact) const
   597 {
   631 {
   626         if (!removeContact(current, changeSet, &functionError)) {
   660         if (!removeContact(current, changeSet, &functionError)) {
   627             *error = functionError;
   661             *error = functionError;
   628             if (errorMap) {
   662             if (errorMap) {
   629                 errorMap->insert(i, functionError);
   663                 errorMap->insert(i, functionError);
   630             }
   664             }
   631         } else {
   665         }
       
   666 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
       
   667         else {
   632             if (current == selfCntId ) {
   668             if (current == selfCntId ) {
   633                 QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   669                 QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
   634                 changeSet.setOldAndNewSelfContactId(ownCard);
   670                 changeSet.setOldAndNewSelfContactId(ownCard);
   635             }
   671             }
   636         }
   672         }
       
   673 #endif
   637     }
   674     }
   638     changeSet.emitSignals(this);
   675     changeSet.emitSignals(this);
   639     return (*error == QContactManager::NoError);
   676     return (*error == QContactManager::NoError);
   640 }
   677 }
   641 
   678 
   652     return m_relationship->relationships(relationshipType, participantId, role, error);
   689     return m_relationship->relationships(relationshipType, participantId, role, error);
   653 }
   690 }
   654 
   691 
   655 bool CntSymbianEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error* error)
   692 bool CntSymbianEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error* error)
   656 {
   693 {
   657     //affected contacts
       
   658     QContactChangeSet changeSet;
       
   659 
       
   660     //save the relationship
   694     //save the relationship
   661     QSet<QContactLocalId> affectedContactIds;
   695     QSet<QContactLocalId> affectedContactIds;
   662     bool returnValue = m_relationship->saveRelationship(&affectedContactIds, relationship, error);
   696     bool returnValue = m_relationship->saveRelationship(&affectedContactIds, relationship, error);
       
   697 
       
   698 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
       
   699     //affected contacts
       
   700     QContactChangeSet changeSet;
   663     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   701     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   664 
   702 
   665     //add contacts to the list that shouldn't be emitted
   703     //add contacts to the list that shouldn't be emitted
   666     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   704     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   667 
   705 
   668     //emit signals
   706     //emit signals
   669     changeSet.emitSignals(this);
   707     changeSet.emitSignals(this);
       
   708 #endif
   670 
   709 
   671     return returnValue;
   710     return returnValue;
   672 }
   711 }
   673 
   712 
   674 bool CntSymbianEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   713 bool CntSymbianEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   675 {
   714 {
   676     //affected contacts
       
   677     QContactChangeSet changeSet;
       
   678 
       
   679     //save the relationships
   715     //save the relationships
   680     QSet<QContactLocalId> affectedContactIds;
   716     QSet<QContactLocalId> affectedContactIds;
   681     bool returnValue = m_relationship->saveRelationships(&affectedContactIds, relationships, errorMap, error);
   717     bool returnValue = m_relationship->saveRelationships(&affectedContactIds, relationships, errorMap, error);
       
   718     
       
   719 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
       
   720     //affected contacts
       
   721     QContactChangeSet changeSet;
   682     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   722     changeSet.insertAddedRelationshipsContacts(affectedContactIds.toList());
   683 
   723 
   684     //add contacts to the list that shouldn't be emitted
   724     //add contacts to the list that shouldn't be emitted
   685     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   725     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   686 
   726 
   687     //emit signals
   727     //emit signals
   688     changeSet.emitSignals(this);
   728     changeSet.emitSignals(this);
       
   729 #endif
   689 
   730 
   690     return returnValue;
   731     return returnValue;
   691 }
   732 }
   692 
   733 
   693 bool CntSymbianEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error* error)
   734 bool CntSymbianEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error* error)
   694 {
   735 {
   695     //affected contacts
       
   696     QContactChangeSet changeSet;
       
   697 
       
   698     //remove the relationship
   736     //remove the relationship
   699     QSet<QContactLocalId> affectedContactIds;
   737     QSet<QContactLocalId> affectedContactIds;
   700     bool returnValue = m_relationship->removeRelationship(&affectedContactIds, relationship, error);
   738     bool returnValue = m_relationship->removeRelationship(&affectedContactIds, relationship, error);
       
   739     
       
   740 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
       
   741     //affected contacts
       
   742     QContactChangeSet changeSet;
   701     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   743     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   702 
   744 
   703     //add contacts to the list that shouldn't be emitted
   745     //add contacts to the list that shouldn't be emitted
   704     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   746     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   705 
   747 
   706     //emit signals
   748     //emit signals
   707     changeSet.emitSignals(this);
   749     changeSet.emitSignals(this);
       
   750 #endif
   708 
   751 
   709     return returnValue;
   752     return returnValue;
   710 }
   753 }
   711 
   754 
   712 bool CntSymbianEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   755 bool CntSymbianEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   713 {
   756 {
   714     //affected contacts
       
   715     QContactChangeSet changeSet;
       
   716 
       
   717     //remove the relationships
   757     //remove the relationships
   718     QSet<QContactLocalId> affectedContactIds;
   758     QSet<QContactLocalId> affectedContactIds;
   719     bool returnValue = m_relationship->removeRelationships(&affectedContactIds, relationships, errorMap, error);
   759     bool returnValue = m_relationship->removeRelationships(&affectedContactIds, relationships, errorMap, error);
       
   760     
       
   761 #ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
       
   762     //affected contacts
       
   763     QContactChangeSet changeSet;
   720     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   764     changeSet.insertRemovedRelationshipsContacts(affectedContactIds.toList());
   721 
   765 
   722     //add contacts to the list that shouldn't be emitted
   766     //add contacts to the list that shouldn't be emitted
   723     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   767     m_dataBase->appendContactsEmitted(affectedContactIds.toList());
   724 
   768 
   725     //emit signals
   769     //emit signals
   726     changeSet.emitSignals(this);
   770     changeSet.emitSignals(this);
       
   771 #endif
   727 
   772 
   728     return returnValue;
   773     return returnValue;
   729 }
   774 }
   730 
   775 
   731 QMap<QString, QContactDetailDefinition> CntSymbianEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const
   776 QMap<QString, QContactDetailDefinition> CntSymbianEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const
   732 {
   777 {
   733     // TODO: update for SIM contacts later
       
   734     if (contactType != QContactType::TypeContact && contactType != QContactType::TypeGroup) {
   778     if (contactType != QContactType::TypeContact && contactType != QContactType::TypeGroup) {
   735         *error = QContactManager::InvalidContactTypeError;
   779         *error = QContactManager::InvalidContactTypeError;
   736         return QMap<QString, QContactDetailDefinition>();
   780         return QMap<QString, QContactDetailDefinition>();
   737     }
   781     }
   738 
   782