From 03082b6a3b6190a14e17459a420a373f2fc1c3b5 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Sat, 4 Dec 2010 09:05:25 +0000 Subject: mpris 2.0 support git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1992 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/General/mpris/mpris.pro | 18 +- src/plugins/General/mpris/mpris1/playerobject.cpp | 199 +++++++++++ src/plugins/General/mpris/mpris1/playerobject.h | 101 ++++++ src/plugins/General/mpris/mpris1/rootobject.cpp | 75 +++++ src/plugins/General/mpris/mpris1/rootobject.h | 54 +++ .../General/mpris/mpris1/tracklistobject.cpp | 144 ++++++++ src/plugins/General/mpris/mpris1/tracklistobject.h | 70 ++++ src/plugins/General/mpris/mpris2/player2object.cpp | 370 +++++++++++++++++++++ src/plugins/General/mpris/mpris2/player2object.h | 115 +++++++ src/plugins/General/mpris/mpris2/root2object.cpp | 88 +++++ src/plugins/General/mpris/mpris2/root2object.h | 58 ++++ src/plugins/General/mpris/playerobject.cpp | 199 ----------- src/plugins/General/mpris/playerobject.h | 101 ------ src/plugins/General/mpris/root2object.cpp | 88 ----- src/plugins/General/mpris/root2object.h | 58 ---- src/plugins/General/mpris/rootobject.cpp | 75 ----- src/plugins/General/mpris/rootobject.h | 54 --- src/plugins/General/mpris/tracklistobject.cpp | 146 -------- src/plugins/General/mpris/tracklistobject.h | 70 ---- src/qmmpui/playlistmodel.cpp | 39 ++- src/qmmpui/playlistmodel.h | 14 +- src/ui/mainwindow.cpp | 4 +- 22 files changed, 1322 insertions(+), 818 deletions(-) create mode 100644 src/plugins/General/mpris/mpris1/playerobject.cpp create mode 100644 src/plugins/General/mpris/mpris1/playerobject.h create mode 100644 src/plugins/General/mpris/mpris1/rootobject.cpp create mode 100644 src/plugins/General/mpris/mpris1/rootobject.h create mode 100644 src/plugins/General/mpris/mpris1/tracklistobject.cpp create mode 100644 src/plugins/General/mpris/mpris1/tracklistobject.h create mode 100644 src/plugins/General/mpris/mpris2/player2object.cpp create mode 100644 src/plugins/General/mpris/mpris2/player2object.h create mode 100644 src/plugins/General/mpris/mpris2/root2object.cpp create mode 100644 src/plugins/General/mpris/mpris2/root2object.h delete mode 100644 src/plugins/General/mpris/playerobject.cpp delete mode 100644 src/plugins/General/mpris/playerobject.h delete mode 100644 src/plugins/General/mpris/root2object.cpp delete mode 100644 src/plugins/General/mpris/root2object.h delete mode 100644 src/plugins/General/mpris/rootobject.cpp delete mode 100644 src/plugins/General/mpris/rootobject.h delete mode 100644 src/plugins/General/mpris/tracklistobject.cpp delete mode 100644 src/plugins/General/mpris/tracklistobject.h diff --git a/src/plugins/General/mpris/mpris.pro b/src/plugins/General/mpris/mpris.pro index e97282e03..a60b36c06 100644 --- a/src/plugins/General/mpris/mpris.pro +++ b/src/plugins/General/mpris/mpris.pro @@ -39,17 +39,19 @@ INSTALLS += target HEADERS += mprisfactory.h \ mpris.h \ - playerobject.h \ - rootobject.h \ - tracklistobject.h \ - root2object.h + mpris1/playerobject.h \ + mpris1/rootobject.h \ + mpris1/tracklistobject.h \ + mpris2/root2object.h \ + mpris2/player2object.h SOURCES += mprisfactory.cpp \ mpris.cpp \ - playerobject.cpp \ - rootobject.cpp \ - tracklistobject.cpp \ - root2object.cpp + mpris1/playerobject.cpp \ + mpris1/rootobject.cpp \ + mpris1/tracklistobject.cpp \ + mpris2/root2object.cpp \ + mpris2/player2object.cpp INCLUDEPATH += ../../../../src diff --git a/src/plugins/General/mpris/mpris1/playerobject.cpp b/src/plugins/General/mpris/mpris1/playerobject.cpp new file mode 100644 index 000000000..e5d4af632 --- /dev/null +++ b/src/plugins/General/mpris/mpris1/playerobject.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright (C) 2008-2009 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "playerobject.h" + + +//register << operator +QDBusArgument &operator << (QDBusArgument &arg, const PlayerStatus &status) +{ + arg.beginStructure(); + arg << status.state; + arg << status.random; + arg << status.repeat; + arg << status.repeatPlayList; + arg.endStructure(); + return arg; +} + +//register >> operator +const QDBusArgument &operator >> (const QDBusArgument &arg, PlayerStatus &status) +{ + arg.beginStructure(); + arg >> status.state; + arg >> status.random; + arg >> status.repeat; + arg >> status.repeatPlayList; + arg.endStructure(); + return arg; +} + +PlayerObject::PlayerObject(QObject *parent) : QObject(parent) +{ + qDBusRegisterMetaType(); + m_core = SoundCore::instance(); + m_player = MediaPlayer::instance(); + m_pl_manager = m_player->playListManager(); + connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(updateCaps())); + connect(m_core, SIGNAL(metaDataChanged ()), SLOT(updateTrack())); + connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(updateStatus())); + connect(m_pl_manager, SIGNAL(repeatableListChanged(bool)), SLOT(updateStatus())); + connect(m_pl_manager, SIGNAL(shuffleChanged(bool)), SLOT(updateStatus())); + connect(m_player, SIGNAL(repeatableChanged(bool)), SLOT(updateStatus())); +} + +PlayerObject::~PlayerObject() +{} + +void PlayerObject::Next() +{ + m_player->next(); +} + +void PlayerObject::Prev() +{ + m_player->previous(); +} + +void PlayerObject::Pause() +{ + m_core->pause(); +} + +void PlayerObject::Stop() +{ + m_player->stop(); +} + +void PlayerObject::Play() +{ + m_player->play(); +} + +void PlayerObject::Repeat(bool in0) +{ + m_player->setRepeatable(in0); +} + +PlayerStatus PlayerObject::GetStatus() +{ + PlayerStatus st; + switch (m_core->state()) + { + case Qmmp::Stopped: + case Qmmp::NormalError: + case Qmmp::FatalError: + st.state = 2; + break; + case Qmmp::Playing: + case Qmmp::Buffering: + st.state = 0; + break; + case Qmmp::Paused: + st.state = 1; + }; + st.random = int(m_pl_manager->isShuffle()); + st.repeat = int(m_player->isRepeatable()); + st.repeatPlayList = int(m_pl_manager->isRepeatableList()); + return st; +} + +QVariantMap PlayerObject::GetMetadata() +{ + QVariantMap map; + + if (m_core->metaData(Qmmp::URL).contains("://")) + map.insert("location", m_core->metaData(Qmmp::URL)); + else + map.insert("location", "file://" + m_core->metaData(Qmmp::URL)); + map.insert("arturl", MetaDataManager::instance()->getCoverPath(m_core->metaData(Qmmp::URL))); + map.insert("title", m_core->metaData(Qmmp::TITLE)); + map.insert("artist", m_core->metaData(Qmmp::ARTIST)); + map.insert("album", m_core->metaData(Qmmp::ALBUM)); + map.insert("tracknumber", m_core->metaData(Qmmp::TRACK)); + map.insert("time", (quint32)m_core->totalTime()/1000); + map.insert("mtime", (quint32)m_core->totalTime()); + map.insert("genre", m_core->metaData(Qmmp::GENRE)); + map.insert("comment", m_core->metaData(Qmmp::COMMENT)); + map.insert("audio-bitrate", (quint32)m_core->bitrate()); + map.insert("audio-samplerate", (quint32)m_core->frequency()); + map.insert("year", m_core->metaData(Qmmp::YEAR).toUInt()); + return map; +} + +int PlayerObject::GetCaps() +{ + int caps = NONE; + if (GetStatus().state == 0) + caps |= CAN_PAUSE; + else + caps |= CAN_PLAY; + if ((GetStatus().state < 2) && (m_core->totalTime() > 0)) + caps |= CAN_SEEK; + caps |= CAN_GO_NEXT; + caps |= CAN_GO_PREV; + caps |= CAN_PROVIDE_METADATA; + return caps; +} + +void PlayerObject::VolumeSet(int volume) +{ + int balance = (VolumeGet() > 0) ? (m_core->rightVolume() - m_core->leftVolume()) * 100/VolumeGet() : 0; + m_core->setVolume(volume - qMax(balance,0)*volume/100, + volume + qMin(balance,0)*volume/100); +} + +int PlayerObject::VolumeGet() +{ + return qMax(m_core->leftVolume(), m_core->rightVolume()); +} + +void PlayerObject::PositionSet(int pos) +{ + m_core->seek(pos); +} + +int PlayerObject::PositionGet() +{ + return m_core->elapsed(); +} + +void PlayerObject::updateCaps() +{ + emit CapsChange(GetCaps()); +} + +void PlayerObject::updateTrack() +{ + emit TrackChange(GetMetadata()); +} + +void PlayerObject::updateStatus() +{ + emit StatusChange(GetStatus()); +} diff --git a/src/plugins/General/mpris/mpris1/playerobject.h b/src/plugins/General/mpris/mpris1/playerobject.h new file mode 100644 index 000000000..709357387 --- /dev/null +++ b/src/plugins/General/mpris/mpris1/playerobject.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (C) 2008-2009 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PLAYEROBJECT_H +#define PLAYEROBJECT_H + +#include +#include + +class SoundCore; +class MediaPlayer; +class PlayListManager; + +/** + @author Ilya Kotov +*/ + +struct PlayerStatus +{ + int state; // 0 = Playing, 1 = Paused, 2 = Stopped. + int random; // 0 = Playing linearly, 1 = Playing randomly. + int repeat; // 0 = Go to the next element once the current has finished playing, 1 = Repeat the current element + int repeatPlayList; // 0 = Stop playing once the last element has been played, 1 = Never give up playing +}; + +Q_DECLARE_METATYPE(PlayerStatus); + +class PlayerObject : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") + +public: + PlayerObject(QObject *parent = 0); + + ~PlayerObject(); + + + enum PlayerCaps + { + + NONE = 0, + CAN_GO_NEXT = 1 << 0, + CAN_GO_PREV = 1 << 1, + CAN_PAUSE = 1 << 2, + CAN_PLAY = 1 << 3, + CAN_SEEK = 1 << 4, + CAN_PROVIDE_METADATA = 1 << 5, + CAN_HAS_TRACKLIST = 1 << 6 + }; + + +public slots: + void Next(); + void Prev(); + void Pause(); + void Stop(); + void Play(); + void Repeat(bool in0); + PlayerStatus GetStatus(); + QVariantMap GetMetadata(); + int GetCaps(); + void VolumeSet(int in0); + int VolumeGet(); + void PositionSet(int in0); + int PositionGet(); + +signals: + void CapsChange(int); + void TrackChange(QVariantMap); + void StatusChange(PlayerStatus); + +private slots: + void updateCaps(); + void updateTrack(); + void updateStatus(); + +private: + SoundCore *m_core; + MediaPlayer *m_player; + PlayListManager *m_pl_manager; + +}; + +#endif diff --git a/src/plugins/General/mpris/mpris1/rootobject.cpp b/src/plugins/General/mpris/mpris1/rootobject.cpp new file mode 100644 index 000000000..7c4267d08 --- /dev/null +++ b/src/plugins/General/mpris/mpris1/rootobject.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include +#include "rootobject.h" + +//register << operator +QDBusArgument &operator << (QDBusArgument &arg, const Version &v) +{ + arg.beginStructure(); + arg << v.major; + arg << v.minor; + arg.endStructure(); + return arg; +} + +//register >> operator +const QDBusArgument &operator >> (const QDBusArgument &arg, Version &v) +{ + arg.beginStructure(); + arg >> v.major; + arg >> v.minor; + arg.endStructure(); + return arg; +} + +RootObject::RootObject(QObject *parent) + : QObject(parent) +{ + qDBusRegisterMetaType(); +} + + +RootObject::~RootObject() +{ +} + +QString RootObject::Identity() +{ + QString name = "Qmmp " + Qmmp::strVersion(); + return name; +} + +Version RootObject::MprisVersion() +{ + struct Version v; + v.major = 1; + v.minor = 0; + return v; +} + +void RootObject::Quit() +{ + QMetaObject::invokeMethod(parent(), "exit"); +} diff --git a/src/plugins/General/mpris/mpris1/rootobject.h b/src/plugins/General/mpris/mpris1/rootobject.h new file mode 100644 index 000000000..378d9f51a --- /dev/null +++ b/src/plugins/General/mpris/mpris1/rootobject.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef ROOTOBJECT_H +#define ROOTOBJECT_H + +#include +#include + +/** + @author Ilya Kotov +*/ + + +struct Version +{ + quint16 major; + quint16 minor; +}; + +Q_DECLARE_METATYPE(Version); + +class RootObject : public QObject +{ +Q_OBJECT +Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") +public: + RootObject(QObject *parent = 0); + + ~RootObject(); + +public slots: + QString Identity(); + Version MprisVersion(); + void Quit(); +}; + +#endif diff --git a/src/plugins/General/mpris/mpris1/tracklistobject.cpp b/src/plugins/General/mpris/mpris1/tracklistobject.cpp new file mode 100644 index 000000000..63e4dfe89 --- /dev/null +++ b/src/plugins/General/mpris/mpris1/tracklistobject.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "tracklistobject.h" + +TrackListObject::TrackListObject(QObject *parent) : QObject(parent) +{ + m_player = MediaPlayer::instance(); + m_pl_manager = m_player->playListManager(); + m_model = m_pl_manager->currentPlayList(); + connect (m_model, SIGNAL(listChanged()), SLOT(updateTrackList())); + connect (m_pl_manager, SIGNAL(currentPlayListChanged(PlayListModel*,PlayListModel*)), + SLOT(switchPlayList(PlayListModel*,PlayListModel*))); + m_prev_count = 0; +} + + +TrackListObject::~TrackListObject() +{ +} + +int TrackListObject::AddTrack(const QString &in0, bool in1) +{ + QString path = in0; + if(in0.startsWith("file://")) + { + path = QUrl(in0).toLocalFile (); + if(!QFile::exists(path)) + return 1; //error + } + if(in1) + { + m_pl_manager->selectPlayList(m_model); + m_player->stop(); + m_prev_count = m_model->count(); + connect(m_model, SIGNAL(listChanged()), this, SLOT(checkNewItem())); + connect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); + } + m_model->add(path); + return 0; +} + +void TrackListObject::DelTrack(int in0) +{ + m_model->removeAt(in0); +} + +int TrackListObject::GetCurrentTrack() +{ + return m_model->currentRow(); +} + +int TrackListObject::GetLength() +{ + return m_model->count(); +} + +QVariantMap TrackListObject::GetMetadata(int in0) +{ + QVariantMap map; + PlayListItem *item = m_model->item(in0); + if (item) + { + if (QFile::exists(item->url())) + map.insert("location", "file://" + item->url()); + else + map.insert("location", item->url()); + map.insert("title", item->value(Qmmp::TITLE)); + map.insert("artist", item->value(Qmmp::ARTIST)); + map.insert("album", item->value(Qmmp::ALBUM)); + map.insert("tracknumber", item->value(Qmmp::TRACK)); + map.insert("time", (quint32)item->length()); + map.insert("mtime", (quint32)item->length() * 1000); + map.insert("genre", item->value(Qmmp::GENRE)); + map.insert("comment", item->value(Qmmp::COMMENT)); + map.insert("year", item->value(Qmmp::YEAR).toUInt()); + } + return map; +} + +void TrackListObject::SetLoop(bool in0) +{ + m_pl_manager->setRepeatableList(in0); +} + +void TrackListObject::SetRandom(bool in0) +{ + m_pl_manager->setShuffle(in0); +} + +void TrackListObject::disconnectPl() +{ + disconnect(m_model, SIGNAL(listChanged()), this, SLOT(checkNewItem())); + disconnect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); +} + +void TrackListObject::checkNewItem() //checks for new item in playlist +{ + if(m_model->count() > m_prev_count) + { + disconnectPl(); //disconnect playlist; + m_model->setCurrent(m_prev_count); // activate first added item + m_player->play(); // ... and play it + } +} + +void TrackListObject::updateTrackList() +{ + emit TrackListChange(m_model->count()); +} + +void TrackListObject::switchPlayList(PlayListModel *cur, PlayListModel *prev) +{ + disconnectPl(); + m_model = cur; + connect (m_model, SIGNAL(listChanged()), SLOT(updateTrackList())); + if(prev) + disconnect(prev,0,this,0); + updateTrackList(); +} diff --git a/src/plugins/General/mpris/mpris1/tracklistobject.h b/src/plugins/General/mpris/mpris1/tracklistobject.h new file mode 100644 index 000000000..eec9eda3c --- /dev/null +++ b/src/plugins/General/mpris/mpris1/tracklistobject.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2008-2009 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef TRACKLISTOBJECT_H +#define TRACKLISTOBJECT_H + +#include +#include +#include + +class PlayListModel; +class PlayListManager; +class MediaPlayer; + +/** + @author Ilya Kotov +*/ +class TrackListObject : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") + +public: + TrackListObject(QObject *parent = 0); + + ~TrackListObject(); + +public slots: + int AddTrack(const QString &in0, bool in1); + void DelTrack(int in0); + int GetCurrentTrack(); + int GetLength(); + QVariantMap GetMetadata(int in0); + void SetLoop(bool in0); + void SetRandom(bool in0); + +signals: + void TrackListChange(int in0); + +private slots: + void disconnectPl(); + void checkNewItem(); + void updateTrackList(); + void switchPlayList(PlayListModel *cur, PlayListModel *prev); + +private: + PlayListModel *m_model; + PlayListManager *m_pl_manager; + MediaPlayer *m_player; + int m_prev_count; + +}; + +#endif diff --git a/src/plugins/General/mpris/mpris2/player2object.cpp b/src/plugins/General/mpris/mpris2/player2object.cpp new file mode 100644 index 000000000..161153c68 --- /dev/null +++ b/src/plugins/General/mpris/mpris2/player2object.cpp @@ -0,0 +1,370 @@ +/*************************************************************************** + * Copyright (C) 2010 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "player2object.h" + +Player2Object::Player2Object(QObject *parent) : QObject(parent) +{ + m_prev_item = 0; + m_previous_pos = 0; + m_core = SoundCore::instance(); + m_player = MediaPlayer::instance(); + m_pl_manager = m_player->playListManager(); + connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(emitPropertiesChanged())); + connect(m_core, SIGNAL(metaDataChanged ()), SLOT(updateId())); + connect(m_core, SIGNAL(metaDataChanged ()), SLOT(emitPropertiesChanged())); + connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(emitPropertiesChanged())); + connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(checkState(Qmmp::State))); + connect(m_core, SIGNAL(volumeChanged(int,int)), SLOT(emitPropertiesChanged())); + connect(m_core, SIGNAL(elapsedChanged(qint64)), SLOT(checkSeeking(qint64))); + connect(m_pl_manager, SIGNAL(repeatableListChanged(bool)), SLOT(emitPropertiesChanged())); + connect(m_pl_manager, SIGNAL(shuffleChanged(bool)), SLOT(emitPropertiesChanged())); + connect(m_player, SIGNAL(repeatableChanged(bool)), SLOT(emitPropertiesChanged())); + syncProperties(); +} + +Player2Object::~Player2Object() +{} + +bool Player2Object::canControl() const +{ + return true; +} + +bool Player2Object::canGoNext() const +{ + return m_pl_manager->currentPlayList()->nextItem() != 0; +} + +bool Player2Object::canGoPrevious() const +{ + return m_pl_manager->currentPlayList()->currentRow() > 0; +} + +bool Player2Object::canPause() const +{ + return (m_core->state() == Qmmp::Paused || m_core->state() == Qmmp::Playing); +} +bool Player2Object::canPlay() const +{ + return m_pl_manager->currentPlayList()->count() != 0; +} + +bool Player2Object::canSeek() const +{ + return m_core->totalTime() > 0; +} + +QString Player2Object::loopStatus() const +{ + if(m_player->isRepeatable()) + return "Track"; + else if(m_pl_manager->isRepeatableList()) + return "Playlist"; + else + return "None"; +} + +void Player2Object::setLoopStatus(const QString &value) +{ + if(value == "Track") + { + m_player->setRepeatable(true); + } + else if(value == "Playlist") + { + m_pl_manager->setRepeatableList(true); + m_player->setRepeatable(false); + } + else + { + m_pl_manager->setRepeatableList(false); + m_player->setRepeatable(false); + } +} + +double Player2Object::maximumRate() const +{ + return 1.0; +} + +QVariantMap Player2Object::metadata() const +{ + PlayListItem *item = m_pl_manager->currentPlayList()->currentItem(); + if(!item || m_core->metaData(Qmmp::URL).isEmpty()) + return QVariantMap(); + QVariantMap map; + map["mpris:length"] = m_core->totalTime() * 1000; + if(!MetaDataManager::instance()->getCoverPath(m_core->metaData(Qmmp::URL)).isEmpty()) + map["mpris:artUrl"] = MetaDataManager::instance()->getCoverPath(m_core->metaData(Qmmp::URL)); + if(!m_core->metaData(Qmmp::ALBUM).isEmpty()) + map["xesam:album"] = m_core->metaData(Qmmp::ALBUM); + if(!m_core->metaData(Qmmp::ARTIST).isEmpty()) + map["xesam:artist"] = QStringList() << m_core->metaData(Qmmp::ARTIST); + if(!m_core->metaData(Qmmp::COMMENT).isEmpty()) + map["xseam:comment"] = QStringList() << m_core->metaData(Qmmp::COMMENT); + if(!m_core->metaData(Qmmp::COMPOSER).isEmpty()) + map["xesam:composer"] = QStringList() << m_core->metaData(Qmmp::COMPOSER); + if(!m_core->metaData(Qmmp::DISCNUMBER).isEmpty()) + map["xesam:discNumber"] = m_core->metaData(Qmmp::DISCNUMBER).toInt(); + if(!m_core->metaData(Qmmp::GENRE).isEmpty()) + map["xesam:genre"] = QStringList() << m_core->metaData(Qmmp::GENRE); + if(!m_core->metaData(Qmmp::TITLE).isEmpty()) + map["xesam:title"] = QStringList() << m_core->metaData(Qmmp::TITLE); + if(!m_core->metaData(Qmmp::TRACK).isEmpty()) + map["xesam:trackNumber"] = m_core->metaData(Qmmp::TRACK); + map["mpris:trackid"] = m_trackID; + map["xesam:url"] = m_core->metaData(Qmmp::URL); + return map; +} + +double Player2Object::minimumRate() const +{ + return 1.0; +} + +QString Player2Object::playbackStatus() const +{ + if(m_core->state() == Qmmp::Playing) + return "Playing"; + else if (m_core->state() == Qmmp::Paused) + return "Paused"; + return "Stopped"; +} + +qlonglong Player2Object::position() const +{ + return m_core->elapsed() * 1000; +} + +double Player2Object::rate() const +{ + return 1.0; +} + +void Player2Object::setRate(double value) +{ + Q_UNUSED(value) +} + +bool Player2Object::shuffle() const +{ + return m_pl_manager->isShuffle(); +} + +void Player2Object::setShuffle(bool value) +{ + m_pl_manager->setShuffle(value); +} + +double Player2Object::volume() const +{ + return qMax(m_core->leftVolume(), m_core->rightVolume())/100.0; +} + +void Player2Object::Player2Object::setVolume(double value) +{ + value = qBound(0.0, value ,1.0); + int balance = (volume() > 0) ? (m_core->rightVolume() - m_core->leftVolume())/volume() : 0; + m_core->setVolume(value*100 - qMax(balance,0)*value, + value*100 + qMin(balance,0)*value); +} + +void Player2Object::Next() +{ + m_player->next(); +} + +void Player2Object::OpenUri(const QString &in0) +{ + QString path = in0; + if(in0.startsWith("file://")) + { + path = QUrl(in0).toLocalFile (); + if(!QFile::exists(path)) + return; //error + } + if(!m_pl_manager->currentPlayList()->isLoaderRunning()) + { + m_pl_manager->selectPlayList(m_pl_manager->currentPlayList()); + connect(m_pl_manager->currentPlayList(), SIGNAL(itemAdded(PlayListItem*)), + SLOT(playItem(PlayListItem*))); + connect(m_pl_manager->currentPlayList(), SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); + } + m_pl_manager->currentPlayList()->add(path); +} + +void Player2Object::Pause() +{ + m_core->pause(); +} + +void Player2Object::Play() +{ + m_player->play(); +} + +void Player2Object::PlayPause() +{ + if(m_core->state() == Qmmp::Stopped) + m_player->play(); + else if(m_core->state() == Qmmp::Paused || m_core->state() == Qmmp::Playing) + m_core->pause(); +} + +void Player2Object::Previous() +{ + m_player->previous(); +} + +void Player2Object::Seek(qlonglong Offset) +{ + m_core->seek(qMin((qint64)0, m_core->elapsed() + Offset/1000)); +} +void Player2Object::SetPosition(const QDBusObjectPath &TrackId, qlonglong Position) +{ + if(m_trackID == TrackId.path()) + m_core->seek(Position/1000); + else + qWarning("Player2Object: SetPosition() called with a invalid trackId"); +} + +void Player2Object::Stop() +{ + m_core->stop(); +} + +void Player2Object::emitPropertiesChanged() +{ + QList changedProps; + if(m_props["canGoNext"] != canGoNext()) + changedProps << "canGoNext"; + if(m_props["canGoPrevious"] != canGoPrevious()) + changedProps << "canGoPrevious"; + if(m_props["canPause"] != canPause()) + changedProps << "canPause"; + if(m_props["canPlay"] != canPlay()) + changedProps << "canPlay"; + if(m_props["canSeek"] != canSeek()) + changedProps << "canSeek"; + if(m_props["loopStatus"] != loopStatus()) + changedProps << "loopStatus"; + if(m_props["maximumRate"] != maximumRate()) + changedProps << "maximumRate"; + if(m_props["minimumRate"] != minimumRate()) + changedProps << "minimumRate"; + if(m_props["playbackStatus"] != playbackStatus()) + changedProps << "playbackStatus"; + if(m_props["position"] != position()) + changedProps << "position"; + if(m_props["rate"] != rate()) + changedProps << "rate"; + if(m_props["shuffle"] != shuffle()) + changedProps << "shuffle"; + if(m_props["volume"] != volume()) + changedProps << "volume"; + if(m_props["metadata"] != metadata()) + changedProps << "metadata"; + + syncProperties(); + + if(changedProps.isEmpty()) + return; + + QVariantMap map; + foreach(QByteArray name, changedProps) + map.insert(name, m_props.value(name)); + + QDBusMessage msg = QDBusMessage::createSignal("/org/mpris/MediaPlayer2", + "org.freedesktop.DBus.Properties", "PropertiesChanged"); + QVariantList args = QVariantList() + << "org.mpris.MediaPlayer2.Player" + << map + << QStringList(); + msg.setArguments(args); + QDBusConnection::sessionBus().send(msg); +} + +void Player2Object::updateId() +{ + if(m_prev_item != m_pl_manager->currentPlayList()->currentItem()) + { + m_trackID = QString("%1/Track/%2").arg("/org/mpris/MediaPlayer2").arg(qrand()); + m_prev_item = m_pl_manager->currentPlayList()->currentItem(); + } +} + +void Player2Object::checkState(Qmmp::State state) +{ + if(state == Qmmp::Playing) + m_previous_pos = 0; +} + +void Player2Object::checkSeeking(qint64 elapsed) +{ + if(abs(elapsed - m_previous_pos) > 2000) + { + emit Seeked(elapsed * 1000); + } + m_previous_pos = elapsed; +} + +void Player2Object::playItem(PlayListItem *item) +{ + m_pl_manager->selectPlayList((PlayListModel*)sender()); + m_pl_manager->activatePlayList((PlayListModel*)sender()); + disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListItem*))), this, SLOT(playItem(PlayListItem*))); + if(!m_pl_manager->currentPlayList()->setCurrent(item)) + return; + m_core->stop(); + m_player->play(); +} + +void Player2Object::disconnectPl() +{ + disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListItem*))), this, SLOT(playItem(PlayListItem*))); +} + +void Player2Object::syncProperties() +{ + m_props["canGoNext"] = canGoNext(); + m_props["canGoPrevious"] = canGoPrevious(); + m_props["canPause"] = canPause(); + m_props["canPlay"] = canPlay(); + m_props["canSeek"] = canSeek(); + m_props["loopStatus"] = loopStatus(); + m_props["maximumRate"] = maximumRate(); + m_props["minimumRate"] = minimumRate(); + m_props["playbackStatus"] = playbackStatus(); + m_props["position"] = position(); + m_props["rate"] = rate(); + m_props["shuffle"] = shuffle(); + m_props["volume"] = volume(); + m_props["metadata"] = metadata(); +} diff --git a/src/plugins/General/mpris/mpris2/player2object.h b/src/plugins/General/mpris/mpris2/player2object.h new file mode 100644 index 000000000..a3addf2f2 --- /dev/null +++ b/src/plugins/General/mpris/mpris2/player2object.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2010 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PLAYER2OBJECT_H +#define PLAYER2OBJECT_H + +#include +#include +#include +#include +#include +#include + +class SoundCore; +class MediaPlayer; +class PlayListManager; +class PlayListItem; + +/** + @author Ilya Kotov +*/ +class Player2Object : public QObject +{ +Q_OBJECT +Q_CLASSINFO("D-Bus Interface", "org.mpris.MediaPlayer2.Player") +Q_PROPERTY(bool CanControl READ canControl) +Q_PROPERTY(bool CanGoNext READ canGoNext) +Q_PROPERTY(bool CanGoPrevious READ canGoPrevious) +Q_PROPERTY(bool CanPause READ canPause) +Q_PROPERTY(bool CanPlay READ canPlay) +Q_PROPERTY(bool CanSeek READ canSeek) +Q_PROPERTY(QString LoopStatus READ loopStatus WRITE setLoopStatus) +Q_PROPERTY(double MaximumRate READ maximumRate) +Q_PROPERTY(QVariantMap Metadata READ metadata) +Q_PROPERTY(double MinimumRate READ minimumRate) +Q_PROPERTY(QString PlaybackStatus READ playbackStatus) +Q_PROPERTY(qlonglong Position READ position) +Q_PROPERTY(double Rate READ rate WRITE setRate) +Q_PROPERTY(bool Shuffle READ shuffle WRITE setShuffle) +Q_PROPERTY(double Volume READ volume WRITE setVolume) + +public: + Player2Object(QObject *parent = 0); + virtual ~Player2Object(); + bool canControl() const; + bool canGoNext() const; + bool canGoPrevious() const; + bool canPause() const; + bool canPlay() const; + bool canSeek() const; + QString loopStatus() const; + void setLoopStatus(const QString &value); + double maximumRate() const; + QVariantMap metadata() const; + double minimumRate() const; + QString playbackStatus() const; + qlonglong position() const; + double rate() const; + void setRate(double value); + bool shuffle() const; + void setShuffle(bool value); + double volume() const; + void setVolume(double value); + +public slots: + void Next(); + void OpenUri(const QString &in0); + void Pause(); + void Play(); + void PlayPause(); + void Previous(); + void Seek(qlonglong Offset); + void SetPosition(const QDBusObjectPath &TrackId, qlonglong Position); + void Stop(); +signals: + void Seeked(qlonglong Position); + +private slots: + void emitPropertiesChanged(); + void updateId(); + void checkState(Qmmp::State state); + void checkSeeking(qint64 elapsed); + void playItem(PlayListItem *item); + void disconnectPl(); + + +private: + void syncProperties(); + SoundCore *m_core; + MediaPlayer *m_player; + PlayListManager *m_pl_manager; + QMap m_props; + QString m_trackID; + PlayListItem *m_prev_item; + qint64 m_previous_pos; + +}; + +#endif diff --git a/src/plugins/General/mpris/mpris2/root2object.cpp b/src/plugins/General/mpris/mpris2/root2object.cpp new file mode 100644 index 000000000..c0eca65fb --- /dev/null +++ b/src/plugins/General/mpris/mpris2/root2object.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2010 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "root2object.h" + +Root2Object::Root2Object(QObject *parent) : QObject(parent) +{} + + +Root2Object::~Root2Object() +{} + +bool Root2Object::canQuit() const +{ + return true; +} + +bool Root2Object::canRaise() const +{ + return false; +} + +QString Root2Object::desktopEntry() const +{ + return "qmmp"; +} + +bool Root2Object::hasTrackList() const +{ + return false; +} +QString Root2Object::identity() const +{ + QString name = "Qmmp " + Qmmp::strVersion(); + return name; +} + +QStringList Root2Object::supportedMimeTypes() const +{ + QStringList mimeTypes; + foreach(DecoderFactory *factory, *Decoder::factories()) + mimeTypes << factory->properties().contentTypes; + foreach(EngineFactory *factory, *AbstractEngine::factories()) + mimeTypes << factory->properties().contentTypes; + mimeTypes.removeDuplicates(); + return mimeTypes; +} + +QStringList Root2Object::supportedUriSchemes() const +{ + QStringList protocols = MetaDataManager::instance()->protocols(); + if(!protocols.contains("file")) //append file if needed + protocols.append("file"); + return protocols; +} + +void Root2Object::Quit() +{ + QMetaObject::invokeMethod(parent(), "exit"); +} + +void Root2Object::Raise(){} diff --git a/src/plugins/General/mpris/mpris2/root2object.h b/src/plugins/General/mpris/mpris2/root2object.h new file mode 100644 index 000000000..f661df200 --- /dev/null +++ b/src/plugins/General/mpris/mpris2/root2object.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2010 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef ROOT2OBJECT_H +#define ROOT2OBJECT_H + +#include +#include + +/** + @author Ilya Kotov +*/ +class Root2Object : public QObject +{ +Q_OBJECT +Q_CLASSINFO("D-Bus Interface", "org.mpris.MediaPlayer2") +Q_PROPERTY(bool CanQuit READ canQuit) +Q_PROPERTY(bool CanRaise READ canRaise) +Q_PROPERTY(QString DesktopEntry READ desktopEntry) +Q_PROPERTY(bool HasTrackList READ hasTrackList) +Q_PROPERTY(QString Identity READ identity) +Q_PROPERTY(QStringList SupportedMimeTypes READ supportedMimeTypes) +Q_PROPERTY(QStringList SupportedUriSchemes READ supportedUriSchemes) + +public: + Root2Object(QObject *parent = 0); + virtual ~Root2Object(); + + bool canQuit() const; + bool canRaise() const; + QString desktopEntry() const; + bool hasTrackList() const; + QString identity() const; + QStringList supportedMimeTypes() const; + QStringList supportedUriSchemes() const; + +public slots: + void Quit(); + void Raise(); +}; + +#endif diff --git a/src/plugins/General/mpris/playerobject.cpp b/src/plugins/General/mpris/playerobject.cpp deleted file mode 100644 index e5d4af632..000000000 --- a/src/plugins/General/mpris/playerobject.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008-2009 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include "playerobject.h" - - -//register << operator -QDBusArgument &operator << (QDBusArgument &arg, const PlayerStatus &status) -{ - arg.beginStructure(); - arg << status.state; - arg << status.random; - arg << status.repeat; - arg << status.repeatPlayList; - arg.endStructure(); - return arg; -} - -//register >> operator -const QDBusArgument &operator >> (const QDBusArgument &arg, PlayerStatus &status) -{ - arg.beginStructure(); - arg >> status.state; - arg >> status.random; - arg >> status.repeat; - arg >> status.repeatPlayList; - arg.endStructure(); - return arg; -} - -PlayerObject::PlayerObject(QObject *parent) : QObject(parent) -{ - qDBusRegisterMetaType(); - m_core = SoundCore::instance(); - m_player = MediaPlayer::instance(); - m_pl_manager = m_player->playListManager(); - connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(updateCaps())); - connect(m_core, SIGNAL(metaDataChanged ()), SLOT(updateTrack())); - connect(m_core, SIGNAL(stateChanged (Qmmp::State)), SLOT(updateStatus())); - connect(m_pl_manager, SIGNAL(repeatableListChanged(bool)), SLOT(updateStatus())); - connect(m_pl_manager, SIGNAL(shuffleChanged(bool)), SLOT(updateStatus())); - connect(m_player, SIGNAL(repeatableChanged(bool)), SLOT(updateStatus())); -} - -PlayerObject::~PlayerObject() -{} - -void PlayerObject::Next() -{ - m_player->next(); -} - -void PlayerObject::Prev() -{ - m_player->previous(); -} - -void PlayerObject::Pause() -{ - m_core->pause(); -} - -void PlayerObject::Stop() -{ - m_player->stop(); -} - -void PlayerObject::Play() -{ - m_player->play(); -} - -void PlayerObject::Repeat(bool in0) -{ - m_player->setRepeatable(in0); -} - -PlayerStatus PlayerObject::GetStatus() -{ - PlayerStatus st; - switch (m_core->state()) - { - case Qmmp::Stopped: - case Qmmp::NormalError: - case Qmmp::FatalError: - st.state = 2; - break; - case Qmmp::Playing: - case Qmmp::Buffering: - st.state = 0; - break; - case Qmmp::Paused: - st.state = 1; - }; - st.random = int(m_pl_manager->isShuffle()); - st.repeat = int(m_player->isRepeatable()); - st.repeatPlayList = int(m_pl_manager->isRepeatableList()); - return st; -} - -QVariantMap PlayerObject::GetMetadata() -{ - QVariantMap map; - - if (m_core->metaData(Qmmp::URL).contains("://")) - map.insert("location", m_core->metaData(Qmmp::URL)); - else - map.insert("location", "file://" + m_core->metaData(Qmmp::URL)); - map.insert("arturl", MetaDataManager::instance()->getCoverPath(m_core->metaData(Qmmp::URL))); - map.insert("title", m_core->metaData(Qmmp::TITLE)); - map.insert("artist", m_core->metaData(Qmmp::ARTIST)); - map.insert("album", m_core->metaData(Qmmp::ALBUM)); - map.insert("tracknumber", m_core->metaData(Qmmp::TRACK)); - map.insert("time", (quint32)m_core->totalTime()/1000); - map.insert("mtime", (quint32)m_core->totalTime()); - map.insert("genre", m_core->metaData(Qmmp::GENRE)); - map.insert("comment", m_core->metaData(Qmmp::COMMENT)); - map.insert("audio-bitrate", (quint32)m_core->bitrate()); - map.insert("audio-samplerate", (quint32)m_core->frequency()); - map.insert("year", m_core->metaData(Qmmp::YEAR).toUInt()); - return map; -} - -int PlayerObject::GetCaps() -{ - int caps = NONE; - if (GetStatus().state == 0) - caps |= CAN_PAUSE; - else - caps |= CAN_PLAY; - if ((GetStatus().state < 2) && (m_core->totalTime() > 0)) - caps |= CAN_SEEK; - caps |= CAN_GO_NEXT; - caps |= CAN_GO_PREV; - caps |= CAN_PROVIDE_METADATA; - return caps; -} - -void PlayerObject::VolumeSet(int volume) -{ - int balance = (VolumeGet() > 0) ? (m_core->rightVolume() - m_core->leftVolume()) * 100/VolumeGet() : 0; - m_core->setVolume(volume - qMax(balance,0)*volume/100, - volume + qMin(balance,0)*volume/100); -} - -int PlayerObject::VolumeGet() -{ - return qMax(m_core->leftVolume(), m_core->rightVolume()); -} - -void PlayerObject::PositionSet(int pos) -{ - m_core->seek(pos); -} - -int PlayerObject::PositionGet() -{ - return m_core->elapsed(); -} - -void PlayerObject::updateCaps() -{ - emit CapsChange(GetCaps()); -} - -void PlayerObject::updateTrack() -{ - emit TrackChange(GetMetadata()); -} - -void PlayerObject::updateStatus() -{ - emit StatusChange(GetStatus()); -} diff --git a/src/plugins/General/mpris/playerobject.h b/src/plugins/General/mpris/playerobject.h deleted file mode 100644 index 709357387..000000000 --- a/src/plugins/General/mpris/playerobject.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008-2009 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef PLAYEROBJECT_H -#define PLAYEROBJECT_H - -#include -#include - -class SoundCore; -class MediaPlayer; -class PlayListManager; - -/** - @author Ilya Kotov -*/ - -struct PlayerStatus -{ - int state; // 0 = Playing, 1 = Paused, 2 = Stopped. - int random; // 0 = Playing linearly, 1 = Playing randomly. - int repeat; // 0 = Go to the next element once the current has finished playing, 1 = Repeat the current element - int repeatPlayList; // 0 = Stop playing once the last element has been played, 1 = Never give up playing -}; - -Q_DECLARE_METATYPE(PlayerStatus); - -class PlayerObject : public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") - -public: - PlayerObject(QObject *parent = 0); - - ~PlayerObject(); - - - enum PlayerCaps - { - - NONE = 0, - CAN_GO_NEXT = 1 << 0, - CAN_GO_PREV = 1 << 1, - CAN_PAUSE = 1 << 2, - CAN_PLAY = 1 << 3, - CAN_SEEK = 1 << 4, - CAN_PROVIDE_METADATA = 1 << 5, - CAN_HAS_TRACKLIST = 1 << 6 - }; - - -public slots: - void Next(); - void Prev(); - void Pause(); - void Stop(); - void Play(); - void Repeat(bool in0); - PlayerStatus GetStatus(); - QVariantMap GetMetadata(); - int GetCaps(); - void VolumeSet(int in0); - int VolumeGet(); - void PositionSet(int in0); - int PositionGet(); - -signals: - void CapsChange(int); - void TrackChange(QVariantMap); - void StatusChange(PlayerStatus); - -private slots: - void updateCaps(); - void updateTrack(); - void updateStatus(); - -private: - SoundCore *m_core; - MediaPlayer *m_player; - PlayListManager *m_pl_manager; - -}; - -#endif diff --git a/src/plugins/General/mpris/root2object.cpp b/src/plugins/General/mpris/root2object.cpp deleted file mode 100644 index c0eca65fb..000000000 --- a/src/plugins/General/mpris/root2object.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "root2object.h" - -Root2Object::Root2Object(QObject *parent) : QObject(parent) -{} - - -Root2Object::~Root2Object() -{} - -bool Root2Object::canQuit() const -{ - return true; -} - -bool Root2Object::canRaise() const -{ - return false; -} - -QString Root2Object::desktopEntry() const -{ - return "qmmp"; -} - -bool Root2Object::hasTrackList() const -{ - return false; -} -QString Root2Object::identity() const -{ - QString name = "Qmmp " + Qmmp::strVersion(); - return name; -} - -QStringList Root2Object::supportedMimeTypes() const -{ - QStringList mimeTypes; - foreach(DecoderFactory *factory, *Decoder::factories()) - mimeTypes << factory->properties().contentTypes; - foreach(EngineFactory *factory, *AbstractEngine::factories()) - mimeTypes << factory->properties().contentTypes; - mimeTypes.removeDuplicates(); - return mimeTypes; -} - -QStringList Root2Object::supportedUriSchemes() const -{ - QStringList protocols = MetaDataManager::instance()->protocols(); - if(!protocols.contains("file")) //append file if needed - protocols.append("file"); - return protocols; -} - -void Root2Object::Quit() -{ - QMetaObject::invokeMethod(parent(), "exit"); -} - -void Root2Object::Raise(){} diff --git a/src/plugins/General/mpris/root2object.h b/src/plugins/General/mpris/root2object.h deleted file mode 100644 index f661df200..000000000 --- a/src/plugins/General/mpris/root2object.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef ROOT2OBJECT_H -#define ROOT2OBJECT_H - -#include -#include - -/** - @author Ilya Kotov -*/ -class Root2Object : public QObject -{ -Q_OBJECT -Q_CLASSINFO("D-Bus Interface", "org.mpris.MediaPlayer2") -Q_PROPERTY(bool CanQuit READ canQuit) -Q_PROPERTY(bool CanRaise READ canRaise) -Q_PROPERTY(QString DesktopEntry READ desktopEntry) -Q_PROPERTY(bool HasTrackList READ hasTrackList) -Q_PROPERTY(QString Identity READ identity) -Q_PROPERTY(QStringList SupportedMimeTypes READ supportedMimeTypes) -Q_PROPERTY(QStringList SupportedUriSchemes READ supportedUriSchemes) - -public: - Root2Object(QObject *parent = 0); - virtual ~Root2Object(); - - bool canQuit() const; - bool canRaise() const; - QString desktopEntry() const; - bool hasTrackList() const; - QString identity() const; - QStringList supportedMimeTypes() const; - QStringList supportedUriSchemes() const; - -public slots: - void Quit(); - void Raise(); -}; - -#endif diff --git a/src/plugins/General/mpris/rootobject.cpp b/src/plugins/General/mpris/rootobject.cpp deleted file mode 100644 index 7c4267d08..000000000 --- a/src/plugins/General/mpris/rootobject.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include - -#include -#include "rootobject.h" - -//register << operator -QDBusArgument &operator << (QDBusArgument &arg, const Version &v) -{ - arg.beginStructure(); - arg << v.major; - arg << v.minor; - arg.endStructure(); - return arg; -} - -//register >> operator -const QDBusArgument &operator >> (const QDBusArgument &arg, Version &v) -{ - arg.beginStructure(); - arg >> v.major; - arg >> v.minor; - arg.endStructure(); - return arg; -} - -RootObject::RootObject(QObject *parent) - : QObject(parent) -{ - qDBusRegisterMetaType(); -} - - -RootObject::~RootObject() -{ -} - -QString RootObject::Identity() -{ - QString name = "Qmmp " + Qmmp::strVersion(); - return name; -} - -Version RootObject::MprisVersion() -{ - struct Version v; - v.major = 1; - v.minor = 0; - return v; -} - -void RootObject::Quit() -{ - QMetaObject::invokeMethod(parent(), "exit"); -} diff --git a/src/plugins/General/mpris/rootobject.h b/src/plugins/General/mpris/rootobject.h deleted file mode 100644 index 378d9f51a..000000000 --- a/src/plugins/General/mpris/rootobject.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef ROOTOBJECT_H -#define ROOTOBJECT_H - -#include -#include - -/** - @author Ilya Kotov -*/ - - -struct Version -{ - quint16 major; - quint16 minor; -}; - -Q_DECLARE_METATYPE(Version); - -class RootObject : public QObject -{ -Q_OBJECT -Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") -public: - RootObject(QObject *parent = 0); - - ~RootObject(); - -public slots: - QString Identity(); - Version MprisVersion(); - void Quit(); -}; - -#endif diff --git a/src/plugins/General/mpris/tracklistobject.cpp b/src/plugins/General/mpris/tracklistobject.cpp deleted file mode 100644 index a55f2c770..000000000 --- a/src/plugins/General/mpris/tracklistobject.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include - -#include -#include -#include - -#include "tracklistobject.h" - -TrackListObject::TrackListObject(QObject *parent) : QObject(parent) -{ - m_player = MediaPlayer::instance(); - m_pl_manager = m_player->playListManager(); - m_model = m_pl_manager->currentPlayList(); - connect (m_model, SIGNAL(listChanged()), SLOT(updateTrackList())); - connect (m_pl_manager, SIGNAL(currentPlayListChanged(PlayListModel*,PlayListModel*)), - SLOT(switchPlayList(PlayListModel*,PlayListModel*))); - m_prev_count = 0; -} - - -TrackListObject::~TrackListObject() -{ -} - -int TrackListObject::AddTrack(const QString &in0, bool in1) -{ - QString path = in0; - if(in0.startsWith("file://")) - { - path = QUrl(in0).toLocalFile (); - if(!QFile::exists(path)) - return 1; //error - } - if(in1) - { - m_pl_manager->selectPlayList(m_model); - m_player->stop(); - qDebug("1"); - m_prev_count = m_model->count(); - connect(m_model, SIGNAL(listChanged()), this, SLOT(checkNewItem())); - connect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); - qDebug("2"); - } - m_model->add(path); - return 0; -} - -void TrackListObject::DelTrack(int in0) -{ - m_model->removeAt(in0); -} - -int TrackListObject::GetCurrentTrack() -{ - return m_model->currentRow(); -} - -int TrackListObject::GetLength() -{ - return m_model->count(); -} - -QVariantMap TrackListObject::GetMetadata(int in0) -{ - QVariantMap map; - PlayListItem *item = m_model->item(in0); - if (item) - { - if (QFile::exists(item->url())) - map.insert("location", "file://" + item->url()); - else - map.insert("location", item->url()); - map.insert("title", item->value(Qmmp::TITLE)); - map.insert("artist", item->value(Qmmp::ARTIST)); - map.insert("album", item->value(Qmmp::ALBUM)); - map.insert("tracknumber", item->value(Qmmp::TRACK)); - map.insert("time", (quint32)item->length()); - map.insert("mtime", (quint32)item->length() * 1000); - map.insert("genre", item->value(Qmmp::GENRE)); - map.insert("comment", item->value(Qmmp::COMMENT)); - map.insert("year", item->value(Qmmp::YEAR).toUInt()); - } - return map; -} - -void TrackListObject::SetLoop(bool in0) -{ - m_pl_manager->setRepeatableList(in0); -} - -void TrackListObject::SetRandom(bool in0) -{ - m_pl_manager->setShuffle(in0); -} - -void TrackListObject::disconnectPl() -{ - disconnect(m_model, SIGNAL(listChanged()), this, SLOT(checkNewItem())); - disconnect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); -} - -void TrackListObject::checkNewItem() //checks for new item in playlist -{ - if(m_model->count() > m_prev_count) - { - disconnectPl(); //disconnect playlist; - m_model->setCurrent(m_prev_count); // activate first added item - m_player->play(); // ... and play it - } -} - -void TrackListObject::updateTrackList() -{ - emit TrackListChange(m_model->count()); -} - -void TrackListObject::switchPlayList(PlayListModel *cur, PlayListModel *prev) -{ - disconnectPl(); - m_model = cur; - connect (m_model, SIGNAL(listChanged()), SLOT(updateTrackList())); - if(prev) - disconnect(prev,0,this,0); - updateTrackList(); -} diff --git a/src/plugins/General/mpris/tracklistobject.h b/src/plugins/General/mpris/tracklistobject.h deleted file mode 100644 index eec9eda3c..000000000 --- a/src/plugins/General/mpris/tracklistobject.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008-2009 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef TRACKLISTOBJECT_H -#define TRACKLISTOBJECT_H - -#include -#include -#include - -class PlayListModel; -class PlayListManager; -class MediaPlayer; - -/** - @author Ilya Kotov -*/ -class TrackListObject : public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.MediaPlayer") - -public: - TrackListObject(QObject *parent = 0); - - ~TrackListObject(); - -public slots: - int AddTrack(const QString &in0, bool in1); - void DelTrack(int in0); - int GetCurrentTrack(); - int GetLength(); - QVariantMap GetMetadata(int in0); - void SetLoop(bool in0); - void SetRandom(bool in0); - -signals: - void TrackListChange(int in0); - -private slots: - void disconnectPl(); - void checkNewItem(); - void updateTrackList(); - void switchPlayList(PlayListModel *cur, PlayListModel *prev); - -private: - PlayListModel *m_model; - PlayListManager *m_pl_manager; - MediaPlayer *m_player; - int m_prev_count; - -}; - -#endif diff --git a/src/qmmpui/playlistmodel.cpp b/src/qmmpui/playlistmodel.cpp index 541fd3f26..2df8d9ef2 100644 --- a/src/qmmpui/playlistmodel.cpp +++ b/src/qmmpui/playlistmodel.cpp @@ -112,8 +112,7 @@ void PlayListModel::add(PlayListItem *item) m_items << item; m_current = m_items.indexOf(m_currentItem); - if (m_items.size() == 1) - emit firstAdded(); + emit itemAdded(item); emit listChanged(); } @@ -124,29 +123,27 @@ void PlayListModel::add(QList items) if (m_items.isEmpty()) m_currentItem = items.at(0); - foreach(PlayListItem *item, items) - m_total_length += item->length(); m_items << items; - - if (m_items.size() == items.size()) - emit firstAdded(); m_current = m_items.indexOf(m_currentItem); + foreach(PlayListItem *item, items) + { + m_total_length += item->length(); + emit itemAdded(item); + } emit listChanged(); } void PlayListModel::add(const QString &path) { QFileInfo f_info(path); - //if (f_info.exists() || path.contains("://")) + if (f_info.isDir()) + m_loader->loadDirectory(path); + else { - if (f_info.isDir()) - m_loader->loadDirectory(path); - else - { - m_loader->loadFile(path); - loadPlaylist(path); - } + m_loader->loadFile(path); + loadPlaylist(path); } + } void PlayListModel::add(const QStringList &paths) @@ -202,6 +199,13 @@ bool PlayListModel::setCurrent(int c) return true; } +bool PlayListModel::setCurrent(PlayListItem *item) +{ + if(!m_items.contains(item)) + return false; + return setCurrent(m_items.indexOf(item)); +} + bool PlayListModel::next() { if(m_stop_item == currentItem()) @@ -858,6 +862,11 @@ bool PlayListModel::isShuffle() const return m_shuffle; } +bool PlayListModel::isLoaderRunning() const +{ + return m_loader->isRunning(); +} + void PlayListModel::preparePlayState() { m_play_state->prepare(); diff --git a/src/qmmpui/playlistmodel.h b/src/qmmpui/playlistmodel.h index b44270758..3e4c1219d 100644 --- a/src/qmmpui/playlistmodel.h +++ b/src/qmmpui/playlistmodel.h @@ -151,6 +151,11 @@ public: * @param row Number of item. */ bool setCurrent (int row); + /*! + * Sets current item to \b item. + * Returns \b true if success, otherwise returns \b false + */ + bool setCurrent(PlayListItem *item); /*! * Returns \b true if \b row is selected, otherwise returns \b false */ @@ -262,6 +267,10 @@ public: * Returns state of "Shuffle" option. */ bool isShuffle() const; + /*! + * Returns \b true if the file loader thread is active; otherwise returns \b false. + */ + bool isLoaderRunning() const; /*! * Returns \b true if the playlist contains an item with URL \b url; otherwise returns \b false. */ @@ -290,9 +299,10 @@ signals: */ void currentChanged(); /*! - * Emitted when first item has added. + * Emitted when new item has added. + * @param name New playlist item pointer. */ - void firstAdded(); + void itemAdded(PlayListItem *item); /*! * Emitted when playlist name has chanded. * @param name New playlist name. diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 5fb0458f9..b501aa67d 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -564,7 +564,7 @@ void MainWindow::setFileList(const QStringList &l, bool clear) } m_model = m_pl_manager->selectedPlayList(); m_model->clear(); - connect(m_model, SIGNAL(firstAdded()), SLOT(play())); + connect(m_model, SIGNAL(itemAdded(PlayListItem*)), SLOT(play())); connect(m_model, SIGNAL(loaderFinished()), SLOT(disconnectPl())); m_model->add(l); } @@ -631,7 +631,7 @@ void MainWindow::disconnectPl() { if(m_model) { - disconnect(m_model, SIGNAL(firstAdded()), this, SLOT(play())); + disconnect(m_model, SIGNAL(itemAdded(PlayListItem*)), this, SLOT(play())); disconnect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); m_model = 0; } -- cgit v1.2.3-13-gbd6f