summaryrefslogtreecommitdiffstats
path: root/kicker-applets/mediacontrol
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit84da08d7b7fcda12c85caeb5a10b4903770a6f69 (patch)
tree2a6aea76f2dfffb4cc04bb907c4725af94f70e72 /kicker-applets/mediacontrol
downloadtdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.tar.gz
tdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaddons@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kicker-applets/mediacontrol')
-rw-r--r--kicker-applets/mediacontrol/AUTHORS5
-rw-r--r--kicker-applets/mediacontrol/Makefile.am28
-rw-r--r--kicker-applets/mediacontrol/README28
-rw-r--r--kicker-applets/mediacontrol/TODO7
-rw-r--r--kicker-applets/mediacontrol/amarokInterface.cpp310
-rw-r--r--kicker-applets/mediacontrol/amarokInterface.h69
-rw-r--r--kicker-applets/mediacontrol/configfrontend.cpp99
-rw-r--r--kicker-applets/mediacontrol/configfrontend.h52
-rw-r--r--kicker-applets/mediacontrol/configure.in.in48
-rw-r--r--kicker-applets/mediacontrol/jukInterface.cpp314
-rw-r--r--kicker-applets/mediacontrol/jukInterface.h72
-rw-r--r--kicker-applets/mediacontrol/kscdInterface.cpp332
-rw-r--r--kicker-applets/mediacontrol/kscdInterface.h68
-rw-r--r--kicker-applets/mediacontrol/mcslider.cpp66
-rw-r--r--kicker-applets/mediacontrol/mcslider.h37
-rw-r--r--kicker-applets/mediacontrol/mediacontrol.cpp614
-rw-r--r--kicker-applets/mediacontrol/mediacontrol.desktop121
-rw-r--r--kicker-applets/mediacontrol/mediacontrol.h122
-rw-r--r--kicker-applets/mediacontrol/mediacontrolconfig.cpp197
-rw-r--r--kicker-applets/mediacontrol/mediacontrolconfig.h54
-rw-r--r--kicker-applets/mediacontrol/mediacontrolconfigwidget.ui374
-rw-r--r--kicker-applets/mediacontrol/mediacontroliface.h31
-rw-r--r--kicker-applets/mediacontrol/mpdInterface.cpp585
-rw-r--r--kicker-applets/mediacontrol/mpdInterface.h100
-rw-r--r--kicker-applets/mediacontrol/noatunInterface.cpp283
-rw-r--r--kicker-applets/mediacontrol/noatunInterface.h67
-rw-r--r--kicker-applets/mediacontrol/pics/Makefile.am2
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/Makefile.am4
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/next.pngbin0 -> 174 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/pause.pngbin0 -> 119 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/play.pngbin0 -> 160 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/prev.pngbin0 -> 173 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/blueish/stop.pngbin0 -> 115 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/default/Makefile.am4
-rw-r--r--kicker-applets/mediacontrol/pics/default/next.pngbin0 -> 392 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/default/pause.pngbin0 -> 345 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/default/play.pngbin0 -> 342 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/default/prev.pngbin0 -> 379 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/default/stop.pngbin0 -> 356 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/Makefile.am4
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/README12
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/next.pngbin0 -> 553 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/pause.pngbin0 -> 423 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/play.pngbin0 -> 546 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/prev.pngbin0 -> 573 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/source.xcfbin0 -> 9566 bytes
-rw-r--r--kicker-applets/mediacontrol/pics/fulldecent/stop.pngbin0 -> 427 bytes
-rw-r--r--kicker-applets/mediacontrol/playerInterface.cpp34
-rw-r--r--kicker-applets/mediacontrol/playerInterface.h57
-rw-r--r--kicker-applets/mediacontrol/simplebutton.cpp256
-rw-r--r--kicker-applets/mediacontrol/simplebutton.h89
-rw-r--r--kicker-applets/mediacontrol/xmmsInterface.cpp183
-rw-r--r--kicker-applets/mediacontrol/xmmsInterface.h59
53 files changed, 4787 insertions, 0 deletions
diff --git a/kicker-applets/mediacontrol/AUTHORS b/kicker-applets/mediacontrol/AUTHORS
new file mode 100644
index 0000000..b7d6d85
--- /dev/null
+++ b/kicker-applets/mediacontrol/AUTHORS
@@ -0,0 +1,5 @@
+Michael Startek <micha.startek@op.pl>
+Stefan Gehn <metz {AT} gehn {DOT} net>
+Teemu Rytilahti <teemu.rytilahti@kde-fi.org>
+Thomas Capricelli <orzel@freehackers.org>
+William Robinson <airbaggins@yahoo.co.uk>
diff --git a/kicker-applets/mediacontrol/Makefile.am b/kicker-applets/mediacontrol/Makefile.am
new file mode 100644
index 0000000..0afe266
--- /dev/null
+++ b/kicker-applets/mediacontrol/Makefile.am
@@ -0,0 +1,28 @@
+SUBDIRS = . pics
+INCLUDES = $(XMMS_INCLUDES) $(all_includes)
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = mediacontrol_panelapplet.la
+
+mediacontrol_panelapplet_la_COMPILE_FIRST = mediacontrolconfigwidget.h
+mediacontrol_panelapplet_la_SOURCES = mcslider.cpp \
+ mediacontrol.cpp playerInterface.cpp \
+ configfrontend.cpp mediacontrolconfigwidget.ui \
+ mediacontrolconfig.cpp mediacontroliface.skel \
+ noatunInterface.cpp \
+ xmmsInterface.cpp \
+ mpdInterface.cpp \
+ jukInterface.cpp \
+ amarokInterface.cpp \
+ kscdInterface.cpp \
+ simplebutton.cpp
+
+mediacontrol_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) $(XMMS_LIBS)
+mediacontrol_panelapplet_la_LIBADD = $(LIB_KDEUI)
+
+lnkdir = $(kde_datadir)/kicker/applets
+lnk_DATA = mediacontrol.desktop
+EXTRA_DIST = $(lnk_DATA)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/mediacontrol.pot
diff --git a/kicker-applets/mediacontrol/README b/kicker-applets/mediacontrol/README
new file mode 100644
index 0000000..0c3acc7
--- /dev/null
+++ b/kicker-applets/mediacontrol/README
@@ -0,0 +1,28 @@
+MediaControl v0.4
+Stefan Gehn <metz AT gehn.net>
+----------------------------------------------------------------------
+
+This is a small applet for the kde-panel (kicker) to control various
+mediaplayers with.
+
+Supported players at the moment are:
+- Noatun
+- XMMS
+- JuK
+- Amarok
+- KsCD
+- more to come :)
+
+If you ask "Why another applet for xmms?" then there are a few answers for you:
+
+1. most of those applets are for XMMS _only_ and I wanted to support various
+ mediaplayers
+2. there was no applet for noatun (... and I was never able to find that noatun
+ -window on my huge desktop)
+3. many xmms-applets use skins to look like xmms itself, I really dislike that
+ on a panel
+
+The applet is still very small and can't make coffee yet but this will surely
+come one day ;)
+
+Have fun with this small and (hopefully) handy tool.
diff --git a/kicker-applets/mediacontrol/TODO b/kicker-applets/mediacontrol/TODO
new file mode 100644
index 0000000..0066900
--- /dev/null
+++ b/kicker-applets/mediacontrol/TODO
@@ -0,0 +1,7 @@
+Tooltip -> DONE (want to make it configurable)
+Themes -> DONE (need some more contributions)
+i18n -> need to find out where to put it in kde-cvs
+Drag n Drop -> DONE
+Playlist-Popup -> maybe never, what about 9000 files playlists in a popup, eh? :)
+Squelch-Support -> when squelch got its dcopiface
+more players -> hey gimme a nice interface for it and I'll add support ;)
diff --git a/kicker-applets/mediacontrol/amarokInterface.cpp b/kicker-applets/mediacontrol/amarokInterface.cpp
new file mode 100644
index 0000000..2045c12
--- /dev/null
+++ b/kicker-applets/mediacontrol/amarokInterface.cpp
@@ -0,0 +1,310 @@
+/***************************************************************************
+ Interface to access Amarok
+ -------------------
+ begin : Tue Dec 2 23:54:53 CET 2003
+ copyright : (c) 2003 by Thomas Capricelli
+ adapted from juk* (C) 2001-2002 by Stefan Gehn (metz {AT} gehn {DOT} net)
+ email : orzel@freehackers.org
+ ***************************************************************************/
+
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "amarokInterface.h"
+#include "amarokInterface.moc"
+
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <qstrlist.h>
+#include <kurldrag.h>
+
+#define TIMER_FAST 250
+
+AmarokInterface::AmarokInterface() : PlayerInterface()
+{
+ mTimerValue = TIMER_FAST;
+ mAmarokTimer = new QTimer ( this, "mAmaroKTimer" );
+
+ connect(mAmarokTimer, SIGNAL(timeout()), SLOT(updateSlider()) );
+ kapp->dcopClient()->setNotifications ( true );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRegistered(const QCString&)),
+ SLOT(appRegistered(const QCString&)) );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
+ SLOT(appRemoved(const QCString&)));
+
+ QTimer::singleShot(0, this, SLOT(myInit()));
+}
+
+AmarokInterface::~AmarokInterface()
+{
+ kapp->dcopClient()->setNotifications(false);
+ delete mAmarokTimer;
+}
+
+void AmarokInterface::myInit()
+{
+ // Start the timer if amarok is already running
+ // Needed if user adds applet while running amarok
+ if ( findRunningAmarok() )
+ {
+ emit playerStarted();
+ mAmarokTimer->start(mTimerValue);
+ }
+ else
+ {
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void AmarokInterface::appRegistered ( const QCString &appId )
+{
+ if(appId.contains("amarok",false) )
+ {
+ mAppId = appId;
+ emit playerStarted();
+ mAmarokTimer->start(mTimerValue);
+ }
+}
+
+void AmarokInterface::appRemoved ( const QCString &appId )
+{
+ if ( appId.contains("amarok",false) )
+ {
+ // is there still another amarok alive?
+ if ( findRunningAmarok() )
+ return;
+ mAmarokTimer->stop();
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void AmarokInterface::updateSlider ( )
+{
+ // length/time in msecs, -1 means "no playobject in amarok"
+ int len, time;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (!kapp->dcopClient()->call(mAppId, "player", "trackTotalTime()",data, replyType, replyData))
+ {
+ //kdDebug(90200) << "mediacontrol: DCOP communication Error" << endl;
+ // -2 is an internal errornumber, might be used later
+ len = -2;
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> len;
+ }
+ else
+ {
+ //kdDebug(90200) << "mediacontrol: unexpected type of DCOP-reply" << endl;
+ // -3 is an internal errornumber, might be used later
+ len = -3;
+ }
+ }
+
+ data = 0;
+ replyData = 0;
+ replyType = 0;
+
+ if (!kapp->dcopClient()->call(mAppId, "player", "trackCurrentTime()",data, replyType, replyData))
+ {
+ //kdDebug(90200) << "mediacontrol: DCOP communication error" << endl;
+ time = -2;
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> time;
+ }
+ else
+ {
+ //kdDebug(90200) << "mediacontrol: unexpected type of DCOP-reply" << endl;
+ time = -3;
+ }
+ }
+
+ if ( (time < 0) || (len < 0)) // Amarok isn't playing and thus returns -1
+ {
+ len = 0;
+ time = 0;
+ }
+ emit newSliderPosition(len,time);
+ emit playingStatusChanged(playingStatus());
+}
+
+// Drag-n-Drop stuff =================================================================
+
+void AmarokInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+// kdDebug(90200) << "AmarokInterface::dragEnterEvent()" << endl;
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+void AmarokInterface::dropEvent(QDropEvent* event)
+{
+ kdDebug(90200) << "AmarokInterface::dropEvent()" << endl;
+ KURL::List list;
+ if (KURLDrag::decode(event, list))
+ {
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << list;
+ if (!kapp->dcopClient()->send(mAppId, "player", "addMediaList(KURL::List)",data))
+ kdDebug(90200) << "Couldn't send drop to amarok" << endl;
+ }
+}
+
+// ====================================================================================
+
+void AmarokInterface::sliderStartDrag()
+{
+ mAmarokTimer->stop();
+}
+
+void AmarokInterface::sliderStopDrag()
+{
+ mAmarokTimer->start(mTimerValue);
+}
+
+void AmarokInterface::jumpToTime( int sec )
+{
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << sec;
+ kapp->dcopClient()->send(mAppId, "player", "seek(int)", data);
+}
+
+void AmarokInterface::playpause()
+{
+ if (!findRunningAmarok())
+ startPlayer("amarok");
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "playPause()", data);
+}
+
+void AmarokInterface::stop()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "stop()", data);
+}
+
+void AmarokInterface::next()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "next()", data);
+}
+
+void AmarokInterface::prev()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "prev()", data);
+}
+
+void AmarokInterface::volumeUp()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "volumeUp()", data);
+}
+
+void AmarokInterface::volumeDown()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "player", "volumeDown()", data);
+}
+
+const QString AmarokInterface::getTrackTitle() const
+{
+ QString title;
+ QByteArray data, replyData;
+ QCString replyType;
+ if (!kapp->dcopClient()->call(mAppId, "player", "nowPlaying()",data, replyType, replyData))
+ {
+ //kdDebug(90200) << "mediacontrol: DCOP communication Error" << endl;
+ return QString("");
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> title;
+ return title;
+ }
+ else
+ {
+ //kdDebug(90200) << "mediacontrol: unexpected type of DCOP-reply" << endl;
+ return QString("");
+ }
+ }
+}
+
+bool AmarokInterface::findRunningAmarok()
+{
+ QCStringList allApps = kapp->dcopClient()->registeredApplications();
+ QValueList<QCString>::const_iterator iterator;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ for (iterator = allApps.constBegin(); iterator != allApps.constEnd(); ++iterator)
+ {
+ if ((*iterator).contains("amarok",false))
+ {
+ if (kapp->dcopClient()->call((*iterator), "player", "interfaces()", data, replyType, replyData) )
+ {
+ if ( replyType == "QCStringList" )
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ QCStringList list;
+ reply >> list;
+
+ if ( list.contains("AmarokPlayerInterface") )
+ {
+ kdDebug(90200) << "mediacontrol: amarok found" << endl;
+ mAppId = *iterator;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ kdDebug(90200) << "mediacontrol: amarok not found" << endl;
+ return false;
+}
+
+
+int AmarokInterface::playingStatus()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "player", "status()", data, replyType,
+ replyData))
+ {
+ int status = 0;
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> status;
+ if (status == 2)
+ return Playing;
+ else if (status == 1)
+ return Paused;
+ }
+ return Stopped;
+}
diff --git a/kicker-applets/mediacontrol/amarokInterface.h b/kicker-applets/mediacontrol/amarokInterface.h
new file mode 100644
index 0000000..3a71031
--- /dev/null
+++ b/kicker-applets/mediacontrol/amarokInterface.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ Interface to access Amarok
+ -------------------
+ begin : Tue Dec 2 23:54:53 CET 2003
+ copyright : (c) 2003 by Thomas Capricelli
+ adapted from juk* (C) 2001-2002 by Stefan Gehn (metz {AT} gehn {DOT} net)
+ email : orzel@freehackers.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef AMAROKINTERFACE_H
+#define AMAROKINTERFACE_H
+
+#include "playerInterface.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qtimer.h>
+
+class AmarokInterface : public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ AmarokInterface();
+ ~AmarokInterface();
+
+ public slots:
+ virtual void updateSlider(); // gets called on timer-timeout
+ virtual void sliderStartDrag();
+ virtual void sliderStopDrag();
+ virtual void jumpToTime( int msec );
+ virtual void playpause();
+ virtual void stop();
+ virtual void next();
+ virtual void prev();
+ virtual void volumeUp();
+ virtual void volumeDown();
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dropEvent(QDropEvent* event);
+ virtual const QString getTrackTitle() const;
+ virtual int playingStatus();
+
+ private slots:
+ void myInit();
+ void appRegistered ( const QCString &appId );
+ void appRemoved ( const QCString &appId );
+
+ private:
+ QTimer *mAmarokTimer;
+ int mTimerValue;
+ QCString mAppId;
+
+ /**
+ * Tries to find a DCOP registered instance of AmaroK
+ * Stores the name of the first found instance in appId
+ * @returns true is instance is found, false otherwise
+ */
+ bool findRunningAmarok();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/configfrontend.cpp b/kicker-applets/mediacontrol/configfrontend.cpp
new file mode 100644
index 0000000..ba206c8
--- /dev/null
+++ b/kicker-applets/mediacontrol/configfrontend.cpp
@@ -0,0 +1,99 @@
+/***************************************************************************
+ provides access to mediacontrol configuration file
+ -------------------
+ begin : forgot :/
+ copyright : (C) 2000-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+
+ code-skeleton taken from knewsticker which is
+ Copyright (c) Frerich Raabe <raabe@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "configfrontend.h"
+// #include <kdebug.h>
+
+ConfigFrontend::ConfigFrontend() : QObject(0, 0)
+{
+ _config = new KConfig(QString::null, true, false);
+ _ownConfig = true;
+}
+
+ConfigFrontend::~ConfigFrontend()
+{
+ if (_ownConfig)
+ {
+ delete _config;
+ }
+}
+
+ConfigFrontend::ConfigFrontend(KConfig *config) : QObject(0, 0)
+{
+ _config = config;
+ _config->setGroup("MediaControl");
+ _ownConfig = false;
+}
+
+// ====================================================================================
+
+uint ConfigFrontend::mouseWheelSpeed() const
+{
+ return _config->readNumEntry("Mouse wheel speed", 5);
+}
+
+void ConfigFrontend::setMouseWheelSpeed(const uint mouseWheelSpeed)
+{
+ _config->writeEntry("Mouse wheel speed", mouseWheelSpeed);
+ _config->sync();
+}
+
+// ====================================================================================
+
+QString ConfigFrontend::player() const
+{
+ return _config->readPathEntry("Player", "Noatun");
+}
+
+void ConfigFrontend::setPlayer(const QString &player)
+{
+ _config->writePathEntry("Player", player);
+ _config->sync();
+}
+
+// ====================================================================================
+
+QString ConfigFrontend::theme() const
+{
+ return _config->readEntry("Theme", "default");
+}
+
+void ConfigFrontend::setTheme(const QString &theme)
+{
+ _config->writeEntry("Theme", theme);
+ _config->sync();
+}
+
+// ====================================================================================
+
+bool ConfigFrontend::useCustomTheme() const
+{
+ return _config->readBoolEntry("UseCustomTheme", false);
+}
+
+void ConfigFrontend::setUseCustomTheme(const bool use)
+{
+ _config->writeEntry("UseCustomTheme", use);
+ _config->sync();
+}
+
+// ====================================================================================
+
+#include "configfrontend.moc"
diff --git a/kicker-applets/mediacontrol/configfrontend.h b/kicker-applets/mediacontrol/configfrontend.h
new file mode 100644
index 0000000..87a0bf4
--- /dev/null
+++ b/kicker-applets/mediacontrol/configfrontend.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ provides access to mediacontrol configuration file
+ -------------------
+ begin : forgot :/
+ copyright : (C) 2000-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+
+ code-skeleton taken from knewsticker which is
+ Copyright (c) Frerich Raabe <raabe@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef CONFIGFRONTEND_H
+#define CONFIGFRONTEND_H
+
+#include <kconfig.h>
+#include <klocale.h>
+
+class ConfigFrontend : public QObject
+{
+ Q_OBJECT
+ public:
+ ConfigFrontend();
+ ConfigFrontend(KConfig *);
+ virtual ~ConfigFrontend();
+
+ uint mouseWheelSpeed() const;
+ QString player() const;
+ QString theme() const;
+ bool useCustomTheme() const;
+
+ public slots:
+ void setMouseWheelSpeed(const uint);
+ void setPlayer(const QString &player);
+ void setTheme(const QString &theme);
+ void setUseCustomTheme(const bool use);
+ void reparseConfiguration() { _config->reparseConfiguration(); }
+
+ private:
+ KConfig *_config;
+ bool _ownConfig:1;
+};
+
+#endif // CONFIGFRONTEND_H
diff --git a/kicker-applets/mediacontrol/configure.in.in b/kicker-applets/mediacontrol/configure.in.in
new file mode 100644
index 0000000..8a48beb
--- /dev/null
+++ b/kicker-applets/mediacontrol/configure.in.in
@@ -0,0 +1,48 @@
+dnl AM_PATH_XMMS([1.0.0])
+dnl AM_INIT_AUTOMAKE(mediacontrol, 0.1)
+dnl AC_PATH_PROG(XMMS_CONFIG, xmms-config, no)
+dnl AM_PATH_XMMS(1.0.0,,AC_MSG_ERROR([*** XMMS >= 1.0.0 not installed - please install first ***]))
+
+AC_DEFUN([AC_CHECK_XMMS],
+[
+ AC_MSG_CHECKING([for libxmms])
+ AC_CACHE_VAL(ac_cv_have_xmms,
+ [
+ ac_save_libs="$LIBS"
+ LIBS="`xmms-config --libs`"
+ ac_CPPFLAGS_save="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $all_includes `xmms-config --cflags 2> /dev/null`"
+ ac_LDFLAGS_save="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $all_libraries"
+ AC_TRY_LINK(
+ [#include <xmms/xmmsctrl.h>],
+ [xmms_remote_play_pause(0);],
+ [ac_cv_have_xmms="yes"],
+ [ac_cv_have_xmms="no"]
+ )
+ LIBS="$ac_save_libs"
+ LDFLAGS="$ac_LDFLAGS_save"
+ CPPFLAGS="$ac_CPPFLAGS_save"
+ ])
+ AC_MSG_RESULT($ac_cv_have_xmms)
+ if test "$ac_cv_have_xmms" = "yes"; then
+ XMMS_LIBS="`xmms-config --libs`"
+ XMMS_INCLUDES="`xmms-config --cflags`"
+ AC_DEFINE(HAVE_XMMS, 1, [Define if you have xmms libraries and header files.])
+ fi
+])
+
+AC_ARG_WITH(xmms,
+ [AC_HELP_STRING([--with-xmms],[enable XMMS control applet @<:@default=check@:>@])],
+ [], with_xmms=check)
+
+if test "x$with_xmms" != xno; then
+ AC_CHECK_XMMS
+
+ if test "x$with_xmms" != xcheck && test "x$ac_cv_have_xmms" != xyes; then
+ AC_MSG_ERROR([--with-xmms was given, but test for XMMS failed])
+ fi
+fi
+
+AC_SUBST(XMMS_LIBS)
+AC_SUBST(XMMS_INCLUDES)
diff --git a/kicker-applets/mediacontrol/jukInterface.cpp b/kicker-applets/mediacontrol/jukInterface.cpp
new file mode 100644
index 0000000..302e7f2
--- /dev/null
+++ b/kicker-applets/mediacontrol/jukInterface.cpp
@@ -0,0 +1,314 @@
+/***************************************************************************
+ Interface to access JuK
+ -------------------
+ begin : Mon Jan 15 21:09:00 CEST 2001
+ copyright : (C) 2001-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "jukInterface.h"
+#include "jukInterface.moc"
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <qstrlist.h>
+#include <qprocess.h>
+#include <kurldrag.h>
+
+#define TIMER_FAST 250
+
+JuKInterface::JuKInterface() : PlayerInterface(), mProc(0)
+{
+ mTimerValue = TIMER_FAST;
+ mJuKTimer = new QTimer ( this, "mJukTimer" );
+
+ connect(mJuKTimer, SIGNAL(timeout()), SLOT(updateSlider()) );
+ kapp->dcopClient()->setNotifications ( true );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRegistered(const QCString&)),
+ SLOT(appRegistered(const QCString&)) );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
+ SLOT(appRemoved(const QCString&)));
+
+ QTimer::singleShot(0, this, SLOT(myInit()));
+}
+
+JuKInterface::~JuKInterface()
+{
+ kapp->dcopClient()->setNotifications(false);
+ delete mJuKTimer;
+}
+
+void JuKInterface::myInit()
+{
+ // Start the timer if juk is already running
+ // Needed if user adds applet while running juk
+ if ( findRunningJuK() )
+ {
+ emit playerStarted();
+ mJuKTimer->start(mTimerValue);
+ }
+ else
+ {
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void JuKInterface::appRegistered ( const QCString &appId )
+{
+ if(appId.contains("juk",false) )
+ {
+ mAppId = appId;
+
+ // BWAHAHAHA EVIL HACK
+ // JuK blocks DCOP signals on its startup, so if we try to
+ // ping it now, it'll simply cause us to block, which will
+ // cause kicker to block, which is bad, m'kay?
+ //
+ // So what we do is launch the dcop command instead, and let
+ // *it* block for us. As soon as the command exits, we know
+ // that JuK is ready to go (and so are we).
+ mProc = new QProcess(this, "jukdcopCheckProc");
+ mProc->addArgument("dcop");
+ mProc->addArgument("juk");
+ mProc->addArgument("Player");
+ mProc->addArgument("status()");
+
+ connect(mProc, SIGNAL(processExited()), SLOT(jukIsReady()));
+ mProc->start();
+ }
+}
+
+void JuKInterface::appRemoved ( const QCString &appId )
+{
+ if ( appId.contains("juk",false) )
+ {
+ // is there still another juk alive?
+ if ( findRunningJuK() )
+ return;
+ mJuKTimer->stop();
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+/* Called when the dcop process we launch terminates */
+void JuKInterface::jukIsReady()
+{
+ emit playerStarted();
+ mJuKTimer->start(mTimerValue);
+
+ mProc->deleteLater();
+ mProc = 0;
+}
+
+void JuKInterface::updateSlider ()
+{
+ // length/time in msecs, -1 means "no playobject in juk"
+ int len = -1;
+ int time = -1;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "Player", "totalTime()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> len;
+ }
+
+ data = 0;
+ replyData = 0;
+ replyType = 0;
+
+ if (kapp->dcopClient()->call(mAppId, "Player", "currentTime()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> time;
+ }
+
+ if ( (time < 0) || (len < 0)) // JuK isn't playing and thus returns -1
+ {
+ len = 0;
+ time = 0;
+ }
+ emit ( newSliderPosition(len,time) );
+ emit playingStatusChanged(playingStatus());
+}
+
+// Drag-n-Drop stuff =================================================================
+
+void JuKInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+// kdDebug(90200) << "JuKInterface::dragEnterEvent()" << endl;
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+void JuKInterface::dropEvent(QDropEvent* event)
+{
+// kdDebug(90200) << "JuKInterface::dropEvent()" << endl;
+ KURL::List list;
+ if (KURLDrag::decode(event, list))
+ {
+ QByteArray data, replyData;
+ QStringList fileList;
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+
+ // Juk doesn't handle KURL's yet, so we need to form a list
+ // that contains the local paths.
+ for (KURL::List::ConstIterator it = list.begin(); it != list.end(); ++it)
+ fileList += (*it).path();
+
+ arg << fileList << false;
+
+ // Use call instead of send to make sure the files are added
+ // before we try to play.
+ if (!kapp->dcopClient()->call(mAppId, "Collection", "openFile(QStringList)", data,
+ replyType, replyData, true))
+ {
+ kdDebug(90200) << "Couldn't send drop to juk" << endl;
+ }
+
+ // Apparently we should auto-play?
+ QByteArray strData;
+ QDataStream strArg(strData, IO_WriteOnly);
+ strArg << *fileList.begin();
+
+ if (!kapp->dcopClient()->send(mAppId, "Player", "play(QString)", strData))
+ kdDebug(90200) << "Couldn't send play command to juk" << endl;
+ }
+}
+
+// ====================================================================================
+
+void JuKInterface::sliderStartDrag()
+{
+ mJuKTimer->stop();
+}
+
+void JuKInterface::sliderStopDrag()
+{
+ mJuKTimer->start(mTimerValue);
+}
+
+void JuKInterface::jumpToTime( int sec )
+{
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << sec;
+ // Used in JuK shipping with KDE < 3.3
+ //kapp->dcopClient()->send(mAppId, "Player", "setTime(int)", data);
+ kapp->dcopClient()->send(mAppId, "Player", "seek(int)", data);
+}
+
+void JuKInterface::playpause()
+{
+ if (!findRunningJuK())
+ startPlayer("juk");
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "playPause()", data);
+}
+
+void JuKInterface::stop()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "stop()", data);
+}
+
+void JuKInterface::next()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "forward()", data);
+}
+
+void JuKInterface::prev()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "back()", data);
+}
+
+void JuKInterface::volumeUp()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "volumeUp()", data);
+}
+
+void JuKInterface::volumeDown()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "Player", "volumeDown()", data);
+}
+
+const QString JuKInterface::getTrackTitle() const
+{
+ QString title;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "Player", "playingString()",data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> title;
+ return title;
+ }
+ }
+ return QString("");
+}
+
+// FIXME: what if we have a dcop app named, let's say, 'jukfrontend'?
+bool JuKInterface::findRunningJuK()
+{
+ QCStringList allApps = kapp->dcopClient()->registeredApplications();
+ QValueList<QCString>::const_iterator iterator;
+
+ for (iterator = allApps.constBegin(); iterator != allApps.constEnd(); ++iterator)
+ {
+ if ((*iterator).contains("juk",false))
+ {
+ mAppId = *iterator;
+ return true;
+ }
+ }
+ return false;
+}
+
+int JuKInterface::playingStatus()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "Player", "status()", data, replyType,
+ replyData))
+ {
+ int status = 0;
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> status;
+
+ if (status == 2)
+ return Playing;
+ else if (status == 1)
+ return Paused;
+ }
+
+ return Stopped;
+}
diff --git a/kicker-applets/mediacontrol/jukInterface.h b/kicker-applets/mediacontrol/jukInterface.h
new file mode 100644
index 0000000..fb7f9bb
--- /dev/null
+++ b/kicker-applets/mediacontrol/jukInterface.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ Interface to access JuK
+ -------------------
+ begin : Mon Jan 15 21:09:00 CEST 2001
+ copyright : (C) 2001-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef JUKINTERFACE_H
+#define JUKINTERFACE_H
+
+#include "playerInterface.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qtimer.h>
+
+class QProcess;
+
+class JuKInterface : public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ JuKInterface();
+ ~JuKInterface();
+
+ public slots:
+ void updateSlider();
+ void sliderStartDrag();
+ void sliderStopDrag();
+ void jumpToTime( int sec );
+ void playpause();
+ void stop();
+ void next();
+ void prev();
+ void volumeUp();
+ void volumeDown();
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+ const QString getTrackTitle() const;
+ int playingStatus();
+
+ private slots:
+ void myInit();
+ void appRegistered ( const QCString &appId );
+ void appRemoved ( const QCString &appId );
+ void jukIsReady();
+
+ private:
+ QTimer *mJuKTimer;
+ QProcess *mProc;
+ int mTimerValue;
+ QCString mAppId;
+
+ /**
+ * Tries to find a DCOP registered instance of juk
+ * Stores the name of the first found instance in appId
+ * @returns true is instance is found, false otherwise
+ */
+ bool findRunningJuK();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/kscdInterface.cpp b/kicker-applets/mediacontrol/kscdInterface.cpp
new file mode 100644
index 0000000..f7f7e90
--- /dev/null
+++ b/kicker-applets/mediacontrol/kscdInterface.cpp
@@ -0,0 +1,332 @@
+/***************************************************************************
+ Interface to access KsCD
+ -------------------
+ begin : Sat Dec 04 13:36:00 CET 2004
+ copyright : (C) 2004 by Michal Startek
+ adapted from JuK interface which is (C) 2001-2002 by Stefan Gehn
+ email : michal.startek@op.pl
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "kscdInterface.h"
+#include "kscdInterface.moc"
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <qstrlist.h>
+#include <kurldrag.h>
+#include <klocale.h>
+
+#define TIMER_FAST 250
+
+KsCDInterface::KsCDInterface() : PlayerInterface()
+{
+ mKsCDTimer = new QTimer(this, "mKsCDTimer");
+
+ connect(mKsCDTimer, SIGNAL(timeout()), SLOT(updateSlider()) );
+ kapp->dcopClient()->setNotifications ( true );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRegistered(const QCString&)),
+ SLOT(appRegistered(const QCString&)) );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
+ SLOT(appRemoved(const QCString&)));
+
+ QTimer::singleShot(0, this, SLOT(myInit()));
+}
+
+KsCDInterface::~KsCDInterface()
+{
+ kapp->dcopClient()->setNotifications(false);
+ delete mKsCDTimer;
+}
+
+void KsCDInterface::myInit()
+{
+ // Start the timer if KsCD is already running
+ // Needed if user adds applet while running KsCD
+ if (findRunningKsCD())
+ {
+ emit playerStarted();
+ mKsCDTimer->start(TIMER_FAST);
+ }
+ else
+ {
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void KsCDInterface::appRegistered(const QCString &appId)
+{
+ if((appId) == "kscd")
+ {
+ mAppId = appId;
+ emit playerStarted();
+ mKsCDTimer->start(TIMER_FAST);
+ }
+}
+
+void KsCDInterface::appRemoved(const QCString &appId)
+{
+ if ((appId) == "kscd")
+ {
+ // is there still another KsCD alive?
+ // Okay, KsCD does not allow multiple instances
+ // of it to run at the same time, but
+ // this can change.
+ if (findRunningKsCD())
+ return;
+ mKsCDTimer->stop();
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void KsCDInterface::updateSlider()
+{
+ // length/time in secs, -1 means "no playobject in kscd"
+ int len = -1;
+ int time = -1;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentTrackLength()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> len;
+ }
+
+ data = 0;
+ replyData = 0;
+ replyType = 0;
+
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentPosition()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> time;
+ }
+
+ if ( (time < 0) || (len < 0)) // KsCD isn't playing and thus returns -1
+ {
+ len = 0;
+ time = 0;
+ }
+ emit newSliderPosition(len,time);
+ emit playingStatusChanged(playingStatus());
+}
+
+// Drag-n-Drop stuff =================================================================
+// As far as I know there is currently no way to drag an AudioCD track to KsCD,
+// or even no application to drag AudioCD track from (not the KIO-wrapped track
+// path (audiocd:/...) like from Konqueror)
+
+void KsCDInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+ event->ignore();
+}
+
+void KsCDInterface::dropEvent(QDropEvent* event)
+{
+ event->ignore();
+}
+
+// ====================================================================================
+
+void KsCDInterface::sliderStartDrag()
+{
+ mKsCDTimer->stop();
+}
+
+void KsCDInterface::sliderStopDrag()
+{
+ mKsCDTimer->start(TIMER_FAST);
+}
+
+void KsCDInterface::jumpToTime(int sec)
+{
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << sec;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "jumpTo(int)", data);
+}
+
+void KsCDInterface::playpause()
+{
+ if (!findRunningKsCD())
+ startPlayer("kscd");
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "play()", data);
+}
+
+void KsCDInterface::stop()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "stop()", data);
+}
+
+void KsCDInterface::next()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "next()", data);
+}
+
+void KsCDInterface::prev()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "previous()", data);
+}
+
+void KsCDInterface::volumeUp()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "volumeUp()", data);
+}
+
+void KsCDInterface::volumeDown()
+{
+ QByteArray data;
+ kapp->dcopClient()->send(mAppId, "CDPlayer", "volumeDown()", data);
+}
+
+const QString KsCDInterface::getTrackTitle() const
+{
+ QString title, artist, album, result;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ // Get track title from KsCD...
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentTrackTitle()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> title;
+ }
+ }
+
+ // Album...
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentAlbum()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> album;
+ }
+ }
+
+ // Artist...
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentArtist()", data,
+ replyType, replyData))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> artist;
+ }
+ }
+
+ // And compose them into one string that will be displayed...
+ if(album.isEmpty())
+ {
+ if(artist.isEmpty())
+ {
+ result = title;
+ }
+ else // artist is non-empty
+ {
+ if(title.isEmpty())
+ {
+ result = artist;
+ }
+ else
+ {
+ result = i18n("artist - trackname", "%1 - %2").arg(artist, title);
+ }
+ }
+ }
+ else // album is non-empty
+ {
+ if(artist.isEmpty())
+ {
+ if(title.isEmpty())
+ {
+ result = album;
+ }
+ else
+ {
+ result = i18n("(album) - trackname", "(%1) - %2").arg(artist, title);
+ }
+ }
+ else // artist is non-empty
+ {
+ if(title.isEmpty())
+ {
+ result = i18n("artistname (albumname)", "%1 (%2)").arg(artist, album);
+ }
+ else
+ {
+ result = i18n("artistname (albumname) - trackname", "%1 (%2) - %3").arg(artist, album, title);
+ }
+ }
+ }
+
+ return result;
+}
+
+bool KsCDInterface::findRunningKsCD()
+{
+ QCStringList allApps = kapp->dcopClient()->registeredApplications();
+ QValueList<QCString>::const_iterator iterator;
+
+ for (iterator = allApps.constBegin(); iterator != allApps.constEnd(); ++iterator)
+ {
+ if ((*iterator) == "kscd")
+ {
+ mAppId = *iterator;
+ return true;
+ }
+ }
+ return false;
+}
+
+int KsCDInterface::playingStatus()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (kapp->dcopClient()->call(mAppId, "CDPlayer", "getStatus()", data, replyType,
+ replyData))
+ {
+ int status = 0;
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> status;
+
+ switch (status)
+ {
+ case 2:
+ return Playing;
+ case 4:
+ return Paused;
+ default:
+ return Stopped;
+ }
+ }
+ return Stopped;
+}
diff --git a/kicker-applets/mediacontrol/kscdInterface.h b/kicker-applets/mediacontrol/kscdInterface.h
new file mode 100644
index 0000000..0817b1e
--- /dev/null
+++ b/kicker-applets/mediacontrol/kscdInterface.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ Interface to access KsCD
+ -------------------
+ begin : Sat Dec 04 12:48:00 CET 2004
+ copyright : (C) 2004 by Michal Startek
+ adapted from JuK interface which is (C) 2001-2002 by Stefan Gehn
+ email : michal.startek@op.pl
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSCDINTERFACE_H
+#define KSCDINTERFACE_H
+
+#include "playerInterface.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qtimer.h>
+
+class KsCDInterface : public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ KsCDInterface();
+ ~KsCDInterface();
+
+ public slots:
+ void updateSlider();
+ void sliderStartDrag();
+ void sliderStopDrag();
+ void jumpToTime( int sec );
+ void playpause();
+ void stop();
+ void next();
+ void prev();
+ void volumeUp();
+ void volumeDown();
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+ const QString getTrackTitle() const;
+ int playingStatus();
+
+ private slots:
+ void myInit();
+ void appRegistered ( const QCString &appId );
+ void appRemoved ( const QCString &appId );
+
+ private:
+ QTimer *mKsCDTimer;
+ QCString mAppId;
+
+ /**
+ * Tries to find a DCOP registered instance of KsCD
+ * Stores the name of the first found instance in appId
+ * @returns true is instance is found, false otherwise
+ */
+ bool findRunningKsCD();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/mcslider.cpp b/kicker-applets/mediacontrol/mcslider.cpp
new file mode 100644
index 0000000..642d2e2
--- /dev/null
+++ b/kicker-applets/mediacontrol/mcslider.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+ mcslider.cpp - description
+ -------------------
+ begin : 20040410
+ copyright : (C) 2004 by Teemu Rytilahti
+ email : teemu.rytilahti@kde-fi.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <qpixmap.h>
+
+#include "mcslider.h"
+
+MCSlider::MCSlider( Orientation orientation, QWidget *parent, const char *name )
+ : QSlider( orientation, parent, name )
+{
+ setBackgroundOrigin(WidgetOrigin);
+ setBackground();
+}
+
+MCSlider::~MCSlider()
+{
+}
+
+// This is needed because KStyle draws slider background incorrectly.
+
+void MCSlider::setBackground()
+{
+ unsetPalette();
+
+ if (parentWidget()->paletteBackgroundPixmap())
+ {
+ QPixmap pm(width(), height());
+ pm.fill(parentWidget(), pos());
+ setPaletteBackgroundPixmap(pm);
+ }
+}
+
+void MCSlider::wheelEvent(QWheelEvent *e)
+{
+ if (e->orientation() == Horizontal)
+ return;
+
+ if (e->state() == ShiftButton)
+ {
+ if (e->delta() > 0)
+ emit volumeUp();
+ else
+ emit volumeDown();
+ e->accept();
+ }
+ else
+ {
+ QSlider::wheelEvent(e);
+ }
+}
+
+#include "mcslider.moc"
diff --git a/kicker-applets/mediacontrol/mcslider.h b/kicker-applets/mediacontrol/mcslider.h
new file mode 100644
index 0000000..9b11893
--- /dev/null
+++ b/kicker-applets/mediacontrol/mcslider.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ mcslider.h - description
+ -------------------
+ begin : 20040410
+ copyright : (C) 2004 by Teemu Rytilahti
+ email : teemu.rytilahti@kde-fi.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MCSLIDER_H
+#define MCSLIDER_H
+
+#include <qslider.h>
+
+class MCSlider : public QSlider
+{
+ Q_OBJECT
+
+ public:
+ MCSlider( Orientation orientation, QWidget *parent, const char *name = 0 );
+ ~MCSlider();
+ void setBackground();
+ private:
+ virtual void wheelEvent(QWheelEvent *e);
+ signals:
+ void volumeUp();
+ void volumeDown();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/mediacontrol.cpp b/kicker-applets/mediacontrol/mediacontrol.cpp
new file mode 100644
index 0000000..e69e0e0
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrol.cpp
@@ -0,0 +1,614 @@
+/***************************************************************************
+ main file of mediacontrol applet
+ -------------------
+ begin : Tue Apr 25 11:53:11 CEST 2000
+ copyright : (C) 2000-2005 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mediacontrol.h"
+#include "mediacontrol.moc"
+
+#include "mediacontrolconfig.h"
+#include "configfrontend.h"
+
+
+#include "noatunInterface.h"
+#include "xmmsInterface.h"
+#include "jukInterface.h"
+#include "amarokInterface.h"
+#include "mpdInterface.h"
+#include "kscdInterface.h"
+
+#include "mcslider.h"
+
+#include <qfile.h>
+#include <qdragobject.h>
+#include <qtooltip.h>
+#include <qstyle.h>
+#include <qslider.h>
+#include <qpainter.h>
+#include <qiconset.h>
+#include <kpopupmenu.h>
+
+#include <kapplication.h>
+#include <kipc.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <knotifyclient.h>
+#include <kbugreport.h>
+#include <dcopclient.h>
+
+const int MC_BUTTONSIZE = 20; // TODO: Might become dynamical for bigger panels
+const int NO_BUTTONS = 4;
+
+extern "C"
+{
+ KDE_EXPORT KPanelApplet *init( QWidget *parent, const QString &configFile)
+ {
+ KGlobal::locale()->insertCatalogue("mediacontrol");
+ return new MediaControl(configFile, KPanelApplet::Normal,
+ KPanelApplet::About | KPanelApplet::Preferences |
+ KPanelApplet::ReportBug, parent, "mediacontrol");
+ }
+}
+
+// =============================================================================
+
+class MediaControlToolTip : public QToolTip
+{
+ public:
+ MediaControlToolTip(QWidget *widget, PlayerInterface *pl_obj) :
+ QToolTip(widget), mWidget(widget), mPlayer(pl_obj) {}
+
+ protected:
+ virtual void maybeTip(const QPoint &pt)
+ {
+ QRect rc( mWidget->rect());
+ if (rc.contains(pt))
+ {
+ tip ( rc, mPlayer->getTrackTitle() );
+ }
+ }
+ private:
+ QWidget *mWidget;
+ PlayerInterface *mPlayer;
+};
+
+// =============================================================================
+
+MediaControl::MediaControl(const QString &configFile, Type t, int actions,
+ QWidget *parent, const char *name)
+ : DCOPObject("MediaControl"),
+ KPanelApplet(configFile, t, actions, parent, name),
+ mInstance(new KInstance("mediacontrol")),
+ mAboutData(new KAboutData("mediacontrol",
+ I18N_NOOP("MediaControl"),
+ MEDIACONTROL_VERSION,
+ I18N_NOOP("A small control-applet for various media players"),
+ KAboutData::License_GPL_V2,
+ "(c) 2001-2004 Stefan Gehn",
+ 0,
+ "http://metz.gehn.net"))
+{
+ setBackgroundOrigin(AncestorOrigin);
+ _player = 0L;
+ _prefsDialog = 0L;
+
+ _configFrontend = new ConfigFrontend(config());
+ // My own dcopclient
+ _dcopClient = new DCOPClient();
+ _dcopClient->registerAs("mediacontrol", false);
+
+ mAboutData->addAuthor("Stefan Gehn", I18N_NOOP("Main Developer"),
+ "metz@gehn.net", "http://metz.gehn.net");
+ mAboutData->addAuthor("Robbie Ward", I18N_NOOP("Initial About-Dialog"),
+ "wardy@robbieward.co.uk", "http://www.robbieward.co.uk");
+
+ mAboutData->addCredit("Sascha Hoffman", I18N_NOOP("Button-Pixmaps"),
+ "tisch.sush@gmx.de", 0);
+ mAboutData->addCredit("Christian Hoffman", I18N_NOOP("Button-Pixmaps"),
+ "tisch.crix@gmx.de", "http://www.crixensgfxcorner.de.vu/");
+ mAboutData->addCredit("Ulrik Mikaelsson", I18N_NOOP("Fix for Noatun-Support"),
+ "rawler@rsn.bth.se", 0);
+ mAboutData->addCredit("Anthony J Moulen", I18N_NOOP("Fix for Vertical Slider"),
+ "ajmoulen@moulen.org", 0);
+ mAboutData->addCredit("Teemu Rytilahti", I18N_NOOP("Volume Control Implementation"),
+ "teemu.rytilahti@kde-fi.org", 0);
+ mAboutData->addCredit("Jan Spitalnik", I18N_NOOP("Fix for JuK-Support"),
+ "honza@spitalnik.net", 0);
+ mAboutData->addCredit("William Robinson", I18N_NOOP("mpd-Support"),
+ "airbaggins@yahoo.co.uk", 0);
+
+ setAcceptDrops(true);
+
+ prev_button = new TrayButton (this, "PREVIOUS");
+ playpause_button = new TrayButton (this, "PLAYPAUSE");
+ stop_button = new TrayButton (this, "STOP");
+ next_button = new TrayButton (this, "NEXT");
+ time_slider = new MCSlider (QSlider::Horizontal, this, "time_slider" );
+ time_slider->setRange(0,0);
+ time_slider->setValue(0);
+ time_slider->setTracking( false );
+ time_slider->installEventFilter(this);
+
+ // request notification of changes in icon style
+ kapp->addKipcEventMask(KIPC::IconChanged);
+ connect(kapp, SIGNAL(iconChanged(int)), this, SLOT(slotIconChanged()));
+
+ reparseConfig();
+
+ rmbMenu = new KPopupMenu(this, "RMBMenu");
+ rmbMenu->insertTitle(i18n("MediaControl"), 0, 0);
+ rmbMenu->insertItem(SmallIcon("configure"), i18n("Configure MediaControl..."),
+ this, SLOT(preferences()));
+ rmbMenu->insertItem(i18n("About MediaControl"), this, SLOT(about()));
+}
+
+MediaControl::~MediaControl()
+{
+ delete _player;
+ delete _configFrontend;
+ delete _dcopClient;
+ KGlobal::locale()->removeCatalogue("mediacontrol");
+}
+
+// Drag-n-Drop stuff ===========================================================
+
+void MediaControl::dragEnterEvent(QDragEnterEvent* event)
+{
+ _player->dragEnterEvent(event); // Just pass dnd to the playerInterface
+}
+
+void MediaControl::dropEvent(QDropEvent* event)
+{
+ _player->dropEvent(event); // Just pass dnd to the playerInterface
+}
+
+// =============================================================================
+
+
+void MediaControl::setSliderPosition(int len ,int time)
+{
+ time_slider->blockSignals(true);
+ if(orientation() == Vertical)
+ time = len - time;
+
+ if (mLastLen != len)
+ time_slider->setRange(0,len);
+ mLastLen = len;
+
+ if (mLastTime != time)
+ time_slider->setValue(time);
+ mLastTime = time;
+
+ time_slider->blockSignals(false);
+}
+
+void MediaControl::enableAll()
+{
+ prev_button->setDisabled(false);
+ playpause_button->setDisabled(false);
+ QToolTip::remove(playpause_button);
+ stop_button->setDisabled(false);
+ next_button->setDisabled(false);
+ time_slider->setDisabled(false);
+}
+
+void MediaControl::disableAll()
+{
+ prev_button->setDisabled(true);
+ playpause_button->setDisabled(false);
+ QToolTip::add(playpause_button, i18n("Start the player"));
+ stop_button->setDisabled(true);
+ next_button->setDisabled(true);
+ time_slider->setDisabled(true);
+ if(_configFrontend->useCustomTheme()) {
+ QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/");
+ playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png")));
+ }
+ else
+ playpause_button->setIconSet(SmallIconSet("player_play"));
+}
+
+void MediaControl::slotPlayingStatusChanged(int status)
+{
+ if (mLastStatus == status)
+ return;
+
+ mLastStatus = status;
+ QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/");
+
+ switch (status)
+ {
+ case (PlayerInterface::Stopped):
+ case (PlayerInterface::Paused):
+ if(_configFrontend->useCustomTheme())
+ playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png")));
+ else
+ playpause_button->setIconSet(SmallIconSet("player_play"));
+ break;
+ case (PlayerInterface::Playing):
+ if(_configFrontend->useCustomTheme())
+ playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"pause.png")));
+ else
+ playpause_button->setIconSet(SmallIconSet("player_pause"));
+ break;
+ }
+}
+
+void MediaControl::slotIconChanged()
+{
+ if(!_configFrontend->useCustomTheme())
+ {
+ prev_button->setIconSet(SmallIconSet("player_start"));
+ if (_player->playingStatus() == PlayerInterface::Playing)
+ playpause_button->setIconSet(SmallIconSet("player_pause"));
+ else
+ playpause_button->setIconSet(SmallIconSet("player_play"));
+ stop_button->setIconSet(SmallIconSet("player_stop"));
+ next_button->setIconSet(SmallIconSet("player_end"));
+ }
+}
+
+// Dialogs =====================================================================
+
+void MediaControl::preferences()
+{
+ if ( _prefsDialog )
+ {
+ _prefsDialog->raise();
+ }
+ else
+ {
+ _prefsDialog = new MediaControlConfig ( _configFrontend );
+ connect ( _prefsDialog, SIGNAL(closing()),
+ this, SLOT(slotClosePrefsDialog()) );
+ connect ( _prefsDialog, SIGNAL(destroyed()),
+ this, SLOT(slotPrefsDialogClosing()) );
+ connect ( _prefsDialog, SIGNAL(configChanged()),
+ this, SLOT(slotConfigChanged()) );
+ }
+}
+
+void MediaControl::slotConfigChanged()
+{
+ reparseConfig();
+}
+
+void MediaControl::slotClosePrefsDialog()
+{
+ delete _prefsDialog;
+}
+
+void MediaControl::slotPrefsDialogClosing()
+{
+ if ( _prefsDialog )
+ _prefsDialog = 0L;
+}
+
+
+void MediaControl::about()
+{
+ KAboutApplication aboutDlg(mAboutData);
+ aboutDlg.exec();
+}
+
+
+void MediaControl::reportBug()
+{
+ KBugReport bugReport(this, true, mAboutData);
+ bugReport.exec();
+}
+
+
+// Fixing the orientation problem in qslider.
+void MediaControl::adjustTime(int time)
+{
+ if(orientation() == Vertical)
+ emit(newJumpToTime(mLastLen - time));
+ else
+ emit(newJumpToTime(time));
+}
+
+// Config Stuff ================================================================
+
+void MediaControl::reparseConfig()
+{
+// kdDebug(90200) << "reparseConfig();" << endl;
+ _configFrontend->reparseConfiguration();
+
+ if (_player != 0L) // make sure there is no player-object
+ {
+ _player->disconnect(); // disconnect from all things
+
+ time_slider->disconnect();
+ prev_button->disconnect();
+ playpause_button->disconnect();
+ stop_button->disconnect();
+ next_button->disconnect();
+
+ delete slider_tooltip; // tooltip depends on _player : delete it before _player gets deleted
+ slider_tooltip = 0L;
+
+ delete _player;
+ _player = 0L;
+ }
+
+ mLastLen = -1;
+ mLastTime = -1;
+ mLastStatus = -1;
+
+ QString playerString = _configFrontend->player();
+
+
+#ifdef HAVE_XMMS
+ if (playerString == "XMMS")
+ {
+ _player = new XmmsInterface ();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()*1000),
+ (_configFrontend->mouseWheelSpeed()*1000));
+ }
+ else
+#endif
+ if (playerString == "JuK")
+ {
+ _player = new JuKInterface();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()),
+ (_configFrontend->mouseWheelSpeed()));
+ }
+ else if (playerString == "Amarok")
+ {
+ _player = new AmarokInterface();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()),
+ (_configFrontend->mouseWheelSpeed()));
+ }
+ else if (playerString == "KsCD")
+ {
+ _player = new KsCDInterface();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()),
+ (_configFrontend->mouseWheelSpeed()));
+ }
+ else if (playerString == "mpd")
+ {
+ _player = new MpdInterface();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()),
+ (_configFrontend->mouseWheelSpeed()));
+ }
+ else // Fallback is Noatun
+ {
+ _player = new NoatunInterface();
+ time_slider->setSteps((_configFrontend->mouseWheelSpeed()),
+ (_configFrontend->mouseWheelSpeed()));
+ }
+
+ // this signal gets emitted by a playerInterface when the player's playtime changed
+ connect(_player, SIGNAL(newSliderPosition(int,int)),
+ this, SLOT(setSliderPosition(int,int)));
+
+ connect(_player, SIGNAL(playerStarted()), SLOT(enableAll()));
+ connect(_player, SIGNAL(playerStopped()), SLOT(disableAll()));
+ connect(_player, SIGNAL(playingStatusChanged(int)), SLOT(slotPlayingStatusChanged(int)));
+
+ // do we use our icons or the default ones from KDE?
+ if(_configFrontend->useCustomTheme())
+ {
+ // load theme
+ QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/");
+
+ // the user has to take care if all pixmaps are there, we only check for one of them
+ if (QFile(skindir+"play.png").exists())
+ {
+ prev_button->setIconSet(SmallIconSet(locate("data",skindir+"prev.png")));
+ if (_player->playingStatus() == PlayerInterface::Playing)
+ playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png")));
+ else
+ playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"pause.png")));
+ stop_button->setIconSet(SmallIconSet(locate("data",skindir+"stop.png")));
+ next_button->setIconSet(SmallIconSet(locate("data",skindir+"next.png")));
+ }
+ else // icon-theme is invalid or not there
+ {
+ KNotifyClient::event(winId(), KNotifyClient::warning,
+ i18n("There was trouble loading theme %1. Please choose" \
+ " a different theme.").arg(skindir));
+
+ // default to kde-icons, they have to be installed :)
+ slotIconChanged();
+
+ // and open prefs-dialog
+ preferences();
+ }
+ }
+ else // KDE default-icons, assuming that these icons exist!
+ {
+ // sets icons from kde
+ slotIconChanged();
+ }
+
+ slider_tooltip = new MediaControlToolTip(time_slider, _player);
+
+ connect(prev_button, SIGNAL(clicked()), _player, SLOT(prev()));
+ connect(playpause_button, SIGNAL(clicked()), _player, SLOT(playpause()));
+ connect(stop_button, SIGNAL(clicked()), _player, SLOT(stop()));
+ connect(next_button, SIGNAL(clicked()), _player, SLOT(next()));
+
+ connect(time_slider, SIGNAL(sliderPressed()), _player, SLOT(sliderStartDrag()));
+ connect(time_slider, SIGNAL(sliderReleased()), _player, SLOT(sliderStopDrag()));
+ connect(time_slider, SIGNAL(valueChanged(int)), this, SLOT(adjustTime(int)));
+ connect(time_slider, SIGNAL(volumeUp()), _player, SLOT(volumeUp()));
+ connect(time_slider, SIGNAL(volumeDown()), _player, SLOT(volumeDown()));
+ connect(this, SIGNAL(newJumpToTime(int)), _player, SLOT(jumpToTime(int)));
+}
+
+// Widget Placement ===================================================================
+
+// kicker wants to know what width we need for a given height
+// (this is called when being a HORIZONTAL panel)
+int MediaControl::widthForHeight(int height) const
+{
+// kdDebug(90200) << "kicker height: " << height << endl;
+// kdDebug(90200) << "slider needs: " << time_slider->minimumSizeHint().height() << endl;
+
+ // slider height + button height
+ if ( height >= (time_slider->minimumSizeHint().height()+MC_BUTTONSIZE) )
+ { // slider UNDER buttons
+ // (5 * button width + spaces between them);
+ return (4*MC_BUTTONSIZE+10);
+ }
+ else
+ { // slider ASIDE buttons
+ // (5 * button width + spaces between them) * 2 [size of slider = size of all buttons]
+ return ((4*MC_BUTTONSIZE+10)*2);
+ }
+}
+
+// kicker wants to know what height we need for a given width
+// (this is called when being a VERTICAL panel)
+int MediaControl::heightForWidth(int width) const
+{
+// kdDebug(90200) << "kicker width: " << width << endl;
+
+ // slider height + button height
+ if ( width >= (time_slider->minimumSizeHint().width()+MC_BUTTONSIZE) )
+ { // slider ASIDE icons
+ // (5 * button width + spaces between them);
+ return (4*MC_BUTTONSIZE+10);
+ }
+ else
+ { // slider UNDER buttons
+ // (5 * button width + spaces between them) * 2
+ // because the size of the slider = the size of all buttons
+ return ((4*MC_BUTTONSIZE+10)*2);
+ }
+}
+
+void MediaControl::mousePressEvent(QMouseEvent* e)
+{
+ if (e->button() == QMouseEvent::RightButton)
+ rmbMenu->popup(e->globalPos());
+}
+
+bool MediaControl::eventFilter(QObject *, QEvent *e)
+{
+ if (e->type() == QEvent::MouseButtonPress)
+ {
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ if (me->button() == QMouseEvent::RightButton)
+ {
+ rmbMenu->popup(me->globalPos());
+ return true;
+ }
+ }
+ return false;
+}
+
+void MediaControl::paletteChange( const QPalette& )
+{
+ time_slider->setBackground();
+}
+
+void MediaControl::moveEvent( QMoveEvent* )
+{
+ time_slider->setBackground();
+}
+
+// Danger: Weird Code ahead! ;))
+void MediaControl::resizeEvent( QResizeEvent* )
+{
+// kdDebug(90200) << "resizeEvent()" << endl;
+ int w = width();
+ int h = height();
+ if ( orientation() == Vertical )
+ { // ====== VERTICAL =================================================
+ time_slider->setOrientation(QSlider::Vertical);
+ int slider_width = time_slider->minimumSizeHint().width();
+ // some styles need more space for sliders than avilable in very small panels :(
+ if ( slider_width > w ) slider_width = w;
+
+ // that width would be needed to put the slider aside the buttons
+ if ( w >= (slider_width+MC_BUTTONSIZE) )
+ { // Slider ASIDE icons
+ int applet_space = (w - (slider_width+MC_BUTTONSIZE) ) / 2;
+ if ( applet_space < 0 )
+ applet_space = 0;
+
+ prev_button->setGeometry ( applet_space, 1, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ playpause_button->setGeometry ( applet_space, 3+1*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ stop_button->setGeometry ( applet_space, 5+2*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ next_button->setGeometry ( applet_space, 7+3*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ time_slider->setGeometry ( applet_space+MC_BUTTONSIZE, 1, slider_width, NO_BUTTONS*MC_BUTTONSIZE+8 );
+ }
+ else
+ { // Slider UNDER Icons
+ int slider_space = (w - slider_width)/2;
+ int button_space = (w - MC_BUTTONSIZE)/2;
+
+ prev_button->setGeometry ( button_space, 1 , MC_BUTTONSIZE, MC_BUTTONSIZE );
+ playpause_button->setGeometry ( button_space, 3+1*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ stop_button->setGeometry ( button_space, 5+2*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ next_button->setGeometry ( button_space, 7+3*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ time_slider->setGeometry ( slider_space, 9+4*MC_BUTTONSIZE, slider_width, NO_BUTTONS*MC_BUTTONSIZE+8 );
+ }
+ }
+ else // ====== HORIZONTAL ===============================================
+ {
+ time_slider->setOrientation(QSlider::Horizontal);
+ int slider_height = time_slider->minimumSizeHint().height();
+ // some styles need more space for sliders than avilable in very small panels :(
+ if ( slider_height > h ) slider_height = h;
+
+ // that h would be needed to put the slider under the buttons
+ if ( h >= (slider_height+MC_BUTTONSIZE) )
+ { // Slider UNDER icons
+ int applet_space = (h-(slider_height+MC_BUTTONSIZE))/2;
+ if ( applet_space < 0 )
+ applet_space = 0;
+
+ prev_button->setGeometry ( 1 , applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ playpause_button->setGeometry ( 3+MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ stop_button->setGeometry ( 5+2*MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ next_button->setGeometry ( 7+3*MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ time_slider->setGeometry ( 1, applet_space + MC_BUTTONSIZE, NO_BUTTONS*MC_BUTTONSIZE+8, slider_height );
+ }
+ else
+ { // Slider ASIDE Icons
+ int slider_space = (h - slider_height)/2;
+ int button_space = (h - MC_BUTTONSIZE)/2;
+
+ prev_button->setGeometry ( 1 , button_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ playpause_button->setGeometry ( 3+1*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ stop_button->setGeometry ( 5+2*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ next_button->setGeometry ( 7+3*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE );
+ time_slider->setGeometry ( 9+4*MC_BUTTONSIZE, slider_space, NO_BUTTONS*MC_BUTTONSIZE+8, slider_height );
+ }
+ }
+}
+
+// Our Button ========================================================================
+
+TrayButton::TrayButton(QWidget* parent, const char* name)
+ : SimpleButton (parent, name)
+{
+ setBackgroundMode(PaletteBackground);
+ setBackgroundOrigin(AncestorOrigin);
+}
+
+void TrayButton::setIconSet(const QIconSet &iconSet)
+{
+ setPixmap(iconSet.pixmap(QIconSet::Automatic, QIconSet::Normal, QIconSet::On));
+}
+
diff --git a/kicker-applets/mediacontrol/mediacontrol.desktop b/kicker-applets/mediacontrol/mediacontrol.desktop
new file mode 100644
index 0000000..b7ed81d
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrol.desktop
@@ -0,0 +1,121 @@
+[Desktop Entry]
+Type=Plugin
+Name=Media Control
+Name[ar]=التحكم بلوسائط
+Name[bg]=Медия контрол
+Name[ca]=Control multimèdia
+Name[cs]=Ovládání médií
+Name[da]=Mediekontrol
+Name[de]=Medienkontrolle
+Name[el]=Έλεγχος μέσων
+Name[eo]=Mediostirilo
+Name[es]=Control de medios
+Name[et]=Meediakontroll
+Name[eu]=Multimedia kontrola
+Name[fa]=کنترل رسانه
+Name[fi]=Medianhallinta
+Name[fr]=Télécommande multimédia
+Name[gl]=Controlo Multimédia
+Name[he]=בקרת מדיה
+Name[hr]=Upravljanje medijima
+Name[hu]=Médiavezérlő
+Name[is]=Margmiðlunarstjórn
+Name[it]=Controllo multimediale
+Name[ja]=メディアコントロール
+Name[ka]=მედიის მმართველი
+Name[kk]=Ойнатқышты басқару
+Name[km]=វត្ថុ​បញ្ជា​មេឌៀ​
+Name[lt]=Media valdymas
+Name[mk]=Контрола на мултимедија
+Name[nb]=Mediastyring
+Name[nds]=Medienkuntrull
+Name[ne]=मिडिया नियन्त्रण
+Name[nn]=Mediekontroll
+Name[pa]=ਮੀਡਿਆ ਕੰਟਰੋਲ
+Name[pl]=Zarządzanie mediami
+Name[pt]=Controlo Multimédia
+Name[pt_BR]=Controle de Mídia
+Name[ru]=Управление мультимедиа
+Name[sk]=Ovládanie médií
+Name[sl]=Nadzor predvajalnikov
+Name[sr]=Контрола медија
+Name[sr@Latn]=Kontrola medija
+Name[sv]=Mediakontroll
+Name[tr]=Medya Kontrolü
+Name[uk]=Керування медіа
+Name[uz]=Media-pleyer boshqaruvi
+Name[uz@cyrillic]=Медиа-плейер бошқаруви
+Name[vi]=Điều khiển nhạc/ảnh
+Name[zh_CN]=媒体控制
+Name[zh_TW]=媒體控制
+Comment=Applet to control mediaplayers
+Comment[af]=Miniprogram na kontrole media spelers
+Comment[ar]=بريمج للتحكم بمشغلات الوسائط
+Comment[az]=Konsol medya çalğıcıları appleti
+Comment[bg]=Лесно и универсално управление на плеъри за мултимедийни файлове
+Comment[bs]=Applet za kontrolu mediaplayera
+Comment[ca]=Applet controlador dels reproductors multimèdia
+Comment[cs]=Applet pro ovládání přehrávačů médií
+Comment[cy]=Rhaglennig i reoli chwaraewyr cyfryngau
+Comment[da]=Program til at kontrollere medieafspillere
+Comment[de]=Programm zur Steuerung von Medienabspielern
+Comment[el]=Μικροεφαρμογή για τον έλεγχο αναπαραγωγέων μέσων
+Comment[eo]=Aplikaĵo por stiri medioludilojn
+Comment[es]=Aplicación integrada para controlar el reproductor de medios
+Comment[et]=Meediafailide mängijate juhtimise aplett
+Comment[eu]=Multimedia erreproduzigailuak kontrolatzeko appleta
+Comment[fa]=برنامکی برای کنترل پخش‌کننده‌های رسانه
+Comment[fi]=Mediasoittimien hallintasovelma
+Comment[fo]=Smáforrit at stýra mediuspælarum við
+Comment[fr]=Applet pour commander les lecteurs multimédia
+Comment[fy]=Applet om mediaspilers te bestjoeren
+Comment[ga]=Feidhmchláirín chun seinnteoirí meán a rialú
+Comment[gl]=Unha applet para controlar os reprodutores multimédia
+Comment[he]=יישומן לשליטה בנגני מדיה
+Comment[hi]=मीडिया प्लेयर्स को नियंत्रित करने का ऐपलेट
+Comment[hr]=Aplet za upravljanje multimedijskim programima
+Comment[hu]=Médialejátszók vezérlésére szolgáló kisalkalmazás
+Comment[is]=Íforrit til að stjórna margmiðlunarspilurum
+Comment[it]=Applet per controllare i lettori multimediali
+Comment[ja]=メディアプレーヤを操作するアプレット
+Comment[ka]=მედია დამკვრელის მართვის აპლეტი
+Comment[kk]=Мультимедиа ойнатқыштарды басқару апплеті
+Comment[km]=អាប់ភ្លេត​ដើម្បី​ត្រួតពិនិត្យ​​កម្មវិធី​ចាក់​មេឌៀ
+Comment[lt]=Media grotuvų valdymo įskiepis
+Comment[lv]=Aplets mēdijuatskaņotāju vadībai
+Comment[mk]=Аплет за контрола на медијаплеери
+Comment[ms]=Aplet untuk kawal pemain media
+Comment[mt]=Applet biex tikkontrolla players ta' media
+Comment[nb]=Miniprogram for å styre multimediaspillere
+Comment[nds]=Lüttprogramm för't Stüern vun Medienafspelers
+Comment[ne]=मिडिया प्लेएर नियन्त्रण गर्ने एप्लेट
+Comment[nl]=Applet om mediaspelers te besturen
+Comment[nn]=Applet for kontroll av mediespelarar
+Comment[pa]=ਮੀਡਿਆ ਪਲੇਅਰ ਕੰਟਰੋਲ ਲਈ ਐਪਲਿਟ
+Comment[pl]=Programik do zarządzania mediami
+Comment[pt]=Uma 'applet' para controlar os reprodutores multimédia
+Comment[pt_BR]=Mini-aplicativo para controlar tocadores de mídia
+Comment[ro]=Miniaplicaţie pentru controlul redării multimedia
+Comment[ru]=Аплет для управления медиаплеерами
+Comment[sk]=Applet pre ovládanie prehrávačov médií
+Comment[sl]=Vstavek za nadzor večpredstavnih predvajalnikov
+Comment[sr]=Аплет за контролисање медија плејера
+Comment[sr@Latn]=Aplet za kontrolisanje medija plejera
+Comment[sv]=Miniprogram för att kontrollera mediaspelare
+Comment[ta]=ஊடக வாசிப்பான்களை கட்டுப்படுத்துவதற்கு சிறுநிரல்
+Comment[tg]=Аплет барои идоракунии медиаплеерҳо
+Comment[th]=แอพเพล็ตควบคุมโปรแกรมเล่นสื่อ
+Comment[tr]=Ortam yürütücülerini kontrol etmek için bir programcık
+Comment[uk]=Аплет для керування програвачами мультимедіа
+Comment[uz]=Media-pleyerlarni boshqarish uchun applet
+Comment[uz@cyrillic]=Медиа-плейерларни бошқариш учун апплет
+Comment[ven]=Apulete yau langula tshitambi tsha media
+Comment[vi]=Tiểu dụng điều khiển bộ phát nhạc/ảnh
+Comment[xh]=Applet ukulawula usasazo lwabadlali
+Comment[zh_CN]=控制媒体播放器的小程序
+Comment[zh_TW]=控制媒體播放器的小程式
+Comment[zu]=i Applet ukulawula abadlali bolawulo laphakathi
+X-KDE-Library=mediacontrol_panelapplet
+X-KDE-UniqueApplet=true
+Icon=multimedia
+X-KDE-ParentApp=kicker
diff --git a/kicker-applets/mediacontrol/mediacontrol.h b/kicker-applets/mediacontrol/mediacontrol.h
new file mode 100644
index 0000000..f5a6e5e
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrol.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ main file of mediacontrol applet
+ -------------------
+ begin : Tue Apr 25 11:53:11 CEST 2000
+ copyright : (C) 2000-2005 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MEDIACONTROL_H
+#define MEDIACONTROL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <klocale.h>
+#include <kpanelapplet.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kaboutdata.h>
+#include <kaboutapplication.h>
+
+#include <qpalette.h>
+
+// used everywhere :)
+#include <qstring.h>
+
+#include "playerInterface.h"
+#include "configfrontend.h"
+#include "mediacontroliface.h"
+#include "simplebutton.h"
+
+#define MEDIACONTROL_VERSION "0.4"
+
+class MCSlider;
+class KPopupMenu;
+class KInstance;
+class MediaControlConfig;
+class KAboutData;
+class MediaControlToolTip;
+
+// =============================================================================
+
+class TrayButton : public SimpleButton
+{
+ Q_OBJECT
+
+ public:
+ TrayButton(QWidget* parent, const char* name);
+ virtual ~TrayButton() {}
+ void setIconSet(const QIconSet &iconSet);
+};
+
+// =============================================================================
+
+class MediaControl : public KPanelApplet, virtual public MediaControlIface
+{
+ Q_OBJECT
+
+ public:
+ MediaControl(const QString&, Type, int ,QWidget * = 0, const char * = 0);
+ virtual ~MediaControl();
+
+ int widthForHeight(int height) const;
+ int heightForWidth(int width) const;
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+ virtual void reparseConfig();
+
+ public slots:
+ void about();
+ void preferences();
+ void reportBug();
+
+ private:
+ KInstance *mInstance;
+ KAboutData *mAboutData;
+ DCOPClient *_dcopClient;
+ PlayerInterface *_player;
+ ConfigFrontend *_configFrontend;
+ MediaControlConfig *_prefsDialog;
+ TrayButton *prev_button; // GoTo Previous Playlist-Item
+ TrayButton *playpause_button; // Start/Pause playing
+ TrayButton *stop_button; // Stop the music
+ TrayButton *next_button; // GoTo Next Playlist-Item
+ MCSlider *time_slider;
+ int mLastLen, mLastTime, mLastStatus;
+ KPopupMenu *rmbMenu;
+
+ virtual void mousePressEvent(QMouseEvent* e);
+ virtual void moveEvent(QMoveEvent*);
+ virtual void paletteChange(const QPalette&);
+ virtual void resizeEvent(QResizeEvent*);
+ virtual bool eventFilter(QObject *watched, QEvent *e);
+
+ friend class MediaControlToolTip;
+ MediaControlToolTip *slider_tooltip;
+
+ private slots:
+ void setSliderPosition(int len, int time);
+ void slotIconChanged();
+ void disableAll();
+ void enableAll();
+ void slotClosePrefsDialog();
+ void slotPrefsDialogClosing();
+ void slotConfigChanged();
+ void adjustTime(int);
+ void slotPlayingStatusChanged(int status);
+
+ signals:
+ void newJumpToTime(int);
+};
+#endif
diff --git a/kicker-applets/mediacontrol/mediacontrolconfig.cpp b/kicker-applets/mediacontrol/mediacontrolconfig.cpp
new file mode 100644
index 0000000..b146ff1
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrolconfig.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ mediacontrol configuration dialog
+ -------------------
+ begin : forgot :/
+ copyright : (C) 2000-2005 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+
+ code-skeleton taken from knewsticker which is
+ Copyright (c) Frerich Raabe <raabe@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mediacontrolconfig.h"
+#include "mediacontrolconfigwidget.h"
+
+#include <qdir.h>
+#include <qcheckbox.h>
+#include <qlistbox.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <klistbox.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kstandarddirs.h>
+
+MediaControlConfig::MediaControlConfig( ConfigFrontend *cfg, QWidget *parent, const char* name)
+: KDialogBase( parent, name, false, i18n("MediaControl"), Ok | Apply | Cancel, Ok, false )
+{
+ _configFrontend = cfg;
+ if (!_configFrontend) // emergency!!!
+ return;
+
+ _child = new MediaControlConfigWidget(this);
+ setMainWidget ( _child );
+
+#ifdef HAVE_XMMS
+ _child->playerListBox->insertItem("XMMS");
+#endif
+ _child->playerListBox->insertItem("Noatun");
+ _child->playerListBox->insertItem("Amarok");
+ _child->playerListBox->insertItem("JuK");
+ _child->playerListBox->insertItem("mpd");
+ _child->playerListBox->insertItem("KsCD");
+
+ _child->themeListBox->clear();
+ // fill with available skins
+ KGlobal::dirs()->addResourceType("themes", KStandardDirs::kde_default("data") + "mediacontrol");
+ QStringList list = KGlobal::dirs()->resourceDirs("themes");
+ for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
+ readSkinDir(*it);
+
+ connect(_child->mWheelScrollAmount, SIGNAL(valueChanged(int)), SLOT(slotConfigChanged()));
+ connect(_child->playerListBox, SIGNAL(selectionChanged()), SLOT(slotConfigChanged()));
+ connect(_child->themeListBox, SIGNAL(selectionChanged()), SLOT(slotConfigChanged()));
+ connect(_child->themeListBox, SIGNAL(selectionChanged(QListBoxItem *)), SLOT(slotChangePreview(QListBoxItem *)));
+ connect(_child->mUseThemes, SIGNAL(toggled(bool)), SLOT(slotConfigChanged()) );
+ connect(_child->mUseThemes, SIGNAL(toggled(bool)), SLOT(slotUseThemesToggled(bool)) );
+
+ load();
+ show();
+
+ enableButtonApply ( false ); // apply id disabled until something changed
+}
+
+void MediaControlConfig::readSkinDir( const QString &dir )
+{
+ QDir directory( dir );
+ if (!directory.exists())
+ return;
+
+ const QFileInfoList *list = directory.entryInfoList();
+ QFileInfoListIterator it(*list);
+
+ while ( it.current() )
+ {
+ // append directory-name to our theme-listbox
+ if ( QFile(it.current()->absFilePath()+"/play.png").exists() )
+ _child->themeListBox->insertItem ( it.current()->baseName(), -1 );
+ ++it;
+ }
+}
+
+// ============================================================================
+
+void MediaControlConfig::load()
+{
+ // find the playerstring from config in the playerlist and select it if found
+ QListBoxItem *item = 0;
+
+ item = _child->playerListBox->findItem( _configFrontend->player() );
+ if ( item )
+ _child->playerListBox->setCurrentItem ( item );
+ else
+ _child->playerListBox->setCurrentItem( 0 );
+
+ // reset item to a proper state
+ item=0;
+
+ _child->mWheelScrollAmount->setValue( _configFrontend->mouseWheelSpeed() );
+
+ // Select the used Theme
+ item = _child->themeListBox->findItem( _configFrontend->theme() );
+ if ( item )
+ _child->themeListBox->setCurrentItem( item );
+ else
+ _child->themeListBox->setCurrentItem( 0 );
+
+
+ bool ison = _configFrontend->useCustomTheme();
+ _child->mUseThemes->setChecked( ison );
+ slotUseThemesToggled( ison );
+}
+
+void MediaControlConfig::save()
+{
+// kdDebug(90200) << "MediaControlConfig::save()" << endl;
+ for ( int it=0 ; it <= _child->playerListBox->numRows(); ++it )
+ {
+ if ( _child->playerListBox->isSelected(it) )
+ {
+ _configFrontend->setPlayer ( _child->playerListBox->text(it) );
+ }
+ }
+
+ _configFrontend->setMouseWheelSpeed ( _child->mWheelScrollAmount->value() );
+
+ for ( int it=0 ; it <= _child->themeListBox->numRows(); ++it )
+ {
+ if ( _child->themeListBox->isSelected(it) )
+ {
+ _configFrontend->setTheme ( _child->themeListBox->text(it) );
+ }
+ }
+
+ _configFrontend->setUseCustomTheme( _child->mUseThemes->isChecked() );
+
+ emit configChanged();
+}
+
+void MediaControlConfig::slotApply()
+{
+ save();
+ enableButtonApply(false);
+}
+
+void MediaControlConfig::slotOk()
+{
+ save();
+ emit closing();
+}
+
+void MediaControlConfig::slotCancel()
+{
+ emit closing();
+}
+
+void MediaControlConfig::slotConfigChanged()
+{
+ enableButtonApply ( true );
+}
+
+void MediaControlConfig::slotChangePreview(QListBoxItem *item)
+{
+ QString skindir = item->text();
+ _child->previewPrev->setIconSet(SmallIconSet(locate("themes",skindir+"/prev.png")));
+ _child->previewPlay->setIconSet(SmallIconSet(locate("themes",skindir+"/play.png")));
+ _child->previewPause->setIconSet(SmallIconSet(locate("themes",skindir+"/pause.png")));
+ _child->previewStop->setIconSet(SmallIconSet(locate("themes",skindir+"/stop.png")));
+ _child->previewNext->setIconSet(SmallIconSet(locate("themes",skindir+"/next.png")));
+}
+
+void MediaControlConfig::slotUseThemesToggled(bool on)
+{
+ _child->themeListBox->setEnabled(on);
+ _child->previewGroupBox->setEnabled(on);
+}
+
+#include "mediacontrolconfig.moc"
diff --git a/kicker-applets/mediacontrol/mediacontrolconfig.h b/kicker-applets/mediacontrol/mediacontrolconfig.h
new file mode 100644
index 0000000..5869722
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrolconfig.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ mediacontrol configuration dialog
+ -------------------
+ begin : forgot :/
+ copyright : (C) 2000-2005 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MEDIACONTROLCONFIG_H
+#define MEDIACONTROLCONFIG_H
+
+#include "configfrontend.h"
+#include <kdialogbase.h>
+
+class MediaControlConfigWidget;
+class ConfigFrontend;
+class KConfig;
+
+class MediaControlConfig: public KDialogBase
+{
+Q_OBJECT
+public:
+ MediaControlConfig(ConfigFrontend *cfg, QWidget *parent = 0, const char* name = "MediaControlConfig");
+
+ void readSkinDir(const QString &dir);
+ void load();
+ void save();
+
+signals:
+ void closing();
+ void configChanged();
+
+protected slots:
+ void slotConfigChanged();
+ void slotChangePreview(QListBoxItem *item);
+ void slotUseThemesToggled(bool);
+ virtual void slotApply();
+ virtual void slotOk();
+ virtual void slotCancel();
+
+private:
+ ConfigFrontend *_configFrontend;
+ MediaControlConfigWidget *_child;
+};
+#endif // MEDIACONTROLCONFIG_H
diff --git a/kicker-applets/mediacontrol/mediacontrolconfigwidget.ui b/kicker-applets/mediacontrol/mediacontrolconfigwidget.ui
new file mode 100644
index 0000000..9f5c662
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontrolconfigwidget.ui
@@ -0,0 +1,374 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>MediaControlConfigWidget</class>
+<comment>Preferences-Dialog for MediaControl </comment>
+<author>Stefan Gehn &lt;metz@gehn.net&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MediaControlConfigWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>318</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string></string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tabGeneral</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;General</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>gbMediaPlayer</cstring>
+ </property>
+ <property name="title">
+ <string>Media-Player</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KListBox" row="0" column="0">
+ <property name="name">
+ <cstring>playerListBox</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Select the multimedia player you are using from this list.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lmousewheelscrollingamount</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Wheel scroll seconds:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mWheelScrollAmount</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>mWheelScrollAmount</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the number of lines a mousewheel will scroll in the current file.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>themes</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Themes</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>mUseThemes</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Use themes</string>
+ </property>
+ </widget>
+ <widget class="KListBox">
+ <item>
+ <property name="text">
+ <string>default</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>themeListBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>previewGroupBox</cstring>
+ </property>
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Shows you how the selected theme will look</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <widget class="QToolButton" row="0" column="0">
+ <property name="name">
+ <cstring>previewPrev</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&lt;</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="0" column="1">
+ <property name="name">
+ <cstring>previewPlay</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&gt;</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="0" column="2">
+ <property name="name">
+ <cstring>previewPause</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>o</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="0" column="3">
+ <property name="name">
+ <cstring>previewStop</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>O</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="0" column="4">
+ <property name="name">
+ <cstring>previewNext</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>18</width>
+ <height>18</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ </hbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<includes>
+ <include location="local" impldecl="in implementation"></include>
+ <include location="local" impldecl="in declaration"></include>
+ <include location="global" impldecl="in declaration">knuminput.h</include>
+ <include location="global" impldecl="in declaration">klistview.h</include>
+ <include location="global" impldecl="in declaration">klistbox.h</include>
+</includes>
+<signals>
+ <signal>toggled(bool)</signal>
+</signals>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistbox.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>klistbox.h</includehint>
+</includehints>
+</UI>
diff --git a/kicker-applets/mediacontrol/mediacontroliface.h b/kicker-applets/mediacontrol/mediacontroliface.h
new file mode 100644
index 0000000..5a47fb3
--- /dev/null
+++ b/kicker-applets/mediacontrol/mediacontroliface.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ dcopinterface for mediacontrol
+ mainly used to be informed about new settings
+ -------------------
+ begin : Mon Jan 15 21:09:00 MEZ 2001
+ copyright : (C) 2001 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MEDIACONTROLIFACE_H
+#define MEDIACONTROLIFACE_H
+
+#include <dcopobject.h>
+
+class MediaControlIface : virtual public DCOPObject
+{
+ K_DCOP
+
+ k_dcop:
+ virtual void reparseConfig() = 0;
+};
+
+#endif // MEDIACONTROLIFACE_H
diff --git a/kicker-applets/mediacontrol/mpdInterface.cpp b/kicker-applets/mediacontrol/mpdInterface.cpp
new file mode 100644
index 0000000..8027f82
--- /dev/null
+++ b/kicker-applets/mediacontrol/mpdInterface.cpp
@@ -0,0 +1,585 @@
+/***************************************************************************
+ Interface to access mpd
+ -------------------
+ begin : Tue Apr 19 18:31:00 BST 2005
+ copyright : (C) 2005 by William Robinson
+ email : airbaggins@yahoo.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mpdInterface.h"
+
+#include <cstring>
+
+#include <qregexp.h>
+
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kurldrag.h>
+
+MpdInterface::MpdInterface()
+: PlayerInterface()
+, sock()
+, sock_mutex()
+, messagebox_mutex()
+, hostname("localhost")
+, port(6600)
+, slider_timer(0)
+, reconnect_timer(0)
+{
+ connect(&sock, SIGNAL(error(int)), this, SLOT(connectionError(int)));
+ connect(&sock, SIGNAL(error(int)), this, SLOT(stopSliderClock()));
+
+ connect(&sock, SIGNAL(connected()), this, SLOT(startSliderClock()));
+ connect(&sock, SIGNAL(connected()), this, SLOT(stopReconnectClock()));
+ connect(&sock, SIGNAL(connected()), this, SLOT(connected()));
+
+ connect(&sock, SIGNAL(connectionClosed()), this, SLOT(stopSliderClock()));
+ connect(&sock, SIGNAL(connectionClosed()), this, SLOT(startReconnectClock()));
+ connect(&sock, SIGNAL(connectionClosed()), this, SIGNAL(playerStopped()));
+
+ reconnect();
+}
+
+MpdInterface::~MpdInterface()
+{
+}
+
+void MpdInterface::startSliderClock()
+{
+ if (!slider_timer)
+ {
+ //kdDebug(90200) << "Starting slider clock\n";
+ slider_timer = startTimer(SLIDER_TIMER_INTERVAL);
+ }
+}
+
+void MpdInterface::stopSliderClock()
+{
+ if (slider_timer)
+ {
+ //kdDebug(90200) << "Stopping slider clock\n";
+ killTimer(slider_timer);
+ slider_timer=0;
+ }
+}
+void MpdInterface::startReconnectClock()
+{
+ if (!reconnect_timer)
+ {
+ //kdDebug(90200) << "Starting Reconnect clock\n";
+ reconnect_timer = startTimer(RECONNECT_TIMER_INTERVAL);
+ }
+}
+
+void MpdInterface::stopReconnectClock()
+{
+ if (reconnect_timer)
+ {
+ //kdDebug(90200) << "Stopping Reconnect clock\n";
+ killTimer(reconnect_timer);
+ reconnect_timer=0;
+ }
+}
+
+
+void MpdInterface::timerEvent(QTimerEvent* te)
+{
+ if (te->timerId() == slider_timer) updateSlider();
+ else if (te->timerId() == reconnect_timer) reconnect();
+}
+
+
+void MpdInterface::reconnect() const
+{
+ if (sock.state()==QSocket::Idle)
+ {
+ sock_mutex.tryLock();
+ //kdDebug(90200) << "Connecting to " << hostname.latin1() << ":" << port << "...\n";
+ sock.connectToHost(hostname,port);
+ }
+}
+
+void MpdInterface::connected()
+{
+ if (fetchOk()) // unlocks
+ {
+ //kdDebug(90200) << "Connected ok\n";
+ emit playerStarted();
+ emit playingStatusChanged(playingStatus());
+ }
+ else
+ {
+ //kdDebug(90200) << "Connection error\n";
+ emit playerStopped();
+ }
+}
+
+void MpdInterface::connectionError(int e)
+{
+ sock_mutex.unlock();
+ emit playerStopped();
+ QString message;
+ if (messagebox_mutex.tryLock())
+ {
+ switch (e)
+ {
+ case QSocket::ErrConnectionRefused:
+ message=i18n("Connection refused to %1:%2.\nIs mpd running?").arg(hostname).arg(port);
+ break;
+ case QSocket::ErrHostNotFound:
+ message=i18n("Host '%1' not found.").arg(hostname);
+ break;
+ case QSocket::ErrSocketRead:
+ message=i18n("Error reading socket.");
+ break;
+ default:
+ message=i18n("Connection error");
+ break;
+ }
+ // :TODO: KSimpleConfig to prompt for hostname/port values ?
+ if (KMessageBox::warningContinueCancel( 0, message,
+ i18n("MediaControl MPD Error"),
+ i18n("Reconnect"))==KMessageBox::Continue)
+ {
+ startReconnectClock();
+ }
+ else
+ {
+ stopReconnectClock();
+ }
+ messagebox_mutex.unlock();
+ }
+}
+
+bool MpdInterface::dispatch(const char* cmd) const
+{
+ if (sock.state()==QSocket::Connected && sock_mutex.tryLock())
+ {
+ long cmd_len=strlen(cmd);
+ //kdDebug(90200) << "sending: " << cmd;
+ long written=sock.writeBlock(cmd,cmd_len);
+ if (written==cmd_len)
+ {
+ //kdDebug(90200) << "All bytes written\n";
+ sock.flush();
+ return true;
+ }
+ else
+ {
+ //kdDebug(90200) << written << '/' << cmd_len << " bytes written\n";
+ }
+ sock.flush();
+ }
+ return false;
+}
+
+bool MpdInterface::fetchLine(QString& res) const
+{
+ QString errormessage;
+ while (sock.state()==QSocket::Connected)
+ {
+ if (!sock.canReadLine())
+ {
+ sock.waitForMore(20);
+ continue;
+ }
+ res=sock.readLine().stripWhiteSpace();
+ //kdDebug(90200) << "received: " << res.latin1() << "\n";
+ if (res.startsWith("OK"))
+ {
+ sock_mutex.unlock();
+ // if theres a message and we clear it and there's no other messagebox
+ if (!errormessage.isEmpty()
+ && dispatch("clearerror\n") && fetchOk()
+ && messagebox_mutex.tryLock())
+ {
+ KMessageBox::error(0,errormessage,i18n("MediaControl MPD Error"));
+ messagebox_mutex.unlock();
+ }
+ return false;
+ }
+ else if (res.startsWith("ACK"))
+ {
+ sock_mutex.unlock();
+ return false;
+ }
+ else if (res.startsWith("error: "))
+ {
+ errormessage=i18n(res.latin1());
+ }
+ else
+ {
+ return true;
+ }
+ }
+ sock_mutex.unlock();
+ return false;
+}
+
+bool MpdInterface::fetchOk() const
+{
+ QString res;
+ while (fetchLine(res)) { }
+ if (res.startsWith("OK"))
+ return true;
+ else
+ return false;
+}
+
+void MpdInterface::updateSlider()
+{
+ //kdDebug(90200) << "update slider\n";
+ if (!dispatch("status\n")) return;
+
+ QString res;
+ QRegExp time_re("time: (\\d+):(\\d+)");
+ while(fetchLine(res))
+ {
+ if (res.startsWith("state: "))
+ {
+ if (res.endsWith("play"))
+ {
+ emit playingStatusChanged(Playing);
+ }
+ else if (res.endsWith("pause"))
+ {
+ emit playingStatusChanged(Paused);
+ }
+ else
+ {
+ emit playingStatusChanged(Stopped);
+ }
+ }
+ else if (time_re.search(res)>=0)
+ {
+ QStringList timeinfo=time_re.capturedTexts();
+ timeinfo.pop_front();
+ int elapsed_seconds=timeinfo.first().toInt();
+ timeinfo.pop_front();
+ int total_seconds=timeinfo.first().toInt();
+ emit newSliderPosition(total_seconds,elapsed_seconds);
+ }
+ }
+}
+
+void MpdInterface::sliderStartDrag()
+{
+ stopSliderClock();
+}
+
+void MpdInterface::sliderStopDrag()
+{
+ startSliderClock();
+}
+
+void MpdInterface::jumpToTime(int sec)
+{
+ reconnect();
+ if (!dispatch("status\n")) return;
+
+ long songid=-1;
+
+ QString res;
+ QRegExp songid_re("songid: (\\d+)");
+ while(fetchLine(res))
+ {
+ if (songid_re.search(res)>=0)
+ {
+ QStringList songidinfo=songid_re.capturedTexts();
+ songidinfo.pop_front();
+ songid=songidinfo.first().toInt();
+ }
+ }
+
+ if (songid>-1)
+ {
+ if (dispatch(QString("seekid %1 %2\n").arg(songid).arg(sec).latin1()))
+ {
+ fetchOk(); // unlocks
+ }
+ }
+}
+
+void MpdInterface::playpause()
+{
+ reconnect();
+ if (playingStatus()==Stopped ? dispatch("play\n") : dispatch("pause\n"))
+ {
+ fetchOk();
+ }
+}
+
+void MpdInterface::stop()
+{
+ reconnect();
+ if (dispatch("stop\n")) fetchOk();
+}
+
+void MpdInterface::next()
+{
+ reconnect();
+ if (dispatch("next\n")) fetchOk();
+}
+
+void MpdInterface::prev()
+{
+ reconnect();
+ if (dispatch("previous\n")) fetchOk();
+}
+
+
+void MpdInterface::changeVolume(int delta)
+{
+ reconnect();
+
+ if (!dispatch("status\n")) return;
+
+ int volume=-1;
+
+ QString res;
+ QRegExp volume_re("volume: (\\d+)");
+ while(fetchLine(res))
+ {
+ if (volume_re.search(res)>=0)
+ {
+ QStringList info=volume_re.capturedTexts();
+ info.pop_front();
+ volume=info.first().toInt();
+ }
+ }
+
+ if (volume>-1)
+ {
+ volume+=delta;
+ if (volume<0) volume=0;
+ if (volume>100) volume=100;
+ if (dispatch(QString("setvol %1\n").arg(volume).latin1()))
+ {
+ fetchOk();
+ }
+ }
+}
+
+void MpdInterface::volumeUp()
+{
+ reconnect();
+ changeVolume(5);
+}
+
+void MpdInterface::volumeDown()
+{
+ reconnect();
+ changeVolume(-5);
+}
+
+void MpdInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+void MpdInterface::dropEvent(QDropEvent* event)
+{
+ reconnect();
+
+ KURL::List list;
+ if (KURLDrag::decode(event, list))
+ {
+ if (list.count()==1) // just one file dropped
+ {
+ // check to see if its in the playlist already
+ if (dispatch("playlistid\n"))
+ {
+ long songid=-1;
+ QString file;
+ QString res;
+ while(fetchLine(res))
+ {
+ QRegExp file_re("file: (.+)");
+ QRegExp id_re("Id: (.+)");
+ if (file.isEmpty() && file_re.search(res)>=0)
+ {
+ QStringList info=file_re.capturedTexts();
+ info.pop_front();
+ // if the dropped file ends with the same name, record it
+ if (list.front().path().endsWith(info.first()))
+ {
+ file=info.first().toInt();
+ }
+ }
+ else if (!file.isEmpty() && id_re.search(res)>=0)
+ {
+ // when we have the file, pick up the id (file scomes first)
+ QStringList info=id_re.capturedTexts();
+ info.pop_front();
+ songid=info.first().toInt();
+ fetchOk(); // skip to the end
+ break;
+ }
+ }
+
+ // found song, so lets play it
+ if (songid>-1)
+ {
+ if (dispatch((QString("playid %1\n").arg(songid)).latin1()))
+ {
+ if (fetchOk()) list.pop_front();
+ return;
+ }
+ }
+ }
+ }
+
+ // now if we have got this far, just try to add any files
+ for (KURL::List::const_iterator i = list.constBegin(); i!=list.constEnd(); ++i)
+ {
+ if ((*i).isLocalFile())
+ {
+ QStringList path=QStringList::split("/",(*i).path());
+
+ while (!path.empty())
+ {
+ if (dispatch((QString("add \"")
+ +path.join("/").replace("\"","\\\"")
+ +QString("\"\n")).latin1()))
+ {
+ if (fetchOk()) break;
+ }
+ path.pop_front();
+ }
+ }
+ else
+ {
+ // :TODO: can handle http:// urls but maybe should check port or something
+ }
+ }
+ }
+}
+
+const QString MpdInterface::getTrackTitle() const
+{
+ QString result;
+
+ reconnect();
+
+ if (!dispatch("status\n")) return result;
+
+ long songid=-1;
+ QString res;
+ while(fetchLine(res))
+ {
+ QRegExp songid_re("songid: (\\d+)");
+ if (songid_re.search(res)>=0)
+ {
+ QStringList songidinfo=songid_re.capturedTexts();
+ songidinfo.pop_front();
+ songid=songidinfo.first().toInt();
+ }
+ }
+
+ if (!(songid>-1)) return result;
+
+ if (!dispatch(QString("playlistid %1\n").arg(songid).latin1()))
+ return result;
+
+ QString artist;
+ QString album;
+ QString title;
+ QString track;
+ QString file;
+ while(fetchLine(res))
+ {
+ QRegExp artist_re("Artist: (.+)");
+ QRegExp album_re("Album: (.+)");
+ QRegExp track_re("Album: (.+)");
+ QRegExp title_re("Title: (.+)");
+ QRegExp file_re("file: (.+)");
+ if (artist_re.search(res)>=0)
+ {
+ QStringList info=artist_re.capturedTexts();
+ info.pop_front();
+ artist=info.first();
+ }
+ else if (album_re.search(res)>=0)
+ {
+ QStringList info=album_re.capturedTexts();
+ info.pop_front();
+ album=info.first();
+ }
+ else if (title_re.search(res)>=0)
+ {
+ QStringList info=title_re.capturedTexts();
+ info.pop_front();
+ title=info.first();
+ }
+ else if (track_re.search(res)>=0)
+ {
+ QStringList info=track_re.capturedTexts();
+ info.pop_front();
+ track=info.first();
+ }
+ else if (file_re.search(res)>=0)
+ {
+ QStringList info=file_re.capturedTexts();
+ info.pop_front();
+ file=info.first();
+ }
+ }
+
+ if (!artist.isEmpty())
+ {
+ if (!title.isEmpty())
+ return artist.append(" - ").append(title);
+ else if (!album.isEmpty())
+ return artist.append(" - ").append(album);
+ }
+ else if (!title.isEmpty())
+ {
+ if (!album.isEmpty())
+ return album.append(" - ").append(title);
+ else
+ return title;
+ }
+ else if (!album.isEmpty())
+ {
+ if (!track.isEmpty())
+ return album.append(" - ").append(track);
+ else
+ return album;
+ }
+ return i18n("No tags: %1").arg(file);
+}
+
+int MpdInterface::playingStatus()
+{
+ //kdDebug(90200) << "looking up playing status\n";
+ if (!dispatch("status\n")) return Stopped;
+
+ PlayingStatus status=Stopped;
+ QString res;
+ while(fetchLine(res))
+ {
+ if (res.startsWith("state: "))
+ {
+ if (res.endsWith("play")) status=Playing;
+ else if (res.endsWith("pause")) status=Paused;
+ else status=Stopped;
+ }
+ }
+
+ return status;
+}
+
+#include "mpdInterface.moc"
diff --git a/kicker-applets/mediacontrol/mpdInterface.h b/kicker-applets/mediacontrol/mpdInterface.h
new file mode 100644
index 0000000..d891586
--- /dev/null
+++ b/kicker-applets/mediacontrol/mpdInterface.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ this is the class to access mpd from
+ -------------------
+ begin : Tue Apr 19 18:31:00 BST 2005
+ copyright : (C) 2005 by William Robinson
+ email : airbaggins@yahoo.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef MPDINTERFACE_H
+#define MPDINTERFACE_H
+
+#include "playerInterface.h"
+#include <qtimer.h>
+#include <klocale.h>
+#include <qsocket.h>
+#include <qmutex.h>
+
+class MpdInterface
+: public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ MpdInterface();
+ ~MpdInterface();
+
+ public slots:
+ virtual void updateSlider();
+ virtual void sliderStartDrag();
+ virtual void sliderStopDrag();
+ virtual void jumpToTime(int sec);
+ virtual void playpause();
+ virtual void stop();
+ virtual void next();
+ virtual void prev();
+ virtual void volumeUp();
+ virtual void volumeDown();
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dropEvent(QDropEvent* event);
+ virtual const QString getTrackTitle() const;
+ virtual int playingStatus();
+
+ void changeVolume(int delta);
+
+ void connectionError(int e);
+ void connected();
+
+ void startSliderClock();
+ void stopSliderClock();
+
+ void startReconnectClock();
+ void stopReconnectClock();
+
+
+ protected:
+ virtual void timerEvent(QTimerEvent* te);
+
+ private:
+ mutable QSocket sock;
+ mutable QMutex sock_mutex;
+
+ mutable QMutex messagebox_mutex;
+
+ QString hostname;
+ int port;
+
+ static const int SLIDER_TIMER_INTERVAL = 500; // ms
+ int slider_timer;
+
+ static const int RECONNECT_TIMER_INTERVAL = 5000; // ms
+ int reconnect_timer;
+
+ /** starts connecting and returns, if not connected already. */
+ void reconnect() const;
+
+ /** this locks the sock sock_mutex. remember to unlock it. */
+ bool dispatch(const char* cmd) const;
+
+ /** fetches everything from the sock to the OK and unlocks the mutex.
+ returns true if OK, false on anything else. */
+ bool fetchOk() const;
+
+ /** fetches a line and returns true, or false if OK or ACK (end of
+ message). Will unlock the sock_mutex on the end of message. */
+ bool fetchLine(QString& res) const;
+};
+
+#endif // MPDINTERFACE_H
diff --git a/kicker-applets/mediacontrol/noatunInterface.cpp b/kicker-applets/mediacontrol/noatunInterface.cpp
new file mode 100644
index 0000000..f6cdfc8
--- /dev/null
+++ b/kicker-applets/mediacontrol/noatunInterface.cpp
@@ -0,0 +1,283 @@
+/***************************************************************************
+ Interface to access Noatun
+ -------------------
+ begin : Mon Jan 15 21:09:00 CEST 2001
+ copyright : (C) 2000-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "noatunInterface.h"
+#include "noatunInterface.moc"
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <qstrlist.h>
+#include <kurldrag.h>
+
+#define TIMER_FAST 250
+
+NoatunInterface::NoatunInterface() : PlayerInterface()
+{
+ mTimerValue = TIMER_FAST;
+ mNoatunTimer = new QTimer(this, "mNoatunTimer");
+
+ connect(mNoatunTimer, SIGNAL(timeout()), SLOT(updateSlider()));
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRegistered(const QCString&)),
+ SLOT(appRegistered(const QCString&)) );
+
+ connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
+ SLOT(appRemoved(const QCString&)));
+
+ kapp->dcopClient()->setNotifications(true);
+ QTimer::singleShot(0, this, SLOT(myInit()));
+}
+
+NoatunInterface::~NoatunInterface()
+{
+ kapp->dcopClient()->setNotifications(false);
+}
+
+void NoatunInterface::myInit()
+{
+ // Start the timer if noatun is already running
+ // Needed if user adds applet while running noatun
+ if ( findRunningNoatun() )
+ {
+ emit playerStarted();
+ mNoatunTimer->start(mTimerValue);
+ }
+ else
+ {
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void NoatunInterface::appRegistered(const QCString &appId)
+{
+ if (appId.contains("noatun",false))
+ {
+ mAppId = appId;
+ emit playerStarted();
+ mNoatunTimer->start(mTimerValue);
+ }
+}
+
+void NoatunInterface::appRemoved(const QCString &appId)
+{
+ if (appId.contains("noatun",false))
+ {
+ // is there still another noatun alive?
+ if (findRunningNoatun())
+ return;
+ mNoatunTimer->stop();
+ emit playerStopped();
+ emit newSliderPosition(0,0);
+ }
+}
+
+void NoatunInterface::updateSlider()
+{
+ // length/time in msecs, -1 means "no playobject in noatun"
+ int len, time;
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (!kapp->dcopClient()->call(mAppId, "Noatun", "length()", data, replyType, replyData, false, 200))
+ {
+ //kdDebug(90200) << "mediacontrol: DCOP communication Error" << endl;
+ // -2 is an internal errornumber, might be used later
+ len = -2;
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> len;
+ }
+ else
+ {
+ //kdDebug(90200) << "mediacontrol: unexpected type of DCOP-reply" << endl;
+ // -3 is an internal errornumber, might be used later
+ len = -3;
+ }
+ }
+
+ data = 0;
+ replyData = 0;
+ replyType = 0;
+
+ if (!kapp->dcopClient()->call(mAppId, "Noatun", "position()", data,
+ replyType, replyData, false, 200))
+ {
+ //kdDebug(90200) << "mediacontrol: DCOP communication error" << endl;
+ time = -2;
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> time;
+ }
+ else
+ {
+ //kdDebug(90200) << "mediacontrol: unexpected type of DCOP-reply" << endl;
+ time = -3;
+ }
+ }
+
+ if ((time < 0) || (len < 0)) // Noatun isn't playing and thus returns -1
+ {
+ len = 0;
+ time = 0;
+ }
+ emit newSliderPosition(len/1000,time/1000);
+ emit playingStatusChanged(playingStatus());
+}
+
+int NoatunInterface::playingStatus()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+
+ if (!kapp->dcopClient()->call(mAppId, "Noatun", "state()", data, replyType,
+ replyData, false, 200))
+ {
+ return Stopped;
+ }
+ else
+ {
+ int status = 0;
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ reply >> status;
+
+ if (status == 1)
+ return Paused;
+ else if (status == 2)
+ return Playing;
+ else
+ return Stopped;
+ }
+}
+
+
+// Drag-n-Drop stuff =================================================================
+
+void NoatunInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+// kdDebug(90200) << "NoatunInterface::dragEnterEvent()" << endl;
+ event->accept(KURLDrag::canDecode(event));
+}
+
+void NoatunInterface::dropEvent(QDropEvent* event)
+{
+// kdDebug(90200) << "NoatunInterface::dropEvent()" << endl;
+ KURL::List list;
+ if (KURLDrag::decode(event, list))
+ {
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << list.toStringList() << false;
+ kapp->dcopClient()->send(mAppId, "Noatun", "addFile(QStringList,bool)", data);
+ }
+}
+
+// ====================================================================================
+
+void NoatunInterface::sliderStartDrag()
+{
+ mNoatunTimer->stop();
+}
+
+void NoatunInterface::sliderStopDrag()
+{
+ mNoatunTimer->start(mTimerValue);
+}
+
+void NoatunInterface::jumpToTime(int sec)
+{
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << (sec*1000); // noatun wants milliseconds
+ kapp->dcopClient()->send(mAppId, "Noatun", "skipTo(int)", data);
+}
+
+void NoatunInterface::playpause()
+{
+ if (!findRunningNoatun())
+ startPlayer("noatun");
+ kapp->dcopClient()->send(mAppId, "Noatun", "playpause()", QString::null);
+}
+
+void NoatunInterface::stop()
+{
+ kapp->dcopClient()->send(mAppId, "Noatun", "stop()", QString::null);
+}
+
+void NoatunInterface::next()
+{
+ // fastForward() is noatun from kde2
+ //kapp->dcopClient()->send("noatun", "Noatun", "fastForward()", QString::null);
+ kapp->dcopClient()->send(mAppId, "Noatun", "forward()", QString::null);
+}
+
+void NoatunInterface::prev()
+{
+ kapp->dcopClient()->send(mAppId, "Noatun", "back()", QString::null);
+}
+
+void NoatunInterface::volumeUp()
+{
+ kapp->dcopClient()->send(mAppId, "Noatun", "volumeDown()", QString::null);
+}
+
+void NoatunInterface::volumeDown()
+{
+ kapp->dcopClient()->send(mAppId, "Noatun", "volumeUp()", QString::null);
+}
+
+const QString NoatunInterface::getTrackTitle() const
+{
+ QString title("");
+ QByteArray data, replyData;
+ QCString replyType;
+ if (kapp->dcopClient()->call(mAppId, "Noatun", "title()", data, replyType,
+ replyData, false, 200))
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ reply >> title;
+ }
+ return title;
+}
+
+bool NoatunInterface::findRunningNoatun()
+{
+ // FIXME: what if we have a dcop app named, let's say, 'noatunfrontend'?
+ QCStringList allApps = kapp->dcopClient()->registeredApplications();
+ QValueList<QCString>::const_iterator iterator;
+
+ for (iterator = allApps.constBegin(); iterator != allApps.constEnd(); ++iterator)
+ {
+ if ((*iterator).contains("noatun", false))
+ {
+ mAppId = *iterator;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/kicker-applets/mediacontrol/noatunInterface.h b/kicker-applets/mediacontrol/noatunInterface.h
new file mode 100644
index 0000000..99191b5
--- /dev/null
+++ b/kicker-applets/mediacontrol/noatunInterface.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ Interface to access Noatun
+ -------------------
+ begin : Mon Jan 15 21:09:00 MEZ 2001
+ copyright : (C) 2001-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef NOATUNINTERFACE_H
+#define NOATUNINTERFACE_H
+
+#include "playerInterface.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qtimer.h>
+
+class NoatunInterface : public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ NoatunInterface();
+ ~NoatunInterface();
+
+ public slots:
+ void updateSlider();
+ void sliderStartDrag();
+ void sliderStopDrag();
+ void jumpToTime(int sec);
+ void playpause();
+ void stop();
+ void next();
+ void prev();
+ void volumeUp();
+ void volumeDown();
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+ const QString getTrackTitle() const;
+ void appRegistered(const QCString &appId);
+ void appRemoved(const QCString &appId);
+ int playingStatus();
+
+ void myInit(void);
+
+ private:
+ QTimer *mNoatunTimer;
+ int mTimerValue;
+ QCString mAppId;
+
+ /**
+ * Tries to find a DCOP registered instance of Noatun
+ * Stores the name of the first found instance in appId
+ * @returns true is instance is found, false otherwise
+ */
+ bool findRunningNoatun();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/pics/Makefile.am b/kicker-applets/mediacontrol/pics/Makefile.am
new file mode 100644
index 0000000..85ecf9b
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/Makefile.am
@@ -0,0 +1,2 @@
+# Files to install
+SUBDIRS= blueish default fulldecent
diff --git a/kicker-applets/mediacontrol/pics/blueish/Makefile.am b/kicker-applets/mediacontrol/pics/blueish/Makefile.am
new file mode 100644
index 0000000..5f7d372
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/Makefile.am
@@ -0,0 +1,4 @@
+# Files to install
+pics_DATA = next.png pause.png play.png prev.png stop.png
+# This is where it will all be installed
+picsdir = $(kde_datadir)/mediacontrol/blueish
diff --git a/kicker-applets/mediacontrol/pics/blueish/next.png b/kicker-applets/mediacontrol/pics/blueish/next.png
new file mode 100644
index 0000000..260a033
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/next.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/blueish/pause.png b/kicker-applets/mediacontrol/pics/blueish/pause.png
new file mode 100644
index 0000000..4c62dae
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/pause.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/blueish/play.png b/kicker-applets/mediacontrol/pics/blueish/play.png
new file mode 100644
index 0000000..6e85050
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/play.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/blueish/prev.png b/kicker-applets/mediacontrol/pics/blueish/prev.png
new file mode 100644
index 0000000..d4d8640
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/prev.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/blueish/stop.png b/kicker-applets/mediacontrol/pics/blueish/stop.png
new file mode 100644
index 0000000..05b1d33
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/blueish/stop.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/default/Makefile.am b/kicker-applets/mediacontrol/pics/default/Makefile.am
new file mode 100644
index 0000000..0ab094e
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/Makefile.am
@@ -0,0 +1,4 @@
+# Files to install
+pics_DATA = next.png pause.png play.png prev.png stop.png
+# This is where it will all be installed
+picsdir = $(kde_datadir)/mediacontrol/default
diff --git a/kicker-applets/mediacontrol/pics/default/next.png b/kicker-applets/mediacontrol/pics/default/next.png
new file mode 100644
index 0000000..7c47f76
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/next.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/default/pause.png b/kicker-applets/mediacontrol/pics/default/pause.png
new file mode 100644
index 0000000..6f51172
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/pause.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/default/play.png b/kicker-applets/mediacontrol/pics/default/play.png
new file mode 100644
index 0000000..789065f
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/play.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/default/prev.png b/kicker-applets/mediacontrol/pics/default/prev.png
new file mode 100644
index 0000000..addcfc9
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/prev.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/default/stop.png b/kicker-applets/mediacontrol/pics/default/stop.png
new file mode 100644
index 0000000..e2bf48d
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/default/stop.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/Makefile.am b/kicker-applets/mediacontrol/pics/fulldecent/Makefile.am
new file mode 100644
index 0000000..6892b15
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/Makefile.am
@@ -0,0 +1,4 @@
+# Files to install
+pics_DATA = next.png pause.png play.png prev.png stop.png
+# This is where it will all be installed
+picsdir = $(kde_datadir)/mediacontrol/fulldecent
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/README b/kicker-applets/mediacontrol/pics/fulldecent/README
new file mode 100644
index 0000000..17fadd0
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/README
@@ -0,0 +1,12 @@
+#
+# "Sketchy" mediacontrol theme
+# (c) 2003 Will Entriken "Full Decent"
+#
+
+This theme is was drawn freehand with GIMP, the original layered gimp file
+is included as an XCF file for your modifying pleasure.
+
+The artwork is released under the terms of the GNU GPL version 2.
+The license is available at http://www.gnu.org
+
+Hope you enjoy! \ No newline at end of file
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/next.png b/kicker-applets/mediacontrol/pics/fulldecent/next.png
new file mode 100644
index 0000000..e833248
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/next.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/pause.png b/kicker-applets/mediacontrol/pics/fulldecent/pause.png
new file mode 100644
index 0000000..2fb8572
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/pause.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/play.png b/kicker-applets/mediacontrol/pics/fulldecent/play.png
new file mode 100644
index 0000000..836c46e
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/play.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/prev.png b/kicker-applets/mediacontrol/pics/fulldecent/prev.png
new file mode 100644
index 0000000..7e24e76
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/prev.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/source.xcf b/kicker-applets/mediacontrol/pics/fulldecent/source.xcf
new file mode 100644
index 0000000..712236a
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/source.xcf
Binary files differ
diff --git a/kicker-applets/mediacontrol/pics/fulldecent/stop.png b/kicker-applets/mediacontrol/pics/fulldecent/stop.png
new file mode 100644
index 0000000..dc26b5f
--- /dev/null
+++ b/kicker-applets/mediacontrol/pics/fulldecent/stop.png
Binary files differ
diff --git a/kicker-applets/mediacontrol/playerInterface.cpp b/kicker-applets/mediacontrol/playerInterface.cpp
new file mode 100644
index 0000000..cc388c0
--- /dev/null
+++ b/kicker-applets/mediacontrol/playerInterface.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ this is the abstract class to access a player from
+ -------------------
+ begin : Mon Jan 15 21:09:00 CEST 2001
+ copyright : (C) 2001-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "playerInterface.h"
+#include "playerInterface.moc"
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+PlayerInterface::PlayerInterface() { } // Constructor
+PlayerInterface::~PlayerInterface() { } // Destructor
+
+void PlayerInterface::startPlayer(const QString &desktopname)
+{
+ if (KApplication::startServiceByDesktopName(desktopname, QStringList(),
+ 0, 0, 0, "", false) > 0)
+ {
+ KMessageBox::error(0, i18n("Could not start media player."));
+ }
+}
diff --git a/kicker-applets/mediacontrol/playerInterface.h b/kicker-applets/mediacontrol/playerInterface.h
new file mode 100644
index 0000000..aa4701e
--- /dev/null
+++ b/kicker-applets/mediacontrol/playerInterface.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ this is the abstract class to access a player from
+ -------------------
+ begin : Mon Jan 15 21:09:00 MEZ 2001
+ copyright : (C) 2001 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERINTERFACE_H
+#define PLAYERINTERFACE_H
+
+#include <qobject.h>
+#include <qdragobject.h>
+
+class PlayerInterface : public QObject
+{
+ Q_OBJECT
+ public:
+ PlayerInterface();
+ virtual ~PlayerInterface();
+
+ enum PlayingStatus { Stopped=0, Playing, Paused };
+
+ public slots:
+ virtual void updateSlider()=0; // gets called on timer-timeout
+ virtual void sliderStartDrag()=0;
+ virtual void sliderStopDrag()=0;
+ virtual void jumpToTime( int msec )=0;
+ virtual void playpause()=0;
+ virtual void stop()=0;
+ virtual void next()=0;
+ virtual void prev()=0;
+ virtual void volumeUp()=0;
+ virtual void volumeDown()=0;
+ virtual void dragEnterEvent(QDragEnterEvent* event)=0;
+ virtual void dropEvent(QDropEvent* event)=0;
+ virtual const QString getTrackTitle() const=0;
+ virtual int playingStatus()=0;
+
+ void startPlayer(const QString &desktopname);
+
+ signals:
+ void newSliderPosition(int, int);
+ void playingStatusChanged(int);
+ void playerStarted();
+ void playerStopped();
+};
+#endif
diff --git a/kicker-applets/mediacontrol/simplebutton.cpp b/kicker-applets/mediacontrol/simplebutton.cpp
new file mode 100644
index 0000000..9daa926
--- /dev/null
+++ b/kicker-applets/mediacontrol/simplebutton.cpp
@@ -0,0 +1,256 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <nhasan@kde.org>
+ Copyright (C) 2004-2005 Aaron J. Seigo <aseigo@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "simplebutton.h"
+
+#include <qpainter.h>
+#include <qstyle.h>
+
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kdialog.h>
+#include <kglobalsettings.h>
+#include <kiconeffect.h>
+#include <kicontheme.h>
+#include <kipc.h>
+#include <kstandarddirs.h>
+
+SimpleButton::SimpleButton(QWidget *parent, const char *name)
+ : QButton(parent, name),
+ m_highlight(false),
+ m_orientation(Qt::Horizontal)
+{
+ setBackgroundOrigin( AncestorOrigin );
+
+ connect( kapp, SIGNAL( settingsChanged( int ) ),
+ SLOT( slotSettingsChanged( int ) ) );
+ connect( kapp, SIGNAL( iconChanged( int ) ),
+ SLOT( slotIconChanged( int ) ) );
+
+ kapp->addKipcEventMask( KIPC::SettingsChanged );
+ kapp->addKipcEventMask( KIPC::IconChanged );
+
+ slotSettingsChanged( KApplication::SETTINGS_MOUSE );
+}
+
+void SimpleButton::setPixmap(const QPixmap &pix)
+{
+ QButton::setPixmap(pix);
+ generateIcons();
+ update();
+}
+
+void SimpleButton::setOrientation(Qt::Orientation orientation)
+{
+ m_orientation = orientation;
+ update();
+}
+
+QSize SimpleButton::sizeHint() const
+{
+ const QPixmap* pm = pixmap();
+
+ if (!pm)
+ return QButton::sizeHint();
+ else
+ return QSize(pm->width() + KDialog::spacingHint(), pm->height() + KDialog::spacingHint());
+}
+
+QSize SimpleButton::minimumSizeHint() const
+{
+ const QPixmap* pm = pixmap();
+
+ if (!pm)
+ return QButton::minimumSizeHint();
+ else
+ return QSize(pm->width(), pm->height());
+}
+
+void SimpleButton::drawButton( QPainter *p )
+{
+ drawButtonLabel(p);
+}
+
+void SimpleButton::drawButtonLabel( QPainter *p )
+{
+ if (!pixmap())
+ {
+ return;
+ }
+
+ QPixmap pix = isEnabled() ? (m_highlight? m_activeIcon : m_normalIcon) : m_disabledIcon;
+
+ if (isOn() || isDown())
+ {
+ pix = pix.convertToImage().smoothScale(pix.width() - 2,
+ pix.height() - 2);
+ }
+
+ int h = height();
+ int w = width();
+ int ph = pix.height();
+ int pw = pix.width();
+ int margin = KDialog::spacingHint();
+ QPoint origin(margin / 2, margin / 2);
+
+ if (ph < (h - margin))
+ {
+ origin.setY((h - ph) / 2);
+ }
+
+ if (pw < (w - margin))
+ {
+ origin.setX((w - pw) / 2);
+ }
+
+ p->drawPixmap(origin, pix);
+}
+
+void SimpleButton::generateIcons()
+{
+ if (!pixmap())
+ {
+ return;
+ }
+
+ QImage image = pixmap()->convertToImage();
+ KIconEffect effect;
+
+ m_normalIcon = effect.apply(image, KIcon::Panel, KIcon::DefaultState);
+ m_activeIcon = effect.apply(image, KIcon::Panel, KIcon::ActiveState);
+ m_disabledIcon = effect.apply(image, KIcon::Panel, KIcon::DisabledState);
+
+ updateGeometry();
+}
+
+void SimpleButton::slotSettingsChanged(int category)
+{
+ if (category != KApplication::SETTINGS_MOUSE)
+ {
+ return;
+ }
+
+ bool changeCursor = KGlobalSettings::changeCursorOverIcon();
+
+ if (changeCursor)
+ {
+ setCursor(KCursor::handCursor());
+ }
+ else
+ {
+ unsetCursor();
+ }
+}
+
+void SimpleButton::slotIconChanged( int group )
+{
+ if (group != KIcon::Panel)
+ {
+ return;
+ }
+
+ generateIcons();
+ update();
+}
+
+void SimpleButton::enterEvent( QEvent *e )
+{
+ m_highlight = true;
+
+ repaint( false );
+ QButton::enterEvent( e );
+}
+
+void SimpleButton::leaveEvent( QEvent *e )
+{
+ m_highlight = false;
+
+ repaint( false );
+ QButton::enterEvent( e );
+}
+
+void SimpleButton::resizeEvent( QResizeEvent * )
+{
+ generateIcons();
+}
+
+
+SimpleArrowButton::SimpleArrowButton(QWidget *parent, Qt::ArrowType arrow, const char *name)
+ : SimpleButton(parent, name)
+{
+ setBackgroundOrigin(AncestorOrigin);
+ _arrow = arrow;
+ _inside = false;
+}
+
+QSize SimpleArrowButton::sizeHint() const
+{
+ return QSize( 12, 12 );
+}
+
+void SimpleArrowButton::setArrowType(Qt::ArrowType a)
+{
+ if (_arrow != a)
+ {
+ _arrow = a;
+ update();
+ }
+}
+
+Qt::ArrowType SimpleArrowButton::arrowType() const
+{
+ return _arrow;
+}
+
+void SimpleArrowButton::drawButton( QPainter *p )
+{
+ QRect r(1, 1, width() - 2, height() - 2);
+
+ QStyle::PrimitiveElement pe = QStyle::PE_ArrowLeft;
+ switch (_arrow)
+ {
+ case Qt::LeftArrow: pe = QStyle::PE_ArrowLeft; break;
+ case Qt::RightArrow: pe = QStyle::PE_ArrowRight; break;
+ case Qt::UpArrow: pe = QStyle::PE_ArrowUp; break;
+ case Qt::DownArrow: pe = QStyle::PE_ArrowDown; break;
+ }
+
+ int flags = QStyle::Style_Default | QStyle::Style_Enabled;
+ if (isDown() || isOn()) flags |= QStyle::Style_Down;
+ style().drawPrimitive(pe, p, r, colorGroup(), flags);
+}
+
+void SimpleArrowButton::enterEvent( QEvent *e )
+{
+ _inside = true;
+ SimpleButton::enterEvent( e );
+ update();
+}
+
+void SimpleArrowButton::leaveEvent( QEvent *e )
+{
+ _inside = false;
+ SimpleButton::enterEvent( e );
+ update();
+}
+
+#include "simplebutton.moc"
+
+// vim:ts=4:sw=4:et
diff --git a/kicker-applets/mediacontrol/simplebutton.h b/kicker-applets/mediacontrol/simplebutton.h
new file mode 100644
index 0000000..5423dff
--- /dev/null
+++ b/kicker-applets/mediacontrol/simplebutton.h
@@ -0,0 +1,89 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <nhasan@kde.org>
+ Copyright (C) 2004-2005 Aaron J. Seigo <aseigo@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SIMPLEBUTTON_H
+#define SIMPLEBUTTON_H
+
+#include <qbutton.h>
+#include <qpixmap.h>
+
+#include <kdemacros.h>
+
+class KDE_EXPORT SimpleButton : public QButton
+{
+ Q_OBJECT
+
+ public:
+ SimpleButton(QWidget *parent, const char *name = 0);
+ void setPixmap(const QPixmap &pix);
+ void setOrientation(Qt::Orientation orientaton);
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ protected:
+ void drawButton( QPainter *p );
+ void drawButtonLabel( QPainter *p );
+ void generateIcons();
+
+ void enterEvent( QEvent *e );
+ void leaveEvent( QEvent *e );
+ void resizeEvent( QResizeEvent *e );
+
+ protected slots:
+ virtual void slotSettingsChanged( int category );
+ virtual void slotIconChanged( int group );
+
+ private:
+ bool m_highlight;
+ QPixmap m_normalIcon;
+ QPixmap m_activeIcon;
+ QPixmap m_disabledIcon;
+ Qt::Orientation m_orientation;
+ class SimpleButtonPrivate;
+ SimpleButtonPrivate* d;
+};
+
+class KDE_EXPORT SimpleArrowButton: public SimpleButton
+{
+ Q_OBJECT
+
+ public:
+ SimpleArrowButton(QWidget *parent = 0, Qt::ArrowType arrow = Qt::UpArrow, const char *name = 0);
+ virtual ~SimpleArrowButton() {};
+ QSize sizeHint() const;
+
+ protected:
+ virtual void enterEvent( QEvent *e );
+ virtual void leaveEvent( QEvent *e );
+ virtual void drawButton(QPainter *p);
+ Qt::ArrowType arrowType() const;
+
+ public slots:
+ void setArrowType(Qt::ArrowType a);
+
+ private:
+ Qt::ArrowType _arrow;
+ bool _inside;
+};
+
+
+#endif // HIDEBUTTON_H
+
+// vim:ts=4:sw=4:et
diff --git a/kicker-applets/mediacontrol/xmmsInterface.cpp b/kicker-applets/mediacontrol/xmmsInterface.cpp
new file mode 100644
index 0000000..e2512e5
--- /dev/null
+++ b/kicker-applets/mediacontrol/xmmsInterface.cpp
@@ -0,0 +1,183 @@
+/***************************************************************************
+ Interface to access XMMS
+ -------------------
+ begin : Tue Apr 25 11:53:11 CEST 2000
+ copyright : (C) 2000-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_XMMS // only use if there is xmms installed on compiletime
+
+#include "xmmsInterface.h"
+#include "xmmsInterface.moc"
+#include <xmms/xmmsctrl.h>
+#include <kdebug.h>
+
+#define TIMER_SLOW 1000
+#define TIMER_FAST 100
+#define XMMS_SESSION 0
+
+XmmsInterface::XmmsInterface() : PlayerInterface()
+{
+ timervalue = TIMER_FAST;
+ bStartingXMMS = false;
+ xmms_timer = new QTimer ( this, "xmms_timer" );
+
+ QObject::connect( xmms_timer, SIGNAL(timeout()), SLOT(updateSlider()) );
+
+ // Better start the timer as late as possible in initialization
+ xmms_timer->start ( timervalue );
+}
+
+XmmsInterface::~XmmsInterface()
+{
+ delete xmms_timer;
+}
+
+void XmmsInterface::updateSlider ( void )
+{
+ if ( !xmms_remote_is_running(XMMS_SESSION) )
+ { // XMMS not running
+ if (timervalue == TIMER_FAST) // timer is running fast
+ {
+ emit playerStopped();
+ timervalue = TIMER_SLOW; // timer does not need to run fast if XMMS is not running
+ xmms_timer->changeInterval(timervalue);
+ emit newSliderPosition(0,0);
+ }
+ return; // as XMMS is not running we can leave now
+ }
+
+ // huh, XMMS is running :)
+ if (timervalue == TIMER_SLOW) // what? Still running slow?
+ {
+ emit playerStarted();
+ timervalue = TIMER_FAST; // boost the timer to have better reaction-times for the applet
+ xmms_timer->changeInterval(timervalue);
+ }
+
+ int len = xmms_remote_get_playlist_time ( XMMS_SESSION, xmms_remote_get_playlist_pos(XMMS_SESSION) );
+ int time = xmms_remote_get_output_time(XMMS_SESSION);
+
+ if (len < 0)
+ {
+ len = 0;
+ time = 0;
+ }
+
+ emit newSliderPosition(len,time);
+ emit playingStatusChanged(playingStatus());
+}
+
+
+// Drag-n-Drop stuff =================================================================
+
+void XmmsInterface::dragEnterEvent(QDragEnterEvent* event)
+{
+ event->accept( QTextDrag::canDecode(event) );
+}
+
+void XmmsInterface::dropEvent(QDropEvent* event)
+{
+ QString text;
+// kdDebug(90200) << "XmmsInterface::dropEvent()" << endl;
+ if ( QTextDrag::decode(event, text) )
+ {
+ xmms_remote_playlist_add_url_string(XMMS_SESSION,
+ (gchar *)text.local8Bit().data());
+ }
+}
+
+// ====================================================================================
+
+
+void XmmsInterface::sliderStartDrag()
+{
+ xmms_timer->stop();
+}
+
+void XmmsInterface::sliderStopDrag()
+{
+ xmms_timer->start( timervalue );
+}
+
+void XmmsInterface::jumpToTime( int msec )
+{
+ xmms_remote_jump_to_time(XMMS_SESSION, msec);
+}
+
+void XmmsInterface::playpause()
+{
+ if (!xmms_remote_is_running(XMMS_SESSION))
+ {
+ if (bStartingXMMS)
+ return;
+ startPlayer("xmms");
+ bStartingXMMS = true;
+ QTimer::singleShot(500, this, SLOT(playpause()));
+ }
+ else
+ {
+ bStartingXMMS = false;
+ xmms_remote_play_pause(XMMS_SESSION);
+ }
+}
+
+void XmmsInterface::stop()
+{
+ xmms_remote_stop(XMMS_SESSION);
+}
+
+void XmmsInterface::next()
+{
+ xmms_remote_playlist_next(XMMS_SESSION);
+}
+
+void XmmsInterface::prev()
+{
+ xmms_remote_playlist_prev(XMMS_SESSION);
+}
+
+void XmmsInterface::volumeUp()
+{
+ const int cur = xmms_remote_get_main_volume(XMMS_SESSION);
+ xmms_remote_set_main_volume(XMMS_SESSION, cur+1);
+}
+
+void XmmsInterface::volumeDown()
+{
+ const int cur = xmms_remote_get_main_volume(XMMS_SESSION);
+ xmms_remote_set_main_volume(XMMS_SESSION, cur-1);
+}
+
+int XmmsInterface::playingStatus()
+{
+ if (xmms_remote_is_paused(XMMS_SESSION))
+ return Paused;
+
+ if (xmms_remote_is_playing(XMMS_SESSION))
+ return Playing;
+
+ return Stopped;
+}
+
+const QString XmmsInterface::getTrackTitle() const
+{
+ return QString::fromLocal8Bit(
+ xmms_remote_get_playlist_title(XMMS_SESSION,
+ xmms_remote_get_playlist_pos(XMMS_SESSION)));
+}
+#endif // HAVE_XMMS
diff --git a/kicker-applets/mediacontrol/xmmsInterface.h b/kicker-applets/mediacontrol/xmmsInterface.h
new file mode 100644
index 0000000..ca514b2
--- /dev/null
+++ b/kicker-applets/mediacontrol/xmmsInterface.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ Interface to access XMMS
+ -------------------
+ begin : Tue Apr 25 11:53:11 CEST 2000
+ copyright : (C) 2000-2002 by Stefan Gehn
+ email : metz {AT} gehn {DOT} net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_XMMS // only use if there's xmms installed on compiletime
+
+#ifndef XMMSINTERFACE_H
+#define XMMSINTERFACE_H
+
+#include "playerInterface.h"
+#include <qtimer.h>
+
+class XmmsInterface : public PlayerInterface
+{
+ Q_OBJECT
+ public:
+ XmmsInterface();
+ ~XmmsInterface();
+
+ public slots:
+ virtual void updateSlider();
+ virtual void sliderStartDrag();
+ virtual void sliderStopDrag();
+ virtual void jumpToTime(int msec);
+ virtual void playpause();
+ virtual void stop();
+ virtual void next();
+ virtual void prev();
+ virtual void volumeUp();
+ virtual void volumeDown();
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dropEvent(QDropEvent* event);
+ virtual const QString getTrackTitle() const;
+ virtual int playingStatus();
+
+ private:
+ QTimer *xmms_timer;
+ int timervalue;
+ bool bStartingXMMS;
+};
+#endif // XMMSINTERFACE_H
+#endif // HAVE_XMMS