not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / dataengines / nowplaying / playerinterface / mpris / mpris.cpp
blob4ee699d8e79705565761db79a43d85070b283c1e
1 /*
2 * Copyright 2007 Alex Merry <alex.merry@kdemail.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License version 2 as
6 * published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU Library General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "mpris.h"
20 #include "mpris_p.h"
21 #include <mprisplayer.h>
23 #include <QtDBus>
24 #include <QFile>
26 #include <kdebug.h>
27 #include <KIO/NetAccess>
31 MprisFactory::MprisFactory(QObject* parent)
32 : DBusPlayerFactory(parent)
34 setObjectName("MprisFactory");
35 qDBusRegisterMetaType<MprisDBusVersion>();
36 qDBusRegisterMetaType<MprisDBusStatus>();
39 Player::Ptr MprisFactory::create(const QVariantList& args)
41 if (args.isEmpty()) {
42 return Player::Ptr(0);
44 QString dbusName(args.first().toString());
45 if (dbusName.isEmpty()) {
46 return Player::Ptr(0);
48 Mpris* player = new Mpris(dbusName, this);
49 if (!player->isRunning()) {
50 delete player;
51 player = 0;
53 return Player::Ptr(player);
56 bool MprisFactory::matches(const QString& serviceName)
58 return serviceName.startsWith("org.mpris");
63 Mpris::Mpris(const QString& name, PlayerFactory* factory)
64 : QObject(),
65 Player(factory),
66 m_player(0),
67 m_playerName(name)
69 if (!name.startsWith("org.mpris")) {
70 m_playerName = "org.mpris." + name;
72 setName(m_playerName);
73 setup();
76 Mpris::~Mpris()
78 delete m_player;
81 void Mpris::setup() {
82 delete m_player;
83 m_player = new MprisPlayer(
84 m_playerName,
85 "/Player",
86 QDBusConnection::sessionBus());
88 m_metadata.clear();
89 m_state = Stopped;
90 m_caps = NO_CAPS;
92 if (m_player->isValid()) {
93 connect(m_player, SIGNAL(CapsChange(int)),
94 this, SLOT(capsChanged(int)));
95 connect(m_player, SIGNAL(TrackChange(QVariantMap)),
96 this, SLOT(trackChanged(QVariantMap)));
97 connect(m_player, SIGNAL(StatusChange(MprisDBusStatus)),
98 this, SLOT(stateChanged(MprisDBusStatus)));
100 capsChanged(m_player->GetCaps());
101 trackChanged(m_player->GetMetadata());
102 stateChanged(m_player->GetStatus());
106 bool Mpris::isRunning()
108 if (!m_player->isValid()) {
109 setup();
111 return m_player->isValid();
114 Player::State Mpris::state()
116 return m_state;
119 QString Mpris::artist()
121 if (m_metadata.contains("artist")) {
122 return m_metadata["artist"].toString();
124 return QString();
127 QString Mpris::album()
129 if (m_metadata.contains("album")) {
130 return m_metadata["album"].toString();
132 return QString();
135 QString Mpris::title()
137 if (m_metadata.contains("title")) {
138 return m_metadata["title"].toString();
140 return QString();
143 int Mpris::trackNumber()
145 QVariant track;
146 if (m_metadata.contains("trackNumber")) {
147 track = m_metadata["trackNumber"];
148 } else if (m_metadata.contains("tracknumber")) {
149 track = m_metadata["tracknumber"];
151 if (track.isValid()) {
152 if (track.canConvert(QVariant::Int)) {
153 return track.toInt();
154 } else {
155 QString text = track.toString();
156 int pos = text.indexOf('/');
157 if (pos >= 0) {
158 text.truncate(pos);
160 return text.toInt();
163 return 0;
166 QString Mpris::comment()
168 if (m_metadata.contains("comment")) {
169 return m_metadata["comment"].toString();
171 return QString();
174 QString Mpris::genre()
176 if (m_metadata.contains("genre")) {
177 return m_metadata["genre"].toString();
179 return QString();
182 int Mpris::length()
184 if (m_metadata.contains("time")) {
185 return m_metadata["time"].toInt();
186 } else if (m_metadata.contains("length")) {
187 // stupid audacious...
188 return m_metadata["length"].toInt()/1000;
190 return 0;
193 int Mpris::position()
195 if (m_player->isValid()) {
196 return m_player->PositionGet() / 1000;
198 return 0;
201 float Mpris::volume()
203 if (m_player->isValid()) {
204 return ((float)m_player->VolumeGet()) / 100;
206 return 0;
209 QPixmap Mpris::artwork()
211 if (m_metadata.contains("arturl")) {
212 QString arturl = m_metadata["arturl"].toString();
213 if (!arturl.isEmpty()) {
214 if (!m_artfiles.contains(arturl) ||
215 !QFile::exists(m_artfiles[arturl])) {
216 QString artfile;
217 if (!KIO::NetAccess::download(arturl, artfile, 0)) {
218 kWarning() << KIO::NetAccess::lastErrorString();
219 return QPixmap();
221 m_artfiles[arturl] = artfile;
223 return QPixmap(m_artfiles[arturl]);
226 return QPixmap();
229 bool Mpris::canPlay()
231 return m_caps & CAN_PLAY;
234 void Mpris::play()
236 if (m_player->isValid()) {
237 m_player->Play();
241 bool Mpris::canPause()
243 return m_caps & CAN_PAUSE;
246 void Mpris::pause()
248 if (m_player->isValid()) {
249 m_player->Pause();
253 bool Mpris::canStop()
255 return m_state != Stopped;
258 void Mpris::stop()
260 if (m_player->isValid()) {
261 m_player->Stop();
265 bool Mpris::canGoPrevious()
267 return m_caps & CAN_GO_PREV;
270 void Mpris::previous()
272 if (m_player->isValid()) {
273 m_player->Prev();
277 bool Mpris::canGoNext()
279 return m_caps & CAN_GO_NEXT;
282 void Mpris::next()
284 if (m_player->isValid()) {
285 m_player->Next();
289 bool Mpris::canSetVolume()
291 return true;
294 void Mpris::setVolume(qreal volume)
296 if (m_player->isValid()) {
297 m_player->VolumeSet((int)(volume * 100));
301 bool Mpris::canSeek()
303 return m_caps & CAN_SEEK;
306 void Mpris::seek(int time)
308 if (m_player->isValid()) {
309 // m_player->seek() wants milliseconds
310 m_player->PositionSet(time * 1000);
314 // SLOTS
316 void Mpris::trackChanged(const QVariantMap& metadata)
318 kDebug() << m_playerName << "metadata:" << metadata;
319 m_metadata = metadata;
322 void Mpris::stateChanged(MprisDBusStatus state)
324 kDebug() << m_playerName << "state:" << state.play;
325 switch (state.play) {
326 case MprisDBusStatus::Playing:
327 m_state = Playing;
328 break;
329 case MprisDBusStatus::Paused:
330 m_state = Paused;
331 break;
332 case MprisDBusStatus::Stopped:
333 m_state = Stopped;
334 break;
335 default:
336 kDebug() << m_playerName << "unexpected state" << state.play;
340 void Mpris::capsChanged(int caps)
342 kDebug() << m_playerName << "capabilities:" << caps;
343 m_caps = (DBusCaps)caps;
344 if (!(caps & CAN_PROVIDE_METADATA)) {
345 m_metadata.clear();
350 #include "mpris.moc"
351 #include "mpris_p.moc"