phonebookengines/cntlistmodel/src/cntlistmodel.cpp
changeset 72 6abfb1094884
parent 61 d30183af6ca6
equal deleted inserted replaced
67:59984e68247d 72:6abfb1094884
    30 #include <xqsettingskey.h>
    30 #include <xqsettingskey.h>
    31 
    31 
    32 const uint dummyMyCardId = 0;
    32 const uint dummyMyCardId = 0;
    33 
    33 
    34 /*!
    34 /*!
    35  * Constuct a new contact model instance. The model will own its handle
    35  * Construct a new CntListModel object using manager as the QContactManager
    36  * to the default persisted store.
    36  * instance to communicate with the contacts database.
    37  */
    37  *
    38 CntListModel::CntListModel(const QContactFilter& contactFilter,
    38  * \param manager A QContactManager instance to be used for
    39                          bool showMyCard,
    39  *  communications with the contacts persistant store.
    40                          QObject *parent)
    40  */
       
    41 CntListModel::CntListModel(QContactManager* manager,
       
    42                            const QContactFilter& contactFilter,
       
    43                            bool showMyCard,
       
    44                            QObject *parent)
    41     : QAbstractListModel(parent)
    45     : QAbstractListModel(parent)
    42 {
    46 {
    43     CNT_ENTRY
    47     CNT_ENTRY
       
    48 
       
    49     // create icons
    44     m_defaultIcon = HbIcon("qtg_large_avatar");
    50     m_defaultIcon = HbIcon("qtg_large_avatar");
    45     m_defaultMyCardIcon = HbIcon("qtg_large_avatar_mycard");
    51     m_defaultMyCardIcon = HbIcon("qtg_large_avatar_mycard");
    46 
    52 
       
    53     // set up data
    47     d = new CntListModelData(contactFilter, showMyCard);
    54     d = new CntListModelData(contactFilter, showMyCard);
    48     d->m_contactManager = new QContactManager;
    55     d->m_contactManager = manager;
    49     d->m_ownedContactManager = true;
    56     d->m_cache = CntCache::instance(d->m_contactManager);
    50     d->m_cache = CntCache::instance();
    57     d->m_myCardId = d->m_contactManager->selfContactId();     
       
    58     updateContactIdsArray();
       
    59     
       
    60     // get current setting how to show an item in the name list and subscribe for changes
       
    61     d->m_Settings = new XQSettingsManager;
       
    62     d->m_NameListRowSettingkey = new XQSettingsKey(XQSettingsKey::TargetCentralRepository,
       
    63         KCRCntSettings.iUid,
       
    64         KCntNameListRowSetting);
       
    65     d->m_currentRowSetting = d->m_Settings->readItemValue(*d->m_NameListRowSettingkey,
       
    66         XQSettingsManager::TypeInt).toInt();
       
    67     d->m_Settings->startMonitoring(*d->m_NameListRowSettingkey, XQSettingsManager::TypeInt);
       
    68     connect(d->m_Settings, SIGNAL(valueChanged(const XQSettingsKey&, const QVariant&)), this, SLOT(handleRowSettingChanged(const XQSettingsKey&, const QVariant&)));
       
    69     
       
    70     // listen to cache for changes in contacts
    51     connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
    71     connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
    52     d->m_myCardId = d->m_contactManager->selfContactId();
    72     connect(d->m_cache, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&)));
    53     if (doConstruct() != QContactManager::NoError) {
    73     connect(d->m_cache, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&)));
    54         throw("exception");
    74     connect(d->m_cache, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&)));
    55     }
    75     connect(d->m_cache, SIGNAL(dataChanged()), this, SLOT(refreshModel()));
    56     CNT_EXIT
    76 
    57 }
    77     // listen to contactmanager for changes in relationships or mycard
    58 
    78     connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&)));
    59 /*!
    79     connect(d->m_contactManager, SIGNAL(relationshipsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAddedRelationship(const QList<QContactLocalId>&)));
    60  * Construct a new CntListModel object using manager as the QContactManager
    80     connect(d->m_contactManager, SIGNAL(relationshipsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemovedRelationship(const QList<QContactLocalId>&)));
    61  * instance to communicate with the contacts database.
    81 
    62  *
       
    63  * \param manager A QContactManager instance to be used for
       
    64  *  communications with the contacts persistant store.
       
    65  */
       
    66 CntListModel::CntListModel(QContactManager* manager,
       
    67                          const QContactFilter& contactFilter,
       
    68                          bool showMyCard,
       
    69                          QObject *parent)
       
    70     : QAbstractListModel(parent)
       
    71 {
       
    72     CNT_ENTRY
       
    73     m_defaultIcon = HbIcon("qtg_large_avatar");
       
    74     m_defaultMyCardIcon = HbIcon("qtg_large_avatar_mycard");
       
    75 
       
    76     d = new CntListModelData(contactFilter, showMyCard);
       
    77 
       
    78     d->m_contactManager = manager;
       
    79     d->m_cache = CntCache::instance();
       
    80 
       
    81     connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
       
    82     d->m_myCardId = d->m_contactManager->selfContactId();     
       
    83 
       
    84     if (doConstruct() != QContactManager::NoError) {
       
    85         throw("exception");
       
    86     }
       
    87     CNT_EXIT
    82     CNT_EXIT
    88 }
    83 }
    89 
    84 
    90 CntListModel::~CntListModel()
    85 CntListModel::~CntListModel()
    91 {
    86 {
   247 {
   242 {
   248     return createIndex(rowId(contactId), 0);
   243     return createIndex(rowId(contactId), 0);
   249 }
   244 }
   250 
   245 
   251 /*!
   246 /*!
   252  * Return the contact manager used by this model.
       
   253  *
       
   254  * \return Reference to contact manager.
       
   255  */
       
   256 QContactManager& CntListModel::contactManager() const
       
   257 {
       
   258     return *d->m_contactManager;
       
   259 }
       
   260 
       
   261 /*!
       
   262  * Set new filter and sort order for the model.
   247  * Set new filter and sort order for the model.
   263  *
   248  *
   264  * \param contactFilter New contact filter.
   249  * \param contactFilter New contact filter.
   265  * \param contactSortOrders New sort order.
   250  * \param contactSortOrders New sort order.
   266  */
   251  */
   267 void CntListModel::setFilter(const QContactFilter& contactFilter)
   252 void CntListModel::setFilter(const QContactFilter& contactFilter)
   268 {
   253 {
   269     CNT_ENTRY
   254     CNT_ENTRY
   270     
   255     
   271     d->setFilter(contactFilter);
   256     d->setFilter(contactFilter);
   272     
       
   273     //refresh model
       
   274     updateContactIdsArray();
       
   275 
       
   276     beginResetModel();
       
   277     reset();
       
   278     endResetModel();
       
   279     
       
   280     CNT_EXIT
       
   281 }
       
   282 
       
   283 void CntListModel::setSortOrder()
       
   284 {
       
   285     XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
       
   286                          KCRCntSettings.iUid,
       
   287                          KCntNameOrdering);
       
   288     XQSettingsManager settingsMng;
       
   289     int order = settingsMng.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
       
   290 
       
   291     QContactSortOrder sortOrderFirstName;
       
   292     sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
       
   293         QContactName::FieldFirstName);
       
   294     sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
       
   295 
       
   296     QContactSortOrder sortOrderLastName;
       
   297     sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
       
   298         QContactName::FieldLastName);
       
   299     sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
       
   300 
       
   301     QList<QContactSortOrder> sortOrders;
       
   302     if (order == CntOrderLastFirst || order == CntOrderLastCommaFirst) {
       
   303         sortOrders.append(sortOrderLastName);
       
   304         sortOrders.append(sortOrderFirstName);
       
   305     } else {
       
   306         sortOrders.append(sortOrderFirstName);
       
   307         sortOrders.append(sortOrderLastName);
       
   308     }
       
   309     
       
   310     d->m_sortOrders = sortOrders;
       
   311 }
       
   312 
       
   313 void CntListModel::refreshModel()
       
   314 {
       
   315     CNT_ENTRY
       
   316     
       
   317     setSortOrder();
       
   318     d->m_cache->clearCache();
       
   319     d->m_currentRow = -1;
       
   320     
   257     
   321     //refresh model
   258     //refresh model
   322     updateContactIdsArray();
   259     updateContactIdsArray();
   323 
   260 
   324     beginResetModel();
   261     beginResetModel();
   388 {
   325 {
   389     return d->m_myCardId;
   326     return d->m_myCardId;
   390 }
   327 }
   391 
   328 
   392 /*!
   329 /*!
   393  * Initializes model data and attaches database notifications to handlers.
       
   394  * 
       
   395  * \return Error status
       
   396  */
       
   397 int CntListModel::doConstruct()
       
   398 {
       
   399     CNT_ENTRY
       
   400     
       
   401     int error = initializeData();
       
   402     
       
   403     // Attach database notifications to handlers.
       
   404     connect(d->m_contactManager, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&)));
       
   405     connect(d->m_contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&)));
       
   406     connect(d->m_contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&)));
       
   407     connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&)));
       
   408     connect(d->m_contactManager, SIGNAL(dataChanged()), this, SLOT(refreshModel()));
       
   409     connect(d->m_contactManager, SIGNAL(relationshipsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAddedRelationship(const QList<QContactLocalId>&)));
       
   410     connect(d->m_contactManager, SIGNAL(relationshipsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemovedRelationship(const QList<QContactLocalId>&)));
       
   411     
       
   412     // Get current setting how to show an item in the name list and subscribe for changes
       
   413     d->m_Settings = new XQSettingsManager;
       
   414 
       
   415     d->m_NameListRowSettingkey = new XQSettingsKey(XQSettingsKey::TargetCentralRepository,
       
   416                             KCRCntSettings.iUid,
       
   417                             KCntNameListRowSetting);
       
   418     d->m_currentRowSetting = d->m_Settings->readItemValue(*d->m_NameListRowSettingkey, XQSettingsManager::TypeInt).toInt();
       
   419     d->m_Settings->startMonitoring(*d->m_NameListRowSettingkey, XQSettingsManager::TypeInt);
       
   420     connect(d->m_Settings, SIGNAL(valueChanged(const XQSettingsKey&, const QVariant&)), this, SLOT(handleRowSettingChanged(const XQSettingsKey&, const QVariant&)));
       
   421     
       
   422     CNT_EXIT
       
   423 
       
   424     return error;
       
   425 }
       
   426 
       
   427 /*!
       
   428  * Initializes d->m_contactIds to contain contact Ids from the database.
       
   429  * 
       
   430  * \return Error status
       
   431  */
       
   432 int CntListModel::initializeData()
       
   433 {
       
   434     CNT_ENTRY
       
   435     int error(QContactManager::NoError);
       
   436     
       
   437     setSortOrder();
       
   438 
       
   439     // Get a list of all contact IDs in the database.
       
   440     updateContactIdsArray();
       
   441 
       
   442     CNT_EXIT
       
   443     return error;
       
   444 }
       
   445 
       
   446 /*!
       
   447  * Gets the filtered list of the contact Ids in a sorted order  
   330  * Gets the filtered list of the contact Ids in a sorted order  
   448  * 
   331  * 
   449  * \return Error status
   332  * \return Error status
   450  */
   333  */
   451 void CntListModel::updateContactIdsArray()
   334 void CntListModel::updateContactIdsArray()
   452 {
   335 {
   453     CNT_ENTRY
   336     CNT_ENTRY
   454     d->m_contactIds = d->m_contactManager->contactIds(d->m_filter,
   337 
   455             d->m_sortOrders);
   338     QContactDetailFilter* detailFilter = NULL;
   456                       
   339 
       
   340     if (d->m_filter.type() == QContactFilter::ContactDetailFilter) {
       
   341         detailFilter = static_cast<QContactDetailFilter*>(&d->m_filter);
       
   342     }
       
   343 
       
   344     // special handling for all-contacts filter
       
   345     if (detailFilter
       
   346         && detailFilter->detailDefinitionName() == QContactType::DefinitionName
       
   347         && detailFilter->detailFieldName() == QContactType::FieldType
       
   348         && detailFilter->value() == QContactType::TypeContact) {
       
   349         d->m_contactIds = d->m_cache->sortIdsByName(NULL);
       
   350     } else if (detailFilter
       
   351         && detailFilter->detailDefinitionName() == QContactDisplayLabel::DefinitionName
       
   352         && detailFilter->detailFieldName() == QContactDisplayLabel::FieldLabel
       
   353         && detailFilter->matchFlags() == Qt::MatchStartsWith) {
       
   354         QStringList searchList = detailFilter->value().toStringList();
       
   355         d->m_contactIds = d->m_cache->sortIdsByName(searchList);
       
   356     } else {
       
   357         QSet<QContactLocalId> filterIds = d->m_contactManager->contactIds(d->m_filter).toSet();
       
   358         d->m_contactIds = d->m_cache->sortIdsByName(&filterIds);
       
   359     }
       
   360     
   457     //find MyCard contact and move it to the first position
   361     //find MyCard contact and move it to the first position
   458     QContactLocalId myCardId = d->m_myCardId;
   362     QContactLocalId myCardId = d->m_myCardId;
   459     if (myCardId > 0) {
   363     if (myCardId > 0) {
   460         // MyCard exists
   364         // MyCard exists
   461         d->m_contactIds.removeOne(myCardId);
   365         d->m_contactIds.removeOne(myCardId);
   576  */
   480  */
   577 void CntListModel::handleAdded(const QList<QContactLocalId>& contactIds)
   481 void CntListModel::handleAdded(const QList<QContactLocalId>& contactIds)
   578 {
   482 {
   579     CNT_ENTRY
   483     CNT_ENTRY
   580     
   484     
   581     //if contacts are added already, no need to do anything
   485     // if contacts are added already, no need to do anything
   582     bool newContacts = false;
   486     bool newContacts = false;
   583     for (int k = 0; k < contactIds.count() && !newContacts; k++) { 
   487     for (int k = 0; k < contactIds.count() && !newContacts; k++) { 
   584         if(!d->m_contactIds.contains(contactIds.at(k))) {
   488         if (!d->m_contactIds.contains(contactIds.at(k))) {
   585             newContacts = true;
   489             newContacts = true;
   586         }
   490         }
   587     }
   491     }
   588     if (!newContacts) {
   492     if (!newContacts) {
   589         return;
   493         return;
   590     }
   494     }
   591 
   495 
   592     //invalidate cached contact
   496     // invalidate cached contact
   593     d->m_currentRow = -1;
   497     d->m_currentRow = -1;
   594     
   498     
   595     QList<QContactLocalId> oldIdList = d->m_contactIds;
   499     QList<QContactLocalId> oldIdList = d->m_contactIds;
   596     updateContactIdsArray();
   500     updateContactIdsArray();
   597     
   501 
   598     //Find all new contacts (=rows)
       
   599     QList<int> newRows;
   502     QList<int> newRows;
   600     for(int i = 0; i < d->m_contactIds.count(); i++) {
   503     for (int i = 0; i < d->m_contactIds.count(); i++) {
   601         if (!oldIdList.contains(d->m_contactIds.at(i))) {
   504         if (!oldIdList.contains(d->m_contactIds.at(i))) {
   602             newRows.append(i);
   505             newRows.append(i);
   603         }
   506         }
   604     }
   507     }
   605     
   508 
   606     // only 1 (or no) contact is added, it can be handled by beginInsertRows()
   509     if (newRows.size() == 1) {
   607     // and endInsertRows()
   510         beginInsertRows(QModelIndex(), newRows.at(0), newRows.at(0));
   608     if (newRows.count() <= 1) {
   511         endInsertRows();
   609         for(int j = 0; j < newRows.count(); j++) {
   512     } else {
   610             beginInsertRows(QModelIndex(), newRows.at(j), newRows.at(j));
       
   611             endInsertRows();   
       
   612         }
       
   613     }
       
   614     else {
       
   615         beginResetModel();
   513         beginResetModel();
   616         reset();
   514         reset();
   617         endResetModel();
   515         endResetModel();
   618     }
   516     }
       
   517 
   619     CNT_EXIT
   518     CNT_EXIT
   620 }
   519 }
   621 
   520 
   622 /*!
   521 /*!
   623  * Handle changes in contacts. 
   522  * Handle changes in contacts. 
   629     CNT_ENTRY
   528     CNT_ENTRY
   630     
   529     
   631     if (contactIds.count() == 0) {
   530     if (contactIds.count() == 0) {
   632         return;
   531         return;
   633     }
   532     }
   634     
   533 
   635     //invalidate cached contact
   534     //invalidate cached contact
   636     d->m_currentRow = -1; 
   535     d->m_currentRow = -1; 
   637 
   536 
   638     int firstChangedContactPosBefore = rowId(contactIds.at(0));  
   537     int firstChangedContactPosBefore = rowId(contactIds.at(0));  
   639     updateContactIdsArray();
   538     updateContactIdsArray();
   694         d->m_myCardId = 0;
   593         d->m_myCardId = 0;
   695     }
   594     }
   696 
   595 
   697     // remove rows starting from the bottom
   596     // remove rows starting from the bottom
   698     qSort(removeRows.begin(), removeRows.end(), qGreater<int>());
   597     qSort(removeRows.begin(), removeRows.end(), qGreater<int>());
   699     for (int j = 0; j < removeRows.count(); j++) {
   598     foreach (int row, removeRows) {
   700         if (removeRows.at(j) != myCardRow || !d->m_showMyCard) {
   599         if (row != myCardRow || !d->m_showMyCard) {
   701             beginRemoveRows(QModelIndex(), removeRows.at(j), removeRows.at(j));
   600             beginRemoveRows(QModelIndex(), row, row);
   702             endRemoveRows();
   601             endRemoveRows();
   703         }
   602         }
   704     }
   603     }
   705 
   604 
   706     foreach (QContactLocalId id, contactIds) {
   605     foreach (QContactLocalId id, contactIds) {
   847     
   746     
   848     CNT_EXIT
   747     CNT_EXIT
   849 }
   748 }
   850 
   749 
   851 /*!
   750 /*!
   852 * Handle a change how name list item should be represented
   751 * Handle a change in how name list item should be represented
   853 *
   752 *
   854 * \param key Central repository key
   753 * \param key Central repository key
   855 * \param value New value in the key
   754 * \param value New value in the key
   856 */
   755 */
   857 void CntListModel::handleRowSettingChanged(const XQSettingsKey& /*key*/, const QVariant& value)
   756 void CntListModel::handleRowSettingChanged(const XQSettingsKey& /*key*/, const QVariant& value)
   863         beginResetModel();
   762         beginResetModel();
   864         reset();
   763         reset();
   865         endResetModel();
   764         endResetModel();
   866     }
   765     }
   867 }
   766 }
       
   767 
       
   768 /*!
       
   769 * Handle a change in data
       
   770 */
       
   771 void CntListModel::refreshModel()
       
   772 {
       
   773     d->m_currentRow = -1;
       
   774 
       
   775     updateContactIdsArray();
       
   776 
       
   777     beginResetModel();
       
   778     reset();
       
   779     endResetModel();
       
   780 }