Index: include/QtTapioca/contactgroup.h =================================================================== --- ../include/QtTapioca/contactgroup.h (revision 2022) +++ ../include/QtTapioca/contactgroup.h (revision 2023) @@ -30,6 +30,7 @@ namespace QtTapioca { +class Channel; class Conatct; class Connection; class ContactGroupPrivate; @@ -63,10 +64,12 @@ QList contacts() const; QList pendingContacts() const; + Channel * channel() const; + Q_SIGNALS: - void contactEntered(Contact *contact); - void contactLeft(Contact *contact); - void newPendingContact(Contact *contact); + void contactEntered(QtTapioca::Contact *contact); + void contactLeft(QtTapioca::Contact *contact); + void newPendingContact(QtTapioca::Contact *contact); private Q_SLOTS: void onGroupFlagsChanged(uint added, uint removed); @@ -75,10 +78,12 @@ const QList &remote_pending, uint actor, uint reason); private: - ContactGroup(Connection *connection, const QString &serviceName, const QString &objPath, QObject *parent = 0); + ContactGroup(Connection *connection, const QString &serviceName, const QString &objPath, Channel *channel); QList contactsFromContactList(QList ids) const; ContactGroupPrivate *d; + + friend class Channel; }; } // namespace Index: include/QtTapioca/channel.h =================================================================== --- ../include/QtTapioca/channel.h (revision 2022) +++ ../include/QtTapioca/channel.h (revision 2023) @@ -57,9 +57,13 @@ void close(); virtual void join(); - ContactGroup *contactGroup() const; + ContactGroup * contactGroup(); bool hasGroupSupport() const; + bool hasSupportFor(const QString &) const; + + Connection * connection() const; + Q_SIGNALS: void closed(); Index: include/QtTapioca/contactlist.h =================================================================== --- ../include/QtTapioca/contactlist.h (revision 2022) +++ ../include/QtTapioca/contactlist.h (revision 2023) @@ -102,8 +102,8 @@ QObject *parent = 0); void loadContacts(); - Contact *contact(Handle *handle) const; - Contact *contact(uint id) const; + Contact *contact(Handle *handle); + Contact *contact(uint id); Contact *addContact(const Handle *handle); ContactListPrivate *d; Index: src/contactgroup.cpp =================================================================== --- ../src/contactgroup.cpp (revision 2022) +++ ../src/contactgroup.cpp (revision 2023) @@ -35,8 +35,9 @@ public: ContactGroupPrivate(Connection *connection, const QString &serviceName, - const QString &objPath) - : conn(connection) + const QString &objPath, + Channel * chan) + : conn(connection), channel(chan) { telepathyIChannelGroup = new org::freedesktop::Telepathy::ChannelGroupInterface(serviceName, objPath, QDBusConnection::sessionBus()); @@ -50,6 +51,7 @@ uint flags; Connection *conn; + Channel * channel; org::freedesktop::Telepathy::ChannelGroupInterface *telepathyIChannelGroup; }; @@ -57,19 +59,19 @@ using namespace QtTapioca; -ContactGroup::ContactGroup(Connection *connection, const QString &serviceName, const QString &objPath, QObject *parent) - : d(new ContactGroupPrivate(connection, serviceName, objPath)) +ContactGroup::ContactGroup(Connection *connection, const QString &serviceName, const QString &objPath, Channel *channel) + : d(new ContactGroupPrivate(connection, serviceName, objPath, channel)) { Q_ASSERT(d); - QObject::connect(d->telepathyIChannelGroup, SIGNAL(GroupFlagsChanged(uint added, uint removed)), this, SLOT(onGroupFlagsChanged(uint added, uint removed))); - QObject::connect(d->telepathyIChannelGroup, SIGNAL(MembersChanged(const QString &message, const QList &added, - const QList &removed, const QList &local_pending, - const QList &remote_pending, uint actor, uint reason)), + QObject::connect(d->telepathyIChannelGroup, SIGNAL(GroupFlagsChanged(uint, uint)), this, SLOT(onGroupFlagsChanged(uint, uint))); + QObject::connect(d->telepathyIChannelGroup, SIGNAL(MembersChanged(const QString&, const QList&, + const QList&, const QList &, + const QList&, uint, uint)), this, - SLOT(onMembersChanged(const QString &message, const QList &added, - const QList &removed, const QList &local_pending, - const QList &remote_pending, uint actor, uint reason))); + SLOT(onMembersChanged(const QString&, const QList&, + const QList&, const QList&, + const QList&, uint, uint))); } ContactGroup::~ContactGroup() @@ -154,6 +156,8 @@ return lc; } +Channel * ContactGroup::channel() const { return d->channel; } + QList ContactGroup::contactsFromContactList(QList ids) const { uint i; Index: src/channel.cpp =================================================================== --- ../src/channel.cpp (revision 2022) +++ ../src/channel.cpp (revision 2023) @@ -25,6 +25,7 @@ #include "QtTapioca/Channel" #include "QtTapioca/ChannelTarget" +#include "QtTapioca/ContactGroup" #include #include @@ -54,7 +55,7 @@ Connection *conn; org::freedesktop::Telepathy::Channel *ch; ChannelTarget* target; - ContactGroup *cg; + ContactGroup * cg; bool join; }; @@ -99,17 +100,35 @@ return d->target; } -ContactGroup *Channel::contactGroup() const +ContactGroup *Channel::contactGroup() { + if (!hasGroupSupport()) { return 0; } + if (0 == d->cg) + { + d->cg = new ContactGroup(d->conn, serviceName(), objectPath(), this); + Q_ASSERT(0 != d->cg); + } return d->cg; } bool Channel::hasGroupSupport() const { - return (d->cg); + return hasSupportFor("org.freedesktop.Telepathy.Channel.Interface.Group"); } +bool Channel::hasSupportFor(const QString & interface) const +{ + QStringList interfaces = d->ch->GetInterfaces(); + return interfaces.contains(interface); +} + void Channel::join() { d->join = true; } + +Connection * Channel::connection() const +{ + return d->conn; +} + Index: src/contactlist.cpp =================================================================== --- ../src/contactlist.cpp (revision 2022) +++ ../src/contactlist.cpp (revision 2023) @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -273,7 +274,7 @@ /* * Get Contact from Handle */ -Contact *ContactList::contact(Handle *handle) const +Contact *ContactList::contact(Handle *handle) { return contact(handle->id()); } @@ -294,9 +295,30 @@ /* * Get Contact from id */ -Contact *ContactList::contact(uint id) const +Contact * ContactList::contact(const uint id) { - return d->contacts.value(id); + QMutexLocker lock(&(d->mutex)); + if (d->contacts.contains(id)) + { return d->contacts.value(id); } + + // Handle connections without a contact list: + Handle * handle(d->handleFactory->createHandle(Handle::Contact, id)); + + if (0 == handle) { return 0; } + Contact * c(new Contact(d->telepathyConn, + d->telepathyIAvatar, + d->telepathyIPresence, + d->telepathyIAliasing, + d->telepathyICapabilities, + d->lists[CONTACT_LIST_TYPE_SUBSCRIBE], + d->lists[CONTACT_LIST_TYPE_PUBLISH], + d->lists[CONTACT_LIST_TYPE_HIDE], + d->lists[CONTACT_LIST_TYPE_ALLOW], + d->lists[CONTACT_LIST_TYPE_DENY], + handle, this)); + d->contacts[id] = c; + + return c; } /*