summaryrefslogtreecommitdiff
path: root/TelepathyQt4
diff options
context:
space:
mode:
authorAndre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk>2010-12-15 21:57:24 -0200
committerAndre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk>2010-12-17 10:57:24 -0200
commit714552024f7f77407fc5d1c0b14a8a18f6578f49 (patch)
tree3c87677d4e23ddd0688ff5905292188aadf41a8e /TelepathyQt4
parentdfa8224ba9df935e9560d09d6407e105f85a2b9e (diff)
Connection/ContactManager/Contact: Added support for Conn.Iface.ContactGroups.
Diffstat (limited to 'TelepathyQt4')
-rw-r--r--TelepathyQt4/connection.cpp101
-rw-r--r--TelepathyQt4/connection.h2
-rw-r--r--TelepathyQt4/contact-manager.cpp275
-rw-r--r--TelepathyQt4/contact-manager.h9
-rw-r--r--TelepathyQt4/contact.cpp5
-rw-r--r--TelepathyQt4/contact.h3
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;