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_Hdiff --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