[Telepathy-commits] [telepathy-qt4/master] Channel: Re-enable support for group member change info.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Mon Feb 9 09:07:28 PST 2009
---
TelepathyQt4/Client/channel.cpp | 172 +++++++++++++++++++++++++++-----------
TelepathyQt4/Client/channel.h | 26 ++++--
2 files changed, 140 insertions(+), 58 deletions(-)
diff --git a/TelepathyQt4/Client/channel.cpp b/TelepathyQt4/Client/channel.cpp
index 4cd7d0a..e6c9237 100644
--- a/TelepathyQt4/Client/channel.cpp
+++ b/TelepathyQt4/Client/channel.cpp
@@ -75,7 +75,7 @@ struct Channel::Private
void introspectGroup();
void introspectGroupFallbackFlags();
void introspectGroupFallbackMembers();
- // void introspectGroupFallbackLocalPending();
+ void introspectGroupFallbackLocalPendingWithInfo();
void introspectGroupFallbackSelfHandle();
void extract0177MainProps(const QVariantMap &props);
@@ -131,12 +131,15 @@ struct Channel::Private
QSet<uint> pendingGroupMembers;
QSet<uint> pendingGroupLocalPendingMembers;
QSet<uint> pendingGroupRemotePendingMembers;
+ QMap<uint, LocalPendingInfo> pendingGroupMembersChangeInfo;
UIntList groupMembersToRemove;
UIntList groupLocalPendingMembersToRemove;
UIntList groupRemotePendingMembersToRemove;
QHash<uint, QSharedPointer<Contact> > groupContacts;
QHash<uint, QSharedPointer<Contact> > groupLocalPendingContacts;
QHash<uint, QSharedPointer<Contact> > groupRemotePendingContacts;
+ QHash<uint, GroupMemberChangeInfo > groupLocalPendingContactsChangeInfo;
+ GroupMemberChangeInfo groupSelfContactRemoveInfo;
QQueue<GroupMembersChangedInfo *> groupMembersChangedQueue;
GroupMembersChangedInfo *currentGroupMembersChangedInfo;
@@ -147,9 +150,6 @@ struct Channel::Private
// Group self handle
bool groupIsSelfHandleTracked;
uint groupSelfHandle;
-
- // Group remove info
- GroupMemberChangeInfo groupSelfRemoveInfo;
};
struct Channel::Private::GroupMembersChangedInfo
@@ -361,8 +361,7 @@ void Channel::Private::introspectGroupFallbackMembers()
SLOT(gotAllMembers(QDBusPendingCallWatcher*)));
}
-#if 0
-void Channel::Private::introspectGroupFallbackLocalPending()
+void Channel::Private::introspectGroupFallbackLocalPendingWithInfo()
{
Q_ASSERT(group != 0);
@@ -372,9 +371,8 @@ void Channel::Private::introspectGroupFallbackLocalPending()
parent);
parent->connect(watcher,
SIGNAL(finished(QDBusPendingCallWatcher*)),
- SLOT(gotLocalPending(QDBusPendingCallWatcher*)));
+ SLOT(gotLocalPendingMembersWithInfo(QDBusPendingCallWatcher*)));
}
-#endif
void Channel::Private::introspectGroupFallbackSelfHandle()
{
@@ -434,8 +432,7 @@ void Channel::Private::extract0176GroupProps(const QVariantMap &props)
introspectQueue.enqueue(&Private::introspectGroupFallbackFlags);
introspectQueue.enqueue(&Private::introspectGroupFallbackMembers);
- // TODO reenable here, disabled for now
- // introspectQueue.enqueue(&Private::introspectGroupFallbackLocalPending);
+ introspectQueue.enqueue(&Private::introspectGroupFallbackLocalPendingWithInfo);
introspectQueue.enqueue(&Private::introspectGroupFallbackSelfHandle);
}
else {
@@ -449,10 +446,10 @@ void Channel::Private::extract0176GroupProps(const QVariantMap &props)
groupHandleOwners = qdbus_cast<HandleOwnerMap>(props["HandleOwners"]);
pendingGroupMembers = QSet<uint>::fromList(qdbus_cast<UIntList>(props["Members"]));
- // TODO add GroupMemberChangeInfo support
- foreach (LocalPendingInfo info,
+ foreach (const LocalPendingInfo &info,
qdbus_cast<LocalPendingInfoList>(props["LocalPendingMembers"])) {
pendingGroupLocalPendingMembers.insert(info.toBeAdded);
+ pendingGroupMembersChangeInfo[info.actor] = info;
}
pendingGroupRemotePendingMembers =
QSet<uint>::fromList(qdbus_cast<UIntList>(props["RemotePendingMembers"]));
@@ -487,10 +484,18 @@ void Channel::Private::buildContacts()
UIntList toBuild = QSet<uint>(pendingGroupMembers +
pendingGroupLocalPendingMembers +
pendingGroupRemotePendingMembers).toList();
+
+ foreach (const uint &handle, pendingGroupMembersChangeInfo.keys()) {
+ if (handle) {
+ toBuild.append(handle);
+ }
+ }
+
if (currentGroupMembersChangedInfo &&
currentGroupMembersChangedInfo->actor != 0) {
toBuild.append(currentGroupMembersChangedInfo->actor);
}
+
PendingContacts *pendingContacts = manager->contactsForHandles(
toBuild);
parent->connect(pendingContacts,
@@ -526,7 +531,14 @@ void Channel::Private::processMembersChanged()
foreach (uint handle, currentGroupMembersChangedInfo->localPending) {
if (!groupLocalPendingContacts.contains(handle)) {
+ LocalPendingInfo info = {
+ handle,
+ currentGroupMembersChangedInfo->actor,
+ currentGroupMembersChangedInfo->reason,
+ currentGroupMembersChangedInfo->message
+ };
pendingGroupLocalPendingMembers.insert(handle);
+ pendingGroupMembersChangeInfo[info.actor] = info;
}
}
@@ -538,6 +550,16 @@ void Channel::Private::processMembersChanged()
foreach (uint handle, currentGroupMembersChangedInfo->removed) {
groupMembersToRemove.append(handle);
+
+ if (handle == groupSelfHandle) {
+ LocalPendingInfo info = {
+ handle,
+ currentGroupMembersChangedInfo->actor,
+ currentGroupMembersChangedInfo->reason,
+ currentGroupMembersChangedInfo->message
+ };
+ pendingGroupMembersChangeInfo[info.actor] = info;
+ }
}
if (pendingGroupMembers.isEmpty() &&
@@ -567,19 +589,42 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
} else if (pendingGroupLocalPendingMembers.contains(handle)) {
groupLocalPendingContactsAdded.append(contact);
groupLocalPendingContacts[handle] = contact;
+ groupLocalPendingContactsChangeInfo[handle] = GroupMemberChangeInfo();
} else if (pendingGroupRemotePendingMembers.contains(handle)) {
groupRemotePendingContactsAdded.append(contact);
groupRemotePendingContacts[handle] = contact;
}
+
if (currentGroupMembersChangedInfo &&
currentGroupMembersChangedInfo->actor == contact->handle()[0]) {
actorContact = contact;
}
}
+ // this is not ideal, but we need to make sure groupLocalPendingContactsChangeInfo
+ // is there first
+ foreach (QSharedPointer<Contact> contact, contacts) {
+ uint handle = contact->handle()[0];
+ // the key here is the actor
+ // if we retrieved the actor as well as the contact, update info for the
+ // contact
+ if (pendingGroupMembersChangeInfo.contains(handle)) {
+ LocalPendingInfo info = pendingGroupMembersChangeInfo[handle];
+ if (groupLocalPendingContactsChangeInfo.contains(info.toBeAdded)) {
+ groupLocalPendingContactsChangeInfo[info.toBeAdded].update(
+ contact, info.reason, info.message);
+ }
+ else if (handle == groupSelfHandle) {
+ groupSelfContactRemoveInfo = GroupMemberChangeInfo(
+ contact, info.reason, info.message);
+ }
+ }
+ }
+
pendingGroupMembers.clear();
pendingGroupLocalPendingMembers.clear();
pendingGroupRemotePendingMembers.clear();
+ pendingGroupMembersChangeInfo.clear();
if (buildingInitialContacts) {
buildingInitialContacts = false;
@@ -606,6 +651,10 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
groupRemotePendingContacts.remove(handle);
}
+ if (groupLocalPendingContactsChangeInfo.contains(handle)) {
+ groupLocalPendingContactsChangeInfo.remove(handle);
+ }
+
if (contactToRemove) {
groupContactsRemoved.append(contactToRemove);
}
@@ -1098,6 +1147,60 @@ QList<QSharedPointer<Contact> > Channel::groupRemotePendingContacts() const
}
/**
+ * Return information of a local pending contact change. If
+ * no information is available, an object for which
+ * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
+ *
+ * \param A Contact object that is on the local pending contacts list.
+ * \return The change info in a GroupMemberChangeInfo object.
+ */
+Channel::GroupMemberChangeInfo Channel::groupLocalPendingContactChangeInfo(
+ const QSharedPointer<Contact> &contact) const
+{
+ if (!isReady()) {
+ warning() << "Channel::groupLocalPending() used channel not ready";
+ }
+ else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
+ warning() << "Channel::groupLocalPending() used with no group interface";
+ }
+ else if (!contact) {
+ warning() << "Channel::groupLocalPending() used with null contact param";
+ return GroupMemberChangeInfo();
+ }
+
+ uint handle = contact->handle()[0];
+ return mPriv->groupLocalPendingContactsChangeInfo.value(handle);
+}
+
+/**
+ * Return information on the removal of the local user from the group. If
+ * the user hasn't been removed from the group, an object for which
+ * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
+ *
+ * This method should be called only after the channel has been closed.
+ * This is useful for getting the remove information after missing the
+ * corresponding groupMembersChanged() signal, as the local user being
+ * removed usually causes the remote Channel to be closed.
+ *
+ * The returned information is not guaranteed to be correct if
+ * groupIsSelfHandleTracked() returns false and a self handle change has
+ * occurred on the remote object.
+ *
+ * \return The remove info in a GroupMemberChangeInfo object.
+ */
+Channel::GroupMemberChangeInfo Channel::groupSelfContactRemoveInfo() const
+{
+ if (!isReady()) {
+ warning() << "Channel::groupLocalPending() used channel not ready";
+ }
+ else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
+ warning() << "Channel::groupLocalPending() used with no group interface";
+ }
+
+ return mPriv->groupSelfContactRemoveInfo;
+}
+
+/**
* Returns whether globally valid handles can be looked up using the
* channel-specific handle on this channel using this object.
*
@@ -1204,37 +1307,6 @@ uint Channel::groupSelfHandle() const
}
/**
- * Returns information on the removal of the local user from the group. If
- * the user hasn't been removed from the group, an object for which
- * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
- *
- * This method should be called only after the channel has been closed.
- * This is useful for getting the remove information after missing the
- * corresponding groupMembersChanged() (or
- * groupLocalPendingChanged()/groupRemotePendingChanged()) signal, as
- * the local user being removed usually causes the remote %Channel to be
- * closed.
- *
- * The returned information is not guaranteed to be correct if
- * groupIsSelfHandleTracked() returns false and a self handle change has
- * occurred on the remote object.
- *
- * \return The remove info in a GroupMemberChangeInfo object.
- */
-Channel::GroupMemberChangeInfo Channel::groupSelfRemoveInfo() const
-{
- if (isValid()) {
- warning() << "Channel::groupSelfRemoveInfo() used channel not closed";
- }
- else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
- warning() << "Channel::groupSelfRemoveInfo() used with "
- "no group interface";
- }
-
- return mPriv->groupSelfRemoveInfo;
-}
-
-/**
* \fn void groupFlagsChanged(uint flags, uint added, uint removed)
*
* Emitted when the value returned by groupFlags() changes.
@@ -1663,15 +1735,13 @@ void Channel::gotAllMembers(QDBusPendingCallWatcher *watcher)
mPriv->pendingGroupLocalPendingMembers = QSet<uint>::fromList(reply.argumentAt<1>());
mPriv->pendingGroupRemotePendingMembers = QSet<uint>::fromList(reply.argumentAt<2>());
- mPriv->buildingInitialContacts = true;
- mPriv->buildContacts();
+ // delay building contacts now until we process gotLocalPendingMembersWithInfo
}
continueIntrospection();
}
-#if 0
-void Channel::gotLocalPending(QDBusPendingCallWatcher *watcher)
+void Channel::gotLocalPendingMembersWithInfo(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<LocalPendingInfoList> reply = *watcher;
@@ -1685,14 +1755,16 @@ void Channel::gotLocalPending(QDBusPendingCallWatcher *watcher)
"Channel.Interface.Group::GetLocalPendingMembersWithInfo()";
foreach (LocalPendingInfo info, reply.value()) {
- mPriv->groupLocalPending[info.toBeAdded] =
- GroupMemberChangeInfo(info.actor, info.reason, info.message);
+ mPriv->pendingGroupMembersChangeInfo[info.actor] = info;
}
}
+ // build contacts even if the call failed
+ mPriv->buildingInitialContacts = true;
+ mPriv->buildContacts();
+
continueIntrospection();
}
-#endif
void Channel::gotSelfHandle(QDBusPendingCallWatcher *watcher)
{
diff --git a/TelepathyQt4/Client/channel.h b/TelepathyQt4/Client/channel.h
index e3204ec..aa6cf53 100644
--- a/TelepathyQt4/Client/channel.h
+++ b/TelepathyQt4/Client/channel.h
@@ -97,21 +97,30 @@ public:
{
public:
GroupMemberChangeInfo()
- : mActor(-1), mReason(0), mIsValid(false) {}
+ : mReason(0), mIsValid(false) {}
- GroupMemberChangeInfo(uint actor, uint reason, const QString &message)
+ GroupMemberChangeInfo(const QSharedPointer<Contact> &actor, uint reason, const QString &message)
: mActor(actor), mReason(reason), mMessage(message), mIsValid(true) {}
- bool isValid() const { return mIsValid; }
+ bool isValid() const { return !mActor.isNull(); }
- uint actor() const { return mActor; }
+ QSharedPointer<Contact> actor() const { return mActor; }
uint reason() const { return mReason; }
const QString &message() const { return mMessage; }
private:
- uint mActor;
+ friend class Channel;
+
+ void update(const QSharedPointer<Contact> &actor, uint reason, const QString &message)
+ {
+ mActor = actor;
+ mReason = reason;
+ mMessage = message;
+ }
+
+ QSharedPointer<Contact> mActor;
uint mReason;
QString mMessage;
bool mIsValid;
@@ -119,6 +128,9 @@ public:
typedef QMap<uint, GroupMemberChangeInfo> GroupMemberChangeInfoMap;
+ GroupMemberChangeInfo groupLocalPendingContactChangeInfo(const QSharedPointer<Contact> &contact) const;
+ GroupMemberChangeInfo groupSelfContactRemoveInfo() const;
+
bool groupAreHandleOwnersAvailable() const;
HandleOwnerMap groupHandleOwners() const;
@@ -127,8 +139,6 @@ public:
uint groupSelfHandle() const;
- GroupMemberChangeInfo groupSelfRemoveInfo() const;
-
Q_SIGNALS:
void groupFlagsChanged(uint flags, uint added, uint removed);
@@ -259,7 +269,7 @@ private Q_SLOTS:
void gotGroupProperties(QDBusPendingCallWatcher *watcher);
void gotGroupFlags(QDBusPendingCallWatcher *watcher);
void gotAllMembers(QDBusPendingCallWatcher *watcher);
- // void gotLocalPending(QDBusPendingCallWatcher *watcher);
+ void gotLocalPendingMembersWithInfo(QDBusPendingCallWatcher *watcher);
void gotSelfHandle(QDBusPendingCallWatcher *watcher);
void gotContacts(Telepathy::Client::PendingOperation *op);
void onGroupFlagsChanged(uint, uint);
--
1.5.6.5
More information about the telepathy-commits
mailing list