[Telepathy-commits] [telepathy-qt4/master] Import library code for a prototype Qt4 Telepathy convenience library
Simon McVittie
simon.mcvittie at collabora.co.uk
Thu Nov 20 09:48:55 PST 2008
This will be merged into the main telepathy-qt4 code over time; the goal
is for the Prototype directory to end up either empty, or populated with
trivial wrapper classes.
---
TelepathyQt4/Makefile.am | 21 +-
TelepathyQt4/Prototype/Account.cpp | 274 +++++++
TelepathyQt4/Prototype/Account.h | 172 ++++
TelepathyQt4/Prototype/AccountManager.cpp | 310 ++++++++
TelepathyQt4/Prototype/AccountManager.h | 141 ++++
TelepathyQt4/Prototype/AvatarManager.cpp | 320 ++++++++
TelepathyQt4/Prototype/AvatarManager.h | 174 ++++
TelepathyQt4/Prototype/CapabilitiesManager.cpp | 321 ++++++++
TelepathyQt4/Prototype/CapabilitiesManager.h | 129 +++
TelepathyQt4/Prototype/ChatChannel.cpp | 223 ++++++
TelepathyQt4/Prototype/ChatChannel.h | 119 +++
TelepathyQt4/Prototype/Client/ChannelHandler | 6 +
TelepathyQt4/Prototype/Connection.cpp | 434 ++++++++++
TelepathyQt4/Prototype/Connection.h | 256 ++++++
TelepathyQt4/Prototype/ConnectionFacade.cpp | 265 +++++++
TelepathyQt4/Prototype/ConnectionFacade.h | 137 ++++
TelepathyQt4/Prototype/Constants | 6 +
TelepathyQt4/Prototype/Contact.cpp | 189 +++++
TelepathyQt4/Prototype/Contact.h | 247 ++++++
TelepathyQt4/Prototype/ContactManager.cpp | 965 +++++++++++++++++++++++
TelepathyQt4/Prototype/ContactManager.h | 304 +++++++
TelepathyQt4/Prototype/DBusInterface.cpp | 47 ++
TelepathyQt4/Prototype/DBusInterface.h | 51 ++
TelepathyQt4/Prototype/Makefile.am | 161 ++++
TelepathyQt4/Prototype/PresenceManager.cpp | 620 +++++++++++++++
TelepathyQt4/Prototype/PresenceManager.h | 151 ++++
TelepathyQt4/Prototype/StreamedMediaChannel.cpp | 578 ++++++++++++++
TelepathyQt4/Prototype/StreamedMediaChannel.h | 229 ++++++
TelepathyQt4/Prototype/TpQt4Prototype.pc.in | 11 +
TelepathyQt4/Prototype/Types | 6 +
TelepathyQt4/Prototype/all.xml | 9 +
TelepathyQt4/Prototype/channel-handler.xml | 9 +
TelepathyQt4/Prototype/constants.h | 27 +
TelepathyQt4/Prototype/types.cpp | 22 +
TelepathyQt4/Prototype/types.h | 27 +
configure.ac | 2 +
36 files changed, 6956 insertions(+), 7 deletions(-)
create mode 100644 TelepathyQt4/Prototype/Account.cpp
create mode 100644 TelepathyQt4/Prototype/Account.h
create mode 100644 TelepathyQt4/Prototype/AccountManager.cpp
create mode 100644 TelepathyQt4/Prototype/AccountManager.h
create mode 100644 TelepathyQt4/Prototype/AvatarManager.cpp
create mode 100644 TelepathyQt4/Prototype/AvatarManager.h
create mode 100644 TelepathyQt4/Prototype/CapabilitiesManager.cpp
create mode 100644 TelepathyQt4/Prototype/CapabilitiesManager.h
create mode 100644 TelepathyQt4/Prototype/ChatChannel.cpp
create mode 100644 TelepathyQt4/Prototype/ChatChannel.h
create mode 100644 TelepathyQt4/Prototype/Client/ChannelHandler
create mode 100644 TelepathyQt4/Prototype/Connection.cpp
create mode 100644 TelepathyQt4/Prototype/Connection.h
create mode 100644 TelepathyQt4/Prototype/ConnectionFacade.cpp
create mode 100644 TelepathyQt4/Prototype/ConnectionFacade.h
create mode 100644 TelepathyQt4/Prototype/Constants
create mode 100644 TelepathyQt4/Prototype/Contact.cpp
create mode 100644 TelepathyQt4/Prototype/Contact.h
create mode 100644 TelepathyQt4/Prototype/ContactManager.cpp
create mode 100644 TelepathyQt4/Prototype/ContactManager.h
create mode 100644 TelepathyQt4/Prototype/DBusInterface.cpp
create mode 100644 TelepathyQt4/Prototype/DBusInterface.h
create mode 100644 TelepathyQt4/Prototype/Makefile.am
create mode 100644 TelepathyQt4/Prototype/PresenceManager.cpp
create mode 100644 TelepathyQt4/Prototype/PresenceManager.h
create mode 100644 TelepathyQt4/Prototype/StreamedMediaChannel.cpp
create mode 100644 TelepathyQt4/Prototype/StreamedMediaChannel.h
create mode 100644 TelepathyQt4/Prototype/TpQt4Prototype.pc.in
create mode 100644 TelepathyQt4/Prototype/Types
create mode 100644 TelepathyQt4/Prototype/all.xml
create mode 100644 TelepathyQt4/Prototype/channel-handler.xml
create mode 100644 TelepathyQt4/Prototype/constants.h
create mode 100644 TelepathyQt4/Prototype/types.cpp
create mode 100644 TelepathyQt4/Prototype/types.h
diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index 0ac9f23..86022a0 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -1,3 +1,6 @@
+# We need to build this directory before the Prototype subdirectory
+SUBDIRS = . Prototype
+
tpqt4includedir=$(includedir)/telepathy-1.0/TelepathyQt4
tpqt4clientincludedir=$(tpqt4includedir)/Client
genincludedir=$(tpqt4includedir)/_gen
@@ -142,15 +145,17 @@ _gen/spec-stamp: $(wildcard $(top_srcdir)/spec/*.xml)
_gen/stable-stamp: $(wildcard *.xml) _gen/spec-stamp
touch $@
-_gen/stable-spec.xml: stable-interfaces.xml _gen/stable-stamp \
- ../tools/xincludator.py
+_gen/stable-spec.xml: $(srcdir)/stable-interfaces.xml _gen/stable-stamp \
+ $(top_srcdir)/tools/xincludator.py \
+ Makefile.am
$(PYTHON) $(top_srcdir)/tools/xincludator.py \
$< > $@
# Things generated from the whole spec at once
_gen/constants.h: _gen/stable-spec.xml \
- ../tools/qt4-constants-gen.py
+ $(top_srcdir)/tools/qt4-constants-gen.py \
+ Makefile.am
$(PYTHON) $(top_srcdir)/tools/qt4-constants-gen.py \
--namespace='Telepathy' \
--str-constant-prefix='TELEPATHY_' \
@@ -158,7 +163,8 @@ _gen/constants.h: _gen/stable-spec.xml \
> $@.tmp && mv $@.tmp $@
_gen/types.h _gen/types-body.hpp: _gen/stable-spec.xml \
- ../tools/qt4-types-gen.py
+ $(top_srcdir)/tools/qt4-types-gen.py \
+ Makefile.am
$(PYTHON) $(top_srcdir)/tools/qt4-types-gen.py \
--namespace='Telepathy' \
--declfile='_gen/types.h' \
@@ -169,13 +175,14 @@ _gen/types.h _gen/types-body.hpp: _gen/stable-spec.xml \
# Things generated per interface group
-_gen/spec-%.xml: %.xml ../tools/xincludator.py _gen/spec-stamp
+_gen/spec-%.xml: %.xml $(top_srcdir)/tools/xincludator.py _gen/spec-stamp
$(PYTHON) $(top_srcdir)/tools/xincludator.py \
$< > $@
_gen/cli-%.h _gen/cli-%-body.hpp: _gen/spec-%.xml \
_gen/stable-spec.xml \
- ../tools/qt4-client-gen.py
+ $(top_srcdir)/tools/qt4-client-gen.py \
+ Makefile.am
set -e; \
namespace='Telepathy::Client'; \
group= ; \
@@ -218,7 +225,7 @@ _gen/cli-%.h _gen/cli-%-body.hpp: _gen/spec-%.xml \
group='clientprops'; \
prettyinclude='Properties';; \
esac; \
- $(PYTHON) $(srcdir)/../tools/qt4-client-gen.py \
+ $(PYTHON) $(top_srcdir)/tools/qt4-client-gen.py \
--group=$$group \
--namespace=$$namespace \
--typesnamespace='Telepathy' \
diff --git a/TelepathyQt4/Prototype/Account.cpp b/TelepathyQt4/Prototype/Account.cpp
new file mode 100644
index 0000000..efa1be6
--- /dev/null
+++ b/TelepathyQt4/Prototype/Account.cpp
@@ -0,0 +1,274 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/Account.h"
+
+#include <QDebug>
+#include <QMetaProperty>
+
+#include <TelepathyQt4/Client/AccountManager>
+
+#include <TelepathyQt4/Prototype/Connection.h>
+#include <TelepathyQt4/Prototype/PresenceManager.h>
+
+#define ENABLE_SALUT_WORKAROUND_ // Salut shows incorrect object path.
+
+namespace {
+ const int g_protocolPosition = 6;
+ const int g_connectionManagerPosition = 5;
+ const char* g_offline = "offline";
+}
+
+using namespace TpPrototype;
+
+class TpPrototype::AccountPrivate
+{
+public:
+ AccountPrivate()
+ { init(); }
+
+ QString m_handle;
+ bool m_isValid;
+ Telepathy::Client::AccountInterface* m_pInterface;
+ QVariantMap m_parameters;
+ QVariantMap m_properties;
+ QString m_connectionManagerName;
+ QString m_protocolName;
+ QPointer<TpPrototype::Connection> m_pConnection;
+
+ void init()
+ {
+ m_isValid = true;
+ m_pInterface = NULL;
+ m_pConnection= NULL;
+ }
+};
+
+Account::Account( const QString& handle, QObject* parent ):
+ QObject( parent ),
+ d( new AccountPrivate )
+{
+ init( handle );
+}
+
+Account::~Account()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "D'tor Account:" << this;
+#endif
+ delete d;
+}
+
+QVariantMap Account::parameters()
+{
+ if ( d->m_parameters.isEmpty() )
+ {
+ d->m_parameters = d->m_pInterface->Parameters();
+ }
+
+ return d->m_parameters;
+}
+
+QVariantMap Account::properties()
+{
+ Q_ASSERT( d->m_pInterface );
+ if ( d->m_properties.isEmpty() )
+ {
+ for ( int i = 0; i < d->m_pInterface->metaObject()->propertyCount(); ++i )
+ {
+ const char* property_name = d->m_pInterface->metaObject()->property( i ).name();
+ if ( QString( property_name ) == "objectName" )
+ { continue; }
+ d->m_properties.insert( property_name, d->m_pInterface->property( property_name ) );
+ }
+ }
+
+ return d->m_properties;
+}
+
+void Account::setProperties( const QVariantMap& properties )
+{
+ // Update local property cache and save property to DBUS service
+ QStringList keys = properties.keys();
+ foreach( const QString& key, keys )
+ {
+ d->m_pInterface->setProperty( qPrintable( key ), properties.value( key ) );
+ d->m_properties.insert( key, properties.value( key ) );
+ }
+}
+
+bool Account::setParameters( const QVariantMap& parameters )
+{
+ if ( parameters.isEmpty() )
+ { return false; }
+
+ QDBusPendingReply<> reply = d->m_pInterface->UpdateParameters( parameters, QStringList() );
+ reply.waitForFinished();
+
+ if ( !reply.isValid() )
+ {
+ QDBusError error = reply.error();
+
+ qWarning() << "setParameters: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+ // Update local cache.
+ QStringList keys = parameters.keys();
+ foreach( const QString& key, keys )
+ {
+ d->m_parameters.insert( key, parameters.value( key ) );
+ }
+ // fall through..
+ return true;
+}
+
+TpPrototype::Connection* Account::connection( QObject *parent )
+{
+ if ( !d->m_pConnection )
+ {
+ d->m_pConnection = new Connection( this, parent ? parent : this );
+ }
+ return d->m_pConnection;
+}
+
+bool Account::remove()
+{
+ Q_ASSERT( d->m_pInterface );
+
+ emit signalAboutToRemove();
+
+ QDBusPendingReply<> remove_reply = d->m_pInterface->Remove();
+ remove_reply.waitForFinished();
+
+ if ( !remove_reply.isValid() )
+ {
+ QDBusError error = remove_reply.error();
+
+ qWarning() << "Remove: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+ // slotRemoved();
+
+ emit signalRemoved();
+
+ // Fall through
+ return true;
+}
+
+bool Account::isValid()
+{
+ return d->m_isValid;
+}
+
+QString Account::connectionManagerName()
+{
+ return d->m_connectionManagerName;
+}
+
+QString Account::protocolName()
+{
+ return d->m_protocolName;
+}
+
+QString Account::currentPresence()
+{
+ if ( !connection()->presenceManager() )
+ {
+ return g_offline;
+ }
+ return connection()->presenceManager()->currentPresence().status;
+}
+
+QString Account::handle() const
+{
+ return d->m_handle;
+}
+
+Telepathy::Client::AccountInterface* Account::interface()
+{
+ return d->m_pInterface;
+}
+
+void Account::slotPropertiesChanged( const QVariantMap& properties )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Account::slotPropertiesChanged(): " << properties;
+#endif
+ QStringList keys = properties.keys();
+ foreach( const QString& key, keys )
+ {
+ d->m_properties.insert( key, properties.value( key ) );
+ }
+}
+
+void Account::slotRemoved()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Account::slotRemoved(): sender:" << sender();
+#endif
+ d->m_isValid = false;
+}
+
+void Account::init( const QString handle )
+{
+ d->m_handle = handle;
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Handle:" << d->m_handle;
+#endif
+ d->m_pInterface = new Telepathy::Client::AccountInterface( "org.freedesktop.Telepathy.AccountManager",
+ d->m_handle,
+ this );
+
+ QStringList object_path_elements = d->m_pInterface->path().split('/');
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Object path: " << d->m_pInterface->path();
+ qDebug() << "Elements : " << object_path_elements;
+#endif
+ d->m_connectionManagerName = object_path_elements.at( g_connectionManagerPosition );
+ d->m_protocolName = object_path_elements.at( g_protocolPosition );
+
+#ifdef ENABLE_SALUT_WORKAROUND_
+ // Salut workaround..
+ // Salut has a corrupt object path that results in an invalid protocol name
+ if ( d->m_protocolName == "local_2dxmpp" )
+ { d->m_protocolName = "local_xmpp"; }
+#endif
+
+ // "-" is not allowed on as DBus object path. Thus "-" is mapped to "_".
+ // Revert the mapping to get a correct protocol name
+ d->m_protocolName.replace( '_', '-' );
+
+ connect( d->m_pInterface, SIGNAL( AccountPropertyChanged( const QVariantMap& ) ),
+ this, SLOT( slotPropertiesChanged( const QVariantMap& ) ) );
+ connect( d->m_pInterface, SIGNAL( AccountPropertyChanged( const QVariantMap& ) ),
+ this, SIGNAL( signalPropertiesChanged( const QVariantMap& ) ) );
+ connect( d->m_pInterface, SIGNAL( Removed() ),
+ this, SLOT( slotRemoved() ) );
+}
diff --git a/TelepathyQt4/Prototype/Account.h b/TelepathyQt4/Prototype/Account.h
new file mode 100644
index 0000000..6c049f4
--- /dev/null
+++ b/TelepathyQt4/Prototype/Account.h
@@ -0,0 +1,172 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_Account_H_
+#define TelepathyQt4_Prototype_Account_H_
+
+#include <QObject>
+#include <QPointer>
+#include <QVariantMap>
+
+namespace Telepathy {
+namespace Client {
+class AccountInterface;
+}
+}
+
+namespace TpPrototype {
+
+class Connection;
+class AccountPrivate;
+
+/**
+ * @ingroup qt_accountmgm
+ * This class manages an account.
+ * @todo: Account should be more like QPersistantModelIndex. Thus we don't have to use pointer of it.
+ * @todo In order to allow custom extensions, we need a support to register proxies in the AccountManager
+ */
+class Account : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * The parameters of this account.
+ * Returns a list of all parameters of this account that were explicitly set by AccountManager::createAccount().
+ * @return The properties as key,value pair.
+ */
+ QVariantMap parameters();
+
+ /**
+ * Properties of this account
+ */
+ QVariantMap properties();
+
+ /**
+ * Set Properties. Changes the given list of Properties.
+ * @param properties The list of changed or new properties.
+ */
+ void setProperties( const QVariantMap& properties );
+
+ /**
+ * Set Parameters. Changes the given list of parameters.
+ * @param parameters The list of changed or new parameters
+ * @return True if successful.
+ */
+ bool setParameters( const QVariantMap& parameters );
+
+ /**
+ * Connection.
+ * Returns a connection object that belongs to this account.<br>
+ * <b>Info:</b> This class keeps ownership of this class.
+ * @param parent The parent of this object. If NULL the connection is used as parent.
+ * @return Connection object.
+ */
+ TpPrototype::Connection* connection( QObject* parent = NULL );
+
+ /**
+ * Remove account. Removes the given account.
+ * <b>Note:</b> Although this call is synchronous, the internal book keeping of valid accounts is
+ * updated by DBUS signals that might need some time. Thus, calling AccountManager::count() emmediately
+ * after removing might return an incorrect value. Wait until AccountManager::signalAccountsUpdated() is emitted.
+ * @return true if remove operation was successful.
+ */
+ bool remove();
+
+ /**
+ * Validity check.
+ * Do not access any functions if this account is invalid.
+ */
+ bool isValid();
+
+ /**
+ * Get connection manager for this account.
+ * Returns the connection manager that belongs to this account
+ * @return The name of the connection manager (like gabble, ..).
+ */
+ QString connectionManagerName();
+
+ /**
+ * Get protocol for this account.
+ * Returns the protocol that belongs to this account
+ * @return The name of the protocol (like jabber, ..)
+ */
+ QString protocolName();
+
+ /**
+ * Get the current presence.
+ * The presence for the current connection is returned.
+ * @return The current aggregated presence.
+ */
+ QString currentPresence();
+
+signals:
+ /** Property were changed. This signal is emitted when properties were changed. */
+ void signalPropertiesChanged( const QVariantMap& properties );
+
+ /** About to remove. This signal is emmitted before the account is removed. */
+ void signalAboutToRemove();
+
+ /** Removed. This signal is emmitted after the account is removed. */
+ void signalRemoved();
+
+ /** Account presence was changed. Signal is emitted after the account changed its presence state.
+ * @todo Implement this..
+ */
+ void signalPresenceChanged();
+
+
+protected slots:
+ void slotPropertiesChanged( const QVariantMap& properties );
+ void slotRemoved();
+
+protected:
+ /**
+ * Constructor. The account manager cannot be instantiated directly. Use AccountManager::account() for it!
+ */
+ Account( const QString& handle, QObject* parent );
+ ~Account();
+
+ /**
+ * D-BUS interface.
+ * This protected access to the D-BUS interface can be used to extend this class with special features.
+ */
+ Telepathy::Client::AccountInterface* interface();
+
+ /**
+ * Returns the handle.
+ * The handle is an internal representation to access the real data. Its format should
+ * not be interpreted.
+ */
+ QString handle() const;
+
+private:
+ void init( const QString handle );
+
+ AccountPrivate * const d;
+ friend class AccountManager; // TODO: Remove this friend class
+ friend class AccountManagerPrivate;
+};
+
+}
+
+
+#endif
diff --git a/TelepathyQt4/Prototype/AccountManager.cpp b/TelepathyQt4/Prototype/AccountManager.cpp
new file mode 100644
index 0000000..285ea1d
--- /dev/null
+++ b/TelepathyQt4/Prototype/AccountManager.cpp
@@ -0,0 +1,310 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/AccountManager.h"
+
+#include <QCoreApplication>
+#include <QDBusObjectPath>
+#include <QDBusPendingReply>
+#include <QDebug>
+#include <QMap>
+#include <QPointer>
+
+#include <TelepathyQt4/Client/AccountManager>
+#include <TelepathyQt4/Types>
+
+#include <TelepathyQt4/Prototype/Account.h>
+
+// #define ENABLE_DEBUG_OUTPUT_
+
+using namespace TpPrototype;
+
+AccountManager* TpPrototype::AccountManager::m_pInstance = NULL;
+
+class TpPrototype::AccountManagerPrivate
+{
+public:
+ AccountManagerPrivate()
+ { init(); }
+
+ Telepathy::Client::AccountManagerInterface* m_pInterface;
+ QMap<QString, QPointer<Account> > m_validAccountHandles;
+
+ void init()
+ {
+ m_pInterface = NULL;
+ }
+
+ void removeAccount( const QString& handle )
+ {
+ if ( m_validAccountHandles.contains( handle ) )
+ {
+ delete m_validAccountHandles.value( handle );
+ m_validAccountHandles.remove( handle );
+ }
+ }
+};
+
+AccountManager::AccountManager( QObject* parent ):
+ QObject( parent ),
+ d( new AccountManagerPrivate )
+{
+ init();
+}
+
+AccountManager* AccountManager::instance()
+{
+ if ( NULL == m_pInstance )
+ {
+ m_pInstance = new AccountManager( QCoreApplication::instance() );
+ Q_ASSERT( m_pInstance );
+ }
+
+ return m_pInstance;
+}
+
+
+AccountManager::~AccountManager()
+{
+ delete d;
+}
+
+int AccountManager::count()
+{
+ return d->m_validAccountHandles.count();
+}
+
+// TODO: Define a accountlist container class that stores the accounts and is doing the book keeping..
+QList<QPointer<Account> > AccountManager::accountList()
+{
+ QList<QPointer<Account> > ret_list;
+
+ Account* account = NULL;
+ QStringList handles = d->m_validAccountHandles.keys();
+ foreach( const QString& handle, handles )
+ {
+ account = d->m_validAccountHandles.value( handle );
+ Q_ASSERT( account );
+ if ( !account )
+ {
+ qWarning() << "Found handles that points to no object!";
+ d->removeAccount( handle );
+ continue;
+ }
+ ret_list.append( QPointer<Account>( account ) );
+ }
+
+ return ret_list;
+}
+
+#if 0
+TpPrototype::Account* account( int num )
+{
+ if ( d->m_validAccountHandles.at(
+}
+#endif
+
+
+QList<QPointer<Account> > AccountManager::accountListOfEnabledAccounts()
+{
+ QList<QPointer<Account> > ret_list;
+
+ if ( accountList().count() != 0)
+ {
+ foreach (const QPointer<Account>& account, accountList() )
+ {
+ if ( account->properties().value( "Enabled" ) == true )
+ {
+ ret_list.append( account );
+ }
+ }
+ }
+ return ret_list;
+}
+
+bool AccountManager::createAccount( const QString& connectionManager, const QString& protocol, const QString& displayName, const QVariantMap& _parameters )
+{
+ QVariantMap parameters = _parameters;
+
+ //HACK: Set server for google talk which cannot be set after the account was created.
+ // This should be removed after fixing the create account workflow!
+ if ( parameters.value( "account" ).toString().contains( "google" ) )
+ { parameters.insert( "server", "talk.google.com" ); }
+
+ if ( parameters.contains( "port" ) && parameters.value( "port" ).type() != QVariant::UInt )
+ {
+ qWarning() << "We got the wrong type of the port. We correct it here manually";
+ parameters.insert( "port", qvariant_cast<uint>( parameters.value( "port" ) ) );
+ }
+
+ // empty Parameterlists should not be send to create account. Otherwise strange things may happen..
+ if ( parameters.size() > 0 )
+ {
+ QStringList keys = parameters.keys();
+ foreach( const QString& key, keys )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "createAccount--> Key:" << key << "value:" << parameters.value( key );
+#endif
+ if (parameters.value(key).toString().isEmpty() )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Remove Key:" << key << "value:" << parameters.value( key );
+#endif
+ parameters.remove( key );
+ }
+ }
+ }
+
+ QDBusPendingReply<QDBusObjectPath> create_reply = d->m_pInterface->CreateAccount( connectionManager,
+ protocol,
+ displayName,
+ parameters );
+ create_reply.waitForFinished();
+
+ if ( !create_reply.isValid() )
+ {
+ QDBusError error = create_reply.error();
+
+ qWarning() << "Disconnect: error type:" << error.type()
+ << "Disconnect: error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+ // Fall through
+ return true;
+}
+
+void AccountManager::slotAccountValidityChanged( const QDBusObjectPath& account, bool valid )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotAccountValidityChanged: " << valid;
+#endif
+ bool update_occurred = false;
+ if ( valid )
+ {
+ // Add account to the list if it is not already stored
+ if ( !d->m_validAccountHandles.contains( account.path() )
+ || !d->m_validAccountHandles.value( account.path() ) )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotAccountValidityChanged: Add new account to list";
+#endif
+ TpPrototype::Account* new_account = new Account( account.path(), this );
+ connect( new_account, SIGNAL( signalRemoved() ),
+ this, SLOT( slotAccountRemoved() ) );
+ connect( new_account, SIGNAL( signalPropertiesChanged( const QVariantMap& ) ),
+ this, SLOT( slotPropertiesChanged() ) );
+ d->m_validAccountHandles.insert( account.path(), QPointer<Account>( new_account ) );
+ update_occurred = true;
+ emit signalNewAccountAvailable( new_account );
+ }
+ }
+ else
+ {
+ if ( d->m_validAccountHandles.contains( account.path() ) )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotAccountValidityChanged: Remove account from list";
+#endif
+ d->removeAccount( account.path() );
+ update_occurred = true;
+ }
+ }
+ if ( update_occurred )
+ { emit signalAccountsUpdated(); }
+}
+
+void AccountManager::slotAccountRemoved( const QDBusObjectPath& account )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotAccountRemoved() <external>";
+#endif
+ d->removeAccount( account.path() );
+ emit signalAccountsUpdated();
+}
+
+
+void AccountManager::slotPropertiesChanged()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotPropertiesChanged()";
+#endif
+ emit signalAccountsUpdated();
+}
+
+// Called when an Account was removed
+void AccountManager::slotAccountRemoved()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AccountManager::slotAccountRemoved sender:" << sender();
+#endif
+ Account* account = qobject_cast<Account*>( sender() );
+ Q_ASSERT( account );
+ if ( account )
+ {
+ QString handle = account->handle();
+ d->removeAccount( handle );
+ emit signalAccountsUpdated();
+ }
+}
+
+void AccountManager::init()
+{
+ Telepathy::registerTypes();
+ d->m_pInterface = new Telepathy::Client::AccountManagerInterface( "org.freedesktop.Telepathy.AccountManager",
+ "/org/freedesktop/Telepathy/AccountManager",
+ this );
+ Q_ASSERT( d->m_pInterface );
+ if ( ! d->m_pInterface )
+ { return; }
+
+ if ( !d->m_pInterface->isValid() )
+ {
+ qWarning() << "Unable to connect to AccountManagerInterface: MissionControl seems to be missing!";
+ }
+ //Q_ASSERT( d->m_pInterface->isValid() );
+
+ // It might be better to use layzy initializing here.. (ses)
+ Telepathy::ObjectPathList account_handles = d->m_pInterface->ValidAccounts();
+ foreach( const QDBusObjectPath& account_handle, account_handles )
+ {
+
+ Account* account = new Account( account_handle.path(), this );
+ connect( account, SIGNAL( signalRemoved() ),
+ this, SLOT( slotAccountRemoved() ) );
+ connect( account, SIGNAL( signalPropertiesChanged( const QVariantMap& ) ),
+ this, SLOT( slotPropertiesChanged() ) );
+ d->m_validAccountHandles.insert( account_handle.path(), QPointer<Account>( account ) );
+ emit signalAccountsUpdated();
+ }
+
+ connect( d->m_pInterface, SIGNAL( AccountValidityChanged( const QDBusObjectPath&, bool ) ),
+ this, SLOT( slotAccountValidityChanged( const QDBusObjectPath&, bool ) ) );
+ connect( d->m_pInterface, SIGNAL( AccountRemoved(const QDBusObjectPath& ) ),
+ this, SLOT( slotAccountRemoved( const QDBusObjectPath& ) ) );
+
+
+}
+
diff --git a/TelepathyQt4/Prototype/AccountManager.h b/TelepathyQt4/Prototype/AccountManager.h
new file mode 100644
index 0000000..12304d3
--- /dev/null
+++ b/TelepathyQt4/Prototype/AccountManager.h
@@ -0,0 +1,141 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef TelepathyQt4_Prototype_AccountManager_H_
+#define TelepathyQt4_Prototype_AccountManager_H_
+
+#include <QDBusObjectPath>
+#include <QObject>
+#include <QPointer>
+
+#include <TelepathyQt4/Prototype/Account.h>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+
+namespace TpPrototype {
+//
+class AccountManagerPrivate;
+
+/**
+ * @defgroup qt_accountmgm Account Management
+ * @ingroup qt_style_api
+ * Classes that provide functions to handle accounts.
+ */
+
+
+/**
+ * This class manages all accounts.
+ * The account manager provides access to the list of accounts. Additionally you can create and remove accounts.<br>
+ * Use the Connectionfacade to obtain a list of valid parameters for a protocol or the list of available connection managers.<br>
+ * @see ConnectionFacade
+ * @ingroup qt_accountmgm
+ * @todo Integrate all functions related to Accounts from the ConnectionFacade into this class.
+ */
+class AccountManager : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Returns pointer to the instance of this class.
+ * @return Instance pointer.
+ */
+ static AccountManager* instance();
+
+ /**
+ * Number of Accounts. Returns how many accounts are available.
+ * @return Number of accounts available.
+ * @deprecated Use accountList().count() instead.
+ */
+ int count() ATTRIBUTE_DEPRECATED;
+
+ /**
+ * List of accounts. The account pointer is stored in a QPointer. If the account is removed it is deleted
+ * by the account manager. Thus, the pointer is set to 0.
+ * @todo: Return QList<Account> here, instead of a pointer.
+ */
+ QList<QPointer<Account> > accountList();
+
+ /**
+ * List of enabled accounts
+ */
+ QList<QPointer<Account> > accountListOfEnabledAccounts();
+
+ /**
+ * Create account. This function creates an account with the given parameters.<br>
+ * <b>Note:</b> Although this call is synchronous, the internal book keeping of valid accounts is
+ * updated by DBUS signals that might need some time. Thus, calling count() emmediately after create might
+ * return an incorrect value. Wait until signalAccountsUpdated() is emitted.
+ * @param connectionManager The name of the connection manager, e.g. "salut".
+ * @param protocol The protocol, e.g. "local-xmpp".
+ * @param parameters List of parameters needed to create the account
+ * @param displayName The name of the account to display.
+ * @return true when creating was successful.
+ */
+ bool createAccount( const QString& connectionManager, const QString& protocol, const QString& displayName, const QVariantMap& parameters );
+
+ /**
+ * Remove account. Removes the given account.
+ * @param account The pointer to the account. The pointer is not accessable after this call!
+ * @return true if remove operation was successful.
+ */
+ bool removeAccount( Account* account );
+
+signals:
+ /**
+ * Some changes occurred on the account data. This signal is emitted if the internal data of the account manager
+ * is changed (accounts were created or removed).<br>
+ * It is suggested to refetch all locally stored data after this signal.
+ */
+ void signalAccountsUpdated();
+
+ /**
+ * A new account is available.
+ * This signal is emitted if a new account was created by a contact manager
+ */
+ void signalNewAccountAvailable( TpPrototype::Account* account );
+protected:
+ /**
+ * Constructor. The account manager cannot be instantiated directly. Use instance() for it!
+ */
+ AccountManager( QObject* parent = NULL );
+ ~AccountManager();
+
+protected slots:
+ void slotAccountValidityChanged( const QDBusObjectPath& account, bool valid );
+ void slotAccountRemoved( const QDBusObjectPath& account );
+ void slotAccountRemoved();
+ void slotPropertiesChanged();
+
+private:
+ void init();
+
+ AccountManagerPrivate * const d;
+ static AccountManager* m_pInstance;
+};
+
+}
+
+#endif
diff --git a/TelepathyQt4/Prototype/AvatarManager.cpp b/TelepathyQt4/Prototype/AvatarManager.cpp
new file mode 100644
index 0000000..6d7ff15
--- /dev/null
+++ b/TelepathyQt4/Prototype/AvatarManager.cpp
@@ -0,0 +1,320 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/AvatarManager.h"
+
+#include <QCoreApplication>
+#include <QDBusObjectPath>
+#include <QDBusPendingReply>
+#include <QDebug>
+#include <QMap>
+#include <QPointer>
+
+#include <TelepathyQt4/Client/Connection>
+
+#include <TelepathyQt4/Prototype/Account.h>
+#include <TelepathyQt4/Prototype/AccountManager.h>
+#include <TelepathyQt4/Prototype/ConnectionFacade.h>
+#include <TelepathyQt4/Prototype/Connection.h>
+#include <TelepathyQt4/Prototype/Contact.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+
+// #define ENABLE_DEBUG_OUTPUT_
+
+using namespace TpPrototype;
+
+class TpPrototype::AvatarManagerPrivate
+{
+public:
+ AvatarManagerPrivate( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+ { init( connection, interface ); }
+
+ Telepathy::Client::ConnectionInterface* m_pConnectionInterface;
+ Telepathy::Client::ConnectionInterfaceAvatarsInterface* m_pAvatarsInterface;
+ QPointer<Connection> m_pConnection;
+
+ bool m_isValid;
+ void init( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+ {
+ m_pConnection = connection;
+ m_pConnectionInterface = interface;
+ m_pAvatarsInterface = NULL;
+ m_isValid = true;
+ }
+
+};
+
+AvatarManager::AvatarManager( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent ):
+ QObject( parent ),
+ d( new AvatarManagerPrivate( connection, interface ) )
+{
+ init( connection, interface );
+}
+
+AvatarManager::~AvatarManager()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "D'tor AvatarManager (" << this << ")";
+#endif
+ delete d;
+}
+
+bool AvatarManager::isValid()
+{
+ return d->m_isValid;
+}
+
+
+
+TpPrototype::Connection* AvatarManager::connection()
+{
+ return d->m_pConnection;
+}
+
+bool AvatarManager::setAvatar( const TpPrototype::AvatarManager::Avatar& newValue )
+{
+ QDBusPendingReply<QString> set_avatar_reply = d->m_pAvatarsInterface->SetAvatar( newValue.avatar, newValue.mimeType );
+ set_avatar_reply.waitForFinished();
+
+ if ( !set_avatar_reply.isValid() )
+ {
+ QDBusError error = set_avatar_reply.error();
+
+ qWarning() << "AvatarManager::setAvatar: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return false;
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AvatarManager::setAvatar: token " << set_avatar_reply.value();
+#endif
+
+ return true;
+}
+
+void AvatarManager::requestAvatar()
+{
+ uint self_handle = TpPrototype::ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pConnectionInterface );
+ QList<uint> contact_ids;
+ contact_ids << self_handle;
+
+ QDBusPendingReply<> avatars_reply = d->m_pAvatarsInterface->RequestAvatars( contact_ids );
+
+ // slotAvatarRetrieved is called after this point.
+}
+
+TpPrototype::AvatarManager::AvatarRequirements AvatarManager::avatarRequirements()
+{
+ Q_ASSERT( d->m_pAvatarsInterface );
+
+ TpPrototype::AvatarManager::AvatarRequirements return_data;
+ return_data.isValid = false;
+
+ QDBusPendingReply<QStringList, ushort, ushort, ushort, ushort, uint> requirements_reply = d->m_pAvatarsInterface->GetAvatarRequirements();
+ requirements_reply.waitForFinished();
+
+ if ( !requirements_reply.isValid() )
+ {
+ QDBusError error = requirements_reply.error();
+
+ qWarning() << "AvatarManager::GetAvatarRequirements: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return return_data;
+ }
+
+ TpPrototype::AvatarManager::AvatarRequirements ret_requirement;
+ ret_requirement.mimeTypes = qvariant_cast<QStringList>( requirements_reply.argumentAt( 0 ) );
+ ret_requirement.minimumWidth = qvariant_cast<ushort>(requirements_reply.argumentAt( 1 ) );
+ ret_requirement.minimumHeight = qvariant_cast<ushort>(requirements_reply.argumentAt( 2 ) );
+ ret_requirement.maximumWidth = qvariant_cast<ushort>(requirements_reply.argumentAt( 3 ) );
+ ret_requirement.maximumHeight = qvariant_cast<ushort>(requirements_reply.argumentAt( 4 ) );
+ ret_requirement.maxSize = qvariant_cast<uint>(requirements_reply.argumentAt( 5 ) );
+ return_data.isValid = true;
+
+ return ret_requirement;
+}
+
+void AvatarManager::avatarForContactList( const QList<QPointer<Contact> >& contacts )
+{
+ Q_ASSERT( d->m_pAvatarsInterface );
+ Telepathy::UIntList contact_ids;
+ foreach( Contact* contact, contacts )
+ {
+ if ( !contact )
+ { continue; }
+ contact_ids.append( contact->telepathyHandle() );
+ }
+
+ QDBusPendingReply<> avatars_reply = d->m_pAvatarsInterface->RequestAvatars( contact_ids );
+
+ // slotAvatarRetrieved is called after this point.
+}
+
+
+void AvatarManager::slotAvatarUpdated( uint contactHandle, const QString& newAvatarToken )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AvatarManager::slotAvatarUpdated(" << contactHandle << "," << newAvatarToken << ")";
+#endif
+ if ( !d->m_pConnection )
+ {
+ qWarning() << "AvatarManager::slotAvatarUpdated(): Received a Avatar changed signal but no connection object exists!";
+ return;
+ }
+
+ Q_ASSERT( d->m_pAvatarsInterface );
+ Q_ASSERT( d->m_pAvatarsInterface->isValid() );
+ Q_ASSERT( d->m_pConnection );
+ Q_ASSERT( d->m_pConnection->contactManager() );
+
+ if ( !d->m_pConnection
+ || !d->m_pConnection->contactManager() )
+ {
+ qWarning() << "AvatarManager::slotAvatarUpdated(): Unable to request contact manager or connection is not valid!";
+ return;
+ }
+
+ uint self_handle = ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pConnectionInterface );
+
+ if ( self_handle == contactHandle )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "AvatarManager::slotAvatarUpdated(): Ignored that my avatar is updated.";
+#endif
+
+ //emit void signalOwnAvatarChanged();
+ }
+ else
+ {
+ foreach( TpPrototype::Contact* contact, d->m_pConnection->contactManager()->contactList() )
+ {
+ if ( ( contact->telepathyHandle() == contactHandle )
+ && ( contact->avatar().token != newAvatarToken ) )
+ {
+ // Request avatar for this contact.
+ avatarForContactList( QList<QPointer<Contact> >() << QPointer<Contact>( contact ) );
+ }
+ }
+ }
+}
+
+// Called after avatarForContactList() is called.
+void AvatarManager::slotAvatarRetrieved( uint contactHandle, const QString& token, const QByteArray& avatar, const QString& type )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "slotAvatarRetrieved: Handle: " << contactHandle << "Token:" << token << "Type: " << type;
+#endif
+
+ TpPrototype::AvatarManager::Avatar new_avatar;
+ new_avatar.avatar = avatar;
+ new_avatar.token = token;
+ new_avatar.mimeType = type;
+
+ uint self_handle = ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pConnectionInterface );
+ if ( self_handle == contactHandle )
+ {
+ emit signalOwnAvatarChanged( new_avatar );
+ return;
+ }
+
+ foreach( TpPrototype::Contact* contact, d->m_pConnection->contactManager()->contactList() )
+ {
+ // Find contact for handle and check whether the token has changed. If not, the avatar was not changed.
+ if ( ( contact->telepathyHandle() == contactHandle )
+ && ( contact->avatar().token != token ) )
+ {
+ contact->setAvatar( new_avatar );
+ emit signalAvatarChanged( contact );
+ }
+ }
+}
+
+void AvatarManager::init( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+{
+ Q_ASSERT( interface );
+
+ if ( !interface || !connection )
+ {
+ d->m_isValid = false;
+ return;
+ }
+
+ Telepathy::registerTypes();
+ qRegisterMetaType<TpPrototype::AvatarManager::Avatar>();
+
+ QDBusPendingReply<QStringList> interfaces_reply = d->m_pConnectionInterface->GetInterfaces();
+ interfaces_reply.waitForFinished();
+
+ if ( !interfaces_reply.isValid() )
+ {
+ QDBusError error = interfaces_reply.error();
+
+ qWarning() << "GetInterfaces: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return;
+ }
+
+ QString avatar_interface_name;
+ bool found_avatar_support = false;
+ foreach( const QString& interface, interfaces_reply.value() )
+ {
+ if ( interface.endsWith( ".Avatars" ) )
+ {
+ found_avatar_support = true;
+ avatar_interface_name = interface;
+ break;
+ }
+ }
+ if ( !found_avatar_support )
+ {
+ d->m_isValid = false;
+ qWarning( "AvatarManager::init(): Connection Manager does not support the Interface \"Avatars\". Other interfaces are not supported!" );
+ return;
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Interface Name: " << avatar_interface_name;
+#endif
+ d->m_pAvatarsInterface = new Telepathy::Client::ConnectionInterfaceAvatarsInterface( d->m_pConnectionInterface->service(), d->m_pConnectionInterface->path(), this );
+
+ connect( d->m_pAvatarsInterface, SIGNAL( AvatarUpdated(uint, const QString&) ),
+ this, SLOT( slotAvatarUpdated(uint, const QString&) ) );
+ connect( d->m_pAvatarsInterface, SIGNAL( AvatarRetrieved(uint , const QString& , const QByteArray& , const QString& ) ),
+ this, SLOT( slotAvatarRetrieved( uint , const QString& , const QByteArray& , const QString& ) ) );
+
+}
+
+
diff --git a/TelepathyQt4/Prototype/AvatarManager.h b/TelepathyQt4/Prototype/AvatarManager.h
new file mode 100644
index 0000000..085a281
--- /dev/null
+++ b/TelepathyQt4/Prototype/AvatarManager.h
@@ -0,0 +1,174 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef TelepathyQt4_Prototype_AvatarManager_H_
+#define TelepathyQt4_Prototype_AvatarManager_H_
+
+#include <QDBusObjectPath>
+#include <QObject>
+#include <QPointer>
+
+#include <TelepathyQt4/Types>
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+namespace TpPrototype {
+
+class AvatarManagerPrivate;
+class Connection;
+class Contact;
+class Account;
+
+/**
+ * @ingroup qt_connection
+ * This class manages avatar information for one connection.
+ * Whenever a contact avatar changes, the signal signalAvatarChanged() is emitted. This signal provides the related contact object
+ * obtained from the ContactManager.
+ * In order to keep the contacts updated, you just have to instantiate this class (by requesting the object with Connection::avatarManager())
+ * and initialize the list of contacts once (by calling avatarForContactList() ). After this point, the avatar of the contact
+ * is updated automatically if a change is signalled by the backend.
+ * @see Connection
+ */
+class AvatarManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * The required Avatar format.
+ */
+ struct AvatarRequirements
+ {
+ /** The list of supported Mimetypes */
+ QStringList mimeTypes;
+ /** The minimum image width */
+ uint minimumWidth;
+ /** The minmum image height */
+ uint minimumHeight;
+ /** The maximum image width */
+ uint maximumWidth;
+ /** The maximum image height */
+ uint maximumHeight;
+ /** The maximum size */
+ uint maxSize;
+ /** data validity */
+ bool isValid;
+ };
+
+ /**
+ * The Avatar
+ */
+ struct Avatar
+ {
+ /** The avatar data */
+ QByteArray avatar;
+ /** The mimetype of this data */
+ QString mimeType;
+ /** The id associated with this avatar */
+ QString token;
+ };
+
+ /**
+ * Validity.
+ * Do not access any methods if the object is invalid!
+ */
+ bool isValid();
+
+ /**
+ * Returns the connection that belongs to this capabilities information.
+ * @return The connection object
+ */
+ TpPrototype::Connection* connection();
+
+ /**
+ * Set local Avatar.
+ * This function sets the capabilites of the account that belongs to this connection.
+ * @param newValue The new avatar. The content of <i>token</i> is ignored.
+ * @return true if setting was successful
+ */
+ bool setAvatar( const TpPrototype::AvatarManager::Avatar& newValue );
+
+ /**
+ * Request local Avatar.
+ * Requests the avatar of the account that belongs to this connection.
+ * <b>Info:</b> The signal signalOwnAvatarChanged() is called asynchonously after this call.
+ */
+ void requestAvatar();
+
+ /**
+ * Get the required format of avatars on this connection.
+ * @return The requirements of supported avatars.
+ * @see AvatarRequirements
+ */
+ AvatarRequirements avatarRequirements();
+
+ /**
+ * Get the avatar for a list of contacts.
+ * The avatars can be requested from the contact object.
+ * <b>Info:</b> The signal signalAvatarChanged() is called asynchonously after this call for every contact in this list.
+ * @param List of contacts to request the avatars from.
+ * @see signalAvatarChanged()
+ */
+ void avatarForContactList( const QList<QPointer<Contact> >& contacts );
+
+signals:
+ /**
+ * The avatar of a contact was changed. This signal is emitted when any of the known contacts changed its avatar.
+ */
+ void signalAvatarChanged( TpPrototype::Contact* contact );
+
+ /**
+ * My avatar was changed.
+ * This signal is emmitted if the local avatar was changed.
+ */
+ void signalOwnAvatarChanged( TpPrototype::AvatarManager::Avatar avatar );
+
+protected:
+ /**
+ * Constructor. The capabilities manager cannot be instantiated directly. Use Connection::AvatarManager() for it!
+ */
+ AvatarManager( TpPrototype::Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent = NULL );
+ ~AvatarManager();
+
+protected slots:
+ void slotAvatarUpdated( uint contact, const QString& newAvatarToken );
+ void slotAvatarRetrieved( uint contact, const QString& token, const QByteArray& avatar, const QString& type );
+
+private:
+ void init( TpPrototype::Connection* connection, Telepathy::Client::ConnectionInterface* interface );
+
+ TpPrototype::AvatarManagerPrivate * const d;
+ friend class Connection;
+ friend class ConnectionPrivate;
+};
+}
+
+Q_DECLARE_METATYPE( TpPrototype::AvatarManager::Avatar );
+Q_DECLARE_METATYPE( TpPrototype::AvatarManager::AvatarRequirements );
+#endif
diff --git a/TelepathyQt4/Prototype/CapabilitiesManager.cpp b/TelepathyQt4/Prototype/CapabilitiesManager.cpp
new file mode 100644
index 0000000..250cd0d
--- /dev/null
+++ b/TelepathyQt4/Prototype/CapabilitiesManager.cpp
@@ -0,0 +1,321 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/CapabilitiesManager.h"
+
+#include <QCoreApplication>
+#include <QDBusObjectPath>
+#include <QDBusPendingReply>
+#include <QDebug>
+#include <QMap>
+#include <QPointer>
+
+#include <TelepathyQt4/Client/Connection>
+
+#include <TelepathyQt4/Prototype/Account.h>
+#include <TelepathyQt4/Prototype/AccountManager.h>
+#include <TelepathyQt4/Prototype/ConnectionFacade.h>
+#include <TelepathyQt4/Prototype/Connection.h>
+#include <TelepathyQt4/Prototype/Contact.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+
+// #define ENABLE_DEBUG_OUTPUT_
+
+using namespace TpPrototype;
+
+class TpPrototype::CapabilitiesManagerPrivate
+{
+public:
+ CapabilitiesManagerPrivate()
+ { init(); }
+
+ Telepathy::Client::ConnectionInterface* m_pConnectionInterface;
+ Telepathy::Client::ConnectionInterfaceCapabilitiesInterface* m_pCapabilitiesInterface;
+
+
+ QPointer<Connection> m_pConnection;
+
+ bool m_isValid;
+ void init()
+ {
+ m_pConnectionInterface = NULL;
+ m_pCapabilitiesInterface = NULL;
+ m_pConnection = NULL;
+ m_isValid = true;
+ }
+
+};
+
+CapabilitiesManager::CapabilitiesManager( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent ):
+ QObject( parent ),
+ d( new CapabilitiesManagerPrivate )
+{
+ init( connection, interface );
+}
+
+CapabilitiesManager::~CapabilitiesManager()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "D'tor CapabilitiesManager (" << this << ")";
+#endif
+ delete d;
+}
+
+bool CapabilitiesManager::isValid()
+{
+ return d->m_isValid;
+}
+
+
+
+TpPrototype::Connection* CapabilitiesManager::connection()
+{
+ return d->m_pConnection;
+}
+
+bool CapabilitiesManager::setCapabilities( const Telepathy::CapabilityPairList& capabilities, const QStringList& removedChannels )
+{
+ QDBusPendingReply<Telepathy::CapabilityPairList> advertise_capabilities_reply = d->m_pCapabilitiesInterface->AdvertiseCapabilities( capabilities, removedChannels );
+ advertise_capabilities_reply.waitForFinished();
+
+ if ( !advertise_capabilities_reply.isValid() )
+ {
+ QDBusError error = advertise_capabilities_reply.error();
+
+ qWarning() << "CapabilitiesManager::AdvertiseCapabilities: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return false;
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "CapabilitiesManager::setCapabilities: " << capabilities.count();
+ qDebug() << "CapabilitiesManager::setCapabilities: " << advertise_capabilities_reply.value().count();
+#endif
+
+ return true;
+}
+
+Telepathy::ContactCapabilityList CapabilitiesManager::capabilities()
+{
+ uint self_handle = TpPrototype::ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pConnectionInterface );
+ QList<uint> handle_list;
+ handle_list.append( self_handle );
+ QDBusPendingReply<Telepathy::ContactCapabilityList> capabilities_reply = d->m_pCapabilitiesInterface->GetCapabilities( handle_list );
+ capabilities_reply.waitForFinished();
+
+ if ( !capabilities_reply.isValid() )
+ {
+ QDBusError error = capabilities_reply.error();
+
+ qWarning() << "CapabilitiesManager::capabilities: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return Telepathy::ContactCapabilityList();
+ }
+
+ Telepathy::ContactCapabilityList capabilities=capabilities_reply.value();
+
+ return capabilities;
+}
+
+
+void CapabilitiesManager::capabilitiesForContactList( const QList<QPointer<Contact> >& contacts )
+{
+ Q_ASSERT( d->m_pCapabilitiesInterface );
+ Telepathy::UIntList contact_ids;
+ foreach( Contact* contact, contacts )
+ {
+ if ( !contact )
+ { continue; }
+ contact_ids.append( contact->telepathyHandle() );
+ }
+
+ QDBusPendingReply<Telepathy::ContactCapabilityList> capabilities_reply = d->m_pCapabilitiesInterface->GetCapabilities( contact_ids );
+ capabilities_reply.waitForFinished();
+
+ if ( !capabilities_reply.isValid() )
+ {
+ QDBusError error = capabilities_reply.error();
+
+ qWarning() << "GetInterfaces: error type:" << error.type()
+ << "GetInterfaces: error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return;
+ }
+
+ Telepathy::ContactCapabilityList capabilities=capabilities_reply.value();
+
+ foreach( Contact* contact, contacts )
+ {
+ Telepathy::ContactCapabilityList contact_capabilities;
+ for ( int i=0; i < capabilities.size(); i++ )
+ {
+ Telepathy::ContactCapability capability = capabilities.value( i );
+ if ( contact && contact->telepathyHandle() == capability.handle )
+ {
+ contact_capabilities.append( capability );
+ }
+ }
+ contact->setCapabilities( contact_capabilities );
+ }
+}
+
+void CapabilitiesManager::slotCapabilitiesChanged( const Telepathy::CapabilityChangeList& capabilities )
+{
+ if ( !d->m_pConnection )
+ {
+ qWarning() << "CapabilitiesManager::slotCapabilitiesChanged(): Received a Capabilities changed signal but no connection object exists!";
+ return;
+ }
+
+ Q_ASSERT( d->m_pCapabilitiesInterface );
+ Q_ASSERT( d->m_pCapabilitiesInterface->isValid() );
+
+ QPointer<TpPrototype::Contact> contact;
+ for (int i=0; i<capabilities.size(); i++)
+ {
+
+ Telepathy::CapabilityChange changed_capability = capabilities.value( i );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "CapabilityChange "<< i<< "handle" <<changed_capability.handle;
+ qDebug() << "CapabilityChange"<< i << "CannelType" <<changed_capability.channelType;
+ qDebug() << "CapabilityChange "<< i << "Generic Flags" <<changed_capability.oldGenericFlags;
+ qDebug() << "CapabilityChange "<< i << "Generic Flags" <<changed_capability.newGenericFlags;
+ qDebug() << "CapabilityChange "<< i << "Type Specific Flags" <<changed_capability.oldTypeSpecificFlags;
+ qDebug() << "CapabilityChange "<< i << "Type Specific Flags" <<changed_capability.newTypeSpecificFlags;
+#endif
+
+ if ( !d->m_pConnection->contactManager() )
+ {
+ qWarning() << "CapabilitiesManager::slotCapabilitiesChanged(): Unable to request contact manager!";
+ return;
+ }
+
+ uint self_handle = ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pConnectionInterface );
+ foreach( const Telepathy::CapabilityChange& changed_capability, capabilities )
+ {
+ if ( changed_capability.handle == self_handle )
+ {
+ emit signalOwnCapabilityChanged( changed_capability );
+ }
+ else
+ {
+ foreach( Contact* contact, d->m_pConnection->contactManager()->contactList() )
+ {
+ if ( contact && contact->telepathyHandle() == changed_capability.handle )
+ {
+ // Modify stored list of capabilities
+ Telepathy::ContactCapabilityList contact_capabilities = contact->capabilities();
+ for ( int i = 0; i < contact_capabilities.size(); ++i )
+ {
+ if ( contact_capabilities.at(i).channelType == changed_capability.channelType )
+ {
+ contact_capabilities.removeAt( i );
+ }
+ }
+
+ Telepathy::ContactCapability new_capability;
+ new_capability.handle = changed_capability.handle;
+ new_capability.channelType = changed_capability.channelType;
+ new_capability.genericFlags = changed_capability.newGenericFlags;
+ new_capability.typeSpecificFlags = changed_capability.newTypeSpecificFlags;
+ contact_capabilities.append( new_capability );
+
+ contact->setCapabilities( contact_capabilities );
+ emit signalCapabilitiesChanged( contact, changed_capability );
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void CapabilitiesManager::init( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+{
+ Q_ASSERT( interface );
+
+ if ( !interface || !connection )
+ {
+ d->m_isValid = false;
+ return;
+ }
+
+ Telepathy::registerTypes();
+ d->m_pConnectionInterface = interface;
+ d->m_pConnection = connection;
+ QDBusPendingReply<QStringList> interfaces_reply = d->m_pConnectionInterface->GetInterfaces();
+ interfaces_reply.waitForFinished();
+
+ if ( !interfaces_reply.isValid() )
+ {
+ QDBusError error = interfaces_reply.error();
+
+ qWarning() << "GetInterfaces: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return;
+ }
+ QString capabilities_interface_name;
+ bool found_capabilities_support = false;
+
+
+ foreach( const QString& interface, interfaces_reply.value() )
+ {
+ if ( interface.endsWith( ".Capabilities" ) )
+ {
+ found_capabilities_support = true;
+ capabilities_interface_name = interface;
+ break;
+ }
+ }
+ if ( !found_capabilities_support )
+ {
+ d->m_isValid = false;
+ qWarning( "CapabilitiesManager::init(): Connection Manager does not support the Interface \"Capabilities\". Other interfaces are not supported!" );
+ return;
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ //qDebug() << "Connection interface :" << d->m_pConnectionInterface->connection().interface()->path();
+ qDebug() << "Interface Name: " << capabilities_interface_name;
+#endif
+ d->m_pCapabilitiesInterface = new Telepathy::Client::ConnectionInterfaceCapabilitiesInterface(d->m_pConnectionInterface->service(),d->m_pConnectionInterface->path(),this );
+
+ connect( d->m_pCapabilitiesInterface, SIGNAL( CapabilitiesChanged( const Telepathy::CapabilityChangeList& ) ),
+ this, SLOT( slotCapabilitiesChanged( const Telepathy::CapabilityChangeList& ) ) );
+
+}
+
+
diff --git a/TelepathyQt4/Prototype/CapabilitiesManager.h b/TelepathyQt4/Prototype/CapabilitiesManager.h
new file mode 100644
index 0000000..a92f460
--- /dev/null
+++ b/TelepathyQt4/Prototype/CapabilitiesManager.h
@@ -0,0 +1,129 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_CapabilitiesManager_H_
+#define TelepathyQt4_Prototype_CapabilitiesManager_H_
+
+#include <QDBusObjectPath>
+#include <QObject>
+#include <QPointer>
+
+#include <TelepathyQt4/Types>
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+namespace TpPrototype {
+
+class CapabilitiesManagerPrivate;
+class Connection;
+class Contact;
+class Account;
+
+/**
+ * @ingroup qt_connection
+ * This class manages capabilities information for one connection.
+ * Setting the right capability decide whether it is possible to handle incoming or outgoing VoIP or Video over IP channels!
+ * Whenever a contact capability changes, the signal signalCapabilitiesChanged() is emitted. This signal provides the related contact object
+ * obtained from the ContactManager.
+ * In order to keep the contacts updated, you just have to instantiate this class (by requesting the object with Connection::capabilitiesManager())
+ * and initialize the list of contacts once (by calling capabilitiesForContactList() ). After this point, the capabilty information of the contact
+ * is updated automatically if a change is signalled by the backend.
+ * @see Connection
+ * @see StreamedMediaChannel
+ */
+class CapabilitiesManager : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Validity.
+ * Do not access any methods if the object is invalid!
+ */
+ bool isValid();
+
+ /**
+ * Returns the connection that belongs to this capabilities information.
+ * @return The connection object
+ */
+ TpPrototype::Connection* connection();
+
+ /**
+ * Set the capabilities.
+ * This function sets the capabilites of the account that belongs to this connection.
+ * @param capabilities List of capabilities for a specific channel. See Telepathy D-Bus spec section "Channel_Media_Capabilities"
+ * @param removedChanels List of channels that are removed.
+ * @return true if setting was successful
+ */
+ bool setCapabilities( const Telepathy::CapabilityPairList& capabilities, const QStringList& removedChannels = QStringList() );
+
+ /**
+ * Request capabilites.
+ * Returns the capabilites of the account that belongs to this connection.
+ * @return List of capabilities
+ */
+ Telepathy::ContactCapabilityList capabilities();
+
+ /**
+ * Gets the capabilities for a list of contacts and provides them to to specific contacts.
+ * The capabilities can be requested from the contact object.
+ */
+ void capabilitiesForContactList( const QList<QPointer<Contact> >& contacts );
+
+signals:
+ /**
+ * The capability of a contact has changed. This signal is emitted when any of the known contacts changed its capability.
+ */
+ void signalCapabilitiesChanged( TpPrototype::Contact* contact, const Telepathy::CapabilityChange& changedCapability );
+
+ /**
+ * My capability was changed. This signal is emmitted if the capability of one of my channes was changed.
+ */
+ void signalOwnCapabilityChanged( const Telepathy::CapabilityChange& changedCapability );
+
+protected:
+ /**
+ * Constructor. The capabilities manager cannot be instantiated directly. Use Connection::CapabilitiesManager() for it!
+ */
+ CapabilitiesManager( TpPrototype::Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent = NULL );
+ ~CapabilitiesManager();
+
+protected slots:
+ void slotCapabilitiesChanged( const Telepathy::CapabilityChangeList& capabilities );
+
+private:
+ void init( TpPrototype::Connection* connection, Telepathy::Client::ConnectionInterface* interface );
+
+ TpPrototype::CapabilitiesManagerPrivate * const d;
+ friend class Connection;
+ friend class ConnectionPrivate;
+};
+}
+
+#endif
diff --git a/TelepathyQt4/Prototype/ChatChannel.cpp b/TelepathyQt4/Prototype/ChatChannel.cpp
new file mode 100644
index 0000000..f02916b
--- /dev/null
+++ b/TelepathyQt4/Prototype/ChatChannel.cpp
@@ -0,0 +1,223 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/ChatChannel.h"
+
+#include <QDebug>
+#include <QMetaProperty>
+
+#include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/Channel>
+
+#include <TelepathyQt4/Prototype/Contact.h>
+
+using namespace TpPrototype;
+
+class TpPrototype::ChatChannelPrivate
+{
+public:
+ ChatChannelPrivate()
+ { init(); }
+
+ QPointer<TpPrototype::Contact> m_pContact;
+ Telepathy::Client::ChannelTypeTextInterface* m_pTextChannel;
+ QPointer<Telepathy::Client::ConnectionInterface> m_pConnectionInterface;
+
+ bool m_isValid;
+ bool m_areSignalsConnected;
+
+private:
+ void init()
+ {
+ m_pContact = NULL;
+ m_pConnectionInterface = NULL;
+ m_pTextChannel = NULL;
+ m_isValid = true;
+ m_areSignalsConnected = false;
+ }
+};
+
+ChatChannel::ChatChannel( Contact* contact, Telepathy::Client::ConnectionInterface* connectionInterface, QObject* parent ):
+ QObject( parent ),
+ d(new ChatChannelPrivate())
+{
+ Telepathy::registerTypes();
+
+ d->m_pContact = contact;
+ d->m_pConnectionInterface = connectionInterface;
+
+ requestTextChannel( d->m_pContact->telepathyHandle() );
+}
+
+ChatChannel::~ChatChannel()
+ { delete d; }
+
+bool ChatChannel::isValid() const
+{ return d->m_isValid; }
+
+
+void ChatChannel::sendTextMessage( const QString& text )
+{
+
+ if ( d->m_pTextChannel == NULL )
+ {
+ requestTextChannel( d->m_pContact->telepathyHandle() );
+ }
+
+ Q_ASSERT( d->m_pTextChannel );
+ if ( !d->m_pTextChannel )
+ {
+ qWarning() << "ChatChannel::sendTextMessage: Action ignored due to missing text channel!";
+ }
+
+ d->m_pTextChannel->Send( 0, text ); // TODO: Remove this magic number!
+
+}
+
+void ChatChannel::pendingTextMessages()
+{
+ if ( d->m_pTextChannel == NULL )
+ {
+ requestTextChannel( d->m_pContact->telepathyHandle() );
+ }
+
+ Q_ASSERT( d->m_pTextChannel );
+ if ( !d->m_pTextChannel )
+ {
+ qWarning() << "ChatChannel::pendingTextMessages: Action ignored due to missing text channel!";
+ }
+
+ QDBusPendingReply<Telepathy::PendingTextMessageList> reply= d->m_pTextChannel->ListPendingMessages( true );
+ const Telepathy::PendingTextMessageList chatMessages = reply.value();
+ Telepathy::PendingTextMessage messageshandle;
+ for ( int i=0; i < chatMessages.size(); i++ )
+ {
+ messageshandle = chatMessages.at(i);
+ slotReceivedText( messageshandle.identifier,
+ messageshandle.unixTimestamp,
+ messageshandle.sender,
+ messageshandle.messageType,
+ messageshandle.flags,
+ messageshandle.text );
+ }
+}
+
+// Called if a new text channel shall be established.
+void ChatChannel::requestTextChannel( uint handle )
+{
+ QDBusPendingReply<QDBusObjectPath> reply0 =
+ d->m_pConnectionInterface->RequestChannel( "org.freedesktop.Telepathy.Channel.Type.Text",
+ Telepathy::HandleTypeContact, handle, true );
+ reply0.waitForFinished();
+ if (!reply0.isValid())
+ {
+ QDBusError error = reply0.error();
+ qWarning() << "Get ContactListChannel: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+ d->m_isValid = false;
+ return;
+ }
+
+ QDBusObjectPath channel_path=reply0.value();
+ openTextChannel( handle, 1,channel_path.path(), "org.freedesktop.Telepathy.Channel.Type.Text" ); // TODO: Remove magic number
+}
+
+// Called if a new text channel was notified by the connection channel
+void ChatChannel::openTextChannel(uint handle, uint handleType, const QString& channel_path, const QString& channelType)
+{
+ QString channel_service_name = d->m_pConnectionInterface->service();
+ qDebug() << "ContactManager Channel Services Name" << channel_service_name;
+ qDebug() << "ContactManager Channel Path" << channel_path;
+ // This channel may never be closed!
+ d->m_pTextChannel = new Telepathy::Client::ChannelTypeTextInterface( channel_service_name,
+ channel_path,
+ this );
+ if (!d->m_pTextChannel->isValid())
+ {
+ qDebug() << "Failed to connect channel interface class to D-Bus object.";
+ delete d->m_pTextChannel;
+ d->m_pTextChannel = NULL;
+ d->m_isValid = false;
+ return;
+ }
+ else
+ {
+ if ( d->m_areSignalsConnected )
+ { return; }
+
+ d->m_areSignalsConnected = true;
+
+ qDebug() << "Success WE got a valid Text channel";
+ //ChatChannel * pChatChannel=new ChatChannel();
+ //pChatChannel->setChannel(d->m_groupTextChannel);
+ //pChatChannel->setContact(channel_contact);
+ QString messagesender;
+ messagesender = d->m_pContact->name();
+
+ qDebug() << "*************************************";
+
+ connect(d->m_pTextChannel, SIGNAL(Received(uint , uint , uint , uint , uint , const QString& )),
+ this, SLOT(slotReceivedText(uint , uint , uint , uint , uint , const QString& )));
+ connect(d->m_pTextChannel, SIGNAL(Sent(uint , uint , const QString& )),
+ this, SLOT(slotSentText(uint , uint , const QString& )));
+ connect(d->m_pTextChannel, SIGNAL(LostMessage()),
+ this, SLOT(slotLostMessage()));
+ connect(d->m_pTextChannel, SIGNAL(SendError(uint , uint , uint , const QString& )),
+ this, SLOT(slotSendError(uint , uint , uint , const QString& )));
+
+ /* QDBusPendingReply<Telepathy::PendingTextMessageList> reply= d->m_groupTextChannel->ListPendingMessages(false);
+ const Telepathy::PendingTextMessageList chatMessages=reply.value();
+ Telepathy::PendingTextMessage messageshandle;
+ for (int i=0; i<chatMessages.size(); i++)
+ {
+ messageshandle= chatMessages.at(i);
+ pChatChannel->slotReceivedText( messageshandle.identifier, messageshandle.unixTimestamp, messageshandle.sender, messageshandle.messageType, messageshandle.flags, messageshandle.text);
+
+ } */
+ }
+}
+
+
+void ChatChannel::slotReceivedText( uint id, uint timestamp, uint sender, uint type, uint flags, const QString& text )
+{
+ qDebug() << "ChatChannel: Reveived text:" << text;
+ QList<uint> message_ids;
+ message_ids.append( id );
+ d->m_pTextChannel->AcknowledgePendingMessages( message_ids );
+ emit signalTextMessageReceived( this , timestamp, type, flags, text );
+}
+
+void ChatChannel::slotSentText(uint timestamp, uint type, const QString& text )
+{
+ qDebug() << "ChatChannel: Sent text:" << text;
+ emit signalTextMessageSent( this, timestamp, type, text );
+}
+
+void ChatChannel::slotLostMessage()
+{
+}
+
+void ChatChannel::slotSendError(uint error, uint timestamp, uint type, const QString& text )
+{
+}
diff --git a/TelepathyQt4/Prototype/ChatChannel.h b/TelepathyQt4/Prototype/ChatChannel.h
new file mode 100644
index 0000000..14d05b6
--- /dev/null
+++ b/TelepathyQt4/Prototype/ChatChannel.h
@@ -0,0 +1,119 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_ChatChannel_H_
+#define TelepathyQt4_Prototype_ChatChannel_H_
+
+#include <QObject>
+#include <QPointer>
+#include <QVariantMap>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+namespace Telepathy {
+namespace Client{
+ class ConnectionInterface;
+}
+}
+
+namespace TpPrototype {
+
+class ChatChannelPrivate;
+class Contact;
+class Account;
+
+/**
+ * @ingroup qt_connection
+ * Chat Channel.
+ * This class provides the interface to send or receive text messages.
+ */
+class ChatChannel : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Validity check.
+ * Do not access any functions if this account is invalid.
+ */
+ bool isValid() const;
+
+ /**
+ * Send a text message.
+ * This function sends a text message to the contact that belongs to this channel.
+ */
+ void sendTextMessage( const QString& text );
+
+ /**
+ * Fetch pending text messages.
+ * Force to refetch all messages that were sent while the account was offline.
+ * A signal signalTextMessageReceived() will be emitted for every message.
+ * @see signalTextMessageReceived()
+ */
+ void pendingTextMessages();
+
+ /**
+ * Destructor.
+ * Deleting this object forces to drop all channels.
+ */
+ ~ChatChannel();
+
+signals:
+ /**
+ * A new text message was received.
+ * This signal is emmitted right after receiving a new test message.
+ */
+ void signalTextMessageReceived( TpPrototype::ChatChannel* chatchannel, uint timestamp, uint type, uint flags, const QString& text );
+
+ /**
+ * A text message was sent.
+ * This signal is emmitted right after test message was delivered.
+ */
+ void signalTextMessageSent( TpPrototype::ChatChannel* chatchannel, uint timestamp, uint type, const QString& text );
+
+protected:
+ /**
+ * Constructor.
+ * Use Contact::chatChannel() to obtain an object of ChatChannel.
+ */
+ ChatChannel( Contact* contact, Telepathy::Client::ConnectionInterface* connectionInterface , QObject* parent = NULL );
+
+ void requestTextChannel(uint handle);
+ void openTextChannel(uint handle, uint handleType, const QString& channelPath, const QString& channelType );
+
+protected slots:
+ void slotSentText(uint timestamp, uint type, const QString& text );
+ void slotLostMessage();
+ void slotSendError(uint error, uint timestamp, uint type, const QString& text );
+ void slotReceivedText(uint ID, uint timestamp, uint sender, uint type, uint flags, const QString& text);
+private:
+ ChatChannelPrivate * const d;
+ friend class ContactManager;
+ friend class Contact;
+};
+
+} // namespace
+
+#endif // Header guard
diff --git a/TelepathyQt4/Prototype/Client/ChannelHandler b/TelepathyQt4/Prototype/Client/ChannelHandler
new file mode 100644
index 0000000..142eada
--- /dev/null
+++ b/TelepathyQt4/Prototype/Client/ChannelHandler
@@ -0,0 +1,6 @@
+#ifndef _TelepathyQt4_Prototype_Client_ChannelHandler_HEADER_GUARD_
+#define _TelepathyQt4_Prototype_Client_ChannelHandler_HEADER_GUARD_
+
+#include <TelepathyQt4/Prototype/_gen/cli-channel-handler.h>
+
+#endif
diff --git a/TelepathyQt4/Prototype/Connection.cpp b/TelepathyQt4/Prototype/Connection.cpp
new file mode 100644
index 0000000..9a9ca06
--- /dev/null
+++ b/TelepathyQt4/Prototype/Connection.cpp
@@ -0,0 +1,434 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/Connection.h"
+
+#include <QDebug>
+#include <QMetaProperty>
+
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/ConnectionManager>
+
+#include <TelepathyQt4/Prototype/Account.h>
+#include <TelepathyQt4/Prototype/AvatarManager.h>
+#include <TelepathyQt4/Prototype/CapabilitiesManager.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+#include <TelepathyQt4/Prototype/PresenceManager.h>
+
+// #define ENABLE_DEBUG_OUTPUT_
+
+namespace TpPrototype {
+
+class ConnectionPrivate
+{
+public:
+ ConnectionPrivate()
+ { init(); }
+
+ QString m_serviceName;
+ QString m_objectPath;
+ bool m_isValid;
+ Telepathy::ConnectionStatus m_status;
+ Telepathy::ConnectionStatusReason m_reason;
+ Telepathy::Client::ConnectionInterface* m_pInterface;
+ QPointer<ContactManager> m_pContactManager;
+ QPointer<PresenceManager> m_pPresenceManager;
+ QPointer<CapabilitiesManager> m_pCapabilitiesManager;
+ QPointer<AvatarManager> m_pAvatarManager;
+ QPointer<Account> m_pAccount;
+ QString m_connectionManager;
+ QString m_protocol;
+ void init()
+ {
+ m_isValid = false; // Will be set on true after initial initialization.
+ m_status = Telepathy::ConnectionStatusDisconnected;
+ m_reason = Telepathy::ConnectionStatusReasonNoneSpecified;
+ m_pInterface = NULL;
+ m_pContactManager = NULL;
+ m_pPresenceManager = NULL;
+ m_pCapabilitiesManager = NULL;
+ m_pAvatarManager = NULL;
+ m_pAccount = NULL;
+ }
+
+ void cleanup()
+ {
+ m_isValid = true;
+ m_status = Telepathy::ConnectionStatusDisconnected;
+ m_reason = Telepathy::ConnectionStatusReasonNoneSpecified;
+ delete m_pInterface;
+ m_pInterface = NULL;
+ delete m_pContactManager;
+ m_pContactManager = NULL;
+ delete m_pPresenceManager;
+ m_pPresenceManager = NULL;
+ delete m_pCapabilitiesManager;
+ m_pCapabilitiesManager = NULL;
+ delete m_pAvatarManager;
+ m_pAvatarManager = NULL;
+ }
+
+ void initConnectionDBUSService()
+ {
+ cleanup();
+
+ Q_ASSERT( m_pAccount );
+ Q_ASSERT( !m_pInterface ); // needs to be removed. Otherwise all following will fail
+ Q_ASSERT( !m_connectionManager.isEmpty() );
+ Q_ASSERT( !m_protocol.isEmpty() );
+
+ Telepathy::Client::ConnectionManagerInterface cm_interface( "org.freedesktop.Telepathy.ConnectionManager." + m_connectionManager,
+ "/org/freedesktop/Telepathy/ConnectionManager/" + m_connectionManager,
+ NULL );
+
+
+ QVariantMap parameter_map = m_pAccount->parameters();
+
+ // 2. Request a connection to the server
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Protocol: " << m_protocol;
+ qDebug() << "Params : " << parameter_map;
+#endif
+
+ QDBusPendingReply<QString, QDBusObjectPath> reply = cm_interface.RequestConnection( m_protocol, parameter_map );
+ reply.waitForFinished();
+
+ if ( !reply.isValid() )
+ {
+ QDBusError error = reply.error();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "initConnectionDBUSService: error type:" << error.type()
+ << " error name:" << error.name();
+#endif
+ m_isValid = false;
+ return /*NULL*/;
+ }
+
+ QString connection_service_name = reply.argumentAt<0>();
+ QDBusObjectPath connection_object_path = reply.argumentAt<1>();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Service Name: " << connection_service_name;
+ qDebug() << "Object Path : " << connection_object_path.path();
+#endif
+ m_serviceName = connection_service_name;
+ m_objectPath = connection_object_path.path();
+
+ m_pInterface = new Telepathy::Client::ConnectionInterface( m_serviceName,
+ m_objectPath,
+ NULL );
+
+ }
+};
+};
+
+TpPrototype::Connection::Connection( TpPrototype::Account* account, QObject* parent ):
+ QObject( parent ),
+ d( new ConnectionPrivate )
+{
+
+ if ( !account )
+ { return; }
+
+ init( account );
+}
+
+using namespace TpPrototype;
+Connection::~Connection()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "D'tor Connection:" << this;
+#endif
+ if ( Telepathy::ConnectionStatusDisconnected != d->m_status )
+ { requestDisconnect(); }
+ delete d;
+}
+
+
+bool Connection::isValid()
+{
+ return d->m_isValid;
+}
+
+Telepathy::ConnectionStatus Connection::status()
+{
+ return d->m_status;
+}
+
+Telepathy::ConnectionStatusReason Connection::reason()
+{
+ return d->m_reason;
+}
+
+bool Connection::requestConnect()
+{
+ if ( ( Telepathy::ConnectionStatusConnecting == d->m_status )
+ || ( Telepathy::ConnectionStatusConnected == d->m_status ) )
+ { return false; }
+
+ startupInit();
+
+ if ( !d->m_pInterface )
+ { return false; }
+
+ d->m_status = Telepathy::ConnectionStatusConnecting;
+ QDBusPendingReply<> connection_connect_reply = d->m_pInterface->Connect();
+ connection_connect_reply.waitForFinished();
+
+ if ( !connection_connect_reply.isValid() )
+ {
+ QDBusError error = connection_connect_reply.error();
+
+ qWarning() << "Connect: error type:" << error.type()
+ << "Connect: error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_status = Telepathy::ConnectionStatusDisconnected;
+ d->m_isValid = false;
+
+ return false;
+ }
+
+ d->m_isValid = true;
+ return true;
+}
+
+bool Connection::requestDisconnect()
+{
+ if ( ! d->m_pInterface || ! isValid() || ( Telepathy::ConnectionStatusDisconnected == d->m_status ) )
+ { return false; }
+
+ QDBusPendingReply<> connection_disconnect_reply = d->m_pInterface->Disconnect();
+ connection_disconnect_reply.waitForFinished();
+
+ if ( !connection_disconnect_reply.isValid() )
+ {
+ QDBusError error = connection_disconnect_reply.error();
+
+ qWarning() << "Connect: error type:" << error.type()
+ << "Connect: error name:" << error.name()
+ << "error message:" << error.message();
+ }
+
+ // Always expect that we are disconnected after this point!
+ d->m_status = Telepathy::ConnectionStatusDisconnected;
+
+ // Get rid of the contact and presence manager
+ delete d->m_pContactManager;
+ d->m_pContactManager = NULL;
+ delete d->m_pPresenceManager;
+ d->m_pPresenceManager = NULL;
+
+ return d->m_status;
+}
+
+ContactManager* Connection::contactManager()
+{
+ if ( Telepathy::ConnectionStatusConnected != d->m_status )
+ { return NULL; }
+ if ( !d->m_pContactManager )
+ { d->m_pContactManager = new ContactManager( d->m_pInterface, this ); }
+ return d->m_pContactManager;
+}
+
+PresenceManager* Connection::presenceManager()
+{
+ return createManager<PresenceManager>( d->m_pPresenceManager, "Presence" );
+}
+
+CapabilitiesManager* Connection::capabilitiesManager()
+{
+ return createManager<CapabilitiesManager>(d->m_pCapabilitiesManager, "Capabilities" );
+}
+
+AvatarManager* Connection::avatarManager()
+{
+ return createManager<AvatarManager>( d->m_pAvatarManager, "Avatars" );
+}
+
+
+Account* Connection::account() const
+{
+ if ( !d->m_pAccount
+ || !d->m_pAccount->isValid() )
+ { return NULL; }
+
+ return d->m_pAccount;
+}
+
+QString Connection::handle() const
+{
+ return d->m_objectPath;
+}
+
+Telepathy::Client::ConnectionInterface* Connection::interface()
+{
+ return d->m_pInterface;
+}
+
+void Connection::slotStatusChanged( uint status, uint reason )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Connection::slotStatusChanged() Status:" << status;
+#endif
+ Telepathy::ConnectionStatus old_status = d->m_status;
+ d->m_status = static_cast<Telepathy::ConnectionStatus>( status );
+ d->m_reason = static_cast<Telepathy::ConnectionStatusReason>( reason );
+
+ emit signalStatusChanged( this, d->m_status, old_status );
+
+ if ( account() && account()->parameters().value( "register") == true )
+ {
+ QVariantMap parameter_map;
+ parameter_map.insert( "register", false );
+ account()->setParameters( parameter_map );
+ }
+}
+
+void Connection::slotNewChannel(const QDBusObjectPath& objectPath, const QString& channelType, uint handleType, uint handle, bool suppressHandler)
+{
+ Q_UNUSED( suppressHandler );
+
+ QString tmp_objectpath=objectPath.path();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Connection:: slotNewChannel";
+ qDebug() << "Connection:: slotNewChannel ObjectPath"<< tmp_objectpath;
+ qDebug() << "Connection:: slotNewChannel ChannelType"<< channelType;
+ qDebug() << "Connection:: slotNewChannel handleType"<< handleType <<"handle"<<handle;
+#endif
+
+ // Ignore signals if no contact manager is available..
+ if ( !contactManager() )
+ {
+ // Q_ASSERT( contactManager() ); //FIXME: We have to understand why this can happen and how to avoid it!
+ qWarning() << "Connection::slotNewChannel: Receiving signals but don't get a contact manager!";
+ return;
+ }
+
+ if ( handleType == Telepathy::HandleTypeContact )
+ {
+ contactManager()->openTextChannel(handle,handleType,objectPath.path(),channelType);
+ }
+
+ if (channelType==QString("org.freedesktop.Telepathy.Channel.Type.ContactList"))
+ {
+ if (tmp_objectpath.contains("/subscribe"))
+ {
+ contactManager()->openSubscribedContactsChannel(handle,objectPath,channelType);
+ }
+ }
+
+ if (channelType==QString("org.freedesktop.Telepathy.Channel.Type.ContactList"))
+ {
+ if (tmp_objectpath.contains("/known"))
+ {
+ contactManager()->openKnownContactsChannel(handle,objectPath,channelType);
+ }
+ }
+ if (channelType==QString("org.freedesktop.Telepathy.Channel.Type.ContactList"))
+ {
+ if (tmp_objectpath.contains("/publish"))
+ {
+ contactManager()->openPublishContactsChannel(handle,objectPath,channelType);
+ }
+ }
+
+ if (channelType==QString("org.freedesktop.Telepathy.Channel.Type.ContactList"))
+ {
+ if (tmp_objectpath.contains("/deny"))
+ {
+ contactManager()->openDenyContactsChannel(handle,objectPath,channelType);
+ }
+ }
+
+ if (channelType==QString("org.freedesktop.Telepathy.Channel.Type.StreamedMedia"))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Connection::slotNewChannel(): Stream media channel opened!!";
+#endif
+ contactManager()->openStreamedMediaChannel( handle, handleType, objectPath.path(), channelType );
+ }
+}
+
+QList<uint> Connection::RequestHandles( Telepathy::HandleType handletype, QStringList& handlestrings)
+{
+ Telepathy::registerTypes();
+ return d->m_pInterface->RequestHandles( handletype,handlestrings);
+}
+
+
+bool Connection::managerSupported( const QString& managerName )
+{
+ QDBusPendingReply<QStringList> interfaces_reply = interface()->GetInterfaces();
+ interfaces_reply.waitForFinished();
+
+ if ( !interfaces_reply.isValid() )
+ {
+ QDBusError error = interfaces_reply.error();
+
+ qWarning() << "Connection::GetInterfaces: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+ foreach( const QString& interface, interfaces_reply.value() )
+ {
+ if ( interface.endsWith( managerName ) )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Connection::init( TpPrototype::Account* account )
+{
+ Telepathy::registerTypes();
+
+ if ( !account )
+ { return; }
+
+ d->m_pAccount = account;
+ d->m_connectionManager = account->connectionManagerName();
+ d->m_protocol = account->protocolName();
+
+ d->m_isValid = true;
+}
+
+// Called immediately before connection attempts
+void Connection::startupInit()
+{
+ d->initConnectionDBUSService();
+
+ if ( !d->m_isValid )
+ { return; }
+
+ Q_ASSERT( d->m_pInterface );
+
+
+ connect( d->m_pInterface, SIGNAL( NewChannel( const QDBusObjectPath&, const QString&, uint, uint, bool ) ),
+ this, SLOT( slotNewChannel( const QDBusObjectPath&, const QString&, uint, uint, bool ) ) );
+ connect( d->m_pInterface, SIGNAL( StatusChanged( uint, uint ) ),
+ this, SLOT( slotStatusChanged( uint, uint ) ) );
+}
diff --git a/TelepathyQt4/Prototype/Connection.h b/TelepathyQt4/Prototype/Connection.h
new file mode 100644
index 0000000..34e4904
--- /dev/null
+++ b/TelepathyQt4/Prototype/Connection.h
@@ -0,0 +1,256 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef TelepathyQt4_Prototype_Connection_H_
+#define TelepathyQt4_Prototype_Connection_H_
+
+#include <QDBusObjectPath>
+#include <QDBusPendingReply>
+#include <QObject>
+#include <QPointer>
+#include <QVariantMap>
+
+#include <TelepathyQt4/Constants>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+/**
+ * @defgroup qt_connection Connection Management
+ * @ingroup qt_style_api
+ * Classes that provide functions to handle connections and additional optional interfaces related to a connection.
+ */
+
+
+
+namespace TpPrototype {
+
+class ConnectionPrivate;
+class ContactManager;
+class PresenceManager;
+class CapabilitiesManager;
+class AvatarManager;
+class Account;
+/**
+ * @ingroup qt_connection
+ * This class manages a connection.
+ * The connection object provides access to optional interfaces that are related to the connection using contactManager(),
+ * capabilitiesManager(), presenceManager(), avatarManager().
+ * @todo In order to allow custom extensions, we need a support for register proxies in the Account object
+ */
+class Connection : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( bool valid READ isValid )
+public:
+
+ ~Connection();
+
+ /**
+ * Validity check.
+ * Do not access any functions if this account is invalid.
+ */
+ bool isValid();
+
+ /**
+ * Connection Status.
+ * @return The current connection status.
+ * @see Telepathy::ConnectionStatus defined in constants.h
+ */
+ Telepathy::ConnectionStatus status();
+
+ /**
+ * Reason for last state change.
+ * @return The reason.
+ * @see Telepathy::ConnectionStatusReason defined in constants.h
+ */
+ Telepathy::ConnectionStatusReason reason();
+
+ /**
+ * Connect to server.
+ * This call is asynchrous. Wait until signalStatusChanged() was emitted and the connection state is Telepathy::ConnectionStatusConnected
+ * before calling contactManager() or presenceManager() will succeed.
+ * @see signalStatusChanged()
+ */
+ bool requestConnect();
+
+ /**
+ * Disconnect. Disconnects from the server.
+ */
+ bool requestDisconnect();
+
+ /**
+ * Returns the contact list manager.
+ * The contact list manager contains the list of contacts and provides functions like add and remove.<br>
+ * <b>Note:</b> You have to request a connection with requestConnect() before a contact manager can be returned. If the connection disconnects the ContactManager will be invalid!
+ * @return Pointer to the contact manager or NULL if something went wrong.
+ * @see requestConnect()
+ */
+ ContactManager* contactManager();
+
+ /**
+ * Returns the presence manager.
+ * The presence manager handles your presence state for this connection.<br>
+ * <br>
+ * <b>Note:</b>
+ * <ul><li>You have to request a connection with requestConnect() before a presence manager can be returned.</li>
+ * <li>You have to call this function in order to get your contacts updated automatically.</li>
+ * </ul>
+ * @return Pointer to the presence manager or NULL if no presence handling is supported or no connection was requested.
+ * @see requestConnect()
+ */
+ PresenceManager* presenceManager();
+
+ /**
+ * Returns the capabilities manager.
+ * The capabilities manager handles your capabilities state for this connection.<br>
+ * <br>
+ * <b>Note:</b>
+ * <ul><li>You have to request a connection with requestConnect() before a capability manager can be returned.</li>
+ * <li>You have to call this function in order to get your contacts updated automatically.</li>
+ * </ul>
+ * @return Pointer to the capabilities manager or NULL if no capabilities handling is supported or no connection was requested.
+ * @see requestConnect()
+ */
+ CapabilitiesManager* capabilitiesManager();
+
+ /**
+ * Returns the avatar manager.
+ * The avatar manager provides you information about the avatars of the connection.<br>
+ * <br>
+ * <b>Note:</b>
+ * <ul><li>You have to request a connection with requestConnect() before an avatar manager can be returned.</li>
+ * <li>You have to call this function in order to get your contacts updated automatically.</li>
+ * </ul>
+ * @return Pointer to the avatar manager or NULL if no avatar support is available or no connection was requested.
+ * @see requestConnect()
+ */
+ AvatarManager* avatarManager();
+
+ /**
+ * Returns the account for this connection.
+ * Every connection belongs to an account that is returned with this call.
+ * @return The account for this connection or NULL if no valid account exists.
+ */
+ Account* account() const;
+
+signals:
+ /**
+ * Connection status changed.
+ * This signal is emitted if the status of the connection was changed
+ * @param connection The connection which changes its status.
+ * @param newStatus The new status that is valid now.
+ * @param oldStatus The old status that was valid before.
+ * @see Telepathy::ConnectionStatus
+ */
+ void signalStatusChanged( TpPrototype::Connection* connection,
+ Telepathy::ConnectionStatus newStatus,
+ Telepathy::ConnectionStatus oldStatus );
+
+protected slots:
+ void slotStatusChanged( uint status, uint reason );
+ void slotNewChannel( const QDBusObjectPath& objectPath, const QString& channelType, uint handleType, uint handle, bool suppressHandler );
+
+protected:
+ /**
+ * Constructor.
+ * The connection cannot be instantiated directly. Use Account::connection() to receive a valid connection object.
+ * @param account Account to create connection with.
+ */
+ Connection( TpPrototype::Account* account, QObject* parent );
+
+ /**
+ * Returns the handle.
+ * The handle is an internal representation to access the real data. Its format should
+ * not be interpreted.
+ */
+ QString handle() const;
+
+ /**
+ * D-BUS interface.
+ * This protected access to the D-BUS interface can be used to extend this class with special features.
+ */
+ Telepathy::Client::ConnectionInterface* interface();
+
+ /**
+ * Provides a generic handle.
+ * @param handleType The type of handle required.
+ * @param handlestrings An array of names of entities to request handles for
+ * @return An array of integer handle numbers in the same order as the given strings
+ */
+ QList<uint> RequestHandles( Telepathy::HandleType handletype, QStringList& handlestrings);
+
+ /**
+ * Check if manager is supported.
+ */
+ bool managerSupported( const QString& managerName );
+
+ template <class Manager>
+ inline Manager* createManager( QPointer<Manager>& pManager, const QString& managerName )
+ {
+ if ( pManager && pManager->isValid() )
+ { return pManager; }
+
+ // Force to reinitialize an invalid manager
+ if ( pManager && !pManager->isValid() )
+ {
+ delete pManager;
+ pManager = NULL;
+ }
+
+ if ( status() != Telepathy::ConnectionStatusConnected )
+ { return NULL; }
+
+ pManager = new Manager( this, interface(), this );
+ Q_ASSERT( pManager );
+
+ if ( pManager->isValid() )
+ { return pManager; }
+
+ // Fall through: Cleanup if manager is not valid.
+ delete pManager;
+ pManager = NULL;
+ return NULL;
+ }
+
+
+private:
+ void init( TpPrototype::Account* account );
+ void startupInit();
+ ConnectionPrivate * const d;
+
+ friend class Account;
+};
+
+} // namespace
+
+#endif
diff --git a/TelepathyQt4/Prototype/ConnectionFacade.cpp b/TelepathyQt4/Prototype/ConnectionFacade.cpp
new file mode 100644
index 0000000..d4b8af0
--- /dev/null
+++ b/TelepathyQt4/Prototype/ConnectionFacade.cpp
@@ -0,0 +1,265 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/ConnectionFacade.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QPointer>
+
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/ConnectionManager>
+
+#include <TelepathyQt4/Prototype/Account.h>
+#include <TelepathyQt4/Prototype/AccountManager.h>
+#include <TelepathyQt4/Prototype/Connection.h>
+#include <TelepathyQt4/Prototype/DBusInterface.h>
+
+using namespace TpPrototype;
+
+ConnectionFacade* ConnectionFacade::m_instance = NULL;
+
+enum {
+ mgr_Param_Flag_Required = 1,
+ mgr_Param_Flag_Register = 2,
+ mgr_Param_Flag_Has_Default = 4,
+ mgr_Param_Flag_Secret = 8
+};
+
+
+class TpPrototype::ConnectionFacadePrivate
+{
+public:
+};
+
+ConnectionFacade* ConnectionFacade::instance()
+{
+ if ( NULL == m_instance )
+ {
+ m_instance = new ConnectionFacade( QCoreApplication::instance() );
+ }
+
+ return m_instance;
+}
+
+ConnectionFacade::ConnectionFacade( QObject* parent ):
+ QObject( parent ),
+ d( new ConnectionFacadePrivate )
+{
+}
+
+ConnectionFacade::~ConnectionFacade()
+{
+ delete d;
+}
+
+QStringList ConnectionFacade::listOfConnectionManagers()
+{
+ Telepathy::registerTypes();
+
+ QStringList ret_list;
+
+ DBusInterface* interface = new DBusInterface( NULL );
+
+ QDBusReply<QStringList> reply = interface->listActivatableNames();
+
+ delete interface;
+
+ if ( !reply.isValid() )
+ {
+ QDBusError error = reply.error();
+
+ qWarning() << "Disconnect: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return ret_list; // returns empty list
+ }
+
+
+ foreach( const QString& name, reply.value() )
+ {
+ // qDebug() << "+++Name: " << name;
+ if ( !name.startsWith( "org.freedesktop.Telepathy.ConnectionManager" )
+ || name.isEmpty() )
+ { continue; }
+
+ QString cm_name;
+ int pos_of_last_dot = name.lastIndexOf( "." );
+ Q_ASSERT( pos_of_last_dot >= 0 );
+ cm_name = name.right( name.length() - ( pos_of_last_dot + 1 ) );
+ ret_list << cm_name;
+ }
+
+ // qDebug() << "+++Names found: " << ret_list;
+ return ret_list;
+}
+
+QStringList ConnectionFacade::listOfProtocolsForConnectionManager( const QString& connectionManager )
+{
+ Telepathy::registerTypes();
+
+ QStringList empty_list;
+
+ QStringList list_of_connection_managers = listOfConnectionManagers();
+ if ( !list_of_connection_managers.contains( connectionManager ) )
+ { return empty_list; } // return empty list
+
+ Telepathy::Client::ConnectionManagerInterface connection_manager_interface( "org.freedesktop.Telepathy.ConnectionManager." + connectionManager,
+ "/org/freedesktop/Telepathy/ConnectionManager/" + connectionManager );
+
+ QDBusPendingReply<QStringList> list_protocols_reply = connection_manager_interface.ListProtocols();
+ list_protocols_reply.waitForFinished();
+
+ if ( !list_protocols_reply.isValid() )
+ {
+ QDBusError error = list_protocols_reply.error();
+
+ qWarning() << "ListProtocols: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return empty_list; // returns empty list
+ }
+
+ return list_protocols_reply.value();
+}
+
+// TODO: Return the parameter list with all flags as we receive it from telepathy. This solution hides the flags and is unable
+// to handle all required types..
+Telepathy::ParamSpecList ConnectionFacade::paramSpecListForConnectionManagerAndProtocol( const QString& connectionManager, const QString& protocol )
+{
+ Telepathy::registerTypes();
+
+ Telepathy::Client::ConnectionManagerInterface connection_manager_interface( "org.freedesktop.Telepathy.ConnectionManager." + connectionManager,
+ "/org/freedesktop/Telepathy/ConnectionManager/" + connectionManager );
+
+ QDBusPendingReply<Telepathy::ParamSpecList> get_parameters_reply = connection_manager_interface.GetParameters( protocol );
+ get_parameters_reply.waitForFinished();
+
+ if ( !get_parameters_reply.isValid() )
+ {
+ QDBusError error = get_parameters_reply.error();
+
+ qWarning() << "ListProtocols: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return Telepathy::ParamSpecList() ; // returns empty list
+ }
+
+ Telepathy::ParamSpecList param_spec_list = get_parameters_reply.value();
+
+ return param_spec_list;
+}
+
+QVariantMap ConnectionFacade::parameterListForConnectionManagerAndProtocol( const QString& connectionManager, const QString& protocol )
+{
+ QVariantMap ret_map;
+
+ foreach( const Telepathy::ParamSpec& item, paramSpecListForConnectionManagerAndProtocol(connectionManager, protocol) )
+ {
+ ret_map.insert( item.name, item.defaultValue.variant() );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "item: " << item.name << "flag:" << item.flags;
+#endif
+ if ( ( item.flags & ( mgr_Param_Flag_Required | mgr_Param_Flag_Register ) )
+ && item.defaultValue.variant().toString().isEmpty() )
+ {
+
+ if ( item.defaultValue.variant().type() == QVariant::String )
+ {
+ ret_map.insert( item.name, QVariant("required") );
+ }
+ }
+ }
+
+ return ret_map;
+}
+
+QVariantMap ConnectionFacade::parameterListForProtocol( const QString& protocol, int account_number )
+{
+ Telepathy::registerTypes();
+
+ QVariantMap ret_map;
+
+ if (account_number==1)
+ {
+ ret_map.insert( "account", "basyskom at localhost" );
+ }
+ else if (account_number==2)
+ {
+ ret_map.insert( "account", "test at localhost" );
+ }
+ ret_map.insert( "password", "basyskom" );
+ ret_map.insert( "server", "localhost" );
+ ret_map.insert( "resource", "Telepathy" );
+ ret_map.insert( "port", static_cast<uint>(5222) );
+ return ret_map;
+}
+
+// account_number is used for test purposes only we have to delte this later
+TpPrototype::Connection* ConnectionFacade::connectionWithAccount( Account* account, int account_number )
+{
+ Telepathy::registerTypes();
+
+ if ( !account )
+ { return NULL; }
+
+ account->setParameters( parameterListForProtocol( "jabber", account_number ) );
+
+ // Get the default connection manager. "Default" is currently only the first one in the list of possible connection managers
+ QStringList connection_managers = listOfConnectionManagers();
+ Q_ASSERT( connection_managers.count() );
+ if ( !connection_managers.count() )
+ { return NULL; }
+
+ return account->connection();
+}
+
+int ConnectionFacade::selfHandleForConnectionInterface( Telepathy::Client::ConnectionInterface* connectionInterface )
+{
+ if ( !connectionInterface )
+ {
+ return -1;
+ }
+
+ QDBusPendingReply<uint> local_handle_reply = connectionInterface->GetSelfHandle();
+ local_handle_reply.waitForFinished();
+
+ if ( !local_handle_reply.isValid() )
+ {
+ QDBusError error = local_handle_reply.error();
+
+ qWarning() << "GetSelfHandle: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return -1;
+ }
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "****Self handle:" << local_handle_reply.value();
+#endif
+
+ return local_handle_reply.value();
+}
+
diff --git a/TelepathyQt4/Prototype/ConnectionFacade.h b/TelepathyQt4/Prototype/ConnectionFacade.h
new file mode 100644
index 0000000..4dbf1ed
--- /dev/null
+++ b/TelepathyQt4/Prototype/ConnectionFacade.h
@@ -0,0 +1,137 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef ConnectionFacade_H_
+#define ConnectionFacade_H_
+
+#include <QObject>
+#include <QStringList>
+#include <QVariantMap>
+
+#include <TelepathyQt4/Types>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+namespace TpPrototype
+{
+
+/**
+ * @defgroup qt_style_api Qt-Style Client API
+ * This API provides a high level client side API that enables developer to access to Telepathy on a high level of abstraction.
+ * These classes encapsulate all the D-Bus communication, error handling and Telepathy-Channel handling.
+ */
+
+/**
+ * @defgroup qt_convenience Convenience Classes
+ * @ingroup qt_style_api
+ * Classes that provide functions that are needed for various tasks.
+ */
+
+class ConnectionFacadePrivate;
+class Connection;
+class Account;
+
+/**
+ * @ingroup qt_convenience
+ * Class to access to Telepathy and Mission control services. This class is used to encapsulate the low level D-BUS Interface
+ * to Telepathy and MissionControl. It provides a series of helper functions.<br>
+ * This class follows the <i>facade</i> pattern.
+ * @todo Move as much functions as possible into adequate classes.
+ */
+class ConnectionFacade: public QObject
+{
+ Q_OBJECT
+public:
+ static ConnectionFacade* instance();
+ /**
+ * Returns a list of all connection managers registered.
+ * @return List of connection manager names.
+ */
+ QStringList listOfConnectionManagers();
+
+ /**
+ * Returns a list of supported protocols of a connection manager.
+ * @return List of supported protocols.
+ */
+ QStringList listOfProtocolsForConnectionManager( const QString& connectionManager );
+
+ /**
+ * Returns a Telepathy::ParamSpecList from the given protocol an connection manager.
+ * @param connectionManager The connection manager for the protocol.
+ * @param protocol Name of the protocol that is supported by the connection manager.
+ * @return A map with all supported parameters with default values.
+ */
+ Telepathy::ParamSpecList paramSpecListForConnectionManagerAndProtocol( const QString& connectionManager, const QString& protocol );
+
+ /**
+ * Returns a list of parameters for the given protocol and connection manager.
+ * @param connectionManager The connection manager for the protocol.
+ * @param protocol Name of the protocol that is supported by the connection manager.
+ * @return A map with all supported parameters with default values.
+ */
+ QVariantMap parameterListForConnectionManagerAndProtocol( const QString& connectionManager, const QString& protocol );
+
+ /**
+ * Returns a list of parameters for the given protocol.
+ * @deprecated Use parameterListForConnectionManagerAndProtocol() instead!
+ * @param protocol Name of the protocol.
+ * @return A map with all supported parameters with default values.
+ */
+ QVariantMap parameterListForProtocol( const QString& protocol, int account_number=1 ) ATTRIBUTE_DEPRECATED;
+
+ /**
+ * Connects to account. Connects an account to a service using the default connection manager.
+ * @deprecated Use <i>Account::connection()</i> instead!
+ * @param account The account to use.
+ * @return A connection. A null pointer is returned if the connection was <i>not</i> successful.
+ */
+ TpPrototype::Connection* connectionWithAccount( Account* account, int account_number=1 ) ATTRIBUTE_DEPRECATED;
+
+ /**
+ * Returns the self handle. The self handle is needed by various interfaces to request information about myself
+ * @todo: This is more or less a local function and should not be part of a public API. But I don't have a better place right now!
+ * @return The local handle is usually 1 but may change on demand. -1 is returned on error.
+ */
+ int selfHandleForConnectionInterface( Telepathy::Client::ConnectionInterface* connectionInterface );
+
+private:
+ ConnectionFacade( QObject* parent );
+ ~ConnectionFacade();
+
+ ConnectionFacadePrivate * const d;
+ static ConnectionFacade* m_instance;
+};
+
+}
+#endif // ConnectionFacade_H_
+
diff --git a/TelepathyQt4/Prototype/Constants b/TelepathyQt4/Prototype/Constants
new file mode 100644
index 0000000..3cc33f9
--- /dev/null
+++ b/TelepathyQt4/Prototype/Constants
@@ -0,0 +1,6 @@
+#ifndef _TelepathyQt4_Prototype_Constants_HEADER_GUARD_
+#define _TelepathyQt4_Prototype_Constants_HEADER_GUARD_
+
+#include <TelepathyQt4/Prototype/constants.h>
+
+#endif
diff --git a/TelepathyQt4/Prototype/Contact.cpp b/TelepathyQt4/Prototype/Contact.cpp
new file mode 100644
index 0000000..c1ec2b8
--- /dev/null
+++ b/TelepathyQt4/Prototype/Contact.cpp
@@ -0,0 +1,189 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/Contact.h"
+
+#include <QDebug>
+#include <QMetaProperty>
+
+#include <TelepathyQt4/Client/Channel>
+#include <TelepathyQt4/Constants>
+
+#include <TelepathyQt4/Prototype/ChatChannel.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+#include <TelepathyQt4/Prototype/StreamedMediaChannel.h>
+
+using namespace TpPrototype;
+
+class TpPrototype::ContactPrivate
+{
+public:
+ ContactPrivate( const uint & handle, const QString & name, Contact::ContactTypes type,
+ Telepathy::Client::ConnectionInterface* connectionInterface, TpPrototype::ContactManager* contactManager )
+ { init(handle, name, type, connectionInterface, contactManager); }
+ ~ContactPrivate()
+ {}
+ uint m_handle;
+ bool m_isValid;
+ bool m_isPresenceInitialized;
+ Contact::ContactTypes m_type;
+ QString m_name;
+ uint m_presenceType;
+ QString m_presenceStatus;
+ QString m_presenceMessage;
+ Telepathy::ContactCapabilityList m_capabilityList;
+ TpPrototype::AvatarManager::Avatar m_avatar;
+ Telepathy::Client::ConnectionInterface* m_pConnectionInterface;
+ QPointer<TpPrototype::ChatChannel> m_pChatChannel;
+ QPointer<TpPrototype::StreamedMediaChannel> m_pStreamedMediaChannel;
+ QPointer<TpPrototype::ContactManager> m_pContactManager;
+
+private:
+ void init( uint handle, const QString & name, Contact::ContactTypes type,
+ Telepathy::Client::ConnectionInterface* connectionInterface, TpPrototype::ContactManager* contactManager )
+ {
+ Q_ASSERT( connectionInterface );
+ Q_ASSERT( contactManager );
+
+ m_handle = handle;
+ m_name = name;
+ m_type = type;
+ m_presenceType = 0;
+ m_presenceStatus = "unknown";
+ m_presenceMessage = "";
+ m_pChatChannel = NULL;
+ m_pStreamedMediaChannel = NULL;
+ m_pConnectionInterface = connectionInterface;
+ m_pContactManager = contactManager;
+ m_isPresenceInitialized = false;
+
+ if ( 0 == m_handle )
+ m_isValid = false;
+ else
+ m_isValid = true;
+ }
+};
+
+uint Contact::telepathyHandle() const
+{ return d->m_handle; }
+
+uint Contact::telepathyHandleType() const
+{ return Telepathy::HandleTypeContact; }
+
+QString Contact::name() const
+{ return d->m_name; }
+
+Contact::ContactTypes Contact::type() const
+{ return d->m_type; }
+
+void Contact::setType( ContactTypes type )
+{
+ d->m_type = type;
+}
+
+bool Contact::isValid() const
+{ return d->m_isValid; }
+
+void Contact::setPresenceType( uint _presenceType)
+{ d->m_presenceType=_presenceType; }
+
+uint Contact::presenceType()
+{
+ d->m_isPresenceInitialized = true;
+ return d->m_presenceType;
+}
+
+void Contact::setPresenceStatus( QString _presenceStatus)
+{
+ d->m_isPresenceInitialized = true;
+ d->m_presenceStatus=_presenceStatus;
+}
+
+QString Contact::presenceStatus()
+{ return d->m_presenceStatus; }
+
+bool Contact::isPresenceStateAvailable()
+{ return d->m_isPresenceInitialized; }
+
+void Contact::setPresenceMessage( QString _presenceMessage)
+{ d->m_presenceMessage=_presenceMessage; }
+
+QString Contact::presenceMessage()
+{ return d->m_presenceMessage; }
+
+void Contact::setCapabilities( const Telepathy::ContactCapabilityList& capabilityList )
+{ d->m_capabilityList = capabilityList; }
+
+Telepathy::ContactCapabilityList Contact::capabilities() const
+{ return d->m_capabilityList; }
+
+void Contact::setAvatar( const TpPrototype::AvatarManager::Avatar& avatar )
+{
+ d->m_avatar = avatar;
+}
+
+Telepathy::Client::ConnectionInterface* Contact::interface()
+{
+ return d->m_pConnectionInterface;
+}
+
+TpPrototype::AvatarManager::Avatar Contact::avatar() const
+{
+ return d->m_avatar;
+}
+
+ChatChannel* Contact::chatChannel()
+{
+ if ( !d->m_pChatChannel )
+ {
+ d->m_pChatChannel = new ChatChannel( this, d->m_pConnectionInterface, this );
+ Q_ASSERT( d->m_pChatChannel->isValid() );
+ }
+ return d->m_pChatChannel;
+}
+
+TpPrototype::StreamedMediaChannel* Contact::streamedMediaChannel()
+{
+ if ( !d->m_pStreamedMediaChannel )
+ {
+ d->m_pStreamedMediaChannel = new StreamedMediaChannel( this, d->m_pConnectionInterface, this );
+ Q_ASSERT( d->m_pStreamedMediaChannel->isValid() );
+ }
+ return d->m_pStreamedMediaChannel;
+
+}
+
+TpPrototype::ContactManager* Contact::contactManager()
+{
+ return d->m_pContactManager;
+}
+
+
+Contact::Contact( const uint & handle, const QString & url, ContactTypes type,
+ Telepathy::Client::ConnectionInterface* connectionInterface, TpPrototype::ContactManager* contactManager ) :
+ QObject( contactManager ),
+ d( new ContactPrivate( handle, url, type, connectionInterface, contactManager ) )
+{
+}
+
+Contact::~Contact()
+{ delete d; }
diff --git a/TelepathyQt4/Prototype/Contact.h b/TelepathyQt4/Prototype/Contact.h
new file mode 100644
index 0000000..3dc9bab
--- /dev/null
+++ b/TelepathyQt4/Prototype/Contact.h
@@ -0,0 +1,247 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_Contact_H_
+#define TelepathyQt4_Prototype_Contact_H_
+
+#include <QObject>
+#include <QPointer>
+#include <QVariantMap>
+
+#include <TelepathyQt4/Client/Channel>
+
+#include <TelepathyQt4/Prototype/AvatarManager.h>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+namespace TpPrototype {
+
+class ContactPrivate;
+class ContactManager;
+class ChatChannel;
+class StreamedMediaChannel;
+
+/**
+ * This class handles information related to a contact.
+ * Contact objects are always owned by ContactManager. Therefore, there is no way to create or remove a contact without using the ContactManager object.<br>
+ * Other Managers (like PresenceManager, AvatarManager) are accessing the contacts inside of the contact manager to update its information.
+ * Whether a contact was updated is signalled by the Managers but the new information is stored in the contact object and can be retrieved from it.
+ * @ingroup qt_connection
+ * @ingroup qt_contact
+ * @todo Do not provide a function for every presence parameter. Use SimplePresence instead.
+ * @todo Use implicit sharing instead of expolicit sharig!
+ * @see CapabilitiesManager, AvatarManager, PresenceManager
+ */
+class Contact : public QObject
+{
+ Q_OBJECT
+public:
+ enum ContactTypes
+ {
+ CT_Subscribed = 0,
+ CT_LocalPending,
+ CT_RemotePending,
+ CT_Removed,
+ CT_Known,
+ CT_Blocked
+ };
+
+ /**
+ * Validity.
+ * Do not access any method if this function returns false.
+ */
+ bool isValid() const;
+
+ /**
+ * Returns the contact type.
+ * @return The contact type.
+ */
+ ContactTypes type() const;
+
+ /**
+ * Set type.
+ * @param type The new type
+ * @see ContactTypes
+ */
+ void setType( ContactTypes type );
+
+ /**
+ * Returns the telepathy internal handle.
+ * @return The telepathy internal handle.
+ */
+ uint telepathyHandle() const;
+
+ /**
+ * Returns the telepathy internal handle type.
+ * @return The telepathy internal handle type.
+ */
+ uint telepathyHandleType() const;
+
+ /**
+ * Returns the name of the contact.
+ * @return The name of the contact as it is used by protocol (E.g. user at jabber.org).
+ * @todo Make this private. We need an encapsulation for </i>PresenceManager::presencesForContacts()</i> first. (ses)
+ * THUN: Stefan, this is not possible as this information is required to work with all telepathy classes
+ * unknown to this lib.
+ */
+ QString name() const;
+
+ /**
+ * Returns the presence information of this contact.
+ * This presence information is automatically updated after the presence information was requested for the first time (PresenceManager::presencesForContacts()).<br>
+ * <b>Note:</b> Use <i>isPresenceStateAvailable()</i> to check whether the returned presence is valid!
+ * @todo Implement this!
+ * @see PresenceManager
+ */
+ Telepathy::SimplePresence presence() { return Telepathy::SimplePresence(); /* TODO: Implement me ! */ };
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ * @deprecated Use <i>presence()</i> instead.
+ *
+ */
+ uint presenceType() ATTRIBUTE_DEPRECATED;
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ * @deprecated Use <i>presence()</i> instead.
+ *
+ */
+ QString presenceStatus() ATTRIBUTE_DEPRECATED;
+
+ /**
+ * Returns whether there is any presence information available.
+ * This functionreturns <i>false</i> if there is no valid presence information available.
+ * @return <i>true</i> if valid resence information is available. Otherwise <i>false</i> is returned.
+ */
+ bool isPresenceStateAvailable();
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ * @deprecated Use <i>presence()</i> instead.
+ *
+ */
+ QString presenceMessage() ATTRIBUTE_DEPRECATED;
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ *
+ */
+ Telepathy::ContactCapabilityList capabilities() const;
+
+
+ /**
+ * Get Avatar for this contact.
+ * This function does not return valid information after the avatar was not requested by avatarForContactList()
+ * @see AvatarManager
+ */
+ TpPrototype::AvatarManager::Avatar avatar() const;
+
+ /**
+ * Get chat channel for this contact.
+ * This function provides the chat channel object for this contact. It contains all information to do a text chat
+ * @return The channel object.
+ */
+ TpPrototype::ChatChannel* chatChannel();
+
+ /**
+ * Get channel for media streaming.
+ * This function returns the media streaming object for this contact. It contains all information and functions for VoIP and Video Over IP communication.
+ */
+ TpPrototype::StreamedMediaChannel* streamedMediaChannel();
+
+ /**
+ * Get the contact manager where this object is stored.
+ * @return The contact manager that owns this object.
+ */
+ TpPrototype::ContactManager* contactManager();
+
+protected:
+ /**
+ * Contstuctor.
+ * This object is never created directly. Use ContactManager to create or request a contact.
+ * @see ContactManager
+ */
+ Contact( const uint & handle, const QString & name, ContactTypes type, Telepathy::Client::ConnectionInterface* connectionInterface, TpPrototype::ContactManager* contactManager );
+
+ ~Contact();
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ */
+ void setPresenceType( uint _presenceType);
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ */
+ void setPresenceStatus( QString _presenceStatus);
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ */
+ void setPresenceMessage( QString _presenceMessage);
+
+ /**
+ * @todo: Add Doc and get/setr in presence manager
+ */
+ void setCapabilities( const Telepathy::ContactCapabilityList& capabilityList );
+
+ /**
+ * Set the avatar.
+ * This avatar is set by the AvatarManager.
+ *
+ */
+ void setAvatar( const TpPrototype::AvatarManager::Avatar& avatar );
+
+ /**
+ * D-BUS interface.
+ * This protected access to the D-BUS interface can be used to extend this class with special features.
+ */
+ Telepathy::Client::ConnectionInterface* interface();
+
+
+private:
+ ContactPrivate * const d;
+
+ friend class ContactManager;
+ friend class AvatarManager;
+ friend class PresenceManager;
+ friend class CapabilitiesManager;
+};
+
+} // namespace
+
+// Q_DECLARE_METATYPE( TpPrototype::Contact )
+
+#endif // Header guard
diff --git a/TelepathyQt4/Prototype/ContactManager.cpp b/TelepathyQt4/Prototype/ContactManager.cpp
new file mode 100644
index 0000000..61f76f3
--- /dev/null
+++ b/TelepathyQt4/Prototype/ContactManager.cpp
@@ -0,0 +1,965 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/ContactManager.h"
+
+#include <time.h>
+
+#include <QCoreApplication>
+#include <QDBusPendingReply>
+#include <QDBusObjectPath>
+#include <QDebug>
+#include <QHash>
+#include <QPointer>
+#include <QString>
+
+#include <TelepathyQt4/Client/Channel>
+
+#include <TelepathyQt4/Prototype/ChatChannel.h>
+#include <TelepathyQt4/Prototype/ConnectionFacade.h>
+#include <TelepathyQt4/Prototype/Contact.h>
+#include <TelepathyQt4/Prototype/StreamedMediaChannel.h>
+
+//#define ENABLE_DEBUG_OUTPUT_
+
+using namespace TpPrototype;
+
+class TpPrototype::ContactManagerPrivate
+{
+public:
+ ContactManagerPrivate()
+ { init(); }
+
+ ~ContactManagerPrivate()
+ { }
+
+ Telepathy::Client::ConnectionInterface* m_pInterface;
+ Telepathy::Client::ChannelInterfaceGroupInterface* m_groupSubscribedChannel;
+ Telepathy::Client::ChannelInterfaceGroupInterface* m_groupKnownChannel;
+ Telepathy::Client::ChannelInterfaceGroupInterface* m_groupPublishedChannel;
+ Telepathy::Client::ChannelTypeTextInterface* m_groupTextChannel;
+
+ QHash<uint, QPointer<Contact> > m_members;
+ QHash<uint, QPointer<Contact> > m_subscribed;
+ QHash<uint, QPointer<Contact> > m_localPending;
+ QHash<uint, QPointer<Contact> > m_remotePending;
+ QHash<uint, QPointer<Contact> > m_known;
+
+ bool m_isValid;
+
+ void init()
+ {
+ m_pInterface = NULL;
+ m_groupSubscribedChannel = NULL;
+ m_groupKnownChannel = NULL;
+ m_groupPublishedChannel = NULL;
+ m_groupTextChannel = NULL; //leave this temporaryly here push it later to contact
+ m_isValid = false;
+ }
+
+ QList<uint> SubscribedHandlesToLookUp(const Telepathy::UIntList& handles)
+ {
+ QList<uint> subscribed_to_look_up;
+ foreach(uint handle, handles)
+ {
+ if (!m_subscribed.contains(handle) )
+ subscribed_to_look_up.append(handle);
+ }
+ return subscribed_to_look_up;
+ }
+
+ QList<uint> KnownHandlesToLookUp(const Telepathy::UIntList& handles)
+ {
+ QList<uint> known_to_look_up;
+ foreach(uint handle, handles)
+ {
+ if (!m_members.contains(handle) )
+ known_to_look_up.append(handle);
+ }
+ return known_to_look_up;
+ }
+ QList<uint> RemovedHandlesToLookUp(const Telepathy::UIntList& handles)
+ {
+ QList<uint> removed_to_look_up;
+ foreach(uint handle, handles)
+ {
+ if (m_members.contains(handle) )
+ removed_to_look_up.append(handle);
+ }
+ return removed_to_look_up;
+ }
+
+ QList<uint> LocalPendingHandlesToLookUp(const Telepathy::UIntList& handles)
+ {
+ QList<uint> localpending_to_look_up;
+ foreach(uint handle, handles)
+ {
+ if (!m_localPending.contains(handle))
+ localpending_to_look_up.append(handle);
+ }
+ return localpending_to_look_up;
+ }
+
+ QList<uint> RemotePendingHandlesToLookUp(const Telepathy::UIntList& handles)
+ {
+ QList<uint> remotepending_to_look_up;
+ foreach(uint handle, handles)
+ {
+ if (!m_remotePending.contains(handle))
+ remotepending_to_look_up.append(handle);
+
+ }
+ return remotepending_to_look_up;
+ }
+
+ QList<QPointer<TpPrototype::Contact> > mapHashToList( QHash<uint, QPointer<Contact> > hash )
+ {
+ QList<QPointer<TpPrototype::Contact> > ret_list;
+
+ foreach( const QPointer<TpPrototype::Contact>& contact, hash )
+ {
+ // Filter possilble null pointers
+ if ( NULL == contact )
+ { continue; }
+
+ ret_list.append( contact );
+ }
+
+ return ret_list;
+ }
+
+};
+
+ContactManager::ContactManager( Telepathy::Client::ConnectionInterface* connection,
+ QObject* parent ):
+ QObject( parent ),
+ d( new ContactManagerPrivate )
+{
+ init( connection );
+}
+
+ContactManager::~ContactManager()
+{
+ // Delete this here as we are a friend of contact.
+ foreach (QPointer<Contact> current_contact, d->m_members)
+ { delete current_contact; }
+ foreach (QPointer<Contact> current_contact, d->m_subscribed)
+ { delete current_contact; }
+ foreach (QPointer<Contact> current_contact, d->m_localPending)
+ { delete current_contact; }
+ foreach (QPointer<Contact> current_contact, d->m_remotePending)
+ { delete current_contact; }
+
+ delete d;
+}
+
+int ContactManager::count()
+{ return d->m_members.size(); }
+
+bool ContactManager::isValid()
+{ return d->m_isValid; }
+
+QList<QPointer<Contact> > ContactManager::contactList()
+{ return d->m_members.values(); }
+
+QList<QPointer<Contact> > ContactManager::toAuthorizeList()
+{ return d->m_localPending.values();}
+
+QList<QPointer<Contact> > ContactManager::remoteAuthorizationPendingList()
+{ return d->m_remotePending.values();}
+
+
+void ContactManager::init( Telepathy::Client::ConnectionInterface* connection )
+{
+ Q_ASSERT(0 != connection);
+ Telepathy::registerTypes();
+ d->m_pInterface = connection;
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager up and running... waiting for signals.";
+#endif//
+ d->m_isValid = true;
+}
+
+bool ContactManager::requestContact( const QString& id )
+{
+ QStringList contact_ids;
+ contact_ids.append(id);
+
+ QList<uint> contact_handles=d->m_pInterface->RequestHandles( Telepathy::HandleTypeContact,contact_ids);
+ if (!contact_handles.empty())
+ {
+ if ( d->m_groupSubscribedChannel)
+ d->m_groupSubscribedChannel->AddMembers(contact_handles,"Contact Request");
+ return true;
+ }
+ return false;
+}
+
+bool ContactManager::authorizeContact( const Contact* contact )
+{
+ if ( !contact )
+ { return false; }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager Try to authorize a contact";
+#endif
+ QList<uint> toauthorizelist;
+ toauthorizelist.append(contact->telepathyHandle());
+ if ( d->m_groupPublishedChannel)
+ d->m_groupPublishedChannel->AddMembers(toauthorizelist,"Add");
+ return true;
+}
+
+
+bool ContactManager::removeContact( const Contact* contact_toremove )
+{
+ if ( !contact_toremove )
+ { return false; }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager Try to remove a contact";
+#endif
+ QList<uint> toremovelist;
+ toremovelist.append(contact_toremove->telepathyHandle());
+ d->m_members.remove(contact_toremove->telepathyHandle());
+ d->m_subscribed.remove(contact_toremove->telepathyHandle());
+ d->m_remotePending.remove(contact_toremove->telepathyHandle());
+ d->m_localPending.remove(contact_toremove->telepathyHandle());
+ d->m_known.remove(contact_toremove->telepathyHandle());
+ if ( d->m_groupSubscribedChannel)
+ d->m_groupSubscribedChannel->RemoveMembers(toremovelist,"Remove");
+ if ( d->m_groupPublishedChannel)
+ d->m_groupPublishedChannel->RemoveMembers(toremovelist,"Remove");
+ if ( d->m_groupKnownChannel)
+ d->m_groupKnownChannel->RemoveMembers(toremovelist,"Remove");
+
+ delete contact_toremove;
+
+ return true;
+}
+
+QPointer<TpPrototype::Contact> ContactManager::contactForHandle( uint handle )
+{
+ return d->m_members.value( handle );
+}
+
+uint ContactManager::localHandle()
+{
+ return ConnectionFacade::instance()->selfHandleForConnectionInterface( d->m_pInterface );
+}
+
+
+/*
+ inline QDBusPendingReply<> AcknowledgePendingMessages(const Telepathy::UIntList& IDs)
+{
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(IDs);
+ return asyncCallWithArgumentList(QLatin1String("AcknowledgePendingMessages"), argumentList);
+}
+
+ inline QDBusPendingReply<Telepathy::UIntList> GetMessageTypes()
+{
+ return asyncCall(QLatin1String("GetMessageTypes"));
+}
+
+*/
+
+
+void ContactManager::openSubscribedContactsChannel(uint handle, const QDBusObjectPath& channelPath, const QString& channelType)
+{
+ Telepathy::registerTypes();
+
+ QString channel_service_name(d->m_pInterface->service());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager Channel Services Name" << channel_service_name;
+ qDebug() << "ContactManager Channel Path" << channelPath.path();
+#endif
+ // This channel may never be closed!
+ d->m_groupSubscribedChannel = new Telepathy::Client::ChannelInterfaceGroupInterface(channel_service_name,channelPath.path(),
+ this);
+ if (!d->m_groupSubscribedChannel->isValid())
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Failed to connect Group channel interface class to D-Bus object.";
+#endif
+ delete d->m_groupSubscribedChannel;
+ d->m_groupSubscribedChannel = 0;
+ return;
+ }
+ QDBusPendingReply<Telepathy::UIntList, Telepathy::UIntList, Telepathy::UIntList> reply2=d->m_groupSubscribedChannel->GetAllMembers();
+ reply2.waitForFinished();
+
+ const Telepathy::UIntList mlist1= QList< quint32 > (reply2.argumentAt<0>());
+ const Telepathy::UIntList mlist2;
+ const Telepathy::UIntList mlist3= QList< quint32 > (reply2.argumentAt<1>());
+ const Telepathy::UIntList mlist4= QList< quint32 > (reply2.argumentAt<2>());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Number of current members" << mlist1.size();
+ qDebug() << "Number of local pending members" << mlist2.size();
+ qDebug() << "Number of remote pending members" << mlist3.size();
+#endif
+ if (( mlist1.size()>0) || ( mlist3.size()>0) || ( mlist4.size()>0))
+ slotSubscribedMembersChanged("",
+ mlist1,
+ mlist2,
+ mlist3,
+ mlist4,
+ 0, 0);
+
+ // All lists are empty when the channel is created, so it suffices to connect
+ // the MembersChanged signal.
+ connect(d->m_groupSubscribedChannel, SIGNAL(MembersChanged(const QString&,
+ const Telepathy::UIntList&, // added to members list
+ const Telepathy::UIntList&, // removed from members list
+ const Telepathy::UIntList&, // local pending list
+ const Telepathy::UIntList&, // remote pending list
+ uint, uint)),
+ this, SLOT(slotSubscribedMembersChanged(const QString&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ uint, uint)));
+
+}
+
+void ContactManager::openKnownContactsChannel(uint handle, const QDBusObjectPath& channelPath, const QString& channelType)
+{
+ Telepathy::registerTypes();
+
+ QString channel_service_name(d->m_pInterface->service());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager Channel Services Name" << channel_service_name;
+ qDebug() << "ContactManager Channel Path" << channelPath.path();
+#endif
+ // This channel may never be closed!
+ d->m_groupKnownChannel = new Telepathy::Client::ChannelInterfaceGroupInterface(channel_service_name,channelPath.path(),
+ this);
+ if (!d->m_groupKnownChannel->isValid())
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Failed to connect Group channel interface class to D-Bus object.";
+#endif
+ delete d->m_groupKnownChannel;
+ d->m_groupKnownChannel = 0;
+ return;
+ }
+ QDBusPendingReply<Telepathy::UIntList, Telepathy::UIntList, Telepathy::UIntList> reply2=d->m_groupKnownChannel->GetAllMembers();
+ reply2.waitForFinished();
+
+ const Telepathy::UIntList mlist1= QList< quint32 > (reply2.argumentAt<0>());
+ const Telepathy::UIntList mlist2;
+ const Telepathy::UIntList mlist3= QList< quint32 > (reply2.argumentAt<1>());
+ const Telepathy::UIntList mlist4= QList< quint32 > (reply2.argumentAt<2>());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Number of current members" << mlist1.size();
+ qDebug() << "Number of local pending members" << mlist2.size();
+ qDebug() << "Number of remote pending members" << mlist3.size();
+#endif
+ if (( mlist1.size()>0) || ( mlist3.size()>0) || ( mlist4.size()>0))
+ slotKnownMembersChanged("",
+ mlist1,
+ mlist2,
+ mlist3,
+ mlist4,
+ 0, 0);
+
+ // qDebug() << "Number of current members" << mlist1.size();
+ // qDebug() << "Number of local pending members" << mlist2.size();
+ // qDebug() << "Number of remote pending members" << mlist3.size();
+
+ // All lists are empty when the channel is created, so it suffices to connect
+ // the MembersChanged signal.
+ connect(d->m_groupKnownChannel, SIGNAL(MembersChanged(const QString&,
+ const Telepathy::UIntList&, // added to members list
+ const Telepathy::UIntList&, // removed from members list
+ const Telepathy::UIntList&, // local pending list
+ const Telepathy::UIntList&, // remote pending list
+ uint, uint)),
+ this, SLOT(slotKnownMembersChanged(const QString&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ uint, uint)));
+
+}
+
+void ContactManager::openTextChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelTyp )
+{
+ Contact* contact = d->m_members.value( handle );
+
+ if ( !contact )
+ {
+ qWarning() << "ContactManager::openTextChannel: Tried to open a text channel but there was no receiving contact found!";
+ return;
+ }
+ if ( !contact->chatChannel() )
+ {
+ qWarning() << "ContactManager::openTextChannel: Requesting a valid text channel object failed!";
+ return;
+ }
+
+ if ( contact && contact->chatChannel() )
+ {
+ contact->chatChannel()->openTextChannel( handle, handleType, channelPath, channelTyp );
+ emit signalTextChannelOpenedForContact( contact );
+ }
+}
+
+void ContactManager::openStreamedMediaChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelType )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager::openStreamedMediaChannel handle: " << handle
+ << "handleType:" << handleType
+ << "channelPath: " << channelPath
+ << "channelType: " << channelType;
+#endif
+
+ // Outbound calls have no handle and don't need to be handled here.
+ if ( handle == 0 )
+ { return; }
+
+
+ Contact* contact = d->m_members.value( handle );
+
+ if ( !contact )
+ {
+ qWarning() << "ContactManager::openStreamedMediaChannel: Tried to open a media stream channel but there was no receiving contact found!";
+ return;
+ }
+ if ( !contact->streamedMediaChannel() )
+ {
+ qWarning() << "ContactManager::openStreamedMediaChannel: Requesting a valid streamed media channel object failed!";
+ return;
+ }
+
+ if ( contact && contact->streamedMediaChannel() )
+ {
+ disconnect( contact->streamedMediaChannel(), SIGNAL( signalIncomingChannel( TpPrototype::Contact* ) ), this, 0 );
+ connect( contact->streamedMediaChannel(), SIGNAL( signalIncomingChannel( TpPrototype::Contact* ) ),
+ this, SIGNAL( signalStreamedMediaChannelOpenedForContact( TpPrototype::Contact* ) ) );
+ contact->streamedMediaChannel()->openStreamedMediaChannel( handle, handleType, channelPath, channelType );
+ }
+}
+
+void ContactManager::openPublishContactsChannel(uint handle, const QDBusObjectPath& channelPath, const QString& channelType)
+{
+ Telepathy::registerTypes();
+
+ QString channel_service_name(d->m_pInterface->service());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "ContactManager Channel Services Name" << channel_service_name;
+ qDebug() << "ContactManager Channel Path" << channelPath.path();
+#endif
+ // This channel may never be closed!
+ d->m_groupPublishedChannel = new Telepathy::Client::ChannelInterfaceGroupInterface(channel_service_name,channelPath.path(),
+ this);
+ if (!d->m_groupPublishedChannel->isValid())
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Failed to connect Group channel interface class to D-Bus object.";
+#endif
+ delete d->m_groupPublishedChannel;
+ d->m_groupPublishedChannel = 0;
+ return;
+ }
+ QDBusPendingReply<Telepathy::UIntList, Telepathy::UIntList, Telepathy::UIntList> reply2=d->m_groupPublishedChannel->GetAllMembers();
+ reply2.waitForFinished();
+
+ const Telepathy::UIntList mlist1= QList< quint32 > (reply2.argumentAt<0>());
+ const Telepathy::UIntList mlist2;
+ const Telepathy::UIntList mlist3= QList< quint32 > (reply2.argumentAt<1>());
+ const Telepathy::UIntList mlist4= QList< quint32 > (reply2.argumentAt<2>());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Number of current members" << mlist1.size();
+ qDebug() << "Number of local pending members" << mlist2.size();
+ qDebug() << "Number of remote pending members" << mlist3.size();
+#endif
+ if (( mlist1.size()>0) || ( mlist3.size()>0) || ( mlist4.size()>0))
+ slotPublishedMembersChanged("",
+ mlist1,
+ mlist2,
+ mlist3,
+ mlist4,
+ 0, 0);
+ // qDebug() << "Number of current members" << mlist1.size();
+ // qDebug() << "Number of local pending members" << mlist2.size();
+ // qDebug() << "Number of remote pending members" << mlist3.size();
+
+ // All lists are empty when the channel is created, so it suffices to connect
+ // the MembersChanged signal.
+ connect(d->m_groupPublishedChannel, SIGNAL(MembersChanged(const QString&,
+ const Telepathy::UIntList&, // added to members list
+ const Telepathy::UIntList&, // removed from members list
+ const Telepathy::UIntList&, // local pending list
+ const Telepathy::UIntList&, // remote pending list
+ uint, uint)),
+ this, SLOT(slotPublishedMembersChanged(const QString&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ const Telepathy::UIntList&,
+ uint, uint)));
+
+}
+
+
+
+void ContactManager::slotKnownMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason)
+{
+ slotMembersChanged("Known",
+ members_added,
+ members_removed,
+ local_pending,
+ remote_pending,
+ actor, reason);
+}
+void ContactManager::slotPublishedMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason)
+{
+ slotMembersChanged("Published",
+ members_added,
+ members_removed,
+ local_pending,
+ remote_pending,
+ actor, reason);
+}
+
+void ContactManager::slotSubscribedMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason)
+{
+ slotMembersChanged("Subscribed",
+ members_added,
+ members_removed,
+ local_pending,
+ remote_pending,
+ actor, reason);
+}
+
+// TODO: This function is a real beast. It should be split into separate functions. Rething whether it is a good idea
+// to map all slots to this functions!?
+void ContactManager::slotMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason)
+{
+ Q_UNUSED(actor);
+ Q_UNUSED(reason);
+// Q_UNUSED(message);
+
+// qDebug() << "Members Changed" << message << "Actor" << actor << "Reason" <<reason;
+// qDebug() << "Members Added" << members_added.size();
+// qDebug() << "Members Removed" << members_removed.size();
+// qDebug() << "Members Local Pending" << local_pending.size();
+// qDebug() << "Members Remote Pending" << remote_pending.size();
+ // Figure out handles that we need to look up.
+ // Batch them up to minimize roundtrips.
+
+
+
+
+ if (members_added.size()!=0)
+ {
+ if (message==QString("Known"))
+ {
+ QList<uint> known_to_look_up(d->KnownHandlesToLookUp(members_added));
+ // look up 'missing' handles:
+ QDBusPendingReply<QStringList> handle_names =
+ d->m_pInterface->InspectHandles(Telepathy::HandleTypeContact, known_to_look_up);
+ handle_names.waitForFinished();
+ if (!handle_names.isValid())
+ {
+ QDBusError error = handle_names.error();
+
+ qWarning() << "InspectHandles: error type:" << error.type()
+ << "error name:" << error.name();
+ return;
+ }
+ Q_ASSERT(handle_names.value().size() == known_to_look_up.size());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Known Handle" << handle_names.value().size() <<"Look Up Size" << known_to_look_up.size();
+#endif
+ // Create Contacts for the looked up handles:
+ QHash<uint, QPointer<Contact> > tmp_list;
+ for (int i = 0; i < known_to_look_up.size(); ++i)
+ {
+
+
+ QPointer<Contact> contact = new Contact(known_to_look_up.at(i), handle_names.value().at(i), Contact::CT_Known, d->m_pInterface, this );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Known Handle" << handle_names.value().at(i);
+#endif
+ Q_ASSERT(contact->isValid());
+ tmp_list.insert(known_to_look_up.at(i), contact);
+
+ }
+ known_to_look_up.clear();
+ if (tmp_list.size()>0)
+ {
+ foreach (uint handle, members_added)
+ {
+ //Q_ASSERT(!d->m_subscribed.contains(handle)); // We do not yet know that handle.
+ // FIXME: Check where the handle comes from to figure out whether it was
+ // Getting authorized, etc.
+ QPointer<Contact> current_contact = tmp_list.value(handle);
+ // Detect mixups when writing into the hash.
+ if (current_contact)
+ {
+ Q_ASSERT(current_contact->telepathyHandle() == handle);
+ tmp_list.remove(handle);
+ if (!d->m_subscribed.contains(handle))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Added Handle to Known List";
+#endif
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Known Contact already in contactlist";
+#endif
+ d->m_members.remove(handle);
+ d->m_subscribed.remove(handle);
+ }
+ d->m_members.insert(handle, current_contact);
+ d->m_known.insert(handle, current_contact);
+ emit signalContactKnown( this, current_contact );
+ }
+ }
+ }
+ }
+ else //message!="Known"
+ {
+
+ QList<uint> subscribed_to_look_up(d->SubscribedHandlesToLookUp(members_added));
+
+ // look up 'missing' handles:
+ QDBusPendingReply<QStringList> handle_names =
+ d->m_pInterface->InspectHandles(Telepathy::HandleTypeContact, subscribed_to_look_up);
+ handle_names.waitForFinished();
+ if (!handle_names.isValid())
+ {
+ QDBusError error = handle_names.error();
+
+ qWarning() << "InspectHandles: error type:" << error.type()
+ << "error name:" << error.name();
+ return;
+ }
+ Q_ASSERT(handle_names.value().size() == subscribed_to_look_up.size());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Subscribed Handle" << handle_names.value().size() <<"Look Up Size" << subscribed_to_look_up.size()<< "Mmebers Added Size "<< members_added.size();
+#endif
+ // Create Contacts for the looked up handles:
+ QHash<uint, QPointer<Contact> > tmp_list;
+ for (int i = 0; i < subscribed_to_look_up.size(); ++i)
+ {
+
+ QPointer<Contact> contact = new Contact(subscribed_to_look_up.at(i), handle_names.value().at(i), Contact::CT_Subscribed, d->m_pInterface, this );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Subscribed Handle" << handle_names.value().at(i);
+#endif
+ Q_ASSERT(contact->isValid());
+ tmp_list.insert(subscribed_to_look_up.at(i), contact);
+ }
+ if (tmp_list.size()>0)
+ {
+ QPointer<Contact> current_contact;
+ foreach (uint handle, members_added)
+ {
+ //Q_ASSERT(!d->m_subscribed.contains(handle)); // We do not yet know that handle.
+ // FIXME: Check where the handle comes from to figure out whether it was
+ // Getting authorized, etc.
+ current_contact = tmp_list.value(handle);
+
+ if (current_contact)
+ {
+ // Detect mixups when writing into the hash.
+ Q_ASSERT(current_contact->telepathyHandle() == handle);
+
+ tmp_list.remove(handle);
+ if (!d->m_members.contains(handle))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Added Handle to Subscribed List"<< handle;
+#endif
+ d->m_members.insert(handle, current_contact);
+ //d->m_subscribed.insert(handle, current_contact);
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Subscribed Contact already in contactlist"<< handle;
+#endif
+
+ if (d->m_members[handle]->type()==Contact::CT_LocalPending)
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Changed Subscribed Contact to local pending"<< handle;
+#endif
+ d->m_members[handle]->setType(Contact::CT_LocalPending);
+ }
+ else
+ {
+ d->m_members[handle]->setType(Contact::CT_Subscribed);
+ if (d->m_remotePending.contains(handle))
+ d->m_remotePending.remove(handle);
+ if (d->m_localPending.contains(handle))
+ d->m_localPending.remove(handle);
+
+ }
+ delete current_contact;
+ }
+
+ emit signalContactSubscribed( this, d->m_members[handle] );
+ emit signalForModelContactSubscribed( this, d->m_members[handle] );
+ }
+ }
+ }
+ }
+ }
+ if (local_pending.size()!=0)
+ {
+ QList<uint> localPending_to_look_up(d->LocalPendingHandlesToLookUp(local_pending));
+ // look up 'missing' handles:
+ QDBusPendingReply<QStringList> handle_names =
+ d->m_pInterface->InspectHandles(Telepathy::HandleTypeContact, localPending_to_look_up);
+ handle_names.waitForFinished();
+ if (!handle_names.isValid())
+ {
+ QDBusError error = handle_names.error();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "InspectHandles: error type:" << error.type()
+ << "error name:" << error.name();
+#endif
+ return;
+ }
+ Q_ASSERT(handle_names.value().size() == localPending_to_look_up.size());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Local Pending Size" << handle_names.value().size() <<"Look Up Size" << localPending_to_look_up.size();
+#endif
+
+ // Create Contacts for the looked up handles:
+ QHash<uint, QPointer<Contact> > tmp_list;
+ for (int i = 0; i < localPending_to_look_up.size(); ++i)
+ {
+ QPointer<Contact> contact = new Contact(localPending_to_look_up.at(i), handle_names.value().at(i), Contact::CT_LocalPending, d->m_pInterface, this );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Local Pending Handle" << handle_names.value().at(i);
+#endif
+ Q_ASSERT(contact->isValid());
+ tmp_list.insert(localPending_to_look_up.at(i), contact);
+ }
+ if (tmp_list.size()>0)
+ {
+ foreach (uint handle, local_pending)
+ {
+ QPointer<Contact> current_contact = tmp_list.value(handle);
+ if (current_contact)
+ {
+ Q_ASSERT(current_contact->telepathyHandle() == handle);
+
+ tmp_list.remove(handle);
+ if (!d->m_members.contains(handle))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Added Handle to Local Pending List";
+#endif
+ d->m_members.insert(handle, current_contact);
+ d->m_localPending.insert(handle, current_contact);
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Local Pending Contact already in contactlist";
+#endif
+ d->m_members[handle]->setType(Contact::CT_LocalPending);
+ if (d->m_remotePending.contains(handle))
+ d->m_remotePending.remove(handle);
+ delete current_contact;
+ }
+
+ emit signalContactLocalPending( this, d->m_members[handle] );
+ }
+
+ }
+ }
+ }
+
+ if (remote_pending.size()!=0)
+ {
+ QList<uint> remotePending_to_look_up(d->RemotePendingHandlesToLookUp(remote_pending));
+
+ // look up 'missing' handles:
+ QDBusPendingReply<QStringList> handle_names =
+ d->m_pInterface->InspectHandles(Telepathy::HandleTypeContact, remotePending_to_look_up);
+ handle_names.waitForFinished();
+
+ if (!handle_names.isValid())
+ {
+ QDBusError error = handle_names.error();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "InspectHandles: error type:" << error.type()
+ << "error name:" << error.name();
+#endif
+ return;
+ }
+ Q_ASSERT(handle_names.value().size() == remotePending_to_look_up.size());
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Remote Pending Handle Size" << handle_names.value().size() <<"Look Up Size" << remotePending_to_look_up.size();
+#endif
+ // Create Contacts for the looked up handles:
+ QHash<uint, QPointer<Contact> > tmp_list;
+ for (int i = 0; i < remotePending_to_look_up.size(); ++i)
+ {
+ QPointer<Contact> contact = new Contact(remotePending_to_look_up.at(i), handle_names.value().at(i), Contact::CT_RemotePending, d->m_pInterface, this );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Remote Pending Handle " << handle_names.value().at(i);
+#endif
+ Q_ASSERT(contact->isValid());
+ tmp_list.insert(remotePending_to_look_up.at(i), contact);
+ }
+ if (tmp_list.size()>0)
+ {
+ foreach (uint handle, remote_pending)
+ {
+
+ QPointer<Contact> current_contact = tmp_list.value(handle);
+ if (current_contact)
+ {
+ // Detect mixups when writing into the hash.
+ Q_ASSERT(current_contact->telepathyHandle() == handle);
+ tmp_list.remove(handle);
+ if (!d->m_members.contains(handle))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Added Handle to Remote Pending List";
+#endif
+ d->m_remotePending.insert(handle, current_contact);
+ d->m_members.insert(handle, current_contact);
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Remote Pending Contact already in contactlist";
+#endif
+ d->m_members[handle]->setType(Contact::CT_RemotePending);
+
+ if (d->m_localPending.contains(handle))
+ d->m_localPending.remove(handle);
+
+ delete current_contact;
+ }
+
+ emit signalContactRemotePending( this, d->m_members[handle] );
+ }
+
+ }
+ }
+ }
+
+ if (members_removed.size()!=0)
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "SlotMembers Changed Removed Called";
+#endif
+ QList<uint> removed_to_look_up(d->RemovedHandlesToLookUp(members_removed));
+ // look up 'missing' handles:
+ QDBusPendingReply<QStringList> handle_names =
+ d->m_pInterface->InspectHandles(Telepathy::HandleTypeContact, removed_to_look_up);
+ handle_names.waitForFinished();
+ if (!handle_names.isValid())
+ {
+ QDBusError error = handle_names.error();
+ qWarning() << "InspectHandles: error type:" << error.type()
+ << "error name:" << error.name();
+ return;
+ }
+ Q_ASSERT(handle_names.value().size() == removed_to_look_up.size());
+ // Create Contacts for the looked up handles:
+ QHash<uint, QPointer<Contact> > tmp_list;
+ for (int i = 0; i < removed_to_look_up.size(); ++i)
+ {
+ QPointer<Contact> contact = new Contact(removed_to_look_up.at(i), handle_names.value().at(i), Contact::CT_Known, d->m_pInterface, this );
+ Q_ASSERT(contact->isValid());
+ tmp_list.insert(removed_to_look_up.at(i), contact);
+ }
+
+ if (tmp_list.size()>0)
+ {
+ foreach (uint handle, members_removed)
+ {
+
+ QPointer<Contact> current_contact = tmp_list.value(handle);
+ if (current_contact)
+ {
+ // Detect mixups when writing into the hash.
+ Q_ASSERT(current_contact->telepathyHandle() == handle);
+
+ tmp_list.remove(handle);
+ if (d->m_members.contains(handle))
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Remove Contact";
+#endif
+ d->m_members.remove(handle);
+ d->m_subscribed.remove(handle);
+ d->m_remotePending.remove(handle);
+ d->m_localPending.remove(handle);
+ d->m_known.remove(handle);
+ emit signalContactRemoved( this, current_contact );
+ delete current_contact;
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Removed Contact not in contactlist";
+#endif
+ delete current_contact;
+ }
+ }
+ }
+ }
+ }
+ emit signalMembersChanged( this,
+ message,
+ d->mapHashToList( d->m_members ),
+ d->mapHashToList( d->m_localPending ),
+ d->mapHashToList( d->m_remotePending ),
+ contactForHandle( actor ),
+ static_cast<Telepathy::ChannelGroupChangeReason>( reason ) );
+}
diff --git a/TelepathyQt4/Prototype/ContactManager.h b/TelepathyQt4/Prototype/ContactManager.h
new file mode 100644
index 0000000..f396985
--- /dev/null
+++ b/TelepathyQt4/Prototype/ContactManager.h
@@ -0,0 +1,304 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_ContactManager_H_
+#define TelepathyQt4_Prototype_ContactManager_H_
+
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Constants>
+
+#include <QObject>
+#include <QDBusObjectPath>
+#include <QPointer>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+/**
+ * @defgroup qt_contact Contact Management
+ * @ingroup qt_style_api
+ * Classes that provide functions to handle contacts.
+ */
+
+
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ class ChannelInterfaceGroupInterface;
+
+ }
+}
+
+namespace TpPrototype {
+
+class ContactManagerPrivate;
+class Contact;
+class Connection;
+class ChatChannel;
+class StreamedMediaChannel;
+
+/**
+ * @ingroup qt_connection
+ * @ingroup qt_contact
+ * This class manages all contacts.
+ * This class provides the list of contacts associated with an account. It is possible to register new contacts by requestContact(), or remove contacts
+ * by removeContact(). Signals providing information whether any contact changes or wether a communication channel is opened.
+ * @todo We need a ContactGroup that contains the Contacts instead use QList< QPointer<> >. If a contact is removed we get a NULL element in the list instead to remove one element from the list (seil)
+ */
+class ContactManager : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Validity of this class.
+ * Do not access any methods if this object is invalid.
+ */
+ bool isValid();
+
+ /**
+ * Number of Contacts. Returns how many contacts are available.
+ * @return Number of contacts available.
+ */
+ int count();
+
+ /**
+ * List of contacts. The contact pointer is stored in a QPointer. If the contact is removed it is deleted
+ * by the contact manager. Thus, the pointer is set to 0.
+ * @todo: Return ContactGroup here, instead a list of a pointer.
+ */
+ QList<QPointer<TpPrototype ::Contact> > contactList();
+
+ /**
+ * List of contacts that have requested authorization from us.
+ *
+ * The contact pointer is stored in a QPointer. If the contact is removed it is deleted
+ * by the contact manager. Thus, the pointer is set to 0.
+ * @todo: Return ContactGroup here, instead a list of a pointer.
+ */
+ QList<QPointer<TpPrototype ::Contact> > toAuthorizeList();
+
+ /**
+ * List of contacts <i>we</i> asked to authorize us to see their presence state.
+ *
+ * The contact pointer is stored in a QPointer. If the contact is removed it is deleted
+ * by the contact manager. Thus, the pointer is set to 0.
+ * @todo: Return ContactGroup here, instead of a list of pointer.
+ */
+ QList<QPointer<TpPrototype ::Contact> > remoteAuthorizationPendingList();
+
+ /**
+ * Request a contact.
+ * A remote contact should be added to the list of known contacts.
+ * @param id The id identifies the contact (protocol specific)
+ * @return true if the handle was found else false.
+ */
+ bool requestContact( const QString& id );
+
+ /**
+ * Authorize contact.
+ * A remote contact should be authorized.
+ * @param contact The contact to autorize.
+ * @return true if ...
+ */
+ bool authorizeContact( const Contact* contact );
+
+ /**
+ * Remove a contact.
+ * The contact should be removed.
+ * @param contactToRemove The contact that should be removed. Do not use this pointer after this call!
+ */
+ bool removeContact( const TpPrototype ::Contact* contactToRemove );
+
+ /**
+ * Returns a contact pointer for handle id.
+ * This function provides a fast lookup of a contact if a valid handle is provided.
+ * @return The contact that corresponds to the handle or NULL if the handle is unknown.
+ */
+ QPointer<TpPrototype ::Contact> contactForHandle( uint handle );
+
+ /**
+ * The local use handle.
+ * The local user has a handle that is returned by this function. The local handle cannot be used to get
+ * a valid contact with contactForHandle()!
+ */
+ uint localHandle();
+
+signals:
+ /**
+ * A text channel was opened.
+ * This signal is emitted when a text channel was opened for a contact. This usually means that you received a text message.<br>
+ * The chat channel object can be retrieved from the contact.
+ * @param contact The contact that received the text message and contains the text channel object.
+ */
+ void signalTextChannelOpenedForContact( TpPrototype ::Contact* contact );
+
+ /**
+ * A streamed media channel was opened.
+ * This signal is emitted when a streamed media channel was opened for a contact and all interfaces were established successfully.
+ * This usually means that you received a call.<br>
+ * The StreamedMedia channel object can be retrieved from the contact. Use acceptIncomingStream() or rejectIncomingStream() to accept or reject.
+ * @param contact The contact that received the text message and contains the StreamedMediaChannel object.
+ * @see StreamMediaChannel
+ */
+ void signalStreamedMediaChannelOpenedForContact( TpPrototype ::Contact* contact );
+
+ /**
+ * A Contact was added.
+ * A new remote Contact was added but needs to be accepted remotely.
+ * @see signalContactRemotePending()
+ */
+ void signalContactAdded( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * A Contact is pending locally.
+ * A Contact that is local pending have requested membership of the channel, but the local user of the framework must
+ * accept their request before they may join.
+ */
+ void signalContactLocalPending( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * A Contact is pending remotely.
+ * A Contact that is remote pending list have been invited to the channel, but the remote user has not
+ * accepted the invitation.
+ */
+ void signalContactRemotePending( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * A Contact was subscribed.
+ * This signal is emitted if a new contact was subscribed.
+ */
+ void signalContactSubscribed( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * A Contact was removed.
+ * This signal is emitted if a new contact was removed.
+ */
+ void signalContactRemoved( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * @todo: Add doc! (seil)
+ */
+ void signalContactKnown( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * @todo: Add doc! (seil)
+ */
+ void signalForModelContactSubscribed( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * @todo: Add doc! (seil)
+ */
+ void signalForModelContactRemoved( TpPrototype ::ContactManager* contactManager, TpPrototype ::Contact* contact );
+
+ /**
+ * Members changed.
+ * This signal is emitted whenever one of the internal lists of contacts (member, local pending, remote pending) changes.
+ * @param contactManager The contact manager that handles the contacts.
+ * @param message A string message from the server, or blank if not
+ * @param members List of contacts currently listed as members.
+ * @param localPending Contacts that are waiting for a local approval.
+ * @param remotePending Contacs that are waiting for a remote approval.
+ * @param actor The contact that causes the change. May be NULL if unkown.
+ * @param reason The reason of the change.
+ */
+ void signalMembersChanged( TpPrototype ::ContactManager* contactManager,
+ const QString& message,
+ QList<QPointer<TpPrototype ::Contact> > members,
+ QList<QPointer<TpPrototype ::Contact> > localPending,
+ QList<QPointer<TpPrototype ::Contact> > remotePending,
+ TpPrototype ::Contact* actor,
+ Telepathy::ChannelGroupChangeReason reason );
+
+protected:
+ /**
+ * Constructor. The contact manager cannot be instantiated directly. Use Connection::contactManager() for it!
+ */
+ ContactManager( Telepathy::Client::ConnectionInterface* connection,
+ QObject* parent = NULL );
+ ~ContactManager();
+
+
+ void openSubscribedContactsChannel(uint handle, const QDBusObjectPath& objectPath, const QString& channelType);
+
+ /**
+ * ..
+ */
+ void openPublishContactsChannel(uint handle, const QDBusObjectPath& objectPath, const QString& channelType);
+
+ /**
+ * ..
+ */
+ void openKnownContactsChannel(uint handle, const QDBusObjectPath& objectPath, const QString& channelType);
+
+ /**
+ * ..
+ */
+ void openDenyContactsChannel(uint handle, const QDBusObjectPath& objectPath, const QString& channelType);
+
+ void openTextChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelType );
+
+ void openStreamedMediaChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelType );
+
+protected slots:
+
+ void slotMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason);
+ void slotKnownMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason);
+ void slotPublishedMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason);
+ void slotSubscribedMembersChanged(const QString& message,
+ const Telepathy::UIntList& members_added,
+ const Telepathy::UIntList& members_removed,
+ const Telepathy::UIntList& local_pending,
+ const Telepathy::UIntList& remote_pending,
+ uint actor, uint reason);
+private:
+ void init( Telepathy::Client::ConnectionInterface* connection );
+
+ ContactManagerPrivate * const d;
+ friend class Connection;
+ friend class ConnectionPrivate;
+ friend class Contact;
+};
+
+}
+
+#endif
diff --git a/TelepathyQt4/Prototype/DBusInterface.cpp b/TelepathyQt4/Prototype/DBusInterface.cpp
new file mode 100644
index 0000000..fd0f5c8
--- /dev/null
+++ b/TelepathyQt4/Prototype/DBusInterface.cpp
@@ -0,0 +1,47 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/DBusInterface.h"
+
+namespace
+{
+ const char* g_serviceName = "org.freedesktop.DBus";
+ const char* g_objectPath = "/";
+ const char* g_interfaceName = "org.freedesktop.DBus";
+}
+
+using namespace TpPrototype;
+
+DBusInterface::DBusInterface( QObject* parent ):
+QDBusAbstractInterface( g_serviceName,
+ g_objectPath,
+ g_interfaceName,
+ QDBusConnection::sessionBus(),
+ parent )
+{
+}
+
+QDBusReply<QStringList> DBusInterface::listActivatableNames()
+{
+ Q_ASSERT( isValid() );
+ return call( QLatin1String("ListActivatableNames") );
+}
diff --git a/TelepathyQt4/Prototype/DBusInterface.h b/TelepathyQt4/Prototype/DBusInterface.h
new file mode 100644
index 0000000..e786ff1
--- /dev/null
+++ b/TelepathyQt4/Prototype/DBusInterface.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef TelepathyQt4_Prototype_DBusInterface_h_
+#define TelepathyQt4_Prototype_DBusInterface_h_
+
+#include <QDBusAbstractInterface>
+#include <QDBusReply>
+#include <QStringList>
+
+namespace TpPrototype
+{
+
+/**
+ * Class to access function provided by dbus daemon.
+ */
+class DBusInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ DBusInterface( QObject* parent = NULL );
+
+ /**
+ * Return a list of all registered service names. These names can be activated by calling the service.
+ * @return List of service names.
+ */
+ QDBusReply<QStringList> listActivatableNames();
+
+};
+
+}
+#endif
+
diff --git a/TelepathyQt4/Prototype/Makefile.am b/TelepathyQt4/Prototype/Makefile.am
new file mode 100644
index 0000000..15fb7af
--- /dev/null
+++ b/TelepathyQt4/Prototype/Makefile.am
@@ -0,0 +1,161 @@
+protoincludedir=$(includedir)/tpqt4-prototype/TelepathyQt4/Prototype
+protoclientincludedir=$(protoincludedir)/Client
+genincludedir=$(protoincludedir)/_gen
+
+pkgconfigdir = ${libdir}/pkgconfig
+pkgconfig_DATA = TpQt4Prototype.pc
+
+EXTRA_DIST = \
+ all.xml \
+ channel-handler.xml
+
+lib_LTLIBRARIES = libtpqt4-prototype.la
+
+# The quoting here is unnecessary but harmless, and has the useful side-effect
+# that vim quickfix mode (:make) doesn't interpret the libtool --mode=link
+# command as an error message in a bizarrely named file
+libtpqt4_prototype_la_LDFLAGS = \
+ -version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)" -static
+libtpqt4_prototype_la_LIBADD = $(ALL_LIBS)
+libtpqt4_prototype_la_DEPENDENCIES = Makefile.am
+
+libtpqt4_prototype_la_SOURCES = \
+ Account.cpp \
+ AccountManager.cpp \
+ AvatarManager.cpp \
+ CapabilitiesManager.cpp \
+ ChatChannel.cpp \
+ Connection.cpp \
+ ConnectionFacade.cpp \
+ DBusInterface.cpp \
+ PresenceManager.cpp \
+ StreamedMediaChannel.cpp \
+ types.cpp
+
+nodist_libtpqt4_prototype_la_SOURCES = \
+ _gen/cli-channel-handler-body.hpp \
+ _gen/types-body.hpp
+
+protoinclude_HEADERS = \
+ Account.h \
+ AccountManager.h \
+ AvatarManager.h \
+ CapabilitiesManager.h \
+ ChatChannel.h \
+ Connection.h \
+ ConnectionFacade.h \
+ Constants \
+ Contact.h \
+ DBusInterface.h \
+ PresenceManager.h \
+ StreamedMediaChannel.h \
+ Types \
+ constants.h \
+ types.h
+
+nodist_geninclude_HEADERS = \
+ _gen/cli-channel-handler.h \
+ _gen/constants.h \
+ _gen/types.h
+
+BUILT_SOURCES = \
+ $(nodist_libtpqt4_prototype_la_SOURCES) \
+ $(nodist_geninclude_HEADERS) \
+ _gen/stable-spec.xml \
+ _gen/spec-stamp \
+ _gen/stable-stamp
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+distclean-local:
+ rm -rf _gen
+
+include $(top_srcdir)/tools/check-coding-style.mk
+check-local: check-coding-style
+
+AM_CXXFLAGS = \
+ $(ERROR_CXXFLAGS) \
+ @QTCORE_CFLAGS@ \
+ @QTDBUS_CFLAGS@ \
+ -I$(top_builddir) \
+ -I$(top_srcdir)
+
+ALL_LIBS = \
+ @QTCORE_LIBS@ \
+ @QTDBUS_LIBS@
+
+# Generated stuff
+
+# Bootstrapping
+
+_gen/spec-stamp: $(wildcard $(top_srcdir)/spec/*.xml)
+ $(mkdir_p) _gen
+ touch $@
+
+_gen/stable-stamp: $(wildcard *.xml) _gen/spec-stamp
+ touch $@
+
+_gen/stable-spec.xml: all.xml _gen/stable-stamp \
+ $(top_srcdir)/tools/xincludator.py \
+ Makefile.am
+ $(PYTHON) $(top_srcdir)/tools/xincludator.py \
+ $< > $@
+
+# Things generated from the whole spec at once
+
+_gen/constants.h: _gen/stable-spec.xml \
+ $(top_srcdir)/tools/qt4-constants-gen.py \
+ Makefile.am
+ $(PYTHON) $(top_srcdir)/tools/qt4-constants-gen.py \
+ --namespace='TpPrototype' \
+ --str-constant-prefix='TP_PROTOTYPE_' \
+ --specxml=$< \
+ > $@.tmp && mv $@.tmp $@
+
+_gen/types.h _gen/types-body.hpp: _gen/stable-spec.xml \
+ $(top_srcdir)/tools/qt4-types-gen.py \
+ Makefile.am
+ $(PYTHON) $(top_srcdir)/tools/qt4-types-gen.py \
+ --namespace='TpPrototype' \
+ --declfile='_gen/types.h' \
+ --implfile='_gen/types-body.hpp' \
+ --realinclude='TelepathyQt4/Prototype/types.h' \
+ --prettyinclude='TelepathyQt4/Prototype/Types' \
+ --specxml=$<
+
+# Things generated per interface group
+
+_gen/spec-%.xml: %.xml $(top_srcdir)/tools/xincludator.py _gen/spec-stamp
+ $(PYTHON) $(top_srcdir)/tools/xincludator.py \
+ $< > $@
+
+_gen/cli-%.h _gen/cli-%-body.hpp: _gen/spec-%.xml \
+ _gen/stable-spec.xml \
+ $(top_srcdir)/tools/qt4-client-gen.py \
+ Makefile.am
+ set -e; \
+ namespace='TpPrototype::Client'; \
+ group= ; \
+ prettyinclude= ; \
+ mainiface= ; \
+ case $* in \
+ channel-handler) \
+ group='clientchannelhandler'; \
+ prettyinclude='ChannelHandler';; \
+ esac; \
+ $(PYTHON) $(top_srcdir)/tools/qt4-client-gen.py \
+ --group=$$group \
+ --namespace=$$namespace \
+ --typesnamespace='Telepathy' \
+ --headerfile=_gen/cli-$*.h \
+ --implfile=_gen/cli-$*-body.hpp \
+ --realinclude='TelepathyQt4/Prototype/cli-$*.h' \
+ --prettyinclude='TelepathyQt4/Prototype/Client/'$$prettyinclude \
+ --specxml=_gen/stable-spec.xml \
+ --ifacexml=$< \
+ --extraincludes='<TelepathyQt4/Types>,<TelepathyQt4/Prototype/Types>' \
+ $$mainiface
+
+%.moc.hpp: %.h _gen/constants.h _gen/types.h
+ $(MOC) @QTCORE_CFLAGS@ @QTDBUS_CFLAGS@ -I$(top_builddir) -I$(top_srcdir) -i $< -o $@
diff --git a/TelepathyQt4/Prototype/PresenceManager.cpp b/TelepathyQt4/Prototype/PresenceManager.cpp
new file mode 100644
index 0000000..caaa18d
--- /dev/null
+++ b/TelepathyQt4/Prototype/PresenceManager.cpp
@@ -0,0 +1,620 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/PresenceManager.h"
+
+#include <QCoreApplication>
+#include <QDBusObjectPath>
+#include <QDBusPendingReply>
+#include <QDebug>
+#include <QMap>
+#include <QPointer>
+
+#include <TelepathyQt4/Client/Connection>
+
+#include <TelepathyQt4/Prototype/Account.h>
+#include <TelepathyQt4/Prototype/AccountManager.h>
+#include <TelepathyQt4/Prototype/ConnectionFacade.h>
+#include <TelepathyQt4/Prototype/Connection.h>
+#include <TelepathyQt4/Prototype/Contact.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+
+// #define ENABLE_DEBUG_OUTPUT_
+
+namespace
+{
+ const char* g_offlineStatusString = "offline";
+ const char* g_statusParamMessageString = "message";
+}
+
+using namespace TpPrototype;
+
+class TpPrototype::PresenceManagerPrivate
+{
+public:
+ PresenceManagerPrivate( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+ { init( connection, interface ); }
+
+ Telepathy::Client::ConnectionInterface* m_pConnectionInterface;
+ Telepathy::Client::ConnectionInterfaceSimplePresenceInterface* m_pSimplePresenceInterface;
+ Telepathy::Client::ConnectionInterfacePresenceInterface* m_pPresenceInterface;
+ QPointer<Connection> m_pConnection;
+ bool m_isValid;
+ QMap<QString,int> m_mapStatusStringToType;
+
+ void init( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface )
+ {
+ m_pConnectionInterface = interface;
+ m_pConnection = connection;
+ m_pSimplePresenceInterface = NULL;
+ m_pPresenceInterface = NULL;
+ m_isValid = true;
+
+ m_mapStatusStringToType.insert( "offline" , 1 /*Connection_Presence_Type_Offline*/ ); //TODO: Why is there no enum for these types?
+ m_mapStatusStringToType.insert( "available", 2 /*Connection_Presence_Type_Available*/ );
+ m_mapStatusStringToType.insert( "away" , 3 /*Connection_Presence_Type_Away*/ );
+ m_mapStatusStringToType.insert( "brb" , 3 /*Connection_Presence_Type_Away*/ );
+ m_mapStatusStringToType.insert( "xa" , 4 /*Connection_Presence_Type_Extended_Away*/ );
+ m_mapStatusStringToType.insert( "hidden" , 5 /*Connection_Presence_Type_Busy*/ );
+ m_mapStatusStringToType.insert( "busy" , 6 /*Connection_Presence_Type_Busy*/ );
+ m_mapStatusStringToType.insert( "dnd" , 6 /*Connection_Presence_Type_Busy*/ );
+ m_mapStatusStringToType.insert( "unknown" , 7 /*Connection_Presence_Type_Unknown*/ );
+ m_mapStatusStringToType.insert( "error" , 8 /*Connection_Presence_Type_Error*/ );
+
+ }
+
+ uint localHandle()
+ {
+ uint self_handle = ConnectionFacade::instance()->selfHandleForConnectionInterface( m_pConnectionInterface );
+ if ( self_handle < 0 )
+ { m_isValid = false; }
+
+ return self_handle;
+ }
+
+// Protected functions
+
+ uint mapStatusStringToType( const QString& status ) const
+ {
+ return m_mapStatusStringToType.value( status );
+ }
+
+ Telepathy::SimplePresence convertToSimplePresence( const Telepathy::LastActivityAndStatuses& status ) const
+ {
+ Telepathy::SimplePresence simple_presence;
+
+ QStringList status_list = status.statuses.keys();
+
+ Q_ASSERT( status_list.count() == 1 );
+ if ( status_list.count() < 1 )
+ { return simple_presence; }
+
+ simple_presence.type = mapStatusStringToType( status_list.at( 0 ) );
+ simple_presence.status = status_list.at( 0 );
+ simple_presence.statusMessage = status.statuses.value( status_list.at( 0 ) ).value( g_statusParamMessageString ).toString();
+
+ return simple_presence;
+ }
+
+ Telepathy::SimpleContactPresences convertToSimplePresences( const Telepathy::ContactPresences& presences ) const
+ {
+ Telepathy::SimpleContactPresences contact_presences;
+
+ QList<uint> keys = presences.keys();
+ foreach( uint key, keys )
+ {
+ contact_presences.insert( key, convertToSimplePresence( presences.value( key ) ) );
+ }
+
+ return contact_presences;
+ }
+
+ Telepathy::MultipleStatusMap convertToMultipleStatusMap( const QString& status, const QString& statusMessage ) const
+ {
+ Telepathy::MultipleStatusMap status_map;
+
+ QVariantMap protocol_specif_parameters;
+ if ( !statusMessage.isEmpty() )
+ { protocol_specif_parameters.insert( g_statusParamMessageString, statusMessage ); }
+
+ status_map.insert( status, protocol_specif_parameters );
+
+ return status_map;
+ }
+};
+
+PresenceManager::PresenceManager( Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent ):
+ QObject( parent ),
+ d( new PresenceManagerPrivate( connection, interface ) )
+{
+ init();
+}
+
+PresenceManager::~PresenceManager()
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "D'tor PresenceManager (" << this << ")";
+#endif
+ delete d;
+}
+
+bool PresenceManager::isValid()
+{
+ return d->m_isValid;
+}
+
+Telepathy::SimpleStatusSpecMap PresenceManager::statuses()
+{
+ Q_ASSERT( d->m_pSimplePresenceInterface || d->m_pPresenceInterface );
+
+ if ( d->m_pSimplePresenceInterface )
+ { return d->m_pSimplePresenceInterface->Statuses(); }
+
+ if ( d->m_pPresenceInterface )
+ {
+ // We return a minimum set of states that should be provided by every contact manager and protocol
+ Telepathy::SimpleStatusSpecMap ret_status;
+ Telepathy::SimpleStatusSpec available = { 2, 2, true };
+ ret_status.insert( "available", available );
+ Telepathy::SimpleStatusSpec away = { 3, 3, true };
+ ret_status.insert( "away", away );
+ Telepathy::SimpleStatusSpec offline = { 1, 1, true };
+ ret_status.insert( "offline", offline );
+
+ return ret_status;
+ }
+
+ return Telepathy::SimpleStatusSpecMap();
+}
+
+bool PresenceManager::setPresence( const QString& status, const QString& statusMessage )
+{
+ Q_ASSERT( d->m_pSimplePresenceInterface || d->m_pPresenceInterface );
+
+ if ( !d->m_pSimplePresenceInterface && !d->m_pPresenceInterface )
+ { return false; }
+
+ // The state "offline" is presented as possible state with statuses(). Due to unknown reasons it is not
+ // a valid name for setPresence(). Thus, we handle it on this layer..
+ if ( status == g_offlineStatusString )
+ {
+ Q_ASSERT( d->m_pConnection );
+
+ // TODO: Think whether sending this signal here manually (and before disconnecting) is really a good idea!
+ const Telepathy::SimplePresence new_presence = { d->mapStatusStringToType( "offline" ), status, statusMessage };
+ emit signalOwnPresenceUpdated( d->m_pConnection->account(), new_presence );
+
+ d->m_pConnection->requestDisconnect();
+ return true;
+ }
+
+ if ( d->m_pSimplePresenceInterface )
+ {
+ QDBusPendingReply<> set_presence_reply = d->m_pSimplePresenceInterface->SetPresence( status, statusMessage );
+ set_presence_reply.waitForFinished();
+
+ if ( !set_presence_reply.isValid() )
+ {
+ QDBusError error = set_presence_reply.error();
+
+ qWarning() << "SetPresence: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return false;
+ }
+ return true;
+ }
+
+ if ( d->m_pPresenceInterface )
+ {
+ QDBusPendingReply<> set_status_reply = d->m_pPresenceInterface->SetStatus( d->convertToMultipleStatusMap( status, statusMessage ) );
+ set_status_reply.waitForFinished();
+ if ( !set_status_reply.isValid() )
+ {
+ QDBusError error = set_status_reply.error();
+
+ qWarning() << "SetStatus: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return false;
+ }
+
+#if 0 // TODO: Exame further: At some point I received the signal. Don't know why..
+ // The simple presence interface is emitting a signal if I changed the local presence here but the presence interface does not!
+ // We simulate this behavior here..
+ const Telepathy::SimplePresence new_presence = { d->mapStatusStringToType( status ), status, statusMessage };
+ emit signalOwnPresenceUpdated( d->m_pConnection->account(), new_presence );
+#endif
+ return true;
+ }
+
+ // Fall through..
+ return false;
+}
+
+// TODO: This function is doing the same as presencesForContacts() but just for one contact! Merge both functions to remove code duplication!
+Telepathy::SimplePresence PresenceManager::currentPresence()
+{
+ Q_ASSERT( d->m_pSimplePresenceInterface || d->m_pPresenceInterface );
+
+ if ( !d->m_pConnection || ( !d->m_pSimplePresenceInterface && !d->m_pPresenceInterface ) )
+ {
+ return Telepathy::SimplePresence();
+ }
+
+ Telepathy::UIntList uid_list;
+ uid_list << d->localHandle();
+
+ if ( d->m_pSimplePresenceInterface )
+ {
+ QDBusPendingReply<Telepathy::SimpleContactPresences> get_presence_reply = d->m_pSimplePresenceInterface->GetPresences( uid_list );
+ get_presence_reply.waitForFinished();
+
+ if ( !get_presence_reply.isValid() )
+ {
+ QDBusError error = get_presence_reply.error();
+
+ qWarning() << "GetPresences: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return Telepathy::SimplePresence();
+ }
+
+ Telepathy::SimpleContactPresences presence_list = get_presence_reply.value();
+ QList<Telepathy::SimplePresence> value_list = presence_list.values();
+
+ if ( value_list.count() == 0 )
+ { return Telepathy::SimplePresence(); }
+
+ return value_list.at( 0 );
+ }
+
+ if ( d->m_pPresenceInterface )
+ {
+ QDBusPendingReply<Telepathy::ContactPresences> get_presence_reply = d->m_pPresenceInterface->GetPresence( uid_list );
+ get_presence_reply.waitForFinished();
+
+ if ( !get_presence_reply.isValid() )
+ {
+ QDBusError error = get_presence_reply.error();
+
+ qWarning() << "GetPresence: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return Telepathy::SimplePresence();
+ }
+
+ Telepathy::ContactPresences presence_list = get_presence_reply.value();
+ QList<Telepathy::LastActivityAndStatuses> value_list = presence_list.values();
+
+ if ( value_list.count() == 0 )
+ { return Telepathy::SimplePresence(); }
+
+ return d->convertToSimplePresence( value_list.at( 0 ) );
+ }
+
+ // Fall through..
+ return Telepathy::SimplePresence();
+}
+
+// TODO: See comment for currentPresence! Merge both to remove code duplication
+Telepathy::SimpleContactPresences PresenceManager::presencesForContacts( const QList<QPointer<Contact> >& contacts )
+{
+ Q_ASSERT( d->m_pSimplePresenceInterface || d->m_pPresenceInterface );
+
+ if ( !d->m_pConnection || ( !d->m_pSimplePresenceInterface && !d->m_pPresenceInterface ) )
+ { return Telepathy::SimpleContactPresences(); }
+
+ Telepathy::UIntList contact_ids;
+ foreach( Contact* contact, contacts )
+ {
+ if ( !contact )
+ { continue; }
+ contact_ids.append( contact->telepathyHandle() );
+ }
+
+ if ( d->m_pSimplePresenceInterface )
+ {
+ QDBusPendingReply<Telepathy::SimpleContactPresences> get_presence_reply = d->m_pSimplePresenceInterface->GetPresences( contact_ids );
+ get_presence_reply.waitForFinished();
+
+ if ( !get_presence_reply.isValid() )
+ {
+ QDBusError error = get_presence_reply.error();
+
+ qWarning() << "GetPresences: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return Telepathy::SimpleContactPresences();
+ }
+
+ Telepathy::SimpleContactPresences presences=get_presence_reply.value();
+ QList<uint> keys = presences.keys();
+ QPointer<TpPrototype::Contact> contact;
+ foreach( uint key, keys )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "presencesForContacts Key"<<key;
+#endif
+ for (int i=0; i<contacts.size(); i++)
+ {
+
+ contact=contacts.at( i);
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Contact "<< key << "Status" <<presences.value( key ).status << "Message:" << presences.value( key ).statusMessage;
+#endif
+ if (contact->telepathyHandle()==key)
+ {
+ contact->setPresenceType(presences.value( key ).type);
+ contact->setPresenceStatus(presences.value( key ).status);
+ contact->setPresenceMessage(presences.value( key ).statusMessage);
+ }
+ }
+ }
+
+ return get_presence_reply.value();
+ }
+
+ if ( d->m_pPresenceInterface )
+ {
+ QDBusPendingReply<Telepathy::ContactPresences> get_presence_reply = d->m_pPresenceInterface->GetPresence( contact_ids );
+ get_presence_reply.waitForFinished();
+
+ if ( !get_presence_reply.isValid() )
+ {
+ QDBusError error = get_presence_reply.error();
+
+ qWarning() << "GetPresence: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return Telepathy::SimpleContactPresences();
+ }
+
+ Telepathy::ContactPresences presences = get_presence_reply.value();
+ QList<uint> keys = presences.keys();
+ QPointer<TpPrototype::Contact> contact;
+ foreach( uint key, keys )
+ {
+ //qDebug() << "presencesForContacts Key"<<key;
+ for ( int i=0; i<contacts.size(); i++ )
+ {
+ contact=contacts.at( i);
+ //qDebug() << "Contact "<< key << "Status" <<presences.value( key ).status;
+ if (contact->telepathyHandle()==key)
+ {
+ Telepathy::SimplePresence simple_presence = d->convertToSimplePresence( presences.value( key ) );
+ contact->setPresenceType( simple_presence.type );
+ contact->setPresenceStatus( simple_presence.status );
+ contact->setPresenceMessage( simple_presence.statusMessage );
+ }
+ }
+ }
+
+ return d->convertToSimplePresences( presences );
+ }
+
+ // Fall through..
+ return Telepathy::SimpleContactPresences();
+}
+
+// Protected slots
+
+// Called by the _simple_ presence interface if presence were updated
+void PresenceManager::slotPresencesChanged( const Telepathy::SimpleContactPresences& presences )
+{
+ if ( !d->m_pConnection )
+ {
+ qWarning() << "PresenceManager::slotPresencesChanged(): Received a presence changed signal but no connection object exists!";
+ return;
+ }
+
+ QList<uint> keys = presences.keys();
+ foreach( uint key, keys )
+ {
+ Telepathy::SimplePresence changed_presence = presences.value( key );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Contact ID: " << key
+ << "Type: " << changed_presence.type
+ << "Status:" << changed_presence.status
+ << "StatusMessage:"<< changed_presence.statusMessage;
+#endif
+
+ if ( d->localHandle() == key )
+ {
+ if ( !d->m_pConnection->account() )
+ {
+ qWarning() << "PresenceManager::slotPresencesChanged(): Connection without account!";
+ return;
+ }
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "PresenceManager::slotPresencesChanged() -> signalOwnPresenceUpdated";
+#endif
+ emit signalOwnPresenceUpdated( d->m_pConnection->account(), changed_presence );
+ }
+ else
+ {
+ if ( !d->m_pConnection->contactManager() )
+ {
+ qWarning() << "PresenceManager::slotPresencesChanged(): Unable to request contact manager!";
+ return;
+ }
+
+ Contact* found_contact = NULL;
+ foreach( Contact* contact, d->m_pConnection->contactManager()->contactList() )
+ {
+ if ( contact && contact->telepathyHandle() == key )
+ { found_contact = contact; }
+ }
+ if ( found_contact )
+ {
+ found_contact->setPresenceType(changed_presence.type);
+ found_contact->setPresenceStatus(changed_presence.status);
+ found_contact->setPresenceMessage(changed_presence.statusMessage);
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "PresenceManager::slotPresencesChanged() -> signalRemotePresencesUpdated";
+#endif
+ emit signalRemotePresencesUpdated( found_contact, changed_presence );
+ }
+ else
+ {
+ qWarning() << "PresenceManager::slotPresencesChanged: Received a signal that a non existing contact changed its presence!";
+ }
+ }
+ }
+}
+
+// Called by the presence interface (that one without "simple" prefix) if any presences were updated
+void PresenceManager::slotPresencesUpdate( const Telepathy::ContactPresences& presences )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "PresenceManager::slotPresencesUpdate()";
+ QList<uint> keys = presences.keys();
+ foreach( uint key, keys )
+ {
+ qDebug() << "Contact ID : " << key
+ << "LastActivity: " << presences.value( key ).lastActivity;
+ Telepathy::MultipleStatusMap statuses = presences.value( key ).statuses; // QMap<QString, QVariantMap>
+ QList<QString> status_keys = statuses.keys();
+ foreach( QString status_key, status_keys )
+ {
+ qDebug() << "Status:" << status_key << "Map:" << statuses.value( status_key );
+ }
+ }
+#endif
+ slotPresencesChanged( d->convertToSimplePresences( presences ) );
+}
+
+TpPrototype::Connection * PresenceManager::connection()
+{
+ return d->m_pConnection;
+}
+
+void PresenceManager::init()
+{
+ Q_ASSERT( d->m_pConnectionInterface );
+
+ if ( !d->m_pConnectionInterface || !d->m_pConnection )
+ {
+ d->m_isValid = false;
+ return;
+ }
+
+ Telepathy::registerTypes();
+ QDBusPendingReply<QStringList> interfaces_reply = d->m_pConnectionInterface->GetInterfaces();
+ interfaces_reply.waitForFinished();
+
+ if ( !interfaces_reply.isValid() )
+ {
+ QDBusError error = interfaces_reply.error();
+
+ qWarning() << "GetInterfaces: error type:" << error.type()
+ << "GetInterfaces: error name:" << error.name();
+
+ d->m_isValid = false;
+ return;
+ }
+
+ QString simplepresence_interface_name;
+ bool found_simple_presence_support = false;
+ QString presence_interface_name;
+ bool found_presence_support = false;
+
+ foreach( const QString& interface, interfaces_reply.value() )
+ {
+ if ( interface.endsWith( ".SimplePresence" ) )
+ {
+ found_simple_presence_support = true;
+ simplepresence_interface_name = interface;
+ }
+ if ( interface.endsWith( ".Presence" ) )
+ {
+ found_presence_support = true;
+ presence_interface_name = interface;
+ }
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Simple Presence Interface Name: " << simplepresence_interface_name;
+ qDebug() << "Presence Interface Name : " << presence_interface_name;
+#endif
+
+ // FIXME: The following line shound be commented out!!
+ // found_simple_presence_support = false; // Override to test the (not simple) presence interface implementation
+
+ if ( found_simple_presence_support )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug( "PresenceManager::init(): Connection Manager provides the Interface \"SimplePresence\". I will use this one!" );
+#endif
+ d->m_pSimplePresenceInterface = new Telepathy::Client::ConnectionInterfaceSimplePresenceInterface( d->m_pConnectionInterface->service(),
+ d->m_pConnectionInterface->path(),
+ this );
+ Q_ASSERT( d->m_pSimplePresenceInterface );
+ Q_ASSERT( d->m_pSimplePresenceInterface->isValid() );
+
+ connect( d->m_pSimplePresenceInterface, SIGNAL( PresencesChanged( const Telepathy::SimpleContactPresences& ) ),
+ this, SLOT( slotPresencesChanged( const Telepathy::SimpleContactPresences& ) ) );
+
+ return;
+ }
+
+ if ( found_presence_support )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug( "PresenceManager::init(): Connection Manager provides the Interface \"Presence\". I will use this one!" );
+#endif
+ d->m_pPresenceInterface = new Telepathy::Client::ConnectionInterfacePresenceInterface( d->m_pConnectionInterface->service(),
+ d->m_pConnectionInterface->path(),
+ this );
+ Q_ASSERT( d->m_pPresenceInterface );
+ Q_ASSERT( d->m_pPresenceInterface->isValid() );
+
+ connect( d->m_pPresenceInterface, SIGNAL( PresenceUpdate(const Telepathy::ContactPresences& ) ),
+ this, SLOT( slotPresencesUpdate( const Telepathy::ContactPresences& ) ) );
+
+ return;
+
+ }
+
+ // Fall through: No valid presence interface was found..
+ d->m_isValid = false;
+ qWarning( "PresenceManager::init(): Connection Manager neither supports the Interface \"Presence\" nor the Interface \"SimplePresence\". Other interfaces are not supported!" );
+ return;
+}
+
+
diff --git a/TelepathyQt4/Prototype/PresenceManager.h b/TelepathyQt4/Prototype/PresenceManager.h
new file mode 100644
index 0000000..1a9c8cd
--- /dev/null
+++ b/TelepathyQt4/Prototype/PresenceManager.h
@@ -0,0 +1,151 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef TelepathyQt4_Prototype_PresenceManager_H_
+#define TelepathyQt4_Prototype_PresenceManager_H_
+
+#include <QDBusObjectPath>
+#include <QObject>
+#include <QPointer>
+
+#include <TelepathyQt4/Types>
+
+namespace Telepathy
+{
+ namespace Client
+ {
+ class ConnectionInterface;
+ }
+}
+
+namespace TpPrototype {
+
+class PresenceManagerPrivate;
+class Connection;
+class Contact;
+class Account;
+
+/**
+ * @ingroup qt_connection
+ * This class manages presence information for one connection.
+ * Whenever a contact presence changes, the signal signalRemotePresencesUpdated() is emitted. This signal provides the related contact object
+ * obtained from the ContactManager.
+ * In order to keep the contacts updated, you just have to instantiate this class (by requesting the object with Connection::presenceManager())
+ * and initialize the list of contacts once (by calling presencesForContacts() ). After this point, the presence information of the contact
+ * is updated automatically if a change is signalled by the backend.<br>
+ * <br>
+ * <b>Info:</b> The deprecated interface "org.freedesktop.Telepathy.Channel.Interface.Presence" is used as fallback, if the interface
+ * "org.freedesktop.Telepathy.Channel.Interface.SimplePresence" is not supported by the connection manager. Thus, a wide range of
+ * connection managers should work with this class.
+
+ * @see Connection
+ */
+class PresenceManager : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Validity.
+ * Do not access any methods if the object is invalid!
+ */
+ bool isValid();
+
+ /**
+ * Supported statuses.
+ * Returns the list of supported status states. The list may change if the status of the connection changes from <i>disconnected</i> to <i>connected</i>.
+ * @return The list of supported statuses.
+ * @see connection::status();
+ */
+ Telepathy::SimpleStatusSpecMap statuses();
+
+ /**
+ * Set Presence.
+ * Request that the presence status and status message are published for the connection. Changes will be indicated by
+ * signal signalOwnPresenceUpdated().
+ * @param status The state to set the presence to as returned by statuses().
+ * @see signalOwnPresenceUpdated().;
+ */
+ bool setPresence( const QString& status, const QString& statusMessage );
+
+ /**
+ * Gets local presence.
+ * The local presence is returned for the connection.
+ * @return Returns my current local presence or an empty item on error.
+ */
+ Telepathy::SimplePresence currentPresence();
+
+ /**
+ * Request presences.
+ * Requests a list of presences for the given list of contacts.
+ * @param contacts List of contacts.
+ * @return List of presence information for contacts as <i>QMap<int,SimplePresence> </i>. The <i>int</i> represents the
+ * identifier of the contact as returned by Contact::identifier(), An empty list is returned on error.
+ * @todo Future: Use QList<Contact> instead QList<QPointer<Contact> > or introduce a class <i>ContactGroup</i> that handles all internally.
+ * @todo Future: Telepathy::SimpleContactPresences relies of an handle (the <i>int</i>). This should be encapsulated.
+ */
+ Telepathy::SimpleContactPresences presencesForContacts( const QList<QPointer<TpPrototype::Contact> >& contacts );
+
+ /**
+ * Returns the connection that belongs to this presence information.
+ * @return The connection object
+ */
+ TpPrototype::Connection* connection();
+
+signals:
+ /**
+ * Presences of remote contacts are changed.
+ * This signal is emitted when the presence state of a remote contact is changed.
+ * @param contact The contact that changes.
+ * @param presence The presence information.
+ */
+ void signalRemotePresencesUpdated( TpPrototype::Contact* contact, const Telepathy::SimplePresence& presence );
+
+ /**
+ * Local presence changed.
+ * This signal is emitted when the local presence state was changed.
+ * @param account The account that changes.
+ * @param presence The presence information.
+ */
+ void signalOwnPresenceUpdated( const TpPrototype::Account* account, const Telepathy::SimplePresence& presence );
+
+protected:
+ /**
+ * Constructor. The presence manager cannot be instantiated directly. Use Connection::presenceManager() for it!
+ */
+ PresenceManager( TpPrototype::Connection* connection,
+ Telepathy::Client::ConnectionInterface* interface,
+ QObject* parent = NULL );
+ ~PresenceManager();
+
+protected slots:
+ void slotPresencesChanged( const Telepathy::SimpleContactPresences& presences );
+ void slotPresencesUpdate( const Telepathy::ContactPresences& presences );
+private:
+ void init();
+
+ TpPrototype::PresenceManagerPrivate * const d;
+ friend class Connection;
+ friend class ConnectionPrivate;
+};
+}
+
+
+#endif
diff --git a/TelepathyQt4/Prototype/StreamedMediaChannel.cpp b/TelepathyQt4/Prototype/StreamedMediaChannel.cpp
new file mode 100644
index 0000000..a4724cb
--- /dev/null
+++ b/TelepathyQt4/Prototype/StreamedMediaChannel.cpp
@@ -0,0 +1,578 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "TelepathyQt4/Prototype/StreamedMediaChannel.h"
+
+#include <QDebug>
+#include <QMetaProperty>
+
+#include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/Channel>
+
+#include <TelepathyQt4/Prototype/Client/ChannelHandler>
+#include <TelepathyQt4/Prototype/ConnectionFacade.h>
+#include <TelepathyQt4/Prototype/Contact.h>
+#include <TelepathyQt4/Prototype/ContactManager.h>
+
+#define ENABLE_DEBUG_OUTPUT_
+
+using namespace TpPrototype;
+
+class TpPrototype::StreamedMediaChannelPrivate
+{
+public:
+ StreamedMediaChannelPrivate()
+ { init(); }
+
+ QPointer<TpPrototype::Contact> m_pContact;
+ QPointer<Telepathy::Client::ConnectionInterface> m_pConnectionInterface;
+ Telepathy::Client::ChannelTypeStreamedMediaInterface* m_pStreamedMediaInterface;
+ Telepathy::Client::ChannelInterfaceGroupInterface* m_pGroupInterface;
+ Telepathy::Client::ChannelInterfaceMediaSignallingInterface* m_pMediaSignallingInterface;
+ Telepathy::Client::ChannelInterfaceCallStateInterface* m_pCallStateInterface;
+ TpPrototype::Client::ChannelHandlerInterface* m_pStreamEngineHandlerInterface;
+
+ bool m_isValid;
+
+ uint localHandle()
+ {
+ int self_handle = ConnectionFacade::instance()->selfHandleForConnectionInterface( m_pConnectionInterface );
+ Q_ASSERT( self_handle >= 0 );
+ return (uint) self_handle;
+ }
+
+private:
+ void init()
+ {
+ m_pContact = NULL;
+ m_pConnectionInterface = NULL;
+ m_pStreamedMediaInterface = NULL;
+ m_pCallStateInterface = NULL;
+ m_pMediaSignallingInterface = NULL;
+ m_pStreamEngineHandlerInterface = NULL;
+ m_pGroupInterface = NULL;
+ m_isValid = true;
+ }
+};
+
+StreamedMediaChannel::StreamedMediaChannel( Contact* contact, Telepathy::Client::ConnectionInterface* connectionInterface, QObject* parent ):
+ QObject( parent ),
+ d(new StreamedMediaChannelPrivate())
+{
+ Telepathy::registerTypes();
+
+ d->m_pContact = contact;
+ d->m_pConnectionInterface = connectionInterface;
+
+ //requestTextChannel( d->m_pContact->telepathyHandle() );
+}
+
+StreamedMediaChannel::~StreamedMediaChannel()
+ { delete d; }
+
+bool StreamedMediaChannel::isValid() const
+{ return d->m_isValid; }
+
+// This functions adds the local handle from the group of local pending members into the group of members.
+bool StreamedMediaChannel::acceptIncomingStream()
+{
+ QList<uint> accept_handles;
+ accept_handles << d->localHandle();
+
+ return addMembers( accept_handles );
+}
+
+bool StreamedMediaChannel::rejectIncomingStream()
+{
+ QList<uint> reject_handles;
+ reject_handles << d->localHandle();
+
+ return removeMembers( reject_handles );
+}
+
+bool StreamedMediaChannel::requestChannel( QList<Telepathy::MediaStreamType> types )
+{
+ Q_ASSERT( d->m_pConnectionInterface );
+ Q_ASSERT( d->m_pContact );
+ if ( !d->m_pConnectionInterface
+ || !d->m_pContact )
+ {
+ return false;
+ }
+
+ QDBusPendingReply<QDBusObjectPath> request_channel_reply = d->m_pConnectionInterface->RequestChannel( Telepathy::Client::ChannelTypeStreamedMediaInterface::staticInterfaceName(),
+ Telepathy::HandleTypeNone,
+ 0,
+ true );
+ request_channel_reply.waitForFinished();
+
+ if ( !request_channel_reply.isValid() )
+ {
+ QDBusError error = request_channel_reply.error();
+
+ qWarning() << "RequestChannel: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+
+ requestStreamedMediaChannel( d->m_pContact->telepathyHandle() );
+
+ //Q_ASSERT( d->m_pStreamedMediaInterface );
+ if ( !d->m_pStreamedMediaInterface )
+ {
+ return false;
+ }
+
+
+ QList<uint> stream_types;
+ foreach( uint type, types )
+ {
+ stream_types << type;
+ }
+
+
+ QDBusPendingReply<Telepathy::MediaStreamInfoList> request_streams_reply = d->m_pStreamedMediaInterface->RequestStreams( d->m_pContact->telepathyHandle(),
+ stream_types );
+ request_streams_reply.waitForFinished();
+
+ if ( !request_streams_reply.isValid() )
+ {
+ QDBusError error = request_streams_reply.error();
+
+ qWarning() << "RequestStreams: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+
+ // Fall through..
+ return true;
+}
+
+bool StreamedMediaChannel::addContactsToGroup( QList<QPointer<TpPrototype::Contact> > contacts )
+{
+ QList<uint> handle_list;
+
+ foreach( TpPrototype::Contact* contact, contacts )
+ {
+ if ( !contact )
+ { continue; }
+
+ handle_list.append( contact->telepathyHandle() );
+ }
+
+ return addMembers( handle_list );
+}
+
+QList<QPointer<TpPrototype::Contact> > StreamedMediaChannel::localPendingContacts()
+{
+ QList<QPointer<TpPrototype::Contact> > local_pending_members;
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Local Pending members : ";
+#endif
+ foreach( Telepathy::LocalPendingInfo local_pending_info, d->m_pGroupInterface->LocalPendingMembers() )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "To be added: " << local_pending_info.toBeAdded;
+ qDebug() << "Actor : " << local_pending_info.actor;
+ qDebug() << "Reason : " << local_pending_info.reason;
+ qDebug() << "Message : " << local_pending_info.message;
+#endif
+ local_pending_members.append( d->m_pContact->contactManager()->contactForHandle( local_pending_info.toBeAdded ) );
+ }
+ return local_pending_members;
+}
+
+QList<QPointer<TpPrototype::Contact> > StreamedMediaChannel::members()
+{
+ Telepathy::UIntList member_handles = d->m_pGroupInterface->Members();
+
+ QList<QPointer<TpPrototype::Contact> > member_list;
+
+ foreach( uint member_handle, member_handles )
+ {
+ member_list.append( d->m_pContact->contactManager()->contactForHandle( member_handle ) );
+ }
+
+ return member_list;
+}
+
+
+// Protected functions
+
+// Called if a new media channel shall be established.
+void StreamedMediaChannel::requestStreamedMediaChannel( uint handle )
+{
+ // Ignore this call if the media channel is already available
+ if ( d->m_pStreamedMediaInterface )
+ {
+ delete d->m_pStreamedMediaInterface;
+ d->m_pStreamedMediaInterface = NULL;
+ }
+
+ QDBusPendingReply<QDBusObjectPath> reply0 = d->m_pConnectionInterface->RequestChannel( "org.freedesktop.Telepathy.Channel.Type.StreamedMedia",
+ Telepathy::HandleTypeContact,
+ handle,
+ true );
+ reply0.waitForFinished();
+ if (!reply0.isValid())
+ {
+ QDBusError error = reply0.error();
+ qWarning() << "RequestChannel (Type: StreamedMedia): error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+ d->m_isValid = false;
+ return;
+ }
+ QDBusObjectPath channel_path=reply0.value();
+ d->m_pStreamedMediaInterface = new Telepathy::Client::ChannelTypeStreamedMediaInterface( d->m_pConnectionInterface->service(), channel_path.path(), this );
+ connectSignals();
+}
+
+
+// Called if a new streamed media channel was notified by the connection
+void StreamedMediaChannel::openStreamedMediaChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelType )
+{
+ Q_ASSERT( d->m_pConnectionInterface );
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "StreamedMediaChannel::openStreamedMediaChannel(): handle:" << handle
+ << "handleType:" << handleType
+ << "channel path: " << channelPath
+ << "Channel Type:" << channelType;
+#endif
+
+ QString channel_service_name = d->m_pConnectionInterface->service();
+
+ if ( !d->m_pStreamedMediaInterface )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Create new ChannelTypeStreamedMediaInterface";
+#endif
+ d->m_pStreamedMediaInterface = new Telepathy::Client::ChannelTypeStreamedMediaInterface( channel_service_name, channelPath, this );
+ connectSignals();
+ }
+ if (!d->m_pStreamedMediaInterface->isValid())
+ {
+ qWarning() << "Failed to connect streamed media interface class to D-Bus object.";
+ delete d->m_pStreamedMediaInterface;
+ d->m_pStreamedMediaInterface = NULL;
+ d->m_isValid = false;
+ return;
+ }
+ else
+ {
+ // Obtain the group and callstate interfaces.
+ QString streamed_media_service_name = d->m_pStreamedMediaInterface->service();
+
+ // I don't know why, but I have to reinitialize the group channel every time..
+ if ( d->m_pGroupInterface )
+ {
+ delete d->m_pGroupInterface;
+ d->m_pGroupInterface = NULL;
+ }
+
+ if ( !d->m_pGroupInterface )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Initialize ChannelInterfaceGroupInterface..";
+#endif
+ d->m_pGroupInterface = new Telepathy::Client::ChannelInterfaceGroupInterface( streamed_media_service_name,
+ channelPath );
+
+ connect( d->m_pGroupInterface, SIGNAL( MembersChanged(const QString& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ uint ,
+ uint )
+ ),
+ this, SLOT( slotMembersChanged(const QString& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ const Telepathy::UIntList& ,
+ uint ,
+ uint )
+ )
+ );
+
+
+ }
+
+ if ( !d->m_pCallStateInterface )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Initialize ChannelInterfaceCallStateInterface..";
+#endif
+ d->m_pCallStateInterface = new Telepathy::Client::ChannelInterfaceCallStateInterface( streamed_media_service_name,
+ channelPath );
+ }
+
+ if ( !d->m_pMediaSignallingInterface )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Initialize ChannelInterfaceMediaSignallingInterface..";
+#endif
+ d->m_pMediaSignallingInterface = new Telepathy::Client::ChannelInterfaceMediaSignallingInterface( streamed_media_service_name, channelPath );
+ }
+
+ if ( !d->m_pStreamEngineHandlerInterface )
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Initialize ChannelHandlerInterface..";
+#endif
+ d->m_pStreamEngineHandlerInterface = new TpPrototype::Client::ChannelHandlerInterface( "org.freedesktop.Telepathy.StreamEngine",
+ "/org/freedesktop/Telepathy/StreamEngine",
+ this );
+ }
+
+ Q_ASSERT( d->m_pCallStateInterface->isValid() );
+ // Q_ASSERT( d->m_pGroupInterface->isValid() );
+ Q_ASSERT( d->m_pMediaSignallingInterface->isValid() );
+ Q_ASSERT( d->m_pStreamEngineHandlerInterface->isValid() );
+
+ // Cleanup if we were unable to establish interfaces..
+ if ( d->m_pGroupInterface && !d->m_pGroupInterface->isValid() )
+ {
+ qWarning() << "Could not establish interface:" << Telepathy::Client::ChannelInterfaceGroupInterface::staticInterfaceName();
+ delete d->m_pGroupInterface;
+ d->m_pGroupInterface = NULL;
+ }
+
+ if ( d->m_pCallStateInterface && !d->m_pCallStateInterface->isValid() )
+ {
+ qWarning() << "Could not establish interface:" << Telepathy::Client::ChannelInterfaceCallStateInterface::staticInterfaceName();
+ delete d->m_pCallStateInterface;
+ d->m_pCallStateInterface = NULL;
+ }
+
+ if ( d->m_pMediaSignallingInterface && !d->m_pMediaSignallingInterface->isValid() )
+ {
+ qWarning() << "Could not establish interface:" << Telepathy::Client::ChannelInterfaceMediaSignallingInterface::staticInterfaceName();
+ delete d->m_pMediaSignallingInterface;
+ d->m_pMediaSignallingInterface = NULL;
+ }
+
+ // Now use the streaming engine to handle this media channel
+ if ( d->m_pStreamEngineHandlerInterface && !d->m_pStreamEngineHandlerInterface->isValid() )
+ {
+ qWarning() << "Could not establish interface:" << TpPrototype::Client::ChannelHandlerInterface::staticInterfaceName();
+ delete d->m_pStreamEngineHandlerInterface;
+ d->m_pStreamEngineHandlerInterface = NULL;
+
+ // This is fatal, cause we need this interface
+ d->m_isValid = false;
+ qWarning() << "The interface:" << TpPrototype::Client::ChannelHandlerInterface::staticInterfaceName() << "is required! We will be unable to handle this call!";
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Now delegate stream to stream-engine by calling HandleChannel()";
+#endif
+ QDBusPendingReply<> handle_channel_reply = d->m_pStreamEngineHandlerInterface->HandleChannel( d->m_pConnectionInterface->service(),
+ QDBusObjectPath( d->m_pConnectionInterface->path() ),
+ channelType,
+ QDBusObjectPath( channelPath ),
+ handleType,
+ handle );
+
+ handle_channel_reply.waitForFinished();
+
+ if ( !handle_channel_reply.isValid() )
+ {
+ QDBusError error = handle_channel_reply.error();
+
+ qWarning() << "HandleChannel: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ d->m_isValid = false;
+ return ;
+ }
+ }
+
+ }
+
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "Telling the world about new channel (signalIncomingChannel())";
+#endif
+ emit signalIncomingChannel( d->m_pContact );
+
+}
+
+void StreamedMediaChannel::connectSignals()
+{
+ connect( d->m_pStreamedMediaInterface, SIGNAL( StreamAdded(uint , uint , uint ) ),
+ this, SLOT( slotStreamAdded(uint , uint , uint ) ) );
+ connect( d->m_pStreamedMediaInterface, SIGNAL( StreamDirectionChanged(uint , uint , uint ) ),
+ this, SLOT( slotStreamDirectionChanged(uint , uint , uint ) ) );
+ connect( d->m_pStreamedMediaInterface, SIGNAL( StreamError(uint , uint , const QString& ) ),
+ this, SLOT( slotStreamError(uint , uint , const QString& ) ) );
+ connect( d->m_pStreamedMediaInterface, SIGNAL( StreamRemoved(uint) ),
+ this, SLOT( slotStreamRemoved(uint) ) );
+ connect( d->m_pStreamedMediaInterface, SIGNAL( StreamStateChanged(uint , uint ) ),
+ this, SLOT( slotStreamStateChanged(uint , uint ) ) );
+}
+
+bool StreamedMediaChannel::addMembers( QList<uint> handles )
+{
+ if ( !d->m_pGroupInterface )
+ {
+ qWarning() << "StreamedMediaChannel::addMembers: No group channel found. Ignore call ..";
+ return false;
+ }
+
+ QDBusPendingReply<> add_members_reply = d->m_pGroupInterface->AddMembers( handles, "Welcome!" );
+ add_members_reply.waitForFinished();
+
+ if ( !add_members_reply.isValid() )
+ {
+ QDBusError error = add_members_reply.error();
+
+ qWarning() << "AddMembers: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+ return true;
+}
+
+bool StreamedMediaChannel::removeMembers( QList<uint> handles )
+{
+ if ( !d->m_pGroupInterface )
+ {
+ qWarning() << "StreamedMediaChannel::removeMembers: No group channel found. Ignore call ..";
+ return false;
+ }
+
+ QDBusPendingReply<> remove_members_reply = d->m_pGroupInterface->RemoveMembers( handles, "Bye-bye!!" );
+ remove_members_reply.waitForFinished();
+
+ if ( !remove_members_reply.isValid() )
+ {
+ QDBusError error = remove_members_reply.error();
+
+ qWarning() << "RemoveMembers: error type:" << error.type()
+ << "error name:" << error.name()
+ << "error message:" << error.message();
+
+ return false;
+ }
+ return true;
+}
+
+
+void StreamedMediaChannel::slotStreamAdded(uint streamID, uint contactHandle, uint streamType)
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__ << "streamID:" << streamID << "contactHandle: " << contactHandle << "streamType:" << streamType;
+#endif
+ emit signalStreamAdded( d->m_pContact->contactManager()->contactForHandle( contactHandle ), streamID, static_cast<Telepathy::MediaStreamType>(streamType) );
+}
+
+void StreamedMediaChannel::slotStreamDirectionChanged(uint streamID, uint streamDirection, uint pendingFlags)
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__ << "streamID:" << streamID << "streamDirection: " << streamDirection << "pendingFlags:" << pendingFlags;
+#endif
+}
+
+void StreamedMediaChannel::slotStreamError(uint streamID, uint errorCode, const QString& message)
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__ << "streamID:" << streamID << "errorCode: " << errorCode << "message:" << message;
+#endif
+}
+
+void StreamedMediaChannel::slotStreamRemoved(uint streamID)
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__ << "streamID:" << streamID;
+#endif
+ emit signalStreamRemoved( streamID );
+}
+
+void StreamedMediaChannel::slotStreamStateChanged(uint streamID, uint streamState)
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__ << "streamID:" << streamID << "streamState: " << streamState;
+#endif
+}
+
+void StreamedMediaChannel::slotMembersChanged( const QString& message,
+ const Telepathy::UIntList& added,
+ const Telepathy::UIntList& removed,
+ const Telepathy::UIntList& localPending,
+ const Telepathy::UIntList& remotePending,
+ uint actor,
+ uint reason )
+{
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << __PRETTY_FUNCTION__
+ << "message:" << message
+ << "added:" << added
+ << "removed:" << removed
+ << "localPending:" << localPending
+ << "remotePending:" << remotePending
+ << "actor:" << actor
+ << "reason:" << reason;
+#endif
+ uint local_handle = d->localHandle();
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "local handle: " << local_handle;
+#endif
+ if ( !added.isEmpty() )
+ {
+ foreach ( uint handle, added )
+ {
+ if ( handle == local_handle )
+ { continue; }
+ emit signalContactAdded( d->m_pContact->contactManager()->contactForHandle( handle ) );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "signalContactAdded: " << handle;
+#endif
+ }
+ }
+
+ if ( !removed.isEmpty() )
+ {
+ foreach ( uint handle, removed )
+ {
+ if ( handle == local_handle )
+ { continue; }
+ emit signalContactRemoved( d->m_pContact->contactManager()->contactForHandle( handle ) );
+#ifdef ENABLE_DEBUG_OUTPUT_
+ qDebug() << "signalContactRemoved: " << handle;
+#endif
+ }
+ }
+}
+
+
diff --git a/TelepathyQt4/Prototype/StreamedMediaChannel.h b/TelepathyQt4/Prototype/StreamedMediaChannel.h
new file mode 100644
index 0000000..daf68f3
--- /dev/null
+++ b/TelepathyQt4/Prototype/StreamedMediaChannel.h
@@ -0,0 +1,229 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 basysKom GmbH
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TelepathyQt4_Prototype_StreamedMediaChannel_H_
+#define TelepathyQt4_Prototype_StreamedMediaChannel_H_
+
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/Channel>
+
+#include <QObject>
+#include <QVariantMap>
+#include <QPointer>
+
+#ifdef DEPRECATED_ENABLED__
+#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define ATTRIBUTE_DEPRECATED
+#endif
+
+
+namespace TpPrototype {
+
+class StreamedMediaChannelPrivate;
+class Contact;
+class Account;
+
+/**
+ * @ingroup qt_connection
+ * StreamedMedia Channel for VoIP and Video Over IP.
+ * <b>Hint:</b> You have to set the right capabilities with CapabilitiesManager::setCapabilities() before VoIP or Video over IP will work!
+ * @see CapabiltiesManager
+ */
+class StreamedMediaChannel : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Validity check.
+ * Do not access any functions if this account is invalid.
+ */
+ bool isValid() const;
+
+ /**
+ * Destructor.
+ * Deleting this object forces to drop all channels.
+ */
+ ~StreamedMediaChannel();
+
+ /**
+ * Accept the incoming media stream (call).
+ * This function must be called to accept the incoming media stream.
+ * @return Returns true if command was successful.
+ */
+ bool acceptIncomingStream();
+
+ /**
+ * Reject the incoming media stream (call).
+ * This function should be called if an incoming call should be rejected.
+ * @return Returns true if command was successful.
+ */
+ bool rejectIncomingStream();
+
+ /**
+ * Request outgoing media channel (call).
+ * Ask remote contact to start a media channel.
+ * @todo Describe what happens after this call ..
+ * @param types The stream types that should be opened for this channel
+ * @return Returns true if request call was successful.
+ */
+ bool requestChannel( QList<Telepathy::MediaStreamType> types );
+
+ /**
+ * Add contacts to the group.
+ * Multiple contacts may sharing the same stream. Use this function to invite a contact to this group. The contact will
+ * be added to the group after he accepted the invitation.
+ * @return Returns true if command was successful.
+ */
+ bool addContactsToGroup( QList<QPointer<TpPrototype::Contact> > contacts );
+
+ /**
+ * Returns a list of contacts that are waiting locally for accaptance.
+ * A Contact that is local pending has requested membership of the channel, but the local user of the framework must
+ * accept their request before they may join.
+ * @return Returns the list of contacts that are waiting for acceptance.
+ */
+ QList<QPointer<TpPrototype::Contact> > localPendingContacts();
+
+ /**
+ * Returns the list of members in the group.
+ * The StreamedMediaChannel contains a group of members that currently part of the group.
+ * @return Returns the list of contacts that are currently group members.
+ */
+ QList<QPointer<TpPrototype::Contact> > members();
+
+signals:
+ /**
+ * Incoming channel detected.
+ * This signal is emitted when a valid incoming channel was detected and all needed interfaces were established successfully.
+ * Usually it does not make sense to connect to this signal, because this object might be created or removed without any prior notification. Thus,
+ * there is no chance to connect before this signal is emitted.<br>
+ * Use ContactManager::signalStreamedMediaChannelOpenedForContact() instead to get informed about new channels!
+ * @param contact The contact that contains this StreamedMediaChannel object.
+ * @see ContactManager
+ */
+ void signalIncomingChannel( TpPrototype::Contact* contact );
+
+ /**
+ * A stream was added.
+ * If a new stream was added to this media channel.
+ * @param contact The contact that belongs to this media channel
+ * @param streamId The id of the stream.
+ * @param streamType The type of the stream.
+ */
+ void signalStreamAdded( TpPrototype::Contact* contact, uint streamId, Telepathy::MediaStreamType streamType );
+
+ /**
+ * Stream was removed.
+ * This signal is emmitted when a media stream was removed. This may happen on network errors, if the remote contact
+ * rejected the call or if the established connection was closed.
+ * @param streamId The id of the stream.
+ */
+ void signalStreamRemoved( uint streamId );
+
+ /**
+ * A remove contact was added.
+ * This signal has different meaning with regard to the context:
+ * <ul><li>Outgoing call: The remote contact accapted the call</li>
+ * <li><i>Please add further situations</i></li>
+ * </ul>
+ */
+ void signalContactAdded( TpPrototype::Contact* acceptingContact );
+
+ /**
+ * Call was canceled by remote contact.
+ * This signal has different meaning with regard to the context:
+ * <ul><li>Ongoing chat: The remote contact disconnected</li>
+ * <li><i>Please add further situations</i></li>
+ * </ul>
+ */
+ void signalContactRemoved( TpPrototype::Contact* rejectingContact );
+protected:
+ /**
+ * Constructor.
+ * Use Contact::streamedMediaChannel() to obtain an object of StreamedMediaChannel.
+ */
+ StreamedMediaChannel( Contact* contact, Telepathy::Client::ConnectionInterface* connectionInterface , QObject* parent = NULL );
+
+ /**
+ * Request a new streamed media channel.
+ * This functions needs to be called if a new streamed media channel D-BUS object should be established.
+ */
+ void requestStreamedMediaChannel( uint handle );
+
+ /**
+ * Called internally to notify that a new media channel object was stablished on D-BUS.
+ */
+ void openStreamedMediaChannel( uint handle, uint handleType, const QString& channelPath, const QString& channelType );
+
+ /** Connect slots to channel signals */
+ void connectSignals();
+
+ bool addMembers( QList<uint> handles );
+
+ bool removeMembers( QList<uint> handles );
+
+protected slots:
+ /**
+ * Represents the signal "slotStreamAdded" on the remote object.
+ */
+ void slotStreamAdded(uint streamID, uint contactHandle, uint streamType);
+
+ /**
+ * Represents the signal "StreamDirectionChanged" on the remote object.
+ */
+ void slotStreamDirectionChanged(uint streamID, uint streamDirection, uint pendingFlags);
+
+ /**
+ * Represents the signal "StreamError" on the remote object.
+ */
+ void slotStreamError(uint streamID, uint errorCode, const QString& message);
+
+ /**
+ * Represents the signal "StreamRemoved" on the remote object.
+ */
+ void slotStreamRemoved(uint streamID);
+
+ /**
+ * Represents the signal "StreamStateChanged" on the remote object.
+ */
+ void slotStreamStateChanged(uint streamID, uint streamState);
+
+ /**
+ * Represents the signal "MembersChanged" on the remote object.
+ */
+ void slotMembersChanged(const QString& message,
+ const Telepathy::UIntList& added,
+ const Telepathy::UIntList& removed,
+ const Telepathy::UIntList& localPending,
+ const Telepathy::UIntList& remotePending,
+ uint actor,
+ uint reason);
+private:
+ StreamedMediaChannelPrivate * const d;
+ friend class ContactManager;
+ friend class Contact;
+};
+
+} // namespace
+
+#endif // Header guard
diff --git a/TelepathyQt4/Prototype/TpQt4Prototype.pc.in b/TelepathyQt4/Prototype/TpQt4Prototype.pc.in
new file mode 100644
index 0000000..e62070d
--- /dev/null
+++ b/TelepathyQt4/Prototype/TpQt4Prototype.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: TpQt4Prototype
+Description: Transitional Qt4 utility library for the Telepathy framework
+Version: @VERSION@
+Requires.private: QtCore >= 4.5, QtDBus >= 4.5, TelepathyQt4 >= @VERSION@
+Libs: -L${libdir} -ltpqt4-prototype
+Cflags: -I${includedir}/tpqt4-prototype
diff --git a/TelepathyQt4/Prototype/Types b/TelepathyQt4/Prototype/Types
new file mode 100644
index 0000000..59ee649
--- /dev/null
+++ b/TelepathyQt4/Prototype/Types
@@ -0,0 +1,6 @@
+#ifndef _TelepathyQt4_Prototype_Types_HEADER_GUARD_
+#define _TelepathyQt4_Prototype_Types_HEADER_GUARD_
+
+#include <TelepathyQt4/Prototype/types.h>
+
+#endif
diff --git a/TelepathyQt4/Prototype/all.xml b/TelepathyQt4/Prototype/all.xml
new file mode 100644
index 0000000..011e479
--- /dev/null
+++ b/TelepathyQt4/Prototype/all.xml
@@ -0,0 +1,9 @@
+<tp:spec
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <tp:title>Prototype/transitional spec extensions</tp:title>
+
+<xi:include href="channel-handler.xml"/>
+
+</tp:spec>
diff --git a/TelepathyQt4/Prototype/channel-handler.xml b/TelepathyQt4/Prototype/channel-handler.xml
new file mode 100644
index 0000000..71c9c7e
--- /dev/null
+++ b/TelepathyQt4/Prototype/channel-handler.xml
@@ -0,0 +1,9 @@
+<tp:spec
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<tp:title>Old ChannelHandler interface</tp:title>
+
+<xi:include href="../../spec/Channel_Handler.xml"/>
+
+</tp:spec>
diff --git a/TelepathyQt4/Prototype/constants.h b/TelepathyQt4/Prototype/constants.h
new file mode 100644
index 0000000..79fd647
--- /dev/null
+++ b/TelepathyQt4/Prototype/constants.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _TelepathyQt4_Prototype_constants_h_HEADER_GUARD_
+#define _TelepathyQt4_Prototype_constants_h_HEADER_GUARD_
+
+#include <TelepathyQt4/Prototype/_gen/constants.h>
+
+#endif
diff --git a/TelepathyQt4/Prototype/types.cpp b/TelepathyQt4/Prototype/types.cpp
new file mode 100644
index 0000000..12aeb7c
--- /dev/null
+++ b/TelepathyQt4/Prototype/types.cpp
@@ -0,0 +1,22 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "_gen/types-body.hpp"
diff --git a/TelepathyQt4/Prototype/types.h b/TelepathyQt4/Prototype/types.h
new file mode 100644
index 0000000..d94e621
--- /dev/null
+++ b/TelepathyQt4/Prototype/types.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _TelepathyQt4_Prototype_types_h_HEADER_GUARD_
+#define _TelepathyQt4_Prototype_types_h_HEADER_GUARD_
+
+#include <TelepathyQt4/Prototype/_gen/types.h>
+
+#endif
diff --git a/configure.ac b/configure.ac
index 92f283b..c29af6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,8 @@ AC_OUTPUT( Makefile \
spec/Makefile \
TelepathyQt4/Makefile \
TelepathyQt4/TelepathyQt4.pc \
+ TelepathyQt4/Prototype/Makefile \
+ TelepathyQt4/Prototype/TpQt4Prototype.pc \
tools/Makefile \
m4/Makefile \
examples/Makefile \
--
1.5.6.5
More information about the Telepathy-commits
mailing list