[Telepathy-commits] [telepathy-qt4/master] Channel: Added support for MembersChangedDetailed.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Tue Feb 10 18:55:57 PST 2009
---
TelepathyQt4/Client/channel.cpp | 149 ++++++++++++++++++++++++++++++++++-----
TelepathyQt4/Client/channel.h | 40 ++++++++++-
tests/dbus/chan-group.cpp | 10 ++--
3 files changed, 174 insertions(+), 25 deletions(-)
diff --git a/TelepathyQt4/Client/channel.cpp b/TelepathyQt4/Client/channel.cpp
index f03b9c7..4422fb1 100644
--- a/TelepathyQt4/Client/channel.cpp
+++ b/TelepathyQt4/Client/channel.cpp
@@ -83,6 +83,8 @@ struct Channel::Private
void nowHaveInterfaces();
+ bool setGroupFlags(uint groupFlags);
+
void buildContacts();
void processMembersChanged();
void updateContacts(const QList<QSharedPointer<Contact> > &contacts =
@@ -128,6 +130,8 @@ struct Channel::Private
// Group flags
uint groupFlags;
+ bool usingMembersChangedDetailed;
+
// Group members
bool groupHaveMembers;
bool buildingInitialContacts;
@@ -160,27 +164,34 @@ struct Channel::Private
struct Channel::Private::GroupMembersChangedInfo
{
- GroupMembersChangedInfo(const QString &message,
- const Telepathy::UIntList &added, const Telepathy::UIntList &removed,
+ GroupMembersChangedInfo(const Telepathy::UIntList &added, const Telepathy::UIntList &removed,
const Telepathy::UIntList &localPending, const Telepathy::UIntList &remotePending,
- uint actor, uint reason)
- : message(message),
- added(added),
+ uint actor, uint reason, const QString &message,
+ const HandleIdentifierMap &contactIds = HandleIdentifierMap(),
+ const QString &error = QString(), const QString &debugMessage = QString())
+ : added(added),
removed(removed),
localPending(localPending),
remotePending(remotePending),
actor(actor),
- reason(reason)
+ reason(reason),
+ message(message),
+ contactIds(contactIds),
+ error(error),
+ debugMessage(debugMessage)
{
}
- QString message;
Telepathy::UIntList added;
Telepathy::UIntList removed;
Telepathy::UIntList localPending;
Telepathy::UIntList remotePending;
uint actor;
uint reason;
+ QString message;
+ HandleIdentifierMap contactIds;
+ QString error;
+ QString debugMessage;
};
class Channel::Private::PendingReady : public PendingOperation
@@ -212,6 +223,7 @@ Channel::Private::Private(Channel *parent, Connection *connection)
requested(false),
initiatorHandle(0),
groupFlags(0),
+ usingMembersChangedDetailed(false),
groupHaveMembers(false),
buildingInitialContacts(false),
buildingContacts(false),
@@ -464,7 +476,7 @@ void Channel::Private::extract0176GroupProps(const QVariantMap &props)
groupAreHandleOwnersAvailable = true;
groupIsSelfHandleTracked = true;
- groupFlags = qdbus_cast<uint>(props["GroupFlags"]);
+ setGroupFlags(qdbus_cast<uint>(props["GroupFlags"]));
groupHandleOwners = qdbus_cast<HandleOwnerMap>(props["HandleOwners"]);
pendingGroupMembers = QSet<uint>::fromList(qdbus_cast<UIntList>(props["Members"]));
@@ -493,6 +505,61 @@ void Channel::Private::nowHaveInterfaces()
}
}
+bool Channel::Private::setGroupFlags(uint newGroupFlags)
+{
+ if (groupFlags == newGroupFlags) {
+ return false;
+ }
+
+ groupFlags = newGroupFlags;
+
+ // this shouldn't happen but let's make sure
+ if (!interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
+ return false;
+ }
+
+ if ((groupFlags & ChannelGroupFlagMembersChangedDetailed) &&
+ !usingMembersChangedDetailed) {
+ usingMembersChangedDetailed = true;
+ parent->disconnect(group,
+ SIGNAL(MembersChanged(const QString&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, uint, uint)),
+ parent,
+ SLOT(onMembersChanged(const QString&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, uint, uint)));
+ parent->connect(group,
+ SIGNAL(MembersChangedDetailed(const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const QVariantMap&)),
+ SLOT(onMembersChangedDetailed(const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const QVariantMap&)));
+ } else if (!(groupFlags & ChannelGroupFlagMembersChangedDetailed) &&
+ usingMembersChangedDetailed) {
+ usingMembersChangedDetailed = false;
+ parent->disconnect(group,
+ SIGNAL(MembersChangedDetailed(const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const QVariantMap&)),
+ parent,
+ SLOT(onMembersChangedDetailed(const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const QVariantMap&)));
+ parent->connect(group,
+ SIGNAL(MembersChanged(const QString&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, uint, uint)),
+ parent,
+ SLOT(onMembersChanged(const QString&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, const Telepathy::UIntList&,
+ const Telepathy::UIntList&, uint, uint)));
+ }
+
+ return true;
+}
+
void Channel::Private::buildContacts()
{
buildingContacts = true;
@@ -737,14 +804,19 @@ void Channel::Private::updateContacts(const QList<QSharedPointer<Contact> > &con
!groupLocalPendingContactsAdded.isEmpty() ||
!groupRemotePendingContactsAdded.isEmpty() ||
!groupContactsRemoved.isEmpty()) {
+ GroupMemberChangeDetails details(
+ actorContact,
+ currentGroupMembersChangedInfo->reason,
+ currentGroupMembersChangedInfo->message,
+ currentGroupMembersChangedInfo->contactIds,
+ currentGroupMembersChangedInfo->error,
+ currentGroupMembersChangedInfo->debugMessage);
emit parent->groupMembersChanged(
groupContactsAdded,
groupLocalPendingContactsAdded,
groupRemotePendingContactsAdded,
groupContactsRemoved,
- actorContact,
- currentGroupMembersChangedInfo->reason,
- currentGroupMembersChangedInfo->message);
+ details);
}
delete currentGroupMembersChangedInfo;
currentGroupMembersChangedInfo = 0;
@@ -1870,7 +1942,7 @@ void Channel::gotGroupFlags(QDBusPendingCallWatcher *watcher)
}
else {
debug() << "Got reply to fallback Channel.Interface.Group::GetGroupFlags()";
- mPriv->groupFlags = reply.value();
+ mPriv->setGroupFlags(reply.value());
if (mPriv->groupFlags & ChannelGroupFlagProperties) {
warning() << " Reply included ChannelGroupFlagProperties, even "
@@ -1985,10 +2057,10 @@ void Channel::onGroupFlagsChanged(uint added, uint removed)
debug().nospace() << "Arguments after filtering (" << hex << added <<
", " << removed << ")";
- mPriv->groupFlags |= added;
- mPriv->groupFlags &= ~removed;
-
- if (added || removed) {
+ uint groupFlags = mPriv->groupFlags;
+ groupFlags |= added;
+ groupFlags &= ~removed;
+ if (mPriv->setGroupFlags(groupFlags)) {
debug() << "Emitting groupFlagsChanged with" << mPriv->groupFlags <<
"value" << added << "added" << removed << "removed";
emit groupFlagsChanged(mPriv->groupFlags, added, removed);
@@ -2036,8 +2108,49 @@ void Channel::onMembersChanged(const QString &message,
}
mPriv->groupMembersChangedQueue.enqueue(
- new Private::GroupMembersChangedInfo(message, added, removed,
- localPending, remotePending, actor, reason));
+ new Private::GroupMembersChangedInfo(added, removed,
+ localPending, remotePending, actor, reason, message));
+
+ if (!mPriv->buildingContacts) {
+ // if we are building contacts, we should wait it to finish so we don't
+ // present the user with wrong information
+ mPriv->processMembersChanged();
+ }
+}
+
+void Channel::onMembersChangedDetailed(
+ const Telepathy::UIntList &added, const Telepathy::UIntList &removed,
+ const Telepathy::UIntList &localPending, const Telepathy::UIntList &remotePending,
+ const QVariantMap &details)
+{
+ debug() << "Got Channel.Interface.Group::MembersChangedDetailed with" << added.size() <<
+ "added," << removed.size() << "removed," << localPending.size() <<
+ "moved to LP," << remotePending.size() << "moved to RP," << details.value("actor").value<uint>() <<
+ "being the actor," << details.value("change-reason").value<uint>() << "the reason and" <<
+ details.value("message").value<QString>() << "the message";
+
+ if (!mPriv->groupHaveMembers) {
+ debug() << "Still waiting for initial group members, "
+ "so ignoring delta signal...";
+ return;
+ }
+
+ if (added.isEmpty() && removed.isEmpty() &&
+ localPending.isEmpty() && remotePending.isEmpty()) {
+ debug() << "Nothing really changed, so skipping membersChanged";
+ return;
+ }
+
+ mPriv->groupMembersChangedQueue.enqueue(
+ new Private::GroupMembersChangedInfo(
+ added, removed,
+ localPending, remotePending,
+ details.value("actor").value<uint>(),
+ details.value("reason").value<uint>(),
+ details.value("message").value<QString>(),
+ details.value("contact-ids").value<HandleIdentifierMap>(),
+ details.value("error").value<QString>(),
+ details.value("debug-message").value<QString>()));
if (!mPriv->buildingContacts) {
// if we are building contacts, we should wait it to finish so we don't
diff --git a/TelepathyQt4/Client/channel.h b/TelepathyQt4/Client/channel.h
index a3f2881..f914600 100644
--- a/TelepathyQt4/Client/channel.h
+++ b/TelepathyQt4/Client/channel.h
@@ -133,6 +133,39 @@ public:
bool mIsValid;
};
+ class GroupMemberChangeDetails
+ {
+ public:
+ GroupMemberChangeDetails(const QSharedPointer<Contact> &actorContact,
+ uint reason, const QString &message,
+ const HandleIdentifierMap &contactIds,
+ const QString &error, const QString &debugMessage)
+ : mActorContact(actorContact), mReason(reason), mMessage(message),
+ mContactIds(contactIds), mError(error), mDebugMessage(debugMessage) {}
+
+ QSharedPointer<Contact> actorContact() const { return mActorContact; }
+
+ uint reason() const { return mReason; }
+
+ const QString &message() const { return mMessage; }
+
+ HandleIdentifierMap contactIds() const { return mContactIds; }
+
+ QString error() const { return mError; }
+
+ QString debugMessage() const { return mDebugMessage; }
+
+ private:
+ friend class Channel;
+
+ QSharedPointer<Contact> mActorContact;
+ uint mReason;
+ QString mMessage;
+ HandleIdentifierMap mContactIds;
+ QString mError;
+ QString mDebugMessage;
+ };
+
typedef QMap<uint, GroupMemberChangeInfo> GroupMemberChangeInfoMap;
GroupMemberChangeInfo groupLocalPendingContactChangeInfo(const QSharedPointer<Contact> &contact) const;
@@ -157,8 +190,7 @@ Q_SIGNALS:
const QList<QSharedPointer<Contact> > &groupLocalPendingMembersAdded,
const QList<QSharedPointer<Contact> > &groupLocalPendingMembersRemoved,
const QList<QSharedPointer<Contact> > &groupMembersRemoved,
- QSharedPointer<Contact> actor,
- uint reason, const QString &message);
+ const Channel::GroupMemberChangeDetails &details);
void groupHandleOwnersChanged(const HandleOwnerMap &owners,
const Telepathy::UIntList &added, const Telepathy::UIntList &removed);
@@ -286,6 +318,10 @@ private Q_SLOTS:
void onMembersChanged(const QString&,
const Telepathy::UIntList&, const Telepathy::UIntList&,
const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint);
+ void onMembersChangedDetailed(
+ const Telepathy::UIntList &added, const Telepathy::UIntList &removed,
+ const Telepathy::UIntList &localPending, const Telepathy::UIntList &remotePending,
+ const QVariantMap &details);
void onHandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&);
void onSelfHandleChanged(uint);
diff --git a/tests/dbus/chan-group.cpp b/tests/dbus/chan-group.cpp
index 52ec771..cf5bcda 100644
--- a/tests/dbus/chan-group.cpp
+++ b/tests/dbus/chan-group.cpp
@@ -43,7 +43,7 @@ protected Q_SLOTS:
const QList<QSharedPointer<Contact> > &groupLocalPendingMembersAdded,
const QList<QSharedPointer<Contact> > &groupRemotePendingMembersAdded,
const QList<QSharedPointer<Contact> > &groupMembersRemoved,
- QSharedPointer<Contact> actor, uint reason, const QString &message);
+ const Channel::GroupMemberChangeDetails &details);
private Q_SLOTS:
void initTestCase();
@@ -216,7 +216,7 @@ void TestChanGroup::onGroupMembersChanged(
const QList<QSharedPointer<Contact> > &groupLocalPendingMembersAdded,
const QList<QSharedPointer<Contact> > &groupRemotePendingMembersAdded,
const QList<QSharedPointer<Contact> > &groupMembersRemoved,
- QSharedPointer<Contact> actor, uint reason, const QString &message)
+ const Channel::GroupMemberChangeDetails &details)
{
int ret = -1;
@@ -254,7 +254,7 @@ void TestChanGroup::onGroupMembersChanged(
}
} else {
if (mChan->groupRemotePendingContacts().count() == 1) {
- QCOMPARE(message, QString("I want to add john"));
+ QCOMPARE(details.message(), QString("I want to add john"));
QCOMPARE(mChan->groupRemotePendingContacts().first()->id(),
QString("john@#room"));
ret = 1;
@@ -405,13 +405,13 @@ void TestChanGroup::testCreateChannel()
const QList<QSharedPointer<Contact> > &,
const QList<QSharedPointer<Contact> > &,
const QList<QSharedPointer<Contact> > &,
- QSharedPointer<Contact>, uint, const QString &)),
+ const Channel::GroupMemberChangeDetails &)),
SLOT(onGroupMembersChanged(
const QList<QSharedPointer<Contact> > &,
const QList<QSharedPointer<Contact> > &,
const QList<QSharedPointer<Contact> > &,
const QList<QSharedPointer<Contact> > &,
- QSharedPointer<Contact>, uint, const QString &))));
+ const Channel::GroupMemberChangeDetails &))));
QCOMPARE(mLoop->exec(), 0);
QStringList ids = QStringList() << "john@#room";
--
1.5.6.5
More information about the telepathy-commits
mailing list