summaryrefslogtreecommitdiffstats
path: root/kicker-applets
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
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')
-rw-r--r--kicker-applets/Makefile.am2
-rw-r--r--kicker-applets/kbinaryclock/Makefile.am22
-rw-r--r--kicker-applets/kbinaryclock/datepicker.cpp51
-rw-r--r--kicker-applets/kbinaryclock/datepicker.h42
-rw-r--r--kicker-applets/kbinaryclock/kbinaryclock.cpp411
-rw-r--r--kicker-applets/kbinaryclock/kbinaryclock.desktop108
-rw-r--r--kicker-applets/kbinaryclock/kbinaryclock.h105
-rw-r--r--kicker-applets/kbinaryclock/kbinaryclock.kcfg49
-rw-r--r--kicker-applets/kbinaryclock/prefs.kcfgc7
-rw-r--r--kicker-applets/kbinaryclock/settings.ui483
-rw-r--r--kicker-applets/kolourpicker/Makefile.am23
-rw-r--r--kicker-applets/kolourpicker/TODO1
-rw-r--r--kicker-applets/kolourpicker/kolourpicker.cpp382
-rw-r--r--kicker-applets/kolourpicker/kolourpicker.desktop145
-rw-r--r--kicker-applets/kolourpicker/kolourpicker.h70
-rw-r--r--kicker-applets/kolourpicker/simplebutton.cpp256
-rw-r--r--kicker-applets/kolourpicker/simplebutton.h89
-rw-r--r--kicker-applets/ktimemon/Makefile.am22
-rw-r--r--kicker-applets/ktimemon/README65
-rw-r--r--kicker-applets/ktimemon/TODO13
-rw-r--r--kicker-applets/ktimemon/confdlg.cc295
-rw-r--r--kicker-applets/ktimemon/confdlg.h99
-rw-r--r--kicker-applets/ktimemon/configure.in.in3
-rw-r--r--kicker-applets/ktimemon/cr16-app-ktimemon.pngbin0 -> 306 bytes
-rw-r--r--kicker-applets/ktimemon/cr32-app-ktimemon.pngbin0 -> 345 bytes
-rw-r--r--kicker-applets/ktimemon/ktimemon.desktop129
-rw-r--r--kicker-applets/ktimemon/lo16-app-ktimemon.pngbin0 -> 306 bytes
-rw-r--r--kicker-applets/ktimemon/lo32-app-ktimemon.pngbin0 -> 345 bytes
-rw-r--r--kicker-applets/ktimemon/sample.cc508
-rw-r--r--kicker-applets/ktimemon/sample.h94
-rw-r--r--kicker-applets/ktimemon/timemon.cc435
-rw-r--r--kicker-applets/ktimemon/timemon.h107
-rw-r--r--kicker-applets/math/Makefile.am19
-rw-r--r--kicker-applets/math/mathapplet.cpp285
-rw-r--r--kicker-applets/math/mathapplet.desktop114
-rw-r--r--kicker-applets/math/mathapplet.h74
-rw-r--r--kicker-applets/math/parser.cpp813
-rw-r--r--kicker-applets/math/parser.h241
-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
91 files changed, 10349 insertions, 0 deletions
diff --git a/kicker-applets/Makefile.am b/kicker-applets/Makefile.am
new file mode 100644
index 0000000..462f19f
--- /dev/null
+++ b/kicker-applets/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = $(AUTODIRS)
+
diff --git a/kicker-applets/kbinaryclock/Makefile.am b/kicker-applets/kbinaryclock/Makefile.am
new file mode 100644
index 0000000..5039925
--- /dev/null
+++ b/kicker-applets/kbinaryclock/Makefile.am
@@ -0,0 +1,22 @@
+INCLUDES = $(all_includes)
+
+kde_module_LTLIBRARIES = kbinaryclock_panelapplet.la
+
+kbinaryclock_panelapplet_la_SOURCES = kbinaryclock.cpp settings.ui datepicker.cpp prefs.kcfgc
+
+METASOURCES = AUTO
+
+noinst_HEADERS = kbinaryclock.h datepicker.h
+
+lnkdir = $(kde_datadir)/kicker/applets
+lnk_DATA = kbinaryclock.desktop
+kde_kcfg_DATA = kbinaryclock.kcfg
+
+EXTRA_DIST = $(lnk_DATA)
+
+kbinaryclock_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+kbinaryclock_panelapplet_la_LIBADD = $(LIB_KDEUI)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kbinaryclock.pot
+
diff --git a/kicker-applets/kbinaryclock/datepicker.cpp b/kicker-applets/kbinaryclock/datepicker.cpp
new file mode 100644
index 0000000..19efc1d
--- /dev/null
+++ b/kicker-applets/kbinaryclock/datepicker.cpp
@@ -0,0 +1,51 @@
+/************************************************************
+
+Copyright (c) 1996-2002 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include "datepicker.h"
+
+
+#include <kdatepicker.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kwin.h>
+
+DatePicker::DatePicker(QWidget *parent, const QDate& date)
+ : QVBox( parent, 0, WType_TopLevel | WDestructiveClose |
+ WStyle_Customize | WStyle_StaysOnTop | WStyle_NoBorder )
+{
+ setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
+ KWin::setOnAllDesktops( handle(), true );
+ picker = new KDatePicker(this, date);
+ picker->setCloseButton(true);
+
+ /* name and icon for kicker's taskbar */
+ setCaption(i18n("Calendar"));
+ setIcon(SmallIcon("date"));
+}
+
+void DatePicker::keyReleaseEvent(QKeyEvent *e)
+{
+ DATEPICKER_INHERITED::keyReleaseEvent(e);
+ if (e->key() == Qt::Key_Escape)
+ close();
+}
diff --git a/kicker-applets/kbinaryclock/datepicker.h b/kicker-applets/kbinaryclock/datepicker.h
new file mode 100644
index 0000000..2cf524a
--- /dev/null
+++ b/kicker-applets/kbinaryclock/datepicker.h
@@ -0,0 +1,42 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __DATEPICKER_H
+#define __DATEPICKER_H
+
+#include <qvbox.h>
+
+class QDate;
+class KDatePicker;
+
+#define DATEPICKER_INHERITED QVBox
+class DatePicker : public QVBox
+{
+public:
+ DatePicker(QWidget*, const QDate&);
+private:
+ KDatePicker *picker;
+ void keyReleaseEvent(QKeyEvent *e);
+};
+
+#endif
diff --git a/kicker-applets/kbinaryclock/kbinaryclock.cpp b/kicker-applets/kbinaryclock/kbinaryclock.cpp
new file mode 100644
index 0000000..33e8ced
--- /dev/null
+++ b/kicker-applets/kbinaryclock/kbinaryclock.cpp
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2003 Benjamin C Meyer ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "kbinaryclock.h"
+#include "datepicker.h"
+
+#include <kapplication.h>
+#include <kconfigdialog.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kglobalsettings.h>
+
+#include <qradiobutton.h>
+#include <kcolorbutton.h>
+#include <kpopupmenu.h>
+#include <qslider.h>
+#include <qcursor.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <qlabel.h>
+
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <qclipboard.h>
+#include <kled.h>
+
+extern "C"
+{
+ KDE_EXPORT KPanelApplet* init( QWidget *parent, const QString& configFile ) {
+ KGlobal::locale()->insertCatalogue( "kbinaryclock");
+ return new KBinaryClock( configFile, KPanelApplet::Normal,
+ KPanelApplet::Preferences, parent, "kbinaryclock");
+ }
+}
+
+KConfigDialogImp::KConfigDialogImp( QWidget *parent, const char *name, KConfigSkeleton *prefs, KDialogBase::DialogType dialogType, KDialogBase::ButtonCode defaultButton, bool modal) :
+ KConfigDialog(parent, name, prefs, dialogType,(KDialogBase::ButtonCode) (KDialogBase::Default | KDialogBase::Ok | KDialogBase::Apply | KDialogBase::Cancel ), defaultButton, modal)
+{
+ // As a temporary mesure until the kicker applet's app name is set to the
+ // applets name so KDialogBase gets the right info.
+ setPlainCaption(i18n("Configure - KBinaryClock"));
+ setIcon(SmallIcon("date"));
+
+ settings = new SettingsImp(0, "General");
+ addPage(settings, i18n("General"), "package_settings");
+ connect(this, SIGNAL(widgetModified()), settings, SLOT(updatePreview()));
+}
+
+SettingsImp::SettingsImp(QWidget* parent, const char* name, WFlags fl): Settings(parent, name, fl){
+}
+
+/**
+ * Update the preview
+ */
+void SettingsImp::updatePreview(){
+ int shape = Shape_Circular->isChecked() ? Prefs::EnumShape::Circular : Prefs::EnumShape::Rectangular;
+ int look = KLed::Raised;
+ look = Look_Flat->isChecked() ? Prefs::EnumLook::Flat : look;
+ look = Look_Sunken->isChecked() ? Prefs::EnumLook::Sunken : look;
+ QColor color = kcfg_Color->color();
+ int darkFactor = kcfg_DarkFactor->value();
+ QColor backgroundColor = kcfg_Background->color();
+ frame1->setBackgroundColor(backgroundColor);
+
+ kLed1->setBackgroundColor(backgroundColor);
+ kLed2->setBackgroundColor(backgroundColor);
+ kLed3->setBackgroundColor(backgroundColor);
+ kLed4->setBackgroundColor(backgroundColor);
+ kLed5->setBackgroundColor(backgroundColor);
+ kLed6->setBackgroundColor(backgroundColor);
+
+ kLed1->setShape((KLed::Shape)shape);
+ kLed2->setShape((KLed::Shape)shape);
+ kLed3->setShape((KLed::Shape)shape);
+ kLed4->setShape((KLed::Shape)shape);
+ kLed5->setShape((KLed::Shape)shape);
+ kLed6->setShape((KLed::Shape)shape);
+
+ kLed1->setColor(color);
+ kLed2->setColor(color);
+ kLed3->setColor(color);
+ kLed4->setColor(color);
+ kLed5->setColor(color);
+ kLed6->setColor(color);
+
+ kLed1->setLook((KLed::Look)look);
+ kLed2->setLook((KLed::Look)look);
+ kLed3->setLook((KLed::Look)look);
+ kLed4->setLook((KLed::Look)look);
+ kLed5->setLook((KLed::Look)look);
+ kLed6->setLook((KLed::Look)look);
+
+ kLed1->setDarkFactor(darkFactor);
+ kLed2->setDarkFactor(darkFactor);
+ kLed3->setDarkFactor(darkFactor);
+ kLed4->setDarkFactor(darkFactor);
+ kLed5->setDarkFactor(darkFactor);
+ kLed6->setDarkFactor(darkFactor);
+}
+
+/**
+ * Constructor, create LED's
+ */
+KBinaryClock::KBinaryClock(const QString& configFile, Type type, int actions, QWidget *parent, const char *name)
+ : KPanelApplet(configFile, type, actions, parent, name), ledWidth(6),
+ _calendar(NULL), _disableCalendar(false),
+ prefs( new Prefs(sharedConfig())), m_tooltip(this)
+{
+ prefs->readConfig();
+ setBackgroundOrigin(AncestorOrigin);
+ for(int i=0; i < 4; i++){
+ for(int j=0; j < ledWidth;j++){
+ KLed *led = new KLed( this );
+ led->setBackgroundOrigin(AncestorOrigin);
+ ledMatrix[j][i] = led;
+ }
+ }
+
+ // Why does kicker start out with a size of 800x409?
+ // Kicker bug?
+ resize(60,42);
+
+ updateClock();
+ loadSettings();
+ QTimer *timer=new QTimer(this);
+ connect (timer, SIGNAL (timeout()), this, SLOT (updateClock()));
+ timer->start(500,false);
+}
+
+KBinaryClock::~KBinaryClock()
+{
+ delete prefs;
+ KGlobal::locale()->removeCatalogue( "kbinaryclock");
+}
+
+/**
+ * Return the computed height of the widget.
+ */
+int KBinaryClock::widthForHeight( int height ) const {
+ return (height-2)/4*ledWidth;
+}
+
+/**
+ * Return the computed width of the widget.
+ */
+int KBinaryClock::heightForWidth( int width ) const {
+ return (width/ledWidth)*4;
+}
+
+void KBinaryClock::resizeEvent( QResizeEvent *e ) {
+ int width = e->size().width();
+ for (int i=0; i < ledWidth; i++)
+ for (int j=0; j < 4; j++)
+ ledMatrix[i][j]->setGeometry( QRect( (width/ledWidth)*i, (width/ledWidth)*j, width/ledWidth, width/ledWidth) );
+}
+
+/**
+ * Load the settings for the clock.
+ */
+void KBinaryClock::loadSettings(){
+ int shape = prefs->shape();
+ int look = prefs->look();
+ QColor color = prefs->color();
+
+ int darkFactor = prefs->darkFactor();
+ QColor backgroundColor = prefs->background();
+ bool modifyBackground = false;
+ if(backgroundColor != KApplication::palette().active().background()){
+ setPaletteBackgroundColor(backgroundColor);
+ modifyBackground = true;
+ }
+
+ bool showSeconds = prefs->show_Seconds();
+ ledWidth = (showSeconds == true) ? 6 : 4;
+ for(int i=0; i < 4; i++){
+ for(int j=4; j < 6;j++){
+ if(showSeconds)
+ ledMatrix[j][i]->show();
+ else
+ ledMatrix[j][i]->hide();
+ }
+ }
+ for(int i=0; i < 4; i++){
+ for(int j=0; j < ledWidth;j++){
+ ledMatrix[j][i]->setShape((KLed::Shape)shape);
+ ledMatrix[j][i]->setColor(color);
+ ledMatrix[j][i]->setLook((KLed::Look)look);
+ ledMatrix[j][i]->setDarkFactor(darkFactor);
+ // Dammed if you do, dammed if you don't
+ if(modifyBackground || ledMatrix[j][i]->backgroundColor() != backgroundColor)
+ ledMatrix[j][i]->setPaletteBackgroundColor(backgroundColor);
+ }
+ }
+ updateLayout();
+}
+
+/**
+ * Show Settings dialog.
+ */
+void KBinaryClock::preferences(){
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialogImp *dialog = new KConfigDialogImp(this, "settings", prefs, KDialogBase::Swallow);
+ connect(dialog, SIGNAL(settingsChanged()), this, SLOT(loadSettings()));
+ dialog->show();
+ dialog->settings->updatePreview();
+}
+
+/**
+ * Get the time and update the LED's
+ */
+void KBinaryClock::updateClock(){
+ QString time = "hhmmss";
+ if(KGlobal::locale()->use12Clock())
+ time += "ap";
+
+ QString currentTime = (QTime::currentTime()).toString(time);
+ int splice[6];
+ splice[0] = currentTime.mid( 0, 1 ).toInt();
+ splice[1] = currentTime.mid( 1, 1 ).toInt();
+ splice[2] = currentTime.mid( 2, 1 ).toInt();
+ splice[3] = currentTime.mid( 3, 1 ).toInt();
+ splice[4] = currentTime.mid( 4, 1 ).toInt();
+ splice[5] = currentTime.mid( 5, 1 ).toInt();
+
+ for (int i=0; i<ledWidth; i++) {
+ (splice[i] & 8) != 0 ? ledMatrix[i][0]->setState(KLed::On) : ledMatrix[i][0]->setState(KLed::Off);
+ (splice[i] & 4) != 0 ? ledMatrix[i][1]->setState(KLed::On) : ledMatrix[i][1]->setState(KLed::Off);
+ (splice[i] & 2) != 0 ? ledMatrix[i][2]->setState(KLed::On) : ledMatrix[i][2]->setState(KLed::Off);
+ (splice[i] & 1) != 0 ? ledMatrix[i][3]->setState(KLed::On) : ledMatrix[i][3]->setState(KLed::Off);
+ }
+
+ // TODO add hide_Off_Leds checkbox to ui file post 3.3
+ // sense we can't add strings.
+ if(prefs->hide_Off_Leds())
+ for (int i=0; i<ledWidth; i++) {
+ for( int j=0; j < 4;j++){
+ if(ledMatrix[i][j]->state() == KLed::Off)
+ ledMatrix[i][j]->hide();
+ else
+ ledMatrix[i][j]->show();
+ }
+ }
+}
+
+/**
+ * Catch the right click press
+ */
+ void KBinaryClock::mousePressEvent(QMouseEvent *event) {
+ switch (event->button()) {
+ case QMouseEvent::RightButton:
+ QToolTip::remove(this);
+ openContextMenu();
+ break;
+ case QMouseEvent::LeftButton:
+ toggleCalendar();
+ QToolTip::remove(this);
+ break;
+ case QMouseEvent::MidButton:
+ QToolTip::remove(this);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Deal with right click's
+ */
+void KBinaryClock::openContextMenu() {
+ bool bImmutable = config()->isImmutable();
+
+ KPopupMenu *menu = new KPopupMenu();
+ menu->insertTitle( SmallIcon( "clock" ), i18n( "KBinaryClock" ) );
+
+ KLocale *loc = KGlobal::locale();
+ QDateTime dt = QDateTime::currentDateTime();
+
+ KPopupMenu *copyMenu = new KPopupMenu( menu );
+ copyMenu->insertItem(loc->formatDateTime(dt), 201);
+ copyMenu->insertItem(loc->formatDate(dt.date()), 202);
+ copyMenu->insertItem(loc->formatDate(dt.date(), true), 203);
+ copyMenu->insertItem(loc->formatTime(dt.time()), 204);
+ copyMenu->insertItem(loc->formatTime(dt.time(), true), 205);
+ copyMenu->insertItem(dt.date().toString(), 206);
+ copyMenu->insertItem(dt.time().toString(), 207);
+ copyMenu->insertItem(dt.toString(), 208);
+ connect( copyMenu, SIGNAL( activated(int) ), this, SLOT( slotCopyMenuActivated(int) ) );
+
+ if (!bImmutable)
+ {
+ if (kapp->authorize("user/root"))
+ {
+ menu->insertItem(SmallIcon("date"), i18n("&Adjust Date && Time..."), 103, 4);
+ }
+ menu->insertItem(SmallIcon("kcontrol"), i18n("Date && Time &Format..."), 104, 5);
+ }
+
+ menu->insertItem(SmallIcon("editcopy"), i18n("C&opy to Clipboard"), copyMenu, 105, 6);
+ if (!bImmutable)
+ {
+ menu->insertSeparator(7);
+ menu->insertItem(SmallIcon("configure"), i18n("&Configure KBinaryClock..."), 102, 8);
+ }
+ int result = menu->exec( QCursor::pos() );
+
+ KProcess proc;
+ switch (result) {
+ case 102:
+ preferences();
+ break;
+ case 103:
+ proc << locate("exe", "kdesu");
+ proc << "--nonewdcop";
+ proc << QString("%1 clock --lang %2")
+ .arg(locate("exe", "kcmshell"))
+ .arg(KGlobal::locale()->language());
+ proc.start(KProcess::DontCare);
+ break;
+ case 104:
+ proc << locate("exe", "kcmshell");
+ proc << "language";
+ proc.start(KProcess::DontCare);
+ break;
+ case 110:
+ preferences();
+ break;
+ } /* switch() */
+ delete menu;
+}
+
+void KBinaryClock::slotCopyMenuActivated( int id ) {
+ QPopupMenu *m = (QPopupMenu *) sender();
+ QString s = m->text(id);
+ QApplication::clipboard()->setText(s);
+}
+
+void KBinaryClock::toggleCalendar()
+{
+ if (_calendar && !_disableCalendar) {
+ // calls slotCalendarDeleted which does the cleanup for us
+ _calendar->close();
+ return;
+ }
+ if (_calendar || _disableCalendar){
+ return;
+ }
+ _calendar = new DatePicker(this, QDateTime::currentDateTime().date());
+ connect( _calendar, SIGNAL( destroyed() ), SLOT( slotCalendarDeleted() ));
+
+ // some extra spacing is included if aligned on a desktop edge
+ QPoint c = mapToGlobal(QPoint(0,0));
+
+ int w = _calendar->sizeHint().width() + 28;
+ // Added 28 px. to size poperly as said in API
+ int h = _calendar->sizeHint().height();
+
+ switch (position()) {
+ case KPanelApplet::pLeft: c.setX(c.x()+width()+2); break;
+ case KPanelApplet::pRight: c.setX(c.x()-w-2); break;
+ case KPanelApplet::pTop: c.setY(c.y()+height()+2); break;
+ case KPanelApplet::pBottom: c.setY(c.y()-h-2); break;
+ }
+
+ // make calendar fully visible
+ QRect deskR = KGlobalSettings::desktopGeometry(QPoint(0,0));
+
+ if (c.y()+h > deskR.bottom()) c.setY(deskR.bottom()-h-1);
+ if (c.x()+w > deskR.right()) c.setX(deskR.right()-w-1);
+
+ _calendar->move(c);
+ _calendar->show();
+}
+
+void KBinaryClock::slotCalendarDeleted()
+{
+ _calendar = 0L;
+ // don't reopen the calendar immediately ...
+ _disableCalendar = true;
+ QTimer::singleShot(100, this, SLOT(slotEnableCalendar()));
+}
+
+void KBinaryClock::slotEnableCalendar()
+{
+ _disableCalendar = false;
+}
+
+ClockAppletToolTip::ClockAppletToolTip( KBinaryClock *clock ) : QToolTip( clock ), m_clock( clock ) {}
+
+void ClockAppletToolTip::maybeTip( const QPoint & /*point*/ )
+{
+ tip(m_clock->geometry(), KGlobal::locale()->formatDate(QDateTime::currentDateTime().date(), false));
+}
+
+#include "kbinaryclock.moc"
diff --git a/kicker-applets/kbinaryclock/kbinaryclock.desktop b/kicker-applets/kbinaryclock/kbinaryclock.desktop
new file mode 100644
index 0000000..962d48e
--- /dev/null
+++ b/kicker-applets/kbinaryclock/kbinaryclock.desktop
@@ -0,0 +1,108 @@
+[Desktop Entry]
+Type=Plugin
+Name=Binary Clock
+Name[bg]=Двоичен часовник
+Name[br]=Eurier binarel
+Name[ca]=Rellotge binari
+Name[cs]=Binární hodiny
+Name[cy]=Cloc Deuaidd
+Name[da]=Binært ur
+Name[de]=Binäruhr
+Name[el]=Δυαδικό ρολόι
+Name[eo]=Duuma horloĝo
+Name[es]=Reloj binario
+Name[et]=Binaarkell
+Name[eu]=Erloju bitarra
+Name[fa]=ساعت دودویی
+Name[fi]=Binäärikello
+Name[fr]=Horloge binaire
+Name[fy]=Binêre klok
+Name[ga]=Clog Dénártha
+Name[gl]=Relóxio Binário
+Name[he]=שעון בינרי
+Name[hi]=बाइनरी क्लॉक
+Name[hr]=Binarni sat
+Name[hu]=KBinaryClock
+Name[is]=Tvíundarklukka
+Name[it]=Orologio binario
+Name[ja]=バイナリ時計
+Name[ka]=ორობითი საათი
+Name[kk]=Бинарлы сағат
+Name[km]=នាឡិកា​គោលពីរ
+Name[lt]=Skaitmeninis laikrodis
+Name[mk]=Бинарен часовник
+Name[ms]=Jam Binari
+Name[nb]=Binærklokke
+Name[nds]=Bineerklock
+Name[ne]=बाइनरि घडी
+Name[nl]=Binaire klok
+Name[nn]=Binærklokke
+Name[pa]=ਬਾਈਨਰੀ ਘੜੀ
+Name[pl]=Zegar binarny
+Name[pt]=Relógio Binário
+Name[pt_BR]=Relógio Binário
+Name[ru]=Двоичные часы
+Name[sk]=Binárne hodiny
+Name[sl]=Dvojiška ura
+Name[sr]=Бинарни часовник
+Name[sr@Latn]=Binarni časovnik
+Name[sv]=Binärklocka
+Name[ta]=இருநிலை கடிகாரம்
+Name[tr]=İkili Saat
+Name[uk]=KBinaryClock
+Name[uz]=Binar soat
+Name[uz@cyrillic]=Бинар соат
+Name[vi]=Đồng hồ nhị phân
+Name[zh_CN]=二进制时钟
+Name[zh_TW]=二位元鐘
+Comment=Shows the time in binary format
+Comment[bg]=Показване на времето в двоичен формат
+Comment[ca]=Mostra l'hora en format binari
+Comment[cs]=Zobrazuje čas v binárním tvaru
+Comment[da]=Viser tiden i binært format
+Comment[de]=Zeigt die Zeit in binärem Format
+Comment[el]=Εμφάνιση του χρόνου σε δυαδική μορφή
+Comment[eo]=Montras la tempon per duuma formato
+Comment[es]=Muestra la hora en formato binario
+Comment[et]=Näitab aega binaarkujul
+Comment[eu]=Erakutsi ordua formatu bitarrean
+Comment[fa]=فقره‌ها را در قالب دودویی نمایش می‌دهد
+Comment[fi]=Näyttää ajan binäärimuodossa
+Comment[fr]=Affiche l'heure en binaire
+Comment[fy]=Toant de tiid yn in binêr formaat
+Comment[ga]=Taispeáin an t-am i bhformáid dhénártha
+Comment[gl]=Mostra a hora en formato binário
+Comment[hr]=Prikaz vremena u binarnom obliku
+Comment[hu]=Bináris formátumban jeleníti meg az időt
+Comment[is]=Sýnir tímann í tvíunarsniði
+Comment[it]=Mostra il tempo in formato binario
+Comment[ja]=時刻をバイナリ形式で表示します
+Comment[ka]=დროს ორობით ფორმატში აჩვენებს
+Comment[kk]=Уақытты бинарлы пішімінде көрсету
+Comment[km]=បង្ហាញ​ម៉ោង​ជា​​ទ្រង់ទ្រាយ​គោលពីរ
+Comment[lt]=Rodo laiką skaitmeniniu formatu
+Comment[mk]=Го прикажува времето во бинарен формат
+Comment[nb]=Viser klokkeslett i binært format
+Comment[nds]=Wiest de Tiet in bineer Formaat
+Comment[ne]=बाइनरि ढाँचामा समय देखाउछ
+Comment[nl]=Toont de tijd in een binair formaat
+Comment[nn]=Viser tida i binærformat
+Comment[pl]=Pokazuje czas w postaci binarnej
+Comment[pt]=Mostra a hora em formato binário
+Comment[pt_BR]=Mostra a hora em formato binário
+Comment[ru]=Показ времени в двоичном формате
+Comment[sk]=Zobrazí čas v binárnom formáte
+Comment[sl]=Prikazuje čas v dvojiški obliki
+Comment[sr]=Приказује време у бинарном формату
+Comment[sr@Latn]=Prikazuje vreme u binarnom formatu
+Comment[sv]=Visar tiden med binärformat
+Comment[tr]=Zamanı ikili biçemde gösterir
+Comment[uk]=Показує час в двійковому форматі
+Comment[uz]=Vaqtni ikkili sanoq tizimida koʻrsatish
+Comment[uz@cyrillic]=Вақтни иккили саноқ тизимида кўрсатиш
+Comment[vi]=Hiển thị giờ định dạng nhị phân
+Comment[zh_CN]=以二进制格式显示时间
+Comment[zh_TW]=以二進位格式顯示時間
+Icon=kbinaryclock
+X-KDE-Library=kbinaryclock_panelapplet
+X-KDE-UniqueApplet = false
diff --git a/kicker-applets/kbinaryclock/kbinaryclock.h b/kicker-applets/kbinaryclock/kbinaryclock.h
new file mode 100644
index 0000000..9edf51d
--- /dev/null
+++ b/kicker-applets/kbinaryclock/kbinaryclock.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2003 Benjamin C Meyer ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef KBINARYCLOCK_H
+#define KBINARYCLOCK_H
+
+#include <kpanelapplet.h>
+#include <qevent.h>
+#include <kglobal.h>
+#include <kaboutdata.h>
+#include <qdatetime.h>
+#include <qtooltip.h>
+#include <kconfigdialog.h>
+
+#include "settings.h"
+#include "prefs.h"
+
+class KLed;
+class QGridLayout;
+class DatePicker;
+class QGridLayout;
+class KBinaryClock;
+
+class SettingsImp : public Settings {
+ Q_OBJECT
+public:
+ SettingsImp(QWidget* parent=0,
+ const char* name=0,
+ WFlags fl=0);
+public slots:
+ void updatePreview();
+
+};
+
+class KConfigDialogImp : public KConfigDialog {
+public:
+ KConfigDialogImp(QWidget *parent, const char *name,
+ KConfigSkeleton *prefs,
+ KDialogBase::DialogType dialogType = KDialogBase::IconList,
+ KDialogBase::ButtonCode defaultButton = Ok,
+ bool modal=false);
+ SettingsImp *settings;
+};
+
+class ClockAppletToolTip : public QToolTip
+{
+ public:
+ ClockAppletToolTip( KBinaryClock* clock );
+
+ protected:
+ virtual void maybeTip( const QPoint & );
+
+ private:
+ KBinaryClock *m_clock;
+};
+
+class KBinaryClock : public KPanelApplet {
+ Q_OBJECT
+public:
+ KBinaryClock(const QString& configFile, Type t = Normal, int actions = 0, QWidget *parent = 0, const char *name = 0);
+ ~KBinaryClock();
+
+ virtual int widthForHeight (int height) const;
+ virtual int heightForWidth (int width) const;
+
+protected:
+ virtual void resizeEvent(QResizeEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event);
+
+protected slots:
+ void preferences();
+ void updateClock();
+ void loadSettings();
+ void slotCopyMenuActivated(int);
+ void slotCalendarDeleted();
+ void slotEnableCalendar();
+
+private:
+ void openContextMenu();
+ void toggleCalendar();
+ KLed *ledMatrix[6][4];
+ int ledWidth;
+ DatePicker *_calendar;
+ bool _disableCalendar;
+ Prefs *prefs;
+ ClockAppletToolTip m_tooltip;
+};
+
+#endif // KBINARYCLOCK_H
+
diff --git a/kicker-applets/kbinaryclock/kbinaryclock.kcfg b/kicker-applets/kbinaryclock/kbinaryclock.kcfg
new file mode 100644
index 0000000..b5a5fb3
--- /dev/null
+++ b/kicker-applets/kbinaryclock/kbinaryclock.kcfg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <include>kapplication.h</include>
+ <kcfgfile arg="true"/>
+ <group name="General">
+ <entry name="Shape" type="Enum">
+ <label>Shape of the LEDs</label>
+ <choices>
+ <choice name="Rectangular"/>
+ <choice name="Circular"/>
+ </choices>
+ <default>Circular</default>
+ </entry>
+ <entry name="Look" type="Enum">
+ <label>Look</label>
+ <choices>
+ <choice name="Flat"/>
+ <choice name="Raised"/>
+ <choice name="Sunken"/>
+ </choices>
+ <default>Raised</default>
+ </entry>
+ <entry name="Color" type="Color">
+ <label>Color of the LEDs</label>
+ <default>55,49,238</default>
+ </entry>
+ <entry name="DarkFactor" type="Int">
+ <label>Darkness of disabled LEDs</label>
+ <default>300</default>
+ <min>0</min>
+ <max>1000</max>
+ </entry>
+ <entry name="Background" type="Color">
+ <label>Background color</label>
+ <default code="true">KApplication::palette().active().background()</default>
+ </entry>
+ <entry name="Show_Seconds" type="Bool">
+ <label>Whether to show seconds</label>
+ <default>true</default>
+ </entry>
+ <entry name="Hide_Off_Leds" type="Bool">
+ <label>Whether to show LEDs that are off</label>
+ <default>false</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kicker-applets/kbinaryclock/prefs.kcfgc b/kicker-applets/kbinaryclock/prefs.kcfgc
new file mode 100644
index 0000000..7e91072
--- /dev/null
+++ b/kicker-applets/kbinaryclock/prefs.kcfgc
@@ -0,0 +1,7 @@
+# Code generation options for kconfig_compiler
+File=kbinaryclock.kcfg
+#IncludeFiles=defines.h
+ClassName=Prefs
+Singleton=false
+#CustomAdditions=true
+#Mutators=Zoom
diff --git a/kicker-applets/kbinaryclock/settings.ui b/kicker-applets/kbinaryclock/settings.ui
new file mode 100644
index 0000000..43462af
--- /dev/null
+++ b/kicker-applets/kbinaryclock/settings.ui
@@ -0,0 +1,483 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Settings</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Settings</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>452</width>
+ <height>247</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>Disabled LED</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Light</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_DarkFactor</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="lineStep">
+ <number>5</number>
+ </property>
+ <property name="pageStep">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>300</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>NoMarks</enum>
+ </property>
+ <property name="tickInterval">
+ <number>50</number>
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <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>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Dark</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Color</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Background:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>LED:</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_Color</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_Background</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer row="0" column="2" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="2" column="2">
+ <property name="name">
+ <cstring>kcfg_Shape</cstring>
+ </property>
+ <property name="title">
+ <string>LED Shape</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>Shape_Rectangular</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Rectangular</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>Shape_Circular</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Circular</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="2">
+ <property name="name">
+ <cstring>kcfg_Look</cstring>
+ </property>
+ <property name="title">
+ <string>LED Look</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>Look_Flat</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Flat</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>Look_Raised</cstring>
+ </property>
+ <property name="text">
+ <string>R&amp;aised</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>Look_Sunken</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Sunken</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="4" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>preview</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="KLed" row="0" column="0">
+ <property name="name">
+ <cstring>kLed1</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ </widget>
+ <widget class="KLed" row="0" column="1">
+ <property name="name">
+ <cstring>kLed2</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="KLed" row="1" column="1">
+ <property name="name">
+ <cstring>kLed4</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="KLed" row="1" column="0">
+ <property name="name">
+ <cstring>kLed3</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ </widget>
+ <widget class="KLed" row="2" column="1">
+ <property name="name">
+ <cstring>kLed6</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ </widget>
+ <widget class="KLed" row="2" column="0">
+ <property name="name">
+ <cstring>kLed5</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>84</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_Show_Seconds</cstring>
+ </property>
+ <property name="text">
+ <string>Show seconds</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_Hide_Off_Leds</cstring>
+ </property>
+ <property name="text">
+ <string>Hide unlit LEDs</string>
+ </property>
+ </widget>
+ <widget class="Line" row="0" column="3" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kled.h</includehint>
+</includehints>
+</UI>
diff --git a/kicker-applets/kolourpicker/Makefile.am b/kicker-applets/kolourpicker/Makefile.am
new file mode 100644
index 0000000..8c86635
--- /dev/null
+++ b/kicker-applets/kolourpicker/Makefile.am
@@ -0,0 +1,23 @@
+
+INCLUDES = $(all_includes)
+
+kde_module_LTLIBRARIES = kolourpicker_panelapplet.la
+
+kolourpicker_panelapplet_la_SOURCES = kolourpicker.cpp simplebutton.cpp
+
+noinst_HEADERS = kolourpicker.h
+
+kolourpicker_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+kolourpicker_panelapplet_la_LIBADD = $(LIB_KDEUI)
+
+METASOURCES = AUTO
+
+lnkdir = $(kde_datadir)/kicker/applets
+
+lnk_DATA = kolourpicker.desktop
+
+EXTRA_DIST = $(lnk_DATA)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kolourpicker.pot
+
diff --git a/kicker-applets/kolourpicker/TODO b/kicker-applets/kolourpicker/TODO
new file mode 100644
index 0000000..44d9566
--- /dev/null
+++ b/kicker-applets/kolourpicker/TODO
@@ -0,0 +1 @@
+Add a menu item to edit the colour via KColorDialog (wish by Neil Stevens <[email protected]>)
diff --git a/kicker-applets/kolourpicker/kolourpicker.cpp b/kicker-applets/kolourpicker/kolourpicker.cpp
new file mode 100644
index 0000000..98f5302
--- /dev/null
+++ b/kicker-applets/kolourpicker/kolourpicker.cpp
@@ -0,0 +1,382 @@
+/* This file is part of KolourPicker
+ Copyright (c) 2001 Malte Starostik <[email protected]>
+
+ 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.
+
+$Id$
+*/
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlayout.h>
+#include <qimage.h>
+#include <qclipboard.h>
+#include <qregexp.h>
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qcursor.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kconfig.h>
+#include <kaboutdata.h>
+#include <kaboutapplication.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+
+#include "kolourpicker.h"
+#include "kolourpicker.moc"
+
+#include <X11/Xlib.h>
+
+// Applet initialization function
+extern "C"
+{
+ KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile)
+ {
+ KGlobal::locale()->insertCatalogue("kolourpicker");
+ return new KolourPicker(configFile, KPanelApplet::Normal,
+ KPanelApplet::About,
+ parent, "kolourpicker");
+ }
+}
+
+KolourPicker::KolourPicker(const QString& configFile, Type type,
+ int actions, QWidget *parent, const char *name)
+ : KPanelApplet(configFile, type, actions, parent, name),
+ m_picking(0)
+{
+ KAboutData *about = new KAboutData("kolourpicker",
+ I18N_NOOP("Color Picker"),
+ "v0.1",
+ I18N_NOOP("An applet to pick color values from anywhere on the screen"),
+ KAboutData::License_GPL_V2,
+ "(c) 2001 Malte Starostik");
+ about->addAuthor("Malte Starostik", I18N_NOOP("Original Author"), "[email protected]");
+ m_instance = new KInstance(about);
+
+ KConfig *conf = config();
+ conf->setGroup("General");
+ QStringList history = conf->readListEntry("History");
+ for (QStringList::ConstIterator it = history.begin(); it != history.end(); ++it)
+ m_history.append(QColor(*it));
+
+ setBackgroundOrigin(AncestorOrigin);
+
+ m_colourButton = new SimpleButton(this);
+ m_colourButton->setPixmap(SmallIcon("colorpicker"));
+ m_colourButton->setFixedSize(20, 20);
+ QToolTip::add(m_colourButton, i18n("Pick a color"));
+ connect(m_colourButton, SIGNAL(clicked()), SLOT(slotPick()));
+
+ m_historyButton = new SimpleButton(this);
+ m_historyButton->setFixedSize(20, 20);
+ if (m_history.count())
+ m_historyButton->setPixmap(colorPixmap(m_history.last()));
+ else
+ {
+ m_historyButton->setPixmap(colorPixmap(QColor()));
+ m_historyButton->setEnabled(false);
+ }
+ QToolTip::add(m_historyButton, i18n("History"));
+ connect(m_historyButton, SIGNAL(clicked()), SLOT(slotHistory()));
+}
+
+KolourPicker::~KolourPicker()
+{
+ KGlobal::locale()->removeCatalogue("kolourpicker");
+}
+
+
+int KolourPicker::heightForWidth(int width) const
+{
+ return (width > 40) ? 22 : 44;
+}
+
+int KolourPicker::widthForHeight(int height) const
+{
+ return (height > 40) ? 22 : 44;
+}
+
+void KolourPicker::about()
+{
+ KAboutApplication dlg(m_instance->aboutData());
+ dlg.exec();
+}
+
+void KolourPicker::slotPick()
+{
+ m_picking = true;
+ grabMouse(crossCursor);
+ grabKeyboard();
+}
+
+void KolourPicker::slotHistory()
+{
+ KPopupMenu popup;
+ popup.insertTitle(SmallIcon("colorize"), i18n("History"));
+ QPtrList<QPopupMenu> subMenus;
+ subMenus.setAutoDelete(true);
+ for (QValueList<QColor>::ConstIterator it = m_history.fromLast();
+ it != m_history.end();
+ --it)
+ {
+ QPopupMenu *sub = copyPopup(*it, false);
+ subMenus.append(sub);
+ popup.insertItem(colorPixmap(*it),
+ QString("%1, %2, %3").arg((*it).red()).arg((*it).green()).arg((*it).blue()),
+ sub);
+ }
+ popup.insertSeparator();
+ int clear = popup.insertItem(SmallIcon("history_clear"), i18n("&Clear History"));
+ int id = popup.exec(QCursor::pos());
+ if (id == clear)
+ {
+ m_history.clear();
+ m_historyButton->setEnabled(false);
+ arrangeButtons();
+ KConfig *conf = config();
+ conf->setGroup("General");
+ conf->writeEntry("History", QStringList());
+ conf->sync();
+ }
+ else if (id != -1)
+ setClipboard(popup.findItem(id)->text());
+}
+
+void KolourPicker::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (m_picking)
+ {
+ m_picking = false;
+ releaseMouse();
+ releaseKeyboard();
+ QWidget *desktop = QApplication::desktop();
+ QPixmap pm = QPixmap::grabWindow(desktop->winId(),
+ e->globalPos().x(), e->globalPos().y(), 1, 1);
+ QImage img = pm.convertToImage();
+ QColor color(img.pixel(0, 0));
+
+ // eventually remove a dupe
+ QValueListIterator<QColor> dupe = m_history.find(color);
+ if (dupe != m_history.end())
+ m_history.remove(dupe);
+
+ m_history.append(color);
+ while (m_history.count() >= 10)
+ m_history.remove(m_history.begin());
+ m_historyButton->setEnabled(true);
+ arrangeButtons();
+ QStringList history;
+ for (QValueList<QColor>::ConstIterator it = m_history.begin();
+ it != m_history.end();
+ ++it)
+ {
+ history.append((*it).name());
+ }
+ KConfig *conf = config();
+ conf->setGroup("General");
+ conf->writeEntry("History", history);
+ conf->sync();
+ m_historyButton->setPixmap(colorPixmap(color));
+ QPopupMenu *popup = copyPopup(color, true);
+ int id = popup->exec(e->globalPos());
+ if (id != -1)
+ setClipboard( popup->findItem(id)->text() );
+ delete popup;
+ }
+ else
+ KPanelApplet::mouseReleaseEvent(e);
+}
+
+// set both clipboard and selection
+void KolourPicker::setClipboard(const QString& text)
+{
+ QClipboard *clip = QApplication::clipboard();
+ bool oldMode = clip->selectionModeEnabled();
+ clip->setSelectionMode(true);
+ clip->setText(text);
+ clip->setSelectionMode(false);
+ clip->setText(text);
+ clip->setSelectionMode( oldMode );
+}
+
+void KolourPicker::keyPressEvent(QKeyEvent *e)
+{
+ if (m_picking)
+ {
+ if (e->key() == Key_Escape)
+ {
+ m_picking = false;
+ releaseMouse();
+ releaseKeyboard();
+ }
+ e->accept();
+ return;
+ }
+ KPanelApplet::keyPressEvent(e);
+}
+
+void KolourPicker::resizeEvent(QResizeEvent *)
+{
+ arrangeButtons();
+}
+
+void KolourPicker::arrangeButtons()
+{
+ int h, w, p;
+
+ if (orientation() == Horizontal)
+ {
+ h = height();
+ if (h > 40)
+ {
+ // vertical layout
+ p = (h - 40)/3;
+ m_colourButton->setGeometry(2, p, 20, 20);
+ m_historyButton->setGeometry(2, 2*p+20, 20, 20);
+ }
+ else
+ {
+ // horizontal layout
+ p = (h - 20)/2;
+ m_colourButton->setGeometry(2, p, 20, 20);
+ m_historyButton->setGeometry(24, p, 20, 20);
+ }
+ }
+ else
+ {
+ w = width();
+ if (w > 40)
+ {
+ // horizontal layout
+ p = (w - 40)/3;
+ m_colourButton->setGeometry(p, 2, 20, 20);
+ m_historyButton->setGeometry(2*p+20, 2, 20, 20);
+ }
+ else
+ {
+ // vertical layout
+ p = (w - 20)/2;
+ m_colourButton->setGeometry(p, 2, 20, 20);
+ m_historyButton->setGeometry(p, 24, 20, 20);
+ }
+ }
+
+ updateGeometry();
+}
+
+QPopupMenu *KolourPicker::copyPopup(const QColor &c, bool title) const
+{
+ KPopupMenu *popup = new KPopupMenu;
+ if (title)
+ popup->insertTitle(colorPixmap(c), i18n("Copy Color Value"));
+ QString value;
+ // r, g, b
+ value.sprintf("%u, %u, %u", c.red(), c.green(), c.blue());
+ popup->insertItem(SmallIcon("text"), value);
+ // HTML, lower case hex chars
+ value.sprintf("#%.2x%.2x%.2x", c.red(), c.green(), c.blue());
+ popup->insertItem(SmallIcon("html"), value);
+ if (value.find(QRegExp("[a-f]")) >= 0)
+ {
+ // HTML, upper case hex chars
+ value.sprintf("#%.2X%.2X%.2X", c.red(), c.green(), c.blue());
+ popup->insertItem(SmallIcon("html"), value);
+ }
+ // lower case hex chars
+ value.sprintf( "%.2x%.2x%.2x", c.red(), c.green(), c.blue() );
+ popup->insertItem( SmallIcon( "html" ), value );
+ if ( value.find( QRegExp( "[a-f]" ) ) >= 0 )
+ {
+ // upper case hex chars
+ value.sprintf( "%.2X%.2X%.2X", c.red(), c.green(), c.blue() );
+ popup->insertItem( SmallIcon( "html" ), value );
+ }
+ // Color name
+ QStringList names = colorNames(c.red(), c.green(), c.blue());
+ for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it)
+ popup->insertItem(SmallIcon("text"), *it);
+ return popup;
+}
+
+#define AAFACTOR 4
+
+QPixmap KolourPicker::colorPixmap(const QColor &c) const
+{
+ int x, y, dx, dy, d;
+
+ QImage img(16 * AAFACTOR, 16 * AAFACTOR, 32);
+ img.setAlphaBuffer(true);
+ img.fill(0);
+
+ for (x = 0; x < img.width(); x++)
+ for (y = 0; y < img.height(); y++)
+ {
+ dx = 1 + x - 15 * AAFACTOR / 2;
+ dy = 1 + y - 15 * AAFACTOR / 2;
+ d = dx * dx + dy * dy;
+
+ if (d < (36 * AAFACTOR * AAFACTOR))
+ img.setPixel(x, y, c.pixel());
+ else if (d < (56.25 * AAFACTOR * AAFACTOR))
+ img.setPixel(x, y, qRgba(128, 128, 128, 255));
+ }
+
+ QBitmap mask(16, 16);
+ mask.fill(Qt::color0);
+ QPainter p(&mask);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::color1);
+ p.drawEllipse(0, 0, 15, 15);
+ p.end();
+
+ QPixmap pm = QPixmap(img.smoothScale(16, 16));
+ pm.setMask(mask);
+
+ return pm;
+}
+
+const QStringList &KolourPicker::colorNames(int r, int g, int b) const
+{
+ static QStringList NullList;
+ if (m_colorNames.isEmpty())
+ {
+ QFile f("/usr/lib/X11/rgb.txt");
+ if (!f.open(IO_ReadOnly))
+ return NullList;
+ QTextStream str(&f);
+ QString red, green, blue;
+ while (!str.atEnd())
+ {
+ str >> red;
+ if (red.simplifyWhiteSpace()[0].latin1() == '!')
+ {
+ str.readLine();
+ continue;
+ }
+ str >> green >> blue;
+ const_cast<KolourPicker *>(this)->m_colorNames[(red.toInt() << 16) + (green.toInt() << 8) + blue.toInt()]
+ .append(str.readLine().simplifyWhiteSpace());
+ }
+ }
+ return m_colorNames[(r << 16) + (g << 8) + b];
+}
+
+// vim: ts=4 sw=4 noet
diff --git a/kicker-applets/kolourpicker/kolourpicker.desktop b/kicker-applets/kolourpicker/kolourpicker.desktop
new file mode 100644
index 0000000..34f13d0
--- /dev/null
+++ b/kicker-applets/kolourpicker/kolourpicker.desktop
@@ -0,0 +1,145 @@
+[Desktop Entry]
+Type=Plugin
+Name=Color Picker
+Name[af]=Kleur Kieser
+Name[ar]=أداة اختيار الألوان
+Name[az]=Rəng Alıcısı
+Name[bg]=Избор на цвят
+Name[br]=Dibaber al liv
+Name[bs]=Izbornik boja
+Name[ca]=Selector de colors
+Name[cs]=Výběr barev
+Name[cy]=Dewisydd Lliw
+Name[da]=Farveplukker
+Name[de]=Farbauswahl
+Name[el]=Επιλογή χρωμάτων
+Name[en_GB]=Colour Picker
+Name[eo]=Kolorelektilo
+Name[es]=Selector de color
+Name[et]=Värvide valimine
+Name[eu]=Kolore hautagailua
+Name[fa]=برگزینندۀ رنگ
+Name[fi]=Värivalitsin
+Name[fo]=Litveljari
+Name[fr]=Pipette
+Name[fy]=Kleurekiezer
+Name[gl]=Escolla de Cores
+Name[he]=בוחר צבעים
+Name[hi]=रंग चयनक
+Name[hr]=Birač boja
+Name[hu]=Színválasztó
+Name[is]=Litaval
+Name[it]=Scelta colore
+Name[ja]=色の抽出
+Name[ka]=ფერთა ამღები
+Name[kk]=Түсті шұқып алу
+Name[km]=កម្មវិធី​រើស​ពណ៌
+Name[ko]=색 고르기
+Name[lt]=Spalvų rinkėjas
+Name[lv]=Krāsu Lasītājs
+Name[mk]=Бирач на бои
+Name[ms]=Pengutip Warna
+Name[mt]=Agħżel kulur
+Name[nb]=Fargevelger
+Name[nds]=Klöörutwahl
+Name[ne]=रङ पिकर
+Name[nl]=Kleurenkiezer
+Name[nn]=Fargeveljar
+Name[pa]=ਰੰਗ ਚੋਣਕਾਰ
+Name[pl]=Wybór koloru
+Name[pt]=Escolha de Cores
+Name[pt_BR]=Seletor de cores
+Name[ro]=Selector de culori
+Name[ru]=Выбор цвета
+Name[sk]=Výber farieb
+Name[sl]=Izbirnik barv
+Name[sr]=Бирач боја
+Name[sr@Latn]=Birač boja
+Name[sv]=Färgväljare
+Name[ta]=வண்ண எடுப்பான்
+Name[tg]=Интихоби рангҳо
+Name[th]=เครื่องมือเลือกสี
+Name[tr]=Renk Seçici
+Name[uk]=Селектор кольорів
+Name[uz]=Rang tanlagich
+Name[uz@cyrillic]=Ранг танлагич
+Name[ven]=Tshidobamuvhala
+Name[vi]=Bộ kén màu
+Name[xh]=Umkhethi Wombala
+Name[zh_CN]=颜色提取程序
+Name[zh_TW]=色彩選擇器
+Name[zu]=Umcoshi Wombala
+Icon=colorpicker
+Comment=Pick colors from anywhere and get their values
+Comment[af]=Kies kleure van orals en kry hulle waardes
+Comment[ar]=اختر الألوان من أي مكان و احصل على قيمتها الرقمية
+Comment[az]=İstədiyiniz yerdən rəng alaraq qiymətlərini öyrənin
+Comment[bg]=Избор на цвят от екрана и получаване на неговата стойност
+Comment[bs]=Izbor boje sa bilo kojeg mjesta i ispis njenih vrijednosti
+Comment[ca]=Selecciona colors des de qualsevol lloc i obté els seus valors
+Comment[cs]=Výběr barev z libovolného místa a získání jejich hodnot
+Comment[cy]=Dewis lliwiau oddiwrth unrhyw man a cael eu gwerthoedd
+Comment[da]=Pluk farver fra et vilkårligt sted og få deres værdier
+Comment[de]=Farben aufnehmen und ihre RGB-Werte ermitteln
+Comment[el]=Επιλέξτε χρώματα από οπουδήποτε και πάρτε τις τιμές τους
+Comment[en_GB]=Pick colours from anywhere and get their values
+Comment[eo]=Elprenas koloron de ie sur la ekrano kaj montras ĝiajn valorojn
+Comment[es]=Selecciona colores desde cualquier sitio y devuelve sus valores
+Comment[et]=Värvide valimine ekraanilt ja nende väärtuste vaatamine
+Comment[eu]=Hautatu koloreak edonondik eta euren balioak eskuratu
+Comment[fa]=رنگها را از هر جایی برگزیده و مقادیر آنها را به دست می‌آورد.
+Comment[fi]=Valitse värejä kaikkialta ja tutki värien arvoja
+Comment[fo]=Vel litir frá skriviborði.
+Comment[fr]=Capture une couleur n'importe où et obtient sa composition
+Comment[fy]=Kies kleuren fan elk willekeurich plak en krij harren wearden
+Comment[ga]=Roghnaigh dath ó áit ar bith agus faigh a luach
+Comment[gl]=Extrai as cores de calquer sítio e obtén os seus valores
+Comment[he]=בחירת צבעים מכל מקום שהוא וקבלת ערכיהם
+Comment[hi]=कहीं से भी रंग चुने तथा उसका मान प्रदर्शित करता है
+Comment[hr]=Odabir boja s bilo kojeg mjesta i iščitavanje njihovih vrijednosti
+Comment[hu]=Színleolvasás a képernyő bármely képpontjáról
+Comment[is]=Velja liti hvaðan sem er af skjánum og fá tölugildi þeirra
+Comment[it]=Scegli un colore da un posto qualsiasi e scopri il suo valore
+Comment[ja]=色を抽出してそれの値を読み込みます
+Comment[ka]=ნებისმიერი ადგილიდან იღებს ფერს, მათი მნიშვნელობის მისაღებად
+Comment[kk]=Кез келген жерден түсті шұқып, параметрлерін алу
+Comment[km]=រើស​ពណ៌​ពី​​កន្លែង​ណាមួយ ​និង​យក​តម្លៃ​របស់​ពួក​វា
+Comment[ko]=어디에 있는 색이든 고를 수 있는 도구
+Comment[lt]=Paima iš bet kur spalvas ir parodo jų reikšmes
+Comment[lv]= Lasa krāsas no jebkurienes un iegūst to vērtības
+Comment[mk]=Избира бои од каде било и ги зема нивните вредности
+Comment[ms]=Memungut warna dari mana-mana dan dapatkan nilainya
+Comment[mt]=Agħżel kulur minn fejn trid u ħu l-valur tiegħu
+Comment[nb]=Plukk opp farger fra hvor som helst og se verdiene deres
+Comment[nds]=Klören jichtenswo utsöken un ehr Weerten faststellen
+Comment[ne]=सबै ठाउको रङ लिनुहोस् र तिनका मान प्राप्त गर्नुहोस्
+Comment[nl]=Kies kleuren van elke willekeurige plek en verkrijg hun waarden
+Comment[nn]=Plukk fargar frå kvar som helst og finn verdien deira
+Comment[pa]=ਕਿਤੋਂ ਵੀ ਰੰਗ ਵੀ ਚੁੱਕੋ ਅਤੇ ਉਹਨਾਂ ਦੇ ਮੁੱਲ ਲਵੋ
+Comment[pl]=Wybierz kolory z dowolnego miejsca i pobierz ich wartości
+Comment[pt]=Extrai as cores de qualquer sítio e obtém os seus valores
+Comment[pt_BR]=Selecione as cores de qualquer lugar e obtenha seus valores
+Comment[ro]=Preia culori de oriunde şi afişează valorile lor
+Comment[ru]=Подбирает цвет из любого места экрана и показывает его значение
+Comment[sk]=Výber farieb z ktoréhokoľvek miesta a získanie ich hodnôt
+Comment[sl]=Pobira barve od vsepovsod in dobiva njihove vrednosti
+Comment[sr]=Узмите узорак боје одакле било и сазнајте њену вредност
+Comment[sr@Latn]=Uzmite uzorak boje odakle bilo i saznajte njenu vrednost
+Comment[sv]=Välj färger var som helst och få deras värden
+Comment[ta]=எங்கிருந்தும் வண்ணங்களைத் எடுத்து அதன் மதிப்புகளை பெறு
+Comment[tg]=Интихоб кардани ранг аз ҳар ҷойи экран ва нишон додани қимати ӯ
+Comment[th]=เลือกสีจากที่ใด ๆ และรับค่าของมัน
+Comment[tr]=Herhangi bir yerden renk seçer ve değerlerini alır
+Comment[uk]=Вибирає кольори будь-звідки та отримує їхні значення
+Comment[uz]=Ekranning istalgan joyidan rang va uning qiymatini olish
+Comment[uz@cyrillic]=Экраннинг исталган жойидан ранг ва унинг қийматини олиш
+Comment[ven]=Zwi doba mivhala hothe na hothe zwa wana kuitele kwazwo
+Comment[vi]=Kén màu từ bất cứ nơi nào và lấy giá trị của nó
+Comment[xh]=Khetha imibala esuka naphi na ze ufumane amaxabiso awo
+Comment[zh_CN]=从任何地方获取颜色值
+Comment[zh_TW]=從點選的地方取得顏色值
+Comment[zu]=Cosha imibala kunoma ikephi kanye namabizo azo ufumane amaxabiso ayo
+X-KDE-Library=kolourpicker_panelapplet
+X-KDE-UniqueApplet=true
+DocPath=kicker-applets/kolourpicker.html
+X-KDE-ParentApp=applets
diff --git a/kicker-applets/kolourpicker/kolourpicker.h b/kicker-applets/kolourpicker/kolourpicker.h
new file mode 100644
index 0000000..0b576e9
--- /dev/null
+++ b/kicker-applets/kolourpicker/kolourpicker.h
@@ -0,0 +1,70 @@
+/* This file is part of Kolourpicker
+ Copyright (c) 2001 Malte Starostik <[email protected]>
+
+ 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 _KOLOURPICKER_H_
+#define _KOLOURPICKER_H_
+
+#include <qmap.h>
+#include <qvaluelist.h>
+
+#include <kpanelapplet.h>
+
+#include "simplebutton.h"
+
+class KInstance;
+class QPopupMenu;
+
+class KolourPicker : public KPanelApplet
+{
+ Q_OBJECT
+public:
+ KolourPicker(const QString& configFile, Type t = Normal, int actions = 0,
+ QWidget *parent = 0, const char *name = 0);
+ ~KolourPicker();
+ virtual int heightForWidth(int) const;
+ virtual int widthForHeight(int) const;
+ virtual void about();
+
+protected:
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual void resizeEvent(QResizeEvent*);
+
+private slots:
+ void slotPick();
+ void slotHistory();
+
+private:
+ QPopupMenu *copyPopup(const QColor &, bool title) const;
+ QPixmap colorPixmap(const QColor &) const;
+ const QStringList &colorNames(int r, int g, int b) const;
+ void arrangeButtons();
+ void setClipboard(const QString& text);
+
+ KInstance *m_instance;
+ bool m_picking;
+ SimpleButton *m_historyButton, *m_colourButton;
+ QValueList<QColor> m_history;
+ QMap<int, QStringList> m_colorNames;
+};
+
+#endif
+
+// vim: ts=4 sw=4 noet
diff --git a/kicker-applets/kolourpicker/simplebutton.cpp b/kicker-applets/kolourpicker/simplebutton.cpp
new file mode 100644
index 0000000..9daa926
--- /dev/null
+++ b/kicker-applets/kolourpicker/simplebutton.cpp
@@ -0,0 +1,256 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <[email protected]>
+ Copyright (C) 2004-2005 Aaron J. Seigo <[email protected]>
+
+ 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/kolourpicker/simplebutton.h b/kicker-applets/kolourpicker/simplebutton.h
new file mode 100644
index 0000000..5423dff
--- /dev/null
+++ b/kicker-applets/kolourpicker/simplebutton.h
@@ -0,0 +1,89 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <[email protected]>
+ Copyright (C) 2004-2005 Aaron J. Seigo <[email protected]>
+
+ 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/ktimemon/Makefile.am b/kicker-applets/ktimemon/Makefile.am
new file mode 100644
index 0000000..fee10c7
--- /dev/null
+++ b/kicker-applets/ktimemon/Makefile.am
@@ -0,0 +1,22 @@
+kde_module_LTLIBRARIES = ktimemon_panelapplet.la
+
+ktimemon_panelapplet_la_SOURCES = confdlg.cc sample.cc timemon.cc
+METASOURCES = AUTO
+
+noinst_HEADERS = confdlg.h sample.h timemon.h
+
+INCLUDES= $(all_includes)
+
+ktimemon_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+ktimemon_panelapplet_la_LIBADD = $(LIB_KDEUI) $(LIBKSTAT) $(LIB_KIO)
+
+KDE_ICON = ktimemon
+
+lnk_DATA = ktimemon.desktop
+lnkdir = $(kde_datadir)/kicker/applets
+
+EXTRA_DIST = $(lnk_DATA)
+
+messages:
+ $(XGETTEXT) *.cc -o $(podir)/ktimemon.pot
+
diff --git a/kicker-applets/ktimemon/README b/kicker-applets/ktimemon/README
new file mode 100644
index 0000000..ec8fb3a
--- /dev/null
+++ b/kicker-applets/ktimemon/README
@@ -0,0 +1,65 @@
+
+This is the CVS version of KTimemon. Check out the original authors
+homepage at
+
+http://www.fortunecity.com/victorian/university/394/sw/ktimemon.html
+
+for more information. This version is based (despite the original readme
+below says) on KTimemon 0.3b and modified to compile under KDE 2.0 &
+Qt 2.0 by Dirk A. Mueller <[email protected]>.
+
+2006-04-08: version 0.3c, modified to add iowait display
+by Michael Blakeley <[email protected]>
+
+Credits go to the original author(s) Helmut & Martin Maierhofer for
+writing such a useful tool and allowing me to include it into CVS :-).
+
+Please don't bother them with bugs, problems, etc. you may experience
+with this version. It's likely that they're my fault, so report them
+to [email protected]. Thanks!
+
+original README attached below....
+
+==========================================================================
+
+
+KTimemon 0.3a
+-------------
+
+KTimemon is a small but nifty system monitor, which can display information
+about CPU and memory/swap usage as well as ongoing paging/swapping and
+context switch activity. It is well integrated in KDE and can be
+configured graphically. For more information, see the associated
+documentation (before installation it can be found in ktimemon/doc/*.html)
+
+KTimemon works on Linux using the /proc filesystem, on Solaris using the
+kstat interface, and on Digital Unix (formerly known as DEC/OSF1) using
+the table() system call interface. If you can help me to port it to other
+platforms, please drop me a note!
+
+While I was able to test the system interface on Solaris and DEC/OSF1 in
+isolation, I could not test the whole application for lack of KDE on the
+machines I have access to. Hence I have no idea whether this thing
+actually compiles, let alone works on these platforms. The machines I tested
+were running DEC/OSF V4.0 and Solaris 2.5.1 respectively. If you get it to
+work (or not) on such a system, please let me know!
+
+
+Noteworthy changes from version 0.2:
+- Port to DEC/OSF1 and Solaris
+- Configurable mouse bindings
+- Slight rearrangement of memory information
+- Bars can be displayed vertically
+- Improved (actually working) configuration interface
+- Fixed a few bugs and doubtlessly introduced some more
+
+Version 0.3a has only minor improvements over 0.3:
+- New tooltips with numeric information about system load
+- Translation fixes
+
+Note that some of the configuration entry names have changed from version
+0.2 to 0.3, so you may want to delete your current configuration in
+$(HOME)/.kde/share/config/ktimemonrc and start with a fresh installation
+if you are upgrading from 0.2
+
diff --git a/kicker-applets/ktimemon/TODO b/kicker-applets/ktimemon/TODO
new file mode 100644
index 0000000..eec7578
--- /dev/null
+++ b/kicker-applets/ktimemon/TODO
@@ -0,0 +1,13 @@
+* port it to more platforms (what about remote monitoring?)
+
+* include some sort of support for SMP status (smaller bars?); also for
+ multiple swap partitions/files?
+
+* make it more flexible (plug-in concept?)
+
+* improve documentation (add images?), better internationalisation
+
+* add help button in configuration dialog
+
+* have some way of attaching watchdogs (e.g. if %idle > 90 for more than
+ 10 seconds, do this or that (or pop up a dialog))
diff --git a/kicker-applets/ktimemon/confdlg.cc b/kicker-applets/ktimemon/confdlg.cc
new file mode 100644
index 0000000..ff5ab9d
--- /dev/null
+++ b/kicker-applets/ktimemon/confdlg.cc
@@ -0,0 +1,295 @@
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/**********************************************************************/
+
+/*
+ * confdlg.h
+ *
+ * Definitions for the timemon configuration dialog.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <qgroupbox.h>
+#include <qlineedit.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qvgroupbox.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+
+#include <kcolorbutton.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurlrequester.h>
+
+#include "confdlg.h"
+#include "timemon.h"
+
+// -- KConfDialog definition ---------------------------------------------
+
+KConfDialog::KConfDialog(KTimeMon *t)
+ : KDialogBase( Tabbed, i18n("Configuration" ),
+ Ok|Cancel|Apply, Ok, t, 0, false ),
+ timemon(t)
+{
+ QFrame *page;
+ QBoxLayout *bl;
+ QGridLayout *gl;
+ QLabel *l;
+ QGroupBox *b;
+ KColorButton *cb;
+ unsigned i, j;
+
+ setIcon( SmallIcon( "ktimemon" ) );
+
+ // first tab: general
+ page = addPage( i18n( "&General" ) );
+
+ bl = new QVBoxLayout(page, 0, spacingHint());
+
+ b = new QVGroupBox(i18n("Sample &Rate"), page);
+ bl->addWidget(b);
+
+ intervalEdit = new KIntNumInput(250, b);
+ intervalEdit->setRange(20, 1000, 10);
+ intervalEdit->setSuffix(i18n(" msec"));
+
+ // scaling group box
+ b = new QVGroupBox(i18n("Scaling"), page);
+ bl->addWidget(b);
+
+ bl->addStretch();
+
+ autoScaleBox = new QCheckBox(i18n("&Automatic"), b);
+ connect(autoScaleBox, SIGNAL(toggled(bool)), this, SLOT(toggle(bool)));
+
+ pageScaleEdit = new KIntNumInput(intervalEdit, 1000, b);
+ pageScaleEdit->setRange(10, 10000, 10);
+ pageScaleEdit->setLabel(i18n("&Paging:"), AlignVCenter | AlignLeft);
+
+ swapScaleEdit = new KIntNumInput(pageScaleEdit, 1000, b);
+ swapScaleEdit->setRange(1, 10000, 5);
+ swapScaleEdit->setLabel(i18n("&Swapping:"), AlignVCenter | AlignLeft);
+
+ ctxScaleEdit = new KIntNumInput(swapScaleEdit, 10000, b);
+ ctxScaleEdit->setLabel(i18n("&Context switch:"), AlignVCenter | AlignLeft);
+ ctxScaleEdit->setRange(1, 10000, 30);
+
+ bl->addStretch(1);
+
+ // second tab: colours
+ page = addPage( i18n( "C&olors" ) );
+
+ gl = new QGridLayout(page, 12, 10, 0, spacingHint());
+
+ gl->setColStretch(3, 1); gl->setColStretch(6, 1); // eat up horizontal space
+ gl->setRowStretch(11, 1); // eat up vertical space
+
+ gl->addRowSpacing(0, 20); gl->addRowSpacing(4, 20); gl->addRowSpacing(8, 20);
+ gl->addRowSpacing(2, 8); gl->addRowSpacing(6, 8); gl->addRowSpacing(10, 8);
+
+ gl->addColSpacing(0, 10); gl->addColSpacing(9, 25);
+
+ QString cpuColourLabels[4];
+ cpuColourLabels[0] = i18n("Kernel:");
+ cpuColourLabels[1] = i18n("User:");
+ cpuColourLabels[2] = i18n("Nice:");
+ cpuColourLabels[3] = i18n("IOWait:");
+
+ QString memColourLabels[4];
+ memColourLabels[0] = i18n("Kernel:");
+ memColourLabels[1] = i18n("Used:");
+ memColourLabels[2] = i18n("Buffers:");
+ memColourLabels[3] = i18n("Cached:");
+
+ KColorButton **cpuColourButtons[4] = { &kernelCB, &userCB, &niceCB, &iowaitCB };
+ b = new QGroupBox(i18n("CPU"), page);
+ gl->addMultiCellWidget(b, 0, 2, 0, 13);
+
+ for (j = 0; j < 4; j++) {
+ l = new QLabel(cpuColourLabels[j], page);
+ gl->addWidget(l, 1, 3*j+1, AlignVCenter | AlignRight);
+
+ cb = *cpuColourButtons[j] = new KColorButton(white, page);
+ gl->addWidget(cb, 1, 3*j+2, AlignCenter);
+
+ connect(cb, SIGNAL(changed(const QColor &)),
+ this, SLOT(updateSampleWidget(const QColor &)));
+ }
+
+ KColorButton **memColourButtons[4] = { &mkernelCB, &usedCB, &buffersCB, &cachedCB };
+ b = new QGroupBox(i18n("Memory"), page);
+ gl->addMultiCellWidget(b, 4, 6, 0, 13);
+
+ for (j = 0; j < 4; j++) {
+ l = new QLabel(memColourLabels[j], page);
+ gl->addWidget(l, 5, 3*j+1, AlignVCenter | AlignRight);
+
+ cb = *memColourButtons[j] = new KColorButton(white, page);
+ gl->addWidget(cb, 5, 3*j+2, AlignCenter);
+
+ connect(cb, SIGNAL(changed(const QColor &)),
+ this, SLOT(updateSampleWidget(const QColor &)));
+ }
+
+ b = new QGroupBox(i18n("Swap"), page);
+ gl->addMultiCellWidget(b, 8, 10, 0, 6);
+
+ l = new QLabel(i18n("Swap:"), page);
+ gl->addWidget(l, 9, 1, AlignVCenter | AlignRight);
+
+ cb = swapCB = new KColorButton(red, page);
+ gl->addWidget(cb, 9, 2);
+
+ connect(cb, SIGNAL(changed(const QColor &)),
+ this, SLOT(updateSampleWidget(const QColor &)));
+
+ l = new QLabel(i18n("Backgd:"), page);
+ gl->addWidget(l, 9, 4, AlignVCenter | AlignRight);
+
+ cb = bgCB = new KColorButton(blue, page);
+ gl->addWidget(cb, 9, 5);
+
+ connect(cb, SIGNAL(changed(const QColor &)),
+ this, SLOT(updateSampleWidget(const QColor &)));
+
+ //b = new QGroupBox(i18n("Sample"), page);
+ //gl->addMultiCellWidget(b, 8, 10, 7, 9);
+
+ // third tab: interaction
+ page = addPage( i18n( "&Interaction" ) );
+
+ bl = new QVBoxLayout(page, 0, spacingHint());
+
+ b = new QGroupBox(i18n("Mouse Events"), page);
+ b->setColumnLayout( 0, Qt::Vertical );
+ bl->addWidget(b);
+ bl->addStretch();
+
+ QVBoxLayout *vbox = new QVBoxLayout( b->layout() );
+
+ gl = new QGridLayout(b, MAX_MOUSE_ACTIONS + 1, 3, 0, 6 );
+
+ vbox->addLayout( gl );
+
+ for (i = 1; i < MAX_MOUSE_ACTIONS + 1; i++)
+ gl->setRowStretch(i, 1);
+ gl->setColStretch(2, 1);
+
+ QString buttonText[MAX_MOUSE_ACTIONS] = { i18n("Left button:"),
+ i18n("Middle button:"),
+ i18n("Right button:") };
+
+ for (i = 0; i < (int) MAX_MOUSE_ACTIONS; i++) {
+
+ l = new QLabel(buttonText[i], b);
+ gl->addWidget(l, i+1, 0);
+
+ mouseC[i] = new KComboBox(false, b);
+ mouseC[i]->insertItem(i18n("Is Ignored"), KTimeMon::NOTHING);
+// SWITCH doesn't DO anything. remove it from config dialog for now
+// mouseC[i]->insertItem(i18n("Switches Mode"), KTimeMon::SWITCH);
+ mouseC[i]->insertItem(i18n("Pops Up Menu"), KTimeMon::MENU - 1);
+ mouseC[i]->insertItem(i18n("Starts"), KTimeMon::COMMAND - 1);
+ gl->addWidget(mouseC[i], i+1, 1);
+
+ connect( mouseC[ i ], SIGNAL( activated( int ) ), this,
+ SLOT( mouseCommandEnable() ) );
+
+ mouseLE[i] = new KURLRequester(b);
+ mouseLE[i]->lineEdit()->setText(t->mouseActionCommand[i]);
+ gl->addWidget(mouseLE[i], i+1, 2);
+ }
+
+ gl->activate();
+
+ resize(380, 300);
+
+ connect(this, SIGNAL(applyClicked()), timemon, SLOT(apply()));
+ connect(this, SIGNAL(okClicked()), timemon, SLOT(apply()));
+}
+
+// Adjust the colours of the sample widget in the configuration dialog.
+void KConfDialog::updateSampleWidget(const QColor &)
+{
+#if 0
+ sample->kernelColour = kernelCB->color();
+ sample->userColour = userCB->color();
+ sample->niceColour = niceCB->color();
+ sample->iowaitColour = iowaitCB->color();
+ sample->kernelColour = kernelCB->color();
+ sample->cachedColour = cachedCB->color();
+ sample->usedColour = usedCB->color();
+ sample->buffersColour = buffersCB->color();
+ sample->swapColour = swapCB->color();
+ sample->bgColour = bgCB->color();
+ sample->update();
+#endif
+}
+
+// -----------------------------------------------------------------------------
+
+// enable/disable the scale widgets
+void KConfDialog::toggle(bool state)
+{
+ swapScaleEdit->setEnabled(!state);
+ pageScaleEdit->setEnabled(!state);
+ ctxScaleEdit->setEnabled(!state);
+}
+
+void KConfDialog::mouseCommandEnable()
+{
+ for ( int i = 0; i < MAX_MOUSE_ACTIONS; i++ ) {
+ unsigned action = mouseC[ i ]->currentItem();
+
+ // the - 1 is for compat with the no longer shown Switch option
+ mouseLE[ i ]->setEnabled( action == KTimeMon::COMMAND - 1);
+ }
+}
+
+// update the dialog fields
+void KConfDialog::update()
+{
+ intervalEdit->setValue(timemon->interval);
+ kernelCB->setColor(timemon->kernelColour);
+ userCB->setColor(timemon->userColour);
+ niceCB->setColor(timemon->niceColour);
+ iowaitCB->setColor(timemon->iowaitColour);
+ buffersCB->setColor(timemon->buffersColour);
+ mkernelCB->setColor(timemon->mkernelColour);
+ usedCB->setColor(timemon->usedColour);
+ cachedCB->setColor(timemon->cachedColour);
+ swapCB->setColor(timemon->swapColour);
+ bgCB->setColor(timemon->bgColour);
+ pageScaleEdit->setValue(timemon->pageScale);
+ swapScaleEdit->setValue(timemon->swapScale);
+ ctxScaleEdit->setValue(timemon->ctxScale);
+ autoScaleBox->setChecked(timemon->autoScale);
+
+ for ( int i = 0; i < MAX_MOUSE_ACTIONS; i++ )
+ {
+ int action = timemon->mouseAction[i];
+ if (action > 0)
+ --action; // compat for the no longer shown Switch action
+ mouseC[i]->setCurrentItem(action);
+ }
+ mouseCommandEnable();
+
+ updateSampleWidget(white); // fake colour
+}
+
+unsigned int KConfDialog::getMouseAction(int i) const
+{
+ int action = mouseC[i]->currentItem();
+
+ if (action > 0)
+ ++action; // compat for the no longer shown Switch action
+
+ return action;
+}
+
+#include "confdlg.moc"
diff --git a/kicker-applets/ktimemon/confdlg.h b/kicker-applets/ktimemon/confdlg.h
new file mode 100644
index 0000000..d458bf2
--- /dev/null
+++ b/kicker-applets/ktimemon/confdlg.h
@@ -0,0 +1,99 @@
+/* -*- C++ -*- */
+
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/* */
+/* Ported to KDE 2.0 and other stuff: */
+/* Copyright (c) Dirk A. Mueller <[email protected]> */
+/* */
+/**********************************************************************/
+
+/*
+ * confdlg.h
+ *
+ * Definitions for the timemon configuration dialog.
+ */
+
+#ifndef CONFDLG_H
+#define CONFDLG_H
+
+#include <qcolor.h>
+#include <qcheckbox.h>
+#include <qtabdialog.h>
+
+#include <kcolorbutton.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <knuminput.h>
+#include <kdialogbase.h>
+#include <kurlrequester.h>
+
+#include "timemon.h"
+
+// -- forward declaration ------------------------------------------------
+
+class KTimeMon;
+class QLineEdit;
+class QSlider;
+class KColorButton;
+
+// -- KConfDialog declaration --------------------------------------------
+
+/*
+ * KConfDialog
+ */
+
+class KConfDialog : public KDialogBase
+{
+
+ Q_OBJECT
+
+public:
+ KConfDialog(KTimeMon *timemon);
+ ~KConfDialog() {}
+
+ void update(); // get values from timemon
+
+ unsigned getInterval() const { return intervalEdit->value(); }
+ QColor getKernelColour() const { return kernelCB->color(); }
+ QColor getUserColour() const { return userCB->color(); }
+ QColor getNiceColour() const { return niceCB->color(); }
+ QColor getIOWaitColour() const { return iowaitCB->color(); }
+ QColor getCachedColour() const { return cachedCB->color(); }
+ QColor getUsedColour() const { return usedCB->color(); }
+ QColor getBuffersColour() const { return buffersCB->color(); }
+ QColor getMKernelColour() const { return mkernelCB->color(); }
+ QColor getSwapColour() const { return swapCB->color(); }
+ QColor getBgColour() const { return bgCB->color(); }
+
+ bool getAutoScale() const { return autoScaleBox->isChecked(); }
+ unsigned getPageScale() const { return pageScaleEdit->value(); }
+ unsigned getSwapScale() const { return swapScaleEdit->value(); }
+ unsigned getCtxScale() const { return ctxScaleEdit->value(); }
+
+ unsigned getMouseAction(int i) const;
+ QString getMouseActionCommand(int i) const { return mouseLE[i]->lineEdit()->text(); }
+
+private slots:
+ void updateSampleWidget(const QColor &); // update colours in configuration
+ void toggle(bool state); // enable/disable scales
+ void mouseCommandEnable();
+
+private:
+
+ KTimeMon *timemon;
+ KIntNumInput *intervalEdit, *swapScaleEdit, *pageScaleEdit, *ctxScaleEdit;
+ QLineEdit *procFileEdit;
+ QCheckBox *autoScaleBox;
+ KColorButton *kernelCB, *userCB, *niceCB, *iowaitCB;
+ KColorButton *buffersCB, *usedCB, *cachedCB, *mkernelCB;
+ KColorButton *swapCB, *bgCB;
+ KURLRequester *mouseLE[MAX_MOUSE_ACTIONS];
+ KComboBox *mouseC[MAX_MOUSE_ACTIONS];
+ bool haveWarned;
+
+ friend class KTimeMon;
+};
+
+#endif // CONFDLG_H
diff --git a/kicker-applets/ktimemon/configure.in.in b/kicker-applets/ktimemon/configure.in.in
new file mode 100644
index 0000000..7b9657e
--- /dev/null
+++ b/kicker-applets/ktimemon/configure.in.in
@@ -0,0 +1,3 @@
+AC_CHECK_HEADERS(fcntl.h)
+AC_CHECK_LIB(kstat, kstat_open, LIBKSTAT="-lkstat")
+AC_SUBST(LIBKSTAT)
diff --git a/kicker-applets/ktimemon/cr16-app-ktimemon.png b/kicker-applets/ktimemon/cr16-app-ktimemon.png
new file mode 100644
index 0000000..d9295e6
--- /dev/null
+++ b/kicker-applets/ktimemon/cr16-app-ktimemon.png
Binary files differ
diff --git a/kicker-applets/ktimemon/cr32-app-ktimemon.png b/kicker-applets/ktimemon/cr32-app-ktimemon.png
new file mode 100644
index 0000000..71ff476
--- /dev/null
+++ b/kicker-applets/ktimemon/cr32-app-ktimemon.png
Binary files differ
diff --git a/kicker-applets/ktimemon/ktimemon.desktop b/kicker-applets/ktimemon/ktimemon.desktop
new file mode 100644
index 0000000..9f9013e
--- /dev/null
+++ b/kicker-applets/ktimemon/ktimemon.desktop
@@ -0,0 +1,129 @@
+[Desktop Entry]
+Type=Plugin
+Icon=ktimemon
+X-KDE-Library=ktimemon_panelapplet
+X-KDE-UniqueApplet=true
+Comment=A simple system monitor
+Comment[ar]=مراقب النظام بسيط
+Comment[bg]=Системен монитор за KDE
+Comment[br]=Un diskweler reizhiad eeun
+Comment[ca]=Un monitor del sistema senzill
+Comment[cs]=Jednoduchý monitor systému
+Comment[da]=En simpel systemovervåger til KDE
+Comment[de]=Ein einfacher Systemmonitor
+Comment[el]=Ένας απλός επόπτης συστήματος
+Comment[eo]=Simpla sistemobservilo
+Comment[es]=Un monitor de sistema sencillo
+Comment[et]=Lihtne süsteemi monitor
+Comment[eu]=Sistemaren monitore sinplea
+Comment[fa]=نمایشگر سیستم ساده
+Comment[fi]=Yksinkertainen järjestelmänvalvontaohjelma
+Comment[fr]=Un moniteur système simple
+Comment[fy]=In ienfâldige systeemmonitor
+Comment[ga]=Monatóir simplí an chórais
+Comment[gl]=Un monitor do sistema simples
+Comment[he]=צג מערכת פשוט עבור KDE
+Comment[hr]=Jednostavan nadzor sustava
+Comment[hu]=Egyszerű rendszermonitor
+Comment[is]=Einfalt kerfiseftirlit
+Comment[it]=Un semplice monitor di sistema
+Comment[ja]=シンプルなシステムモニタ
+Comment[ka]=მარტივი სისტემური მონიტორი
+Comment[kk]=Қарапайым жүйе қадағалауышы
+Comment[km]=កម្មវិធី​ត្រួត​ពិនិត្យ​ប្រព័ន្ធ​​ធម្មតា​មួយ
+Comment[lt]=Sistemos stebėjimo priemonė
+Comment[mk]=Едноставен набљудувач на системот
+Comment[nb]=En enkel systemovervåker
+Comment[nds]=En eenfach Systeemkieker
+Comment[ne]=एउट सामान्य प्रणाली मनिटर
+Comment[nl]=Een eenvoudige systeemmonitor
+Comment[nn]=Ein enkel systemovervakar
+Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਸਿਸਟਮ ਨਿਗਰਾਨ
+Comment[pl]=Prosty monitor systemu
+Comment[pt]=Um monitor do sistema simples
+Comment[pt_BR]=Um monitor de sistema simples
+Comment[ru]=Простой системный монитор
+Comment[sk]=Jednoduchý monitor systému
+Comment[sl]=Preprost nadzornik sistema
+Comment[sr]=Једноставно надгледање система
+Comment[sr@Latn]=Jednostavno nadgledanje sistema
+Comment[sv]=En enkel systemövervakare
+Comment[tr]=Basit bir sistem izleyici
+Comment[uk]=Простий системний монітор
+Comment[uz]=Tizimni nazorat qilish uchun oddiy vosita
+Comment[uz@cyrillic]=Тизимни назорат қилиш учун оддий восита
+Comment[vi]=Bộ theo dõi hệ thống đơn giản
+Comment[zh_CN]=简单的系统监视器
+Comment[zh_TW]=簡單的系統監視器
+Name=System Monitor
+Name[af]=Stelsel Monitor
+Name[ar]=مراقب النظام
+Name[az]=Sistem İzləyici
+Name[bg]=Системен монитор
+Name[br]=Diskwel saviad ar reizhiad
+Name[bs]=Stanje sistema
+Name[ca]=Monitor del sistema
+Name[cs]=Monitor systému
+Name[cy]=Gwarchodydd Cysawd
+Name[da]=Systemovervåger
+Name[de]=Systemmonitor
+Name[el]=Εποπτεία συστήματος
+Name[eo]=Sistemobservilo
+Name[es]=Monitor de sistema
+Name[et]=Süsteemi monitor
+Name[eu]=Sistemaren monitorea
+Name[fa]=نمایشگر سیستم
+Name[fi]=Järjestelmänvalvonta
+Name[fo]=Skipanaryvirvakari
+Name[fr]=Surveillance du système
+Name[fy]=Systeemmonitor
+Name[ga]=Monatóir Córais
+Name[gl]=Monitor do Sistema
+Name[he]=צג מערכת
+Name[hi]=तंत्र मॉनीटर
+Name[hr]=Nadzor sustava
+Name[hu]=Rendszermonitor
+Name[is]=Kerfiseftirlit
+Name[it]=Monitor di sistema
+Name[ja]=システムモニタ
+Name[ka]=სისტემური მონიტორი
+Name[kk]=Жүйе қадағалауышы
+Name[km]=កម្មវិធី​ត្រួត​ពិនិត្យ​ប្រព័ន្ធ
+Name[ko]=시스템 지켜보기
+Name[lt]=Sistemos stebėtojas
+Name[lv]=Sistēmas Monitors
+Name[mk]=Набљудувач на системот
+Name[ms]=Monitor Sistem
+Name[mt]=Monitur tas-sistema
+Name[nb]=Systemovervåker
+Name[nds]=Systeemkieker
+Name[ne]=प्रणाली मनिटर
+Name[nl]=Systeemmonitor
+Name[nn]=Systemovervakar
+Name[pa]=ਸਿਸਟਮ ਨਿਗਰਾਨ
+Name[pl]=Monitor systemu
+Name[pt]=Monitor do Sistema
+Name[pt_BR]=Monitor do sistema
+Name[ro]=Monitor de sistem
+Name[ru]=Системный монитор
+Name[sk]=Monitor systému
+Name[sl]=Sistemski nadzornik
+Name[sr]=Надгледање система
+Name[sr@Latn]=Nadgledanje sistema
+Name[sv]=Systemövervakare
+Name[ta]=அமைப்பு திரை
+Name[tg]=Монитори системавӣ
+Name[th]=สอดส่องระบบ
+Name[tr]=Sistem İzleyici
+Name[uk]=Системний монітор
+Name[uz]=Oddiy tizim nazoratchisi
+Name[uz@cyrillic]=Оддий тизим назоратчиси
+Name[ven]=Monitha wa Sistemu
+Name[vi]=Bộ theo dõi hệ thống
+Name[xh]=Indlela yokwenza yeCebo lokubonisa
+Name[zh_CN]=系统监视器
+Name[zh_TW]=系統監視器
+Name[zu]=Umphendli Wendlela esetshenziswayo
+DocPath=kicker-applets/ktimemon.html
+X-KDE-StartupNotify=true
+X-KDE-ParentApp=applets
diff --git a/kicker-applets/ktimemon/lo16-app-ktimemon.png b/kicker-applets/ktimemon/lo16-app-ktimemon.png
new file mode 100644
index 0000000..d9295e6
--- /dev/null
+++ b/kicker-applets/ktimemon/lo16-app-ktimemon.png
Binary files differ
diff --git a/kicker-applets/ktimemon/lo32-app-ktimemon.png b/kicker-applets/ktimemon/lo32-app-ktimemon.png
new file mode 100644
index 0000000..71ff476
--- /dev/null
+++ b/kicker-applets/ktimemon/lo32-app-ktimemon.png
Binary files differ
diff --git a/kicker-applets/ktimemon/sample.cc b/kicker-applets/ktimemon/sample.cc
new file mode 100644
index 0000000..25f25a3
--- /dev/null
+++ b/kicker-applets/ktimemon/sample.cc
@@ -0,0 +1,508 @@
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/**********************************************************************/
+
+/*
+ * sample.cc
+ *
+ * Definitions for the system dependent sampling class.
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <fstream>
+#include <stdio.h>
+
+#ifdef __osf__
+#include <sys/table.h>
+#elif defined(USE_SOLARIS)
+#include <kstat.h>
+#include <sys/sysinfo.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#endif
+
+#include <qwidget.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include "timemon.h"
+#include "sample.h"
+
+// -- global definitions -------------------------------------------------
+
+#if defined(__osf__) || defined(USE_SOLARIS)
+extern "C" int getpagesize(); // argh, have to define prototype!
+#endif
+
+#ifdef __linux__
+// -- global constants ---------------------------------------------------
+#define STAT_NAME "/proc/stat"
+#define MEMINFO_NAME "/proc/meminfo"
+#endif
+
+// -- KSample::Sample definition -----------------------------------------
+
+// Fill sample with some default values (e.g. used in preview widget
+// in configuration)
+void KSample::Sample::fill(unsigned scale)
+{
+ user = scale * 40; user /= 100;
+ nice = scale * 25; user /= 100;
+ kernel = scale * 10; kernel /= 100;
+ iowait = scale * 5; iowait /= 100;
+ cpus = 1;
+ buffers = scale * 20; buffers /= 100;
+ used = scale * 30; used /= 100;
+ cached = scale * 20; cached /= 100;
+ sused = scale * 25; sused /= 100;
+}
+
+// -- KSample definition -------------------------------------------------
+
+// Initialise the member variables and try to open the standard files in
+// the proc filesystem; for other platforms perform equivalent initialisation
+KSample::KSample(KTimeMon *t, bool a, unsigned p, unsigned s, unsigned c) :
+ timemon(t),
+#ifdef __linux__
+ memFD(-1), statFD(-1),
+#elif defined (USE_SOLARIS)
+ kc(0), warned(false),
+#endif
+ pageScale(p), swapScale(s), cxScale(c), autoscale(a)
+{
+#ifdef __linux__
+ memstats[0].name = "SwapTotal:";
+ memstats[0].stat = &sample.stotal;
+ memstats[1].name = "MemTotal:";
+ memstats[1].stat = &sample.mtotal;
+ memstats[2].name = "MemFree:";
+ memstats[2].stat = &sample.free;
+ memstats[3].name = "Buffers:";
+ memstats[3].stat = &sample.buffers;
+ memstats[4].name = "Cached:";
+ memstats[4].stat = &sample.cached;
+ memstats[5].name = "SwapFree:";
+ memstats[5].stat = &sample.sfree;
+ memstats[6].name = 0;
+ memstats[6].stat = 0;
+
+ if ((memFD = open(MEMINFO_NAME, O_RDONLY)) == -1) {
+ KMessageBox::error(timemon,
+ i18n("Unable to open the file '%1'. The diagnostics are:\n%2.\n"
+ "This file is required to determine current memory usage.\n"
+ "Maybe your proc filesystem is non-Linux standard?").arg(MEMINFO_NAME).arg(strerror(errno)));
+ exit(1);
+ }
+
+ fcntl( memFD,F_SETFD, FD_CLOEXEC );
+
+ if ((statFD = open(STAT_NAME, O_RDONLY)) == -1) {
+ KMessageBox::error(timemon,
+ i18n("Unable to open the file '%1'. The diagnostics are:\n%2.\n"
+ "This file is required to determine current system info. "
+ "Maybe your proc filesystem is non-Linux standard?").arg(MEMINFO_NAME).arg(strerror(errno)));
+ exit(1);
+ }
+
+ fcntl( statFD,F_SETFD, FD_CLOEXEC );
+
+#elif defined (USE_SOLARIS)
+ if ((kc = kstat_open()) == 0) {
+ KMessageBox::error(timemon, i18n("Unable to initialize the 'kstat' library. "
+ "This library is used for accessing kernel information. "
+ "The diagnostics are:\n%1.\n"
+ "Are you really running Solaris? "
+ "Please contact the maintainer at [email protected] "
+ "who will try to figure out what went wrong.").arg(strerror(errno)));
+ exit(1);
+ }
+#endif
+
+#if defined(USE_SOLARIS) || defined(__osf__)
+ pagesPerMB = (1024*1024) / getpagesize();
+ if (pagesPerMB == 0) pagesPerMB = 1; // paranoia sanity check
+#endif
+
+ readSample();
+ updateSample();
+}
+
+// Get rid of the resources we acquired in the constructor.
+KSample::~KSample()
+{
+#ifdef __linux__
+ close(memFD);
+ close(statFD);
+#elif defined (USE_SOLARIS)
+ if (kc != 0) kstat_close(kc);
+#endif
+}
+
+// Set the appropriate scaling parameters
+void KSample::setScaling(bool a, unsigned p, unsigned s, unsigned c)
+{
+ autoscale = a;
+ pageScale = p;
+ swapScale = s;
+ cxScale = c;
+}
+
+// -----------------------------------------------------------------------------
+// Show a message box with the given message and terminate the application.
+
+void KSample::fatal(const QString& msg)
+{
+ timemon->stop();
+
+ KMessageBox::error(timemon, msg);
+// exit(1);
+}
+
+
+// -----------------------------------------------------------------------------
+// Show a message box with the given message and don't terminate the app ;-)
+
+void KSample::nonfatal(const QString& msg)
+{
+ timemon->stop();
+
+ KMessageBox::sorry(timemon, msg);
+ timemon->cont();
+}
+
+
+// -----------------------------------------------------------------------------
+// Read a new sample from the files or whatever resource the OS implements
+
+/* For 2.5 kernels */
+static inline void
+scan_one(const char* buff, const char *key, unsigned long int* val)
+{
+ const char *b = strstr(buff, key);
+ if (b) {
+ b = strstr(b, " ");
+ if (b)
+ sscanf(b, " %lu", val);
+ }
+}
+
+void KSample::readSample()
+{
+ sample.cpus = 0; // just to make sure...
+
+#ifdef __linux__ // linux makes it simple: use the /proc if
+ int l;
+ char buffer[4096];
+
+ lseek(memFD, 0, 0);
+ if ((l = read(memFD, buffer, sizeof(buffer) - 1)) < 0)
+ {
+ fatal(i18n("Unable to read the memory usage file '%1'.\n"
+ "The diagnostics are: %2").arg(MEMINFO_NAME).arg(strerror(errno)));
+ }
+ buffer[l] = '\0';
+ l = 0;
+ char *p;
+ while (memstats[l].name != 0) {
+ p = strstr(buffer, memstats[l].name);
+ if (p == 0 ||
+ sscanf(p + strlen(memstats[l].name), "%lu kB", memstats[l].stat) < 1)
+ fatal(i18n("The memory usage file '%1' seems to use a "
+ "different file format than expected.\n"
+ "Maybe your version of the proc filesystem is "
+ "incompatible with supported versions. "
+ "Please contact the developer at http://bugs.kde.org/ who will try to sort this out.").arg(MEMINFO_NAME));
+ l++;
+ }
+
+ if ( ( p = strstr(buffer, "Slab:") ) ) {
+ unsigned long slabs;
+ sscanf(p + 5, "%lu kB", &slabs);
+ sample.mkernel = slabs;
+ }
+
+ /* read the data for the cpu stats */
+ lseek(statFD, 0, 0);
+ if ((l = read(statFD, buffer, sizeof(buffer)-1)) < 0)
+ fatal(i18n("Unable to read the system usage file '%1'.\n"
+ "The diagnostics are: %2").arg(STAT_NAME).arg(strerror(errno)));
+
+ buffer[l] = '\0';
+
+ bool ok = (sscanf(buffer, "cpu %lu %lu %lu %lu %lu", &sample.user,
+ &sample.nice, &sample.kernel, &sample.idle, &sample.iowait) == 5);
+
+ if (ok) {
+ for (l = 0; l < MAX_CPU; l++) { // get individual stat for SMP machines
+ char cpuname[10];
+ sprintf(cpuname, "cpu%d", l);
+
+ if ((p = strstr(buffer, cpuname)) == NULL) break;
+
+ unsigned long u, n, k, i;
+ ok = sscanf(p, "cpu%*d %lu %lu %lu %lu", &u, &n, &k, &i);
+ if (!ok) break;
+
+ sample.smptotal[l] = u+n+k+i;
+ sample.smpbusy[l] = sample.smptotal[l] - i;
+ }
+ }
+ sample.cpus = l;
+
+#elif defined(__osf__) // in OSF/2, we can use table()
+
+ QString msg = i18n("Unable to obtain system information.\n"
+ "The table(2) system call returned an error "
+ "for table %1.\n"
+ "Please contact the maintainer at [email protected] "
+ "who will try to figure out what went wrong.");
+
+ struct tbl_sysinfo sysinfo;
+ if (table(TBL_SYSINFO, 0, &sysinfo, 1, sizeof(sysinfo)) != 1)
+ fatal(msg.arg("TBL_SYSINFO"));
+
+ sample.user = sysinfo.si_user;
+ sample.nice = sysinfo.si_nice;
+ sample.kernel = sysinfo.si_sys;
+ sample.iowait = sysinfo.wait;
+ sample.idle = sysinfo.si_idle;
+
+ struct tbl_vmstats vmstats;
+ if (table(TBL_VMSTATS, 0, &vmstats, 1, sizeof(vmstats)) != 1)
+ fatal(msg.arg("TBL_VMSTATS"));
+
+ sample.mtotal = vmstats.free_count + vmstats.active_count +
+ vmstats.inactive_count + vmstats.wire_count;
+ sample.free = vmstats.free_count;
+ sample.buffers = vmstats.inactive_count; // pages not used for some time
+ sample.cached = vmstats.wire_count; // kernel/driver memory
+
+ struct tbl_swapinfo swapinfo;
+ if (table(TBL_SWAPINFO, -1, &swapinfo, 1, sizeof(swapinfo)) != 1)
+ fatal(msg.arg("TBL_SWAPINFO"));
+
+ sample.stotal = swapinfo.size;
+ sample.sfree = swapinfo.free;
+
+#elif defined(USE_SOLARIS)
+ kstat_t *ksp;
+
+ sample.cpus = 0;
+ for (ksp = kc->kc_chain; ksp != 0; ksp = ksp->ks_next) {
+ if (strncmp(ksp->ks_name, "cpu_stat", 8) != 0) continue;
+ sample.cpus++;
+ }
+
+ if (sample.cpus == 0)
+ fatal(i18n("Unable to find any entries for CPU statistics "
+ "in the 'kstat' library. Are you running a non-standard "
+ "version of Solaris?\n"
+ "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out."));
+
+ sample.user = sample.nice = sample.kernel = sample.iowait = sample.idle = 0;
+ sample.stotal = sample.sfree = 0;
+
+ int cpus = 0;
+ for (ksp = kc->kc_chain; ksp != 0; ksp = ksp->ks_next) {
+ if (strncmp(ksp->ks_name, "cpu_stat", 8) != 0) continue;
+ cpus++;
+
+ cpu_stat_t cstat;
+ if (kstat_read(kc, ksp, 0) == -1 || // update from kernel
+ kstat_read(kc, ksp, &cstat) == -1) // and read into buffer
+ fatal(i18n("Unable to read the CPU statistics entry "
+ "from the 'kstat' library. The diagnostics are '%1'.\n"
+ "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno)));
+
+ // fields are: idle user kernel iowait (no nice info?)
+ sample.user += cstat.cpu_sysinfo.cpu[1] / sample.cpus;
+ sample.nice += 0;
+ sample.kernel += cstat.cpu_sysinfo.cpu[2] / sample.cpus;
+ sample.iowait += cstat.cpu_sysinfo.cpu[3] / sample.cpus;
+ sample.idle += cstat.cpu_sysinfo.cpu[0] / sample.cpus;
+ }
+
+ if (cpus != sample.cpus)
+ fatal(i18n("The number of CPUs appears to have changed at "
+ "very short notice, or the 'kstat' library returns "
+ "inconsistent results (%1 vs. %2 CPUs).\n"
+ "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out.").arg(sample.cpus).arg(cpus));
+
+ // availrmem = pages of core for user-proc ( == physmem - kernelmem)
+ // freemem = no of free pages
+ // physmem == total mem in 4KB blocks
+
+ errno = 0;
+ if ((ksp = kstat_lookup(kc, "unix", -1, "system_pages")) == 0 ||
+ kstat_read(kc, ksp, 0) == -1)
+ fatal(i18n("Unable to read the memory statistics entry "
+ "from the 'kstat' library. The diagnostics are '%1'\n"
+ "You might want to contact the maintainer at "
+ "http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno)));
+
+ int i;
+ unsigned long physmem = 0, freemem = 0, availrmem = 0;
+
+ kstat_named_t *kn = (kstat_named_t *)ksp->ks_data;
+ for (i = 0; i < (int) ksp->ks_ndata; i++) {
+ if (strcmp(kn->name, "physmem") == 0) physmem = kn->value.ul;
+ else if (strcmp(kn->name, "freemem") == 0) freemem = kn->value.ul;
+ else if (strcmp(kn->name, "availrmem") == 0) availrmem = kn->value.ul;
+ kn++;
+ }
+
+ if (physmem == 0) // sanity check, this should always be > 0
+ fatal(i18n("There seems to be a problem with KTimeMon's handling "
+ "of the 'kstat' library: 0 bytes of physical memory determined!\n"
+ "Free memory is %1, available memory is %2.\n"
+ "Please contact the maintainer at [email protected] who will try to sort this out.").arg(freemem).arg(availrmem));
+
+ sample.mtotal = physmem;
+ sample.free = freemem;
+ sample.buffers = 0;
+ sample.cached = physmem - availrmem; // memory used by the kernel
+
+ int swapentries;
+ if ((swapentries = swapctl(SC_GETNSWP, 0)) == -1)
+ fatal(i18n("Unable to determine the number of "
+ "swap spaces. The diagnostics are '%1'.\n"
+ "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno)));
+
+ if (swapentries != 0) {
+ // 2* to get some space for padding??
+ swaptbl_t *stbl = (swaptbl_t *) malloc(2*sizeof(int) + swapentries *
+ sizeof(struct swapent));
+ if (stbl == 0)
+ fatal(i18n("KTimeMon ran out of memory while "
+ "trying to determine the swap usage.\n"
+ "Attempted to allocate %1 bytes of memory (2 * %2 + %3 * %4).\n"
+ "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.")
+ .arg(2 * sizeof(int) + swapentries * sizeof(struct swapent))
+ .arg(sizeof(int)).arg(swapentries).arg(sizeof(struct swapent)));
+
+ char path[1024];
+ stbl->swt_n = swapentries;
+ for (i = 0; i < swapentries; i++) stbl->swt_ent[i].ste_path = path;
+
+ if ((swapentries = swapctl(SC_LIST, stbl)) == -1)
+ fatal(i18n("Unable to determine the swap usage.\n"
+ "The diagnostics are '%1'.\n"
+ "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno)));
+
+
+ if (!warned && swapentries != stbl->swt_n) {
+ warned = true;
+ nonfatal(i18n("Information was requested for "
+ "%1 swap spaces, but only %2 swap entries were returned.\n"
+ "KTimeMon will attempt to continue.\n"
+ "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(stbl->swt_n).arg(swapentries));
+ }
+
+ for (i = 0; i < swapentries; i++) {
+ sample.stotal += stbl->swt_ent[i].ste_pages;
+ sample.sfree += stbl->swt_ent[i].ste_free;
+ }
+
+ free(stbl);
+ }
+
+#else
+#warning This type of system is not supported
+ sample.stotal = sample.sfree = 0;
+#endif
+
+ sample.cputotal =
+ sample.user + sample.nice + sample.kernel + sample.iowait + sample.idle;
+ sample.used = sample.mtotal - sample.mkernel - sample.free - sample.buffers - sample.cached;
+ sample.sused = sample.stotal - sample.sfree;
+}
+
+// Read a new sample after copying the old one.
+void KSample::updateSample()
+{
+ oldSample = sample;
+ readSample();
+}
+
+// Convert v to a value representing megabytes.
+inline void KSample::makeMBytes(unsigned long &v)
+{
+#ifdef __linux__
+ v /= 1024; // can it be simpler ;-)
+#elif defined (__osf__) || defined(USE_SOLARIS)
+ v /= pagesPerMB;
+#endif
+}
+
+// Return unscaled sample
+KSample::Sample KSample::getRawSample()
+{
+ Sample diff = sample;
+
+ diff.cputotal -= oldSample.cputotal;
+
+ diff.user -= oldSample.user;
+ diff.nice -= oldSample.nice;
+ diff.kernel -= oldSample.kernel;
+ diff.iowait -= oldSample.iowait;
+
+ for (int i = 0; i < diff.cpus; i++) {
+ diff.smptotal[i] -= oldSample.smptotal[i];
+ diff.smpbusy[i] -= oldSample.smpbusy[i];
+ }
+
+ return diff;
+}
+
+// Better scaling, round according to first decimal
+inline unsigned long KSample::doScale(unsigned long value, unsigned scale1,
+ unsigned long scale2)
+{
+ if (scale2 == 0) scale2 = (unsigned long)~0; // avoid SEGVs
+
+ unsigned long v = value * scale1 * 10;
+ v /= scale2;
+ unsigned r = v % 10;
+ v /= 10;
+ if (r > 4) v++;
+ return v;
+}
+
+// Provide the difference from the last to the current sample, scale it
+// and return it.
+KSample::Sample KSample::getSample(unsigned scale)
+{
+ Sample s = getRawSample();
+
+ s.user = doScale(s.user, scale, s.cputotal);
+ s.nice = doScale(s.nice, scale, s.cputotal);
+ s.kernel = doScale(s.kernel, scale, s.cputotal);
+ s.iowait = doScale(s.iowait, scale, s.cputotal);
+
+ for (int i = 0; i < s.cpus; i++)
+ s.smpbusy[i] = doScale(s.smpbusy[i], scale, s.smptotal[i]);
+
+ s.cached = doScale(s.cached, scale, s.mtotal);
+ s.buffers = doScale(s.buffers, scale, s.mtotal);
+ s.used = doScale(s.used, scale, s.mtotal);
+ s.mkernel = doScale(s.mkernel, scale, s.mtotal);
+ makeMBytes(s.mtotal);
+
+ s.sused = doScale(s.sused, scale, s.stotal);
+ makeMBytes(s.stotal);
+
+ return s;
+}
+
diff --git a/kicker-applets/ktimemon/sample.h b/kicker-applets/ktimemon/sample.h
new file mode 100644
index 0000000..b4a0723
--- /dev/null
+++ b/kicker-applets/ktimemon/sample.h
@@ -0,0 +1,94 @@
+/* -*- C++ -*- */
+
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/**********************************************************************/
+
+/*
+ * sample.h
+ *
+ * Definitions for the system dependent sampling class (currently relies
+ * on the linux /proc filesystem).
+ */
+
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+// -- global constants ---------------------------------------------------
+
+#define MAX_CPU 16 // max number of CPUS in an SMP machine
+ // we get the status for
+
+// -- forward declaration ------------------------------------------------
+class KTimeMon;
+
+#ifdef USE_SOLARIS
+struct kstat_ctl;
+#endif
+
+// -- class declaration --------------------------------------------------
+
+/*
+ * KSample
+ *
+ * This class is responsible for reading the /proc file system and parsing
+ * the system information.
+ */
+class KSample {
+public:
+ // -- Sample declaration -----------------------------------------------
+ struct Sample {
+ unsigned long cputotal;
+ unsigned long user, nice, kernel, iowait, idle;
+ int cpus;
+ unsigned long smptotal[MAX_CPU], smpbusy[MAX_CPU];
+ unsigned long mtotal, free, buffers, cached, mkernel, used;
+ unsigned long stotal, sused, sfree;
+
+ void fill(unsigned scale); // fill sample with some fake values
+ };
+
+ struct MemStats {
+ const char *name;
+ unsigned long *stat;
+ };
+
+ KSample(KTimeMon *timemon, bool autoScale, unsigned pageScale,
+ unsigned swapScale, unsigned ctxScale);
+ virtual ~KSample();
+
+ void setScaling(bool autoScale, unsigned pageScale,
+ unsigned swapScale, unsigned ctxScale);
+
+ Sample getSample(unsigned scale); // returns the current sample
+ Sample getRawSample(); // returns unscaled sample
+ void updateSample(); // updates the internally stored sample
+
+private:
+ void readSample(); // reads a new sample from /proc
+ unsigned long doScale(unsigned long value, unsigned scale1,
+ unsigned long scale2);
+ // converts pages to MB
+ void makeMBytes(unsigned long &pages);
+
+ void fatal(const QString& msg);
+ void nonfatal(const QString& msg);
+
+ KTimeMon *timemon;
+#ifdef __linux__
+ int memFD, statFD;
+#elif defined(USE_SOLARIS)
+ struct kstat_ctl *kc;
+ bool warned;
+#endif
+#if defined(USE_SOLARIS) || defined(__osf__)
+ unsigned long pagesPerMB;
+#endif
+ Sample sample, oldSample;
+ unsigned pageScale, swapScale, cxScale;
+ bool autoscale;
+ struct MemStats memstats[7];
+};
+
+#endif // SAMPLE_H
diff --git a/kicker-applets/ktimemon/timemon.cc b/kicker-applets/ktimemon/timemon.cc
new file mode 100644
index 0000000..84b0e79
--- /dev/null
+++ b/kicker-applets/ktimemon/timemon.cc
@@ -0,0 +1,435 @@
+
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/* maintained by Dirk A. Mueller <[email protected]> */
+/**********************************************************************/
+
+/*
+ * timemon.h
+ *
+ * Definitions for the timemon widget.
+ */
+
+#include <config.h>
+
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+
+#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <khelpmenu.h>
+#include <kpopupmenu.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+#include "timemon.h"
+#include "confdlg.h"
+#include "sample.h"
+
+#include "timemon.moc"
+#include <stdio.h>
+
+extern "C"
+{
+ KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile)
+ {
+ KGlobal::locale()->insertCatalogue("ktimemon");
+ KTimeMon *mon = new KTimeMon(configFile, KPanelApplet::Normal,
+ KPanelApplet::Preferences, parent, "ktimemon");
+ return mon;
+ }
+}
+
+// Update colour settings with the new ones from the config dialog.
+void KTimeMon::updateConfig(KConfDialog *d)
+{
+ kernelColour = d->getKernelColour();
+ userColour = d->getUserColour();
+ iowaitColour = d->getIOWaitColour();
+ niceColour = d->getNiceColour();
+ cachedColour = d->getCachedColour();
+ usedColour = d->getUsedColour();
+ buffersColour = d->getBuffersColour();
+ mkernelColour = d->getMKernelColour();
+ swapColour = d->getSwapColour();
+ bgColour = d->getBgColour();
+}
+
+// -----------------------------------------------------------------------------
+// some KPanelApplet API functions
+
+int KTimeMon::widthForHeight(int height) const
+{
+ int s = (int) (vertical ? 2/3.*height : height);
+ return s>=18? s : 18;
+}
+
+
+int KTimeMon::heightForWidth(int width) const
+{
+ int s = (int) (vertical ? width : 2/3.*width);
+ return s>=18? s : 18;
+}
+
+void KTimeMon::preferences()
+{
+ configure();
+}
+
+
+// -----------------------------------------------------------------------------
+// Repaint the object; get the current sample and paint the bar graphs
+// correspondingly. Use a pixmap to minimise flicker.
+
+void KTimeMon::paintEvent(QPaintEvent *)
+{
+ int w, h, x, y, b, r;
+
+ w = vertical ? width() : height();
+ h = vertical ? height() : width();
+
+ r = w; // remaining height
+
+ x = 0;
+
+ KSample::Sample s;
+
+ if (sample != 0)
+ s = sample->getSample(h);
+ else
+ s.fill(h);
+
+ QPixmap pixmap(width(), height());
+ pixmap.fill(this, 0, 0);
+
+ QPainter painter(&pixmap);
+
+ b = r / 3; // bar width
+ r -= b;
+
+ if (bgColour != colorGroup().background())
+ {
+ paintRect(x, 0, b, h, bgColour, &painter);
+ }
+
+ y = h - s.kernel; paintRect(x, y, b, s.kernel, kernelColour, &painter);
+ y -= s.iowait; paintRect(x, y, b, s.iowait, iowaitColour, &painter);
+ y -= s.user; paintRect(x, y, b, s.user, userColour, &painter);
+ y -= s.nice; paintRect(x, y, b, s.nice, niceColour, &painter);
+
+ x += b;
+ b = r / 2;
+ r -= b;
+
+ if (bgColour != colorGroup().background())
+ {
+ paintRect(x, 0, b, h, bgColour, &painter);
+ }
+
+ y = h - s.mkernel; paintRect(x, y, b, s.mkernel, mkernelColour, &painter);
+ y -= s.used; paintRect(x, y, b, s.used, usedColour, &painter);
+ y -= s.buffers; paintRect(x, y, b, s.buffers, buffersColour, &painter);
+ y -= s.cached; paintRect(x, y, b, s.cached, cachedColour, &painter);
+
+ x += b;
+ b = r;
+
+ if (bgColour != colorGroup().background())
+ {
+ paintRect(x, 0, b, h, bgColour, &painter);
+ }
+
+ y = h - s.sused; paintRect(x, y, b, s.sused, swapColour, &painter);
+ painter.end();
+
+ bitBlt(this, 0, 0, &pixmap);
+}
+
+// -----------------------------------------------------------------------------
+// Draw part of a bar, depending on the bar orientation.
+
+void KTimeMon::paintRect(int x, int y, int w, int h, QColor c, QPainter *p)
+{
+ if (vertical)
+ p->fillRect(x, y, w, h, c);
+ else
+ p->fillRect(width() - y - h, x, h, w, c);
+}
+
+// Show a tool-tip with some status information.
+void KTimeMon::maybeTip(const QPoint& p)
+{
+ if (sample == 0) return; // no associated sample...
+ if(!rect().contains(p)) return;
+
+ KSample::Sample s = sample->getSample(100); // scale to 100(%)
+ int idle = 100 - s.kernel - s.user - s.nice;
+ if ( idle < 0 )
+ idle = 0;
+ QString str = i18n("cpu: %1% idle\nmem: %2 MB %3% free\nswap: %4 MB %5% free")
+ .arg(idle)
+ .arg(KGlobal::locale()->formatNumber(s.used/100.*s.mtotal, 0))
+ .arg(100-s.used)
+ .arg(KGlobal::locale()->formatNumber(s.stotal, 0))
+ .arg(100-s.sused);
+
+ tip(rect(), str);
+}
+
+// -- KTimeMon definition ------------------------------------------------
+
+// Initialise the member variables, read the configuration data base,
+// set up the widget, and start the timer.
+KTimeMon::KTimeMon(const QString& configFile, Type type, int actions,
+ QWidget *parent, const char *name)
+ : KPanelApplet(configFile, type, actions, parent, name, WRepaintNoErase), QToolTip(this),
+ configDialog(0), bgProcess(0),
+ kernelColour("red1"), userColour("blue"),
+ niceColour("yellow"), iowaitColour("darkgreen"),
+ usedColour("blue1"), buffersColour("yellow"),
+ cachedColour("darkgreen"), mkernelColour("red1"),
+ swapColour("cyan3"), bgColour(colorGroup().background())
+{
+ mouseAction[0] = NOTHING;
+ mouseAction[1] = NOTHING;
+ mouseAction[2] = MENU;
+
+ KConfig* conf = config();
+ conf->setGroup("Parameters");
+ interval = conf->readUnsignedNumEntry("Interval", 500);
+ autoScale = conf->readBoolEntry("AutoScale", true);
+
+ pageScale = conf->readUnsignedNumEntry("PageScale", 10);
+ swapScale = conf->readUnsignedNumEntry("SwapScale", 5);
+ ctxScale = conf->readUnsignedNumEntry("ContextScale", 300);
+ for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) {
+ QString n;
+ n.setNum(i);
+
+ mouseAction[i] = (MouseAction)
+ conf->readUnsignedNumEntry(QString("MouseAction")+n, mouseAction[i]);
+ mouseActionCommand[i] = conf->readPathEntry(QString("MouseActionCommand")+n);
+ }
+
+ conf->setGroup("Interface");
+ kernelColour = conf->readColorEntry("KernelColour", &kernelColour);
+ userColour = conf->readColorEntry("UserColour", &userColour);
+ niceColour = conf->readColorEntry("NiceColour", &niceColour);
+ iowaitColour = conf->readColorEntry("IOWaitColour", &iowaitColour);
+ cachedColour = conf->readColorEntry("CachedColour", &cachedColour);
+ usedColour = conf->readColorEntry("UsedColour", &usedColour);
+ buffersColour = conf->readColorEntry("BuffersColour", &buffersColour);
+ swapColour = conf->readColorEntry("SwapColour", &swapColour);
+ mkernelColour = conf->readColorEntry("MKernelColour", &mkernelColour);
+ bgColour = conf->readColorEntry("BgColour", &bgColour);
+
+ vertical = conf->readBoolEntry("Vertical", true);
+
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer->start(interval);
+
+ sample = new KSample(this, autoScale, pageScale, swapScale, ctxScale);
+
+ QString aboutmsg = i18n("KTimeMon for KDE\n"
+ "Maintained by Dirk A. Mueller <[email protected]>\n"
+ "Written by M. Maierhofer ([email protected])\n"
+ "Based on timemon by H. Maierhofer");
+
+ hmenu = new KHelpMenu(this, aboutmsg);
+ menu = new KPopupMenu(this);
+
+ menu->insertTitle( SmallIcon( "ktimemon" ), i18n( "System Monitor" ) ) ;
+ menu->insertItem(i18n("Horizontal Bars"), 4);
+ menu->insertItem(SmallIcon( "configure" ), i18n( "Preferences..." ), 2);
+ menu->insertSeparator();
+ menu->insertItem(SmallIcon( "help" ), i18n("Help"), hmenu->menu(), 1);
+
+ menu->connectItem(2, this, SLOT(configure()));
+ menu->connectItem(4, this, SLOT(orientation()));
+
+ menu->setCheckable(true);
+
+ vertical = !vertical; // and similar for orientation
+ orientation();
+}
+
+// -----------------------------------------------------------------------------
+
+// delete the member variables
+KTimeMon::~KTimeMon()
+{
+ delete sample;
+ delete bgProcess;
+ KGlobal::locale()->removeCatalogue("ktimemon");
+}
+
+
+// Apply the settings from the configuration dialog and save them.
+void KTimeMon::apply()
+{
+ stop();
+ interval = configDialog->getInterval();
+ cont();
+
+ updateConfig(configDialog);
+
+ sample->setScaling(configDialog->getAutoScale(),
+ configDialog->getPageScale(),
+ configDialog->getSwapScale(),
+ configDialog->getCtxScale());
+
+ for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) {
+ mouseAction[i] = (MouseAction) configDialog->getMouseAction(i);
+ mouseActionCommand[i] = configDialog->getMouseActionCommand(i);
+ }
+
+ update();
+ writeConfiguration();
+}
+
+void KTimeMon::stop()
+{
+ timer->stop();
+}
+
+void KTimeMon::cont()
+{
+ timer->start(interval);
+}
+
+// Dump the current configuration entries to the data base.
+void KTimeMon::writeConfiguration()
+{
+ KConfig* conf = config();
+ conf->setGroup("Interface");
+ conf->writeEntry("KernelColour", kernelColour);
+ conf->writeEntry("UserColour", userColour);
+ conf->writeEntry("NiceColour", niceColour);
+ conf->writeEntry("IOWaitColour", iowaitColour);
+ conf->writeEntry("CachedColour", cachedColour);
+ conf->writeEntry("UsedColour", usedColour);
+ conf->writeEntry("BuffersColour", buffersColour);
+ conf->writeEntry("MKernelColour", mkernelColour);
+ conf->writeEntry("SwapColour", swapColour);
+ conf->writeEntry("BgColour", bgColour);
+ conf->writeEntry("Mode", true);
+ conf->writeEntry("Vertical", vertical);
+
+ conf->setGroup("Parameters");
+ conf->writeEntry("Interval", interval);
+ conf->writeEntry("AutoScale", autoScale);
+ conf->writeEntry("PageScale", pageScale);
+ conf->writeEntry("SwapScale", swapScale);
+ conf->writeEntry("ContextScale", ctxScale);
+ conf->writeEntry("WidgetSize", size());
+ for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) {
+ QString n;
+ n.setNum(i);
+
+ conf->writeEntry(QString("MouseAction")+n, (unsigned)mouseAction[i]);
+ conf->writePathEntry(QString("MouseActionCommand")+n, mouseActionCommand[i]);
+ }
+ conf->sync();
+}
+
+// Make the KSample object update its internal sample and repaint the
+// object.
+void KTimeMon::timeout()
+{
+ sample->updateSample();
+ update();
+}
+
+// This is called when the session management strikes, and also when the
+// main program exits with a code of 0 (i.e. there was no error).
+void KTimeMon::save()
+{
+ writeConfiguration();
+}
+
+// -----------------------------------------------------------------------------
+// Update the configuration dialog with the current values and show it.
+
+void KTimeMon::configure()
+{
+ if (configDialog == 0) configDialog = new KConfDialog(this);
+ configDialog->update();
+ configDialog->show();
+}
+
+// -----------------------------------------------------------------------------
+// Change the orientation of the status bars
+
+void KTimeMon::orientation()
+{
+ vertical = !vertical;
+
+ KConfig* conf = config();
+ conf->setGroup("Interface");
+ conf->writeEntry("Vertical", vertical);
+
+ menu->setItemChecked(4, !vertical);
+
+ update();
+ emit updateLayout();
+}
+
+// Pop up the menu when the appropriate button has been pressed.
+void KTimeMon::mousePressEvent(QMouseEvent *event)
+{
+ if (event == 0) return;
+
+ int index = -1;
+ if (event->button() == LeftButton) index = 0;
+ else if (event->button() == MidButton) index = 1;
+ else if (event->button() == RightButton) index = 2;
+
+ if (index == -1) return;
+
+ switch (mouseAction[index]) {
+ case NOTHING:
+ break;
+ case SWITCH:
+ break;
+ case MENU:
+ menu->popup(mapToGlobal(event->pos()));
+ break;
+ case COMMAND:
+ runCommand(index);
+ break;
+ }
+}
+
+// Start the given command
+void KTimeMon::runCommand(int index)
+{
+ // just in case it still hangs around
+ delete bgProcess;
+
+ bgProcess = new KShellProcess;
+ *bgProcess << mouseActionCommand[index];
+ connect(bgProcess, SIGNAL(receivedStderr(KProcess *, char *, int)),
+ this, SLOT(commandStderr(KProcess *, char *, int)));
+ bgProcess->start(KProcess::DontCare, KProcess::Stderr);
+}
+
+// -----------------------------------------------------------------------------
+// Check if there is any diagnostic output (command not found or such)
+
+void KTimeMon::commandStderr(KProcess * /*proc*/, char *buffer, int /*length*/)
+{
+ QString msgbuf;
+
+ msgbuf = i18n("Got diagnostic output from child command:\n\n");
+ msgbuf += QString::fromLocal8Bit(buffer);
+
+ KMessageBox::information(this, msgbuf);
+}
+
+
+// -----------------------------------------------------------------------------
diff --git a/kicker-applets/ktimemon/timemon.h b/kicker-applets/ktimemon/timemon.h
new file mode 100644
index 0000000..8f5664c
--- /dev/null
+++ b/kicker-applets/ktimemon/timemon.h
@@ -0,0 +1,107 @@
+/* -*- C++ -*- */
+
+/**********************************************************************/
+/* TimeMon (c) 1994 Helmut Maierhofer */
+/* KDE-ified M. Maierhofer 1998 */
+/* maintained by Dirk A. Mueller <[email protected] */
+/**********************************************************************/
+
+/*
+ * timemon.h
+ *
+ * Definitions for the timemon widget.
+ */
+
+#ifndef TIMEMON_H
+#define TIMEMON_H
+
+#include <qtooltip.h>
+#include <kiconloader.h>
+#include <kpanelapplet.h>
+
+// -- global constants ---------------------------------------------------
+
+const int MAX_MOUSE_ACTIONS = 3; // event handlers for the three buttons only
+
+// -- forward declaration ------------------------------------------------
+class KSample;
+class KConfDialog;
+class QPaintEvent;
+class QMouseEvent;
+class QPainter;
+class KProcess;
+class KShellProcess;
+class KHelpMenu;
+class KPopupMenu;
+
+// -- KTimeMon declaration -----------------------------------------------
+
+/*
+ * KTimeMon
+ *
+ * This is the main widget of the application. It handles the configuration
+ * dialog and may have an associated KTimeMonWidget in the panel (in which
+ * case it hides itself).
+ */
+
+class KTimeMon : public KPanelApplet, QToolTip {
+ Q_OBJECT
+public:
+ enum MouseAction { NOTHING, SWITCH, MENU, COMMAND };
+
+ KTimeMon(const QString& configFile, Type t = Normal, int actions = 0,
+ QWidget *parent = 0, const char *name = 0);
+ virtual ~KTimeMon();
+
+ void writeConfiguration(); // write back the configuration data
+
+ // reimplemented from KPanelApplet
+ virtual int widthForHeight(int height) const;
+ virtual int heightForWidth(int width) const;
+
+ virtual void preferences();
+
+ void stop();
+ void cont();
+
+public slots:
+ void timeout(); // timer expired
+ void save(); // session management callback
+ void apply(); // apply configuration information
+
+protected:
+ virtual void maybeTip(const QPoint&);
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void updateConfig(KConfDialog *d);
+ virtual void paintEvent(QPaintEvent *event);
+
+private slots: // called from the menu
+ void configure(); // show the configuration dialog
+ void orientation(); // switch vertical/horizontal orientation
+ void commandStderr(KProcess *proc, char *buffer, int length);
+
+private:
+ void runCommand(int index);
+ void paintRect(int x, int y, int w, int h, QColor c, QPainter *p);
+
+ unsigned interval;
+ bool autoScale;
+ unsigned pageScale, swapScale, ctxScale;
+ KPopupMenu* menu;
+ KHelpMenu* hmenu;
+ QTimer* timer;
+ KConfDialog *configDialog;
+ MouseAction mouseAction[MAX_MOUSE_ACTIONS];
+ QString mouseActionCommand[MAX_MOUSE_ACTIONS];
+ KShellProcess *bgProcess;
+
+ KSample *sample;
+ QColor kernelColour, userColour, niceColour, iowaitColour;
+ QColor usedColour, buffersColour, cachedColour, mkernelColour;
+ QColor swapColour, bgColour;
+ bool vertical, tooltip;
+
+ friend class KConfDialog;
+};
+
+#endif // TIMEMON_H
diff --git a/kicker-applets/math/Makefile.am b/kicker-applets/math/Makefile.am
new file mode 100644
index 0000000..da94ffb
--- /dev/null
+++ b/kicker-applets/math/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = $(all_includes)
+
+kde_module_LTLIBRARIES = math_panelapplet.la
+
+math_panelapplet_la_SOURCES = mathapplet.cpp parser.cpp
+
+METASOURCES = mathapplet.moc
+noinst_HEADERS = mathapplet.h parser.h
+
+lnkdir = $(kde_datadir)/kicker/applets
+lnk_DATA = mathapplet.desktop
+
+EXTRA_DIST = $(lnk_DATA)
+
+math_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+math_panelapplet_la_LIBADD = $(LIB_KSYCOCA) $(LIB_KDEUI)
+
+messages:
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kmathapplet.pot
diff --git a/kicker-applets/math/mathapplet.cpp b/kicker-applets/math/mathapplet.cpp
new file mode 100644
index 0000000..b4966b2
--- /dev/null
+++ b/kicker-applets/math/mathapplet.cpp
@@ -0,0 +1,285 @@
+/*****************************************************************
+
+Based on code 'Run' applet code, copyright (c) 2000 Matthias Elter <[email protected]>
+
+Modifications made by Andrew Coles, 2004 <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qlabel.h>
+#include <qfont.h>
+#include <qstringlist.h>
+#include <qpushbutton.h>
+#include <qhbox.h>
+
+#include <kapplication.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kcombobox.h>
+#include <kurifilter.h>
+#include <kdialog.h>
+#include <krun.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+
+#include "parser.h"
+
+
+
+#include "mathapplet.h"
+#include "mathapplet.moc"
+
+extern "C"
+{
+ KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile)
+ {
+ KGlobal::locale()->insertCatalogue("kmathapplet");
+ return new MathApplet(configFile, KPanelApplet::Stretch, 0, parent, "kmathapplet");
+ }
+}
+
+MathApplet::MathApplet(const QString& configFile, Type type, int actions,
+ QWidget *parent, const char *name)
+ : KPanelApplet(configFile, type, actions, parent, name),
+ m_hasFocus(false)
+{
+ // setBackgroundMode(X11ParentRelative);
+ setBackgroundOrigin( AncestorOrigin );
+ // setup label
+ _label = new QLabel(i18n("Evaluate:"), this);
+ QFont f(_label->font());
+ f.setPixelSize(12);
+// _label->setBackgroundMode(X11ParentRelative);
+ _label->setBackgroundOrigin( AncestorOrigin );
+ _label->setFixedHeight(14);
+ _label->setFont(f);
+
+ // setup popup button
+ _btn = new QPushButton(this);
+ f = _btn->font();
+ f.setPixelSize(12);
+ _btn->setFont(f);
+ connect(_btn, SIGNAL(clicked()), SLOT(popup_combo()));
+
+ // setup history combo
+ _input = new KHistoryCombo(this);
+ _input->setFocus();
+ _input->clearEdit();
+ watchForFocus(_input->lineEdit());
+ connect(_input, SIGNAL(activated(const QString&)),
+ SLOT(evaluate(const QString&)));
+
+ initContextMenu();
+ useDegrees();
+
+ KConfig *c = config();
+ c->setGroup("General");
+
+
+ // restore history and completion list
+ QStringList list = c->readListEntry("Completion list");
+ _input->completionObject()->setItems(list);
+ list = c->readListEntry("History list");
+ _input->setHistoryItems(list);
+ int mode = c->readNumEntry( "CompletionMode", KGlobalSettings::completionMode() );
+ _input->setCompletionMode( (KGlobalSettings::Completion) mode );
+
+ _hbox = new QHBox( 0, 0, WStyle_Customize | WType_Popup );
+ _hbox->setFixedSize(120, 22);
+
+
+}
+
+void MathApplet::initContextMenu()
+{
+ mContextMenu = new KPopupMenu(this);
+ mContextMenu->setCheckable(true);
+ mContextMenu->insertItem(i18n("Use &Degrees"), this, SLOT(useDegrees()), 0, 0, 0);
+ mContextMenu->insertItem(i18n("Use &Radians"), this, SLOT(useRadians()), 0, 1, 1);
+ setCustomMenu(mContextMenu);
+}
+
+
+MathApplet::~MathApplet()
+{
+ KConfig *c = config();
+ c->setGroup("General");
+
+ // save history and completion list
+ QStringList list = _input->completionObject()->items();
+ c->writeEntry("Completion list", list);
+ list = _input->historyItems();
+ c->writeEntry("History list", list);
+ c->writeEntry( "CompletionMode", (int) _input->completionMode() );
+ c->sync();
+
+ KGlobal::locale()->removeCatalogue("kmathapplet");
+}
+
+void MathApplet::useDegrees() {
+
+ mContextMenu->setItemChecked(0, true);
+ mContextMenu->setItemChecked(1, false);
+ Parser dummy;
+ dummy.setAngleMode(1);
+}
+
+void MathApplet::useRadians() {
+ mContextMenu->setItemChecked(0, false);
+ mContextMenu->setItemChecked(1, true);
+ Parser dummy;
+ dummy.setAngleMode(0);
+}
+
+void MathApplet::resizeEvent(QResizeEvent*)
+{
+ if(orientation() == Horizontal)
+ {
+ _btn->hide();
+ _input->reparent(this, QPoint(0,0), true);
+ _label->setGeometry(0,0, width(), _label->height());
+
+ if(height() >= _input->sizeHint().height() + _label->height())
+ {
+ int inputVOffset = height() - _input->sizeHint().height() - 2;
+ int labelHeight = _label->sizeHint().height();
+ _label->setGeometry(0, inputVOffset - labelHeight,
+ width(), labelHeight);
+ _input->setGeometry(0, inputVOffset,
+ width(), _input->sizeHint().height());
+ _label->show();
+ }
+ else
+ {
+ _label->hide();
+
+ // make it as high as the combobox naturally wants to be
+ // but no taller than the panel is!
+ // don't forget to center it vertically either.
+ int newHeight = _input->sizeHint().height();
+ if (newHeight > height())
+ newHeight = height();
+ _input->setGeometry(0, (height() - newHeight) / 2,
+ width(), newHeight);
+ }
+ }
+ else
+ {
+ _btn->show();
+ _btn->setFixedSize(width(), 22);
+ _input->reparent( _hbox, QPoint(0, 0), false);
+ _label->hide();
+ }
+ setButtonText();
+}
+
+void MathApplet::positionChange(KPanelApplet::Position)
+{
+ setButtonText();
+}
+
+void MathApplet::setButtonText()
+{
+ QString t;
+
+ if (position() == pLeft)
+ {
+ if (width() >= 42)
+ t = i18n("< Eval");
+ else
+ t = "<";
+ }
+ else
+ {
+ if(width() >= 42)
+ t = i18n("Eval >");
+ else
+ t = ">";
+ }
+
+ _btn->setText(t);
+}
+
+int MathApplet::widthForHeight(int ) const
+{
+ return 110;
+}
+
+int MathApplet::heightForWidth(int ) const
+{
+ return 22;
+}
+
+void MathApplet::popup_combo()
+{
+ QPoint p;
+ if (position() == pLeft)
+ p = mapToGlobal(QPoint(-_input->width()-1, 0));
+ else
+ p = mapToGlobal(QPoint(width()+1, 0));
+ _hbox->move(p);
+ _hbox->show();
+ _input->setFocus();
+}
+
+void MathApplet::evaluate(const QString& command)
+{
+ QString exec;
+
+ Parser evaluator;
+
+ kapp->propagateSessionManager();
+
+ _input->addToHistory(command);
+
+
+ QString cmd = command;
+
+ // Nothing interesting. Quit!
+ if ( cmd.isEmpty() ){
+ KMessageBox::sorry(0L, i18n("You have to enter an expression to be evaluated first."));
+ needsFocus(true);
+ } else {
+ double answer = evaluator.eval(command);
+ if (evaluator.errmsg() == 0) {
+ QString ansAsString = QString::number(answer);
+ _input->clearEdit();
+ _input->setEditText(ansAsString);
+ } else {
+ _input->removeFromHistory(_input->currentText());
+ needsFocus(true);
+ }
+ }
+
+ if (orientation() == Vertical)
+ _hbox->hide();
+}
+
+void MathApplet::mousePressEvent(QMouseEvent *e)
+{
+ if ( e->button() != RightButton )
+ {
+ KPanelApplet::mousePressEvent( e );
+ return;
+ }
+
+ mContextMenu->exec(e->globalPos());
+}
diff --git a/kicker-applets/math/mathapplet.desktop b/kicker-applets/math/mathapplet.desktop
new file mode 100644
index 0000000..9aba622
--- /dev/null
+++ b/kicker-applets/math/mathapplet.desktop
@@ -0,0 +1,114 @@
+[Desktop Entry]
+Type=Plugin
+Name=Math Expression Evaluator
+Name[bg]=Математически изрази
+Name[bs]=Procjena matematičkih izraza
+Name[ca]=Avaluador d'expressions matemàtiques
+Name[cs]=Vyhodnocení matematického výrazu
+Name[da]=Evaluering af matematiske udtryk
+Name[de]=Auswertung mathematischer Ausdrücke
+Name[el]=Ελεγκτής εγκυρότητας μαθηματικής έκφρασης
+Name[en_GB]=Maths Expression Evaluator
+Name[eo]=Matematikesprima interpretilo
+Name[es]=Evaluador de expresiones matemáticas
+Name[et]=Matemaatikaavaldiste kontrollija
+Name[eu]=Espresio matematikoen balidatzailea
+Name[fa]=ارزیاب عبارت ریاضی
+Name[fi]=Matemaattisen lausekkeen laskija
+Name[fr]=Interpréteur d'expressions mathématique
+Name[fy]=Lytse rekkenmachine
+Name[ga]=Luachálaí Slonn Matamaiticiúil
+Name[gl]=Avaliación de Expresións Matemáticas
+Name[he]=מפענח נוסחאות מתמטיות
+Name[hi]=मैथ एक्सप्रेशन इवेल्यूएटर्स
+Name[hr]=Ocjena matematičkih izraza
+Name[hu]=Kifejezéskiértékelő
+Name[is]=Algebrureiknivél
+Name[it]=Disegnatore di funzioni matematiche
+Name[ja]=数学的表現の評価者
+Name[ka]=მათემატიკური გამოსახულებების გამომთვლელი
+Name[kk]=Математикалық өрнегін есептеу
+Name[km]=កម្មវិធី​វាយ​តម្លៃ​កន្សោម​ពិជគណិត
+Name[lt]=Matematinių išraiškų vertinimo priemonė
+Name[mk]=Пресметувач на математички изрази
+Name[ms]=Penilaian Ungkapan Matematik
+Name[nb]=Matematikkberegner
+Name[nds]=Mathemaatsche Utdrück utreken
+Name[ne]=गणित अभिव्यक्ति मुल्याङ्कनकर्ता
+Name[nl]=Kleine rekenmachine
+Name[nn]=Matteuttrykkevaluerar
+Name[pl]=Program wyliczający wyrażenia matematyczne
+Name[pt]=Avaliação de Expressões Matemáticas
+Name[pt_BR]=Validador de Expressões Matemáticas
+Name[ru]=Вычисление математических выражений
+Name[sk]=Vyhodnotenie matematického výrazu
+Name[sl]=Vrednotenje matematičnih izrazov
+Name[sr]=Рачунар математичких израза
+Name[sr@Latn]=Računar matematičkih izraza
+Name[sv]=Utvärdering av matematiska uttryck
+Name[ta]=கணிதத் தொடர் மதிப்பிடு
+Name[tg]=Тафтиши ифодаҳои математикӣ
+Name[tr]=Matematiksel İşlem Değerlendiricisi
+Name[uk]=Перевірка математичних виразів
+Name[uz]=Matematik ifodalarni hisoblagich
+Name[uz@cyrillic]=Математик ифодаларни ҳисоблагич
+Name[vi]=Bộ định giá biểu thức toán học
+Name[zh_CN]=数学表达式计算器
+Name[zh_TW]=數學運算模擬器
+Comment=A mathematical expression evaluator
+Comment[bg]=Изчисление на математически изрази
+Comment[bs]=Procjena matematičkih izraza
+Comment[ca]=Un avaluador d'expressions matemàtiques
+Comment[cs]=Program pro vyhodnocování matematických výrazů
+Comment[da]=Til evaluering af matematiske udtryk
+Comment[de]=Auswerten von mathematischen Ausdrücken
+Comment[el]=Ένας ελεγκτής εγκυρότητας μαθηματικών εκφράσεων
+Comment[eo]=Matematikesprima interpretilo
+Comment[es]=Un evaluador de expresiones matemáticas
+Comment[et]=Matemaatikaavaldiste kontrollija
+Comment[eu]=Espresio matematikoen ebaluatzailea
+Comment[fa]=ارزیاب عبارتهای ریاضی
+Comment[fi]=Matemaattisen lausekkeen laskija
+Comment[fr]=Un interpréteur d'expressions mathématiques
+Comment[fy]=In applet om wiskundige útdrukkingen te evaluearjen
+Comment[ga]=Luachálaí slonn matamaiticiúil
+Comment[gl]=Un avaliador de expresións matemáticas
+Comment[he]=מפענח נוסחאות מתמטיות
+Comment[hi]=एक मैथमेटिकल एक्सप्रेशन इवेल्यूएटर
+Comment[hr]=Ocjenjivanje matematičkih izraza
+Comment[hu]=Matematikai kifejezések kiszámítására alkalmas program
+Comment[is]=Algebrureiknivél
+Comment[it]=Uno strumento per disegnare funzioni matematiche
+Comment[ja]=数学的表現の評価者
+Comment[ka]=მათემატიკური გამოსახულებების გამომთვლელი
+Comment[kk]=Математикалық өрнекті есептеп шығару
+Comment[km]=កម្មវិធី​វាយ​តម្លៃ​កន្សោម​ពិជ​គណិត
+Comment[lt]=Matematinių išraiškų vertinimo priemonė
+Comment[mk]=Пресметување математички изрази
+Comment[ms]=Penilai ungkapan matematik
+Comment[nb]=En beregner for matematiske uttrykk
+Comment[nds]=Utreken vun mathemaatsche Utdrück
+Comment[ne]=एउटा गणितिय अभिव्यक्ति मुल्याङ्कनकर्ता
+Comment[nl]=Een applet waarmee u wiskundige uitdrukkingen kunt evalueren
+Comment[nn]=Ein utreknar for matematiske uttrykk
+Comment[pl]=Program wyliczający wyrażenia matematyczne
+Comment[pt]=Um avaliador de expressões matemáticas
+Comment[pt_BR]=Um validador de expressões
+Comment[ru]=Вычисление математических выражений
+Comment[sk]=Program pre vyhodnotenie matematických výrazov
+Comment[sl]=Vrednotenje matematičnih izrazov
+Comment[sr]=Израчунава задате математичке изразе
+Comment[sr@Latn]=Izračunava zadate matematičke izraze
+Comment[sv]=Ett verktyg för utvärdering av matematiska uttryck
+Comment[ta]=கணிதத் தொடர் மதிப்பிடு
+Comment[tg]=Тафтиши ифодаҳои математикӣ
+Comment[tr]=Matematiksel işlem değerlendirici
+Comment[uk]=Перевірка математичних виразів
+Comment[uz]=Matematik ifodalarni hisoblagich
+Comment[uz@cyrillic]=Математик ифодаларни ҳисоблагич
+Comment[vi]=Bộ định giá biểu thức toán học
+Comment[zh_CN]=数学表达式计算器
+Comment[zh_TW]=數學運算模擬器
+Icon=math_int
+X-KDE-Library=math_panelapplet
+X-KDE-UniqueApplet=true
diff --git a/kicker-applets/math/mathapplet.h b/kicker-applets/math/mathapplet.h
new file mode 100644
index 0000000..1a918c3
--- /dev/null
+++ b/kicker-applets/math/mathapplet.h
@@ -0,0 +1,74 @@
+/*****************************************************************
+
+Based on code 'Run' applet code, copyright (c) 2000 Matthias Elter <[email protected]>
+
+Modifications made by Andrew Coles, 2004 <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __mathapplet_h__
+#define __mathapplet_h__
+
+#include <qstring.h>
+#include <kpanelapplet.h>
+
+class QLabel;
+class QHBox;
+class QPushButton;
+class KHistoryCombo;
+class KPopupMenu;
+
+class MathApplet : public KPanelApplet
+{
+ Q_OBJECT
+
+public:
+ MathApplet(const QString& configFile, Type t = Stretch, int actions = 0,
+ QWidget *parent = 0, const char *name = 0);
+ virtual ~MathApplet();
+
+ int widthForHeight(int height) const;
+ int heightForWidth(int width) const;
+
+protected:
+ void resizeEvent(QResizeEvent*);
+ void positionChange(KPanelApplet::Position);
+
+protected slots:
+ void evaluate(const QString&);
+ void popup_combo();
+ void setButtonText();
+ void useDegrees();
+ void useRadians();
+
+private:
+
+ void initContextMenu();
+ void mousePressEvent(QMouseEvent *e);
+
+ KHistoryCombo *_input;
+ QLabel *_label;
+ QPushButton *_btn;
+ QHBox *_hbox;
+ KPopupMenu *mContextMenu;
+ bool m_hasFocus;
+};
+
+#endif
diff --git a/kicker-applets/math/parser.cpp b/kicker-applets/math/parser.cpp
new file mode 100644
index 0000000..7d99c87
--- /dev/null
+++ b/kicker-applets/math/parser.cpp
@@ -0,0 +1,813 @@
+/*
+* Code based on parser from KmPlot - a math. function plotter for the KDE-Desktop
+*
+* Original code
+* Copyright (C) 1998, 1999 Klaus-Dieter M�ller
+* 2000, 2002 [email protected]
+*
+* Modifications: 2004 Andrew Coles ([email protected])
+*
+* This file is part of the KDE Project.
+* KmPlot is part of the KDE-EDU Project.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*/
+
+// standard c(++) includes
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+//KDE includes
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+// local includes
+#include "parser.h"
+//#include "settings.h"
+//#include "xparser.h"
+
+double Parser::m_anglemode = 0;
+
+/// List of predefined functions.
+Parser::Mfkt Parser::mfkttab[ FANZ ]=
+{
+ {"tanh", ltanh}, // Tangens hyperbolicus
+ {"tan", ltan}, // Tangens
+ {"sqrt", sqrt}, // Square root
+ {"sqr", sqr}, // Square
+ {"sinh", lsinh}, // Sinus hyperbolicus
+ {"sin", lsin}, // Sinus
+ {"sign", sign}, // Signum
+ {"sech", sech}, // Secans hyperbolicus
+ {"sec", sec}, // Secans
+ {"log", log10}, // Logarithm base 10
+ {"ln", log}, // Logarithm base e
+ {"exp", exp}, // Exponential function base e
+ {"coth", coth}, // Co-Tangens hyperbolicus
+ {"cot", cot}, // Co-Tangens = 1/tan
+ {"cosh", lcosh}, // Cosinus hyperbolicus
+ {"cosech", cosech}, // Co-Secans hyperbolicus
+ {"cosec", cosec}, // Co-Secans
+ {"cos", lcos}, // Cosinus
+ {"artanh", artanh}, // Area-tangens hyperbolicus = inverse of tanh
+ {"arsinh", arsinh}, // Area-sinus hyperbolicus = inverse of sinh
+ {"arsech", arsech}, // Area-secans hyperbolicus = invers of sech
+ {"arctan", arctan}, // Arcus tangens = inverse of tan
+ {"arcsin", arcsin}, // Arcus sinus = inverse of sin
+ {"arcsec", arcsec}, // Arcus secans = inverse of sec
+ {"arcoth", arcoth}, // Area-co-tangens hyperbolicus = inverse of coth
+ {"arcosh", arcosh}, // Area-cosinus hyperbolicus = inverse of cosh
+ {"arcosech", arcosech}, // Area-co-secans hyperbolicus = inverse of cosech
+ {"arccot", arccot}, // Arcus co-tangens = inverse of cotan
+ {"arccosec", arccosec}, // Arcus co-secans = inverse of cosec
+ {"arccos", arccos}, // Arcus cosinus = inverse of cos
+ {"abs", fabs} // Absolute value
+};
+
+
+Parser::Parser()
+{ ps_init( UFANZ, MEMSIZE, STACKSIZE );
+}
+
+
+Parser::Parser( int anz, int m_size, int s_size )
+{ ps_init( anz, m_size, s_size );
+}
+
+
+void Parser::ps_init(int anz, int m_size, int s_size)
+{ int ix;
+
+ ufanz=anz;
+ memsize=m_size;
+ stacksize=s_size;
+ ufkt=new Ufkt[ufanz];
+ evalflg=ixa=0;
+ for(ix=0; ix<ufanz; ++ix)
+ { ufkt[ix].memsize=memsize;
+ ufkt[ix].stacksize=stacksize;
+ ufkt[ix].fname=""; //.resize(1);
+ ufkt[ix].fvar=""; //.resize(1);
+ ufkt[ix].fpar=""; //.resize(1);
+ ufkt[ix].fstr=""; //.resize(1);
+ ufkt[ix].mem=new unsigned char [memsize];
+ }
+}
+
+
+Parser::~Parser()
+{ delete [] ufkt;
+}
+
+
+Parser::Ufkt::Ufkt()
+{
+}
+
+
+Parser::Ufkt::~Ufkt()
+{ delete [] mem;
+}
+
+
+void Parser::setAngleMode(int angle)
+{ if(angle==0)
+ m_anglemode = 1;
+ else
+ m_anglemode = M_PI/180;
+}
+
+double Parser::anglemode()
+{ return m_anglemode;
+}
+
+double Parser::eval(QString str)
+{ double erg;
+
+ stack=new double [stacksize];
+ stkptr=stack;
+ evalflg=1;
+ lptr=str.latin1();
+ err=0;
+ heir1();
+ if(*lptr!=0 && err==0) err=1;
+ evalflg=0;
+ erg=*stkptr;
+ delete [] stack;
+ if(err==0)
+ { errpos=0;
+ return erg;
+ }
+ else
+ { errpos=lptr-(str.latin1())+1;
+ return 0.;
+ }
+}
+
+
+double Parser::Ufkt::fkt(double x)
+{ unsigned char token;
+ double *pd, (**pf)(double);
+ double erg, *stack, *stkptr;
+ Ufkt **puf;
+
+ mptr=mem;
+ stack=stkptr= new double [stacksize];
+ while(1)
+ { switch(token=*mptr++)
+ { case KONST: pd=(double*)mptr;
+ *stkptr=*pd++;
+ mptr=(unsigned char*)pd;
+ break;
+ case XWERT: *stkptr=x;
+ break;
+ case YWERT: *stkptr=oldy;
+ break;
+ case KWERT: *stkptr=k;
+ break;
+
+ case PUSH: ++stkptr;
+ break;
+
+ case PLUS: stkptr[-1]+=*stkptr;
+ --stkptr;
+ break;
+
+ case MINUS: stkptr[-1]-=*stkptr;
+ --stkptr;
+ break;
+
+ case MULT: stkptr[-1]*=*stkptr;
+ --stkptr;
+ break;
+
+ case DIV: if(*stkptr==0.)*(--stkptr)=HUGE_VAL;
+ else
+ { stkptr[-1]/=*stkptr;
+ --stkptr;
+ }
+ break;
+
+ case POW: stkptr[-1]=pow(*(stkptr-1), *stkptr);
+ --stkptr;
+ break;
+
+ case NEG: *stkptr=-*stkptr;
+ break;
+
+ case FKT: pf=(double(**)(double))mptr;
+ *stkptr=(*pf++)(*stkptr);
+ mptr=(unsigned char*)pf;
+ break;
+
+ case UFKT: puf=(Ufkt**)mptr;
+ *stkptr=(*puf++)->fkt(*stkptr);
+ mptr=(unsigned char*)puf;
+ break;
+
+ case ENDE: erg=*stkptr;
+ delete [] stack;
+ return erg;
+ }
+ }
+}
+
+int Parser::getNextIndex()
+{
+ int ix = 0;
+ while( ( ix < ufanz ) && !ufkt[ ix ].fname.isEmpty() ) ix++;
+ if( ix == ufanz ) ix = -1;
+ return ix;
+}
+
+int Parser::addfkt(QString str)
+{
+ int ix;
+
+ stkptr=stack=0;
+ err=0;
+ errpos=1;
+ str.remove(" " );
+ const int p1=str.find('(');
+ int p2=str.find(',');
+ const int p3=str.find(")=");
+
+ //insert '*' when it is needed
+ for(int i=p1+3; i < (int) str.length();i++)
+ {
+ if( (str.at(i).isNumber() || str.at(i).category()==QChar::Letter_Uppercase )&& ( str.at(i-1).isLetter() || str.at(i-1) == ')' ) )
+ {
+ str.insert(i,'*');
+ }
+ else if( (str.at(i).isNumber() || str.at(i) == ')' || str.at(i).category()==QChar::Letter_Uppercase) && ( str.at(i+1).isLetter() || str.at(i+1) == '(' ) )
+ {
+ str.insert(i+1,'*');
+ i++;
+ }
+ }
+
+ if(p1==-1 || p3==-1 || p1>p3)
+ { err=4;
+ return -1;
+ }
+ if ( p3+2 == (int) str.length()) //empty function
+ { err=11;
+ return -1;
+ }
+ if(p2==-1 || p2>p3) p2=p3;
+ if(getfix(str.left(p1))!=-1)
+ { err=8;
+ return -1;
+ }
+ else err=0;
+
+ if (str.mid(p1+1, p2-p1-1) == "e")
+ { err=4;
+ return -1;
+ }
+
+ for(ix=0; ix<ufanz; ++ix)
+ { if(ufkt[ix].fname.isEmpty())
+ { ufkt[ix].fname=str.left(p1);
+ ufkt[ix].fvar=str.mid(p1+1, p2-p1-1);
+ ufkt[ix].fstr=str;
+ if(p2<p3) ufkt[ix].fpar=str.mid(p2+1, p3-p2-1);
+ else ufkt[ix].fpar=""; //.resize(1);
+ break;
+ }
+ }
+
+ if(ix==ufanz)
+ { err=5;
+ return -1;
+ } // zu viele Funktionen
+
+ ixa=ix;
+ mem=mptr=ufkt[ix].mem;
+ lptr=(str.latin1())+p3+2;
+ heir1();
+ if(*lptr!=0 && err==0) err=1; // Syntaxfehler
+ addtoken(ENDE);
+
+ if(err!=0)
+ { ufkt[ix].fname=""; //.resize(1);
+ errpos=lptr-(str.latin1())+1;
+ return -1;
+ }
+
+
+ errpos=0;
+ return ix;
+}
+
+
+int Parser::delfkt(QString name)
+{ int ix;
+
+ ix=getfix(name);
+ if(ix!=-1) ufkt[ix].fname=""; //.resize(1); // Name l�chen
+ return ix;
+}
+
+
+int Parser::delfkt(int ix)
+{ if(ix<0 || ix>=ufanz) return -1; // ungltiger Index
+
+ ufkt[ix].fname=""; //.resize(1); // Name l�chen
+ return ix;
+}
+
+
+double Parser::fkt(QString name, double x)
+{ int ix;
+
+ ix=getfix(name);
+ if(ix==-1) return 0.;
+
+ return ufkt[ix].fkt(x);
+}
+
+
+void Parser::heir1()
+{ char c;
+
+ heir2();
+ if(err!=0) return ;
+
+ while(1)
+ { switch(c=*lptr)
+ { default: return ;
+
+ case ' ': ++lptr;
+ continue;
+
+ case '+':
+ case '-': ++lptr;
+ addtoken(PUSH);
+ heir2();
+ if(err!=0) return ;
+ }
+
+ switch(c)
+ { case '+': addtoken(PLUS);
+ break;
+
+ case '-': addtoken(MINUS);
+ }
+ }
+}
+
+
+void Parser::heir2()
+{ if(match("-"))
+ { heir2();
+ if(err!=0) return;
+
+ addtoken(NEG);
+ }
+
+ else heir3();
+}
+
+
+void Parser::heir3()
+{ char c;
+
+ heir4();
+ if(err!=0) return;
+
+ while(1)
+ { switch(c=*lptr)
+ { default: return ;
+
+ case ' ': ++lptr;
+ continue;
+
+ case '*':
+ case '/': ++lptr;
+ addtoken(PUSH);
+ heir4();
+ if(err!=0) return ;
+ }
+
+ switch(c)
+ { case '*': addtoken(MULT);
+ break;
+
+ case '/': addtoken(DIV);
+ }
+ }
+}
+
+
+void Parser::heir4()
+{ primary();
+ if(err!=0) return;
+
+ while(match("^"))
+ { addtoken(PUSH);
+ primary();
+ if(err!=0) return;
+ addtoken(POW);
+ }
+}
+
+
+void Parser::primary()
+{ char *p;
+ int i;
+ double w;
+
+ if(match("("))
+ { heir1();
+ if(match(")")==0) err=2; // fehlende Klammer
+ return;
+ }
+
+ for(i=0; i<FANZ; ++i)
+ { if(match(mfkttab[i].mfstr))
+ { primary();
+ addtoken(FKT);
+ addfptr(mfkttab[i].mfadr);
+ return;
+ }
+ }
+
+ for(i=0; i<ufanz; ++i)
+ { if(ufkt[i].fname[0]==0) continue;
+ if(match(ufkt[i].fname.latin1()))
+ { if(i==ixa) {err=9; return;}
+
+ primary();
+ addtoken(UFKT);
+ addfptr(&ufkt[i]);
+ return;
+ }
+ }
+ // A constant
+ if(lptr[0] >='A' && lptr[0]<='Z' )
+ { char tmp[2];
+ tmp[1] = '\0';
+ for( int i = 0; i< (int)constant.size();i++)
+ {
+ tmp[0] = constant[i].constant;
+ if ( match( tmp) )
+ {
+ addtoken(KONST);
+ addwert(constant[i].value);
+ return;
+ }
+
+ }
+ err = 10;
+ return;
+ }
+
+
+ if(match("pi"))
+ { addtoken(KONST);
+ addwert(M_PI);
+ return;
+ }
+
+ if(match("e"))
+ { addtoken(KONST);
+ addwert(M_E);
+ return;
+ }
+
+ if(match(ufkt[ixa].fvar.latin1()))
+ { addtoken(XWERT);
+ return;
+ }
+
+ if(match("y"))
+ { addtoken(YWERT);
+ return;
+ }
+
+ if(match(ufkt[ixa].fpar.latin1()))
+ { addtoken(KWERT);
+ return;
+ }
+
+ w=strtod(lptr, &p);
+ if(lptr!=p)
+ { lptr=p;
+ addtoken(KONST);
+ addwert(w);
+ }
+ else err=1; // Syntax-Fehler
+}
+
+
+int Parser::match(const char *lit)
+{ const char *p;
+
+ if(*lit==0) return 0;
+
+ while(*lptr==' ') ++lptr;
+ p=lptr;
+ while(*lit)
+ { if(*lit++!=*p++) return 0;
+ }
+ lptr=p;
+ return 1;
+}
+
+
+void Parser::addtoken(unsigned char token)
+{ if(stkptr>=stack+stacksize-1)
+ { err=7;
+ return;
+ }
+
+ if(evalflg==0)
+ { if(mptr>=&mem[memsize-10]) err=6;
+ else *mptr++=token;
+
+ switch(token)
+ { case PUSH: ++stkptr;
+ break;
+
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case DIV:
+ case POW: --stkptr;
+ }
+ }
+ else switch(token)
+ { case PUSH: ++stkptr;
+ break;
+
+ case PLUS: stkptr[-1]+=*stkptr;
+ --stkptr;
+ break;
+
+ case MINUS: stkptr[-1]-=*stkptr;
+ --stkptr;
+ break;
+
+ case MULT: stkptr[-1]*=*stkptr;
+ --stkptr;
+ break;
+
+ case DIV: if(*stkptr==0.) *(--stkptr)=HUGE_VAL;
+ else
+ { stkptr[-1]/=*stkptr;
+ --stkptr;
+ }
+ break;
+
+ case POW: stkptr[-1]=pow(*(stkptr-1), *stkptr);
+ --stkptr;
+ break;
+ case NEG: *stkptr=-*stkptr;
+ }
+}
+
+
+void Parser::addwert(double x)
+{ double *pd=(double*)mptr;
+
+ if(evalflg==0)
+ { if(mptr>=&mem[memsize-10]) err=6;
+ else
+ { *pd++=x;
+ mptr=(unsigned char*)pd;
+ }
+ }
+ else *stkptr=x;
+}
+
+
+void Parser::addfptr(double(*fadr)(double))
+{ double (**pf)(double)=(double(**)(double))mptr;
+
+ if(evalflg==0)
+ { if(mptr>=&mem[memsize-10]) err=6;
+ else
+ { *pf++=fadr;
+ mptr=(unsigned char*)pf;
+ }
+ }
+ else *stkptr=(*fadr)(*stkptr);
+}
+
+
+void Parser::addfptr(Ufkt *adr)
+{ Ufkt **p=(Ufkt**)mptr;
+
+ if(evalflg==0)
+ { if(mptr>=&mem[memsize-10]) err=6;
+ else
+ { *p++=adr;
+ mptr=(unsigned char*)p;
+ }
+ }
+ else *stkptr=adr->fkt(*stkptr);
+}
+
+
+int Parser::chkfix(int ix)
+{ if(ix<0 || ix>=ufanz) return -1; // ungltiger Index
+ if(ufkt[ix].fname.isEmpty()) return -1; // keine Funktion
+ return ix;
+}
+
+
+int Parser::getfkt(int ix, QString& name, QString& str)
+{ if(ix<0 || ix>=ufanz) return -1; // ungltiger Index
+ if(ufkt[ix].fname.isEmpty()) return -1; // keine Funktion
+ name=ufkt[ix].fname.copy();
+ str=ufkt[ix].fstr.copy();
+ return ix;
+}
+
+
+int Parser::getfix(QString name)
+{ int ix;
+
+ err=0;
+ for(ix=0; ix<ufanz; ++ix)
+ { if(name==ufkt[ix].fname) return ix;
+ }
+ err=3; // Name nicht bekannt
+ return -1;
+}
+
+
+int Parser::errmsg()
+{ switch(err)
+ { case 1: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Syntax error").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 2: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Missing parenthesis").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 3: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Function name unknown").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 4: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Void function variable").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 5: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Too many functions").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 6: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Token-memory overflow").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 7: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Stack overflow").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 8: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "Name of function not free").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+
+ case 9: KMessageBox::error(0, i18n("Parser error at position %1:\n"
+ "recursive function not allowed").arg(QString::number(errpos)), i18n("Math Expression Evaluator"));
+ break;
+ case 10: KMessageBox::error(0, i18n("Could not find a defined constant at position %1" ).arg(QString::number(errpos)),
+ i18n("Math Expression Evaluator"));
+ break;
+ case 11: KMessageBox::error(0, i18n("Empty function"), i18n("Math Expression Evaluator"));
+ break;
+ }
+
+ return err;
+}
+
+
+double sign(double x)
+{ if(x<0.) return -1.;
+ else if(x>0.) return 1.;
+ return 0.;
+}
+
+double sqr(double x)
+{ return x*x;
+}
+
+double arsinh(double x)
+{ return log(x+sqrt(x*x+1));
+}
+
+
+double arcosh(double x)
+{ return log(x+sqrt(x*x-1));
+}
+
+
+double artanh(double x)
+{ return log((1+x)/(1-x))/2;
+}
+
+// sec, cosec, cot and their inverses
+
+double sec(double x)
+{ return (1 / cos(x*Parser::anglemode()));
+}
+
+double cosec(double x)
+{ return (1 / sin(x*Parser::anglemode()));
+}
+
+double cot(double x)
+{ return (1 / tan(x*Parser::anglemode()));
+}
+
+double arcsec(double x)
+{ if ( !Parser::anglemode() ) return ( 1/acos(x)* 180/M_PI );
+ else return acos(1/x);
+}
+
+double arccosec(double x)
+{ return asin(1/x)* 1/Parser::anglemode();
+}
+
+double arccot(double x)
+{ return atan(1/x)* 1/Parser::anglemode();
+}
+
+// sech, cosech, coth and their inverses
+
+
+double sech(double x)
+{ return (1 / cosh(x*Parser::anglemode()));
+}
+
+double cosech(double x)
+{ return (1 / sinh(x*Parser::anglemode()));
+}
+
+double coth(double x)
+{ return (1 / tanh(x*Parser::anglemode()));
+}
+
+double arsech(double x)
+{ return arcosh(1/x)* 1/Parser::anglemode();
+}
+
+double arcosech(double x)
+{ return arsinh(1/x)* 1/Parser::anglemode();
+}
+
+double arcoth(double x)
+{ return artanh(1/x)* 1/Parser::anglemode();
+}
+
+//basic trigonometry functions
+
+double lcos(double x)
+{ return cos(x*Parser::anglemode());
+}
+double lsin(double x)
+{ return sin(x*Parser::anglemode());
+}
+double ltan(double x)
+{ return tan(x*Parser::anglemode());
+}
+
+double lcosh(double x)
+{ return cosh(x*Parser::anglemode());
+}
+double lsinh(double x)
+{ return sinh(x*Parser::anglemode());
+}
+double ltanh(double x)
+{ return tanh(x*Parser::anglemode());
+}
+
+double arccos(double x)
+{ return acos(x) * 1/Parser::anglemode();
+}
+double arcsin(double x)
+{ return asin(x)* 1/Parser::anglemode();
+}
+
+double arctan(double x)
+{ return atan(x)* 1/Parser::anglemode();
+}
diff --git a/kicker-applets/math/parser.h b/kicker-applets/math/parser.h
new file mode 100644
index 0000000..44e82ba
--- /dev/null
+++ b/kicker-applets/math/parser.h
@@ -0,0 +1,241 @@
+/*
+* Code based on parser from KmPlot - a math. function plotter for the KDE-Desktop
+*
+* Original code
+* Copyright (C) 1998, 1999 Klaus-Dieter M�ller
+* 2000, 2002 [email protected]
+*
+* Modifications: 2004 Andrew Coles ([email protected])
+*
+* This file is part of the KDE Project.
+* KmPlot is part of the KDE-EDU Project.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*/
+
+/** @file parser.h
+ * \brief Contains the parser core class Parser. */
+
+// Qt includes
+#include <qstring.h>
+#include <qvaluevector.h>
+
+#ifndef parser_included
+#define parser_included
+
+// Voreinstellungen bei Verwendung des Standardkonstruktors :
+
+
+#define UFANZ 10 ///< max. count of user defined functions
+#define MEMSIZE 200 ///< memory size for tokens
+#define STACKSIZE 50 ///< stack depth
+
+//@{
+/** Token type. */
+#define KONST 0 // double value follows
+#define XWERT 1 // get x value
+#define KWERT 2 // get function parameter
+#define PUSH 3 // push value to stack
+#define PLUS 4 // add
+#define MINUS 5 // subtract
+#define MULT 6 // multiply
+#define DIV 7 // divide
+#define POW 8 // exponentiate
+#define NEG 9 // negate
+#define FKT 10 // address to function followes
+#define UFKT 11 // address to user defined function follows
+#define ENDE 12 // end of function
+#define YWERT 13 // get y value
+#define FANZ 31 // number of mathematical functions in mfkttab[]
+//@}
+
+//@{
+/** Predefined mathematical function. */
+double sign(double x);
+double sqr(double x);
+double arsinh(double x);
+double arcosh(double x);
+double artanh(double x);
+
+double sec(double x);
+double cosec(double x);
+double cot(double x);
+double arcsec(double x);
+double arccosec(double x);
+double arccot(double x);
+
+double sech(double x);
+double cosech(double x);
+double coth(double x);
+double arsech(double x);
+double arcosech(double x);
+double arcoth(double x);
+
+double lcos(double x);
+double lsin(double x);
+double ltan(double x);
+
+double lcosh(double x);
+double lsinh(double x);
+double ltanh(double x);
+
+double arccos(double x);
+double arcsin(double x);
+double arctan(double x);
+
+//@}
+
+class Constant
+{
+public:
+ Constant( char c='A', double v=0)
+ {
+ constant = c;
+ value = v;
+ }
+
+ char constant;
+ double value;
+};
+
+/** @short Parser.
+ *
+ * Tokenizes a function equation to be evaluated.
+ */
+class Parser
+{
+public:
+
+ Parser();
+ Parser(int, int, int);
+
+ ~Parser();
+
+ /// Evaluates the given expression.
+ double eval(QString);
+ /// Evaluates the function with the given name at the position.
+ double fkt(QString, double);
+ /// Evaluates the function with the given index at the position.
+ double fkt(int ix, double x) {return ufkt[ix].fkt(x);}
+ /// Adds a user defined function with the given equation.
+ int addfkt(QString);
+ /// Removes the function with the given name.
+ int delfkt(QString);
+ /// Removes the function with the given index.
+ int delfkt(int);
+ /// Returns name and expression of the function with the given index.
+ int getfkt(int, QString&, QString&);
+ /// Checks, if at the given index a function is stored.
+ int chkfix(int);
+ /// Returns the index of the function with the given name.
+ int getfix(QString);
+ /// Returns the lowest index in the array of user defined functions which is empty,
+ /// or -1, if the array is full.
+ int getNextIndex();
+ /// Shows an error message box.
+ int errmsg();
+ /// ?
+ void setparameter(int ix, double k) {ufkt[ix].k=k;}
+ /// return the angletype
+ static double anglemode();
+ /// sets the angletype. TRUE is radians and FALSE degrees
+ void setAngleMode(int);
+
+ QValueVector<Constant> constant;
+
+ /// Error codes.
+ /**
+ * The values have following meanings:
+ * \li 0 => parse success
+ * \li 1 => syntax error
+ * \li 2 => missing bracket
+ * \li 3 => function unknown
+ * \li 4 => function variable not valid
+ * \li 5 => too much functions
+ * \li 6 => memory overflow
+ * \li 7 => stack overflow
+ * \li 8 => function name allready used
+ * \li 9 => recursive function call
+ * \li 10 => didn't found the wanted constant
+ * \li 11 => emtpy function
+ */
+ int err,
+ errpos, ///< Position where the error occured.
+ ufanz; ///< Max. count of user defined functions.
+
+
+ /** User function. */
+ class Ufkt
+ {
+ public:
+ Ufkt();
+ ~Ufkt();
+ double fkt(double); ///< User defined function.
+
+ unsigned char *mem; ///< Pointer to the allocated memory for the tokens.
+ unsigned char *mptr; ///< Pointer to the token.
+ QString fname; ///< Name of the function.
+ QString fvar; ///< Dummy variable.
+ QString fpar; ///< Parameter.
+ QString fstr; ///< Function expression.
+ int memsize; ///< Size of token memory
+ int stacksize; ///< Size of the stack.
+ double k, ///< Function parameter.
+ oldy; ///< The last y-value needed for Euler's method
+ }
+ *ufkt; ///< Points to the array of user defined functions.
+
+protected:
+ /** Mathematical function. */
+ struct Mfkt
+ {
+ const char *mfstr;
+ double (*mfadr)(double);
+ };
+ static Mfkt mfkttab[FANZ];
+
+//private:
+public:
+
+ void ps_init(int, int, int),
+ heir1(),
+ heir2(),
+ heir3(),
+ heir4(),
+ primary(),
+ addtoken(unsigned char),
+ addwert(double),
+ addfptr(double(*)(double)),
+ addfptr(Ufkt*);
+ int match(const char*);
+
+ unsigned
+ char evalflg, // 0 => String wird tokenisiert
+ // 1 => String wird direkt ausgewertet
+ *mem, // Zeiger auf Speicher fr Token
+ *mptr; // Zeiger fr Token
+ const
+ char *lptr; // Zeiger fr Funktions-String
+ int memsize, // Gr�e des Tokenspeichers
+ stacksize, // Gr�e des Stack
+ ixa; // Index der aktuellen Funktion
+ double *stack, // Zeiger auf Stackanfang
+ *stkptr; // Stackpointer
+ static double m_anglemode;
+
+};
+
+#endif // parser_included
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 <[email protected]>
+Stefan Gehn <metz {AT} gehn {DOT} net>
+Teemu Rytilahti <[email protected]>
+Thomas Capricelli <[email protected]>
+William Robinson <[email protected]>
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)
+ ***************************************************************************/
+
+
+/***************************************************************************
+ * *
+ * 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)
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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"),
+ "[email protected]", "http://metz.gehn.net");
+ mAboutData->addAuthor("Robbie Ward", I18N_NOOP("Initial About-Dialog"),
+ "[email protected]", "http://www.robbieward.co.uk");
+
+ mAboutData->addCredit("Sascha Hoffman", I18N_NOOP("Button-Pixmaps"),
+ mAboutData->addCredit("Christian Hoffman", I18N_NOOP("Button-Pixmaps"),
+ "[email protected]", "http://www.crixensgfxcorner.de.vu/");
+ mAboutData->addCredit("Ulrik Mikaelsson", I18N_NOOP("Fix for Noatun-Support"),
+ mAboutData->addCredit("Anthony J Moulen", I18N_NOOP("Fix for Vertical Slider"),
+ mAboutData->addCredit("Teemu Rytilahti", I18N_NOOP("Volume Control Implementation"),
+ mAboutData->addCredit("Jan Spitalnik", I18N_NOOP("Fix for JuK-Support"),
+ mAboutData->addCredit("William Robinson", I18N_NOOP("mpd-Support"),
+
+ 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 <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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;[email protected]&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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <[email protected]>
+ Copyright (C) 2004-2005 Aaron J. Seigo <[email protected]>
+
+ 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 <[email protected]>
+ Copyright (C) 2004-2005 Aaron J. Seigo <[email protected]>
+
+ 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