diff --git a/apps/telepathy/Connection.cxx b/apps/telepathy/Connection.cxx index 43b57f4d3f..efcdc53d77 100644 --- a/apps/telepathy/Connection.cxx +++ b/apps/telepathy/Connection.cxx @@ -36,6 +36,8 @@ using namespace std; #define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON +static const QString c_fileWithContacts = QLatin1String("data.txt"); + tr::Connection::Connection(const QDBusConnection &dbusConnection, const QString &cmName, const QString &protocolName, const QVariantMap ¶meters) : Tp::BaseConnection(dbusConnection, cmName, protocolName, parameters), mUAProfile(new TelepathyMasterProfile(parameters)), @@ -80,7 +82,7 @@ tr::Connection::Connection(const QDBusConnection &dbusConnection, const QString << TP_QT_IFACE_CONNECTION << TP_QT_IFACE_CONNECTION_INTERFACE_CONTACT_LIST << TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE - //<< TP_QT_IFACE_CONNECTION_INTERFACE_ALIASING + << TP_QT_IFACE_CONNECTION_INTERFACE_ALIASING << TP_QT_IFACE_CONNECTION_INTERFACE_REQUESTS //<< TP_QT_IFACE_CONNECTION_INTERFACE_AVATARS ); @@ -92,19 +94,25 @@ tr::Connection::Connection(const QDBusConnection &dbusConnection, const QString mSimplePresenceInterface->setSetPresenceCallback(Tp::memFun(this, &Connection::setPresence)); plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(mSimplePresenceInterface)); - /* Connection.Interface.ContactList */ - mContactListInterface = Tp::BaseConnectionContactListInterface::create(); - mContactListInterface->setContactListPersists(true); - mContactListInterface->setCanChangeContactList(true); - mContactListInterface->setDownloadAtConnection(true); - //mContactListInterface->setGetContactListAttributesCallback(Tp::memFun(this, &Connection::getContactListAttributes)); - //mContactListInterface->setRequestSubscriptionCallback(Tp::memFun(this, &Connection::requestSubscription)); - //mContactListInterface->setAuthorizePublicationCallback(Tp::memFun(this, &Connection::authorizePublication)); - //mContactListInterface->setRemoveContactsCallback(Tp::memFun(this, &Connection::removeContacts)); - //mContactListInterface->setUnsubscribeCallback(Tp::memFun(this, &Connection::unsubscribe)); - //mContactListInterface->setUnpublishCallback(Tp::memFun(this, &Connection::unpublish)); - plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(mContactListInterface)); - + /* Connection.Interface.ContactList */ + mContactListInterface = Tp::BaseConnectionContactListInterface::create(); + mContactListInterface->setContactListPersists(true); + mContactListInterface->setCanChangeContactList(true); + mContactListInterface->setDownloadAtConnection(true); + mContactListInterface->setGetContactListAttributesCallback(Tp::memFun(this, &Connection::getContactListAttributes)); + mContactListInterface->setRequestSubscriptionCallback(Tp::memFun(this, &Connection::requestSubscription)); + // mContactListInterface->setAuthorizePublicationCallback(Tp::memFun(this, &Connection::authorizePublication)); + mContactListInterface->setRemoveContactsCallback(Tp::memFun(this, &Connection::removeContacts)); + //mContactListInterface->setUnsubscribeCallback(Tp::memFun(this, &Connection::unsubscribe)); + //mContactListInterface->setUnpublishCallback(Tp::memFun(this, &Connection::unpublish)); + plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(mContactListInterface)); + + /* Connection.Interface.Aliasing */ + mAliasingInterface = Tp::BaseConnectionAliasingInterface::create(); + mAliasingInterface->setGetAliasesCallback(Tp::memFun(this, &Connection::getAliases)); + mAliasingInterface->setSetAliasesCallback(Tp::memFun(this, &Connection::setAliases)); + plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(mAliasingInterface)); + /* Connection.Interface.Requests */ mRequestsInterface = Tp::BaseConnectionRequestsInterface::create(this); /* Fill requestableChannelClasses */ @@ -143,6 +151,165 @@ tr::Connection::Connection(const QDBusConnection &dbusConnection, const QString setRequestHandlesCallback(Tp::memFun(this, &Connection::requestHandles)); connect(this, SIGNAL(disconnected()), SLOT(doDisconnect())); } + +void +tr::Connection::getContactsFromFile(Tp::DBusError *error) +{ + if (error->isValid()) { + return; + } + + QFile file(c_fileWithContacts); + + if(file.open(QFile::ReadOnly)){ + QTextStream in(&file); + QString line = in.readLine(); + Tp::AliasMap aliases; + while(!line.isNull()){ + uint handle = ensureHandle(line.split(" ").at(0)); + aliases[handle] = line.split(" ").at(1); + line = in.readLine(); + } + setAliases(aliases, error); + } else{ + file.open(QFile::WriteOnly); + } + + mContactListInterface->setContactListState(Tp::ContactListStateSuccess); +} + +void +tr::Connection::setContactsInFile() +{ + QFile file(c_fileWithContacts); + + if(file.open(QIODevice::ReadWrite | QIODevice::Truncate)){ + QTextStream stream(&file); + QMap::iterator it; + for(it = mHandles.begin(); it != mHandles.end(); it++){ + if(it.key() == selfHandle()) continue; + + stream << it.value() << " " << mAliases[it.key()] << endl; + } + file.close(); + } else{ + ErrLog(<<"couldn't write contacts to file" << endl); + } +} + +Tp::AliasMap +tr::Connection::getAliases(const Tp::UIntList& handles, Tp::DBusError *error) +{ + if (error->isValid()) { + return Tp::AliasMap(); + } + + qDebug() << Q_FUNC_INFO << handles; + + Tp::AliasMap aliases; + Q_FOREACH(uint handle, handles) { + if (mAliases.find(handle) == mAliases.end()) { + error->set(TP_QT_ERROR_INVALID_HANDLE, QLatin1String("Invalid handle(s)")); + } + aliases[handle] = mAliases[handle]; + } + + return aliases; +} + +void +tr::Connection::setAliases(const Tp::AliasMap &aliases, Tp::DBusError *error) +{ + if (error->isValid()) { + return; + } + + qDebug() << Q_FUNC_INFO << aliases; + + for(Tp::AliasMap::const_iterator it = aliases.begin(); it != aliases.end(); it++){ + mAliases[it.key()] = it.value(); + } + +} + +void +tr::Connection::deleteContacts(const QStringList& contacts) +{ + + Tp::ContactSubscriptionMap changes; + Tp::HandleIdentifierMap identifiers; + Tp::HandleIdentifierMap removals; + Q_FOREACH(const QString &contact, contacts) { + uint id = mIdentifiers[contact]; + removals[id] = contact; + } + mContactListInterface->contactsChangedWithID(changes, identifiers, removals); + + setContactsInFile(); +} + + +Tp::ContactAttributesMap +tr::Connection::getContactListAttributes(const QStringList &interfaces, bool hold, Tp::DBusError *error) +{ + Tp::UIntList handles = mHandles.keys(); + handles.removeOne(selfHandle()); + + StackLog(<<"getContactListAttributes()"); + qDebug() << handles; + + return getContactAttributes(handles, interfaces, error); +} + +void +tr::Connection::requestSubscription(const Tp::UIntList &handles, const QString &message, Tp::DBusError *error) +{ + + QStringList contacts = inspectHandles(Tp::HandleTypeContact, handles, error); + + if (error->isValid()) { + return; + } + + if (contacts.isEmpty()) { + error->set(TP_QT_ERROR_INVALID_HANDLE, QLatin1String("Invalid handle(s)")); + } + + Tp::ContactSubscriptionMap changes; + Tp::HandleIdentifierMap identifiers; + Tp::HandleIdentifierMap removals; + Q_FOREACH(const QString &contact, contacts) { + uint handle = ensureHandle(contact); + + Tp::ContactSubscriptions change; + change.publish = Tp::SubscriptionStateYes; + change.publishRequest = QString(); + change.subscribe = Tp::SubscriptionStateUnknown; + + changes[handle] = change; + identifiers[handle] = contact; + } + mContactListInterface->contactsChangedWithID(changes, identifiers, removals); + + setContactsInFile(); +} + +void +tr::Connection::removeContacts(const Tp::UIntList &handles, Tp::DBusError *error) +{ + QStringList contacts = inspectHandles(Tp::HandleTypeContact, handles, error); + + if (error->isValid()) { + return; + } + + if (contacts.isEmpty()) { + error->set(TP_QT_ERROR_INVALID_HANDLE, QLatin1String("Invalid handle(s)")); + } + + deleteContacts(contacts); +} + void tr::Connection::doConnect(Tp::DBusError *error) @@ -153,8 +320,11 @@ tr::Connection::doConnect(Tp::DBusError *error) ua->startup(); myConversationManager->startup(); ua->run(); - + statusMap = getSimpleStatusSpecMap(); + mContactListInterface->setContactListState(Tp::ContactListStateWaiting); + + getContactsFromFile(error); } void @@ -163,19 +333,103 @@ tr::Connection::onConnected() setStatus(Tp::ConnectionStatusConnected, Tp::ConnectionStatusReasonRequested); Tp::SimpleContactPresences presences; - mSelfPresence.type = Tp::ConnectionPresenceTypeAvailable; - mSelfPresence.status = QLatin1String("available"); + Tp::DBusError error; + setPresence(QLatin1String("available"), QLatin1String(""), &error); + presences[selfHandle()] = mSelfPresence; + // TODO: get presence from contacts mSimplePresenceInterface->setPresences(presences); } + +// got this method from https://github.com/TelepathyQt/telepathy-morse/blob/master/connection.cpp +Tp::SimpleStatusSpecMap +tr::Connection::getSimpleStatusSpecMap() +{ + + Tp::SimpleStatusSpec spAvailable; + spAvailable.type = Tp::ConnectionPresenceTypeAvailable; + spAvailable.maySetOnSelf = true; + spAvailable.canHaveMessage = true; + + Tp::SimpleStatusSpec spBusy; + spBusy.type = Tp::ConnectionPresenceTypeBusy; + spBusy.maySetOnSelf = true; + spBusy.canHaveMessage = true; + + Tp::SimpleStatusSpec spAway; + spAway.type = Tp::ConnectionPresenceTypeAway; + spAway.maySetOnSelf = true; + spAway.canHaveMessage = true; + + Tp::SimpleStatusSpec spOffline; + spOffline.type = Tp::ConnectionPresenceTypeOffline; + spOffline.maySetOnSelf = true; + spOffline.canHaveMessage = true; + + + Tp::SimpleStatusSpec spHidden; + spHidden.type = Tp::ConnectionPresenceTypeHidden; + spHidden.maySetOnSelf = true; + spHidden.canHaveMessage = true; + + Tp::SimpleStatusSpec spUnknown; + spUnknown.type = Tp::ConnectionPresenceTypeUnknown; + spUnknown.maySetOnSelf = false; + spUnknown.canHaveMessage = true; + + Tp::SimpleStatusSpecMap specs; + specs.insert(QLatin1String("available"), spAvailable); + specs.insert(QLatin1String("dnd"), spBusy); + specs.insert(QLatin1String("away"), spAway); + specs.insert(QLatin1String("offline"), spOffline); + specs.insert(QLatin1String("hidden"), spHidden); + specs.insert(QLatin1String("unknown"), spUnknown); + return specs; +} + uint tr::Connection::setPresence(const QString &status, const QString &message, Tp::DBusError *error) { - //FIXME + // TODO: find out why message is always getting here empty + + StackLog(<<"setPresence()"); + + mSelfPresence.type = statusMap[status].type; + mSelfPresence.status = status; + if (statusMap[status].canHaveMessage) { + mSelfPresence.statusMessage = message; + } + + qDebug() << "status = " << mSelfPresence.status << " type = " << mSelfPresence.type << " message = " << message; + return selfHandle(); } +Tp::SimpleContactPresences +tr::Connection::getPresences(const Tp::UIntList &handles) +{ + StackLog(<<"getPresences()"); + + Tp::SimpleContactPresences presences; + Q_FOREACH(uint handle, handles) { + presences[handle] = getPresence(handle); + } + + return presences; +} + +Tp::SimplePresence +tr::Connection::getPresence(uint handle) +{ + StackLog(<<"getPresence()"); + if (!mPresences.contains(handle)) { + return Tp::SimplePresence(); + } + qDebug() << "presence = " << mPresences.value(handle).status; + + return mPresences.value(handle); +} void tr::Connection::doDisconnect() @@ -241,7 +495,7 @@ tr::Connection::inspectHandles(uint handleType, const Tp::UIntList &handles, Tp: QStringList result; - foreach (uint handle, handles) { + Q_FOREACH(uint handle, handles) { if(!mHandles.contains(handle)) { return QStringList(); } @@ -264,8 +518,7 @@ tr::Connection::requestHandles(uint handleType, const QStringList &identifiers, } Q_FOREACH(const QString &identifier, identifiers) { - ensureHandle(identifier); - result.append(mIdentifiers[identifier]); + result.append(ensureHandle(identifier)); } return result; @@ -347,21 +600,28 @@ Tp::ContactAttributesMap tr::Connection::getContactAttributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error) { StackLog(<<"getContactAttributes"); - qDebug() << "getContactAttributes" << handles << ifaces; Tp::ContactAttributesMap attributesMap; Q_FOREACH(uint handle, handles) { QVariantMap attributes; - QStringList inspectedHandles = inspectHandles(Tp::HandleTypeContact, Tp::UIntList() << handle, error); - if (inspectedHandles.size() > 0) { - attributes[TP_QT_IFACE_CONNECTION+"/contact-id"] = inspectedHandles.at(0); + QStringList inspectedHandle = inspectHandles(Tp::HandleTypeContact, Tp::UIntList() << handle, error); + if (inspectedHandle.size() > 0) { + attributes[TP_QT_IFACE_CONNECTION+"/contact-id"] = inspectedHandle.at(0); } else { continue; } + qDebug() << "handle = " << handle << " inspectedHandle = " << inspectedHandle; + if (ifaces.contains(TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE)) { - attributes[TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE+"/presence"] = QVariant::fromValue(mSelfPresence); + attributes[TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE+"/presence"] = QVariant::fromValue(getPresence(handle)); + } + + if (ifaces.contains(TP_QT_IFACE_CONNECTION_INTERFACE_ALIASING)) { + attributes[TP_QT_IFACE_CONNECTION_INTERFACE_ALIASING + QLatin1String("/alias")] = QVariant::fromValue(mAliases[handle]); } + attributesMap[handle] = attributes; } + return attributesMap; } diff --git a/apps/telepathy/Connection.hxx b/apps/telepathy/Connection.hxx index 9de94ad197..0f4eea9057 100644 --- a/apps/telepathy/Connection.hxx +++ b/apps/telepathy/Connection.hxx @@ -44,17 +44,31 @@ class MyUserAgent; class Connection : public Tp::BaseConnection { - Q_OBJECT + Q_OBJECT public: Connection(const QDBusConnection &dbusConnection, - const QString &cmName, const QString &protocolName, - const QVariantMap ¶meters); + const QString &cmName, const QString &protocolName, + const QVariantMap ¶meters); MyConversationManager& getConversationManager() { return *myConversationManager.get(); }; + Tp::ContactAttributesMap getContactListAttributes(const QStringList &interfaces, bool hold, Tp::DBusError *error); + + void requestSubscription(const Tp::UIntList &handles, const QString &message, Tp::DBusError *error); + void removeContacts(const Tp::UIntList &handles, Tp::DBusError *error); + Tp::AliasMap getAliases(const Tp::UIntList& handles, Tp::DBusError *error); + void setAliases(const Tp::AliasMap &aliases, Tp::DBusError *error); + void getContactsFromFile(Tp::DBusError *error); + void setContactsInFile(); + void deleteContacts(const QStringList& contacts); + Tp::SimpleStatusSpecMap getSimpleStatusSpecMap(); + Tp::SimpleContactPresences getPresences(const Tp::UIntList &handles); + Tp::SimplePresence getPresence(uint handle); + + private: uint setPresence(const QString &status, const QString &message, Tp::DBusError *error); - QStringList inspectHandles(uint handleType, const Tp::UIntList &handles, Tp::DBusError *error); + QStringList inspectHandles(uint handleType, const Tp::UIntList &handles, Tp::DBusError *error); Tp::UIntList requestHandles(uint handleType, const QStringList &identifiers, Tp::DBusError *error); Tp::BaseChannelPtr createChannel(const QVariantMap &request, Tp::DBusError *error); Tp::ContactAttributesMap getContactAttributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error); @@ -76,6 +90,7 @@ private: std::auto_ptr myConversationManager; Tp::BaseConnectionContactsInterfacePtr mContactsInterface; + Tp::BaseConnectionAliasingInterfacePtr mAliasingInterface; Tp::BaseConnectionSimplePresenceInterfacePtr mSimplePresenceInterface; Tp::BaseConnectionContactListInterfacePtr mContactListInterface; Tp::BaseConnectionRequestsInterfacePtr mRequestsInterface; @@ -83,8 +98,11 @@ private: long nextHandleId; QMap mHandles; QMap mIdentifiers; - + Tp::AliasMap mAliases; + + Tp::SimpleStatusSpecMap statusMap; Tp::SimplePresence mSelfPresence; + Tp::SimpleContactPresences mPresences; }; } diff --git a/configure.ac b/configure.ac index 49b00f8320..4d6318a6a0 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ AC_SUBST(LIBTOOL_VERSION_RELEASE) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([foreign subdir-objects]) +AM_INIT_AUTOMAKE m4_pattern_forbid([^PKG_]) AC_CANONICAL_HOST