[Telepathy-commits] [telepathy-qt4/master] Fixed bug 20583: Contact objects don't work without the Contacts interface.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Wed Mar 25 10:19:30 PDT 2009
---
TelepathyQt4/Client/connection.cpp | 2 +-
TelepathyQt4/Client/connection.h | 1 +
TelepathyQt4/Client/contact-manager.cpp | 45 ++++--------
TelepathyQt4/Client/pending-contacts.cpp | 110 +++++++++++++++++++++++++++++-
TelepathyQt4/Client/pending-contacts.h | 8 ++-
TelepathyQt4/Client/referenced-handles.h | 1 +
6 files changed, 133 insertions(+), 34 deletions(-)
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index efabe14..36d8a25 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -182,7 +182,7 @@ Connection::Private::Private(Connection *parent)
ReadinessHelper::Introspectable introspectableSelfContact(
QSet<uint>() << Connection::StatusConnected, // makesSenseForStatuses
Features() << FeatureCore, // dependsOnFeatures (core)
- QStringList() << TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS, // dependsOnInterfaces
+ QStringList(), // dependsOnInterfaces
(ReadinessHelper::IntrospectFunc) &Private::introspectSelfContact,
this);
introspectables[FeatureSelfContact] = introspectableSelfContact;
diff --git a/TelepathyQt4/Client/connection.h b/TelepathyQt4/Client/connection.h
index 3cd6928..8e1678d 100644
--- a/TelepathyQt4/Client/connection.h
+++ b/TelepathyQt4/Client/connection.h
@@ -212,6 +212,7 @@ private:
friend class PendingChannel;
friend class PendingConnect;
friend class PendingContactAttributes;
+ friend class PendingContacts;
friend class PendingHandles;
friend class ReferencedHandles;
Private *mPriv;
diff --git a/TelepathyQt4/Client/contact-manager.cpp b/TelepathyQt4/Client/contact-manager.cpp
index 859da76..6de1556 100644
--- a/TelepathyQt4/Client/contact-manager.cpp
+++ b/TelepathyQt4/Client/contact-manager.cpp
@@ -95,12 +95,9 @@ bool ContactManager::isSupported() const
if (!connection()->isReady()) {
warning() << "ContactManager::isSupported() used before the connection is ready!";
return false;
- } /* FIXME: readd this check when Connection is no longer a steaming pile of junk: else if (connection()->status() != Connection::StatusConnected) {
- warning() << "ContactManager::isSupported() used before the connection is connected!";
- return false;
- } */
+ }
- return connection()->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS);
+ return true;
}
namespace
@@ -135,7 +132,18 @@ QSet<Contact::Feature> ContactManager::supportedFeatures() const
<< Contact::FeatureAlias
<< Contact::FeatureAvatarToken
<< Contact::FeatureSimplePresence;
- QStringList interfaces = mPriv->conn->contactAttributeInterfaces();
+ QStringList interfaces;
+ if (mPriv->conn->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS)) {
+ interfaces = mPriv->conn->contactAttributeInterfaces();
+ } else {
+ if (mPriv->conn->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING)) {
+ interfaces.append(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING);
+ } else if (mPriv->conn->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_AVATARS)) {
+ interfaces.append(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_AVATARS);
+ } else if (mPriv->conn->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE)) {
+ interfaces.append(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE);
+ }
+ }
foreach (Contact::Feature feature, allFeatures) {
if (interfaces.contains(featureToInterface(feature))) {
@@ -550,22 +558,8 @@ PendingContacts *ContactManager::contactsForHandles(const UIntList &handles,
}
PendingContacts *contacts =
- new PendingContacts(this, handles, features, satisfyingContacts);
-
- if (!otherContacts.isEmpty()) {
- debug() << " Fetching" << interfaces.size() << "interfaces for"
- << otherContacts.size() << "contacts";
-
- PendingContactAttributes *attributes =
- mPriv->conn->getContactAttributes(otherContacts.toList(), interfaces.toList(), true);
-
- contacts->connect(attributes,
- SIGNAL(finished(Telepathy::Client::PendingOperation*)),
- SLOT(onAttributesFinished(Telepathy::Client::PendingOperation*)));
- } else {
- contacts->allAttributesFetched();
- }
-
+ new PendingContacts(this, handles, features, interfaces.toList(),
+ satisfyingContacts, otherContacts);
return contacts;
}
@@ -581,13 +575,7 @@ PendingContacts *ContactManager::contactsForIdentifiers(const QStringList &ident
debug() << "Building contacts for" << identifiers.size() << "identifiers" << "with" << features.size()
<< "features";
- PendingHandles *handles = mPriv->conn->requestHandles(HandleTypeContact, identifiers);
-
PendingContacts *contacts = new PendingContacts(this, identifiers, features);
- contacts->connect(handles,
- SIGNAL(finished(Telepathy::Client::PendingOperation*)),
- SLOT(onHandlesFinished(Telepathy::Client::PendingOperation*)));
-
return contacts;
}
@@ -979,6 +967,5 @@ uint ContactManager::ContactListChannel::typeForIdentifier(const QString &identi
return (uint) -1;
}
-
}
}
diff --git a/TelepathyQt4/Client/pending-contacts.cpp b/TelepathyQt4/Client/pending-contacts.cpp
index 43c34c8..e583191 100644
--- a/TelepathyQt4/Client/pending-contacts.cpp
+++ b/TelepathyQt4/Client/pending-contacts.cpp
@@ -22,6 +22,7 @@
#include <TelepathyQt4/Client/PendingContacts>
#include "TelepathyQt4/Client/_gen/pending-contacts.moc.hpp"
+#include <TelepathyQt4/Client/Connection>
#include <TelepathyQt4/Client/ContactManager>
#include <TelepathyQt4/Client/PendingContactAttributes>
#include <TelepathyQt4/Client/PendingHandles>
@@ -92,6 +93,8 @@ struct PendingContacts::Private
UIntList invalidHandles;
QStringList validIds;
QHash<QString, QPair<QString, QString> > invalidIds;
+
+ ReferencedHandles handlesToInspect;
};
/**
@@ -235,7 +238,7 @@ void PendingContacts::onAttributesFinished(PendingOperation *operation)
allAttributesFetched();
}
-void PendingContacts::onHandlesFinished(PendingOperation *operation)
+void PendingContacts::onRequestHandlesFinished(PendingOperation *operation)
{
PendingHandles *pendingHandles = qobject_cast<PendingHandles *>(operation);
@@ -259,6 +262,45 @@ void PendingContacts::onHandlesFinished(PendingOperation *operation)
SLOT(onNestedFinished(Telepathy::Client::PendingOperation*)));
}
+void PendingContacts::onReferenceHandlesFinished(PendingOperation *operation)
+{
+ PendingHandles *pendingHandles = qobject_cast<PendingHandles *>(operation);
+
+ debug() << "Reference Handles finished for" << this;
+
+ if (pendingHandles->isError()) {
+ debug() << " error" << operation->errorName()
+ << "message" << operation->errorMessage();
+ setFinishedWithError(operation->errorName(), operation->errorMessage());
+ return;
+ }
+
+ ReferencedHandles validHandles = pendingHandles->handles();
+ UIntList invalidHandles = pendingHandles->invalidHandles();
+ Connection *conn = mPriv->manager->connection();
+ mPriv->handlesToInspect = ReferencedHandles(conn, HandleTypeContact, UIntList());
+ foreach (uint handle, mPriv->handles) {
+ if (!mPriv->satisfyingContacts.contains(handle)) {
+ int indexInValid = validHandles.indexOf(handle);
+ if (indexInValid >= 0) {
+ ReferencedHandles referencedHandle = validHandles.mid(indexInValid, 1);
+ mPriv->handlesToInspect.append(referencedHandle);
+ } else {
+ mPriv->invalidHandles.push_back(handle);
+ }
+ }
+ }
+
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(
+ conn->baseInterface()->InspectHandles(HandleTypeContact,
+ mPriv->handlesToInspect.toList()),
+ this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onInspectHandlesFinished(QDBusPendingCallWatcher *)));
+}
+
void PendingContacts::onNestedFinished(PendingOperation *operation)
{
Q_ASSERT(operation == mPriv->nested);
@@ -277,18 +319,82 @@ void PendingContacts::onNestedFinished(PendingOperation *operation)
setFinished();
}
+void PendingContacts::onInspectHandlesFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<QStringList> reply = *watcher;
+
+ debug() << "Received reply to InspectHandles";
+
+ if (reply.isError()) {
+ debug().nospace() << " Failure: error " << reply.error().name() << ": "
+ << reply.error().message();
+ setFinishedWithError(reply.error());
+ return;
+ }
+
+ QStringList names = reply.value();
+ int i = 0;
+ Connection *conn = mPriv->manager->connection();
+ foreach (uint handle, mPriv->handlesToInspect) {
+ QVariantMap handleAttributes;
+ handleAttributes.insert(TELEPATHY_INTERFACE_CONNECTION "/contact-id", names[i++]);
+ ReferencedHandles referencedHandle(conn, HandleTypeContact,
+ UIntList() << handle);
+ mPriv->satisfyingContacts.insert(handle, manager()->ensureContact(referencedHandle,
+ features(), handleAttributes));
+ }
+
+ allAttributesFetched();
+
+ watcher->deleteLater();
+}
+
PendingContacts::PendingContacts(ContactManager *manager,
const UIntList &handles, const QSet<Contact::Feature> &features,
- const QMap<uint, ContactPtr> &satisfyingContacts)
+ const QStringList &interfaces,
+ const QMap<uint, ContactPtr> &satisfyingContacts,
+ const QSet<uint> &otherContacts)
: PendingOperation(manager),
mPriv(new Private(manager, handles, features, satisfyingContacts))
{
+ if (!otherContacts.isEmpty()) {
+ debug() << " Fetching" << interfaces.size() << "interfaces for"
+ << otherContacts.size() << "contacts";
+
+ Connection *conn = manager->connection();
+ if (conn->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS)) {
+ debug() << " Building contacts using contact attributes";
+ PendingContactAttributes *attributes =
+ conn->getContactAttributes(otherContacts.toList(),
+ interfaces, true);
+
+ connect(attributes,
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onAttributesFinished(Telepathy::Client::PendingOperation*)));
+ } else {
+ debug() << " Falling back to inspect contact handles";
+ // fallback to just create the contacts
+ PendingHandles *handles = conn->referenceHandles(HandleTypeContact,
+ otherContacts.toList());
+ connect(handles,
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onReferenceHandlesFinished(Telepathy::Client::PendingOperation*)));
+ }
+ } else {
+ allAttributesFetched();
+ }
}
PendingContacts::PendingContacts(ContactManager *manager,
const QStringList &identifiers, const QSet<Contact::Feature> &features)
: PendingOperation(manager), mPriv(new Private(manager, identifiers, features))
{
+ Connection *conn = manager->connection();
+ PendingHandles *handles = conn->requestHandles(HandleTypeContact, identifiers);
+
+ connect(handles,
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onRequestHandlesFinished(Telepathy::Client::PendingOperation*)));
}
PendingContacts::PendingContacts(ContactManager *manager,
diff --git a/TelepathyQt4/Client/pending-contacts.h b/TelepathyQt4/Client/pending-contacts.h
index 2d47f60..2fa6518 100644
--- a/TelepathyQt4/Client/pending-contacts.h
+++ b/TelepathyQt4/Client/pending-contacts.h
@@ -70,15 +70,19 @@ public:
private Q_SLOTS:
void onAttributesFinished(Telepathy::Client::PendingOperation *);
- void onHandlesFinished(Telepathy::Client::PendingOperation *);
+ void onRequestHandlesFinished(Telepathy::Client::PendingOperation *);
+ void onReferenceHandlesFinished(Telepathy::Client::PendingOperation *);
void onNestedFinished(Telepathy::Client::PendingOperation *);
+ void onInspectHandlesFinished(QDBusPendingCallWatcher *);
private:
Q_DISABLE_COPY(PendingContacts);
PendingContacts(ContactManager *manager, const UIntList &handles,
const QSet<Contact::Feature> &features,
- const QMap<uint, ContactPtr> &satisfyingContacts);
+ const QStringList &interfaces,
+ const QMap<uint, ContactPtr> &satisfyingContacts,
+ const QSet<uint> &otherContacts);
PendingContacts(ContactManager *manager, const QStringList &identifiers,
const QSet<Contact::Feature> &features);
PendingContacts(ContactManager *manager, const QList<ContactPtr> &contacts,
diff --git a/TelepathyQt4/Client/referenced-handles.h b/TelepathyQt4/Client/referenced-handles.h
index e539b0b..370ab00 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 PendingContacts;
friend class PendingHandles;
ReferencedHandles(Connection* connection, uint handleType, const UIntList& handles);
--
1.5.6.5
More information about the telepathy-commits
mailing list