mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 10:52:53 +00:00
545 lines
23 KiB
C++
545 lines
23 KiB
C++
/*
|
|
* Copyright (C) 2008 Bruno Virlet <bvirlet@kdemail.net>
|
|
* Copyright (C) 2009 Ryan P. Bitanga <ryan.bitanga@gmail.com>
|
|
* Copyright (C) 2009 Jan G. Marker <jangerrit@weiler-marker.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 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 Library 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 "audioplayercontrolrunner.h"
|
|
#include "imageiconengine.h"
|
|
|
|
#include <QtDBus/QDBusInterface>
|
|
#include <QtDBus/QDBusMetaType>
|
|
#include <QtDBus/QDBusPendingReply>
|
|
#include <QtDBus/qdbuspendingcall.h>
|
|
#include <QtDBus/QDBusMessage>
|
|
|
|
#include <KMessageBox>
|
|
#include <KDebug>
|
|
#include <KIcon>
|
|
#include <KRun>
|
|
#include <KUrl>
|
|
|
|
#include "audioplayercontrolconfigkeys.h"
|
|
|
|
Q_DECLARE_METATYPE(QList<QVariantMap>)
|
|
|
|
/** The variable PLAY contains the action label for play */
|
|
static const QString PLAY(QLatin1String("play"));
|
|
/** The variable APPEND contains the action label for append */
|
|
static const QString APPEND(QLatin1String("append"));
|
|
/** The variable QUEUE contains the action label for queue */
|
|
static const QString QUEUE(QLatin1String("queue"));
|
|
/** The variable NONE says that no action is needed */
|
|
static const QString NONE(QLatin1String("none"));
|
|
|
|
|
|
AudioPlayerControlRunner::AudioPlayerControlRunner(QObject *parent, const QVariantList& args)
|
|
: Plasma::AbstractRunner(parent, args)
|
|
{
|
|
Q_UNUSED(args);
|
|
|
|
setObjectName(QLatin1String( "Audio Player Control Runner" ));
|
|
setSpeed(AbstractRunner::SlowSpeed);
|
|
|
|
qDBusRegisterMetaType<QList<QVariantMap> >();
|
|
|
|
connect(this, SIGNAL(prepare()), this, SLOT(prep()));
|
|
|
|
reloadConfiguration();
|
|
}
|
|
|
|
AudioPlayerControlRunner::~AudioPlayerControlRunner()
|
|
{
|
|
}
|
|
|
|
|
|
void AudioPlayerControlRunner::prep()
|
|
{
|
|
m_running = false;
|
|
m_songsInPlaylist = 0;
|
|
m_currentTrack = -1;
|
|
m_nextSongAvailable = false;
|
|
m_prevSongAvailable = false;
|
|
|
|
QDBusInterface player(QString::fromLatin1( "org.mpris.%1").arg(m_player), QLatin1String( "/TrackList" ), QLatin1String( "org.freedesktop.MediaPlayer" ));
|
|
QDBusPendingCall call = player.asyncCall(QLatin1String( "GetLength" ));
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
|
|
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
|
|
this, SLOT(songsInPlaylist(QDBusPendingCallWatcher*)));
|
|
|
|
call = player.asyncCall(QLatin1String( "GetCurrentTrack" ));
|
|
watcher = new QDBusPendingCallWatcher(call, this);
|
|
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
|
|
this, SLOT(prevNextSongAvailable(QDBusPendingCallWatcher*)));
|
|
}
|
|
|
|
void AudioPlayerControlRunner::match(Plasma::RunnerContext &context)
|
|
{
|
|
if (context.query().length() < 3) {
|
|
return;
|
|
}
|
|
|
|
const QString term = context.query();
|
|
|
|
QList<Plasma::QueryMatch> matches;
|
|
|
|
if (m_useCommands) {
|
|
/* DBus paths that are used in the command executes */
|
|
/* The data variable looks like this:
|
|
* "/PlayerQLatin1String( " " )org.freedesktop.MediaPlayerQLatin1String( " " )PlayQLatin1String( " " )actionsQLatin1String( " " )start" args...
|
|
* <path> <interface> <method> <actions> <start player>
|
|
* <actions> is NONE if no action is needed
|
|
*/
|
|
|
|
QVariantList playcontrol;
|
|
playcontrol << QLatin1String( "/Player" ) << QLatin1String( "org.freedesktop.MediaPlayer" );
|
|
|
|
/* The commands */
|
|
|
|
//Play
|
|
if (context.isValid() && m_comPlay.startsWith(term, Qt::CaseInsensitive) &&
|
|
(!m_running || m_songsInPlaylist)) {
|
|
QVariantList data = playcontrol;
|
|
data << ((currentSong() == -1) ? QLatin1String( "Next" ) : QLatin1String( "Play" )) << NONE << QLatin1String( "start" );
|
|
matches << createMatch(this, i18n("Start playing"), i18n("Audio player control"), QLatin1String( "play" ),
|
|
KIcon( QLatin1String( "media-playback-start" )), data, 1.0);
|
|
}
|
|
|
|
if (!context.isValid() || !m_running) {
|
|
//The interface of the player is not availalbe, so the rest of the commands
|
|
//is not needed
|
|
context.addMatches(term,matches);
|
|
return;
|
|
}
|
|
|
|
if (context.isValid() && m_songsInPlaylist) {
|
|
//The playlist isn't empty
|
|
//Next song
|
|
if (m_comNext.startsWith(term,Qt::CaseInsensitive)
|
|
&& m_nextSongAvailable) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "Next" ) << NONE << QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Play next song"), i18n("Audio player control"),
|
|
QLatin1String( "next" ), KIcon( QLatin1String( "media-skip-forward" )), data, 1.0);
|
|
}
|
|
|
|
//Previous song
|
|
if (context.isValid() && m_comPrev.startsWith(term,Qt::CaseInsensitive)
|
|
&& m_prevSongAvailable) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "Prev" ) << NONE << QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Play previous song"), i18n("Audio player control") ,
|
|
QLatin1String( "previous" ), KIcon( QLatin1String( "media-skip-backward" )), data, 1.0);
|
|
}
|
|
}//--- if (m_songsInPlaylist)
|
|
|
|
//Pause
|
|
if (context.isValid() && m_comPause.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "Pause" ) << NONE << QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Pause playing"), i18n("Audio player control"),
|
|
QLatin1String( "pause" ), KIcon( QLatin1String( "media-playback-pause" )), data, 1.0);
|
|
}
|
|
|
|
//Stop
|
|
if (context.isValid() && m_comStop.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "Stop" ) << NONE << QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Stop playing"), i18n("Audio player control"),
|
|
QLatin1String( "stop" ), KIcon( QLatin1String( "media-playback-stop" )), data, 1.0);
|
|
}
|
|
|
|
//Increase
|
|
if (context.isValid() && m_comIncrease.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "VolumeUp" ) << NONE << QLatin1String( "nostart" ) << m_increaseBy;
|
|
matches << createMatch(this, i18n("Increase volume by %1" , m_increaseBy),
|
|
QLatin1String( "volumeup" ), i18n("Audio player control"), KIcon(QLatin1String( "audio-volume-high" )), data, 1.0);
|
|
} else if (context.isValid() && equals(term, QRegExp( m_comIncrease + QLatin1String( " \\d{1,2}0{0,1}" ) ) ) ) {
|
|
int volumeChange = getNumber(term, ' ' );
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "VolumeUp" ) << NONE << QLatin1String( "nostart" ) << volumeChange;
|
|
matches << createMatch(this, i18n("Increase volume by %1" , volumeChange),
|
|
QLatin1String( "volumeup" ), i18n("Audio player control"), KIcon(QLatin1String( "audio-volume-high" )), data, 1.0);
|
|
}
|
|
|
|
//Decrease
|
|
if (context.isValid() && m_comDecrease.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "VolumeDown" ) << NONE << QLatin1String( "nostart" ) << m_decreaseBy;
|
|
matches << createMatch(this, i18n("Reduce volume by %1", m_decreaseBy),
|
|
QLatin1String( "volumedown" ), i18n("Audio player control"), KIcon(QLatin1String( "audio-volume-low" )), data, 1.0);
|
|
} else if (context.isValid() && equals(term, QRegExp( m_comDecrease + QLatin1String( " \\d{1,2}0{0,1}" ) ) ) ) {
|
|
int volumeChange = getNumber(term, ' ');
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "VolumeDown" ) << NONE << QLatin1String( "nostart" ) << volumeChange;
|
|
matches << createMatch(this, i18n("Reduce volume by %1", volumeChange),
|
|
QLatin1String( "volumedown" ), i18n("Audio player control"), KIcon(QLatin1String( "audio-volume-low" )), data, 1.0);
|
|
}
|
|
|
|
//Set volume to
|
|
if (context.isValid() && equals(term, QRegExp( m_comVolume + QLatin1String( " \\d{1,2}0{0,1}" ) ) ) ) {
|
|
QVariantList data = playcontrol;
|
|
int newVolume = getNumber(term , ' ');
|
|
data << QLatin1String( "VolumeSet" ) << NONE << QLatin1String( "nostart" ) << newVolume;
|
|
matches << createMatch(this, i18n("Set volume to %1%" , newVolume),
|
|
QLatin1String( "volume" ), i18n("Audio player control"), KIcon(QLatin1String( "audio-volume-medium" )), data, 1.0);
|
|
}
|
|
|
|
//Mute
|
|
if (context.isValid() && m_comMute.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data = playcontrol;
|
|
data << QLatin1String( "Mute" ) << NONE << QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Mute"), i18n("Audio player control"),
|
|
QLatin1String( "mute" ), KIcon( QLatin1String( "audio-volume-muted" )), data, 1.0);
|
|
}
|
|
|
|
//Quit player
|
|
if (context.isValid() && m_comQuit.startsWith(term,Qt::CaseInsensitive)) {
|
|
QVariantList data;
|
|
data << QLatin1String( "/" ) << QLatin1String( "org.freedesktop.MediaPlayer" ) << QLatin1String( "Quit" ) << NONE
|
|
<< QLatin1String( "nostart" );
|
|
matches << createMatch(this, i18n("Quit %1", m_player),QLatin1String( "" ),
|
|
QLatin1String( "quit" ), KIcon( QLatin1String( "application-exit" )), data, 1.0);
|
|
}
|
|
}//--- if (m_useCommands)
|
|
|
|
if (context.isValid() && m_searchCollection) {
|
|
QString actionNames;
|
|
QString searchTerm = term;
|
|
QString command;
|
|
|
|
if (term.startsWith(m_comPlay,Qt::CaseInsensitive)
|
|
&& term.length() > m_comPlay.length()) {
|
|
command = m_comPlay;
|
|
actionNames = PLAY;
|
|
} else if (term.startsWith(m_comAppend, Qt::CaseInsensitive)
|
|
&& term.length() > m_comAppend.length()) {
|
|
command = m_comAppend;
|
|
actionNames = APPEND;
|
|
} else if (term.startsWith(m_comQueue, Qt::CaseInsensitive)
|
|
&& term.length() > m_comQueue.length()) {
|
|
command = m_comQueue;
|
|
actionNames = QUEUE;
|
|
} else {
|
|
actionNames = QString::fromLatin1( "%1,%2,%3").arg(PLAY).arg(APPEND).arg(QUEUE);
|
|
}
|
|
|
|
if (!context.isValid())
|
|
{
|
|
return;
|
|
}
|
|
searchTerm = searchTerm.right(searchTerm.length() - (command.length() + 1));
|
|
matches << searchCollectionFor(searchTerm, actionNames);
|
|
//Adds matches for all song matches for term
|
|
}
|
|
|
|
context.addMatches(term, matches);
|
|
}
|
|
|
|
void AudioPlayerControlRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
|
|
{
|
|
Q_UNUSED(context)
|
|
QDBusInterface tracklist(QString::fromLatin1( "org.mpris.%1").arg(m_player),
|
|
QLatin1String( "/TrackList" ), QLatin1String( "org.freedesktop.MediaPlayer" ));
|
|
|
|
QVariantList data = match.data().value<QVariantList>();
|
|
|
|
/* Only Amarok part*/
|
|
QString url = data[2].toString();
|
|
int pos = posInPlaylist(url);
|
|
kDebug() << "pos" << pos;
|
|
QAction *a = match.selectedAction();
|
|
if (data[3].toString().compare(NONE)) {
|
|
if (!a)
|
|
{
|
|
a = action(data[3].toString());
|
|
}
|
|
if (a == action(QUEUE)) {
|
|
KUrl::List list;
|
|
list << KUrl(url);
|
|
KRun::run(QLatin1String( "amarok --queue %u" ), list, 0);
|
|
} else if (a == action(APPEND)) {
|
|
if (!(pos > -1)) {
|
|
tracklist.call(QDBus::NoBlock, QLatin1String( "AddTrack" ), url , false);
|
|
}
|
|
} else {
|
|
//Action play was selected
|
|
if (pos > -1) {
|
|
tracklist.call(QDBus::NoBlock, QLatin1String( "PlayTrack" ), pos);
|
|
} else {
|
|
tracklist.call(QDBus::NoBlock, QLatin1String( "AddTrack" ), url, true);
|
|
}
|
|
}
|
|
}/* Only Amarok part over */ else {
|
|
if ((data[4].toString().compare(QLatin1String( "start" )) == 0)) {
|
|
//The players's interface isn't available but it should be started
|
|
if (!startPlayer()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
QDBusMessage msg = QDBusMessage::createMethodCall(QString::fromLatin1( "org.mpris.%1").arg(m_player),data[0].toString(),
|
|
data[1].toString(), data[2].toString());
|
|
kDebug() << msg;
|
|
QVariantList args;
|
|
for (int i = 5;data.length() > i;++i) {
|
|
args << data[i];
|
|
}
|
|
msg.setArguments(args);
|
|
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
|
|
}
|
|
}
|
|
|
|
QList<QAction*> AudioPlayerControlRunner::actionsForMatch(const Plasma::QueryMatch &match)
|
|
{
|
|
QList<QAction*> ret;
|
|
QVariantList data = match.data().value<QVariantList>();
|
|
|
|
if (data.length() > 3 && data[3].toString().compare(NONE)) {
|
|
if (!action(PLAY)) {
|
|
addAction(PLAY, KIcon(QLatin1String( "media-playback-start" )), i18n("Play"));
|
|
addAction(QUEUE, KIcon(QLatin1String( "media-track-queue-amarok" )), i18n("Queue"));
|
|
addAction(APPEND, KIcon(QLatin1String( "media-track-add-amarok" )), i18n("Append to playlist"));
|
|
}
|
|
|
|
const QStringList actions = data[3].toString().split(QLatin1Char( ',' ));
|
|
|
|
for (int i = 0; i < actions.length(); ++i) {
|
|
ret << action(actions[i]);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void AudioPlayerControlRunner::reloadConfiguration()
|
|
{
|
|
KConfigGroup grp = config();
|
|
m_player = grp.readEntry(CONFIG_PLAYER, "amarok");
|
|
m_useCommands = grp.readEntry(CONFIG_COMMANDS, true);
|
|
m_searchCollection = grp.readEntry(CONFIG_COLLECTION, true);
|
|
m_comPlay = grp.readEntry(CONFIG_PLAY, i18n("play"));
|
|
m_comAppend = grp.readEntry(CONFIG_APPEND, i18n("append"));
|
|
m_comQueue = grp.readEntry(CONFIG_QUEUE, i18n("queue"));
|
|
m_comPause = grp.readEntry(CONFIG_PAUSE, i18n("pause"));
|
|
m_comNext = grp.readEntry(CONFIG_NEXT, i18n("next"));
|
|
m_comMute = grp.readEntry(CONFIG_MUTE, i18n("mute"));
|
|
m_comIncrease = grp.readEntry(CONFIG_INCREASE, i18n("increase"));
|
|
m_increaseBy = qBound(0, grp.readEntry(CONFIG_INCREASE_BY, 15), 100);
|
|
m_comDecrease = grp.readEntry(CONFIG_DECREASE, i18n("decrease"));
|
|
m_decreaseBy = qBound(0, grp.readEntry(CONFIG_DECREASE_BY, 15), 100);
|
|
m_comPrev = grp.readEntry(CONFIG_PREV, i18n("prev"));
|
|
m_comStop = grp.readEntry(CONFIG_STOP, i18n("stop"));
|
|
m_comVolume = grp.readEntry(CONFIG_VOLUME, i18n("volume"));
|
|
m_comQuit = grp.readEntry(CONFIG_QUIT, i18n("quit"));
|
|
|
|
/* Adding the syntaxes for helping the user */
|
|
QList<Plasma::RunnerSyntax> syntaxes;
|
|
|
|
if (m_player == QLatin1String( "amarok" )) {
|
|
syntaxes << Plasma::RunnerSyntax(m_comPlay + QLatin1String( " :q:" ),
|
|
i18n("Plays the selected song. If :q: is not empty it lists songs matching :q: to play them"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comAppend + QLatin1String( " :q:" ),
|
|
i18n("Displays songs matching :q: for appending the selected to the playlist"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comQueue + QLatin1String( " :q:" ),
|
|
i18n("Displays songs matching :q: for queueing them"));
|
|
} else {
|
|
syntaxes << Plasma::RunnerSyntax(m_comPlay,
|
|
i18n("Plays a song from playlist"));
|
|
}
|
|
syntaxes << Plasma::RunnerSyntax(m_comPause,i18n("Pauses the playing"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comNext, i18n("Plays the next song in the playlist if one is available"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comMute, i18n("Mutes/unmutes the player"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comIncrease + QLatin1String( " :q:" ),
|
|
i18n("Increases the volume by :q:. If :q: is empty it increases by the configured value"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comDecrease + QLatin1String( " :q:" ),
|
|
i18n("Decreases the volume by :q:. If :q: is empty it decreases by the configured value"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comPrev, i18n("Plays the previous song if one is available"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comStop, i18n("Stops the playing"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comVolume + QLatin1String( " :q:" ), i18n("Sets the volume to :q:"));
|
|
syntaxes << Plasma::RunnerSyntax(m_comQuit, i18n("Quits the player"));
|
|
|
|
setSyntaxes(syntaxes);
|
|
}
|
|
|
|
Plasma::QueryMatch AudioPlayerControlRunner::createMatch(Plasma::AbstractRunner* runner,
|
|
const QString &title, const QString &subtext, const QString &id,
|
|
const KIcon &icon, const QVariantList &data, const float &relevance)
|
|
{
|
|
Plasma::QueryMatch match(runner);
|
|
match.setText(title);
|
|
match.setSubtext(subtext);
|
|
match.setId(id);
|
|
match.setIcon(icon);
|
|
match.setData(data);
|
|
match.setRelevance(relevance);
|
|
return match;
|
|
}
|
|
|
|
bool AudioPlayerControlRunner::playerRunning() const
|
|
{
|
|
return m_running;
|
|
}
|
|
|
|
bool AudioPlayerControlRunner::startPlayer() const
|
|
{
|
|
if (playerRunning()) {
|
|
return true;
|
|
}
|
|
|
|
if (!KRun::run(m_player, KUrl::List(), 0)) {
|
|
//We couldn't start the player
|
|
KMessageBox::error(0, i18n("%1 not found", m_player),
|
|
i18n("%1 was not found so the runner is unable to work.", m_player));
|
|
return false;
|
|
}
|
|
|
|
/*while (!playerRunning()) {
|
|
//Waiting for the player's interface to appear
|
|
;
|
|
}*/
|
|
return true;
|
|
}
|
|
|
|
int AudioPlayerControlRunner::posInPlaylist(const KUrl& url)
|
|
{
|
|
QDBusInterface player(QString::fromLatin1( "org.mpris.%1").arg(m_player), QLatin1String( "/TrackList" ), QLatin1String( "org.freedesktop.MediaPlayer" ));
|
|
for (int i = 0; i < m_songsInPlaylist; i++) {
|
|
QDBusPendingReply<QVariantMap> data = player.asyncCall(QLatin1String( "GetMetadata" ), i);
|
|
KUrl curl = KUrl(KUrl::fromPercentEncoding(data.value().value(QLatin1String( "location" )).toByteArray()));
|
|
kDebug() << curl << ":" << url;
|
|
if (curl == url) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void AudioPlayerControlRunner::songsInPlaylist(QDBusPendingCallWatcher *call)
|
|
{
|
|
QDBusPendingReply<int> reply = *call;
|
|
m_running = !reply.isError();
|
|
|
|
if (m_running) {
|
|
m_songsInPlaylist = reply.value();
|
|
if (m_currentTrack > -1) {
|
|
// calculate if the next song is available given the new count
|
|
m_nextSongAvailable = m_songsInPlaylist > m_currentTrack;
|
|
}
|
|
} else {
|
|
m_songsInPlaylist = 0;
|
|
}
|
|
|
|
call->deleteLater();
|
|
}
|
|
|
|
void AudioPlayerControlRunner::prevNextSongAvailable(QDBusPendingCallWatcher *call)
|
|
{
|
|
QDBusPendingReply<int> reply = *call;
|
|
m_running = !reply.isError();
|
|
|
|
if (m_running) {
|
|
m_currentTrack = reply.value();
|
|
if (m_songsInPlaylist > 0) {
|
|
m_nextSongAvailable = m_songsInPlaylist > m_currentTrack;
|
|
m_prevSongAvailable = m_currentTrack > 0;
|
|
}
|
|
} else {
|
|
m_currentTrack = 0;
|
|
}
|
|
|
|
call->deleteLater();
|
|
}
|
|
|
|
bool AudioPlayerControlRunner::equals(const QString &text, QRegExp reg)
|
|
{
|
|
reg.setCaseSensitivity(Qt::CaseInsensitive);
|
|
return reg.exactMatch(text);
|
|
}
|
|
|
|
int AudioPlayerControlRunner::getNumber(const QString& term, const char character)
|
|
{
|
|
return term.section(QLatin1Char( character ), 1, 1).toInt();
|
|
}
|
|
|
|
QList<Plasma::QueryMatch> AudioPlayerControlRunner::searchCollectionFor(const QString &term, const QString &actionNames)
|
|
{
|
|
QDBusInterface amarok(QString::fromLatin1( "org.mpris.%1").arg(m_player),
|
|
QLatin1String( "/Collection" ), QLatin1String( "org.kde.amarok.Collection" ));
|
|
|
|
|
|
QString query(QLatin1String( "<query version=\"1.0\"><limit value=\"5\" /><filters>" ));
|
|
QStringList queryItems = term.split(QLatin1Char( ' ' ), QString::SkipEmptyParts);
|
|
foreach(const QString &queryItem, queryItems) {
|
|
query.append(QString::fromLatin1( "<or><include field=\"title\" value=\"%1\" />").arg(queryItem));
|
|
query.append(QString::fromLatin1( "<or><include field=\"artist\" value=\"%1\" />").arg(queryItem));
|
|
query.append(QString::fromLatin1( "<or><include field=\"album\" value=\"%1\" /></or>").arg(queryItem));
|
|
query.append(QLatin1String( "</or></or>"));
|
|
}
|
|
|
|
query.append(QLatin1String( "</filters><includeCollection id=\"localCollection\" /></query>" ));
|
|
|
|
QDBusPendingReply<QList<QVariantMap> > reply = amarok.asyncCall(QLatin1String( "MprisQuery" ), query);
|
|
reply.waitForFinished();
|
|
|
|
if (!reply.isValid()) {
|
|
return QList<Plasma::QueryMatch>();
|
|
}
|
|
|
|
QVariantList data;
|
|
data << QLatin1String( "/TrackList" ) << QLatin1String( "org.freedesktop.MediaPlayer" );
|
|
QList<Plasma::QueryMatch> matches;
|
|
foreach (const QVariantMap &map, reply.value()) {
|
|
QString artist = map[QLatin1String( "artist" )].toString();
|
|
QString title = map[QLatin1String( "title" )].toString();
|
|
QString url = map[QLatin1String( "location" )].toString();
|
|
QUrl arturl = map[QLatin1String( "arturl" )].toUrl();
|
|
double relevance = map[QLatin1String( "rating" )].toInt()*0.2;
|
|
//QString album = map["xesam:album"].toString();
|
|
|
|
data << url << actionNames;
|
|
Plasma::QueryMatch match(this);
|
|
match.setType(Plasma::QueryMatch::PossibleMatch);
|
|
|
|
if (arturl.isValid() && arturl.isLocalFile()) {
|
|
const QImage image = QImage(arturl.toLocalFile());
|
|
QIcon icon(new ImageIconEngine(image));
|
|
match.setIcon(icon);
|
|
} else {
|
|
match.setIcon(KIcon( QLatin1String( "audio-x-generic" )));
|
|
}
|
|
|
|
match.setText(QString::fromLatin1( "%1 - %2").arg(artist).arg(title));
|
|
match.setData(data);
|
|
match.setRelevance(relevance);
|
|
match.setId(QLatin1String( "track_" ) + url);
|
|
matches.append(match);
|
|
data.removeLast();
|
|
data.removeLast();
|
|
}//--- foreach
|
|
|
|
return matches;
|
|
}
|
|
|
|
int AudioPlayerControlRunner::currentSong()
|
|
{
|
|
QDBusPendingReply<int> current = QDBusInterface(QString::fromLatin1( "org.mpris.%1").arg(m_player), QLatin1String( "/TrackList" ), QLatin1String( "org.freedesktop.MediaPlayer" )).asyncCall(QLatin1String( "GetCurrentTrack" ));
|
|
current.waitForFinished();
|
|
return current;
|
|
}
|
|
#include "moc_audioplayercontrolrunner.cpp"
|