diff options
Diffstat (limited to 'kicker-applets/mediacontrol/mediacontrol.cpp')
-rw-r--r-- | kicker-applets/mediacontrol/mediacontrol.cpp | 614 |
1 files changed, 614 insertions, 0 deletions
diff --git a/kicker-applets/mediacontrol/mediacontrol.cpp b/kicker-applets/mediacontrol/mediacontrol.cpp new file mode 100644 index 0000000..e69e0e0 --- /dev/null +++ b/kicker-applets/mediacontrol/mediacontrol.cpp @@ -0,0 +1,614 @@ +/*************************************************************************** + main file of mediacontrol applet + ------------------- + begin : Tue Apr 25 11:53:11 CEST 2000 + copyright : (C) 2000-2005 by Stefan Gehn + email : metz {AT} gehn {DOT} net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "mediacontrol.h" +#include "mediacontrol.moc" + +#include "mediacontrolconfig.h" +#include "configfrontend.h" + + +#include "noatunInterface.h" +#include "xmmsInterface.h" +#include "jukInterface.h" +#include "amarokInterface.h" +#include "mpdInterface.h" +#include "kscdInterface.h" + +#include "mcslider.h" + +#include <qfile.h> +#include <qdragobject.h> +#include <qtooltip.h> +#include <qstyle.h> +#include <qslider.h> +#include <qpainter.h> +#include <qiconset.h> +#include <kpopupmenu.h> + +#include <kapplication.h> +#include <kipc.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <knotifyclient.h> +#include <kbugreport.h> +#include <dcopclient.h> + +const int MC_BUTTONSIZE = 20; // TODO: Might become dynamical for bigger panels +const int NO_BUTTONS = 4; + +extern "C" +{ + KDE_EXPORT KPanelApplet *init( QWidget *parent, const QString &configFile) + { + KGlobal::locale()->insertCatalogue("mediacontrol"); + return new MediaControl(configFile, KPanelApplet::Normal, + KPanelApplet::About | KPanelApplet::Preferences | + KPanelApplet::ReportBug, parent, "mediacontrol"); + } +} + +// ============================================================================= + +class MediaControlToolTip : public QToolTip +{ + public: + MediaControlToolTip(QWidget *widget, PlayerInterface *pl_obj) : + QToolTip(widget), mWidget(widget), mPlayer(pl_obj) {} + + protected: + virtual void maybeTip(const QPoint &pt) + { + QRect rc( mWidget->rect()); + if (rc.contains(pt)) + { + tip ( rc, mPlayer->getTrackTitle() ); + } + } + private: + QWidget *mWidget; + PlayerInterface *mPlayer; +}; + +// ============================================================================= + +MediaControl::MediaControl(const QString &configFile, Type t, int actions, + QWidget *parent, const char *name) + : DCOPObject("MediaControl"), + KPanelApplet(configFile, t, actions, parent, name), + mInstance(new KInstance("mediacontrol")), + mAboutData(new KAboutData("mediacontrol", + I18N_NOOP("MediaControl"), + MEDIACONTROL_VERSION, + I18N_NOOP("A small control-applet for various media players"), + KAboutData::License_GPL_V2, + "(c) 2001-2004 Stefan Gehn", + 0, + "http://metz.gehn.net")) +{ + setBackgroundOrigin(AncestorOrigin); + _player = 0L; + _prefsDialog = 0L; + + _configFrontend = new ConfigFrontend(config()); + // My own dcopclient + _dcopClient = new DCOPClient(); + _dcopClient->registerAs("mediacontrol", false); + + mAboutData->addAuthor("Stefan Gehn", I18N_NOOP("Main Developer"), + "metz@gehn.net", "http://metz.gehn.net"); + mAboutData->addAuthor("Robbie Ward", I18N_NOOP("Initial About-Dialog"), + "wardy@robbieward.co.uk", "http://www.robbieward.co.uk"); + + mAboutData->addCredit("Sascha Hoffman", I18N_NOOP("Button-Pixmaps"), + "tisch.sush@gmx.de", 0); + mAboutData->addCredit("Christian Hoffman", I18N_NOOP("Button-Pixmaps"), + "tisch.crix@gmx.de", "http://www.crixensgfxcorner.de.vu/"); + mAboutData->addCredit("Ulrik Mikaelsson", I18N_NOOP("Fix for Noatun-Support"), + "rawler@rsn.bth.se", 0); + mAboutData->addCredit("Anthony J Moulen", I18N_NOOP("Fix for Vertical Slider"), + "ajmoulen@moulen.org", 0); + mAboutData->addCredit("Teemu Rytilahti", I18N_NOOP("Volume Control Implementation"), + "teemu.rytilahti@kde-fi.org", 0); + mAboutData->addCredit("Jan Spitalnik", I18N_NOOP("Fix for JuK-Support"), + "honza@spitalnik.net", 0); + mAboutData->addCredit("William Robinson", I18N_NOOP("mpd-Support"), + "airbaggins@yahoo.co.uk", 0); + + setAcceptDrops(true); + + prev_button = new TrayButton (this, "PREVIOUS"); + playpause_button = new TrayButton (this, "PLAYPAUSE"); + stop_button = new TrayButton (this, "STOP"); + next_button = new TrayButton (this, "NEXT"); + time_slider = new MCSlider (QSlider::Horizontal, this, "time_slider" ); + time_slider->setRange(0,0); + time_slider->setValue(0); + time_slider->setTracking( false ); + time_slider->installEventFilter(this); + + // request notification of changes in icon style + kapp->addKipcEventMask(KIPC::IconChanged); + connect(kapp, SIGNAL(iconChanged(int)), this, SLOT(slotIconChanged())); + + reparseConfig(); + + rmbMenu = new KPopupMenu(this, "RMBMenu"); + rmbMenu->insertTitle(i18n("MediaControl"), 0, 0); + rmbMenu->insertItem(SmallIcon("configure"), i18n("Configure MediaControl..."), + this, SLOT(preferences())); + rmbMenu->insertItem(i18n("About MediaControl"), this, SLOT(about())); +} + +MediaControl::~MediaControl() +{ + delete _player; + delete _configFrontend; + delete _dcopClient; + KGlobal::locale()->removeCatalogue("mediacontrol"); +} + +// Drag-n-Drop stuff =========================================================== + +void MediaControl::dragEnterEvent(QDragEnterEvent* event) +{ + _player->dragEnterEvent(event); // Just pass dnd to the playerInterface +} + +void MediaControl::dropEvent(QDropEvent* event) +{ + _player->dropEvent(event); // Just pass dnd to the playerInterface +} + +// ============================================================================= + + +void MediaControl::setSliderPosition(int len ,int time) +{ + time_slider->blockSignals(true); + if(orientation() == Vertical) + time = len - time; + + if (mLastLen != len) + time_slider->setRange(0,len); + mLastLen = len; + + if (mLastTime != time) + time_slider->setValue(time); + mLastTime = time; + + time_slider->blockSignals(false); +} + +void MediaControl::enableAll() +{ + prev_button->setDisabled(false); + playpause_button->setDisabled(false); + QToolTip::remove(playpause_button); + stop_button->setDisabled(false); + next_button->setDisabled(false); + time_slider->setDisabled(false); +} + +void MediaControl::disableAll() +{ + prev_button->setDisabled(true); + playpause_button->setDisabled(false); + QToolTip::add(playpause_button, i18n("Start the player")); + stop_button->setDisabled(true); + next_button->setDisabled(true); + time_slider->setDisabled(true); + if(_configFrontend->useCustomTheme()) { + QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/"); + playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png"))); + } + else + playpause_button->setIconSet(SmallIconSet("player_play")); +} + +void MediaControl::slotPlayingStatusChanged(int status) +{ + if (mLastStatus == status) + return; + + mLastStatus = status; + QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/"); + + switch (status) + { + case (PlayerInterface::Stopped): + case (PlayerInterface::Paused): + if(_configFrontend->useCustomTheme()) + playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png"))); + else + playpause_button->setIconSet(SmallIconSet("player_play")); + break; + case (PlayerInterface::Playing): + if(_configFrontend->useCustomTheme()) + playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"pause.png"))); + else + playpause_button->setIconSet(SmallIconSet("player_pause")); + break; + } +} + +void MediaControl::slotIconChanged() +{ + if(!_configFrontend->useCustomTheme()) + { + prev_button->setIconSet(SmallIconSet("player_start")); + if (_player->playingStatus() == PlayerInterface::Playing) + playpause_button->setIconSet(SmallIconSet("player_pause")); + else + playpause_button->setIconSet(SmallIconSet("player_play")); + stop_button->setIconSet(SmallIconSet("player_stop")); + next_button->setIconSet(SmallIconSet("player_end")); + } +} + +// Dialogs ===================================================================== + +void MediaControl::preferences() +{ + if ( _prefsDialog ) + { + _prefsDialog->raise(); + } + else + { + _prefsDialog = new MediaControlConfig ( _configFrontend ); + connect ( _prefsDialog, SIGNAL(closing()), + this, SLOT(slotClosePrefsDialog()) ); + connect ( _prefsDialog, SIGNAL(destroyed()), + this, SLOT(slotPrefsDialogClosing()) ); + connect ( _prefsDialog, SIGNAL(configChanged()), + this, SLOT(slotConfigChanged()) ); + } +} + +void MediaControl::slotConfigChanged() +{ + reparseConfig(); +} + +void MediaControl::slotClosePrefsDialog() +{ + delete _prefsDialog; +} + +void MediaControl::slotPrefsDialogClosing() +{ + if ( _prefsDialog ) + _prefsDialog = 0L; +} + + +void MediaControl::about() +{ + KAboutApplication aboutDlg(mAboutData); + aboutDlg.exec(); +} + + +void MediaControl::reportBug() +{ + KBugReport bugReport(this, true, mAboutData); + bugReport.exec(); +} + + +// Fixing the orientation problem in qslider. +void MediaControl::adjustTime(int time) +{ + if(orientation() == Vertical) + emit(newJumpToTime(mLastLen - time)); + else + emit(newJumpToTime(time)); +} + +// Config Stuff ================================================================ + +void MediaControl::reparseConfig() +{ +// kdDebug(90200) << "reparseConfig();" << endl; + _configFrontend->reparseConfiguration(); + + if (_player != 0L) // make sure there is no player-object + { + _player->disconnect(); // disconnect from all things + + time_slider->disconnect(); + prev_button->disconnect(); + playpause_button->disconnect(); + stop_button->disconnect(); + next_button->disconnect(); + + delete slider_tooltip; // tooltip depends on _player : delete it before _player gets deleted + slider_tooltip = 0L; + + delete _player; + _player = 0L; + } + + mLastLen = -1; + mLastTime = -1; + mLastStatus = -1; + + QString playerString = _configFrontend->player(); + + +#ifdef HAVE_XMMS + if (playerString == "XMMS") + { + _player = new XmmsInterface (); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()*1000), + (_configFrontend->mouseWheelSpeed()*1000)); + } + else +#endif + if (playerString == "JuK") + { + _player = new JuKInterface(); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()), + (_configFrontend->mouseWheelSpeed())); + } + else if (playerString == "Amarok") + { + _player = new AmarokInterface(); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()), + (_configFrontend->mouseWheelSpeed())); + } + else if (playerString == "KsCD") + { + _player = new KsCDInterface(); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()), + (_configFrontend->mouseWheelSpeed())); + } + else if (playerString == "mpd") + { + _player = new MpdInterface(); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()), + (_configFrontend->mouseWheelSpeed())); + } + else // Fallback is Noatun + { + _player = new NoatunInterface(); + time_slider->setSteps((_configFrontend->mouseWheelSpeed()), + (_configFrontend->mouseWheelSpeed())); + } + + // this signal gets emitted by a playerInterface when the player's playtime changed + connect(_player, SIGNAL(newSliderPosition(int,int)), + this, SLOT(setSliderPosition(int,int))); + + connect(_player, SIGNAL(playerStarted()), SLOT(enableAll())); + connect(_player, SIGNAL(playerStopped()), SLOT(disableAll())); + connect(_player, SIGNAL(playingStatusChanged(int)), SLOT(slotPlayingStatusChanged(int))); + + // do we use our icons or the default ones from KDE? + if(_configFrontend->useCustomTheme()) + { + // load theme + QString skindir = locate("data", "mediacontrol/"+_configFrontend->theme()+"/"); + + // the user has to take care if all pixmaps are there, we only check for one of them + if (QFile(skindir+"play.png").exists()) + { + prev_button->setIconSet(SmallIconSet(locate("data",skindir+"prev.png"))); + if (_player->playingStatus() == PlayerInterface::Playing) + playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"play.png"))); + else + playpause_button->setIconSet(SmallIconSet(locate("data",skindir+"pause.png"))); + stop_button->setIconSet(SmallIconSet(locate("data",skindir+"stop.png"))); + next_button->setIconSet(SmallIconSet(locate("data",skindir+"next.png"))); + } + else // icon-theme is invalid or not there + { + KNotifyClient::event(winId(), KNotifyClient::warning, + i18n("There was trouble loading theme %1. Please choose" \ + " a different theme.").arg(skindir)); + + // default to kde-icons, they have to be installed :) + slotIconChanged(); + + // and open prefs-dialog + preferences(); + } + } + else // KDE default-icons, assuming that these icons exist! + { + // sets icons from kde + slotIconChanged(); + } + + slider_tooltip = new MediaControlToolTip(time_slider, _player); + + connect(prev_button, SIGNAL(clicked()), _player, SLOT(prev())); + connect(playpause_button, SIGNAL(clicked()), _player, SLOT(playpause())); + connect(stop_button, SIGNAL(clicked()), _player, SLOT(stop())); + connect(next_button, SIGNAL(clicked()), _player, SLOT(next())); + + connect(time_slider, SIGNAL(sliderPressed()), _player, SLOT(sliderStartDrag())); + connect(time_slider, SIGNAL(sliderReleased()), _player, SLOT(sliderStopDrag())); + connect(time_slider, SIGNAL(valueChanged(int)), this, SLOT(adjustTime(int))); + connect(time_slider, SIGNAL(volumeUp()), _player, SLOT(volumeUp())); + connect(time_slider, SIGNAL(volumeDown()), _player, SLOT(volumeDown())); + connect(this, SIGNAL(newJumpToTime(int)), _player, SLOT(jumpToTime(int))); +} + +// Widget Placement =================================================================== + +// kicker wants to know what width we need for a given height +// (this is called when being a HORIZONTAL panel) +int MediaControl::widthForHeight(int height) const +{ +// kdDebug(90200) << "kicker height: " << height << endl; +// kdDebug(90200) << "slider needs: " << time_slider->minimumSizeHint().height() << endl; + + // slider height + button height + if ( height >= (time_slider->minimumSizeHint().height()+MC_BUTTONSIZE) ) + { // slider UNDER buttons + // (5 * button width + spaces between them); + return (4*MC_BUTTONSIZE+10); + } + else + { // slider ASIDE buttons + // (5 * button width + spaces between them) * 2 [size of slider = size of all buttons] + return ((4*MC_BUTTONSIZE+10)*2); + } +} + +// kicker wants to know what height we need for a given width +// (this is called when being a VERTICAL panel) +int MediaControl::heightForWidth(int width) const +{ +// kdDebug(90200) << "kicker width: " << width << endl; + + // slider height + button height + if ( width >= (time_slider->minimumSizeHint().width()+MC_BUTTONSIZE) ) + { // slider ASIDE icons + // (5 * button width + spaces between them); + return (4*MC_BUTTONSIZE+10); + } + else + { // slider UNDER buttons + // (5 * button width + spaces between them) * 2 + // because the size of the slider = the size of all buttons + return ((4*MC_BUTTONSIZE+10)*2); + } +} + +void MediaControl::mousePressEvent(QMouseEvent* e) +{ + if (e->button() == QMouseEvent::RightButton) + rmbMenu->popup(e->globalPos()); +} + +bool MediaControl::eventFilter(QObject *, QEvent *e) +{ + if (e->type() == QEvent::MouseButtonPress) + { + QMouseEvent *me = static_cast<QMouseEvent *>(e); + if (me->button() == QMouseEvent::RightButton) + { + rmbMenu->popup(me->globalPos()); + return true; + } + } + return false; +} + +void MediaControl::paletteChange( const QPalette& ) +{ + time_slider->setBackground(); +} + +void MediaControl::moveEvent( QMoveEvent* ) +{ + time_slider->setBackground(); +} + +// Danger: Weird Code ahead! ;)) +void MediaControl::resizeEvent( QResizeEvent* ) +{ +// kdDebug(90200) << "resizeEvent()" << endl; + int w = width(); + int h = height(); + if ( orientation() == Vertical ) + { // ====== VERTICAL ================================================= + time_slider->setOrientation(QSlider::Vertical); + int slider_width = time_slider->minimumSizeHint().width(); + // some styles need more space for sliders than avilable in very small panels :( + if ( slider_width > w ) slider_width = w; + + // that width would be needed to put the slider aside the buttons + if ( w >= (slider_width+MC_BUTTONSIZE) ) + { // Slider ASIDE icons + int applet_space = (w - (slider_width+MC_BUTTONSIZE) ) / 2; + if ( applet_space < 0 ) + applet_space = 0; + + prev_button->setGeometry ( applet_space, 1, MC_BUTTONSIZE, MC_BUTTONSIZE ); + playpause_button->setGeometry ( applet_space, 3+1*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + stop_button->setGeometry ( applet_space, 5+2*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + next_button->setGeometry ( applet_space, 7+3*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + time_slider->setGeometry ( applet_space+MC_BUTTONSIZE, 1, slider_width, NO_BUTTONS*MC_BUTTONSIZE+8 ); + } + else + { // Slider UNDER Icons + int slider_space = (w - slider_width)/2; + int button_space = (w - MC_BUTTONSIZE)/2; + + prev_button->setGeometry ( button_space, 1 , MC_BUTTONSIZE, MC_BUTTONSIZE ); + playpause_button->setGeometry ( button_space, 3+1*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + stop_button->setGeometry ( button_space, 5+2*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + next_button->setGeometry ( button_space, 7+3*MC_BUTTONSIZE, MC_BUTTONSIZE, MC_BUTTONSIZE ); + time_slider->setGeometry ( slider_space, 9+4*MC_BUTTONSIZE, slider_width, NO_BUTTONS*MC_BUTTONSIZE+8 ); + } + } + else // ====== HORIZONTAL =============================================== + { + time_slider->setOrientation(QSlider::Horizontal); + int slider_height = time_slider->minimumSizeHint().height(); + // some styles need more space for sliders than avilable in very small panels :( + if ( slider_height > h ) slider_height = h; + + // that h would be needed to put the slider under the buttons + if ( h >= (slider_height+MC_BUTTONSIZE) ) + { // Slider UNDER icons + int applet_space = (h-(slider_height+MC_BUTTONSIZE))/2; + if ( applet_space < 0 ) + applet_space = 0; + + prev_button->setGeometry ( 1 , applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + playpause_button->setGeometry ( 3+MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + stop_button->setGeometry ( 5+2*MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + next_button->setGeometry ( 7+3*MC_BUTTONSIZE, applet_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + time_slider->setGeometry ( 1, applet_space + MC_BUTTONSIZE, NO_BUTTONS*MC_BUTTONSIZE+8, slider_height ); + } + else + { // Slider ASIDE Icons + int slider_space = (h - slider_height)/2; + int button_space = (h - MC_BUTTONSIZE)/2; + + prev_button->setGeometry ( 1 , button_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + playpause_button->setGeometry ( 3+1*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + stop_button->setGeometry ( 5+2*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + next_button->setGeometry ( 7+3*MC_BUTTONSIZE, button_space, MC_BUTTONSIZE, MC_BUTTONSIZE ); + time_slider->setGeometry ( 9+4*MC_BUTTONSIZE, slider_space, NO_BUTTONS*MC_BUTTONSIZE+8, slider_height ); + } + } +} + +// Our Button ======================================================================== + +TrayButton::TrayButton(QWidget* parent, const char* name) + : SimpleButton (parent, name) +{ + setBackgroundMode(PaletteBackground); + setBackgroundOrigin(AncestorOrigin); +} + +void TrayButton::setIconSet(const QIconSet &iconSet) +{ + setPixmap(iconSet.pixmap(QIconSet::Automatic, QIconSet::Normal, QIconSet::On)); +} + |