diff options
author | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2010-12-15 21:57:24 -0200 |
---|---|---|
committer | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2010-12-17 10:57:24 -0200 |
commit | 714552024f7f77407fc5d1c0b14a8a18f6578f49 (patch) | |
tree | 3c87677d4e23ddd0688ff5905292188aadf41a8e /TelepathyQt4 | |
parent | dfa8224ba9df935e9560d09d6407e105f85a2b9e (diff) |
Connection/ContactManager/Contact: Added support for Conn.Iface.ContactGroups.
Diffstat (limited to 'TelepathyQt4')
-rw-r--r-- | TelepathyQt4/connection.cpp | 101 | ||||
-rw-r--r-- | TelepathyQt4/connection.h | 2 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.cpp | 275 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.h | 9 | ||||
-rw-r--r-- | TelepathyQt4/contact.cpp | 5 | ||||
-rw-r--r-- | TelepathyQt4/contact.h | 3 |
6 files changed, 318 insertions, 77 deletions
diff --git a/TelepathyQt4/connection.cpp b/TelepathyQt4/connection.cpp index 389c92ff..5c343607 100644 --- a/TelepathyQt4/connection.cpp +++ b/TelepathyQt4/connection.cpp @@ -554,28 +554,59 @@ void Connection::Private::introspectContactListContacts() void Connection::Private::introspectRosterGroups(Connection::Private *self) { - debug() << "Introspecting roster groups"; + if (self->parent->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_LIST)) { + if (!self->parent->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS)) { + self->readinessHelper->setIntrospectCompleted(FeatureRosterGroups, false, + TP_QT4_ERROR_NOT_IMPLEMENTED, QLatin1String("Roster groups not supported")); + return; + } - ++self->featureRosterGroupsTodo; // decremented in gotChannels + debug() << "Introspecting contact list groups"; - // we already checked if requests interface exists, so bypass requests - // interface checking - Client::ConnectionInterfaceRequestsInterface *iface = - self->parent->interface<Client::ConnectionInterfaceRequestsInterface>(); + Client::ConnectionInterfaceContactGroupsInterface *iface = + self->parent->interface<Client::ConnectionInterfaceContactGroupsInterface>(); - debug() << "Connecting to Requests.NewChannels"; - self->parent->connect(iface, - SIGNAL(NewChannels(Tp::ChannelDetailsList)), - SLOT(onNewChannels(Tp::ChannelDetailsList))); + self->contactManager->connect(iface, + SIGNAL(GroupsChanged(Tp::UIntList,QStringList,QStringList)), + SLOT(onContactListGroupsChanged(Tp::UIntList,QStringList,QStringList))); + self->contactManager->connect(iface, + SIGNAL(GroupsCreated(QStringList)), + SLOT(onContactListGroupsCreated(QStringList))); + self->contactManager->connect(iface, + SIGNAL(GroupRenamed(QString,QString)), + SLOT(onContactListGroupRenamed(QString,QString))); + self->contactManager->connect(iface, + SIGNAL(GroupsRemoved(QStringList)), + SLOT(onContactListGroupsRemoved(QStringList))); - debug() << "Retrieving channels"; - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher( - self->properties->Get( - QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS), - QLatin1String("Channels")), self->parent); - self->parent->connect(watcher, - SIGNAL(finished(QDBusPendingCallWatcher*)), - SLOT(gotChannels(QDBusPendingCallWatcher*))); + PendingVariantMap *pvm = iface->requestAllProperties(); + self->parent->connect(pvm, + SIGNAL(finished(Tp::PendingOperation*)), + SLOT(gotContactListGroupsProperties(Tp::PendingOperation*))); + } else { + debug() << "Introspecting contact list group channels"; + + ++self->featureRosterGroupsTodo; // decremented in gotChannels + + // we already checked if requests interface exists, so bypass requests + // interface checking + Client::ConnectionInterfaceRequestsInterface *iface = + self->parent->interface<Client::ConnectionInterfaceRequestsInterface>(); + + debug() << "Connecting to Requests.NewChannels"; + self->parent->connect(iface, + SIGNAL(NewChannels(Tp::ChannelDetailsList)), + SLOT(onNewChannels(Tp::ChannelDetailsList))); + + debug() << "Retrieving channels"; + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher( + self->properties->Get( + QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS), + QLatin1String("Channels")), self->parent); + self->parent->connect(watcher, + SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(gotChannels(QDBusPendingCallWatcher*))); + } } void Connection::Private::introspectBalance(Connection::Private *self) @@ -1732,6 +1763,40 @@ void Connection::gotContactListContacts(QDBusPendingCallWatcher *watcher) } } +void Connection::gotContactListGroupsProperties(PendingOperation *op) +{ + if (op->isError()) { + mPriv->readinessHelper->setIntrospectCompleted(FeatureRosterGroups, false, + op->errorName(), op->errorMessage()); + return; + } + + debug() << "Got contact list groups properties"; + PendingVariantMap *pvm = qobject_cast<PendingVariantMap*>(op); + + QVariantMap props = pvm->result(); + mPriv->contactManager->setContactListGroupsProperties(props); + + PendingContacts *pc = mPriv->contactManager->upgradeContacts( + mPriv->contactManager->allKnownContacts().toList(), + Contact::FeatureRosterGroups); + connect(pc, + SIGNAL(finished(Tp::PendingOperation*)), + SLOT(onContactListContactsUpgraded(Tp::PendingOperation*))); +} + +void Connection::onContactListContactsUpgraded(PendingOperation *op) +{ + if (op->isError()) { + mPriv->readinessHelper->setIntrospectCompleted(FeatureRosterGroups, false, + op->errorName(), op->errorMessage()); + return; + } + + debug() << "Contact list groups ready"; + mPriv->readinessHelper->setIntrospectCompleted(FeatureRosterGroups, true); +} + void Connection::onContactListStateChanged(uint state) { if (mPriv->contactListState == state) { diff --git a/TelepathyQt4/connection.h b/TelepathyQt4/connection.h index 10e99421..075feb52 100644 --- a/TelepathyQt4/connection.h +++ b/TelepathyQt4/connection.h @@ -198,6 +198,8 @@ private Q_SLOTS: void gotSelfContact(Tp::PendingOperation *op); void gotContactListProperties(Tp::PendingOperation *op); void gotContactListContacts(QDBusPendingCallWatcher *watcher); + void gotContactListGroupsProperties(Tp::PendingOperation *op); + void onContactListContactsUpgraded(Tp::PendingOperation *op); void onContactListStateChanged(uint state); void onContactListContactsChanged(const Tp::ContactSubscriptionMap &changes, const Tp::UIntList &removals); diff --git a/TelepathyQt4/contact-manager.cpp b/TelepathyQt4/contact-manager.cpp index 710e6e3a..c8d17bd7 100644 --- a/TelepathyQt4/contact-manager.cpp +++ b/TelepathyQt4/contact-manager.cpp @@ -59,7 +59,9 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private void ensureTracking(const Feature &feature); // roster specific methods + void processContactListChanges(); void processContactListUpdates(); + void processContactListGroupsUpdates(); Contacts allKnownContactsFallback() const; void computeKnownContactsChangesFallback(const Contacts &added, @@ -93,6 +95,7 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private QString &avatarFileName, QString &mimeTypeFileName); struct ContactListUpdateInfo; + struct ContactListGroupsUpdateInfo; ContactManager *parent; QWeakPointer<Connection> connection; @@ -109,8 +112,11 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private // new roster API bool canChangeContactList; bool contactListRequestUsesMessage; + QSet<QString> allKnownGroups; + QQueue<void (Private::*)()> contactListChangesQueue; QQueue<ContactListUpdateInfo> contactListUpdatesQueue; - bool processingContactListUpdates; + QQueue<ContactListGroupsUpdateInfo> contactListGroupsUpdatesQueue; + bool processingContactListChanges; // old roster API QMap<uint, ContactListChannel> contactListChannels; @@ -137,13 +143,28 @@ struct ContactManager::Private::ContactListUpdateInfo UIntList removals; }; +struct ContactManager::Private::ContactListGroupsUpdateInfo +{ + ContactListGroupsUpdateInfo(const UIntList &contacts, + const QStringList &groupsAdded, const QStringList &groupsRemoved) + : contacts(contacts), + groupsAdded(groupsAdded), + groupsRemoved(groupsRemoved) + { + } + + UIntList contacts; + QStringList groupsAdded; + QStringList groupsRemoved; +}; + ContactManager::Private::Private(ContactManager *parent, Connection *connection) : parent(parent), connection(connection), fallbackContactList(false), canChangeContactList(false), contactListRequestUsesMessage(false), - processingContactListUpdates(false), + processingContactListChanges(false), requestAvatarsIdle(false) { } @@ -212,6 +233,9 @@ void ContactManager::Private::ensureTracking(const Feature &feature) simplePresenceInterface, SIGNAL(PresencesChanged(Tp::SimpleContactPresences)), SLOT(onPresencesChanged(Tp::SimpleContactPresences))); + } else if (feature == Contact::FeatureRosterGroups) { + // nothing to do here, but we don't want to warn + ; } else { warning() << " Unknown feature" << feature << "when trying to figure out how to connect change notification!"; @@ -220,14 +244,19 @@ void ContactManager::Private::ensureTracking(const Feature &feature) tracking[feature] = true; } -void ContactManager::Private::processContactListUpdates() + +void ContactManager::Private::processContactListChanges() { - if (processingContactListUpdates || contactListUpdatesQueue.isEmpty()) { + if (processingContactListChanges || contactListChangesQueue.isEmpty()) { return; } - processingContactListUpdates = true; + processingContactListChanges = true; + (this->*(contactListChangesQueue.dequeue()))(); +} +void ContactManager::Private::processContactListUpdates() +{ ContactListUpdateInfo info = contactListUpdatesQueue.head(); // construct Contact objects for all contacts in added to the contact list @@ -244,12 +273,58 @@ void ContactManager::Private::processContactListUpdates() } } - PendingContacts *pc = parent->contactsForHandles(added, Features()); + Features features; + if (parent->connection()->isReady(Connection::FeatureRosterGroups)) { + features << Contact::FeatureRosterGroups; + } + PendingContacts *pc = parent->contactsForHandles(added, features); parent->connect(pc, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactListNewContactsConstructed(Tp::PendingOperation*))); } +void ContactManager::Private::processContactListGroupsUpdates() +{ + ContactListGroupsUpdateInfo info = contactListGroupsUpdatesQueue.dequeue(); + + foreach (const QString &group, info.groupsAdded) { + Contacts contacts; + foreach (uint bareHandle, info.contacts) { + ContactPtr contact = parent->lookupContactByHandle(bareHandle); + if (!contact) { + warning() << "contact with handle" << bareHandle << "was added to a group but " + "never added to the contact list, ignoring"; + continue; + } + contacts << contact; + contact->setAddedToGroup(group); + } + + emit parent->groupMembersChanged(group, contacts, + Contacts(), Channel::GroupMemberChangeDetails()); + } + + foreach (const QString &group, info.groupsRemoved) { + Contacts contacts; + foreach (uint bareHandle, info.contacts) { + ContactPtr contact = parent->lookupContactByHandle(bareHandle); + if (!contact) { + warning() << "contact with handle" << bareHandle << "was removed from a group but " + "never added to the contact list, ignoring"; + continue; + } + contacts << contact; + contact->setRemovedFromGroup(group); + } + + emit parent->groupMembersChanged(group, Contacts(), + contacts, Channel::GroupMemberChangeDetails()); + } + + processingContactListChanges = false; + processContactListChanges(); +} + Contacts ContactManager::Private::allKnownContactsFallback() const { Contacts contacts; @@ -558,34 +633,6 @@ bool ContactManager::Private::buildAvatarFileName(QString token, bool createDir, return true; } -namespace -{ - -QString featureToInterface(const Feature &feature) -{ - if (feature == Contact::FeatureAlias) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING); - } else if (feature == Contact::FeatureAvatarToken) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_AVATARS); - } else if (feature == Contact::FeatureAvatarData) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_AVATARS); - } else if (feature == Contact::FeatureSimplePresence) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE); - } else if (feature == Contact::FeatureCapabilities) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES); - } if (feature == Contact::FeatureLocation) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_LOCATION); - } if (feature == Contact::FeatureInfo) { - return QLatin1String(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACT_INFO); - } else { - warning() << "ContactManager doesn't know which interface corresponds to feature" - << feature; - return QString(); - } -} - -} - ContactManager::ContactManager(Connection *connection) : Object(), mPriv(new Private(this, connection)) @@ -675,8 +722,7 @@ QStringList ContactManager::allKnownGroups() const return mPriv->contactListGroupChannels.keys(); } - // FIXME: implement for Conn.Iface.ContactList - return QStringList(); + return mPriv->allKnownGroups.toList(); } /** @@ -718,10 +764,16 @@ PendingOperation *ContactManager::addGroup(const QString &group) return mPriv->addGroupFallback(group); } - // FIXME: implement for Conn.Iface.ContactList - return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), - QLatin1String("Not implemented"), - connection()); + if (!connection()->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS)) { + return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), + QLatin1String("Not implemented"), + connection()); + } + + Client::ConnectionInterfaceContactGroupsInterface *iface = + connection()->interface<Client::ConnectionInterfaceContactGroupsInterface>(); + Q_ASSERT(iface); + return new PendingVoid(iface->AddToGroup(group, UIntList()), connection()); } /** @@ -757,10 +809,16 @@ PendingOperation *ContactManager::removeGroup(const QString &group) return mPriv->removeGroupFallback(group); } - // FIXME: implement for Conn.Iface.ContactList - return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), - QLatin1String("Not implemented"), - connection()); + if (!connection()->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS)) { + return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), + QLatin1String("Not implemented"), + connection()); + } + + Client::ConnectionInterfaceContactGroupsInterface *iface = + connection()->interface<Client::ConnectionInterfaceContactGroupsInterface>(); + Q_ASSERT(iface); + return new PendingVoid(iface->RemoveGroup(group), connection()); } /** @@ -789,8 +847,12 @@ Contacts ContactManager::groupContacts(const QString &group) const return channel->groupContacts(); } - // FIXME: implement for Conn.Iface.ContactList - return Contacts(); + Contacts ret; + foreach (const ContactPtr &contact, allKnownContacts()) { + if (contact->groups().contains(group)) + ret << contact; + } + return ret; } /** @@ -821,10 +883,21 @@ PendingOperation *ContactManager::addContactsToGroup(const QString &group, return mPriv->addContactsToGroupFallback(group, contacts); } - // FIXME: implement for Conn.Iface.ContactList - return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), - QLatin1String("Not implemented"), - connection()); + if (!connection()->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS)) { + return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), + QLatin1String("Not implemented"), + connection()); + } + + UIntList handles; + foreach (const ContactPtr &contact, contacts) { + handles << contact->handle()[0]; + } + + Client::ConnectionInterfaceContactGroupsInterface *iface = + connection()->interface<Client::ConnectionInterfaceContactGroupsInterface>(); + Q_ASSERT(iface); + return new PendingVoid(iface->AddToGroup(group, handles), connection()); } /** @@ -855,10 +928,21 @@ PendingOperation *ContactManager::removeContactsFromGroup(const QString &group, return mPriv->removeContactsFromGroupFallback(group, contacts); } - // FIXME: implement for Conn.Iface.ContactList - return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), - QLatin1String("Not implemented"), - connection()); + if (!connection()->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS)) { + return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), + QLatin1String("Not implemented"), + connection()); + } + + UIntList handles; + foreach (const ContactPtr &contact, contacts) { + handles << contact->handle()[0]; + } + + Client::ConnectionInterfaceContactGroupsInterface *iface = + connection()->interface<Client::ConnectionInterfaceContactGroupsInterface>(); + Q_ASSERT(iface); + return new PendingVoid(iface->RemoveFromGroup(group, handles), connection()); } /** @@ -1690,8 +1774,8 @@ void ContactManager::onContactListNewContactsConstructed(Tp::PendingOperation *o { if (op->isError()) { mPriv->contactListUpdatesQueue.dequeue(); - mPriv->processingContactListUpdates = false; - mPriv->processContactListUpdates(); + mPriv->processingContactListChanges = false; + mPriv->processContactListChanges(); return; } @@ -1751,8 +1835,48 @@ void ContactManager::onContactListNewContactsConstructed(Tp::PendingOperation *o emit allKnownContactsChanged(added, removed, Channel::GroupMemberChangeDetails()); } - mPriv->processingContactListUpdates = false; - mPriv->processContactListUpdates(); + mPriv->processingContactListChanges = false; + mPriv->processContactListChanges(); +} + +void ContactManager::onContactListGroupsChanged(const Tp::UIntList &contacts, + const QStringList &added, const QStringList &removed) +{ + Q_ASSERT(mPriv->fallbackContactList == false); + + mPriv->contactListGroupsUpdatesQueue.enqueue(Private::ContactListGroupsUpdateInfo(contacts, + added, removed)); + mPriv->contactListChangesQueue.enqueue(&Private::processContactListGroupsUpdates); + mPriv->processContactListChanges(); +} + +void ContactManager::onContactListGroupsCreated(const QStringList &names) +{ + Q_ASSERT(mPriv->fallbackContactList == false); + + foreach (const QString &name, names) { + mPriv->allKnownGroups.insert(name); + emit groupAdded(name); + } +} + +void ContactManager::onContactListGroupRenamed(const QString &oldName, const QString &newName) +{ + Q_ASSERT(mPriv->fallbackContactList == false); + + mPriv->allKnownGroups.remove(oldName); + mPriv->allKnownGroups.insert(newName); + emit groupRenamed(oldName, newName); +} + +void ContactManager::onContactListGroupsRemoved(const QStringList &names) +{ + Q_ASSERT(mPriv->fallbackContactList == false); + + foreach (const QString &name, names) { + mPriv->allKnownGroups.remove(name); + emit groupRemoved(name); + } } void ContactManager::onStoredChannelMembersChangedFallback( @@ -1976,7 +2100,15 @@ void ContactManager::updateContactListContacts(const ContactSubscriptionMap &cha Q_ASSERT(mPriv->fallbackContactList == false); mPriv->contactListUpdatesQueue.enqueue(Private::ContactListUpdateInfo(changes, removals)); - mPriv->processContactListUpdates(); + mPriv->contactListChangesQueue.enqueue(&Private::processContactListUpdates); + mPriv->processContactListChanges(); +} + +void ContactManager::setContactListGroupsProperties(const QVariantMap &props) +{ + Q_ASSERT(mPriv->fallbackContactList == false); + + mPriv->allKnownGroups = qdbus_cast<QStringList>(props[QLatin1String("Groups")]).toSet(); } void ContactManager::setContactListChannelsFallback( @@ -2082,6 +2214,31 @@ void ContactManager::addContactListGroupChannelFallback( emit groupAdded(id); } +QString ContactManager::featureToInterface(const Feature &feature) +{ + if (feature == Contact::FeatureAlias) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_ALIASING; + } else if (feature == Contact::FeatureAvatarToken) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_AVATARS; + } else if (feature == Contact::FeatureAvatarData) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_AVATARS; + } else if (feature == Contact::FeatureSimplePresence) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE; + } else if (feature == Contact::FeatureCapabilities) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES; + } else if (feature == Contact::FeatureLocation) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_LOCATION; + } else if (feature == Contact::FeatureInfo) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_INFO; + } else if (feature == Contact::FeatureRosterGroups) { + return TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS; + } else { + warning() << "ContactManager doesn't know which interface corresponds to feature" + << feature; + return QString(); + } +} + QString ContactManager::ContactListChannel::identifierForType(Type type) { static QString identifiers[LastType] = { diff --git a/TelepathyQt4/contact-manager.h b/TelepathyQt4/contact-manager.h index ffbf4601..0f0bbfec 100644 --- a/TelepathyQt4/contact-manager.h +++ b/TelepathyQt4/contact-manager.h @@ -121,6 +121,7 @@ Q_SIGNALS: const Tp::Channel::GroupMemberChangeDetails &details); void groupAdded(const QString &group); + void groupRenamed(const QString &oldGroup, const QString &newGroup); void groupRemoved(const QString &group); void groupMembersChanged(const QString &group, @@ -143,6 +144,11 @@ private Q_SLOTS: void onContactInfoChanged(uint, const Tp::ContactInfoFieldList &); void onContactListNewContactsConstructed(Tp::PendingOperation *op); + void onContactListGroupsChanged(const Tp::UIntList &contacts, + const QStringList &added, const QStringList &removed); + void onContactListGroupsCreated(const QStringList &names); + void onContactListGroupRenamed(const QString &oldName, const QString &newName); + void onContactListGroupsRemoved(const QStringList &names); void onStoredChannelMembersChangedFallback( const Tp::Contacts &groupMembersAdded, @@ -226,6 +232,7 @@ private: void setContactListContacts(const ContactAttributesMap &attrs); void updateContactListContacts(const ContactSubscriptionMap &changes, const UIntList &removals); + void setContactListGroupsProperties(const QVariantMap &props); void setContactListChannelsFallback( const QMap<uint, ContactListChannel> &contactListChannels); @@ -234,6 +241,8 @@ private: void addContactListGroupChannelFallback( const ChannelPtr &contactListGroupChannel); + static QString featureToInterface(const Feature &feature); + struct Private; friend struct Private; Private *mPriv; diff --git a/TelepathyQt4/contact.cpp b/TelepathyQt4/contact.cpp index 48dfe038..eb9c08ea 100644 --- a/TelepathyQt4/contact.cpp +++ b/TelepathyQt4/contact.cpp @@ -165,6 +165,7 @@ const Feature Contact::FeatureCapabilities = Feature(QLatin1String(Contact::stat const Feature Contact::FeatureInfo = Feature(QLatin1String(Contact::staticMetaObject.className()), 4, false); const Feature Contact::FeatureLocation = Feature(QLatin1String(Contact::staticMetaObject.className()), 5, false); const Feature Contact::FeatureSimplePresence = Feature(QLatin1String(Contact::staticMetaObject.className()), 6, false); +const Feature Contact::FeatureRosterGroups = Feature(QLatin1String(Contact::staticMetaObject.className()), 7, false); Contact::Contact(ContactManager *manager, const ReferencedHandles &handle, const Features &requestedFeatures, const QVariantMap &attributes) @@ -602,6 +603,10 @@ void Contact::augment(const Features &requestedFeatures, const QVariantMap &attr mPriv->presence.setStatus(ConnectionPresenceTypeUnknown, QLatin1String("unknown"), QLatin1String("")); } + } else if (feature == FeatureRosterGroups) { + QStringList groups = qdbus_cast<QStringList>(attributes.value( + TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS + QLatin1String("/groups"))); + mPriv->groups = groups.toSet(); } else { warning() << "Unknown feature" << feature << "encountered when augmenting Contact"; } diff --git a/TelepathyQt4/contact.h b/TelepathyQt4/contact.h index 04b8fe3a..a8d8dfe6 100644 --- a/TelepathyQt4/contact.h +++ b/TelepathyQt4/contact.h @@ -184,6 +184,8 @@ Q_SIGNALS: // want to signal that change right away with a handle? private: + static const Feature FeatureRosterGroups; + Contact(ContactManager *manager, const ReferencedHandles &handle, const Features &requestedFeatures, const QVariantMap &attributes); @@ -210,6 +212,7 @@ private: void setRemovedFromGroup(const QString &group); struct Private; + friend class Connection; friend class ContactManager; friend struct Private; Private *mPriv; |