[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [simon] plugins/Commands/MprisPlayer: Add the feature to play a media from media player's tracklist
From: Ashish Madeti <ashishmadeti () gmail ! com>
Date: 2014-07-30 8:18:53
Message-ID: E1XCP65-0006uA-72 () scm ! kde ! org
[Download RAW message or body]
Git commit 4c2ff5e33b7358edfcb907ac58ece763b21904ae by Ashish Madeti.
Committed on 30/07/2014 at 08:11.
Pushed by madeti into branch 'master'.
Add the feature to play a media from media player's tracklist to \
MprisPlayer plug-in
REVIEW: 119286
M +1 -0 plugins/Commands/MprisPlayer/CMakeLists.txt
M +1 -1 plugins/Commands/MprisPlayer/createmprisplayercommandwidget.cpp
M +10 -1 plugins/Commands/MprisPlayer/mprisconstants.h
M +28 -5 plugins/Commands/MprisPlayer/mprisplayercommand.cpp
M +17 -1 plugins/Commands/MprisPlayer/mprisplayercommand.h
M +198 -7 plugins/Commands/MprisPlayer/mprisplayercommandmanager.cpp
M +12 -1 plugins/Commands/MprisPlayer/mprisplayercommandmanager.h
M +1 -1 plugins/Commands/MprisPlayer/mprisplayerconfiguration.cpp
A +188 -0 plugins/Commands/MprisPlayer/player.cpp [License: GPL \
(v2)] A +65 -0 plugins/Commands/MprisPlayer/player.h [License: \
GPL (v2)]
http://commits.kde.org/simon/4c2ff5e33b7358edfcb907ac58ece763b21904ae
diff --git a/plugins/Commands/MprisPlayer/CMakeLists.txt \
b/plugins/Commands/MprisPlayer/CMakeLists.txt index 3fc5c1c..92bd5b7 100644
--- a/plugins/Commands/MprisPlayer/CMakeLists.txt
+++ b/plugins/Commands/MprisPlayer/CMakeLists.txt
@@ -3,6 +3,7 @@ set (simonmprisplayerplugin_SRCS
mprisplayerconfiguration.cpp
mprisplayercommand.cpp
createmprisplayercommandwidget.cpp
+ player.cpp
)
kde4_add_ui_files(simonmprisplayerplugin_SRCS
diff --git a/plugins/Commands/MprisPlayer/createmprisplayercommandwidget.cpp \
b/plugins/Commands/MprisPlayer/createmprisplayercommandwidget.cpp index \
d25137b..92338fd 100644
--- a/plugins/Commands/MprisPlayer/createmprisplayercommandwidget.cpp
+++ b/plugins/Commands/MprisPlayer/createmprisplayercommandwidget.cpp
@@ -46,7 +46,7 @@ CreateMprisPlayerCommandWidget::~CreateMprisPlayerCommandWidget()
{
}
-Command *CreateMprisPlayerCommandWidget::createCommand(const QString \
&name, const QString &iconSrc, const QString &description) +Command \
*CreateMprisPlayerCommandWidget::createCommand(const QString& name, const \
QString& iconSrc, const QString& description) {
CommandRole role = \
static_cast<CommandRole>(ui.cbCommand->itemData(ui.cbCommand->currentIndex()).toInt());
return new MprisPlayerCommand(name, iconSrc, description, role);
diff --git a/plugins/Commands/MprisPlayer/mprisconstants.h \
b/plugins/Commands/MprisPlayer/mprisconstants.h index bfff506..a736967 \
100644
--- a/plugins/Commands/MprisPlayer/mprisconstants.h
+++ b/plugins/Commands/MprisPlayer/mprisconstants.h
@@ -20,6 +20,9 @@
#ifndef SIMON_MPRIS_CONSTANTS_H_9A22E03B797C494599B9629C6B47E478
#define SIMON_MPRIS_CONSTANTS_H_9A22E03B797C494599B9629C6B47E478
+typedef QPair<QString, QString> Track;
+typedef QList<Track> TrackList;
+
enum CommandRole
{
PlayPause,
@@ -31,13 +34,19 @@ enum CommandRole
VolumeUp,
VolumeDown,
SeekAhead,
- SeekBack
+ SeekBack,
+ PlayParticular
};
static const QString MprisPlayerPrefix("org.mpris.MediaPlayer2.");
static const QString DBusMprisPath("/org/mpris/MediaPlayer2");
static const QString PlayerInterface("org.mpris.MediaPlayer2.Player");
+static const QString \
TracklistInterface("org.mpris.MediaPlayer2.TrackList"); static const \
QString PropertiesInterface("org.freedesktop.DBus.Properties"); +
+static const QString titleMetadata("xesam:title");
+static const QString trackIdMetadata("mpris:trackid");
+
static const double volumeChange = 0.05;
static const qlonglong seekOffset = 1000000; // 1 second
diff --git a/plugins/Commands/MprisPlayer/mprisplayercommand.cpp \
b/plugins/Commands/MprisPlayer/mprisplayercommand.cpp index \
d732901..e503e81 100644
--- a/plugins/Commands/MprisPlayer/mprisplayercommand.cpp
+++ b/plugins/Commands/MprisPlayer/mprisplayercommand.cpp
@@ -55,6 +55,16 @@ CommandRole MprisPlayerCommand::role()
return m_role;
}
+QString MprisPlayerCommand::trackId()
+{
+ return m_trackId.path();
+}
+
+QString MprisPlayerCommand::serviceName()
+{
+ return m_serviceName;
+}
+
QDomElement MprisPlayerCommand::serializePrivate(QDomDocument *doc, \
QDomElement& commandElem) {
QDomElement roleElem = doc->createElement("role");
@@ -111,6 +121,9 @@ const QMap<QString,QVariant> \
MprisPlayerCommand::getValueMapPrivate() const case SeekBack:
typeString = i18nc("Rewind to some time back", "Seek Back");
break;
+ case PlayParticular:
+ typeString = i18nc("Play a particular track from a playlist", \
"Play Particular"); + break;
}
out.insert(i18nc("Type of the command", "Type"), typeString);
return out;
@@ -124,6 +137,10 @@ bool MprisPlayerCommand::triggerPrivate(int *state)
QString method;
QList<QVariant> args;
+ QDBusMessage m;
+ qlonglong offset;
+ double currentVolume, change;
+
bool success = true;
switch (m_role) {
case PlayPause:
@@ -146,7 +163,6 @@ bool MprisPlayerCommand::triggerPrivate(int *state)
break;
case VolumeUp:
case VolumeDown:
- double currentVolume, change;
change = volumeChange;
if (m_role == VolumeDown) {
change *= -1.0;
@@ -160,16 +176,23 @@ bool MprisPlayerCommand::triggerPrivate(int *state)
return success;
case SeekAhead:
case SeekBack:
- qlonglong offset = seekOffset;
+ offset = seekOffset;
if (m_role == SeekBack) {
offset *= -1;
}
args << offset;
method = "Seek";
break;
+ case PlayParticular:
+ m = QDBusMessage::createMethodCall(m_serviceName, DBusMprisPath,
+ \
TracklistInterface, + \
"GoTo"); + args << QVariant::fromValue(m_trackId);
+ m.setArguments(args);
+ success = QDBusConnection::sessionBus().send(m);
+ return success;
}
- QDBusMessage m;
foreach (const QString& service, playersList) {
m = QDBusMessage::createMethodCall(service, DBusMprisPath, \
PlayerInterface, method); m.setArguments(args);
@@ -180,7 +203,7 @@ bool MprisPlayerCommand::triggerPrivate(int *state)
return success;
}
-QDBusReply<QVariant> MprisPlayerCommand::getPropertyValue(const QString \
&service, const QString &interfaceName, const QString &propertyName) \
+QDBusReply<QVariant> MprisPlayerCommand::getPropertyValue(const QString& \
service, const QString& interfaceName, const QString& propertyName) {
QDBusInterface *iface = new QDBusInterface(service, DBusMprisPath, \
PropertiesInterface,
\
QDBusConnection::sessionBus()); @@ -190,7 +213,7 @@ QDBusReply<QVariant> \
MprisPlayerCommand::getPropertyValue(const QString &service return reply;
}
-bool MprisPlayerCommand::setPropertyValue(const QString &service, const \
QString &interfaceName, const QString &propertyName, const QVariant& \
propValue) +bool MprisPlayerCommand::setPropertyValue(const QString& \
service, const QString& interfaceName, const QString& propertyName, const \
QVariant& propValue) {
QDBusInterface *iface = new QDBusInterface(service, DBusMprisPath, \
PropertiesInterface,
\
QDBusConnection::sessionBus());
diff --git a/plugins/Commands/MprisPlayer/mprisplayercommand.h \
b/plugins/Commands/MprisPlayer/mprisplayercommand.h index d7287a3..d076018 \
100644
--- a/plugins/Commands/MprisPlayer/mprisplayercommand.h
+++ b/plugins/Commands/MprisPlayer/mprisplayercommand.h
@@ -53,14 +53,26 @@ class MprisPlayerCommand : public Command
m_role(role)
{
}
+ MprisPlayerCommand(const QString& name, const QString& iconSrc,
+ const QString& description, const QString& \
serviceName, + const QString& trackId) :
+ Command(name, iconSrc, description),
+ m_role(PlayParticular),
+ m_serviceName(serviceName),
+ m_trackId(trackId)
+ {
+ }
+
~MprisPlayerCommand() {}
CommandRole role();
+ QString trackId();
+ QString serviceName();
STATIC_CREATE_INSTANCE_H(MprisPlayerCommand)
protected:
- const QMap<QString,QVariant> getValueMapPrivate() const;
+ const QMap<QString, QVariant> getValueMapPrivate() const;
bool triggerPrivate(int *state);
MprisPlayerCommand() {}
@@ -71,6 +83,10 @@ class MprisPlayerCommand : public Command
const QString& propertyName, const QVariant& \
propValue);
CommandRole m_role;
+
+ //These members used only for "PlayParticular" CommandRole
+ QString m_serviceName;
+ QDBusObjectPath m_trackId;
};
#endif // SIMON_MPRISPLAYERCOMMAND_H_1822E03B797C494599B9629C6B47E478
diff --git a/plugins/Commands/MprisPlayer/mprisplayercommandmanager.cpp \
b/plugins/Commands/MprisPlayer/mprisplayercommandmanager.cpp index \
f41e757..ea59b0a 100644
--- a/plugins/Commands/MprisPlayer/mprisplayercommandmanager.cpp
+++ b/plugins/Commands/MprisPlayer/mprisplayercommandmanager.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Ashish Madeti <ashishmadeti@gmail.com>
+ * Copyright (C) 2014 Peter Grasch <peter.grasch@bedahr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
@@ -20,8 +21,11 @@
#include "mprisplayercommandmanager.h"
#include "mprisplayerconfiguration.h"
#include "mprisplayercommand.h"
-#include "mprisconstants.h"
#include "createmprisplayercommandwidget.h"
+#include "player.h"
+#include <simonactions/actionmanager.h>
+#include <simonscenarios/scenario.h>
+#include <simonscenarios/activevocabulary.h>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
@@ -34,7 +38,9 @@ K_PLUGIN_FACTORY( MprisPlayerPluginFactory,
K_EXPORT_PLUGIN( MprisPlayerPluginFactory("simoncommandmprisplayer") )
-MprisPlayerCommandManager::MprisPlayerCommandManager(QObject *parent, \
const QVariantList &args) +const QString MprisCategoryPrefix("MPRIS_");
+
+MprisPlayerCommandManager::MprisPlayerCommandManager(QObject *parent, \
const QVariantList& args) : CommandManager((Scenario*) parent, args)
{
}
@@ -59,6 +65,11 @@ const QString MprisPlayerCommandManager::name() const
return i18n("Media Player Control");
}
+void MprisPlayerCommandManager::finalize()
+{
+ cleanupCommandsAndWords();
+}
+
const QStringList MprisPlayerCommandManager::targetServices()
{
if (static_cast<MprisPlayerConfiguration*>(config)->supportAll()) {
@@ -74,16 +85,87 @@ const QStringList \
MprisPlayerCommandManager::runningMediaPlayerServices() return \
m_mediaPlayerList; }
+void MprisPlayerCommandManager::cleanupCommandsAndWords()
+{
+ removeWordsWithCategoryPrefix(MprisCategoryPrefix);
+
+ ScenarioManager::getInstance()->startGroup();
+
+ CommandList oldCommands = commands;
+ foreach (Command *c, oldCommands) {
+ MprisPlayerCommand *mpCommand = \
static_cast<MprisPlayerCommand*>(c); + if (mpCommand && \
mpCommand->role() == PlayParticular) { + deleteCommand(c);
+ }
+ }
+
+ ScenarioManager::getInstance()->commitGroup();
+}
+
+void MprisPlayerCommandManager::cleanupCommandsAndWords(const QString& \
serviceName) +{
+ QString categoryPrefix = MprisCategoryPrefix + \
serviceName.mid(MprisPlayerPrefix.size()); + \
removeWordsWithCategoryPrefix(categoryPrefix); +
+ ScenarioManager::getInstance()->startGroup();
+
+ CommandList oldCommands = commands;
+ foreach (Command *c, oldCommands) {
+ MprisPlayerCommand *mpCommand = \
static_cast<MprisPlayerCommand*>(c); + if (mpCommand && \
mpCommand->serviceName() == serviceName) { + deleteCommand(c);
+ oldCommands.removeAll(c);
+ }
+ }
+
+ ScenarioManager::getInstance()->commitGroup();
+}
+
+void MprisPlayerCommandManager::removeWordsWithCategoryPrefix(const \
QString& prefix) +{
+ ScenarioManager::getInstance()->startGroup();
+
+ Vocabulary *vocab = parentScenario->vocabulary();
+ QList<Word*> internalWords = vocab->getWords();
+
+ foreach (Word *w, internalWords) {
+ if (w->getCategory().startsWith(prefix)) {
+ vocab->removeWord(w, true);
+ internalWords.removeAll(w);
+ }
+ }
+
+ ScenarioManager::getInstance()->commitGroup();
+}
+
CreateCommandWidget* \
MprisPlayerCommandManager::getCreateCommandWidget(QWidget *parent) {
return new CreateMprisPlayerCommandWidget(this, parent);
}
-bool MprisPlayerCommandManager::deSerializeConfig(const QDomElement &elem)
+bool MprisPlayerCommandManager::deSerializeConfig(const QDomElement& elem)
{
config = new MprisPlayerConfiguration(parentScenario);
config->deSerialize(elem);
+ return true;
+}
+
+bool MprisPlayerCommandManager::deSerializeCommandsPrivate(const \
QDomElement& elem) +{
+ if (elem.isNull()) {
+ return false;
+ }
+ QDomElement commandElem = elem.firstChildElement("command");
+ while(!commandElem.isNull())
+ {
+ Command *c = MprisPlayerCommand::createInstance(commandElem);
+ if (c) {
+ commands.append(c);
+ }
+ commandElem = commandElem.nextSiblingElement("command");
+ }
+
QDBusConnection sessionConn = QDBusConnection::sessionBus();
QDBusReply<QStringList> reply = \
sessionConn.interface()->registeredServiceNames(); if (reply.isValid()) {
@@ -104,20 +186,129 @@ bool \
MprisPlayerCommandManager::deSerializeConfig(const QDomElement &elem) \
return true; }
-DEFAULT_DESERIALIZE_COMMANDS_PRIVATE_C(MprisPlayerCommandManager, \
MprisPlayerCommand)
-
MprisPlayerCommandManager::~MprisPlayerCommandManager()
{
+ delete m_registerWatcher;
+ delete m_unregisterWatcher;
}
-void MprisPlayerCommandManager::serviceRegistered(const QString \
&serviceName) +void MprisPlayerCommandManager::serviceRegistered(const \
QString& serviceName) {
+ Player *player;
if (serviceName.startsWith(MprisPlayerPrefix) && \
!m_mediaPlayerList.contains(serviceName)) { m_mediaPlayerList << \
serviceName; +
+ player = new Player(serviceName, this);
+ m_players.insert(serviceName, player);
}
}
-void MprisPlayerCommandManager::serviceUnregistered(const QString \
&serviceName) +void MprisPlayerCommandManager::serviceUnregistered(const \
QString& serviceName) {
m_mediaPlayerList.removeAll(serviceName);
+
+ Player *player = m_players.take(serviceName);
+ if (player != 0) {
+ player->deleteLater();
+ cleanupCommandsAndWords(serviceName);
+ }
+}
+
+void MprisPlayerCommandManager::addToCommandlist(const TrackList& \
trackList, const QString& serviceName) +{
+ ScenarioManager::getInstance()->startGroup();
+
+ Vocabulary *vocab = parentScenario->vocabulary();
+ QList<Word*> internalWords = vocab->getWords();
+ CommandList oldCommands = commands;
+
+ //pairs of word and category name
+ QList< QPair<QString, QString> > pseudoWordsToAdd;
+ QStringList toTranscribe;
+
+ QString categoryPrefix = MprisCategoryPrefix + \
serviceName.mid(MprisPlayerPrefix.size()) + "_"; +
+ QString trackTitle;
+ QString trackId;
+ foreach (const Track& t, trackList) {
+ trackId = t.first;
+ trackTitle = t.second;
+
+ //create safe trigger word
+ trackTitle.remove(QRegExp(QLatin1String("\\(.*\\)")));
+ trackTitle.remove(QLatin1String("("));
+ trackTitle.remove(QLatin1String(")"));
+ trackTitle.remove(QLatin1String("$"));
+ trackTitle.remove(QLatin1String("/"));
+ trackTitle.replace(' ', '_');
+ trackTitle = trackTitle.trimmed();
+
+
+ QString category = categoryPrefix + \
trackId.mid(trackId.lastIndexOf("/") + 1); + toTranscribe << \
trackTitle.split('_', QString::SkipEmptyParts); + \
pseudoWordsToAdd.append(QPair<QString, QString>(trackTitle, category)); +
+ //check if we already have the required command
+ bool isNew = true;
+ foreach (Command *c, oldCommands) {
+ if (static_cast<MprisPlayerCommand*>(c)->trackId() == trackId
+ && static_cast<MprisPlayerCommand*>(c)->serviceName() \
== serviceName) { + isNew = false;
+ break;
+ }
+ }
+
+ //if not, add the command
+ if (isNew) {
+ addCommand(new MprisPlayerCommand(trackTitle,
+ "applications-multimedia",
+ i18n("Play media: %1", \
trackTitle), serviceName, + \
trackId)); + }
+ }
+
+ //add the (pseudo) words
+ QHash<QString,QString> transcriptions = \
ScenarioManager::getInstance()->transcribe(toTranscribe); + \
QPair<QString, QString> wordToBe; + foreach (wordToBe, pseudoWordsToAdd) \
{ + QStringList transcription;
+ foreach (const QString realWord, wordToBe.first.split('_'))
+ transcription.append(transcriptions.value(realWord.toUpper()));
+ parentScenario->addWord(new Word(wordToBe.first, \
transcription.join(" "), wordToBe.second)); + }
+
+ ScenarioManager::getInstance()->commitGroup();
+}
+
+void MprisPlayerCommandManager::removeFromCommandlist(const QStringList& \
removedTracksList, const QString& serviceName) +{
+ ScenarioManager::getInstance()->startGroup();
+
+ Vocabulary *vocab = parentScenario->vocabulary();
+ QList<Word*> internalWords = vocab->getWords();
+ CommandList oldCommands = commands;
+
+ QString categoryPrefix = MprisCategoryPrefix + \
serviceName.mid(MprisPlayerPrefix.size()) + "_"; +
+ foreach (const QString& trackId, removedTracksList) {
+ foreach (Command *c, oldCommands) {
+ MprisPlayerCommand *mpCommand = \
static_cast<MprisPlayerCommand*>(c); + if (mpCommand && \
mpCommand->trackId() == trackId && + \
mpCommand->serviceName() == serviceName) { + \
deleteCommand(c); + oldCommands.removeAll(c);
+ break;
+ }
+ }
+
+ QString category = categoryPrefix + \
trackId.mid(trackId.lastIndexOf("/") + 1); + foreach (Word *w, \
internalWords) { + if (w->getCategory().startsWith(category)) {
+ vocab->removeWord(w, true);
+ internalWords.removeAll(w);
+ }
+ }
+ }
+
+ ScenarioManager::getInstance()->commitGroup();
}
diff --git a/plugins/Commands/MprisPlayer/mprisplayercommandmanager.h \
b/plugins/Commands/MprisPlayer/mprisplayercommandmanager.h index \
f2c091b..6c029a0 100644
--- a/plugins/Commands/MprisPlayer/mprisplayercommandmanager.h
+++ b/plugins/Commands/MprisPlayer/mprisplayercommandmanager.h
@@ -21,10 +21,12 @@
#define SIMON_MPRISPLAYERCOMMANDMANAGER_H_7A7B9100FF5245329569C1B540119C37
#include <simonscenarios/commandmanager.h>
+#include "mprisconstants.h"
#include <QDBusServiceWatcher>
class MprisPlayerConfiguration;
+class Player;
/**
* @class MprisPlayerCommandManager
@@ -45,13 +47,18 @@ class MprisPlayerCommandManager : public CommandManager
const QString preferredTrigger() const;
const QString iconSrc() const;
const QString name() const;
+ void finalize();
const QStringList targetServices();
+ void addToCommandlist(const TrackList& trackIdTitleMap,
+ const QString& serviceName);
+ void removeFromCommandlist(const QStringList& removedTracksList,
+ const QString& serviceName);
CreateCommandWidget* getCreateCommandWidget(QWidget *parent);
bool deSerializeConfig(const QDomElement& elem);
- DEFAULT_DESERIALIZE_COMMANDS_PRIVATE_H
+ bool deSerializeCommandsPrivate(const QDomElement& elem);
MprisPlayerCommandManager(QObject* parent, const QVariantList& args);
~MprisPlayerCommandManager();
@@ -62,10 +69,14 @@ class MprisPlayerCommandManager : public CommandManager
private:
const QStringList runningMediaPlayerServices();
+ void cleanupCommandsAndWords();
+ void cleanupCommandsAndWords(const QString& serviceName);
+ void removeWordsWithCategoryPrefix(const QString& prefix);
QStringList m_mediaPlayerList;
QDBusServiceWatcher* m_registerWatcher;
QDBusServiceWatcher* m_unregisterWatcher;
+ QHash<QString, Player*> m_players;
};
#endif // SIMON_MPRISPLAYERCOMMANDMANAGER_H_7A7B9100FF5245329569C1B540119C37
diff --git a/plugins/Commands/MprisPlayer/mprisplayerconfiguration.cpp \
b/plugins/Commands/MprisPlayer/mprisplayerconfiguration.cpp index \
4f25541..0a73db6 100644
--- a/plugins/Commands/MprisPlayer/mprisplayerconfiguration.cpp
+++ b/plugins/Commands/MprisPlayer/mprisplayerconfiguration.cpp
@@ -92,7 +92,7 @@ void MprisPlayerConfiguration::populateMediaServices()
QStringList services = reply.value();
foreach (const QString& serviceName, services) {
if (serviceName.startsWith(MprisPlayerPrefix)
- && ui.cbMediaServiceNames->findText(serviceName) == -1) {
+ && ui.cbMediaServiceNames->findText(serviceName) == -1) {
ui.cbMediaServiceNames->addItem(serviceName);
}
}
diff --git a/plugins/Commands/MprisPlayer/player.cpp \
b/plugins/Commands/MprisPlayer/player.cpp new file mode 100644
index 0000000..3dce705
--- /dev/null
+++ b/plugins/Commands/MprisPlayer/player.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2014 Ashish Madeti <ashishmadeti@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or (at your option) any later version, as published by the Free
+ * Software Foundation
+ *
+ * This program 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 General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "player.h"
+#include "mprisconstants.h"
+#include "mprisplayercommand.h"
+#include "mprisplayercommandmanager.h"
+
+#include <QDBusConnection>
+#include <QDBusObjectPath>
+#include <QDBusInterface>
+#include <QDBusReply>
+#include <QDBusPendingCallWatcher>
+
+Player::Player(const QString& serviceName, QObject *parent)
+ : QObject(parent),
+ m_serviceName(serviceName)
+{
+ qDBusRegisterMetaType< QList<QVariantMap> >();
+ getAllTracks();
+ connectTracklistSignals();
+}
+
+Player::~Player()
+{
+}
+
+void Player::trackAdded(const QVariantMap& metadata, const \
QDBusObjectPath& afterTrack) +{
+ Q_UNUSED(afterTrack)
+
+ QString trackId = \
metadata[trackIdMetadata].value<QDBusObjectPath>().path(); + QString \
title = metadata[titleMetadata].toString(); + \
m_currentTracklist[trackId] = title; +
+ TrackList m;
+ m << Track(trackId, title);
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ addToCommandlist(m, m_serviceName);
+}
+
+void Player::trackRemoved(const QDBusObjectPath& trackId)
+{
+ m_currentTracklist.remove(trackId.path());
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ removeFromCommandlist(QStringList() << trackId.path(), \
m_serviceName); +}
+
+void Player::trackMetadataChanged(const QDBusObjectPath& trackId, const \
QVariantMap& metadata) +{
+ QString newTrackId;
+ QString newTitle;
+ if (m_currentTracklist.contains(trackId.path())) {
+ newTrackId = \
metadata[trackIdMetadata].value<QDBusObjectPath>().path(); + \
newTitle = metadata[titleMetadata].toString(); + \
m_currentTracklist[newTrackId] = newTitle; + if (trackId.path() != \
newTrackId) { + m_currentTracklist.remove(trackId.path());
+ }
+
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ removeFromCommandlist(QStringList() << trackId.path(), \
m_serviceName); +
+ TrackList m;
+ m << Track(newTrackId, newTitle);
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ addToCommandlist(m, m_serviceName);
+ }
+}
+
+void Player::tracklistReplaced(const QList<QDBusObjectPath>& tracks, const \
QDBusObjectPath& currentTrack) +{
+ Q_UNUSED(currentTrack)
+
+ QDBusInterface iface(m_serviceName, DBusMprisPath, \
TracklistInterface); + QDBusPendingCall pendingCall = \
iface.asyncCall("GetTracksMetadata", + \
QVariant::fromValue< QList<QDBusObjectPath> >(tracks)); +
+ connect(new QDBusPendingCallWatcher(pendingCall, this),
+ SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(tracksMetadataReceived(QDBusPendingCallWatcher*)));
+}
+
+void Player::tracksMetadataReceived(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply< QList<QVariantMap> > reply = *watcher;
+
+ if (reply.error().isValid()) {
+ kDebug() << "GetTracksMetadata for service " << m_serviceName
+ << " failed with error: " << reply.error().message();
+ return;
+ }
+
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ removeFromCommandlist(m_currentTracklist.uniqueKeys(), \
m_serviceName); + m_currentTracklist.clear();
+
+ QString trackId;
+ TrackList m;
+ foreach (const QVariantMap& metadata, reply.value()) {
+ trackId = metadata[trackIdMetadata].value<QDBusObjectPath>().path();
+ m_currentTracklist[trackId] = metadata[titleMetadata].toString();
+ m << Track(trackId, metadata[titleMetadata].toString());
+ }
+
+ static_cast<MprisPlayerCommandManager*>(parent())->
+ addToCommandlist(m, m_serviceName);
+
+ watcher->deleteLater();
+}
+
+void Player::connectTracklistSignals()
+{
+
+ QDBusConnection::sessionBus().connect(m_serviceName,
+ DBusMprisPath,
+ TracklistInterface,
+ "TrackAdded",
+ this,
+ \
SLOT(trackAdded(QVariantMap,QDBusObjectPath))); + \
QDBusConnection::sessionBus().connect(m_serviceName, + \
DBusMprisPath, + \
TracklistInterface, + \
"TrackRemoved", + this,
+ \
SLOT(trackRemoved(QDBusObjectPath))); + \
QDBusConnection::sessionBus().connect(m_serviceName, + \
DBusMprisPath, + \
TracklistInterface, + \
"TrackMetadataChanged", + this,
+ \
SLOT(trackMetadataChanged(QDBusObjectPath,QVariantMap))); + \
QDBusConnection::sessionBus().connect(m_serviceName, + \
DBusMprisPath, + \
TracklistInterface, + \
"TrackListReplaced", + this,
+ \
SLOT(tracklistReplaced(QList<QDBusObjectPath>,QDBusObjectPath))); +}
+
+void Player::getAllTracks()
+{
+ QDBusInterface propsIface(m_serviceName, DBusMprisPath, \
PropertiesInterface); + QDBusPendingCall pendingCall = \
propsIface.asyncCall("Get",TracklistInterface, "Tracks"); +
+ connect(new QDBusPendingCallWatcher(pendingCall, this),
+ SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(tracksPropertyReceived(QDBusPendingCallWatcher*)));
+
+}
+
+void Player::tracksPropertyReceived(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<QVariant> reply = *watcher;
+ if (reply.isError()) {
+ kDebug() << "\"Get\" for property \"Tracks\" for service "
+ << m_serviceName << " failed with error: "
+ << reply.error().message();
+ return;
+ }
+
+ QList<QDBusObjectPath> tracks;
+ const QDBusArgument& arg = reply.value().value<QDBusArgument>();
+ arg.beginArray();
+ while (!arg.atEnd()) {
+ tracks << arg.asVariant().value<QDBusObjectPath>();
+ }
+ arg.endArray();
+
+ tracklistReplaced(tracks, QDBusObjectPath());
+ watcher->deleteLater();
+}
diff --git a/plugins/Commands/MprisPlayer/player.h \
b/plugins/Commands/MprisPlayer/player.h new file mode 100644
index 0000000..ce74d2e
--- /dev/null
+++ b/plugins/Commands/MprisPlayer/player.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Ashish Madeti <ashishmadeti@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or (at your option) any later version, as published by the Free
+ * Software Foundation
+ *
+ * This program 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 General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SIMON_PLAYER_H_ABC0C7EC08DA40FEBD5B5BA233D7AC7C
+#define SIMON_PLAYER_H_ABC0C7EC08DA40FEBD5B5BA233D7AC7C
+
+#include <QDBusMetaType>
+
+Q_DECLARE_METATYPE(QList<QVariantMap>)
+
+class QDBusObjectPath;
+class QDBusPendingCallWatcher;
+
+/**
+ * @class Player
+ * @brief Manages Tracklist of an MPRIS media player
+ *
+ * @version 0.1
+ * @date 29.06.2014
+ * @author Ashish Madeti
+ */
+
+class Player : public QObject
+{
+ Q_OBJECT
+
+public:
+ Player(const QString& serviceName, QObject *parent = 0);
+ ~Player();
+
+public slots:
+ void trackAdded(const QVariantMap& metadata, const QDBusObjectPath& \
afterTrack); + void trackRemoved(const QDBusObjectPath& trackId);
+ void trackMetadataChanged(const QDBusObjectPath& trackId, const \
QVariantMap& metadata); + void tracklistReplaced(const \
QList<QDBusObjectPath>& tracks, const QDBusObjectPath& currentTrack); +
+private slots:
+ void tracksPropertyReceived(QDBusPendingCallWatcher* watcher);
+ void tracksMetadataReceived(QDBusPendingCallWatcher* watcher);
+
+private:
+ void connectTracklistSignals();
+ void getAllTracks();
+
+ QHash<QString, QString> m_currentTracklist;
+ QString m_serviceName;
+};
+
+#endif // SIMON_PLAYER_H_ABC0C7EC08DA40FEBD5B5BA233D7AC7C
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic