[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