summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Araujo Oliveira Filho <renato.filho@canonical.com>2014-03-07 15:11:27 -0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-24 17:01:55 +0200
commitcfc2068c19e4980e9a173238c85da2e74c9d7f31 (patch)
treeddcf561b9cb293c2471d0c213bc2b82defcdb3a2
parentb5017b863eaeb2ff5ced656488103b977e35dcbb (diff)
Delete declarative contact after remove it from the model.
Keep any contact fetched by the model update even if the contact is not in the model. Delete any fetched contact if it get removed from the engine. Change-Id: I646cc2d53ca7bb25b107f44c9517c0aac6814422 Reviewed-by: Alex Blasche <alexander.blasche@digia.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
-rw-r--r--src/imports/contacts/qdeclarativecontactmodel.cpp55
-rw-r--r--src/imports/contacts/qdeclarativecontactmodel_p.h1
2 files changed, 52 insertions, 4 deletions
diff --git a/src/imports/contacts/qdeclarativecontactmodel.cpp b/src/imports/contacts/qdeclarativecontactmodel.cpp
index 5e9bec6f7..7d6cf4703 100644
--- a/src/imports/contacts/qdeclarativecontactmodel.cpp
+++ b/src/imports/contacts/qdeclarativecontactmodel.cpp
@@ -51,6 +51,7 @@
#include <QtGui/qpixmap.h>
#include <QtQml/qqmlinfo.h>
+#include <QtQml/qqmlengine.h>
#include <QtContacts/qcontactdetails.h>
#include <QtContacts/qcontactmanager.h>
@@ -117,6 +118,7 @@ public:
QList<QDeclarativeContact*> m_contacts;
QMap<QContactId, QDeclarativeContact*> m_contactMap;
+ QMap<QContactId, QDeclarativeContact*> m_contactFetchedMap;
QContactManager* m_manager;
QContactAbstractRequest::StorageLocations m_storageLocations;
QDeclarativeContactFetchHint* m_fetchHint;
@@ -482,6 +484,13 @@ void QDeclarativeContactModel::contactsExported(QVersitWriter::State state)
}
}
+void QDeclarativeContactModel::onFetchedContactDestroyed(QObject *obj)
+{
+ QContactId id = d->m_contactFetchedMap.key(static_cast<QDeclarativeContact*>(obj));
+ if (!id.isNull())
+ d->m_contactFetchedMap.remove(id);
+}
+
int QDeclarativeContactModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
@@ -684,8 +693,21 @@ void QDeclarativeContactModel::onFetchContactsRequestStateChanged(QContactAbstra
if (request->error() == QContactManager::NoError) {
QList<QContact> contacts(request->contacts());
foreach (const QContact &contact, contacts) {
- QDeclarativeContact *declarativeContact(0);
- declarativeContact = new QDeclarativeContact(this);
+ // if the contact was already fetched update the contact
+ QDeclarativeContact *declarativeContact = d->m_contactFetchedMap.value(contact.id(), 0);
+ if (!declarativeContact) {
+ declarativeContact = new QDeclarativeContact(this);
+ // Transfer the ownership to QML
+ // The model will destroy the contact if it get removed from the backend, otherwise the QML side need to destroy it.
+ QQmlEngine::setObjectOwnership(declarativeContact, QQmlEngine::JavaScriptOwnership);
+
+ // keep track of contact destruction to remove it from the list if QML destroys it
+ connect(declarativeContact, SIGNAL(destroyed(QObject*)), SLOT(onFetchedContactDestroyed(QObject*)));
+
+ // we need keep track of the contact to update it if the contact get update on the backend. or destroy it
+ // if the contact get removed from the backend
+ d->m_contactFetchedMap[contact.id()] = declarativeContact;
+ }
declarativeContact->setContact(contact);
list.append(QVariant::fromValue(declarativeContact));
}
@@ -699,6 +721,8 @@ void QDeclarativeContactModel::clearContacts()
qDeleteAll(d->m_contacts);
d->m_contacts.clear();
d->m_contactMap.clear();
+ qDeleteAll(d->m_contactFetchedMap.values());
+ d->m_contactFetchedMap.clear();
}
void QDeclarativeContactModel::fetchAgain()
@@ -987,6 +1011,11 @@ void QDeclarativeContactModel::onContactsRemoved(const QList<QContactId> &ids)
bool emitSignal = false;
foreach (const QContactId &id, ids) {
+ // delete the contact from fetched map if necessary
+ QDeclarativeContact* contact = d->m_contactFetchedMap.take(id);
+ if (contact)
+ contact->deleteLater();
+
if (d->m_contactMap.contains(id)) {
int row = 0;
//TODO:need a fast lookup
@@ -997,7 +1026,8 @@ void QDeclarativeContactModel::onContactsRemoved(const QList<QContactId> &ids)
if (row < d->m_contacts.count()) {
beginRemoveRows(QModelIndex(), row, row);
- d->m_contacts.removeAt(row);
+ contact = d->m_contacts.takeAt(row);
+ contact->deleteLater();
d->m_contactMap.remove(id);
endRemoveRows();
emitSignal = true;
@@ -1019,6 +1049,21 @@ void QDeclarativeContactModel::onContactsChanged(const QList<QContactId> &ids)
this, SLOT(onContactsChangedFetchRequestStateChanged(QContactAbstractRequest::State)));
fetchRequest->start();
}
+
+ // If any contact in the fetchedList has changed we need to update it.
+ // We need a different query because feched contacts could not be part of the model.
+ //
+ // For example: if the model contains a filter
+ if (!ids.isEmpty()) {
+ QStringList pendingFetch;
+ foreach (const QContactId &id, ids) {
+ QDeclarativeContact* dc = d->m_contactFetchedMap.value(id);
+ if (dc)
+ pendingFetch << dc->contactId();
+ }
+ if (!pendingFetch.isEmpty())
+ fetchContacts(pendingFetch);
+ }
}
QContactFetchRequest *QDeclarativeContactModel::createContactFetchRequest(const QList<QContactId> &ids)
@@ -1190,7 +1235,9 @@ void QDeclarativeContactModel::onContactsChangedFetchRequestStateChanged(QContac
for (int i=0;i<d->m_contacts.size();++i) {
if (d->m_contacts.at(i)->contactId() == id.toString()) {
beginRemoveRows(QModelIndex(), i, i);
- d->m_contacts.removeAt(i);
+ // Remove and delete contact object
+ QDeclarativeContact* dc = d->m_contacts.takeAt(i);
+ dc->deleteLater();
d->m_contactMap.remove(id);
endRemoveRows();
contactsUpdated = true;
diff --git a/src/imports/contacts/qdeclarativecontactmodel_p.h b/src/imports/contacts/qdeclarativecontactmodel_p.h
index cb2dfccdc..c5517b39d 100644
--- a/src/imports/contacts/qdeclarativecontactmodel_p.h
+++ b/src/imports/contacts/qdeclarativecontactmodel_p.h
@@ -184,6 +184,7 @@ private slots:
void onContactsChanged(const QList<QContactId>& ids);
void startImport(QVersitReader::State state);
void contactsExported(QVersitWriter::State state);
+ void onFetchedContactDestroyed(QObject *obj);
// handle fetch request from onContactsAdded()
void onContactsAddedFetchRequestStateChanged(QContactAbstractRequest::State state);