34 */ |
34 */ |
35 MobCntModel::MobCntModel(const QContactFilter& contactFilter, |
35 MobCntModel::MobCntModel(const QContactFilter& contactFilter, |
36 const QList<QContactSortOrder>& contactSortOrders, |
36 const QList<QContactSortOrder>& contactSortOrders, |
37 bool showMyCard, |
37 bool showMyCard, |
38 QObject *parent) |
38 QObject *parent) |
39 : QAbstractListModel(parent), |
39 : QAbstractListModel(parent) |
40 mIconManager(0) |
40 { |
41 { |
|
42 mIconManager = new MobCntIconManager(); |
|
43 connect(mIconManager, SIGNAL(contactIconReady(int)), this, SLOT(updateContactIcon(int))); |
|
44 |
|
45 mDefaultIcon = HbIcon("qtg_large_avatar"); |
41 mDefaultIcon = HbIcon("qtg_large_avatar"); |
46 mDefaultMyCardIcon = HbIcon("qtg_large_mycard"); |
42 mDefaultMyCardIcon = HbIcon("qtg_large_mycard"); |
47 |
43 |
48 d = new MobCntModelData(contactFilter, contactSortOrders, showMyCard); |
44 d = new MobCntModelData(contactFilter, contactSortOrders, showMyCard); |
49 d->m_contactManager = new QContactManager; |
45 d->m_contactManager = new QContactManager; |
50 d->ownedContactManager = true; |
46 d->ownedContactManager = true; |
|
47 d->m_cache = CntCache::instance(); |
|
48 connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId))); |
51 d->mMyCardId = d->m_contactManager->selfContactId(); |
49 d->mMyCardId = d->m_contactManager->selfContactId(); |
52 if (doConstruct() != QContactManager::NoError) { |
50 if (doConstruct() != QContactManager::NoError) { |
53 throw("exception"); |
51 throw("exception"); |
54 } |
52 } |
55 } |
53 } |
64 MobCntModel::MobCntModel(QContactManager* manager, |
62 MobCntModel::MobCntModel(QContactManager* manager, |
65 const QContactFilter& contactFilter, |
63 const QContactFilter& contactFilter, |
66 const QList<QContactSortOrder>& contactSortOrders, |
64 const QList<QContactSortOrder>& contactSortOrders, |
67 bool showMyCard, |
65 bool showMyCard, |
68 QObject *parent) |
66 QObject *parent) |
69 : QAbstractListModel(parent), |
67 : QAbstractListModel(parent) |
70 mIconManager(0) |
68 { |
71 { |
|
72 mIconManager = new MobCntIconManager(); |
|
73 connect(mIconManager, SIGNAL(contactIconReady(int)), this, SLOT(updateContactIcon(int))); |
|
74 |
|
75 mDefaultIcon = HbIcon("qtg_large_avatar"); |
69 mDefaultIcon = HbIcon("qtg_large_avatar"); |
76 mDefaultMyCardIcon = HbIcon("qtg_large_mycard"); |
70 mDefaultMyCardIcon = HbIcon("qtg_large_mycard"); |
77 |
71 |
78 d = new MobCntModelData(contactFilter, contactSortOrders, showMyCard); |
72 d = new MobCntModelData(contactFilter, contactSortOrders, showMyCard); |
79 d->m_contactManager = manager; |
73 d->m_contactManager = manager; |
|
74 d->m_cache = CntCache::instance(); |
|
75 connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId))); |
80 d->mMyCardId = d->m_contactManager->selfContactId(); |
76 d->mMyCardId = d->m_contactManager->selfContactId(); |
81 if (doConstruct() != QContactManager::NoError) { |
77 if (doConstruct() != QContactManager::NoError) { |
82 throw("exception"); |
78 throw("exception"); |
83 } |
79 } |
84 } |
80 } |
85 |
81 |
86 MobCntModel::~MobCntModel() |
82 MobCntModel::~MobCntModel() |
87 { |
83 { |
88 delete mIconManager; |
|
89 } |
84 } |
90 |
85 |
91 /*! |
86 /*! |
92 * Return the data to be used by the view or delegates for a particular |
87 * Return the data to be used by the view or delegates for a particular |
93 * item and role. |
88 * item and role. |
101 int row = index.row(); |
96 int row = index.row(); |
102 |
97 |
103 // check that row is ok |
98 // check that row is ok |
104 if (!validRowId(row)) { |
99 if (!validRowId(row)) { |
105 // invalid row |
100 // invalid row |
106 return QVariant(); |
101 return QVariant(); |
107 } |
102 } |
108 |
103 |
109 // update current contact if needed |
104 // update current contact if needed |
110 if (row != d->currentRow ) { |
105 if (row != d->currentRow ) { |
111 if (d->contactIds[row] == dummyMyCardId) { |
106 if (d->contactIds[row] == dummyMyCardId) { |
112 // row contains dummy MyCard, so create dummy QContact |
107 // row contains dummy MyCard, so create dummy CntContactInfo |
113 d->currentContact = QContact(); |
108 d->currentContact = CntContactInfo(); |
114 } |
109 } |
115 else { |
110 else { |
116 // define fields we are interested in |
111 d->currentContact = d->m_cache->fetchContactInfo(row, d->contactIds); |
117 QStringList definitionRestrictions; |
|
118 definitionRestrictions.append(QContactName::DefinitionName); |
|
119 definitionRestrictions.append(QContactAvatar::DefinitionName); |
|
120 definitionRestrictions.append(QContactPhoneNumber::DefinitionName); |
|
121 definitionRestrictions.append(QContactOrganization::DefinitionName); |
|
122 QContactFetchHint restrictions; |
|
123 restrictions.setDetailDefinitionsHint(definitionRestrictions); |
|
124 restrictions.setOptimizationHints(QContactFetchHint::NoRelationships); |
|
125 |
|
126 d->currentContact = d->m_contactManager->contact(d->contactIds[row], restrictions); |
|
127 } |
112 } |
128 d->currentRow = row; |
113 d->currentRow = row; |
129 } |
114 } |
130 |
115 |
131 if (role == Qt::DisplayRole) { |
116 if (role == Qt::DisplayRole) { |
132 return dataForDisplayRole(row); |
117 return dataForDisplayRole(row); |
133 } |
118 } |
134 else if (role == Hb::IndexFeedbackRole) { |
119 else if (role == Hb::IndexFeedbackRole) { |
135 return dataForDisplayRole(row).toStringList().at(0).toUpper(); |
120 if (row == 0 && (d->mMyCardId == d->contactIds[0] || dummyMyCardId == d->contactIds[0])) { |
136 } |
121 // do not include MyCard in index feedback |
137 else if (role == Qt::BackgroundRole) { |
122 return QVariant(); |
138 if (d->mMyCardId == d->contactIds[row] || |
123 } |
139 dummyMyCardId == d->contactIds[row]) { |
124 else { |
140 return HbFrameBackground("qtg_fr_list_parent_normal", HbFrameDrawer::NinePieces); |
125 return dataForDisplayRole(row).toStringList().at(0).toUpper(); |
141 } |
126 } |
142 } |
127 } |
143 else if (role == Qt::DecorationRole) { |
128 else if (role == Qt::BackgroundRole) { |
144 QContactAvatar contactAvatar = d->currentContact.detail<QContactAvatar>(); |
129 if (d->mMyCardId == d->contactIds[row] || dummyMyCardId == d->contactIds[row]) { |
145 QList<QVariant> icons; |
130 return HbFrameBackground("qtg_fr_list_parent_normal", HbFrameDrawer::NinePieces); |
146 |
131 } |
147 if(!contactAvatar.imageUrl().isEmpty()) { |
132 } |
148 QIcon icon = mIconManager->contactIcon(contactAvatar.imageUrl().toString(), row); |
133 else if (role == Qt::DecorationRole) { |
149 if (icon.isNull()) { |
134 QList<QVariant> icons; |
150 if (d->mMyCardId == d->contactIds[row] || |
135 HbIcon avatar = d->currentContact.icon1(); |
151 dummyMyCardId == d->contactIds[row]) { |
136 HbIcon statusIcon = d->currentContact.icon2(); |
152 icons.append(mDefaultMyCardIcon); |
137 |
153 } |
138 if (!avatar.isNull()) { |
154 else { |
139 icons.append(avatar); |
155 icons.append(mDefaultIcon); |
140 } |
156 } |
141 else if (d->mMyCardId == d->contactIds[row] || dummyMyCardId == d->contactIds[row]) { |
157 } |
142 icons.append(mDefaultMyCardIcon); |
158 else { |
143 } |
159 icons.append(icon); |
144 else { |
160 } |
145 icons.append(mDefaultIcon); |
161 } |
146 } |
162 else { |
147 |
163 if (d->mMyCardId == d->contactIds[row] || |
148 if (!statusIcon.isNull()) { |
164 dummyMyCardId == d->contactIds[row]) { |
149 icons.append(statusIcon); |
165 icons.append(mDefaultMyCardIcon); |
150 } |
166 } |
151 |
167 else { |
152 return icons; |
168 icons.append(mDefaultIcon); |
153 } |
169 } |
154 |
170 |
155 return QVariant(); |
171 } |
|
172 |
|
173 return QVariant(icons); |
|
174 } |
|
175 |
|
176 return QVariant(); |
|
177 } |
156 } |
178 |
157 |
179 /*! |
158 /*! |
180 * Get the number of rows (contacts) in this model. |
159 * Get the number of rows (contacts) in this model. |
181 * |
160 * |
182 * \param parent Optional parent index value. |
161 * \param parent Optional parent index value. |
183 * \return Number of contacts in this model. |
162 * \return Number of contacts in this model. |
184 */ |
163 */ |
185 int MobCntModel::rowCount(const QModelIndex& /*parent*/) const |
164 int MobCntModel::rowCount(const QModelIndex& /*parent*/) const |
186 { |
165 { |
187 return d->contactIds.count(); |
166 return d->contactIds.count(); |
188 } |
167 } |
189 |
168 |
190 /*! |
169 /*! |
191 * Read a full contact entry from the database for the given model |
170 * Read a full contact entry from the database for the given model |
192 * index value. Only the row part of the index information will be |
171 * index value. Only the row part of the index information will be |
325 |
304 |
326 // Attach database notifications to handlers. |
305 // Attach database notifications to handlers. |
327 connect(d->m_contactManager, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&))); |
306 connect(d->m_contactManager, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&))); |
328 connect(d->m_contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&))); |
307 connect(d->m_contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&))); |
329 connect(d->m_contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&))); |
308 connect(d->m_contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&))); |
330 connect(d->m_contactManager, SIGNAL(relationshipsAdded(const QList<QContactLocalId>&)), this, SLOT(handleAdded(const QList<QContactLocalId>&))); |
|
331 connect(d->m_contactManager, SIGNAL(relationshipsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&))); |
|
332 connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&))); |
309 connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&))); |
333 |
310 |
334 return error; |
311 return error; |
335 } |
312 } |
336 |
313 |
425 */ |
402 */ |
426 QVariant MobCntModel::dataForDisplayRole(int row) const |
403 QVariant MobCntModel::dataForDisplayRole(int row) const |
427 { |
404 { |
428 QStringList list; |
405 QStringList list; |
429 QString name; |
406 QString name; |
430 QString number; |
407 QString infoText; |
|
408 bool isSelfContact = false; |
431 bool isNonEmptySelfContact = false; |
409 bool isNonEmptySelfContact = false; |
432 bool isSelfContact = false; |
|
433 |
410 |
434 QContactLocalId id = d->contactIds[row]; |
411 QContactLocalId id = d->contactIds[row]; |
435 if (d->mMyCardId == id || |
412 if (d->mMyCardId == id || dummyMyCardId == id) { |
436 dummyMyCardId == id) { |
|
437 isSelfContact = true; |
413 isSelfContact = true; |
438 if (d->currentContact.details().count() <= 4) { |
414 if (d->currentContact.id() == -1) { |
439 //empty card |
415 // empty card |
440 name = hbTrId("txt_phob_dblist_mycard"); |
416 name = hbTrId("txt_phob_dblist_mycard"); |
441 number = hbTrId("txt_phob_dblist_mycard_val_create_my_identity"); |
417 infoText = hbTrId("txt_phob_dblist_mycard_val_create_my_identity"); |
442 } |
418 } |
443 else { |
419 else { |
444 isNonEmptySelfContact = true; |
420 isNonEmptySelfContact = true; |
445 } |
421 } |
446 } |
422 } |
|
423 |
447 if (!isSelfContact || isNonEmptySelfContact) { |
424 if (!isSelfContact || isNonEmptySelfContact) { |
448 |
425 name = d->currentContact.name(); |
449 name = d->currentContact.displayLabel(); |
426 if (name.isEmpty()) { |
450 |
427 name = hbTrId("txt_phob_list_unnamed"); |
451 QContactPhoneNumber phoneNumber = d->currentContact.detail<QContactPhoneNumber>(); |
428 } |
452 number = phoneNumber.number(); |
429 infoText = d->currentContact.text(); |
453 } |
430 } |
|
431 |
|
432 list << name; |
454 |
433 |
455 if (!isNonEmptySelfContact) { |
434 if (!isNonEmptySelfContact) { |
456 list << name << number; |
435 list << infoText; |
|
436 } |
|
437 |
|
438 return list; |
|
439 } |
|
440 |
|
441 /*! |
|
442 * Handle adding of contacts. |
|
443 * |
|
444 * \param contactIds Ids of contacts added. |
|
445 */ |
|
446 void MobCntModel::handleAdded(const QList<QContactLocalId>& contactIds) |
|
447 { |
|
448 //if contacts are added already, no need to do anything |
|
449 bool newContacts = false; |
|
450 for (int k = 0; k < contactIds.count() && !newContacts; k++) { |
|
451 if(!d->contactIds.contains(contactIds.at(k))) { |
|
452 newContacts = true; |
|
453 } |
|
454 } |
|
455 if (!newContacts) { |
|
456 return; |
|
457 } |
|
458 |
|
459 //invalidate cached contact |
|
460 d->currentRow = -1; |
|
461 |
|
462 QList<QContactLocalId> oldIdList = d->contactIds; |
|
463 updateContactIdsArray(); |
|
464 |
|
465 //Find all new contacts (=rows) |
|
466 QList<int> newRows; |
|
467 for(int i = 0; i < d->contactIds.count(); i++) { |
|
468 if (!oldIdList.contains(d->contactIds.at(i))) { |
|
469 newRows.append(i); |
|
470 } |
|
471 } |
|
472 |
|
473 // only 1 (or no) contact is added, it can be handled by beginInsertRows() |
|
474 // and endInsertRows() |
|
475 if (newRows.count() <= 1) { |
|
476 for(int j = 0; j < newRows.count(); j++) { |
|
477 beginInsertRows(QModelIndex(), newRows.at(j), newRows.at(j)); |
|
478 endInsertRows(); |
|
479 } |
457 } |
480 } |
458 else { |
481 else { |
459 list << name; |
482 beginResetModel(); |
460 } |
483 reset(); |
461 |
484 endResetModel(); |
462 return QVariant(list); |
|
463 } |
|
464 |
|
465 /*! |
|
466 * Handle adding of contacts. |
|
467 * |
|
468 * \param contactIds Ids of contacts added. |
|
469 */ |
|
470 void MobCntModel::handleAdded(const QList<QContactLocalId>& contactIds) |
|
471 { |
|
472 //invalidate cached contact |
|
473 d->currentRow = -1; |
|
474 |
|
475 updateContactIdsArray(); |
|
476 QList< QList<int> > indexSequences = findIndexes(contactIds); |
|
477 |
|
478 for (int i = (indexSequences.count() - 1);i >= 0; i--) |
|
479 { |
|
480 beginInsertRows(QModelIndex(), indexSequences.at(i).first(), indexSequences.at(i).last()); |
|
481 endInsertRows(); |
|
482 } |
485 } |
483 } |
486 } |
484 |
487 |
485 /*! |
488 /*! |
486 * Handle changes in contacts. |
489 * Handle changes in contacts. |
508 * |
511 * |
509 * \param contactIds Ids of contacts removed. |
512 * \param contactIds Ids of contacts removed. |
510 */ |
513 */ |
511 void MobCntModel::handleRemoved(const QList<QContactLocalId>& contactIds) |
514 void MobCntModel::handleRemoved(const QList<QContactLocalId>& contactIds) |
512 { |
515 { |
513 QList< QList<int> > indexSequences = findIndexes(contactIds); |
516 bool removeContacts = false; |
514 |
517 QList<QContactLocalId> idList = d->contactIds; |
|
518 for (int k = 0; k < contactIds.count() && !removeContacts; k++) { |
|
519 if(idList.contains(contactIds.at(k))) { |
|
520 removeContacts = true; |
|
521 } |
|
522 } |
|
523 if (!removeContacts) { |
|
524 return; |
|
525 } |
|
526 |
|
527 //Find contacts to remove (=rows) |
|
528 QList<int> removeRows; |
|
529 for(int i = 0; i < contactIds.count(); i++) { |
|
530 if (idList.contains(contactIds.at(i))) { |
|
531 removeRows.append(rowId(contactIds.at(i))); |
|
532 } |
|
533 } |
|
534 |
515 // invalidate cached contact |
535 // invalidate cached contact |
516 d->currentRow = -1; |
536 d->currentRow = -1; |
517 // if myCard has been removed, set myCard id to zero |
537 |
518 if (contactIds.contains(d->mMyCardId)) |
538 bool removeMyCard(false); |
|
539 int myCardRow; |
|
540 if (contactIds.contains(d->mMyCardId)) { |
|
541 removeMyCard = true; |
|
542 myCardRow = rowId(d->mMyCardId); |
519 d->mMyCardId = 0; |
543 d->mMyCardId = 0; |
520 |
544 } |
521 for (int i = (indexSequences.count() - 1);i >= 0; i--) |
545 |
522 { |
546 int removeRowsCount=removeRows.count(); |
523 if (indexSequences.at(i).first() == 0 && d->showMyCard) { |
547 // no of rows |
524 // handle removed for MyCard |
548 for(int j = 0; j < removeRows.count(); j++) { |
525 d->mMyCardId = 0; |
549 if (removeMyCard |
|
550 && removeRows.at(j) == myCardRow |
|
551 && d->showMyCard) { |
526 QModelIndex index = createIndex(0, 0); |
552 QModelIndex index = createIndex(0, 0); |
527 emit dataChanged(index, index); |
553 emit dataChanged(index, index); |
528 |
554 removeRowsCount--; |
529 // handle removed for other contacts deleted besides myCard |
555 } |
530 if (indexSequences.at(i).count() > 1) { |
556 else { |
531 beginRemoveRows(QModelIndex(), indexSequences.at(i).first() + 1, indexSequences.at(i).last()); |
557 beginRemoveRows(QModelIndex(), removeRows.at(j), removeRows.at(j)); |
532 endRemoveRows(); |
|
533 } |
|
534 } |
|
535 else |
|
536 { |
|
537 beginRemoveRows(QModelIndex(), indexSequences.at(i).first(), indexSequences.at(i).last()); |
|
538 endRemoveRows(); |
558 endRemoveRows(); |
539 } |
559 } |
540 } |
560 } |
541 updateContactIdsArray(); |
561 updateContactIdsArray(); |
|
562 |
|
563 // check row count in new list |
|
564 // if there is a mismatch, probable late events. reset model |
|
565 QList<QContactLocalId> updatedIdList = d->contactIds; |
|
566 int rowsRemoved = idList.count() - updatedIdList.count(); |
|
567 if (rowsRemoved != removeRowsCount) { |
|
568 beginResetModel(); |
|
569 reset(); |
|
570 endResetModel(); |
|
571 } |
542 } |
572 } |
543 |
573 |
544 /*! |
574 /*! |
545 * Handle my card change. |
575 * Handle my card change. |
546 * |
576 * |
547 * \param oldId Id of the old MyCard. |
577 * \param oldId Id of the old MyCard. |
548 * \param newId Id of the new MyCard. |
578 * \param newId Id of the new MyCard. |
549 */ |
579 */ |
550 void MobCntModel::handleMyCardChanged(const QContactLocalId& /*oldId*/, const QContactLocalId& newId) |
580 void MobCntModel::handleMyCardChanged(const QContactLocalId& oldId, const QContactLocalId& newId) |
551 { |
581 { |
552 int row = rowId(newId); |
582 int row = rowId(newId); |
553 |
583 |
554 //invalidate cached contact |
584 //invalidate cached contact |
555 d->currentRow = -1; |
585 d->currentRow = -1; |
556 d->mMyCardId = newId; |
586 d->mMyCardId = newId; |
557 |
|
558 updateContactIdsArray(); |
|
559 |
587 |
560 // if the new mycard was taken from an existing contact, |
588 // if the new mycard was taken from an existing contact, |
561 // notify views that that row was removed |
589 // notify views that that row was removed |
562 if (row > 0) { |
590 if (row > 0) { |
563 beginRemoveRows(QModelIndex(), row, row); |
591 beginRemoveRows(QModelIndex(), row, row); |
564 endRemoveRows(); |
592 endRemoveRows(); |
565 } |
593 } |
566 |
594 updateContactIdsArray(); |
|
595 |
|
596 // if old mycard is not 0, it means it probably appears in the list |
|
597 if (oldId > 0 && rowId(oldId) > 0) { |
|
598 beginInsertRows(QModelIndex(), rowId(oldId), rowId(oldId)); |
|
599 endInsertRows(); |
|
600 } |
|
601 |
567 // notify views that mycard was updated |
602 // notify views that mycard was updated |
568 QModelIndex index = createIndex(rowId(newId), 0); |
603 QModelIndex index = createIndex(rowId(newId), 0); |
569 emit dataChanged(index, index); |
604 emit dataChanged(index, index); |
570 } |
605 } |
571 |
606 |