[telepathy-qt4/master] ClientRegistrar: Use exisiting high-level classes for AbstractClientHandler::handlerChannels.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Tue May 19 06:48:59 PDT 2009


Use exisiting high-level classes (Account, Connection, Channel) for
AbstractClientHandler::handlerChannels.
---
 TelepathyQt4/abstract-client.h           |   11 ++-
 TelepathyQt4/client-registrar-internal.h |   65 ++++++++++++++-
 TelepathyQt4/client-registrar.cpp        |  139 ++++++++++++++++++++++++++++-
 3 files changed, 205 insertions(+), 10 deletions(-)

diff --git a/TelepathyQt4/abstract-client.h b/TelepathyQt4/abstract-client.h
index 91d3a88..569cf04 100644
--- a/TelepathyQt4/abstract-client.h
+++ b/TelepathyQt4/abstract-client.h
@@ -29,7 +29,10 @@
 #include <TelepathyQt4/SharedPtr>
 #include <TelepathyQt4/Types>
 
+#include <QList>
 #include <QObject>
+#include <QString>
+#include <QVariantMap>
 
 namespace Tp
 {
@@ -61,12 +64,12 @@ public:
 
     ChannelClassList channelFilter() const;
     virtual bool bypassApproval() const = 0;
-    virtual ObjectPathList handledChannels() const = 0;
+    virtual QList<ChannelPtr> handledChannels() const = 0;
 
     virtual void handleChannels(PendingClientOperation *operation,
-            const QDBusObjectPath &account,
-            const QDBusObjectPath &connection,
-            const ChannelDetailsList &channels,
+            const AccountPtr &account,
+            const ConnectionPtr &connection,
+            const QList<ChannelPtr> &channels,
             const ObjectPathList &requestsSatisfied,
             qulonglong userActionTime,
             const QVariantMap &handlerInfo) = 0;
diff --git a/TelepathyQt4/client-registrar-internal.h b/TelepathyQt4/client-registrar-internal.h
index 322c098..ae991e6 100644
--- a/TelepathyQt4/client-registrar-internal.h
+++ b/TelepathyQt4/client-registrar-internal.h
@@ -26,11 +26,15 @@
 #include <QtDBus/QtDBus>
 
 #include <TelepathyQt4/AbstractClientHandler>
+#include <TelepathyQt4/Channel>
 #include <TelepathyQt4/Types>
 
 namespace Tp
 {
 
+class PendingClientOperation;
+class PendingOperation;
+
 class ClientAdaptor : public QDBusAbstractAdaptor
 {
     Q_OBJECT
@@ -99,7 +103,11 @@ public: // Properties
 
     inline Tp::ObjectPathList HandledChannels() const
     {
-        return mClient->handledChannels();
+        Tp::ObjectPathList paths;
+        foreach (const ChannelPtr &channel, mClient->handledChannels()) {
+            paths.append(QDBusObjectPath(channel->objectPath()));
+        }
+        return paths;
     }
 
 public Q_SLOTS: // Methods
@@ -111,9 +119,64 @@ public Q_SLOTS: // Methods
             const QVariantMap &handlerInfo,
             const QDBusMessage &message);
 
+private Q_SLOTS:
+    void onHandleChannelsCallFinished();
+
 private:
+    void processHandleChannelsQueue();
+
+    class HandleChannelsCall;
+
     QDBusConnection mBus;
     AbstractClientHandler *mClient;
+    QQueue<HandleChannelsCall*> mHandleChannelsQueue;
+    bool mProcessingHandleChannels;
+};
+
+class ClientHandlerAdaptor::HandleChannelsCall : public QObject
+{
+    Q_OBJECT
+
+public:
+    HandleChannelsCall(AbstractClientHandler *client,
+            const QDBusObjectPath &account,
+            const QDBusObjectPath &connection,
+            const ChannelDetailsList &channels,
+            const ObjectPathList &requestsSatisfied,
+            qulonglong userActionTime,
+            const QVariantMap &handlerInfo,
+            const QDBusConnection &bus,
+            const QDBusMessage &message,
+            QObject *parent);
+    virtual ~HandleChannelsCall();
+
+    void process();
+
+Q_SIGNALS:
+    void finished();
+
+private Q_SLOTS:
+    void onObjectReady(Tp::PendingOperation *op);
+    void onConnectionReady(Tp::PendingOperation *op);
+
+private:
+    void checkFinished();
+    void setFinishedWithError(const QString &errorName,
+            const QString &errorMessage);
+
+    AbstractClientHandler *mClient;
+    QDBusObjectPath mAccountPath;
+    QDBusObjectPath mConnectionPath;
+    ChannelDetailsList mChannelDetailsList;
+    ObjectPathList mRequestsSatisfied;
+    qulonglong mUserActionTime;
+    QVariantMap mHandlerInfo;
+    QDBusConnection mBus;
+    QDBusMessage mMessage;
+    PendingClientOperation *mOperation;
+    AccountPtr mAccount;
+    ConnectionPtr mConnection;
+    QList<ChannelPtr> mChannels;
 };
 
 class ClientHandlerRequestsAdaptor : public QDBusAbstractAdaptor
diff --git a/TelepathyQt4/client-registrar.cpp b/TelepathyQt4/client-registrar.cpp
index 263a6be..ec78a35 100644
--- a/TelepathyQt4/client-registrar.cpp
+++ b/TelepathyQt4/client-registrar.cpp
@@ -27,7 +27,11 @@
 
 #include "TelepathyQt4/debug-internal.h"
 
+#include <TelepathyQt4/Account>
+#include <TelepathyQt4/Channel>
+#include <TelepathyQt4/Connection>
 #include <TelepathyQt4/PendingClientOperation>
+#include <TelepathyQt4/PendingReady>
 
 namespace Tp
 {
@@ -47,7 +51,8 @@ ClientHandlerAdaptor::ClientHandlerAdaptor(const QDBusConnection &bus,
         AbstractClientHandler *client)
     : QDBusAbstractAdaptor(client),
       mBus(bus),
-      mClient(client)
+      mClient(client),
+      mProcessingHandleChannels(false)
 {
 }
 
@@ -63,11 +68,135 @@ void ClientHandlerAdaptor::HandleChannels(const QDBusObjectPath &account,
         const QVariantMap &handlerInfo,
         const QDBusMessage &message)
 {
-    PendingClientOperation *operation = new PendingClientOperation(
-            mBus, message, this);
+    mHandleChannelsQueue.enqueue(new HandleChannelsCall(mClient, account,
+                connection, channels, requestsSatisfied,
+                userActionTime, handlerInfo, mBus, message, this));
+    processHandleChannelsQueue();
+}
+
+void ClientHandlerAdaptor::onHandleChannelsCallFinished()
+{
+    mHandleChannelsQueue.dequeue();
+    mProcessingHandleChannels = false;
+    processHandleChannelsQueue();
+}
+
+void ClientHandlerAdaptor::processHandleChannelsQueue()
+{
+    if (mProcessingHandleChannels) {
+        return;
+    }
+
+    mProcessingHandleChannels = true;
+    HandleChannelsCall *call = mHandleChannelsQueue.head();
+    connect(call,
+            SIGNAL(finished()),
+            SLOT(onHandleChannelsCallFinished()));
+    call->process();
+}
 
-    mClient->handleChannels(operation, account, connection, channels,
-            requestsSatisfied, userActionTime, handlerInfo);
+ClientHandlerAdaptor::HandleChannelsCall::HandleChannelsCall(
+        AbstractClientHandler *client,
+        const QDBusObjectPath &account,
+        const QDBusObjectPath &connection,
+        const ChannelDetailsList &channels,
+        const ObjectPathList &requestsSatisfied,
+        qulonglong userActionTime,
+        const QVariantMap &handlerInfo,
+        const QDBusConnection &bus,
+        const QDBusMessage &message,
+        QObject *parent)
+    : QObject(parent),
+      mClient(client),
+      mAccountPath(account),
+      mConnectionPath(connection),
+      mChannelDetailsList(channels),
+      mRequestsSatisfied(requestsSatisfied),
+      mUserActionTime(userActionTime),
+      mHandlerInfo(handlerInfo),
+      mBus(bus),
+      mMessage(message),
+      mOperation(new PendingClientOperation(bus, message, this))
+{
+}
+
+ClientHandlerAdaptor::HandleChannelsCall::~HandleChannelsCall()
+{
+}
+
+void ClientHandlerAdaptor::HandleChannelsCall::process()
+{
+    mAccount = Account::create(mBus,
+            TELEPATHY_ACCOUNT_MANAGER_BUS_NAME,
+            mAccountPath.path());
+    connect(mAccount->becomeReady(),
+            SIGNAL(finished(Tp::PendingOperation *)),
+            SLOT(onObjectReady(Tp::PendingOperation *)));
+
+    QString connectionBusName = mConnectionPath.path().mid(1).replace('/', '.');
+    mConnection = Connection::create(mBus, connectionBusName,
+            mConnectionPath.path());
+    connect(mConnection->becomeReady(),
+            SIGNAL(finished(Tp::PendingOperation *)),
+            SLOT(onConnectionReady(Tp::PendingOperation *)));
+}
+
+void ClientHandlerAdaptor::HandleChannelsCall::onObjectReady(
+        PendingOperation *op)
+{
+    if (op->isError()) {
+        setFinishedWithError(op->errorName(), op->errorMessage());
+        return;
+    }
+    checkFinished();
+}
+
+void ClientHandlerAdaptor::HandleChannelsCall::onConnectionReady(
+        PendingOperation *op)
+{
+    if (op->isError()) {
+        setFinishedWithError(op->errorName(), op->errorMessage());
+        return;
+    }
+
+    ChannelPtr channel;
+    foreach (const ChannelDetails &channelDetails, mChannelDetailsList) {
+        channel = Channel::create(mConnection, channelDetails.channel.path(),
+                channelDetails.properties);
+        connect(channel->becomeReady(),
+                SIGNAL(finished(Tp::PendingOperation *)),
+                SLOT(onObjectReady(Tp::PendingOperation *)));
+        mChannels.append(channel);
+    }
+
+    // just to make sure
+    checkFinished();
+}
+
+void ClientHandlerAdaptor::HandleChannelsCall::checkFinished()
+{
+    if (!mAccount->isReady() || !mConnection->isReady()) {
+        return;
+    }
+
+    foreach (const ChannelPtr &channel, mChannels) {
+        if (!channel->isReady()) {
+            return;
+        }
+    }
+
+    // now we are ready to call AbstractClientHandler::handleChannels
+    mClient->handleChannels(mOperation, mAccount, mConnection, mChannels,
+            mRequestsSatisfied, mUserActionTime, mHandlerInfo);
+    emit finished();
+}
+
+void ClientHandlerAdaptor::HandleChannelsCall::setFinishedWithError(const QString &errorName,
+        const QString &errorMessage)
+{
+    mOperation->setFinishedWithError(errorName, errorMessage);
+    emit finished();
+    deleteLater();
 }
 
 ClientHandlerRequestsAdaptor::ClientHandlerRequestsAdaptor(
-- 
1.5.6.5




More information about the telepathy-commits mailing list