[Telepathy-commits] [telepathy-qt4/master] Add a wrapper for GetContactAttributes integrating it with the handle machinery

Olli Salli olli.salli at collabora.co.uk
Thu Jan 29 13:54:50 PST 2009


---
 TelepathyQt4/Client/PendingContactAttributes       |    6 +
 TelepathyQt4/Client/connection.cpp                 |   57 +++++++
 TelepathyQt4/Client/connection.h                   |    6 +-
 TelepathyQt4/Client/pending-contact-attributes.cpp |  161 +++++++++++++++++++
 TelepathyQt4/Client/pending-contact-attributes.h   |  162 ++++++++++++++++++++
 TelepathyQt4/Client/referenced-handles.h           |    1 +
 TelepathyQt4/Makefile.am                           |    4 +
 7 files changed, 396 insertions(+), 1 deletions(-)
 create mode 100644 TelepathyQt4/Client/PendingContactAttributes
 create mode 100644 TelepathyQt4/Client/pending-contact-attributes.cpp
 create mode 100644 TelepathyQt4/Client/pending-contact-attributes.h

diff --git a/TelepathyQt4/Client/PendingContactAttributes b/TelepathyQt4/Client/PendingContactAttributes
new file mode 100644
index 0000000..719fe21
--- /dev/null
+++ b/TelepathyQt4/Client/PendingContactAttributes
@@ -0,0 +1,6 @@
+#ifndef _TelepathyQt4_Client_PendingContactAttributes_HEADER_GUARD_
+#define _TelepathyQt4_Client_PendingContactAttributes_HEADER_GUARD_
+
+#include <TelepathyQt4/Client/pending-contact-attributes.h>
+
+#endif
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index 6a1ba3a..b0ce8f6 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -30,6 +30,7 @@
 #include "TelepathyQt4/debug-internal.h"
 
 #include <TelepathyQt4/Client/PendingChannel>
+#include <TelepathyQt4/Client/PendingContactAttributes>
 #include <TelepathyQt4/Client/PendingFailure>
 #include <TelepathyQt4/Client/PendingHandles>
 #include <TelepathyQt4/Client/PendingVoidMethodCall>
@@ -1403,6 +1404,62 @@ PendingOperation *Connection::requestDisconnect()
     return new PendingVoidMethodCall(this, baseInterface()->Disconnect());
 }
 
+/**
+ * Requests attributes for contacts. Optionally, the handles of the contacts will be referenced
+ * automatically. Essentially, this method wraps
+ * ConnectionInterfaceContactsInterface::GetContactAttributes(), integrating it with the rest of the
+ * handle-referencing machinery.
+ *
+ * Upon completion, the reply to the request can be retrieved through the returned
+ * PendingContactAttributes object. The object also provides access to the parameters with which the
+ * call was made and a signal to connect to to get notification of the request finishing processing.
+ * See the documentation for that class for more info.
+ *
+ * If the remote object doesn't support the Contacts interface (as signified by the list returned by
+ * interfaces() not containing TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS), the returned
+ * PendingContactAttributes instance will fail instantly with the error
+ * TELEPATHY_ERROR_NOT_IMPLEMENTED.
+ *
+ * \sa PendingContactAttributes
+ *
+ * \param contacts Passed to ConnectionInterfaceContactsInterface::GetContactAttributes().
+ * \param interfaces Passed to ConnectionInterfaceContactsInterface::GetContactAttributes().
+ * \param reference Whether the handles should additionally be referenced.
+ * \return Pointer to a newly constructed PendingContactAttributes, tracking the progress of the
+ *         request.
+ */
+PendingContactAttributes *Connection::getContactAttributes(const UIntList &handles,
+        const QStringList &interfaces, bool reference)
+{
+    debug() << "Request for attributes for" << handles.size() << "contacts";
+
+    if (!this->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS)) {
+        warning() << "Connection::getContactAttributes() used without the remote object supporting"
+                  << "the Contacts interface";
+        PendingContactAttributes *pending =
+            new PendingContactAttributes(this, handles, interfaces, reference);
+        pending->setUnsupported();
+        return pending;
+    }
+
+    {
+        Private::HandleContext *handleContext = mPriv->handleContext;
+        QMutexLocker locker(&handleContext->lock);
+        handleContext->types[HandleTypeContact].requestsInFlight++;
+    }
+
+    PendingContactAttributes *pending =
+        new PendingContactAttributes(this, handles, interfaces, reference);
+    ConnectionInterfaceContactsInterface *contactsInterface =
+        optionalInterface<ConnectionInterfaceContactsInterface>();
+    QDBusPendingCallWatcher *watcher =
+        new QDBusPendingCallWatcher(contactsInterface->GetContactAttributes(handles, interfaces,
+                    reference));
+    pending->connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+                              SLOT(onCallFinished(QDBusPendingCallWatcher*)));
+    return pending;
+}
+
 void Connection::refHandle(uint type, uint handle)
 {
     Private::HandleContext *handleContext = mPriv->handleContext;
diff --git a/TelepathyQt4/Client/connection.h b/TelepathyQt4/Client/connection.h
index 2e41ef0..b4d749c 100644
--- a/TelepathyQt4/Client/connection.h
+++ b/TelepathyQt4/Client/connection.h
@@ -44,8 +44,8 @@ namespace Client
 {
 
 class Channel;
-class Connection;
 class PendingChannel;
+class PendingContactAttributes;
 class PendingHandles;
 class PendingOperation;
 
@@ -159,6 +159,9 @@ public:
 
     PendingHandles *referenceHandles(uint handleType, const UIntList &handles);
 
+    PendingContactAttributes *getContactAttributes(const UIntList &contacts,
+            const QStringList &interfaces, bool reference = true);
+
     bool isReady(Features features = 0) const;
 
     PendingOperation *becomeReady(Features features = 0);
@@ -197,6 +200,7 @@ private:
     friend struct Private;
     friend class PendingChannel;
     friend class PendingConnect;
+    friend class PendingContactAttributes;
     friend class PendingHandles;
     friend class ReferencedHandles;
     Private *mPriv;
diff --git a/TelepathyQt4/Client/pending-contact-attributes.cpp b/TelepathyQt4/Client/pending-contact-attributes.cpp
new file mode 100644
index 0000000..ad08345
--- /dev/null
+++ b/TelepathyQt4/Client/pending-contact-attributes.cpp
@@ -0,0 +1,161 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "pending-contact-attributes.h"
+#include "_gen/pending-contact-attributes.moc.hpp"
+
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/ReferencedHandles>
+
+#include "../debug-internal.h"
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct PendingContactAttributes::Private
+{
+    Connection *connection;
+    UIntList contactsRequested;
+    QStringList interfacesRequested;
+    bool shouldReference;
+    ReferencedHandles validHandles;
+    UIntList invalidHandles;
+    ContactAttributesMap attributes;
+};
+
+PendingContactAttributes::PendingContactAttributes(Connection* connection, const UIntList &handles,
+        const QStringList &interfaces, bool reference)
+    : PendingOperation(connection), mPriv(new Private)
+{
+    debug() << "PendingContactAttributes()";
+
+    mPriv->connection = connection;
+    mPriv->contactsRequested = handles;
+    mPriv->interfacesRequested = interfaces;
+    mPriv->shouldReference = reference;
+}
+
+PendingContactAttributes::~PendingContactAttributes()
+{
+    delete mPriv;
+}
+
+Connection* PendingContactAttributes::connection() const
+{
+    return mPriv->connection;
+}
+
+const UIntList &PendingContactAttributes::contactsRequested() const
+{
+    return mPriv->contactsRequested;
+}
+
+const QStringList &PendingContactAttributes::interfacesRequested() const
+{
+    return mPriv->interfacesRequested;
+}
+
+bool PendingContactAttributes::shouldReference() const
+{
+    return mPriv->shouldReference;
+}
+
+ReferencedHandles PendingContactAttributes::validHandles() const
+{
+    if (!isFinished()) {
+        warning() << "PendingContactAttributes::validHandles() called before finished";
+    } else if (isError()) {
+        warning() << "PendingContactAttributes::validHandles() called when errored";
+    } else if (!shouldReference()) {
+        warning() << "PendingContactAttributes::validHandles() called but weren't asked to"
+                  << "reference handles";
+    }
+
+    return mPriv->validHandles;
+}
+
+UIntList PendingContactAttributes::invalidHandles() const
+{
+    if (!isFinished()) {
+        warning() << "PendingContactAttributes::validHandles() called before finished";
+    } else if (isError()) {
+        warning() << "PendingContactAttributes::validHandles() called when errored";
+    }
+
+    return mPriv->invalidHandles;
+}
+
+ContactAttributesMap PendingContactAttributes::attributes() const
+{
+    if (!isFinished()) {
+        warning() << "PendingContactAttributes::validHandles() called before finished";
+    } else if (isError()) {
+        warning() << "PendingContactAttributes::validHandles() called when errored";
+    }
+
+    return mPriv->attributes;
+}
+
+void PendingContactAttributes::onCallFinished(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<ContactAttributesMap> reply = *watcher;
+
+    debug() << "Received reply to GetContactAttributes";
+
+    if (reply.isError()) {
+        debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
+        setFinishedWithError(reply.error());
+    } else {
+        mPriv->attributes = reply.value();
+
+        UIntList validHandles;
+        foreach (uint contact, mPriv->contactsRequested) {
+            if (mPriv->attributes.contains(contact)) {
+                validHandles << contact;
+            } else {
+                mPriv->invalidHandles << contact;
+            }
+        }
+
+        if (shouldReference()) {
+            mPriv->validHandles = ReferencedHandles(connection(), HandleTypeContact, validHandles);
+        }
+
+        debug() << " Success:" << validHandles.size() << "valid and" << mPriv->invalidHandles.size()
+            << "invalid handles";
+        
+        setFinished();
+    }
+
+    connection()->handleRequestLanded(HandleTypeContact);
+    watcher->deleteLater();
+}
+
+void PendingContactAttributes::setUnsupported()
+{
+    setFinishedWithError(TELEPATHY_ERROR_NOT_IMPLEMENTED,
+            "The remote object doesn't report the Contacts interface as supported");
+}
+
+} // Telepathy::Client
+} // Telepathy
diff --git a/TelepathyQt4/Client/pending-contact-attributes.h b/TelepathyQt4/Client/pending-contact-attributes.h
new file mode 100644
index 0000000..601c171
--- /dev/null
+++ b/TelepathyQt4/Client/pending-contact-attributes.h
@@ -0,0 +1,162 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_pending_contact_attributes_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_pending_contact_attributes_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientconn Connection proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy Connections and their optional
+ * interfaces.
+ */
+
+namespace Telepathy
+{
+namespace Client
+{
+class PendingContactAttributes;
+}
+}
+
+#include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Client/PendingOperation>
+
+namespace Telepathy
+{
+namespace Client
+{
+class Connection;
+class ReferencedHandles;
+
+/**
+ * \class PendingContactAttributes
+ * \ingroup clientconn
+ * \headerfile <TelepathyQt4/cli-pending-contact-attributes.h> <TelepathyQt4/Client/PendingContactAttributes>
+ *
+ * Class containing the parameters of and the reply to an asynchronous request for raw contact
+ * attributes, as used in the Connection::getContactAttributes() low-level convenience method
+ * wrapping the ConnectionInterfaceContactsInterface::GetContactAttributes() D-Bus method.
+ */
+class PendingContactAttributes : public PendingOperation
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Class destructor.
+     */
+    ~PendingContactAttributes();
+
+    /**
+     * Returns the Connection object through which the request was made.
+     *
+     * \return Pointer to the Connection.
+     */
+    Connection *connection() const;
+
+    /**
+     * Returns the contacts for which attributes were requested.
+     *
+     * \return Reference to a list with the handles of the contacts.
+     */
+    const UIntList &contactsRequested() const;
+
+    /**
+     * Returns the interfaces the corresponding attributes of which were requested.
+     *
+     * \return Reference to a list of D-Bus interface names.
+     */
+    const QStringList &interfacesRequested() const;
+
+    /**
+     * Returns whether it was requested that the contact handles should be referenced in addition to
+     * fetching their attributes. This corresponds to the <code>reference</code> argument to
+     * Connection::getContactAttributes().
+     *
+     * \return Whether the handles should be referenced or not.
+     */
+    bool shouldReference() const;
+
+    /**
+     * If referencing the handles was requested (as indicated by shouldReference()), returns the
+     * now-referenced handles resulting from the operation. If the operation has not (yet) finished
+     * successfully (isFinished() returns <code>false</code>), or referencing was not requested, the
+     * return value is undefined.
+     *
+     * Even if referencing was requested, the list will not always contain all of the handles in
+     * contactsRequested(), only the ones which were valid. The valid handles will be in the same
+     * order as in contactsRequested(), though.
+     *
+     * \return ReferencedHandles instance containing the handles.
+     */
+    ReferencedHandles validHandles() const;
+
+    /**
+     * Returns the handles which were found to be invalid while processing the operation. If the
+     * operation has not (yet) finished successfully (isFinished() returns <code>false</code>), the
+     * return value is undefined.
+     *
+     * \return A list with the invalid handles.
+     */
+    UIntList invalidHandles() const;
+
+    /**
+     * Returns a dictionary mapping the valid contact handles in contactsRequested() (the contents
+     * of handles()) to contact attributes. If the operation has not (yet) finished successfully
+     * (isFinished() returns <code>false</code>), the return value is undefined.
+     *
+     * \return Mapping from handles to variant maps containing the attributes.
+     */
+    ContactAttributesMap attributes() const;
+
+private Q_SLOTS:
+    void onCallFinished(QDBusPendingCallWatcher *watcher);
+
+private:
+    friend class Connection;
+
+    PendingContactAttributes(Connection *connection, const UIntList &handles,
+            const QStringList &interfaces, bool reference);
+    void setUnsupported();
+
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+} // Telepathy::Client
+} // Telepathy
+
+#endif
diff --git a/TelepathyQt4/Client/referenced-handles.h b/TelepathyQt4/Client/referenced-handles.h
index 31350df..8242b16 100644
--- a/TelepathyQt4/Client/referenced-handles.h
+++ b/TelepathyQt4/Client/referenced-handles.h
@@ -283,6 +283,7 @@ class ReferencedHandles
 
     private:
         // For access to the "prime" constructor
+        friend class PendingContactAttributes;
         friend class PendingHandles;
 
         ReferencedHandles(Connection* connection, uint handleType, const UIntList& handles);
diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index 85a4ed9..a46840b 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -51,6 +51,7 @@ libtelepathy_qt4_la_SOURCES = \
     Client/pending-account.cpp \
     Client/pending-channel.cpp \
     Client/pending-connection.cpp \
+    Client/pending-contact-attributes.cpp \
     Client/pending-handles.cpp \
     Client/pending-operation.cpp \
     Client/pending-string-list.cpp \
@@ -95,6 +96,7 @@ nodist_libtelepathy_qt4_la_SOURCES = \
     Client/_gen/pending-account.moc.hpp \
     Client/_gen/pending-connection.moc.hpp \
     Client/_gen/pending-channel.moc.hpp \
+    Client/_gen/pending-contact-attributes.moc.hpp \
     Client/_gen/pending-handles.moc.hpp \
     Client/_gen/pending-operation.moc.hpp \
     Client/_gen/pending-string-list.moc.hpp \
@@ -127,6 +129,7 @@ tpqt4clientinclude_HEADERS = \
     Client/PendingAccount \
     Client/PendingChannel \
     Client/PendingConnection \
+    Client/PendingContactAttributes \
     Client/PendingFailure \
     Client/PendingOperation \
     Client/PendingSuccess \
@@ -182,6 +185,7 @@ tpqt4clientinclude_HEADERS = \
     Client/pending-account.h \
     Client/pending-channel.h \
     Client/pending-connection.h \
+    Client/pending-contact-attributes.h \
     Client/pending-handles.h \
     Client/pending-operation.h \
     Client/pending-string-list.h \
-- 
1.5.6.5




More information about the telepathy-commits mailing list