From 723dbc2aa30c214ce457ac4bba6c628d60e00927 Mon Sep 17 00:00:00 2001 From: Dario Freddi Date: Tue, 30 Mar 2010 22:35:59 +0200 Subject: [PATCH] Add a new signal, allKnownContactsChanged, to monitor contact addition/removal Signed-off-by: Dario Freddi --- TelepathyQt4/contact-manager.cpp | 53 ++++++++++++++++++++++++++++++++++++++ TelepathyQt4/contact-manager.h | 14 ++++++++++ 2 files changed, 67 insertions(+), 0 deletions(-) diff --git a/TelepathyQt4/contact-manager.cpp b/TelepathyQt4/contact-manager.cpp index bb52f9d..a20f8af 100644 --- a/TelepathyQt4/contact-manager.cpp +++ b/TelepathyQt4/contact-manager.cpp @@ -56,6 +56,8 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private Private(ContactManager *parent, const ConnectionPtr &connection) : parent(parent), connection(connection) { + // Make the cache start from the current known contacts + cachedAllKnownContacts = allKnownContacts(); } QString addContactListGroupChannel(const ChannelPtr &contactListGroupChannel) @@ -91,6 +93,7 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private ContactManager *parent; WeakPtr connection; QMap > contacts; + Contacts cachedAllKnownContacts; QMap tracking; void ensureTracking(Contact::Feature feature); @@ -106,6 +109,10 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private Contacts allKnownContacts() const; void updateContactsPresenceState(); + void computeKnownContactsChanges(const Contacts &added, + const Contacts &pendingAdded, + const Contacts &remotePendingAdded, + const Contacts &removed); }; ConnectionPtr ContactManager::connection() const @@ -797,6 +804,12 @@ void ContactManager::onSubscribeChannelMembersChanged( debug() << "Contact" << contact->id() << "removed from subscribe list"; contact->setSubscriptionState(Contact::PresenceStateNo); } + + // Perform the needed computation for allKnownContactsChanged + mPriv->computeKnownContactsChanges(groupMembersAdded, + groupLocalPendingMembersAdded, + groupRemotePendingMembersAdded, + groupMembersRemoved); } void ContactManager::onPublishChannelMembersChanged( @@ -830,6 +843,12 @@ void ContactManager::onPublishChannelMembersChanged( if (!groupLocalPendingMembersAdded.isEmpty()) { emit presencePublicationRequested(groupLocalPendingMembersAdded); } + + // Perform the needed computation for allKnownContactsChanged + mPriv->computeKnownContactsChanges(groupMembersAdded, + groupLocalPendingMembersAdded, + groupRemotePendingMembersAdded, + groupMembersRemoved); } void ContactManager::onDenyChannelMembersChanged( @@ -1095,6 +1114,40 @@ Contacts ContactManager::Private::allKnownContacts() const return contacts; } +void ContactManager::Private::computeKnownContactsChanges(const Tp::Contacts& added, + const Tp::Contacts& pendingAdded, + const Tp::Contacts& remotePendingAdded, + const Tp::Contacts& removed) +{ + // First of all, compute the real additions/removals based upon our cache + Tp::Contacts realAdded; + realAdded.unite(added); + realAdded.unite(pendingAdded); + realAdded.unite(remotePendingAdded); + realAdded.subtract(cachedAllKnownContacts); + Tp::Contacts realRemoved = removed; + realRemoved.intersect(cachedAllKnownContacts); + + // Check if realRemoved have been _really_ removed from all lists + foreach (const ContactListChannel &contactListChannel, contactListChannels) { + ChannelPtr channel = contactListChannel.channel; + if (!channel) { + continue; + } + realRemoved.subtract(channel->groupContacts()); + realRemoved.subtract(channel->groupLocalPendingContacts()); + realRemoved.subtract(channel->groupRemotePendingContacts()); + } + + // Are there any real changes? + if (!realAdded.isEmpty() || !realRemoved.isEmpty()) { + // Yes, update our "cache" and emit the signal + cachedAllKnownContacts.unite(realAdded); + cachedAllKnownContacts.subtract(realRemoved); + emit parent->allKnownContactsChanged(realAdded, realRemoved); + } +} + void ContactManager::Private::updateContactsPresenceState() { Contacts subscribeContacts; diff --git a/TelepathyQt4/contact-manager.h b/TelepathyQt4/contact-manager.h index 834916e..0b25bcf 100644 --- a/TelepathyQt4/contact-manager.h +++ b/TelepathyQt4/contact-manager.h @@ -113,6 +113,20 @@ Q_SIGNALS: void groupMembersChanged(const QString &group, const Tp::Contacts &groupMembersAdded, const Tp::Contacts &groupMembersRemoved); + /** + * This signal is emitted whenever some contacts got removed or added from + * ContactManager's known contact list. It is useful for monitoring which contacts + * are currently known by ContactManager. + * + * \param contactsAdded A set of contacts which were added to the known contact list + * \param contactsRemoved A set of contacts which were removed from the known contact list + * + * \note Please note that, in some protocols, this signal could stream newly added contacts + * with both presence subscription and publication state set to No. Be sure to watch + * over publication and/or subscription state changes if that is the case. + */ + void allKnownContactsChanged(const Tp::Contacts &contactsAdded, + const Tp::Contacts &contactsRemoved); private Q_SLOTS: void onAliasesChanged(const Tp::AliasPairList &); -- 1.7.0.3