[Telepathy-commits] [telepathy-qt4/master] roster example: Make a shared library that can be used by other examples.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Fri Mar 13 14:14:03 PDT 2009


---
 examples/roster/Makefile.am       |   26 ++++++--
 examples/roster/main.cpp          |    4 +-
 examples/roster/roster-widget.cpp |  120 ++++++++++++++++-------------------
 examples/roster/roster-widget.h   |   28 +++++---
 examples/roster/roster-window.cpp |  127 +++++++++++++++++++++++++++++++++++++
 examples/roster/roster-window.h   |   65 +++++++++++++++++++
 6 files changed, 286 insertions(+), 84 deletions(-)
 create mode 100644 examples/roster/roster-window.cpp
 create mode 100644 examples/roster/roster-window.h

diff --git a/examples/roster/Makefile.am b/examples/roster/Makefile.am
index 6553f3c..cf39a2a 100644
--- a/examples/roster/Makefile.am
+++ b/examples/roster/Makefile.am
@@ -5,25 +5,41 @@ AM_CXXFLAGS = \
 	$(QTDBUS_CFLAGS) \
 	$(TP_QT4_CFLAGS)
 
-noinst_PROGRAMS = roster
+noinst_LTLIBRARIES = libtelepathy-qt4-examples-roster.la
 
-roster_LDADD = \
+libtelepathy_qt4_examples_roster_la_LIBADD = \
 	$(QTGUI_LIBS) \
 	$(QTDBUS_LIBS) \
 	$(top_builddir)/TelepathyQt4/libtelepathy-qt4.la
 
-roster_SOURCES = \
-	main.cpp \
+libtelepathy_qt4_examples_roster_la_SOURCES = \
 	roster-item.cpp \
 	roster-item.h \
 	roster-widget.cpp \
 	roster-widget.h
 
-nodist_roster_SOURCES = \
+nodist_libtelepathy_qt4_examples_roster_la_SOURCES = \
 	_gen/roster-item.moc.hpp \
 	_gen/roster-widget.moc.hpp
 
+noinst_PROGRAMS = roster
+
+roster_LDADD = \
+	$(QTGUI_LIBS) \
+	$(QTDBUS_LIBS) \
+	$(top_builddir)/TelepathyQt4/libtelepathy-qt4.la \
+	libtelepathy-qt4-examples-roster.la
+
+roster_SOURCES = \
+	main.cpp \
+	roster-window.cpp \
+	roster-window.h
+
+nodist_roster_SOURCES = \
+	_gen/roster-window.moc.hpp
+
 BUILT_SOURCES = \
+	$(nodist_libtelepathy_qt4_examples_roster_la_SOURCES) \
 	$(nodist_roster_SOURCES)
 
 CLEANFILES = \
diff --git a/examples/roster/main.cpp b/examples/roster/main.cpp
index d886baa..5d39880 100644
--- a/examples/roster/main.cpp
+++ b/examples/roster/main.cpp
@@ -5,7 +5,7 @@
 #include <QDebug>
 #include <QtGui>
 
-#include "roster-widget.h"
+#include "roster-window.h"
 
 int main(int argc, char **argv)
 {
@@ -20,7 +20,7 @@ int main(int argc, char **argv)
     Telepathy::enableDebug(true);
     Telepathy::enableWarnings(true);
 
-    RosterWidget w(argv[1], argv[2]);
+    RosterWindow w(argv[1], argv[2]);
     w.show();
 
     return app.exec();
diff --git a/examples/roster/roster-widget.cpp b/examples/roster/roster-widget.cpp
index 5820c7d..60c4c6d 100644
--- a/examples/roster/roster-widget.cpp
+++ b/examples/roster/roster-widget.cpp
@@ -24,8 +24,6 @@
 #include "roster-item.h"
 
 #include <TelepathyQt4/Types>
-#include <TelepathyQt4/Client/Connection>
-#include <TelepathyQt4/Client/ConnectionManager>
 #include <TelepathyQt4/Client/Contact>
 #include <TelepathyQt4/Client/ContactManager>
 #include <TelepathyQt4/Client/PendingConnection>
@@ -48,27 +46,32 @@
 
 using namespace Telepathy::Client;
 
-RosterWidget::RosterWidget(const QString &username, const QString &password,
-        QWidget *parent)
-    : QWidget(parent),
-      mUsername(username),
-      mPassword(password)
+RosterWidget::RosterWidget(QWidget *parent)
+    : QWidget(parent)
 {
     setWindowTitle("Roster");
 
     createActions();
     setupGui();
+}
 
-    mCM = new ConnectionManager("gabble", this);
-    connect(mCM->becomeReady(),
-            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
-            SLOT(onCMReady(Telepathy::Client::PendingOperation *)));
+RosterWidget::~RosterWidget()
+{
+}
 
-    resize(240, 320);
+void RosterWidget::addConnection(Connection *conn)
+{
+    mConns.append(conn);
+    connect(conn->becomeReady(Connection::FeatureRoster),
+            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+            SLOT(onConnectionReady(Telepathy::Client::PendingOperation *)));
 }
 
-RosterWidget::~RosterWidget()
+void RosterWidget::removeConnection(Connection *conn)
 {
+    // TODO remove all contacts from this connection
+    //      if there is only one connection left, disable all actions/buttons
+    mConns.removeOne(conn);
 }
 
 void RosterWidget::createActions()
@@ -146,57 +149,20 @@ void RosterWidget::setupGui()
     mAddDlg->setLayout(addDlgVBox);
 }
 
-void RosterWindow::createItemForContact(const ContactPtr &contact,
-        bool checkExists)
+RosterItem *RosterWidget::createItemForContact(const ContactPtr &contact,
+        bool &exists)
 {
-    bool found = false;
-    if (checkExists) {
-        for (int i = 0; i < mList->count(); ++i) {
-            RosterItem *item = dynamic_cast<RosterItem*>(mList->item(i));
-            if (item->contact() == contact) {
-                found = true;
-            }
+    RosterItem *item;
+    exists = false;
+    for (int i = 0; i < mList->count(); ++i) {
+        item = dynamic_cast<RosterItem*>(mList->item(i));
+        if (item->contact() == contact) {
+            exists = true;
+            return item;
         }
     }
 
-    if (!found) {
-        RosterItem *item = new RosterItem(contact, mList);
-        connect(item, SIGNAL(changed()), SLOT(updateActions()));
-    }
-}
-
-void RosterWidget::onCMReady(Telepathy::Client::PendingOperation *op)
-{
-    if (op->isError()) {
-        qWarning() << "CM cannot become ready";
-        return;
-    }
-
-    qDebug() << "CM ready";
-    QVariantMap params;
-    params.insert("account", QVariant(mUsername));
-    params.insert("password", QVariant(mPassword));
-    PendingConnection *pconn = mCM->requestConnection("jabber", params);
-    connect(pconn,
-            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
-            SLOT(onConnectionCreated(Telepathy::Client::PendingOperation *)));
-}
-
-void RosterWidget::onConnectionCreated(Telepathy::Client::PendingOperation *op)
-{
-    if (op->isError()) {
-        qWarning() << "Unable to create connection";
-        return;
-    }
-
-    qDebug() << "Connection created";
-    PendingConnection *pconn =
-        qobject_cast<PendingConnection *>(op);
-    mConn = pconn->connection();
-    Features features = Features() << Connection::FeatureRoster;
-    connect(mConn->requestConnect(features),
-            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
-            SLOT(onConnectionReady(Telepathy::Client::PendingOperation *)));
+    return new RosterItem(contact, mList);
 }
 
 void RosterWidget::onConnectionReady(Telepathy::Client::PendingOperation *op)
@@ -206,13 +172,21 @@ void RosterWidget::onConnectionReady(Telepathy::Client::PendingOperation *op)
         return;
     }
 
-    connect(mConn->contactManager(),
+    PendingReady *pr = qobject_cast<PendingReady *>(op);
+    Connection *conn = qobject_cast<Connection *>(pr->object());
+    connect(conn->contactManager(),
             SIGNAL(presencePublicationRequested(const Telepathy::Client::Contacts &)),
             SLOT(onPresencePublicationRequested(const Telepathy::Client::Contacts &)));
 
     qDebug() << "Connection ready";
-    foreach (const ContactPtr &contact, mConn->contactManager()->allKnownContacts()) {
-        createItemForContact(contact);
+    RosterItem *item;
+    bool exists;
+    foreach (const ContactPtr &contact, conn->contactManager()->allKnownContacts()) {
+        exists = false;
+        item = createItemForContact(contact, exists);
+        if (!exists) {
+            connect(item, SIGNAL(changed()), SLOT(updateActions()));
+        }
     }
 
     mAddBtn->setEnabled(true);
@@ -221,8 +195,14 @@ void RosterWidget::onConnectionReady(Telepathy::Client::PendingOperation *op)
 void RosterWidget::onPresencePublicationRequested(const Contacts &contacts)
 {
     qDebug() << "Presence publication requested";
+    RosterItem *item;
+    bool exists;
     foreach (const ContactPtr &contact, contacts) {
-        createItemForContact(contact, true);
+        exists = false;
+        item = createItemForContact(contact, exists);
+        if (!exists) {
+            connect(item, SIGNAL(changed()), SLOT(updateActions()));
+        }
     }
 }
 
@@ -240,7 +220,8 @@ void RosterWidget::onAddButtonClicked()
     }
 
     QString username = mAddDlgEdt->text();
-    PendingContacts *pcontacts = mConn->contactManager()->contactsForIdentifiers(
+    // TODO which connection to use?
+    PendingContacts *pcontacts = mConns.first()->contactManager()->contactsForIdentifiers(
             QStringList() << username);
     connect(pcontacts,
             SIGNAL(finished(Telepathy::Client::PendingOperation *)),
@@ -327,7 +308,11 @@ void RosterWidget::onContactRetrieved(Telepathy::Client::PendingOperation *op)
     qDebug() << "Request presence subscription for contact" << username;
     // TODO should we have a signal on ContactManager to signal that a contact was
     //      added to subscribe list?
-    createItemForContact(contact, true);
+    bool exists = false;
+    RosterItem *item = createItemForContact(contact, exists);
+    if (!exists) {
+        connect(item, SIGNAL(changed()), SLOT(updateActions()));
+    }
     contact->requestPresenceSubscription();
 }
 
@@ -339,6 +324,7 @@ void RosterWidget::updateActions()
         mDenyAction->setEnabled(false);
         mRemoveAction->setEnabled(false);
         mBlockAction->setEnabled(false);
+        updateActions(0);
         return;
     }
     Q_ASSERT(selectedItems.size() == 1);
@@ -381,4 +367,6 @@ void RosterWidget::updateActions()
     }
 
     mBlockAction->setChecked(contact->isBlocked());
+
+    updateActions(item);
 }
diff --git a/examples/roster/roster-widget.h b/examples/roster/roster-widget.h
index 67b24c6..d9c9c20 100644
--- a/examples/roster/roster-widget.h
+++ b/examples/roster/roster-widget.h
@@ -28,7 +28,7 @@
 
 namespace Telepathy {
 namespace Client {
-class ConnectionManager;
+class Connection;
 class PendingOperation;
 }
 }
@@ -40,18 +40,29 @@ class QListWidget;
 class QListWidgetItem;
 class QPushButton;
 
+class RosterItem;
+
 class RosterWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    RosterWidget(const QString &username, const QString &password,
-            QWidget *parent = 0);
+    RosterWidget(QWidget *parent = 0);
     virtual ~RosterWidget();
 
+    QList<Telepathy::Client::Connection *> connections() const { return mConns; }
+    void addConnection(Telepathy::Client::Connection *conn);
+    void removeConnection(Telepathy::Client::Connection *conn);
+
+    QListWidget *listWidget() const { return mList; }
+
+protected:
+    virtual RosterItem *createItemForContact(
+            const Telepathy::Client::ContactPtr &contact,
+            bool &exists);
+    virtual void updateActions(RosterItem *item) { }
+
 private Q_SLOTS:
-    void onCMReady(Telepathy::Client::PendingOperation *);
-    void onConnectionCreated(Telepathy::Client::PendingOperation *);
     void onConnectionReady(Telepathy::Client::PendingOperation *);
     void onPresencePublicationRequested(const Telepathy::Client::Contacts &);
     void onItemSelectionChanged();
@@ -66,13 +77,8 @@ private Q_SLOTS:
 private:
     void createActions();
     void setupGui();
-    void createItemForContact(const Telepathy::Client::ContactPtr &contact,
-            bool checkExists = false);
 
-    Telepathy::Client::ConnectionManager *mCM;
-    Telepathy::Client::ConnectionPtr mConn;
-    QString mUsername;
-    QString mPassword;
+    QList<Telepathy::Client::Connection *> mConns;
     QAction *mAuthAction;
     QAction *mRemoveAction;
     QAction *mDenyAction;
diff --git a/examples/roster/roster-window.cpp b/examples/roster/roster-window.cpp
new file mode 100644
index 0000000..5fb29ad
--- /dev/null
+++ b/examples/roster/roster-window.cpp
@@ -0,0 +1,127 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * 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 "roster-window.h"
+#include "_gen/roster-window.moc.hpp"
+
+#include "roster-widget.h"
+
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Client/ConnectionManager>
+#include <TelepathyQt4/Client/PendingConnection>
+#include <TelepathyQt4/Client/PendingOperation>
+#include <TelepathyQt4/Client/PendingReady>
+
+#include <QDebug>
+
+using namespace Telepathy::Client;
+
+RosterWindow::RosterWindow(const QString &username, const QString &password,
+        QWidget *parent)
+    : QMainWindow(parent),
+      mUsername(username),
+      mPassword(password)
+{
+    setWindowTitle("Roster");
+
+    setupGui();
+
+    mCM = new ConnectionManager("gabble", this);
+    connect(mCM->becomeReady(),
+            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+            SLOT(onCMReady(Telepathy::Client::PendingOperation *)));
+
+    resize(240, 320);
+}
+
+RosterWindow::~RosterWindow()
+{
+    foreach (const ConnectionPtr &conn, mConns) {
+        conn->requestDisconnect();
+    }
+}
+
+void RosterWindow::setupGui()
+{
+    mRoster = new RosterWidget();
+    setCentralWidget(mRoster);
+}
+
+void RosterWindow::onCMReady(Telepathy::Client::PendingOperation *op)
+{
+    if (op->isError()) {
+        qWarning() << "CM cannot become ready";
+        return;
+    }
+
+    qDebug() << "CM ready";
+    QVariantMap params;
+    params.insert("account", QVariant(mUsername));
+    params.insert("password", QVariant(mPassword));
+    PendingConnection *pconn = mCM->requestConnection("jabber", params);
+    connect(pconn,
+            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+            SLOT(onConnectionCreated(Telepathy::Client::PendingOperation *)));
+}
+
+void RosterWindow::onConnectionCreated(Telepathy::Client::PendingOperation *op)
+{
+    if (op->isError()) {
+        qWarning() << "Unable to create connection";
+        return;
+    }
+
+    qDebug() << "Connection created";
+    PendingConnection *pconn =
+        qobject_cast<PendingConnection *>(op);
+    ConnectionPtr conn = pconn->connection();
+    mConns.append(conn);
+    connect(conn->requestConnect(),
+            SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+            SLOT(onConnectionConnected(Telepathy::Client::PendingOperation *)));
+    connect(conn.data(),
+            SIGNAL(invalidated(Telepathy::Client::DBusProxy *, const QString &, const QString &)),
+            SLOT(onConnectionInvalidated(Telepathy::Client::DBusProxy *, const QString &, const QString &)));
+}
+
+void RosterWindow::onConnectionConnected(Telepathy::Client::PendingOperation *op)
+{
+    if (op->isError()) {
+        qWarning() << "Connection cannot become connected";
+        return;
+    }
+
+    PendingReady *pr = qobject_cast<PendingReady *>(op);
+    Connection *conn = qobject_cast<Connection *>(pr->object());
+    mRoster->addConnection(conn);
+}
+
+void RosterWindow::onConnectionInvalidated(DBusProxy *proxy,
+        const QString &errorName, const QString &errorMessage)
+{
+    qDebug() << "RosterWindow::onConnectionInvalidated: connection became invalid:" <<
+        errorName << "-" << errorMessage;
+    foreach (const ConnectionPtr &conn, mConns) {
+        if (conn.data() == proxy) {
+            mRoster->removeConnection(conn.data());
+            mConns.removeOne(conn);
+        }
+    }
+}
diff --git a/examples/roster/roster-window.h b/examples/roster/roster-window.h
new file mode 100644
index 0000000..7e05349
--- /dev/null
+++ b/examples/roster/roster-window.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * 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_examples_roster_roster_window_h_HEADER_GUARD_
+#define _TelepathyQt4_examples_roster_roster_window_h_HEADER_GUARD_
+
+#include <QMainWindow>
+#include <QSharedPointer>
+
+#include <TelepathyQt4/Client/Connection>
+
+namespace Telepathy {
+namespace Client {
+class ConnectionManager;
+class DBusProxy;
+class PendingOperation;
+}
+}
+
+class RosterWidget;
+
+class RosterWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    RosterWindow(const QString &username, const QString &password,
+            QWidget *parent = 0);
+    virtual ~RosterWindow();
+
+private Q_SLOTS:
+    void onCMReady(Telepathy::Client::PendingOperation *);
+    void onConnectionCreated(Telepathy::Client::PendingOperation *);
+    void onConnectionConnected(Telepathy::Client::PendingOperation *);
+    void onConnectionInvalidated(Telepathy::Client::DBusProxy *,
+            const QString &, const QString &);
+
+private:
+    void setupGui();
+
+    Telepathy::Client::ConnectionManager *mCM;
+    QList<Telepathy::Client::ConnectionPtr> mConns;
+    QString mUsername;
+    QString mPassword;
+    RosterWidget *mRoster;
+};
+
+#endif
-- 
1.5.6.5




More information about the telepathy-commits mailing list