Logo Search packages:      
Sourcecode: kaffeine version File versions

kaffeine.cpp

/***************************************************************************
 *   Copyright (C) 2004-2005 by J├╝rgen Kofler                                   *
 *   kaffeine@gmx.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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

 /*
  * Last modified: $Date: 2005/03/13 12:12:49 $ by $Author: juergenk $
  */

#include "kaffeine.h"

#include <kkeydialog.h>
#include <kfiledialog.h>
#include <kdirselectdialog.h>
#include <kconfig.h>
#include <kurl.h>
#include <kedittoolbar.h>
#include <kaction.h>
#include <kaccel.h>
#include <kstdaction.h>
#include <klibloader.h>
#include <kparts/componentfactory.h>
#include <kmessagebox.h>
#include <kstatusbar.h>
#include <kmenubar.h>
#include <kcombobox.h>
#include <kpopupmenu.h>
#include <ktabbar.h>
#include <kwin.h>
#include <ktrader.h>
#include <klocale.h>
#include <kdebug.h>
#include <kprocess.h>
#include <kstandarddirs.h>
#include <kio/netaccess.h>
#include <kaboutdata.h>
#include <kiconloader.h>
#include <dcopclient.h>

#include <qdir.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qinputdialog.h>
#include <kurldrag.h>
#include <qsignalmapper.h>
#include <qdockarea.h>

#include <X11/keysym.h>
#ifdef HAVE_XTEST
#include <X11/extensions/XTest.h>
#endif

#include "kaffeine.moc"
#include "kmediapart.h"
#include "playlist.h"
#include "pref.h"
#include "startwindow.h"
#include "systemtray.h"
#include "wizarddialog.h"
#include "drivescombo.h"
#ifdef HAVE_LINUX_DVB_FRONTEND_H
#include "dvbpanel.h"
#endif

#define DEFAULT_FILTER "*.anx *.axa *.axv *.vob *.png *.y4m *.rm *.ram *.rmvb *.pva *.nsv *.ogg *.ogm *.spx *.png *.mng *.pes *.iff *.svx *.8svx *.16sv *.ilbm *.pic *.anim *.wav *.vox *.voc *.snd *.au *.ra *.nsf *.flac *.aif *.aiff *.aud *.flv *.fli *.flc *.avi *.asf *.wmv *.wma *.asx *.wvx *.wax *.mkv *.vmd *.4xm *.mjpg *.cpk *.cak *.film *.str *.iki *.ik2 *.dps *.dat *.xa *.xa1 *.xa2 *.xas *.xap *.roq *.mve *.vqa *.mve *.mv8 *.cin *.wve *.mov *.qt *.mp4 *.ts *.m2t *.trp *.mpg *.mpeg *.dv *.dif *.flac *.mp3 *.mp2 *.mpa *.mpega *.ac3 *.aac *.asc *. *.sub *.srt *.smi *.ssa *.mpv *.m4a *.mpc *.mp+ *.ANX *.AXA *.AXV *.VOB *.PNG *.Y4M *.RM *.RAM *.RMVB *.PVA *.NSV *.OGG *.OGM *.SPX *.PNG *.MNG *.PES *.IFF *.SVX *.8SVX *.16SV *.ILBM *.PIC *.ANIM *.WAV *.VOX *.VOC *.SND *.AU *.RA *.NSF *.FLAC *.AIF *.AIFF *.AUD *.FLV *.FLI *.FLC *.AVI *.ASF *.WMV *.WMA *.ASX *.WVX *.WAX *.MKV *.VMD *.4XM *.MJPG *.CPK *.CAK *.FILM *.STR *.IKI *.IK2 *.DPS *.DAT *.XA *.XA1 *.XA2 *.XAS *.XAP *.ROQ *.MVE *.VQA *.MVE *.MV8 *.CIN *.WVE *.MOV *.QT *.MP4 *.TS *.M2T *.TRP *.MPG *.MPEG *.DV *.DIF *.FLAC *.MP3 *.MP2 *.MPA *.MPEGA *.AC3 *.AAC *.ASC *. *.SUB *.SRT *.SMI *.SSA *.MPV *.M4A *.MPC *.MP+"

#define DEFAULT_PLAYER_PART "kaffeine_part"

#define LONG64
#ifdef HAVE_XTEST
#include <X11/Xmd.h>
extern "C"
{
#include <X11/extensions/dpms.h>
      Bool DPMSQueryExtension(Display *, int *, int *);
      Bool DPMSGetTimeout(Display *dspl, CARD16 *standby, CARD16 *suspend, CARD16 *off);
      Status DPMSEnable(Display *);
      Bool DPMSSetTimeouts(Display *, CARD16, CARD16, CARD16);
}
#endif

CARD16 stb_no;
CARD16 sus_no;
CARD16 off_no;
CARD16 standby;
CARD16 suspend;
CARD16 off;

00104 Kaffeine::Kaffeine(const QStringList& urls, const QStringList& engineParameters, const QString device,
                   bool instantPlay, bool fullscr, bool wizard, QWidget* parent, const char* name)
    : DCOPObject("KaffeineIface"),
      KMainWindow(parent, name), m_mediaPart(NULL), m_simplePart(NULL), m_playerContainer(NULL), m_startWindow(NULL),
      m_systemTray(NULL), m_videoSize(0,0), m_noResize(false), m_autoPaused(false), m_currentPartService(QString::null),
      m_device(device), m_engineParameters(engineParameters)
{
    setAcceptDrops(true);

#ifdef HAVE_LINUX_DVB_FRONTEND_H
    // dvb widget
    if ( DVBconfig::haveDvbDevice() ) {
      kdDebug() << "Found DVB device." << endl;
      dvbPanel = new DvbPanel( this, 0, "dvbpanel" );
    }
    else {
      dvbPanel = 0;
      kdDebug() << "No DVB device found." << endl;
    }
#endif

    setupActions();
    KComboBox* playlistSelector = new KComboBox;
    playlistSelector->setMinimumWidth(150);
    QToolTip::add(playlistSelector, i18n("Select Playlist"));
    KAction* action = new KWidgetAction(playlistSelector, i18n("Select Playlist"), 0, 0, 0, actionCollection(), "playlist_selector");
    action->setWhatsThis(i18n("Select the active playlist. To change playlist name edit it and confirm with 'Return'."));
    setStandardToolBarMenuEnabled(true);
    createStandardStatusBarAction();
    createGUI("kaffeineui.rc");

    //statusBar()->insertItem(i18n("Entries: %1, Playtime: %2  (Total: %3, %4)").arg("0").arg("00:00:00").arg("0").arg("00:00:00"), 9, 0, true);
    statusBar()->insertItem(i18n("Entries: %1, Playtime: %2").arg("0").arg("0:00:00"), 9, 0, true);
    statusBar()->insertItem(i18n("No player"), 10, 0, true);

    QString stamp =  locateLocal("appdata", "wizard_stamp_v0.5");
    if ((!QFile::exists(stamp)) || (wizard))
    {
      WizardDialog* wizardDlg = new WizardDialog( 0, "wizard" );
      wizardDlg->exec();

      KProcess process;
      process << "touch" << stamp;
      process.start(KProcess::Block, KProcess::Stderr);
      process.clearArguments();
    }

    // central tab widget
    m_tabWidget = new TabWidget(this);
    m_tabWidget->setMargin(0);
    setCentralWidget(m_tabWidget);
    connect(m_tabWidget, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotCurrentTabChanged(QWidget*)));

    // playlist
    m_playlist = new PlayList(playlistSelector, m_tabWidget);
    m_playlist->setFileFilter(DEFAULT_FILTER);
    connect(m_playlist, SIGNAL(signalPlay(const MRL&)), this, SLOT(slotPlay(const MRL&)));
    connect(m_playlist, SIGNAL(signalPlaylistStatus(const QString&)), this, SLOT(slotChangePlaylistStatus(const QString&)));
    connect(m_playlist, SIGNAL(signalRequestForDVD()), this, SLOT(slotOpenDVD()));
    connect(m_playlist, SIGNAL(signalRequestForVCD()), this, SLOT(slotOpenVCD()));
    connect(m_playlist, SIGNAL(signalRequestForAudioCD()), this, SLOT(slotOpenAudioCD()));
    connect(m_playlist, SIGNAL(signalToggleDockState()), this, SLOT(slotTogglePlaylistDockState()));
    m_tabWidget->addTab(m_playlist, i18n("Playlist"));

#ifdef HAVE_LINUX_DVB_FRONTEND_H
    if ( dvbPanel ) {
      dvbPanel->reparent(m_tabWidget, QPoint(0,0), true);
      m_tabWidget->addTab(dvbPanel, i18n("DVB"));
      dvbPanel->checkFirstRun();
    }
#endif

    QTextStream ts(&m_filter, IO_WriteOnly);
    ts << "|" << i18n("Supported Media Formats") << "\n"
       << "*.mp3 *.mpa *mpega *.m4a *.mpc *.mp+ *.MP3 *.MPA *.MPEGA *.M4A *.MPC *.MP+|" <<  i18n("MPEG Audio Files") << "\n"
       << "*.mjpeg *.mpg *.mpeg *.mp2 *.mpv *.vob *.MJPEG *.MPG *.MPEG *.MP2 *.MPV *.VOB|" << i18n("MPEG Video Files") << "\n"
       << "*.ogg *.ogm *.OGG *.OGM|" << i18n("Ogg Vorbis Files") << "\n"
       << "*.avi *.AVI|" << i18n("AVI Files") << "\n"
       << "*.mov *.qt *.MOV *.QT|" << i18n("Quicktime Files") << "\n"
       << "*.rm *.ram *.ra *.rmvb *.RM *.RAM *.RA *.RMVB|" << i18n("Real Media Files") << "\n"
       << "*.mkv *.mka *.MKV *.MKA|" << i18n("Matroska Files") << "\n"
       << "*.flac *.flc *.FLAC *.FLC|" << i18n("FLAC Files") << "\n"
       << "*.wmv *.wma *.asf *.asx *.wvx *.wax *.WMV *.WMA *.ASF *.ASX *.WVX *.WAX|" << i18n("Windows Media Files") << "\n"
       << "*.wav *.WAV|" << i18n("WAV Files") << "\n"
       << "*.m3u *.M3U|" << i18n("M3U Playlists") << "\n"
       << "*.kaffeine *.KAFFEINE|" << i18n("Kaffeine Playlists") << "\n"
       << "*.*|" << i18n("All Files");

/** KWin are you there? **/

    m_haveKWin = KApplication::dcopClient()->isApplicationRegistered("kwin");
    if (m_haveKWin)
      kdDebug() << "Window manager: KWin found" << endl;
     else
      kdDebug() << "Window manager: not KWin - using save fullscreen mode" << endl;

/** get a keycode for a faked key event to hold down screensaver **/

#ifdef HAVE_XTEST
    int a,b,c,d;
    m_haveXTest = XTestQueryExtension(x11Display(), &a, &b, &c, &d);
    if (m_haveXTest)
      m_xTestKeycode = XKeysymToKeycode(x11Display(), XK_Shift_L);
    connect(&m_screensaverTimer, SIGNAL(timeout()), this, SLOT(slotFakeKeyEvent()));
#endif

  KAccel* accel = new KAccel(this);
  accel->insert("Escape Fullscreen", Key_Escape, this, SLOT(slotEscapeFullscreen()));

  loadConfig();
  slotChangeStatusbar(i18n("Kaffeine Player") + " " + VERSION);

  bool rmdvb=true;
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) rmdvb = false;
#endif
  if ( rmdvb ) {
      int i, j;
      for ( i=0; i<(int)menuBar()->count(); i++ ) {
            j = menuBar()->idAt(i);
            if (  menuBar()->text(j)==i18n("&DVB") ) {
                  menuBar()->removeItem(j);
                  break;
            }
      }
  }

  // process command line parameters

  if ((!instantPlay) && (!urls.count()) && (m_playlist->parentWidget()))
  {
     if (m_startWindow)
       m_tabWidget->showPage(m_startWindow);
      else
       m_tabWidget->showPage(m_playlist);
  }
  else
  {
    m_tabWidget->showPage(m_playerContainer);
  }

  bool disc = false;
  for (QStringList::ConstIterator it = urls.begin(); it != urls.end(); ++it)
  {
    if ((*it).lower() == "dvd")
    {
      slotOpenDVD();
      disc = true;
    }
    if ((*it).lower() == "vcd")
    {
      slotOpenVCD();
      disc = true;
    }
    if (((*it).lower() == "audiocd") || ((*it).lower() == "cdda"))
    {
      slotOpenAudioCD();
      disc = true;
    }
  }
  if (!disc)
    loadTMP(urls);
  if (fullscr)
    fullscreen();
  if ((instantPlay) && (!disc) && (!urls.count()))
    slotPlaylistPlay();
}

Kaffeine::~Kaffeine()
{
  kdDebug() << "Kaffeine: destructor" << endl;
  delete m_playlist;
}

void Kaffeine::unloadCurrentPart()
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) {
      dvbPanel->stopLive();
      dvbPanel->enableLiveDvb( false );
  }
#endif
  if (!m_currentPartService.isNull())
  {
    kdDebug() << "Kaffeine: Unloading player part: " << m_currentPartService << endl;
    if (m_mediaPart)
    {
      saveMainWindowSettings(kapp->config(), "Main Window");  // save toolbar state etc.
      guiFactory()->removeClient(m_mediaPart);
    }
    else
    if (m_simplePart)
    {
      applyMainWindowSettings(kapp->config(), "Main Window"); // save toolbar state etc.
      guiFactory()->removeClient(m_simplePart);
    }
    KService::Ptr service = KService::serviceByDesktopName(m_currentPartService);
    KLibLoader::self()->unloadLibrary(service->library());
    m_mediaPart = NULL;
    m_simplePart = NULL;
    m_tabWidget->removePage(m_playerContainer);
    delete m_playerContainer;
    m_playerContainer = NULL;
    statusBar()->changeItem(i18n("No player"), 10);
  }
}

void Kaffeine::slotLoadPart(const QString& desktopName)
{
  kdDebug() << "Kaffeine:: Try to load service: " << desktopName << endl;

  if (desktopName == m_currentPartService)
    return;

  KService::Ptr service = KService::serviceByDesktopName(desktopName);
  if (!service)
  {
    KMessageBox::detailedError(this, i18n("Loading of player part '%1' failed.").arg(desktopName), i18n("%1 not found in search path.").arg(QString(desktopName)+ ".desktop"));
    return;
  }

  unloadCurrentPart();

 //player container widget, will contain the player part
  m_playerContainer = new PlayerContainer(m_tabWidget);
  m_tabWidget->insertTab(m_playerContainer, i18n("Player"), 0);
  connect(m_playerContainer, SIGNAL(signalURLDropEvent(const QStringList&)), this, SLOT(slotLoadURLS(const QStringList&)));

  if (service->serviceTypes().contains("KMediaPart"))
  {
    kdDebug() << "This is a KMediaPart..." << endl;
    int error = 0;
    m_mediaPart = KParts::ComponentFactory::createPartInstanceFromService<KMediaPart>(service, m_playerContainer, service->name(),
                  this, 0, m_engineParameters, &error);
    if (error > 0)
    {
      KMessageBox::detailedError(this, i18n("Loading of player part '%1' failed.").arg(service->name()), KLibLoader::self()->lastErrorMessage());
    }
    else
    {
      connect(m_mediaPart, SIGNAL(setWindowCaption(const QString&)), this, SLOT(slotChangeCaption(const QString&)));
      connect(m_mediaPart, SIGNAL(setStatusBarText(const QString&)), this, SLOT(slotChangeStatusbar(const QString&)));
      connect(m_mediaPart, SIGNAL(canceled(const QString&)), this, SLOT(slotLoadingCanceled(const QString&)));
      connect(m_mediaPart, SIGNAL(signalPlaybackFailed()), this, SLOT(slotPlaybackFailed()));
      connect(m_mediaPart, SIGNAL(signalTrackFinished()), this, SLOT(slotPlaylistNext()));
      connect(m_mediaPart, SIGNAL(signalNewMeta()), this, SLOT(slotMetaFromPlayer()));
      connect(m_mediaPart, SIGNAL(signalNewFrameSize(const QSize&)), this, SLOT(slotNewFrameSize(const QSize&)));
#ifdef HAVE_LINUX_DVB_FRONTEND_H
      if ( service->name()=="Kaffeine" && dvbPanel ) {
            connect( dvbPanel, SIGNAL(dvbPause(bool)), m_mediaPart, SLOT(slotTogglePause(bool)) );
      connect( dvbPanel, SIGNAL(dvbOpen(QString,QString,int)), m_mediaPart, SLOT(slotDvbOpen(QString,QString,int)) );
      connect( dvbPanel, SIGNAL(dvbStop()), m_mediaPart, SLOT(slotStop()) );
      connect( m_mediaPart, SIGNAL(stopDvb()), dvbPanel, SLOT(stopLive()) );
      connect( m_mediaPart, SIGNAL(playerPause()), dvbPanel, SLOT(pauseLiveTV()) );
      connect( dvbPanel, SIGNAL(setTimeShiftFilename(QString)), m_mediaPart, SLOT(getTimeShiftFilename(QString)) );
      connect( dvbPanel, SIGNAL(showPlayer()), this, SLOT(slotSwitchToPlayerWindow()) );
      connect( dvbPanel, SIGNAL(showOSD(QString,int,int)), m_mediaPart, SLOT(requestForOSD(QString,int,int)) );
      connect( dvbPanel, SIGNAL(showDvbOSD(QStringList)), m_mediaPart, SLOT(setDvbCurrentNext(QStringList)) );
      dvbPanel->enableLiveDvb( true );
      }
#endif
      m_currentPartService = desktopName;
      m_playlist->setFileFilter(DEFAULT_FILTER);
      //QString playerName = service->name();
      QString playerName = m_mediaPart->instance()->aboutData()->programName();
      if (playerName.length() > 20)
      {
        playerName.truncate(17);
      playerName = playerName + "...";
      }
      statusBar()->changeItem(playerName, 10);
      slotChangeStatusbar(m_mediaPart->instance()->aboutData()->shortDescription());
      guiFactory()->addClient(m_mediaPart);
      applyMainWindowSettings(kapp->config(), "Main Window"); //restore toolbar state
      stateChanged("no_media_part", StateReverse);
      if (m_startWindow)
        m_startWindow->enableDiscIcons(true);
      slotPlaylistPlay();
    }
  }
  else
  {
    kdDebug() << "No KMediaPart..." << endl;
    int error = 0;
    m_simplePart = KParts::ComponentFactory::createPartInstanceFromService<KParts::ReadOnlyPart>(service, m_playerContainer,
                   service->name(), this, 0, m_engineParameters, &error);
    if (error > 0)
    {
      KMessageBox::detailedError(this, i18n("Loading of player part '%1' failed.").arg(service->name()), KLibLoader::self()->lastErrorMessage());
    }
    else
    {
      connect(m_simplePart, SIGNAL(setWindowCaption(const QString&)), this, SLOT(slotChangeCaption(const QString&)));
      connect(m_simplePart, SIGNAL(setStatusBarText(const QString&)), this, SLOT(slotChangeStatusbar(const QString&)));
      connect(m_simplePart, SIGNAL(canceled(const QString&)), this, SLOT(slotLoadingCanceled(const QString&)));
      m_currentPartService = desktopName;
      m_playlist->setFileFilter(DEFAULT_FILTER);
      //QString playerName = service->name();
      QString playerName = m_simplePart->instance()->aboutData()->programName();
      if (playerName.length() > 20)
      {
        playerName.truncate(17);
      playerName = playerName + "...";
      }
      statusBar()->changeItem(playerName, 10);
      slotChangeStatusbar(m_simplePart->instance()->aboutData()->shortDescription());
      guiFactory()->addClient(m_simplePart);
      applyMainWindowSettings(kapp->config(), "Main Window"); //restore toolbar state
      stateChanged("no_media_part");
      if (m_startWindow)
        m_startWindow->enableDiscIcons(false);
      slotPlaylistPlay();
    }
  }
}

void Kaffeine::slotLoadingCanceled(const QString& message)
{
  QString name;
  if (m_mediaPart)
    name = m_mediaPart->name();
   else
    if (m_simplePart)
      name = m_simplePart->name();
  KMessageBox::detailedError(this, i18n("Loading of player part '%1' failed.").arg(name), message);
}

void Kaffeine::slotPlaybackFailed()
{
  /*
   * TODO: ask user for loading another part?
   */
   //slotPlaylistNext();
  m_mediaPart->closeURL();
}

void Kaffeine::load(const QString& url)
{
  load(QStringList(url));
}

00445 void Kaffeine::load(const QStringList& urllist)
{
  if (!urllist.count())
    return;

  if (urllist[0].contains(".kaffeine", false))
  {
    m_playlist->loadPlaylist(urllist[0]);
  }
  else
  {
    m_playlist->add(urllist, NULL);
    QListViewItem* tmp = m_playlist->findByURL(urllist.first());
    if (tmp)
    {
      m_playlist->setCurrentEntry(tmp);
      slotPlaylistPlay();
    }
  }
}

void Kaffeine::slotLoadURLS(const QStringList& list)
{
  loadTMP(list);
}

void Kaffeine::slotPlay(const MRL& mrl)
{
  if (m_mediaPart)
  {
    m_mediaPart->openURL(mrl);
    if (mrl.mime().contains("video"))
      QTimer::singleShot(300, this, SLOT(slotSwitchToPlayerWindow()));
  }
  else
  {
    if (m_simplePart)
    {
      m_simplePart->openURL(mrl.kurl());
      if (mrl.mime().contains("video"))
        QTimer::singleShot(300, this, SLOT(slotSwitchToPlayerWindow()));
    }
  }
}

void Kaffeine::slotPlaylistPlay()
{
  MRL mrl = m_playlist->getCurrent();
  if (!mrl.isEmpty())
  {
    m_recent->addURL(mrl.kurl());
    slotPlay(mrl);
  }
}

void Kaffeine::slotPlaylistNext()
{
  MRL mrl = m_playlist->getNext();
  if (!mrl.isEmpty())
  {
    if (m_sleepAfterPlay->isChecked())
    {
      stop();
      slotSleepAfterPlay();// Shut screen off
      return;
    }
    if (m_quitAfterPlay->isChecked())
    {
      stop();
      slotQuitAfterPlay();
      return;
    }
    m_recent->addURL(mrl.kurl());
    slotPlay(mrl);
  }
  else
  {
    if ((m_mediaPart) && (!m_mediaPart->isPlaying())) // playback finished, nothing more to play
    {
      m_mediaPart->closeURL();
      if (m_sleepAfterPlay->isChecked())
      {
        slotSleepAfterPlay();// Shut screen off
        return;
      }
      if (m_quitAfterPlay->isChecked())
      {
        slotQuitAfterPlay();
        return;
      }
    }
  }
}

void Kaffeine::slotPlaylistPrevious()
{
  if (!m_playlist->getPrevious().isEmpty())
    slotPlaylistPlay();
}

void Kaffeine::slotPlayRecent(const KURL& kurl)
{
  slotPlay(MRL(kurl));
}

void Kaffeine::slotRepeat()
{
  m_playlist->setEndless(m_repeat->isChecked());
}

void Kaffeine::slotShuffle()
{
  m_playlist->setRandom(m_shuffle->isChecked());
}

void Kaffeine::slotMetaFromPlayer()
{
  m_playlist->mergeMeta(m_mediaPart->mrl());
}

/*
void Kaffeine::dragEnterEvent(QDragEnterEvent *dev)
{
   kdDebug() << "Kaffeine: drag enter even" << endl;
   dev->accept(QUriDrag::canDecode(dev) || QTextDrag::canDecode(dev));
}

void Kaffeine::dropEvent(QDropEvent* dev)
{
  QStringList urls;

  if (QUriDrag::decodeToUnicodeUris(dev, urls))
  {
    kdDebug() << "Kaffeine: " << urls.count() << " urls dropped..." << endl;
    load(urls);
  }
  else
  if (strcmp(dev->format(), "text/x-moz-url") == 0)    // for mozilla drops
  {
    QByteArray data = dev->encodedData("text/plain");
    QString md(data);
    load(md);
  }
}
*/

void Kaffeine::setupActions()
{
   /* file menu */
    KStdAction::open(this, SLOT(slotOpenFile()), actionCollection(), "file_open");
    new KAction(i18n("Open &URL"), "www", CTRL|Key_U, this, SLOT(slotOpenURL()), actionCollection(), "file_open_url");
     new KAction(i18n("Open D&irectory"), "folder_video", 0, this, SLOT(slotOpenDirectory()), actionCollection(), "file_open_directory");
    m_recent = KStdAction::openRecent(this, SLOT(slotPlayRecent(const KURL&)), actionCollection(), "file_open_recent");
    new KAction(i18n("Open &DVD"), "dvd_unmount", 0, this, SLOT(slotOpenDVD()), actionCollection(), "file_open_dvd");
    new KAction(i18n("Open &VCD"), "cdrom_unmount", 0, this, SLOT(slotOpenVCD()), actionCollection(), "file_open_vcd");
    new KAction(i18n("Open &Audio-CD"), "cdaudio_unmount", 0, this, SLOT(slotOpenAudioCD()), actionCollection(), "file_open_audiocd");
    m_sleepAfterPlay = new KToggleAction(i18n("Quit And Shutoff Monitor After This Track"), 0, 0, this, SLOT(slotSleepAfterPlayMenu()), actionCollection(), "sleep_after_play");
     m_quitAfterPlay = new KToggleAction(i18n("Quit After This Track"), 0, 0, this, SLOT(slotQuitAfterPlayMenu()), actionCollection(), "quit_after_play");
    KStdAction::quit(this, SLOT(slotQuit()), actionCollection());

    /* playlist menu */
    //new KAction(i18n("&Play Playlist"), "player_play", 0, this, SLOT(slotPlaylistPlay()), actionCollection(), "playlist_play");
    new KAction(i18n("&Next In Playlist/Queue"), "next", ALT|Key_Down, this, SLOT(slotPlaylistNext()), actionCollection(), "playlist_next");
    new KAction(i18n("Pre&vious In Playlist"), "previous", ALT|Key_Up, this, SLOT(slotPlaylistPrevious()), actionCollection(), "playlist_previous");
    m_repeat = new KToggleAction(i18n("&Repeat"), 0 , CTRL|Key_E, this, SLOT(slotRepeat()), actionCollection(),"playlist_repeat");
    m_repeat->setStatusText(i18n("Loop playlist"));
    m_shuffle = new KToggleAction(i18n("Sh&uffle"), 0 , CTRL|Key_R, this, SLOT(slotShuffle()), actionCollection(),"playlist_shuffle");
    m_shuffle->setStatusText(i18n("Play items in random order"));
    new KAction(i18n("Ne&w Playlist"), "filenew", 0, this, SLOT(slotPlaylistNew()), actionCollection(), "playlist_new");
    new KAction(i18n("&Import Playlist"), "project_open", 0, this, SLOT(slotPlaylistLoad()), actionCollection(), "playlist_load");
    new KAction(i18n("&Save Current Playlist As..."), "filesaveas", 0, this, SLOT(slotPlaylistSaveAs()), actionCollection(), "playlist_save_as");
    new KAction(i18n("Re&move Current Playlist"), "fileclose", 0, this, SLOT(slotPlaylistRemove()), actionCollection(), "playlist_remove");

    /*view menu */
    m_fullscreen = KStdAction::fullScreen(this, SLOT(slotToggleFullscreen()), actionCollection(), this, "view_fullscreen");
    m_minimal = new KToggleAction(i18n("&Minimal Mode"), 0, Key_M, this, SLOT(slotToggleMinimalMode()), actionCollection(), "view_minimal");
    new KAction(i18n("Toggle &Playlist/Player"), 0, Key_P, this, SLOT(slotToggleTab()), actionCollection(), "view_toggle_tab");
    m_originalAspect = new KToggleAction(i18n("Preserve &Original Aspect"), 0, 0, this, SLOT(slotOriginalAspect()), actionCollection(), "view_original_aspect");
    m_autoResizeOff = new KToggleAction(i18n("Off"), 0, ALT|Key_0, this, SLOT(slotAutoresizeOff()), actionCollection(), "view_auto_resize_off");
    m_autoResizeOriginal = new KToggleAction(i18n("Original Size"), 0, ALT|Key_1, this, SLOT(slotAutoresizeOriginal()), actionCollection(), "view_auto_resize_original");
    m_autoResizeDouble = new KToggleAction(i18n("Double Size"), 0, ALT|Key_2, this, SLOT(slotAutoresizeDouble()), actionCollection(), "view_auto_resize_double");
    m_autoResizeTriple = new KToggleAction(i18n("Triple Size"), 0, ALT|Key_3, this, SLOT(slotAutoresizeTriple()), actionCollection(), "view_auto_resize_triple");

#ifdef HAVE_LINUX_DVB_FRONTEND_H
    if ( dvbPanel ) {
    /*DVB menu*/
    new KAction(i18n("Next channel"), "next", Key_PageDown, dvbPanel, SLOT(next()), actionCollection(), "dvb_next");
    new KAction(i18n("Previous channel"), "previous", Key_PageUp, dvbPanel, SLOT(previous()), actionCollection(), "dvb_previous");
    new KAction(i18n("Instant record"), "filesave", 0, dvbPanel, SLOT(setRecord()), actionCollection(), "dvb_instant_record");
    new KAction(i18n("Show OSD"), "info", Key_O, dvbPanel, SLOT(dvbOSD()), actionCollection(), "dvb_show_osd");
    new KAction(i18n("EPG ..."), "view_text", Key_G, dvbPanel, SLOT(showEvents()), actionCollection(), "dvb_show_epg");
    new KAction(i18n("Timers ..."), "date", Key_T, dvbPanel, SLOT(showTimers()), actionCollection(), "dvb_show_timers");
    new KAction(i18n("Channels ..."), "kdvbtv", Key_C, dvbPanel, SLOT(scanner()), actionCollection(), "dvb_channels");
    new KAction(i18n("Configure DVB ..."), "configure", CTRL|Key_C, dvbPanel, SLOT(showConfigDialog()), actionCollection(), "dvb_config");
    }
#endif

    m_playersMenu = new KActionMenu(i18n("&Player Engine"), actionCollection(), "options_player");
    KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
    KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
    KStdAction::preferences(this, SLOT(slotPreferences()), actionCollection(), "options_preferences");

    /* fill players action menu */
    QSignalMapper* mapper = new QSignalMapper(this);
    connect(mapper, SIGNAL(mapped(const QString&)), this, SLOT(slotLoadPart(const QString&)));
    KAction* action = NULL;
    QStringList mediaParts;

    // check for kmediaparts
    KTrader::OfferList offers = KTrader::self()->query("audio/x-mp3", "'KMediaPart' in ServiceTypes");
    for(KTrader::OfferList::Iterator it = offers.begin(); it != offers.end(); ++it)
    {
      KService::Ptr ptr = (*it);

      action = new KAction(ptr->name(), ptr->icon(), 0, mapper, SLOT(map()), actionCollection());
      if (!ptr->comment().isNull())
        action->setToolTip(ptr->comment());
      mapper->setMapping(action, ptr->desktopEntryName());
      m_playersMenu->insert(action);
      mediaParts.append(ptr->name());
    }

    m_playersMenu->popupMenu()->insertSeparator();

    // check for readonlyparts
    offers = KTrader::self()->query("audio/x-mp3", "'KParts/ReadOnlyPart' in ServiceTypes");
    for(KTrader::OfferList::Iterator it = offers.begin(); it != offers.end(); ++it)
    {
      KService::Ptr ptr = (*it);

      if (mediaParts.contains(ptr->name()))
        continue;

      action = new KAction(ptr->name(), ptr->icon(), 0, mapper, SLOT(map()), actionCollection());
      if (!ptr->comment().isNull())
        action->setToolTip(ptr->comment());
      mapper->setMapping(action, ptr->desktopEntryName());
      m_playersMenu->insert(action);
    }
}

void Kaffeine::loadConfig()
{
  KConfig* config = kapp->config();

  config->setGroup("General Options");
  bool b;
  b = config->readBoolEntry("Endless Mode", false);
  m_repeat->setChecked(b);
  m_playlist->setEndless(b);

  b = config->readBoolEntry("Random Mode", false);
  m_shuffle->setChecked(b);
  m_playlist->setRandom(b);

  m_screensaverTimeout = config->readNumEntry("Screensaver Timeout", 2);

  m_autoResizeFactor = config->readNumEntry("Autoresize Factor", 0);
  switch (m_autoResizeFactor)
  {
    case 0: m_autoResizeOff->setChecked(true); break;
    case 1: m_autoResizeOriginal->setChecked(true); break;
    case 2: m_autoResizeDouble->setChecked(true); break;
    case 3: m_autoResizeTriple->setChecked(true); break;
  }

  b = config->readBoolEntry("Original Aspect", false);
  m_originalAspect->setChecked(b);

  m_embedSystemTray = config->readBoolEntry("Embed in System Tray", true);
  if (m_embedSystemTray)
    slotSystemTray(m_embedSystemTray);
  m_osdDuration = config->readNumEntry("OSD Duration", 5);

  m_useAlternateEncoding = config->readBoolEntry("Use Alternate Encoding", false);
  slotUseAlternateEncoding(m_useAlternateEncoding);

  m_alternateEncoding = config->readEntry("Alternate Encoding Name", "ISO 8859-1");
  slotAlternateEncoding(m_alternateEncoding);

  m_pauseVideo = config->readBoolEntry("PauseHiddenVideo", true);

  QSize plSize(200,200);
  bool docked = config->readBoolEntry("Playlist Docked", true);
  plSize = config->readSizeEntry("Playlist Size", &plSize);
  if (!docked)
  {
    m_playlist->slotUndockClicked();
    m_playlist->resize(plSize);
  }

  bool goTab = config->readBoolEntry("Show Go Tab", true);
  if (goTab)
    slotShowGoTab(true);

  config->setGroup("Player Part");
  QString partName = config->readEntry("Last Service Desktop Name", DEFAULT_PLAYER_PART);
  slotLoadPart(partName);

  m_recent->loadEntries(config, "Recent Files");

  m_playlist->loadConfig(config);

  applyMainWindowSettings(config, "Main Window");
}

void Kaffeine::saveConfig()
{
  KConfig* config = kapp->config();

  if (!m_fullscreen->isChecked())
  {
    if (m_minimal->isChecked())
      menuBar()->show();
    saveMainWindowSettings(config, "Main Window");
  }

  config->setGroup("General Options");
  config->writeEntry("Endless Mode", m_repeat->isChecked());
  config->writeEntry("Random Mode", m_shuffle->isChecked());
  config->writeEntry("Screensaver Timeout", m_screensaverTimeout);
  config->writeEntry("Autoresize Factor", m_autoResizeFactor);
  config->writeEntry("Original Aspect", m_originalAspect->isChecked());
  config->writeEntry("Embed in System Tray", m_embedSystemTray);
  config->writeEntry("OSD Duration", m_osdDuration);
  config->writeEntry("Use Alternate Encoding", m_useAlternateEncoding);
  config->writeEntry("Alternate Encoding Name", m_alternateEncoding);
  config->writeEntry("Playlist Docked", (m_playlist->parentWidget() != NULL));
  config->writeEntry("Playlist Size", m_playlist->size());
  config->writeEntry("Show Go Tab", (m_startWindow != NULL));
  config->writeEntry("PauseHiddenVideo", m_pauseVideo);

  config->setGroup("Player Part");
  config->writeEntry("Last Service Desktop Name", m_currentPartService);

  m_recent->saveEntries(config, "Recent Files");

  m_playlist->saveConfig(config);
}

void Kaffeine::slotShowGoTab(bool show)
{
  if (show)
  {
    if (!m_startWindow)
    {
      m_startWindow = new StartWindow(m_tabWidget);
      connect(m_startWindow, SIGNAL(signalPlaylistPlay()), this, SLOT(slotPlaylistPlay()));
      connect(m_startWindow, SIGNAL(signalOpenFile()), this, SLOT(slotOpenFile()));
      connect(m_startWindow, SIGNAL(signalOpenURL()), this, SLOT(slotOpenURL()));
      connect(m_startWindow, SIGNAL(signalOpenDirectory()), this, SLOT(slotOpenDirectory()));
      connect(m_startWindow, SIGNAL(signalOpenDVD()), this, SLOT(slotOpenDVD()));
      connect(m_startWindow, SIGNAL(signalOpenVCD()), this, SLOT(slotOpenVCD()));
      connect(m_startWindow, SIGNAL(signalOpenAudioCD()), this, SLOT(slotOpenAudioCD()));
      m_tabWidget->addTab(m_startWindow, i18n("Go!"));
      if (!m_minimal->isChecked())
        m_tabWidget->showTabBar();
    }
  }
  else
  {
    if (m_startWindow)
    {
      m_tabWidget->removePage(m_startWindow);
      delete m_startWindow;
      m_startWindow = NULL;
      if (m_tabWidget->count() < 2)
        m_tabWidget->hideTabBar();
    }
  }
}

void Kaffeine::showEvent(QShowEvent*)
{
  slotSetScreensaverTimeout(m_screensaverTimeout);
  if (m_mediaPart)
  {
    // restart playback if stream contains video
    if ( (m_mediaPart->isPlaying()) && (m_mediaPart->hasVideo()) && (m_mediaPart->isPaused()) && (m_autoPaused) )
      m_mediaPart->slotTogglePause();
  }
  m_autoPaused = false;
}

void Kaffeine::hideEvent (QHideEvent*)
{
  int ssTimeout = m_screensaverTimeout;
  slotSetScreensaverTimeout(0);
  m_screensaverTimeout = ssTimeout;

  if (m_mediaPart && m_pauseVideo)
  {
    // pause playback if stream contains video
    if ( (m_mediaPart->isPlaying()) && (m_mediaPart->hasVideo())
         && (!m_mediaPart->isPaused()) && (m_tabWidget->currentPage() == m_playerContainer) )
    {
      m_mediaPart->slotTogglePause();
      m_autoPaused = true;
    }
  }
}

void Kaffeine::slotPreferences()
{
  KaffeinePreferences dlg;
  dlg.setConfig(m_pauseVideo, m_screensaverTimeout, m_embedSystemTray, m_osdDuration, (m_startWindow != NULL), m_useAlternateEncoding, m_alternateEncoding);
  connect(&dlg, SIGNAL(signalClearRecent()), this, SLOT(slotClearRecent()));
  connect(&dlg, SIGNAL(signalTimeoutInterval(int)), this, SLOT(slotSetScreensaverTimeout(int)));
  connect(&dlg, SIGNAL(signalEmbedSystemTray(bool)), this, SLOT(slotSystemTray(bool)));
  connect(&dlg, SIGNAL(signalUseAlternateEncoding(bool)), this, SLOT(slotUseAlternateEncoding(bool)));
  connect(&dlg, SIGNAL(signalAlternateEncoding(const QString&)), this, SLOT(slotAlternateEncoding(const QString&)));
  connect(&dlg, SIGNAL(signalShowGoTab(bool)), this, SLOT(slotShowGoTab(bool)));
  connect(&dlg, SIGNAL(signalSetOSDTimeout(uint)), this, SLOT(slotSetOSDTimeout(uint)));
  connect(&dlg, SIGNAL(signalPauseVideo(bool)), this, SLOT(slotPauseVideo(bool)));
  dlg.exec();
}

void Kaffeine::slotPauseVideo(bool b)
{
  m_pauseVideo = b;
}

void Kaffeine::slotSetOSDTimeout(uint secs)
{
  m_osdDuration = secs;
}

void Kaffeine::optionsConfigureKeys()
{
    //KKeyDialog::configure(actionCollection(), this);
  KKeyDialog* keyDialog = new KKeyDialog(true,  0);
  if (m_mediaPart)
    keyDialog->insert(m_mediaPart->actionCollection(), i18n("Player"));
  if (m_simplePart)
    keyDialog->insert(m_simplePart->actionCollection(), i18n("Player"));
  keyDialog->insert(actionCollection(), i18n("Main Window"));

  keyDialog->configure(true);

  delete keyDialog;
}

void Kaffeine::optionsConfigureToolbars()
{
  saveMainWindowSettings(KGlobal::config(), autoSaveGroup());

  // use the standard toolbar editor
  KEditToolbar dlg(factory());
  connect(&dlg, SIGNAL(newToolbarConfig()),
          this, SLOT(applyNewToolbarConfig()));
  dlg.exec();
}

void Kaffeine::applyNewToolbarConfig()
{
  applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
}

void Kaffeine::slotSystemTray(bool embed)
{
  m_embedSystemTray = embed;
  if (embed)
  {
    if (!m_systemTray)
    {
      m_systemTray = new SystemTray(this);
      connect(m_systemTray, SIGNAL(signalPlay()), this, SLOT(slotPlaylistPlay()));
      connect(m_systemTray, SIGNAL(signalNext()), this, SLOT(slotPlaylistNext()));
      connect(m_systemTray, SIGNAL(signalPrevious()), this, SLOT(slotPlaylistPrevious()));
      connect(m_systemTray, SIGNAL(signalStop()), this, SLOT(slotStop()));
      connect(m_systemTray, SIGNAL(signalMute()), this, SLOT(slotMute()));
      connect(m_systemTray, SIGNAL(quitSelected()), this, SLOT(slotQuit()));
      m_systemTray->show();
    }
  }
  else
  {
    if (m_systemTray)
    {
      delete m_systemTray;
      m_systemTray = NULL;
    }
  }
}

void Kaffeine::slotSleepAfterPlayMenu()
{
    m_quitAfterPlay->setChecked(false); //Keep from checking both quits

  #ifdef HAVE_XTEST
    Display *dspl = qt_xdisplay();
    int base;
    bool hasDPMS = DPMSQueryExtension(dspl, &base, &base);
    if (!hasDPMS) // Check Xserver for DPMS
    {
      KMessageBox::error(this, i18n("DPMS Xserver extension was not found."));
      m_sleepAfterPlay->setChecked(false);
    }
    else
    {
      if (m_sleepAfterPlay->isChecked())
      {
            KMessageBox::information(this, i18n("This will quit Kaffeine and shut off the monitor's power after the file/playlist has finished. Option \"dpms\" must be in  your X config file for the monitor to power off."), QString::null, "sleep_info", 1);
      }
    }
#else
      /* nothing to do */
#endif
}

void Kaffeine::slotSleepAfterPlay()
{
  #ifdef HAVE_XTEST
    Display *dspl = qt_xdisplay();
    DPMSGetTimeouts(dspl, &standby, &suspend, &off);
    stb_no = standby;
    sus_no = suspend;
    off_no = off;
    DPMSEnable(dspl);
    DPMSSetTimeouts(dspl, 0, 1, 2); // Arbitrarily chosen times
    XFlush(dspl);
    sleep(3); // Wait for DPMS to kill screen
    DPMSSetTimeouts(dspl, stb_no, sus_no, off_no); // For reseting DPMS and toggle
    XFlush(dspl);
#else
    /* nothing to do */
#endif
    if (m_systemTray)
    {
      hide();
      m_sleepAfterPlay->setChecked(false);
    }
    else
      slotQuit();
}

void Kaffeine::slotQuitAfterPlayMenu()
{
      m_sleepAfterPlay->setChecked(false); //Keep from checking both quits
}

void Kaffeine::slotQuitAfterPlay()
{
  if (m_systemTray)
  {
    hide();
    m_quitAfterPlay->setChecked(false);

  }
  else
    slotQuit();
}

void Kaffeine::slotOpenFile()
{
  QStringList urlList;

  QString fileFilter = m_filter;
  fileFilter.prepend(" *.m3u *.pls *.kaffeine *.M3U *.PLS *.KAFFEINE");
  if (m_mediaPart)
  {
    QString extensions = m_mediaPart->supportedExtensions();
    if (extensions.isNull())
      extensions = DEFAULT_FILTER;
    fileFilter.prepend(extensions);
  }
  else
    fileFilter.prepend(DEFAULT_FILTER);

  urlList = KFileDialog::getOpenFileNames(":kaffeine_openFile", fileFilter, 0, i18n("Open File(s)"));
  if (!urlList.count()) return;
  load(urlList);
}

void Kaffeine::slotToggleTab()
{
  //kdDebug() << "Kaffeine: toggle player/playlist" << endl;
  if (!m_playerContainer)
    return;

  if (m_playlist->parentWidget()) // docked
  {
    if (m_tabWidget->currentPage() == m_playerContainer)
    {
      m_tabWidget->showPage(m_playlist);
    }
    else
    {
      if ((m_mediaPart) || (m_simplePart))
      {
        m_tabWidget->showPage(m_playerContainer);
        if (m_fullscreen->isChecked())
        {
          QFrame* tabFrame = dynamic_cast<QFrame*>(m_playerContainer->parentWidget());
          if (tabFrame)
          {
            tabFrame->setFrameShape(QFrame::NoFrame);
            tabFrame->setLineWidth(0);
          }
        }
      }
    }
  }
  else
  {
    m_playlist->show();
    KWin::activateWindow(m_playlist->winId());
  }
}

void Kaffeine::slotSwitchToPlayerWindow()
{
  if ((!m_playerContainer) || (m_tabWidget->currentPage() == m_playerContainer))
    return;

  if (m_mediaPart)
  {
    if (m_mediaPart->isPlaying()) // only if playback
      slotToggleTab();
  }
  else
    slotToggleTab();
}

void Kaffeine::slotTogglePlaylistDockState()
{
  if (m_playlist->parentWidget()) // docked
  {
    QPoint p = mapToGlobal(QPoint(width(), 0));
    m_tabWidget->removePage(m_playlist);
    m_playlist->reparent(0, p, true);
    m_playlist->setCaption(i18n("Kaffeine") + " " + i18n("Playlist"));
    m_playlist->setIcon(KGlobal::iconLoader()->loadIcon("kaffeine", KIcon::Small));
    m_tabWidget->showPage(m_playerContainer);
    if (m_tabWidget->count() < 2)
      m_tabWidget->hideTabBar();
  }
  else
  {
    int index = m_tabWidget->indexOf(m_playerContainer) + 1;
    m_tabWidget->insertTab(m_playlist, i18n("Playlist"), index);
    if (!m_minimal->isChecked())
    {
      m_tabWidget->showPage(m_playlist);
      m_tabWidget->showTabBar();
    }
  }
}

void Kaffeine::slotCurrentTabChanged(QWidget*)
{

}

void Kaffeine::slotToggleMinimalMode()
{
  if (m_fullscreen->isChecked())
    return;

  if (m_minimal->isChecked())
  {
    kdDebug() << "Kaffeine: Go to minimal mode..." << endl;
    menuBar()->hide();
    m_statusBarVisible = statusBar()->isVisible();
    statusBar()->hide();
    m_tabWidget->hideTabBar();
    hideToolbars(true);
  }
  else
  {
    menuBar()->show();
    if (m_statusBarVisible)
      statusBar()->show();
    if (m_tabWidget->count() > 1)
      m_tabWidget->showTabBar();
    hideToolbars(false);
  }
}

void Kaffeine::slotToggleFullscreen()
{
  if (m_fullscreen->isChecked())
  {
    kdDebug() << "Kaffeine: Go to fullscreen mode..." << endl;
    if (m_mediaPart)
      m_mediaPart->slotPrepareForFullscreen(true);
    menuBar()->hide();
    if (!m_minimal->isChecked())
      m_statusBarVisible = statusBar()->isVisible();
    statusBar()->hide();
    m_tabWidget->hideTabBar();
    hideToolbars(true);

    /*
     * uuuh, ugly :-)
     * make sure there is no frame border around the player window
     */
    QFrame* tabFrame = dynamic_cast<QFrame*>(m_playerContainer->parentWidget());
    if (tabFrame)
    {
      tabFrame->setFrameShape(QFrame::NoFrame);
      tabFrame->setLineWidth(0);
    }

    if (m_haveKWin)
      KWin::setState(winId(), NET::FullScreen | NET::StaysOnTop);
     else
      showFullScreen();
  }
  else
  {
    kdDebug() << "Kaffeine: Leave fullscreen mode..." << endl;
    if (m_mediaPart)
      m_mediaPart->slotPrepareForFullscreen(false);
    if (!m_minimal->isChecked())
    {
      menuBar()->show();
      if (m_statusBarVisible)
        statusBar()->show();
      if (m_tabWidget->count() > 1)
        m_tabWidget->showTabBar();
      hideToolbars(false);
    }

    // restore frame style
    QFrame* tabFrame = dynamic_cast<QFrame*>(m_playerContainer->parentWidget());
    if (tabFrame)
    {
      tabFrame->setFrameStyle(QFrame::TabWidgetPanel | QFrame::Raised);
    }

    if (m_haveKWin)
      KWin::clearState(winId(), NET::FullScreen | NET::StaysOnTop);
     else
      showNormal();
  }
}

void Kaffeine::slotEscapeFullscreen()
{
  if (m_fullscreen->isChecked())
  {
    m_fullscreen->setChecked(false);
    slotToggleFullscreen();
  }
  else if (m_minimal->isChecked())
  {
    m_minimal->setChecked(false);
    slotToggleMinimalMode();
  }
}

void Kaffeine::hideToolbars(bool hide)
{
  if (hide)
  {
    leftDock()->hide();
    rightDock()->hide();
    topDock()->hide();
    bottomDock()->hide();
  }
  else
  {
    leftDock()->show();
    rightDock()->show();
    topDock()->show();
    bottomDock()->show();
  }
}

void Kaffeine::mouseDoubleClickEvent(QMouseEvent*)
{
 // kdDebug() << "Kaffeine: doubleclick" << endl;
  if (m_tabWidget->currentPage() == m_playerContainer)
  {
    fullscreen();
  }
}

void Kaffeine::mousePressEvent(QMouseEvent* mev)
{
  kdDebug() << "Kaffeine: Mouse press event" << endl;
  if ((m_fullscreen->isChecked()) && (mev->button() == MidButton))
  {
    if (topDock()->isVisible())
    {
      hideToolbars(true);
      //menuBar()->hide;
      m_tabWidget->hideTabBar();
    }
    else
    {
      if (!m_minimal->isChecked())
      {
        hideToolbars(false);
        //menuBar()->show();
        if (m_tabWidget->count() > 1)
          m_tabWidget->showTabBar();
      }
    }
  }
  mev->ignore();
}

void Kaffeine::mouseMoveEvent(QMouseEvent* mev)
{
  //kdDebug() << "Kaffeine: Mouse move event" << endl;
  mev->ignore();
}

void Kaffeine::resizeEvent(QResizeEvent* rev)
{
  /* FIXME: don't really work proper... */
  KMainWindow::resizeEvent(rev);
  if ((!m_noResize) && (!m_fullscreen->isChecked()) && (m_originalAspect->isChecked())
       && (m_videoSize.height() != 0) && (m_videoSize.width() != 0))
  {
    QSize player = m_tabWidget->currentPage()->size(); // m_playerContainer->size() may not be valid
    double ratio = (double)m_videoSize.height() / (double)m_videoSize.width();
    int newHeight = (int)((double)player.width() * ratio);
    QSize newSize = size() - QSize(0, player.height() - newHeight);
    kdDebug() << "Kaffeine: resize to orignal aspect: old size: " << size().width() << "x" << size().height()
              << ", video size: " << m_videoSize.width() << "x" << m_videoSize.height()
              << ", video ratio: " << ratio
            << ", old height: " << player.height()
            << ", new height: " << newHeight
              << ", resize to: " << newSize.width() << "x" << newSize.height() << endl;
    m_noResize = true;
    resize(newSize);
  }
  else
    m_noResize = false;
}

void Kaffeine::slotOriginalAspect()
{
  if (m_originalAspect->isChecked())
    Kaffeine::resizeEvent(new QResizeEvent(QSize(), QSize()));
}

void Kaffeine::autoresize()
{
  if ((!m_fullscreen->isChecked()) && (m_autoResizeFactor)
       && (m_videoSize.height() != 0) && (m_videoSize.width() != 0))
  {
    QSize player, newSize;
    /*
     * we do the resize twice, because after the first resize toolbars area may be much heigher
     */
    for (uint i = 0; i < 2; i++)
    {
      player = m_tabWidget->currentPage()->size(); // m_playerContainer->size() may not be valid
      newSize = size() - QSize(player.width() - m_videoSize.width() * m_autoResizeFactor,
                               player.height() - m_videoSize.height() * m_autoResizeFactor);
      kdDebug() << "Kaffeine: autoresize: old size: " << size().width() << "x" << size().height()
                << ", video size: " << m_videoSize.width() << "x" << m_videoSize.height()
              << ", player size: " << player.width() << "x" << player.height()
              << ", resize to: " << newSize.width() << "x" << newSize.height() << endl;
      m_noResize = true;
      resize(newSize);
    }
  }
}

void Kaffeine::slotAutoresizeOff()
{
  m_autoResizeFactor = 0;
  m_autoResizeOriginal->setChecked(false);
  m_autoResizeDouble->setChecked(false);
  m_autoResizeTriple->setChecked(false);
}

void Kaffeine::slotAutoresizeOriginal()
{
  m_autoResizeFactor = 1;
  m_autoResizeOff->setChecked(false);
  m_autoResizeDouble->setChecked(false);
  m_autoResizeTriple->setChecked(false);
  autoresize();
}

void Kaffeine::slotAutoresizeDouble()
{
  m_autoResizeFactor = 2;
  m_autoResizeOriginal->setChecked(false);
  m_autoResizeOff->setChecked(false);
  m_autoResizeTriple->setChecked(false);
  autoresize();
}

void Kaffeine::slotAutoresizeTriple()
{
  m_autoResizeFactor = 3;
  m_autoResizeOriginal->setChecked(false);
  m_autoResizeDouble->setChecked(false);
  m_autoResizeOff->setChecked(false);
  autoresize();
}

void Kaffeine::slotNewFrameSize(const QSize& size)
{
  kdDebug() << "Kaffeine: new video frame size: " << size.width() << "x" << size.height() << endl;
  m_videoSize = size;
  autoresize();
}

void Kaffeine::slotOpenURL()
{
  bool ok;
  QString url = QInputDialog::getText(i18n("Open URL"), i18n("Enter a URL:"), QLineEdit::Normal, "", &ok);
  if ((ok) && (!url.isEmpty()))
  {
    if ((!(url.left(1) == "/")) && (!url.contains(":/")))
      url.prepend("http://"); // assume http protocol
    load(url);
  }
}

void Kaffeine::slotOpenDirectory()
{
  if (m_mediaPart)
  {
    QString extensions =  m_mediaPart->supportedExtensions();
    if (!extensions.isNull())
      m_playlist->setFileFilter(extensions);
  }

  KURL path = KDirSelectDialog::selectDirectory(":kaffeine_openDir", false, 0, i18n("Open Directory"));
  if (path.isValid())
    load(path.path());
}

QString Kaffeine::askForOtherDevice(const QString& type)
{
  KDialogBase* dialog = new KDialogBase( 0, "askfordrive", true, i18n("Error"), KDialogBase::Ok|KDialogBase::Cancel);
  QVBox* page = dialog->makeVBoxMainWidget();
  page->setSpacing(5);
  page->setMargin(5);
  new QLabel(i18n("No %1 in drive, or wrong path to device.").arg(type), page);
  new QLabel(QString("\n") + i18n("Please select correct drive:"), page);
  DrivesCombo* drives = new DrivesCombo(page);

  if (dialog->exec() == KDialogBase::Accepted)
  {
    QString newDrive = drives->currentText();
    delete dialog;
    return newDrive;
  }
  else
  {
    delete dialog;
    return QString::null;
  }
}

void Kaffeine::loadTMP(const QStringList& list)
{
  if (!list.count())
    return;

   m_playlist->setPlaylist(i18n("NEW"), true);
   m_playlist->add(list, NULL);
   if (!m_playlist->isQueueMode())
     slotPlaylistPlay();
}

void Kaffeine::slotOpenDVD()
{
  if (!m_mediaPart)
    return;

  MRL::List mrlList;
  bool ok = false;
  bool supported = false;
  QString device = m_device;
  do
  {
    m_mediaPart->dvdMRLS(mrlList, ok, supported, device);

    if (!supported)
    {
       KMessageBox::error(this, i18n("This player doesn't support %1 playback.").arg("DVD"));
       return;
    }

    if (ok)
    {
      m_playlist->setPlaylist("DVD", true);
      m_playlist->add(mrlList, NULL);
      if (!m_playlist->isQueueMode())
        slotPlaylistPlay();
    }
    else
    {
      device = askForOtherDevice("DVD");
      if (device.isNull())
        ok = true;
    }
  } while (!ok);
}

void Kaffeine::slotOpenVCD()
{
  if (!m_mediaPart)
    return;

  MRL::List mrlList;
  bool ok = false;
  bool supported = false;
  QString device = m_device;
  do
  {
    m_mediaPart->vcdMRLS(mrlList, ok, supported, device);

    if (!supported)
    {
       KMessageBox::error(this, i18n("This player doesn't support %1 playback.").arg("VCD"));
       return;
    }

    if (ok)
    {
      m_playlist->setPlaylist("VCD", true);
      m_playlist->add(mrlList, NULL);
      if (!m_playlist->isQueueMode())
        slotPlaylistPlay();
    }
    else
    {
      device = askForOtherDevice("VCD");
      if (device.isNull())
        ok = true;
    }
  } while (!ok);
}

void Kaffeine::slotOpenAudioCD()
{
  if (!m_mediaPart)
    return;

  MRL::List mrlList;
  bool ok = false;
  bool supported = false;
  QString device = m_device;
  do
  {
    m_mediaPart->audiocdMRLS(mrlList, ok, supported, device);

    if (!supported)
    {
       KMessageBox::error(this, i18n("This player doesn't support %1 playback.").arg("AudioCD"));
       return;
    }

    if (ok)
    {
      m_playlist->setPlaylist("AudioCD", true);
      m_playlist->add(mrlList, NULL);
      if (!m_playlist->isQueueMode())
        slotPlaylistPlay();
    }
    else
    {
      device = askForOtherDevice("AudioCD");
      if (device.isNull())
        ok = true;
    }
  } while (!ok);
}

void Kaffeine::slotPlaylistNew()
{
  m_playlist->slotNewList();
}

void Kaffeine::slotPlaylistLoad()
{
   QString path = KFileDialog::getOpenFileName(":kaffeine_openPlaylist", QString("*.kaffeine|") + i18n("Kaffeine Playlists") + "\n*.*|" + i18n("All Files"), 0, i18n("Open Playlist"));
   if (path.isEmpty() || (!path.contains(".kaffeine", false))) return;

   m_playlist->loadPlaylist(path);
}

void Kaffeine::slotPlaylistSaveAs()
{
  QString startPath = ":kaffeine_savePlaylist";
  //if (!lastPlaylist.isEmpty()) startPath = lastPlaylist;
  QString path = KFileDialog::getSaveFileName(startPath, QString("*.kaffeine|") + i18n("Kaffeine Playlists") + "\n*.*|" + i18n("All Files"), 0, i18n("Save Playlist"));
  if (path.isEmpty()) return;
  if ( path.right(9) != ".kaffeine" )
    path.append(".kaffeine");

  m_playlist->savePlaylist(path);
}

void Kaffeine::slotPlaylistRemove()
{
  m_playlist->removeCurrentPlaylist();
}

void Kaffeine::slotQuit()
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) if ( !dvbPanel->close() ) return;
#endif
  saveConfig();

  if (m_systemTray)
  {
    delete m_systemTray;
    m_systemTray = NULL;
  }

  KApplication::exit(0);
}

void Kaffeine::closeEvent(QCloseEvent* e)
{
  if (m_systemTray && !kapp->sessionSaving())
  {
    KMessageBox::information(this, i18n("Closing the main window will keep Kaffeine running in the system tray. Use Quit from the File menu to quit the application."), QString::null, "system_tray_info");
    hide();
    e->ignore();
  }
  else
  {
    slotQuit();
    if (kapp->sessionSaving())
      e->accept();
     else
      e->ignore(); 
  }
}

void Kaffeine::slotClearRecent()
{
  m_recent->clear();
  m_recent->setItems(QStringList());
}

void Kaffeine::slotChangeStatusbar(const QString& text)
{
  // display the text on the statusbar
  statusBar()->message(text, 5000); /* show for 5 seconds */
}

void Kaffeine::slotChangePlaylistStatus(const QString& text)
{
  statusBar()->changeItem(text, 9);
}

void Kaffeine::slotChangeCaption(const QString& text)
{
  // display the text on the caption
  setCaption(text);

  if ((m_systemTray) && (!m_fullscreen->isChecked()))
    m_systemTray->showTitle(text, m_osdDuration);
}

void Kaffeine::slotFakeKeyEvent()
{
#ifdef HAVE_XTEST
  kdDebug() << "Kaffeine: Fake keypress event" << endl;
  if (m_haveXTest)
  {
    XTestFakeKeyEvent(x11Display(), m_xTestKeycode, true, CurrentTime);
    XTestFakeKeyEvent(x11Display(), m_xTestKeycode, false, CurrentTime);
    XSync(x11Display(), false);
  }
#endif
}

void Kaffeine::slotSetScreensaverTimeout(int ssTimeout)
{
  m_screensaverTimeout = ssTimeout;

#ifdef HAVE_XTEST
  kdDebug() << "Kaffeine: Set screensaver timeout to: " << ssTimeout << " min" << endl;
  if (m_screensaverTimeout > 0)
    m_screensaverTimer.start(m_screensaverTimeout* 60000); //min
   else
    m_screensaverTimer.stop();
#endif
}

/** slots for meta to unicode encoding **/

01634 void Kaffeine::slotUseAlternateEncoding(bool useEncoding)
{
  m_useAlternateEncoding = useEncoding;
  m_playlist->useAlternateEncoding(useEncoding);
}

void Kaffeine::slotAlternateEncoding(const QString& encoding)
{
  m_alternateEncoding = encoding;
  m_playlist->setAlternateEncoding(encoding);
}

/** slots for system tray **/

01648 void Kaffeine::slotStop()
{
  stop();
}

void Kaffeine::slotMute()
{
  mute();
}

/********* DCOP INTERFACE *********/

void Kaffeine::openURL(QString url)
{
  loadTMP(QStringList(url));
}

void Kaffeine::appendURL(QString url)
{
  m_playlist->add(url, m_playlist->getLast());
}

void Kaffeine::play()
{
  slotPlaylistPlay();
}

void Kaffeine::playAudioCD()
{
  slotOpenAudioCD();
}

void Kaffeine::playVCD()
{
  slotOpenVCD();
}

void Kaffeine::playDVD()
{
  slotOpenDVD();
}

void Kaffeine::pause()
{
  if (m_mediaPart)
    m_mediaPart->slotTogglePause();
}

void Kaffeine::stop()
{
  if (m_mediaPart)
    m_mediaPart->slotStop();
}

void Kaffeine::next()
{
  if ((m_mediaPart) && (m_mediaPart->hasChapters()))
    m_mediaPart->playNextChapter();
   else
    slotPlaylistNext();
}

void Kaffeine::previous()
{
  if ((m_mediaPart) && (m_mediaPart->hasChapters()))
    m_mediaPart->playPreviousChapter();
   else
    slotPlaylistPrevious();
}

bool Kaffeine::isPlaying()
{
  if (m_mediaPart)
    return m_mediaPart->isPlaying();
   else
    return false;
}

QString Kaffeine::title()
{
  return m_playlist->getCurrent().title();
}

QString Kaffeine::getFileName()
{
  return m_playlist->getCurrent().url();
}

void Kaffeine::random()
{
  m_shuffle->setChecked(!m_shuffle->isChecked());
  slotShuffle();
}

void Kaffeine::fullscreen()
{
  m_fullscreen->setChecked(!m_fullscreen->isChecked());
  slotToggleFullscreen();
}

int Kaffeine::getLength()
{
  QTime length = m_playlist->getCurrent().length();
  return length.hour() * 3600 + length.minute() * 60 + length.second();
}

int Kaffeine::getTimePos()
{
  if (m_mediaPart)
    return m_mediaPart->position() * getLength() / 100;
   else
    return 0;
}

void Kaffeine::posPlus()
{
  if (m_mediaPart)
  {
    int newPos = m_mediaPart->position() + 2;
    if (newPos > 100) newPos = 100;
    m_mediaPart->slotSetPosition(newPos);
  }
}

void Kaffeine::posMinus()
{
  if (m_mediaPart)
  {
    int newPos = m_mediaPart->position() - 2;
    if (newPos < 0) newPos = 0;
    m_mediaPart->slotSetPosition(newPos);
  }
}

void Kaffeine::volUp()
{
  if (m_mediaPart)
  {
    int newVol = m_mediaPart->volume() + 5;
    if (newVol > 100) newVol = 100;
    m_mediaPart->slotSetVolume(newVol);
  }
}

void Kaffeine::volDown()
{
  if (m_mediaPart)
  {
    int newVol = m_mediaPart->volume() - 5;
    if (newVol < 0) newVol = 0;
    m_mediaPart->slotSetVolume(newVol);
  }
}

void Kaffeine::mute()
{
  if (m_mediaPart)
    m_mediaPart->slotMute();
}

void Kaffeine::quit()
{
  slotQuit();
}

void Kaffeine::dvbSetChannelNumber( int num )
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) dvbPanel->numKeyInput( num+10 );
#endif
}

void Kaffeine::dvbNext()
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) dvbPanel->next();
#endif
}

void Kaffeine::dvbPrevious()
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) dvbPanel->previous();
#endif
}

void Kaffeine::dvbOSD()
{
#ifdef HAVE_LINUX_DVB_FRONTEND_H
  if ( dvbPanel ) dvbPanel->dvbOSD();
#endif
}


/********/

TabWidget::TabWidget(QWidget* parent, const char* name) : KTabWidget(parent, name)
{
}

void TabWidget::showTabBar()
{
  tabBar()->show();
}

void TabWidget::hideTabBar()
{
  tabBar()->hide();
}

/**********/

PlayerContainer::PlayerContainer(QWidget* parent, const char* name) : QVBox(parent, name)
{
  setAcceptDrops(true);
}


void PlayerContainer::dragEnterEvent (QDragEnterEvent* dev)
{
  kdDebug() << "PlayerContainer: drag enter event" << endl;
  dev->accept(QUriDrag::canDecode(dev) || QTextDrag::canDecode(dev));
}

void PlayerContainer::dropEvent(QDropEvent* dev)
{
  QStringList urls,newurls;

  if (QUriDrag::decodeLocalFiles(dev, urls))
  {
    if (urls.count())
    {
      for (uint i=0; i < urls.count() ;i++)
      {
        KURL url(QUriDrag::unicodeUriToUri(urls[i]));
        newurls << url.path(-1);
        kdDebug() << "Kaffeine: Dropped " << url.path() << endl;
      }
      emit signalURLDropEvent(newurls);
    }
    else
    {
      QUriDrag::decodeToUnicodeUris(dev, urls);
      if (urls.count())
        emit signalURLDropEvent(urls);
    }
  }
  else
  if (strcmp(dev->format(), "text/x-moz-url") == 0)    // for mozilla drops
  {
    QByteArray data = dev->encodedData("text/plain");
    QString md(data);
    emit signalURLDropEvent(md);
  }
}




Generated by  Doxygen 1.6.0   Back to index