Hi,

the reviewboard is still not set up for telepathy-kded-module, so I'm
sending two patches in (both attached and paste). The first one [1]
integrates global presence into kded, basic integration for now, will be
improved later. The second one [2] vastly improves the mpris interface, now
it's basically working as it should, though the code might be quite crap
(I'm doing it in a bit hurry because I'm leaving in five minutes :)

[1] - http://paste.kde.org/129139/
[2] - http://paste.kde.org/129145/


--
Marty K.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 143afef..32379af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,7 @@ include_directories (${KDE4_INCLUDES}
 )
 
 set (telepathy_module_SRCS
+     global-presence.cpp
      telepathy-module.cpp
      autoaway.cpp
      telepathy-mpris.cpp
diff --git a/autoaway.cpp b/autoaway.cpp
index 812ba97..0313939 100644
--- a/autoaway.cpp
+++ b/autoaway.cpp
@@ -30,7 +30,8 @@
 AutoAway::AutoAway(const Tp::AccountManagerPtr& am, QObject* parent)
     : QObject(parent),
       m_awayTimeoutId(-1),
-      m_extAwayTimeoutId(-1)
+      m_extAwayTimeoutId(-1),
+      m_idle(false)
 {
     readConfig();
     m_accountManager = am;
@@ -57,6 +58,7 @@ void AutoAway::timeoutReached(int id)
                 m_accountManager->onlineAccounts()->accounts().first()->currentPresence().type() != Tp::Presence::hidden().type()) {
 
                 m_prevPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence();
+                m_idle = true;
                 Q_EMIT setPresence(Tp::Presence::away());
 
             }
@@ -74,6 +76,7 @@ void AutoAway::backFromIdle()
 {
     kDebug();
     Q_EMIT setPresence(m_prevPresence);
+    m_idle = false;
 }
 
 void AutoAway::readConfig()
@@ -103,3 +106,8 @@ void AutoAway::onSettingsChanged()
 {
     readConfig();
 }
+
+bool AutoAway::isIdle()
+{
+    return m_idle;
+}
diff --git a/autoaway.h b/autoaway.h
index a95f49a..2421b2b 100644
--- a/autoaway.h
+++ b/autoaway.h
@@ -35,6 +35,7 @@ public:
     ~AutoAway();
 
     void readConfig();
+    bool isIdle();
 
 Q_SIGNALS:
     void setPresence(const Tp::Presence &presence);
@@ -49,6 +50,7 @@ private Q_SLOTS:
 private:
     int m_awayTimeoutId;
     int m_extAwayTimeoutId;
+    bool m_idle;
 
     Tp::Presence m_prevPresence;
     Tp::AccountManagerPtr m_accountManager;
diff --git a/telepathy-module.cpp b/telepathy-module.cpp
index 174cecf..929178a 100644
--- a/telepathy-module.cpp
+++ b/telepathy-module.cpp
@@ -30,6 +30,8 @@
 #include "telepathy-mpris.h"
 #include "autoaway.h"
 #include "error-handler.h"
+#include "global-presence.h"
+#include <KConfigGroup>
 
 K_PLUGIN_FACTORY(TelepathyModuleFactory, registerPlugin<TelepathyModule>(); )
 K_EXPORT_PLUGIN(TelepathyModuleFactory("telepathy_module"))
@@ -77,16 +79,19 @@ void TelepathyModule::onAccountManagerReady(Tp::PendingOperation* op)
         return;
     }
 
+    m_globalPresence = new GlobalPresence(this);
+    m_globalPresence->setAccountManager(m_accountManager);
+
     m_autoAway = new AutoAway(m_accountManager, this);
     connect(m_autoAway, SIGNAL(setPresence(Tp::Presence)),
-            this, SLOT(setPresence(Tp::Presence)));
+            m_globalPresence, SLOT(setPresence(Tp::Presence)));
 
     connect(this, SIGNAL(settingsChanged()),
             m_autoAway, SLOT(onSettingsChanged()));
 
     m_mpris = new TelepathyMPRIS(m_accountManager, this);
     connect(m_mpris, SIGNAL(setPresence(Tp::Presence)),
-            this, SLOT(setPresence(Tp::Presence)));
+            m_globalPresence, SLOT(setPresence(Tp::Presence)));
 
     connect(this, SIGNAL(settingsChanged()),
             m_mpris, SLOT(onSettingsChanged()));
@@ -94,13 +99,18 @@ void TelepathyModule::onAccountManagerReady(Tp::PendingOperation* op)
     m_errorHandler = new ErrorHandler(m_accountManager, this);
 }
 
-void TelepathyModule::setPresence(const Tp::Presence &presence)
+void TelepathyModule::onPresenceChanged(const Tp::Presence &presence)
 {
-    kDebug() << "Setting presence to" << presence.status() << presence.statusMessage();
-    Q_FOREACH (const Tp::AccountPtr &account, m_accountManager->allAccounts()) {
-        if (account->isEnabled() && account->isValid() && account->isOnline()) {
-            account->setRequestedPresence(presence);
-        }
+    //only save if the presence is not auto-set
+    if (!m_autoAway->isIdle()) {
+        KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
+        KConfigGroup presenceConfig = config->group("LastPresence");
+
+        presenceConfig.writeEntry(QLatin1String("PresenceType"), (uint)m_globalPresence->currentPresence().type());
+        presenceConfig.writeEntry(QLatin1String("PresenceStatus"), m_globalPresence->currentPresence().status());
+        presenceConfig.writeEntry(QLatin1String("PresenceMessage"), m_globalPresence->currentPresence().statusMessage());
+
+        presenceConfig.sync();
     }
 }
 
diff --git a/telepathy-module.h b/telepathy-module.h
index 815ee38..64ffa99 100644
--- a/telepathy-module.h
+++ b/telepathy-module.h
@@ -25,13 +25,15 @@
 
 #include <TelepathyQt4/AccountManager>
 
-class ErrorHandler;
-class TelepathyMPRIS;
-class AutoAway;
 namespace Tp {
     class PendingOperation;
 }
 
+class GlobalPresence;
+class ErrorHandler;
+class TelepathyMPRIS;
+class AutoAway;
+
 class TelepathyModule : public KDEDModule
 {
     Q_OBJECT
@@ -43,17 +45,16 @@ public:
 Q_SIGNALS:
     void settingsChanged();
 
-public Q_SLOTS:
-    void setPresence(const Tp::Presence& presence);
-
 private Q_SLOTS:
     void onAccountManagerReady(Tp::PendingOperation*);
+    void onPresenceChanged(const Tp::Presence &presence);
 
 private:
-    Tp::AccountManagerPtr m_accountManager;
-    AutoAway *m_autoAway;
-    TelepathyMPRIS *m_mpris;
-    ErrorHandler *m_errorHandler;
+    Tp::AccountManagerPtr    m_accountManager;
+    AutoAway                *m_autoAway;
+    TelepathyMPRIS          *m_mpris;
+    ErrorHandler            *m_errorHandler;
+    GlobalPresence          *m_globalPresence;
 };
 
 #endif // TELEPATHY_MODULE_H
diff --git a/telepathy-mpris.cpp b/telepathy-mpris.cpp
index b4920d8..ff32554 100644
--- a/telepathy-mpris.cpp
+++ b/telepathy-mpris.cpp
@@ -25,8 +25,13 @@
 #include <QVariant>
 #include <KDebug>
 #include <TelepathyQt4/AccountSet>
+#include <KSharedConfig>
+#include <KConfigGroup>
 
-TelepathyMPRIS::TelepathyMPRIS(const Tp::AccountManagerPtr am, QObject* parent) : QObject(parent)
+TelepathyMPRIS::TelepathyMPRIS(const Tp::AccountManagerPtr am, QObject* parent)
+    : QObject(parent),
+      m_enabled(false),
+      m_playbackActive(false)
 {
     m_accountManager = am;
 
@@ -36,47 +41,11 @@ TelepathyMPRIS::TelepathyMPRIS(const Tp::AccountManagerPtr am, QObject* parent)
 
     m_originalPresence = am->onlineAccounts()->accounts().first()->currentPresence().statusMessage();
 
-    QDBusConnectionInterface *i = QDBusConnection::sessionBus().interface();
-    QStringList mprisServices = i->registeredServiceNames().value().filter(QLatin1String("org.mpris.MediaPlayer2"));
-
-    QString artist;
-    QString title;
-    QString album;
+    //read settings and detect players if plugin is enabled
+    onSettingsChanged();
 
-    Q_FOREACH (const QString &service, mprisServices) {
-        QDBusInterface mprisInterface(service, QLatin1String("/org/mpris/MediaPlayer2"), QLatin1String("org.mpris.MediaPlayer2.Player"));
-        if (mprisInterface.property("PlaybackStatus") == QLatin1String("Playing")) {
-            QMap<QString, QVariant> metadata = mprisInterface.property("Metadata").toMap();
-            artist = metadata.value(QLatin1String("xesam:artist")).toString();
-            title = metadata.value(QLatin1String("xesam:title")).toString();
-            album = metadata.value(QLatin1String("xesam:album")).toString();
-
-            QDBusConnection::sessionBus().connect(
-                service,
-                QLatin1String("/org/mpris/MediaPlayer2"),
-                QLatin1String("org.freedesktop.DBus.Properties"),
-                QLatin1String("PropertiesChanged"),
-                this,
-                SLOT(onPlayerSignalReceived(const QString& ,
-                                            const QVariantMap& ,
-                                            const QStringList& )) );
-
-            break;
-        }
-    }
-
-    if (!am->onlineAccounts()->accounts().isEmpty()) {
-        Tp::Presence currentPresence = am->onlineAccounts()->accounts().first()->currentPresence();
-
-        Tp::SimplePresence presence;
-        presence.type = currentPresence.type();
-        presence.status = currentPresence.status();
-        presence.statusMessage = QString(QLatin1String("Now listening to %1 by %2 from album %3")).arg(title, artist, album);
-
-        kDebug() << "Setting presence message to" << presence.statusMessage;
-
-        Q_EMIT setPresence(presence);
-    }
+    connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
+            this, SLOT(serviceOwnerChanged(QString,QString,QString)));
 }
 
 TelepathyMPRIS::~TelepathyMPRIS()
@@ -89,47 +58,150 @@ void TelepathyMPRIS::onPlayerSignalReceived(const QString &interface, const QVar
     Q_UNUSED(interface)
     Q_UNUSED(invalidatedProperties)
 
+    if (!m_enabled) {
+        return;
+    }
+
     if (m_accountManager->onlineAccounts()->accounts().isEmpty()) {
         return;
     }
+
+    QString artist;
+    QString title;
+    QString album;
+
     //FIXME We can do less lame parsing
     Q_FOREACH (const QVariant &property, changedProperties.values()) {
         if (property.canConvert<QDBusArgument>()) {
-            QString artist;
-            QString title;
-            QString album;
-
             QDBusArgument g = property.value<QDBusArgument>();
             QMap<QString, QVariant> k = qdbus_cast<QMap<QString, QVariant> >(g);
             title = k.value(QLatin1String("xesam:title")).toString();
             artist = k.value(QLatin1String("xesam:artist")).toString();
             album = k.value(QLatin1String("xesam:album")).toString();
 
-            Tp::Presence currentPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence();
-
-            Tp::SimplePresence presence;
-            presence.type = currentPresence.type();
-            presence.status = currentPresence.status();
-            presence.statusMessage = QString(QLatin1String("Now listening to %1 by %2 from album %3")).arg(title, artist, album);
-
-            Q_EMIT setPresence(presence);
+            break;
         }
 
         if (property.canConvert<QString>()) {
             if (property.toString() == QLatin1String("Paused")) {
+                if (m_playbackActive) {
+                    m_playbackActive = false;
+                }
+
                 Tp::Presence currentPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence();
 
                 Tp::SimplePresence presence;
                 presence.type = currentPresence.type();
                 presence.status = currentPresence.status();
                 presence.statusMessage = m_originalPresence;
+
+                kDebug() << "Setting presence message to" << presence.statusMessage;
+                Q_EMIT setPresence(presence);
+                return;
             }
+
+            if (property.toString() == QLatin1String("Playing")) {
+                if (!m_playbackActive) {
+                    m_originalPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence().statusMessage();
+                    m_playbackActive = true;
+                }
+                QStringList mprisServices = QDBusConnection::sessionBus().interface()->registeredServiceNames().value().filter(QLatin1String("org.mpris.MediaPlayer2"));
+
+                Q_FOREACH (const QString &service, mprisServices) {
+                    QDBusInterface mprisInterface(service, QLatin1String("/org/mpris/MediaPlayer2"), QLatin1String("org.mpris.MediaPlayer2.Player"));
+                    if (mprisInterface.property("PlaybackStatus") == QLatin1String("Playing")) {
+                        QMap<QString, QVariant> metadata = mprisInterface.property("Metadata").toMap();
+                        artist = metadata.value(QLatin1String("xesam:artist")).toString();
+                        title = metadata.value(QLatin1String("xesam:title")).toString();
+                        album = metadata.value(QLatin1String("xesam:album")).toString();
+
+                        break;
+                    }
+
+                }
+            }
+        }
+    }
+
+    Tp::Presence currentPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence();
+
+    Tp::SimplePresence presence;
+    presence.type = currentPresence.type();
+    presence.status = currentPresence.status();
+    presence.statusMessage = QString(QLatin1String("Now listening to %1 by %2 from album %3")).arg(title, artist, album);
+
+    kDebug() << "Setting presence message to" << presence.statusMessage;
+    Q_EMIT setPresence(presence);
+}
+
+void TelepathyMPRIS::detectPlayers()
+{
+    QDBusConnectionInterface *i = QDBusConnection::sessionBus().interface();
+    QStringList mprisServices = i->registeredServiceNames().value().filter(QLatin1String("org.mpris.MediaPlayer2"));
+    QStringList players;
+
+    Q_FOREACH (const QString &service, mprisServices) {
+        kDebug() << "Found mpris service:" << service;
+        QDBusInterface mprisInterface(service, QLatin1String("/org/mpris/MediaPlayer2"), QLatin1String("org.mpris.MediaPlayer2.Player"));
+        if (mprisInterface.property("PlaybackStatus") == QLatin1String("Playing")) {
+            QVariantMap m;
+            m.insert(QLatin1String("PlaybackStatus"), QVariant(QLatin1String("Playing")));
+            onPlayerSignalReceived(QString(), m, QStringList());
+        }
+
+        //check if we are already watching this service
+        if (!m_knownPlayers.contains(service)) {
+            QDBusConnection::sessionBus().connect(
+                service,
+                QLatin1String("/org/mpris/MediaPlayer2"),
+                                                QLatin1String("org.freedesktop.DBus.Properties"),
+                                                QLatin1String("PropertiesChanged"),
+                                                this,
+                                                SLOT(onPlayerSignalReceived(const QString&, const QVariantMap&, const QStringList& )) );
+
         }
+
+        players.append(service);
     }
 
+    //this gets rid of removed services and stores only those currently present
+    m_knownPlayers = players;
 }
 
 void TelepathyMPRIS::onSettingsChanged()
 {
+    KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
+    KConfigGroup kdedConfig = config->group("KDED");
+
+    bool pluginEnabled = kdedConfig.readEntry("nowPlayingEnabled", true);
+
+    //if the plugin was enabled is now disabled
+    if (m_enabled && !pluginEnabled) {
+        Tp::Presence currentPresence = m_accountManager->onlineAccounts()->accounts().first()->currentPresence();
+
+        Tp::SimplePresence presence;
+        presence.type = currentPresence.type();
+        presence.status = currentPresence.status();
+        presence.statusMessage = m_originalPresence;
+
+        kDebug() << "Setting presence message to" << presence.statusMessage;
+        Q_EMIT setPresence(presence);
+
+        m_enabled = false;
+        return;
+    }
 
+    //if the plugin was disabled and is now enabled
+    if (!m_enabled && pluginEnabled) {
+        m_enabled = true;
+        detectPlayers();
+    }
+}
+
+void TelepathyMPRIS::serviceOwnerChanged(const QString& a, const QString& b, const QString& c)
+{
+    if (a.contains(QLatin1String("org.mpris.MediaPlayer2"))) {
+        kDebug() << "Found new mpris interface, running detection...";
+        detectPlayers();
+    }
 }
diff --git a/telepathy-mpris.h b/telepathy-mpris.h
index 5dd596f..7be557a 100644
--- a/telepathy-mpris.h
+++ b/telepathy-mpris.h
@@ -36,13 +36,20 @@ public:
 public Q_SLOTS:
     void onPlayerSignalReceived(const QString &interface, const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
     void onSettingsChanged();
+    void detectPlayers();
+    void serviceOwnerChanged(const QString &a, const QString &b, const QString &c);
 
 Q_SIGNALS:
     void setPresence(const Tp::Presence &presence);
+    void togglePlaybackActive(bool);
 
 private:
     Tp::AccountManagerPtr m_accountManager;
     QString m_originalPresence;
+    QStringList m_knownPlayers;
+
+    bool m_enabled;
+    bool m_playbackActive;
 };
 
 #endif // TELEPATHY_MPRIS_H
_______________________________________________
KDE-Telepathy mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kde-telepathy

Reply via email to