--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/src/cntlistmodel.cpp Tue Aug 31 15:05:21 2010 +0300
@@ -0,0 +1,867 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "cntlistmodel_p.h"
+#include "cntlistmodel.h"
+#include "cntcache.h"
+#include "cntdebug.h"
+
+#include <qtcontacts.h>
+#include <QSet>
+#include <QTimerEvent>
+
+#include <hbindexfeedback.h>
+#include <hbframebackground.h>
+#include <hbframedrawer.h>
+#include <xqsettingsmanager.h> // for reading cenrep keys
+#include <xqsettingskey.h>
+
+const uint dummyMyCardId = 0;
+
+/*!
+ * Constuct a new contact model instance. The model will own its handle
+ * to the default persisted store.
+ */
+CntListModel::CntListModel(const QContactFilter& contactFilter,
+ bool showMyCard,
+ QObject *parent)
+ : QAbstractListModel(parent)
+{
+ CNT_ENTRY
+ m_defaultIcon = HbIcon("qtg_large_avatar");
+ m_defaultMyCardIcon = HbIcon("qtg_large_avatar_mycard");
+
+ d = new CntListModelData(contactFilter, showMyCard);
+ d->m_contactManager = new QContactManager;
+ d->m_ownedContactManager = true;
+ d->m_cache = CntCache::instance();
+ connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
+ d->m_myCardId = d->m_contactManager->selfContactId();
+ if (doConstruct() != QContactManager::NoError) {
+ throw("exception");
+ }
+ CNT_EXIT
+}
+
+/*!
+ * Construct a new CntListModel object using manager as the QContactManager
+ * instance to communicate with the contacts database.
+ *
+ * \param manager A QContactManager instance to be used for
+ * communications with the contacts persistant store.
+ */
+CntListModel::CntListModel(QContactManager* manager,
+ const QContactFilter& contactFilter,
+ bool showMyCard,
+ QObject *parent)
+ : QAbstractListModel(parent)
+{
+ CNT_ENTRY
+ m_defaultIcon = HbIcon("qtg_large_avatar");
+ m_defaultMyCardIcon = HbIcon("qtg_large_avatar_mycard");
+
+ d = new CntListModelData(contactFilter, showMyCard);
+
+ d->m_contactManager = manager;
+ d->m_cache = CntCache::instance();
+
+ connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
+ d->m_myCardId = d->m_contactManager->selfContactId();
+
+ if (doConstruct() != QContactManager::NoError) {
+ throw("exception");
+ }
+ CNT_EXIT
+}
+
+CntListModel::~CntListModel()
+{
+}
+
+/*!
+ * Return the data to be used by the view or delegates for a particular
+ * item and role.
+ *
+ * \param index The index of the item to return data about.
+ * \param role The data should be relevant for this particular purpose.
+ * \return QVariant The data for the specified index and role.
+ */
+QVariant CntListModel::data(const QModelIndex &index, int role) const
+{
+ CNT_ENTRY
+ int row = index.row();
+
+ // check that row is ok
+ if (!validRowId(row)) {
+ // invalid row
+ return QVariant();
+ }
+
+ // update current contact if needed
+ if (row != d->m_currentRow ) {
+ if (d->m_contactIds[row] == dummyMyCardId) {
+ // row contains dummy MyCard, so create dummy CntContactInfo
+ d->m_currentContact = CntContactInfo();
+ }
+ else {
+ d->m_currentContact = d->m_cache->fetchContactInfo(row, d->m_contactIds);
+ }
+ d->m_currentRow = row;
+ }
+
+ if (role == Qt::DisplayRole) {
+ return dataForRole(row, role);
+ }
+ else if (role == Hb::IndexFeedbackRole) {
+ if (row == 0 && (d->m_myCardId == d->m_contactIds[0] || dummyMyCardId == d->m_contactIds[0])) {
+ // do not include MyCard in index feedback
+ return QVariant();
+ }
+ else {
+ return dataForRole(row, role).toStringList().at(0).toUpper();
+ }
+ }
+ else if (role == Qt::BackgroundRole) {
+ if (d->m_myCardId == d->m_contactIds[row] || dummyMyCardId == d->m_contactIds[row]) {
+ return HbFrameBackground("qtg_fr_list_parent_normal", HbFrameDrawer::NinePieces);
+ }
+ }
+ else if (role == Qt::DecorationRole) {
+ if (d->m_currentRowSetting == CntTwoRowsNameAndPhoneNumber) {
+ //icon fits only if user selected 2 rows in each name list item
+ QList<QVariant> icons;
+ HbIcon avatar = d->m_currentContact.icon1();
+ HbIcon statusIcon = d->m_currentContact.icon2();
+
+ if (!avatar.isNull()) {
+ icons.append(avatar);
+ }
+ else if (d->m_myCardId == d->m_contactIds[row] || dummyMyCardId == d->m_contactIds[row]) {
+ icons.append(m_defaultMyCardIcon);
+ }
+ else {
+ icons.append(m_defaultIcon);
+ }
+
+ if (!statusIcon.isNull()) {
+ icons.append(statusIcon);
+ }
+
+ return icons;
+ }
+ else {
+ return QVariant();
+ }
+ }
+ CNT_EXIT
+ return QVariant();
+}
+
+/*!
+ * Get the number of rows (contacts) in this model.
+ *
+ * \param parent Optional parent index value.
+ * \return Number of contacts in this model.
+ */
+int CntListModel::rowCount(const QModelIndex& /*parent*/) const
+{
+ return d->m_contactIds.count();
+}
+
+/*!
+ * Read a full contact entry from the database for the given model
+ * index value. Only the row part of the index information will be
+ * read. This is just an overload of CntListModel::contact() that
+ * supports old behaviour and calls:
+ * CntListModel::contact(int row);
+ *
+ * The entry at the requested row will have its full contact information
+ * (all fields) read from the database and returned as a QContact instance.
+ *
+ * \param index Index for the sought contact entry in this model.
+ * \return A newly constructed QContact instance for this entry - ownership
+ * is transferred to the caller.
+ *
+ */
+QContact CntListModel::contact(const QModelIndex &index) const
+{
+ return contact(index.row());
+}
+
+/*!
+ * Returns the id for the contact at the requested row.
+ *
+ * \param index Index for the sought contact entry in this model.
+ * \return The id for the contact, 0 if invalid index.
+ *
+ */
+QContactLocalId CntListModel::contactId(const QModelIndex &index) const
+{
+ CNT_ENTRY
+
+ if (!validRowId(index.row())) {
+ return 0;
+ }
+
+ CNT_EXIT
+ return d->m_contactIds[index.row()];
+}
+
+/*!
+ * Return an index that points to the row relating to the supplied contact.
+ * E.g. if the contact is at row 7, the index with the following properties
+ * is returned:
+ * index.row() == 7
+
+ * \param contact The contact for whose row an index is required
+ * \return a QModelIndex with the row set to match that of the contact.
+ */
+QModelIndex CntListModel::indexOfContact(const QContact &contact) const
+{
+ return createIndex(rowId(contact.localId()), 0);
+}
+
+/*!
+ * Return an index that points to the row relating to the supplied contact id.
+ * E.g. if the contact with this id is at row 7, the index with the following
+ * properties is returned:
+ * index.row() == 7
+
+ * \param contactId The id of the contact for whose row an index is required
+ * \return a QModelIndex with the row set to match that of the contact id.
+ */
+QModelIndex CntListModel::indexOfContactId(const QContactLocalId &contactId) const
+{
+ return createIndex(rowId(contactId), 0);
+}
+
+/*!
+ * Return the contact manager used by this model.
+ *
+ * \return Reference to contact manager.
+ */
+QContactManager& CntListModel::contactManager() const
+{
+ return *d->m_contactManager;
+}
+
+/*!
+ * Set new filter and sort order for the model.
+ *
+ * \param contactFilter New contact filter.
+ * \param contactSortOrders New sort order.
+ */
+void CntListModel::setFilter(const QContactFilter& contactFilter)
+{
+ CNT_ENTRY
+
+ d->setFilter(contactFilter);
+
+ //refresh model
+ updateContactIdsArray();
+
+ beginResetModel();
+ reset();
+ endResetModel();
+
+ CNT_EXIT
+}
+
+void CntListModel::setSortOrder()
+{
+ XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+ KCRCntSettings.iUid,
+ KCntNameOrdering);
+ XQSettingsManager settingsMng;
+ int order = settingsMng.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+
+ QContactSortOrder sortOrderFirstName;
+ sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
+ QContactName::FieldFirstName);
+ sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
+
+ QContactSortOrder sortOrderLastName;
+ sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
+ QContactName::FieldLastName);
+ sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
+
+ QList<QContactSortOrder> sortOrders;
+ if (order == CntOrderLastFirst || order == CntOrderLastCommaFirst) {
+ sortOrders.append(sortOrderLastName);
+ sortOrders.append(sortOrderFirstName);
+ } else {
+ sortOrders.append(sortOrderFirstName);
+ sortOrders.append(sortOrderLastName);
+ }
+
+ d->m_sortOrders = sortOrders;
+}
+
+void CntListModel::refreshModel()
+{
+ CNT_ENTRY
+
+ setSortOrder();
+ d->m_cache->clearCache();
+ d->m_currentRow = -1;
+
+ //refresh model
+ updateContactIdsArray();
+
+ beginResetModel();
+ reset();
+ endResetModel();
+
+ CNT_EXIT
+}
+
+/*!
+ * Enable/disable MyCard appearance in the model.
+ *
+ * \param enabled Status of MyCard appearance in the model.
+ */
+void CntListModel::showMyCard(bool enabled)
+{
+ CNT_ENTRY
+ if (d->m_showMyCard == enabled) {
+ return;
+ }
+
+ QContactLocalId myCardId = d->m_myCardId;
+ if (enabled) {
+ //add MyCard to the list
+ if (myCardId <= 0) {
+ // create a placeholder for MyCard
+ d->m_contactIds.insert(0, dummyMyCardId);
+ }
+ else {
+ d->m_contactIds.insert(0, myCardId);
+ }
+ }
+ else {
+ // remove MyCard from the list
+ if (myCardId <= 0) {
+ d->m_contactIds.removeOne(dummyMyCardId);
+ }
+ else {
+ d->m_contactIds.removeOne(myCardId);
+ }
+ }
+ d->m_showMyCard = enabled;
+ d->m_currentRow = -1;
+
+ beginResetModel();
+ reset();
+ endResetModel();
+ CNT_EXIT
+}
+
+/*!
+ * Returns MyCard status: shown or not.
+ *
+ * \return true if MyCard is shown, false otherwise.
+ */
+bool CntListModel::myCardStatus() const
+{
+ return d->m_showMyCard;
+}
+
+/*!
+ * Returns MyCard id.
+ *
+ * \return MyCard id.
+ */
+QContactLocalId CntListModel::myCardId() const
+{
+ return d->m_myCardId;
+}
+
+/*!
+ * Initializes model data and attaches database notifications to handlers.
+ *
+ * \return Error status
+ */
+int CntListModel::doConstruct()
+{
+ CNT_ENTRY
+
+ int error = initializeData();
+
+ // Attach database notifications to handlers.
+ connect(d->m_contactManager, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&)));
+ connect(d->m_contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&)));
+ connect(d->m_contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&)));
+ connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&)));
+ connect(d->m_contactManager, SIGNAL(dataChanged()), this, SLOT(refreshModel()));
+ connect(d->m_contactManager, SIGNAL(relationshipsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAddedRelationship(const QList<QContactLocalId>&)));
+ connect(d->m_contactManager, SIGNAL(relationshipsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemovedRelationship(const QList<QContactLocalId>&)));
+
+ // Get current setting how to show an item in the name list and subscribe for changes
+ d->m_Settings = new XQSettingsManager;
+
+ d->m_NameListRowSettingkey = new XQSettingsKey(XQSettingsKey::TargetCentralRepository,
+ KCRCntSettings.iUid,
+ KCntNameListRowSetting);
+ d->m_currentRowSetting = d->m_Settings->readItemValue(*d->m_NameListRowSettingkey, XQSettingsManager::TypeInt).toInt();
+ d->m_Settings->startMonitoring(*d->m_NameListRowSettingkey, XQSettingsManager::TypeInt);
+ connect(d->m_Settings, SIGNAL(valueChanged(const XQSettingsKey&, const QVariant&)), this, SLOT(handleRowSettingChanged(const XQSettingsKey&, const QVariant&)));
+
+ CNT_EXIT
+
+ return error;
+}
+
+/*!
+ * Initializes d->m_contactIds to contain contact Ids from the database.
+ *
+ * \return Error status
+ */
+int CntListModel::initializeData()
+{
+ CNT_ENTRY
+ int error(QContactManager::NoError);
+
+ setSortOrder();
+
+ // Get a list of all contact IDs in the database.
+ updateContactIdsArray();
+
+ CNT_EXIT
+ return error;
+}
+
+/*!
+ * Gets the filtered list of the contact Ids in a sorted order
+ *
+ * \return Error status
+ */
+void CntListModel::updateContactIdsArray()
+{
+ CNT_ENTRY
+ d->m_contactIds = d->m_contactManager->contactIds(d->m_filter,
+ d->m_sortOrders);
+
+ //find MyCard contact and move it to the first position
+ QContactLocalId myCardId = d->m_myCardId;
+ if (myCardId > 0) {
+ // MyCard exists
+ d->m_contactIds.removeOne(myCardId);
+ if (d->m_showMyCard) {
+ d->m_contactIds.insert(0, myCardId);
+ }
+ }
+ else if (d->m_showMyCard) {
+ // create a placeholder for MyCard
+ d->m_contactIds.insert(0, dummyMyCardId);
+ }
+ CNT_EXIT
+}
+
+/*!
+ * Read a full contact entry from the database for the row number.
+ *
+ * The entry at the requested row will have its full contact information
+ * (all fields) read from the database and returned as a QContact instance.
+ *
+ * \param row Row at which the sought contact entry is in this model.
+ * \return A newly constructed QContact instance for this entry - ownership
+ * is transferred to the caller.
+ *
+ */
+QContact CntListModel::contact(int row) const
+{
+ CNT_ENTRY
+ if (!validRowId(row) || d->m_contactIds[row] == dummyMyCardId) {
+ return QContact();
+ }
+ CNT_EXIT
+ return d->m_contactManager->contact(d->m_contactIds[row]);
+}
+
+/*!
+ * Verify specified row id is valid.
+ *
+ * \param row A row number
+ * \return bool indicating validity of row id
+ */
+bool CntListModel::validRowId(int row) const
+{
+ return (row >= 0 && row < rowCount());
+}
+
+/*!
+ * Fetch the id of the row containing the contact of the specified id.
+ *
+ * \param contactId The id of the contact
+ * \return the row id of the contact or -1 if no item matched.
+ */
+int CntListModel::rowId(const QContactLocalId &contactId) const
+{
+ return d->m_contactIds.indexOf(contactId);
+}
+
+/*!
+ * Return the data to be used by the view for a display role.
+ *
+ * \param row The row of the item to return data about.
+ * \param column The column of the item to return data about.
+ * \return QVariant The data for the specified index.
+ */
+QVariant CntListModel::dataForRole(int row, int role) const
+{
+ CNT_ENTRY
+ QStringList list;
+ QString name;
+ QString infoText;
+ bool isSelfContact = false;
+ bool isNonEmptySelfContact = false;
+
+ QContactLocalId id = d->m_contactIds[row];
+ if (d->m_myCardId == id || dummyMyCardId == id) {
+ isSelfContact = true;
+ if (d->m_currentContact.id() == -1) {
+ // empty card
+ name = hbTrId("txt_phob_dblist_mycard");
+ infoText = hbTrId("txt_phob_dblist_mycard_val_create_my_identity");
+ }
+ else {
+ isNonEmptySelfContact = true;
+ }
+ }
+
+ if (!isSelfContact || isNonEmptySelfContact) {
+ name = d->m_currentContact.name();
+ if (name.isEmpty()) {
+ name = hbTrId("txt_phob_list_unnamed");
+ }
+ infoText = d->m_currentContact.text();
+ }
+
+ if ( role == Qt::DisplayRole )
+ {
+ list << d->m_Format->formattedText(name, d->m_filter);
+ }
+ else
+ {
+ list << name;
+ }
+
+ if (!isNonEmptySelfContact) {
+ if (d->m_currentRowSetting == CntTwoRowsNameAndPhoneNumber) {
+ //add additional text only if user wants 2 rows in each name list item
+ list << infoText;
+ }
+ }
+ CNT_EXIT
+ return list;
+}
+
+/*!
+ * Handle adding of contacts.
+ *
+ * \param contactIds Ids of contacts added.
+ */
+void CntListModel::handleAdded(const QList<QContactLocalId>& contactIds)
+{
+ CNT_ENTRY
+
+ //if contacts are added already, no need to do anything
+ bool newContacts = false;
+ for (int k = 0; k < contactIds.count() && !newContacts; k++) {
+ if(!d->m_contactIds.contains(contactIds.at(k))) {
+ newContacts = true;
+ }
+ }
+ if (!newContacts) {
+ return;
+ }
+
+ //invalidate cached contact
+ d->m_currentRow = -1;
+
+ QList<QContactLocalId> oldIdList = d->m_contactIds;
+ updateContactIdsArray();
+
+ //Find all new contacts (=rows)
+ QList<int> newRows;
+ for(int i = 0; i < d->m_contactIds.count(); i++) {
+ if (!oldIdList.contains(d->m_contactIds.at(i))) {
+ newRows.append(i);
+ }
+ }
+
+ // only 1 (or no) contact is added, it can be handled by beginInsertRows()
+ // and endInsertRows()
+ if (newRows.count() <= 1) {
+ for(int j = 0; j < newRows.count(); j++) {
+ beginInsertRows(QModelIndex(), newRows.at(j), newRows.at(j));
+ endInsertRows();
+ }
+ }
+ else {
+ beginResetModel();
+ reset();
+ endResetModel();
+ }
+ CNT_EXIT
+}
+
+/*!
+ * Handle changes in contacts.
+ *
+ * \param contactIds Ids of contacts changed.
+ */
+void CntListModel::handleChanged(const QList<QContactLocalId>& contactIds)
+{
+ CNT_ENTRY
+
+ if (contactIds.count() == 0) {
+ return;
+ }
+
+ //invalidate cached contact
+ d->m_currentRow = -1;
+
+ int firstChangedContactPosBefore = rowId(contactIds.at(0));
+ updateContactIdsArray();
+ int firstChangedContactPosAfter = rowId(contactIds.at(0));
+
+ // if only one contact was updated and its position didn't change,
+ // refresh the corresponding row
+ if (contactIds.count() == 1 &&
+ firstChangedContactPosBefore == firstChangedContactPosAfter &&
+ firstChangedContactPosBefore >= 0) {
+ QModelIndex top = index(firstChangedContactPosBefore);
+ QModelIndex bottom = index(firstChangedContactPosBefore);
+ emit dataChanged(top, bottom);
+ }
+ else {
+ beginResetModel();
+ reset();
+ endResetModel();
+ }
+
+ CNT_EXIT
+}
+
+/*!
+ * Handle removing of contacts.
+ *
+ * \param contactIds Ids of contacts removed.
+ */
+void CntListModel::handleRemoved(const QList<QContactLocalId>& contactIds)
+{
+ CNT_ENTRY
+
+ bool removeContacts = false;
+ QList<QContactLocalId> idList = d->m_contactIds;
+ for (int k = 0; k < contactIds.count() && !removeContacts; k++) {
+ if(idList.contains(contactIds.at(k))) {
+ removeContacts = true;
+ }
+ }
+ if (!removeContacts) {
+ return;
+ }
+
+ //Find contacts to remove (=rows)
+ QList<int> removeRows;
+ for(int i = 0; i < contactIds.count(); i++) {
+ if (idList.contains(contactIds.at(i))) {
+ removeRows.append(rowId(contactIds.at(i)));
+ }
+ }
+
+ // invalidate cached contact
+ d->m_currentRow = -1;
+
+ int myCardRow = -1;
+ if (contactIds.contains(d->m_myCardId)) {
+ myCardRow = rowId(d->m_myCardId);
+ d->m_myCardId = 0;
+ }
+
+ // remove rows starting from the bottom
+ qSort(removeRows.begin(), removeRows.end(), qGreater<int>());
+ for (int j = 0; j < removeRows.count(); j++) {
+ if (removeRows.at(j) != myCardRow || !d->m_showMyCard) {
+ beginRemoveRows(QModelIndex(), removeRows.at(j), removeRows.at(j));
+ endRemoveRows();
+ }
+ }
+
+ foreach (QContactLocalId id, contactIds) {
+ d->m_contactIds.removeOne(id);
+ }
+
+ if (myCardRow != -1 && d->m_showMyCard) {
+ d->m_contactIds.insert(0, dummyMyCardId);
+ QModelIndex index = createIndex(0, 0);
+ emit dataChanged(index, index);
+ }
+
+ CNT_EXIT
+}
+
+/*!
+ * Handle my card change.
+ *
+ * \param oldId Id of the old MyCard.
+ * \param newId Id of the new MyCard.
+ */
+void CntListModel::handleMyCardChanged(const QContactLocalId& /*oldId*/, const QContactLocalId& newId)
+{
+ CNT_ENTRY
+
+ //invalidate cached contact
+ d->m_currentRow = -1;
+ d->m_myCardId = newId;
+
+ updateContactIdsArray();
+
+ beginResetModel();
+ reset();
+ endResetModel();
+
+ CNT_EXIT
+}
+
+/*!
+ * Handle added relationships.
+ *
+ * \param contactIds Ids of contacts added (group id and contact ids).
+ */
+void CntListModel::handleAddedRelationship(const QList<QContactLocalId>& contactIds)
+{
+ CNT_ENTRY
+
+ if (contactIds.contains(d->m_groupId)) {
+ foreach (QContactLocalId id, contactIds) {
+ if (id != d->m_groupId && !d->m_contactIds.contains(id)) {
+ // at least one new contact id has been added to this group,
+ // so update the model
+ updateRelationships();
+ break;
+ }
+ }
+ }
+
+ CNT_EXIT
+}
+
+/*!
+ * Handle removed relationships.
+ *
+ * \param contactIds Ids of contacts removed from a relationship (group id and contact ids).
+ */
+void CntListModel::handleRemovedRelationship(const QList<QContactLocalId>& contactIds)
+{
+ CNT_ENTRY
+
+ if (contactIds.contains(d->m_groupId)) {
+ foreach (QContactLocalId id, contactIds) {
+ if (d->m_contactIds.contains(id)) {
+ // at least one new contact id has been removed from this group,
+ // so update the model
+ updateRelationships();
+ break;
+ }
+ }
+ }
+
+ CNT_EXIT
+}
+
+/*!
+ * Updates the model to reflect changes in the relationships.
+ */
+void CntListModel::updateRelationships()
+{
+ CNT_ENTRY
+
+ //invalidate cached contact
+ d->m_currentRow = -1;
+
+ QList<QContactLocalId> oldIdList = d->m_contactIds;
+ updateContactIdsArray();
+
+ // find all changed rows
+ QList<int> newRows, removedRows;
+ for (int i = 0; i < d->m_contactIds.count(); i++) {
+ if (!oldIdList.contains(d->m_contactIds.at(i))) {
+ newRows.append(i);
+ }
+ }
+ for (int i = 0; i < oldIdList.count(); i++) {
+ if (!d->m_contactIds.contains(oldIdList.at(i))) {
+ removedRows.append(i);
+ }
+ }
+
+ // currently only one-row-changes are handled with beginInsertRows/beginRemoveRows
+ // if there are more than one change, the whole model is reset
+ if (removedRows.count() == 1 && newRows.count() == 0) {
+ beginRemoveRows(QModelIndex(), removedRows.at(0), removedRows.at(0));
+ endRemoveRows();
+ }
+ else if (newRows.count() == 1 && removedRows.count() == 0) {
+ beginInsertRows(QModelIndex(), newRows.at(0), newRows.at(0));
+ endInsertRows();
+ }
+ else {
+ beginResetModel();
+ endResetModel();
+ }
+
+ CNT_EXIT
+}
+
+/*!
+* Notify views that info for a contact has become
+* available or has changed.
+*
+* \param contactId the id of the contact
+*/
+void CntListModel::handleContactInfoUpdated(QContactLocalId contactId)
+{
+ CNT_ENTRY
+
+ QModelIndex index = createIndex(rowId(contactId), 0);
+ if (index.row() == d->m_currentRow) {
+ d->m_currentRow = -1;
+ }
+ emit dataChanged(index, index);
+
+ CNT_EXIT
+}
+
+/*!
+* Handle a change how name list item should be represented
+*
+* \param key Central repository key
+* \param value New value in the key
+*/
+void CntListModel::handleRowSettingChanged(const XQSettingsKey& /*key*/, const QVariant& value)
+{
+ bool ok = false;
+ int newSetting = value.toInt(&ok);
+ if (ok) {
+ d->m_currentRowSetting = newSetting;
+ beginResetModel();
+ reset();
+ endResetModel();
+ }
+}