[SCM] ktp-contact-list packaging branch, master, updated. debian/15.12.1-2-1070-g6c56f91

Maximiliano Curia maxy at moszumanska.debian.org
Sat May 28 00:04:45 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-contact-list.git;a=commitdiff;h=592befa

The following commit has been merged in the master branch:
commit 592befa0047fe29193607390a57d4c2ae35b5a24
Author: Dario Freddi <drf at kde.org>
Date:   Sun Apr 18 15:31:38 2010 +0000

    Make Telepathy-Contactlist pick up changes in realtime.
    
    This patch uses the awesome QueryServiceClient to monitor sparql queries for further results.
    
    This means telepathy-contactlist is almost usable right now: added contacts are shown instantly
    as they get approved, and removed contacts are thrown away as they are removed as well.
    
    For finishing, now tp-contactlist only shows contacts that published their presence to us,
    in the same flavour empathy does.
    In the end, this is probably not really what we'll want to do, but it's here to show it works.
    
    With the current architecture, it's just a matter of tuning the SPARQL query retrieving contacts for
    deciding what will be shown: all the rest is done by magic.
    
    Signed-off-by: Dario Freddi <dario.freddi at collabora.co.uk>
    
    svn path=/trunk/playground/network/telepathy-contactlist/; revision=1116075
---
 CMakeLists.txt             |  1 +
 contact-item.cpp           | 10 ++++-
 contact-item.h             |  1 +
 contacts-list-model.cpp    | 98 +++++++++++++++++++++++++++++++++++++++++++---
 contacts-list-model.h      | 19 ++++++++-
 main-widget.cpp            | 10 +++++
 nepomuk-signal-watcher.cpp | 14 +++++++
 nepomuk-signal-watcher.h   |  3 +-
 8 files changed, 147 insertions(+), 9 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 46e2b44..6ed2348 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,6 +118,7 @@ target_link_libraries (telepathy_contactlist_prototype
                        ${KDE4_KDEUI_LIBS}
                        ${TELEPATHY_QT4_LIBRARIES}
                        ${NEPOMUK_LIBRARIES}
+                       ${NEPOMUK_QUERY_LIBRARIES}
                        nie
 
 )
diff --git a/contact-item.cpp b/contact-item.cpp
index d452968..14d7975 100644
--- a/contact-item.cpp
+++ b/contact-item.cpp
@@ -47,6 +47,9 @@ ContactItem::ContactItem(Nepomuk::PersonContact personContact,
 
 ContactItem::~ContactItem()
 {
+    NepomukSignalWatcher *watcher = NepomukSignalWatcher::instance();
+    watcher->unregisterCallbackOnSubject(m_imAccount, this);
+    watcher->unregisterCallbackOnSubject(m_personContact, this);
     kDebug();
 }
 
@@ -55,6 +58,11 @@ Nepomuk::PersonContact ContactItem::personContact() const
     return m_personContact;
 }
 
+Nepomuk::IMAccount ContactItem::imAccount() const
+{
+    return m_imAccount;
+}
+
 QString ContactItem::displayName() const
 {
     // Use the IM Account Nick Name for now.
@@ -199,10 +207,10 @@ void ContactItem::onStatementAdded(const Soprano::Statement &statement)
     updatePresenceIcon();
     Q_EMIT dirty();
 }
+
 const QPixmap& ContactItem::avatar() const
 {
     return m_pixmap;
 }
 
 #include "contact-item.moc"
-
diff --git a/contact-item.h b/contact-item.h
index 420e248..86311bb 100644
--- a/contact-item.h
+++ b/contact-item.h
@@ -54,6 +54,7 @@ public:
     QStringList groups() const;
 
     Nepomuk::PersonContact personContact() const;
+    Nepomuk::IMAccount imAccount() const;
 
     virtual void onStatementAdded(const Soprano::Statement &statement);
 
diff --git a/contacts-list-model.cpp b/contacts-list-model.cpp
index 1acf855..90e971c 100644
--- a/contacts-list-model.cpp
+++ b/contacts-list-model.cpp
@@ -40,10 +40,14 @@
 #include <Nepomuk/ResourceManager>
 #include <Nepomuk/Variant>
 
+#include <Nepomuk/Query/QueryServiceClient>
+#include <Nepomuk/Query/Result>
+
 #include <Soprano/Model>
 #include <Soprano/QueryResultIterator>
 
 #include <unistd.h>
+#include <KMessageBox>
 
 ContactsListModel::ContactsListModel(QObject *parent)
  : QAbstractItemModel(parent),
@@ -61,7 +65,7 @@ ContactsListModel::ContactsListModel(QObject *parent)
     Soprano::Model *model = Nepomuk::ResourceManager::instance()->mainModel();
 
     // Get ALL THE METACONTACT!!!!11!!111!!11one111!!!!eleven!!!1!
-    // FIXME: Actually make this code do something.
+    // FIXME: Actually make this code do something, then port it to QueryServiceClient
     QString metaContactquery = QString("select distinct ?a where { ?a a %7 . }")
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::PIMO::Person()));
 
@@ -79,20 +83,40 @@ ContactsListModel::ContactsListModel(QObject *parent)
 
     // Get all the Telepathy PersonContacts that are not in a metacontact
     // FIXME: At the moment, this just gets all Telepathy PersonContacts.
-    QString query = QString("select distinct ?a ?b where { ?a a %1 . ?a %2 ?b . ?b a %3 . ?b %4 ?r . ?r a %3 . ?s %2 ?r . ?s a %1 . %5 %6 ?s }")
+    QString query = QString("select distinct ?r ?account where { ?r a %1 . ?r %2 ?account . ?acccount a %3 . "
+                            "?account %4 ?t . ?account %5 ?t . ?t a %3 . ?s %2 ?t . ?s a %1 . %6 %7 ?s }")
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::PersonContact()))
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::hasIMAccount()))
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::IMAccount()))
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::Telepathy::isBuddyOf()))
+            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::Telepathy::publishesPresenceTo()))
             .arg(Soprano::Node::resourceToN3(me.resourceUri()))
             .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::PIMO::groundingOccurrence()));
 
-    Soprano::QueryResultIterator it = model->executeQuery(query, Soprano::Query::QueryLanguageSparql);
+    m_contactsQuery = new Nepomuk::Query::QueryServiceClient(this);
+    connect(m_contactsQuery, SIGNAL(newEntries(QList<Nepomuk::Query::Result>)),
+            this, SLOT(onContactsQueryNewEntries(QList<Nepomuk::Query::Result>)));
+    connect(m_contactsQuery, SIGNAL(entriesRemoved(QList<QUrl>)),
+            this, SLOT(onContactsQueryEntriesRemoved(QList<QUrl>)));
+
+    Nepomuk::Query::RequestPropertyMap rpm;
+    rpm.insert("account", Nepomuk::Vocabulary::NCO::IMAccount());
+    bool queryResult = m_contactsQuery->sparqlQuery(query, rpm);
+    kDebug() << "Query result " << queryResult;
+    if (!queryResult) {
+        KMessageBox::error(0, i18n("It was not possible to query Nepomuk database. Please check your "
+                                   "installation and make sure Nepomuk is running."));
+    }
+}
 
+void ContactsListModel::onContactsQueryNewEntries(const QList<Nepomuk::Query::Result> &entries)
+{
+    kDebug();
     // Iterate over all the IMAccounts/PersonContacts found.
-    while(it.next()) {
-        Nepomuk::PersonContact foundPersonContact(it.binding("a").uri());
-        Nepomuk::IMAccount foundIMAccount(it.binding("b").uri());
+    foreach (const Nepomuk::Query::Result &result, entries) {
+        Nepomuk::PersonContact foundPersonContact(result.resource().resourceUri());
+        Nepomuk::IMAccount foundIMAccount(result.requestProperty(Nepomuk::Vocabulary::NCO::IMAccount()).uri());
+        kDebug() << "New resource added: " << foundPersonContact << foundIMAccount;
 
         // Create a fake metacontact to hold this item.
         MetaContactItem *metaContactItem = new MetaContactItem(MetaContactItem::FakeMetaContact, 0);
@@ -106,6 +130,36 @@ ContactsListModel::ContactsListModel(QObject *parent)
         metaContactItem->appendChildItem(item);
         connect(item, SIGNAL(dirty()), SLOT(onItemDirty()));
     }
+
+    reset();
+}
+
+void ContactsListModel::onContactsQueryEntriesRemoved(const QList< QUrl > &entries)
+{
+    kDebug();
+    // Find and remove
+    foreach (const QUrl &url, entries) {
+        kDebug() << "Attempting to remove resource " << url;
+        foreach (const QModelIndex &index, findContacts(url)) {
+            kDebug() << "Found matching item at" << index;
+            AbstractTreeItem *abstractItem = static_cast<AbstractTreeItem*>(index.internalPointer());
+            ContactItem *contactItem = dynamic_cast<ContactItem*>(abstractItem);
+
+            if (contactItem) {
+                // Yeah, we're here. Now let's have a look through metacontacts available
+                AbstractTreeItem *metacontact = contactItem->parentItem();
+                metacontact->removeChildItem(contactItem);
+                delete contactItem;
+                if (metacontact->childItems().isEmpty()) {
+                    // We will have to delete the metacontact as well
+                    m_rootItem->removeChildItem(metacontact);
+                    delete metacontact;
+                }
+            }
+        }
+    }
+
+    reset();
 }
 
 ContactsListModel::~ContactsListModel()
@@ -113,6 +167,35 @@ ContactsListModel::~ContactsListModel()
     kDebug();
 }
 
+QModelIndexList ContactsListModel::findContacts(const QUrl& resource)
+{
+    return findChildrenContacts(resource, QModelIndex());
+}
+
+QModelIndexList ContactsListModel::findChildrenContacts(const QUrl& resource, const QModelIndex& parent)
+{
+    QModelIndexList list;
+
+    kDebug() << "Finding contacts in " << parent << rowCount(parent) << columnCount(parent);
+
+    for (int i = 0; i < rowCount(parent); ++i) {
+        for (int j = 0; j < columnCount(parent); ++j) {
+            QModelIndex current = index(i, j, parent);
+
+            if (current.data(PersonContactResourceRole) == resource) {
+                list << current;
+            }
+
+            // Iterate over children, if any
+            if (hasChildren(current)) {
+                list << findChildrenContacts(resource, current);
+            }
+        }
+    }
+
+    return list;
+}
+
 int ContactsListModel::columnCount(const QModelIndex &parent) const
 {
     Q_UNUSED(parent);
@@ -153,6 +236,9 @@ QVariant ContactsListModel::data(const QModelIndex &index, int role) const
         case ContactsListModel::AvatarRole:
             data.setValue<QPixmap>(contactItem->avatar());
             break;
+        case ContactsListModel::PersonContactResourceRole:
+            data.setValue<QUrl>(contactItem->personContact().resourceUri());
+            break;
         default:
             break;
         }
diff --git a/contacts-list-model.h b/contacts-list-model.h
index 1cb1050..1397525 100644
--- a/contacts-list-model.h
+++ b/contacts-list-model.h
@@ -24,6 +24,14 @@
 
 #include <QtCore/QAbstractItemModel>
 
+class ContactItem;
+namespace Nepomuk {
+namespace Query {
+class QueryServiceClient;
+class Result;
+}
+}
+
 class AbstractTreeItem;
 
 class ContactsListModel : public QAbstractItemModel
@@ -34,7 +42,8 @@ public:
     enum {
         PresenceTypeRole = Qt::UserRole,
         GroupsRole,
-        AvatarRole
+        AvatarRole,
+        PersonContactResourceRole
     };
 
     explicit ContactsListModel(QObject *parent = 0);
@@ -51,16 +60,24 @@ public:
                               const QModelIndex &parent = QModelIndex()) const;
     virtual QModelIndex parent(const QModelIndex &index) const;
     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QModelIndexList findContacts(const QUrl &resource);
 
 private Q_SLOTS:
     void onItemDirty();
 
+    void onContactsQueryNewEntries(const QList<Nepomuk::Query::Result>&);
+    void onContactsQueryEntriesRemoved(const QList<QUrl>&);
+
 private:
     Q_DISABLE_COPY(ContactsListModel);
 
+    QModelIndexList findChildrenContacts(const QUrl &resource, const QModelIndex &parent);
+
     AbstractTreeItem *item(const QModelIndex &index) const;
 
     AbstractTreeItem *m_rootItem;
+
+    Nepomuk::Query::QueryServiceClient *m_contactsQuery;
 };
 
 
diff --git a/main-widget.cpp b/main-widget.cpp
index 9742c05..9d9014e 100644
--- a/main-widget.cpp
+++ b/main-widget.cpp
@@ -41,8 +41,10 @@
 #include <KJob>
 #include <KLineEdit>
 #include <KComboBox>
+#include <KMessageBox>
 
 #include <Nepomuk/ResourceManager>
+#include <Nepomuk/Query/QueryServiceClient>
 
 #include <Soprano/QueryResultIterator>
 
@@ -120,6 +122,14 @@ MainWidget::MainWidget(QWidget *parent)
 {
     kDebug();
 
+    // Check if Nepomuk Query service client is up and running
+    if (!Nepomuk::Query::QueryServiceClient::serviceAvailable()) {
+        // That's a failure
+        KMessageBox::error(this, i18n("The Nepomuk Query Service client is not available on your system. "
+                                      "Contactlist requires the query service client to be available: please "
+                                      "check your system settings"));
+    }
+
     setupUi(this);
 
     // Initialize Telepathy
diff --git a/nepomuk-signal-watcher.cpp b/nepomuk-signal-watcher.cpp
index a98e186..82ab81a 100644
--- a/nepomuk-signal-watcher.cpp
+++ b/nepomuk-signal-watcher.cpp
@@ -90,3 +90,17 @@ void NepomukSignalWatcher::registerCallbackOnSubject(const Nepomuk::Resource &re
    // kDebug() << "Registering callback:" << resource.resourceUri() << callback;
 }
 
+void NepomukSignalWatcher::unregisterCallbackOnSubject(const Nepomuk::Resource& resource,
+                                                       NepomukSignalWatcher::Watcher *callback)
+{
+    // Use an iterator, since we have to remove an item with a specific key AND value
+    QHash< QString, NepomukSignalWatcher::Watcher *>::iterator i = m_subjectCallbacks.begin();
+    while (i != m_subjectCallbacks.end()) {
+        if (i.key() == resource.resourceUri().toString() && i.value() == callback) {
+            i = m_subjectCallbacks.erase(i);
+        } else {
+            ++i;
+        }
+    }
+}
+
diff --git a/nepomuk-signal-watcher.h b/nepomuk-signal-watcher.h
index 8164f0b..d56a10f 100644
--- a/nepomuk-signal-watcher.h
+++ b/nepomuk-signal-watcher.h
@@ -66,6 +66,8 @@ public:
 
     void registerCallbackOnSubject(const Nepomuk::Resource &resource,
                                    NepomukSignalWatcher::Watcher *callback);
+    void unregisterCallbackOnSubject(const Nepomuk::Resource &resource,
+                                     NepomukSignalWatcher::Watcher *callback);
 
 private Q_SLOTS:
     void onStatementAdded(const Soprano::Statement &statement);
@@ -74,7 +76,6 @@ private:
     Q_DISABLE_COPY(NepomukSignalWatcher);
 
     NepomukSignalWatcher();
-    static NepomukSignalWatcher *s_self;
 
     Soprano::Util::SignalCacheModel *m_sopranoModel;
 

-- 
ktp-contact-list packaging



More information about the pkg-kde-commits mailing list