[Telepathy-commits] [telepathy-qt4/master] Channel: Represent selfHandle as a Contact object.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Mon Feb 9 10:34:09 PST 2009
---
TelepathyQt4/Client/channel.cpp | 109 ++++++++++++++++++++++++++++----------
TelepathyQt4/Client/channel.h | 7 +--
2 files changed, 83 insertions(+), 33 deletions(-)
diff --git a/TelepathyQt4/Client/channel.cpp b/TelepathyQt4/Client/channel.cpp
index e6c9237..c3e2d5f 100644
--- a/TelepathyQt4/Client/channel.cpp
+++ b/TelepathyQt4/Client/channel.cpp
@@ -148,8 +148,10 @@ struct Channel::Private
HandleOwnerMap groupHandleOwners;
// Group self handle
+ bool pendingRetrieveGroupSelfContact;
bool groupIsSelfHandleTracked;
uint groupSelfHandle;
+ QSharedPointer<Contact> groupSelfContact;
};
struct Channel::Private::GroupMembersChangedInfo
@@ -209,6 +211,7 @@ Channel::Private::Private(Channel *parent, Connection *connection)
buildingContacts(false),
currentGroupMembersChangedInfo(0),
groupAreHandleOwnersAvailable(false),
+ pendingRetrieveGroupSelfContact(false),
groupIsSelfHandleTracked(false),
groupSelfHandle(0)
{
@@ -496,6 +499,12 @@ void Channel::Private::buildContacts()
toBuild.append(currentGroupMembersChangedInfo->actor);
}
+ // always try to retrieve selfContact and check if it changed on
+ // updateContacts or on gotContacts, in case we were not able to retrieve it
+ if (groupSelfHandle) {
+ toBuild.append(groupSelfHandle);
+ }
+
PendingContacts *pendingContacts = manager->contactsForHandles(
toBuild);
parent->connect(pendingContacts,
@@ -506,6 +515,11 @@ void Channel::Private::buildContacts()
void Channel::Private::processMembersChanged()
{
if (groupMembersChangedQueue.isEmpty()) {
+ if (pendingRetrieveGroupSelfContact) {
+ pendingRetrieveGroupSelfContact = false;
+ // nothing queued but selfContact changed
+ buildContacts();
+ }
return;
}
@@ -513,6 +527,11 @@ void Channel::Private::processMembersChanged()
Q_ASSERT(pendingGroupLocalPendingMembers.isEmpty());
Q_ASSERT(pendingGroupRemotePendingMembers.isEmpty());
+ // always set this to false here, as buildContacts will always try to
+ // retrieve the selfContact and updateContacts will check if the built
+ // contact is the same as the current contact.
+ pendingRetrieveGroupSelfContact = false;
+
currentGroupMembersChangedInfo = groupMembersChangedQueue.dequeue();
foreach (uint handle, currentGroupMembersChangedInfo->added) {
@@ -580,6 +599,7 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
QList<QSharedPointer<Contact> > groupLocalPendingContactsAdded;
QList<QSharedPointer<Contact> > groupRemotePendingContactsAdded;
QSharedPointer<Contact> actorContact;
+ bool selfContactUpdated = false;
foreach (QSharedPointer<Contact> contact, contacts) {
uint handle = contact->handle()[0];
@@ -595,6 +615,11 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
groupRemotePendingContacts[handle] = contact;
}
+ if (groupSelfHandle == handle && groupSelfContact != contact) {
+ groupSelfContact = contact;
+ selfContactUpdated = false;
+ }
+
if (currentGroupMembersChangedInfo &&
currentGroupMembersChangedInfo->actor == contact->handle()[0]) {
actorContact = contact;
@@ -671,17 +696,26 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
}
groupRemotePendingMembersToRemove.clear();
- emit parent->groupMembersChanged(
- groupContactsAdded,
- groupLocalPendingContactsAdded,
- groupRemotePendingContactsAdded,
- groupContactsRemoved,
- actorContact,
- currentGroupMembersChangedInfo->reason,
- currentGroupMembersChangedInfo->message);
+ if (!groupContactsAdded.isEmpty() ||
+ !groupLocalPendingContactsAdded.isEmpty() ||
+ !groupRemotePendingContactsAdded.isEmpty() ||
+ !groupContactsRemoved.isEmpty()) {
+ emit parent->groupMembersChanged(
+ groupContactsAdded,
+ groupLocalPendingContactsAdded,
+ groupRemotePendingContactsAdded,
+ groupContactsRemoved,
+ actorContact,
+ currentGroupMembersChangedInfo->reason,
+ currentGroupMembersChangedInfo->message);
+ }
delete currentGroupMembersChangedInfo;
currentGroupMembersChangedInfo = 0;
+ if (selfContactUpdated) {
+ emit parent->groupSelfContactChanged();
+ }
+
processMembersChanged();
}
@@ -1265,15 +1299,15 @@ HandleOwnerMap Channel::groupHandleOwners() const
}
/**
- * Returns whether the value returned by groupSelfHandle() is guaranteed to
+ * Return whether the value returned by groupSelfContact() is guaranteed to
* stay synchronized with what groupInterface()->GetSelfHandle() would
* return. Older services not providing group properties don't necessarily
- * emit the SelfHandleChanged signal either, so self handle changes can't be
+ * emit the SelfHandleChanged signal either, so self contact changes can't be
* reliably tracked.
*
- * \return Whether or not changes to the self handle are tracked.
+ * \return Whether or not changes to the self contact are tracked.
*/
-bool Channel::groupIsSelfHandleTracked() const
+bool Channel::groupIsSelfContactTracked() const
{
if (!isReady()) {
warning() << "Channel::groupIsSelfHandleTracked() used channel not ready";
@@ -1287,23 +1321,23 @@ bool Channel::groupIsSelfHandleTracked() const
}
/**
- * Returns a handle representing the user in the group if the user is a
- * member of the group, otherwise either a handle representing the user or
+ * Return a Contact object representing the user in the group if the user is a
+ * member of the group, otherwise either a Contact object representing the user or
* 0.
*
* \return A contact handle representing the user, if possible.
*/
-uint Channel::groupSelfHandle() const
+QSharedPointer<Contact> Channel::groupSelfContact() const
{
if (!isReady()) {
- warning() << "Channel::groupSelfHandle() used channel not ready";
+ warning() << "Channel::groupSelfContact() used channel not ready";
}
else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
- warning() << "Channel::groupSelfHandle() used with "
+ warning() << "Channel::groupSelfContact() used with "
"no group interface";
}
- return mPriv->groupSelfHandle;
+ return mPriv->groupSelfContact;
}
/**
@@ -1382,12 +1416,9 @@ uint Channel::groupSelfHandle() const
*/
/**
- * \fn void groupSelfHandleChanged(uint selfHandle)
- *
- * Emitted when the value returned by groupSelfHandle() changes.
+ * \fn void groupSelfContactChanged()
*
- * \param selfHandle The value which would now be returned by
- * groupSelfHandle().
+ * Emitted when the value returned by groupSelfContact() changes.
*/
//@}
@@ -1735,7 +1766,7 @@ void Channel::gotAllMembers(QDBusPendingCallWatcher *watcher)
mPriv->pendingGroupLocalPendingMembers = QSet<uint>::fromList(reply.argumentAt<1>());
mPriv->pendingGroupRemotePendingMembers = QSet<uint>::fromList(reply.argumentAt<2>());
- // delay building contacts now until we process gotLocalPendingMembersWithInfo
+ // delay building contacts now until we process gotSelfHandle
}
continueIntrospection();
@@ -1759,10 +1790,6 @@ void Channel::gotLocalPendingMembersWithInfo(QDBusPendingCallWatcher *watcher)
}
}
- // build contacts even if the call failed
- mPriv->buildingInitialContacts = true;
- mPriv->buildContacts();
-
continueIntrospection();
}
@@ -1779,6 +1806,10 @@ void Channel::gotSelfHandle(QDBusPendingCallWatcher *watcher)
mPriv->groupSelfHandle = reply.value();
}
+ // build contacts even if the call failed
+ mPriv->buildingInitialContacts = true;
+ mPriv->buildContacts();
+
continueIntrospection();
}
@@ -1795,6 +1826,13 @@ void Channel::gotContacts(PendingOperation *op)
if (!pending->invalidHandles().isEmpty()) {
warning() << "Unable to construct Contact objects for handles:" <<
pending->invalidHandles();
+
+ if (mPriv->groupSelfHandle &&
+ pending->invalidHandles().contains(mPriv->groupSelfHandle)) {
+ warning() << "Unable to retrieve self contact";
+ mPriv->groupSelfContact.clear();
+ emit groupSelfContactChanged();
+ }
}
} else {
warning().nospace() << "Getting contacts failed with " <<
@@ -1911,7 +1949,20 @@ void Channel::onSelfHandleChanged(uint newSelfHandle)
mPriv->groupSelfHandle = newSelfHandle;
debug() << " Emitting groupSelfHandleChanged with new self handle" <<
newSelfHandle;
- emit groupSelfHandleChanged(newSelfHandle);
+
+ if (mPriv->groupSelfHandle) {
+ if (!mPriv->buildingContacts) {
+ mPriv->buildContacts();
+ } else {
+ // next call to processMembersChanged will build selfContact again
+ mPriv->pendingRetrieveGroupSelfContact = true;
+ }
+ } else {
+ // newSelfHandle == 0 <- strange
+ // no need to call buildContacts ...
+ mPriv->groupSelfContact.clear();
+ emit groupSelfContactChanged();
+ }
}
}
diff --git a/TelepathyQt4/Client/channel.h b/TelepathyQt4/Client/channel.h
index aa6cf53..a60e410 100644
--- a/TelepathyQt4/Client/channel.h
+++ b/TelepathyQt4/Client/channel.h
@@ -135,9 +135,8 @@ public:
HandleOwnerMap groupHandleOwners() const;
- bool groupIsSelfHandleTracked() const;
-
- uint groupSelfHandle() const;
+ bool groupIsSelfContactTracked() const;
+ QSharedPointer<Contact> groupSelfContact() const;
Q_SIGNALS:
void groupFlagsChanged(uint flags, uint added, uint removed);
@@ -153,7 +152,7 @@ Q_SIGNALS:
void groupHandleOwnersChanged(const HandleOwnerMap &owners,
const Telepathy::UIntList &added, const Telepathy::UIntList &removed);
- void groupSelfHandleChanged(uint selfHandle);
+ void groupSelfContactChanged();
public:
template <class Interface>
--
1.5.6.5
More information about the telepathy-commits
mailing list