[telepathy-qt4/master] Connection: Added initial roster groups support.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Tue Jul 21 23:53:18 PDT 2009


---
 TelepathyQt4/connection.cpp      |  102 ++++++++++++++++++++++++++++++++++++++
 TelepathyQt4/connection.h        |    4 ++
 TelepathyQt4/contact-manager.cpp |   32 ++++++++++++
 TelepathyQt4/contact-manager.h   |    4 ++
 4 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/TelepathyQt4/connection.cpp b/TelepathyQt4/connection.cpp
index bccdf9c..9a8865a 100644
--- a/TelepathyQt4/connection.cpp
+++ b/TelepathyQt4/connection.cpp
@@ -83,6 +83,7 @@ struct Connection::Private
     static void introspectSelfContact(Private *self);
     static void introspectSimplePresence(Private *self);
     static void introspectRoster(Private *self);
+    static void introspectRosterGroups(Private *self);
 
     struct HandleContext;
 
@@ -114,6 +115,8 @@ struct Connection::Private
     uint selfHandle;
     QMap<uint, ContactManager::ContactListChannel> contactListsChannels;
     uint contactListsChannelsReady;
+    QList<ChannelPtr> contactListGroupsChannels;
+    uint contactListGroupsChannelsReady;
 
     // (Bus connection name, service name) -> HandleContext
     static QMap<QPair<QString, QString>, HandleContext *> handleContexts;
@@ -163,6 +166,7 @@ Connection::Private::Private(Connection *parent)
       statusReason(ConnectionStatusReasonNoneSpecified),
       selfHandle(0),
       contactListsChannelsReady(0),
+      contactListGroupsChannelsReady(0),
       handleContext(0),
       contactManager(0)
 {
@@ -200,6 +204,14 @@ Connection::Private::Private(Connection *parent)
         this);
     introspectables[FeatureRoster] = introspectableRoster;
 
+    ReadinessHelper::Introspectable introspectableRosterGroups(
+        QSet<uint>() << Connection::StatusConnected,                                   // makesSenseForStatuses
+        Features() << FeatureRoster,                                                   // dependsOnFeatures (core)
+        QStringList() << TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS,            // dependsOnInterfaces
+        (ReadinessHelper::IntrospectFunc) &Private::introspectRosterGroups,
+        this);
+    introspectables[FeatureRosterGroups] = introspectableRosterGroups;
+
     readinessHelper->addIntrospectables(introspectables);
     readinessHelper->setCurrentStatus(status);
     parent->connect(readinessHelper,
@@ -384,6 +396,30 @@ void Connection::Private::introspectRoster(Connection::Private *self)
     }
 }
 
+void Connection::Private::introspectRosterGroups(Connection::Private *self)
+{
+    debug() << "Introspecting roster groups";
+
+    // we already checked if requests interface exists, so bypass requests
+    // interface checking
+    Client::ConnectionInterfaceRequestsInterface *iface =
+        self->parent->requestsInterface(BypassInterfaceCheck);
+
+    debug() << "Connecting to Requests.NewChannels";
+    self->parent->connect(iface,
+            SIGNAL(NewChannels(const Tp::ChannelDetailsList&)),
+            SLOT(onNewChannels(const Tp::ChannelDetailsList&)));
+
+    debug() << "Retrieving channels";
+    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+            self->parent->propertiesInterface()->Get(
+                TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS,
+                "Channels"), self->parent);
+    self->parent->connect(watcher,
+            SIGNAL(finished(QDBusPendingCallWatcher*)),
+            SLOT(gotChannels(QDBusPendingCallWatcher*)));
+}
+
 Connection::PendingConnect::PendingConnect(Connection *parent, const Features &requestedFeatures)
     : PendingReady(requestedFeatures, parent, parent)
 {
@@ -451,6 +487,7 @@ const Feature Connection::FeatureCore = Feature(Connection::staticMetaObject.cla
 const Feature Connection::FeatureSelfContact = Feature(Connection::staticMetaObject.className(), 1);
 const Feature Connection::FeatureSimplePresence = Feature(Connection::staticMetaObject.className(), 2);
 const Feature Connection::FeatureRoster = Feature(Connection::staticMetaObject.className(), 3);
+const Feature Connection::FeatureRosterGroups = Feature(Connection::staticMetaObject.className(), 4);
 
 ConnectionPtr Connection::create(const QString &busName,
         const QString &objectPath)
@@ -996,6 +1033,71 @@ void Connection::contactListChannelReady()
     }
 }
 
+void Connection::onNewChannels(const Tp::ChannelDetailsList &channelDetailsList)
+{
+    QString channelType;
+    uint handleType;
+    foreach (const ChannelDetails &channelDetails, channelDetailsList) {
+        channelType = channelDetails.properties.value(
+                QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+        if (channelType != TELEPATHY_INTERFACE_CHANNEL_TYPE_CONTACT_LIST) {
+            continue;
+        }
+
+        handleType = channelDetails.properties.value(
+                QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType")).toUInt();
+        if (handleType != Tp::HandleTypeGroup) {
+            continue;
+        }
+
+        ChannelPtr channel = Channel::create(ConnectionPtr(this),
+                channelDetails.channel.path(), channelDetails.properties);
+        mPriv->contactListGroupsChannels.append(channel);
+        connect(channel->becomeReady(),
+                SIGNAL(finished(Tp::PendingOperation*)),
+                SLOT(onContactListGroupChannelReady(Tp::PendingOperation*)));
+    }
+
+    if (channelDetailsList.isEmpty()) {
+        mPriv->readinessHelper->setIntrospectCompleted(
+                FeatureRosterGroups, true);
+    }
+}
+
+void Connection::onContactListGroupChannelReady(Tp::PendingOperation *op)
+{
+    if (!isReady(FeatureRosterGroups)) {
+        if (++mPriv->contactListGroupsChannelsReady ==
+                mPriv->contactListGroupsChannels.size()) {
+            debug() << "FeatureRosterGroups ready";
+            mPriv->contactManager->setContactListGroupsChannels(
+                    mPriv->contactListGroupsChannels);
+            mPriv->readinessHelper->setIntrospectCompleted(
+                    FeatureRosterGroups, true);
+        }
+    } else {
+        PendingReady *pr = qobject_cast<PendingReady*>(op);
+        ChannelPtr channel = ChannelPtr(qobject_cast<Channel*>(pr->object()));
+        mPriv->contactManager->addContactListGroupChannel(channel);
+        mPriv->contactListGroupsChannels.removeOne(channel);
+    }
+}
+
+void Connection::gotChannels(QDBusPendingCallWatcher *watcher)
+{
+    QDBusPendingReply<QVariant> reply = *watcher;
+
+    if (!reply.isError()) {
+        debug() << "Got channels";
+        onNewChannels(qdbus_cast<ChannelDetailsList>(reply.value()));
+    } else {
+        warning().nospace() << "Getting channels failed with " <<
+            reply.error().name() << ":" << reply.error().message();
+    }
+
+    watcher->deleteLater();
+}
+
 /**
  * Get the ConnectionInterface for this Connection. This
  * method is protected since the convenience methods provided by this
diff --git a/TelepathyQt4/connection.h b/TelepathyQt4/connection.h
index ff7f181..b79a6a6 100644
--- a/TelepathyQt4/connection.h
+++ b/TelepathyQt4/connection.h
@@ -70,6 +70,7 @@ public:
     static const Feature FeatureSelfContact;
     static const Feature FeatureSimplePresence;
     static const Feature FeatureRoster;
+    static const Feature FeatureRosterGroups;
 
     enum Status {
         StatusDisconnected = ConnectionStatusDisconnected,
@@ -174,6 +175,9 @@ private Q_SLOTS:
     void gotContactListsHandles(Tp::PendingOperation *);
     void gotContactListChannel(Tp::PendingOperation *);
     void contactListChannelReady();
+    void onNewChannels(const Tp::ChannelDetailsList &);
+    void onContactListGroupChannelReady(Tp::PendingOperation *);
+    void gotChannels(QDBusPendingCallWatcher *);
 
     void doReleaseSweep(uint type);
 
diff --git a/TelepathyQt4/contact-manager.cpp b/TelepathyQt4/contact-manager.cpp
index 09bc987..5894c39 100644
--- a/TelepathyQt4/contact-manager.cpp
+++ b/TelepathyQt4/contact-manager.cpp
@@ -83,6 +83,7 @@ struct ContactManager::Private
     ChannelPtr publishChannel;
     ChannelPtr storedChannel;
     ChannelPtr denyChannel;
+    QMap<QString, ChannelPtr> contactListGroupsChannels;
 
     Contacts allKnownContacts() const;
     void updateContactsPresenceState();
@@ -157,6 +158,11 @@ Contacts ContactManager::allKnownContacts() const
     return mPriv->allKnownContacts();
 }
 
+QStringList ContactManager::allKnownGroups() const
+{
+    return mPriv->contactListGroupsChannels.keys();
+}
+
 /**
  * Return whether subscribing to additional contacts' presence is supported
  * on this channel.
@@ -791,6 +797,32 @@ void ContactManager::setContactListsChannels(
     }
 }
 
+void ContactManager::setContactListGroupsChannels(
+        const QList<ChannelPtr> &contactListGroupsChannels)
+{
+    Q_ASSERT(mPriv->contactListGroupsChannels.isEmpty());
+
+    QString id;
+    foreach (const ChannelPtr &contactListGroupChannel, contactListGroupsChannels) {
+        id = contactListGroupChannel->immutableProperties().value(
+                QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetID")).toString();
+        mPriv->contactListGroupsChannels.insert(id, contactListGroupChannel);
+
+        // TODO connect to closed signal
+    }
+}
+
+void ContactManager::addContactListGroupChannel(
+        const ChannelPtr &contactListGroupChannel)
+{
+    QString id = contactListGroupChannel->immutableProperties().value(
+            QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetID")).toString();
+    mPriv->contactListGroupsChannels.insert(id, contactListGroupChannel);
+
+    // TODO connect to closed signal
+    //      emit group added signal
+}
+
 ContactPtr ContactManager::lookupContactByHandle(uint handle)
 {
     ContactPtr contact;
diff --git a/TelepathyQt4/contact-manager.h b/TelepathyQt4/contact-manager.h
index 58f8634..f1ada75 100644
--- a/TelepathyQt4/contact-manager.h
+++ b/TelepathyQt4/contact-manager.h
@@ -54,6 +54,7 @@ public:
     QSet<Contact::Feature> supportedFeatures() const;
 
     Contacts allKnownContacts() const;
+    QStringList allKnownGroups() const;
 
     bool canRequestPresenceSubscription() const;
     bool subscriptionRequestHasMessage() const;
@@ -168,6 +169,9 @@ private:
 
     void setContactListsChannels(
             const QMap<uint, ContactListChannel> &contactListsChannels);
+    void setContactListGroupsChannels(
+            const QList<ChannelPtr> &contactListGroupsChannels);
+    void addContactListGroupChannel(const ChannelPtr &contactListGroupChannel);
 
     struct Private;
     friend struct Private;
-- 
1.5.6.5




More information about the telepathy-commits mailing list