File indexing completed on 2024-04-14 15:00:55

0001 /***************************************************************************
0002                           kmplayerapp.cpp  -  description
0003                              -------------------
0004     begin                : Sat Dec  7 16:14:51 CET 2002
0005     copyright            : (C) 2002 by Koos Vriezen
0006     email                :
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #undef Always
0019 
0020 // include files for QT
0021 #include <qdatastream.h>
0022 #include <qregexp.h>
0023 #include <qicon.h>
0024 #include <qinputdialog.h>
0025 #include <qiodevice.h>
0026 #include <qprinter.h>
0027 #include <qcursor.h>
0028 #include <qpainter.h>
0029 #include <qcheckbox.h>
0030 #include <qpushbutton.h>
0031 #include <qkeysequence.h>
0032 #include <qapplication.h>
0033 #include <qslider.h>
0034 #include <qlayout.h>
0035 #include <qmenu.h>
0036 #include <qmimedata.h>
0037 #include <qwhatsthis.h>
0038 #include <qtimer.h>
0039 #include <qfile.h>
0040 #include <qmetaobject.h>
0041 #include <QDirIterator>
0042 #include <QDropEvent>
0043 #include <QLabel>
0044 #include <QDockWidget>
0045 #include <QStandardPaths>
0046 #include <QtX11Extras/QX11Info>
0047 
0048 // include files for KDE
0049 #include <kdeversion.h>
0050 #include <kiconloader.h>
0051 #include <kmessagebox.h>
0052 #include <kmenubar.h>
0053 #include <kstatusbar.h>
0054 #include <ktoolbar.h>
0055 #include <klocalizedstring.h>
0056 #include <kconfig.h>
0057 #include <ksharedconfig.h>
0058 #include <kstandardaction.h>
0059 #include <kactioncollection.h>
0060 #include <kdebug.h>
0061 #include <klineedit.h>
0062 #include <kshortcutsdialog.h>
0063 #include <ksystemtrayicon.h>
0064 #include <kedittoolbar.h>
0065 #include <krecentfilesaction.h>
0066 #include <ktoggleaction.h>
0067 
0068 // application specific includes
0069 #include "kmplayer_def.h"
0070 #include "kmplayerconfig.h"
0071 #include "kmplayer.h"
0072 #include "kmplayer_lists.h"
0073 #include "kmplayerview.h"
0074 #include "playmodel.h"
0075 #include "playlistview.h"
0076 #include "viewarea.h"
0077 #include "kmplayercontrolpanel.h"
0078 #include "kmplayerpartbase.h"
0079 #include "kmplayerprocess.h"
0080 #include "kmplayertvsource.h"
0081 //#include "kmplayerbroadcast.h"
0082 //#include "kmplayervdr.h"
0083 #include "kmplayerconfig.h"
0084 
0085 #include <kurlrequester.h>
0086 #include <QFileDialog>
0087 
0088 extern const char * strMPlayerGroup;
0089 
0090 
0091 KDE_NO_CDTOR_EXPORT KMPlayerApp::KMPlayerApp (QWidget *)
0092     : KXmlGuiWindow (NULL),
0093       m_systray (0L),
0094       m_player (new KMPlayer::PartBase (this, 0L, KSharedConfig::openConfig ())),
0095       m_view (static_cast <KMPlayer::View*> (m_player->view())),
0096       //m_ffserverconfig (new KMPlayerFFServerConfig),
0097       //m_broadcastconfig (new KMPlayerBroadcastConfig (m_player, m_ffserverconfig)),
0098       edit_tree_id (-1),
0099       last_time_left (0),
0100       m_played_intro (false),
0101       m_played_exit (false),
0102       m_minimal_mode (false)
0103 {
0104     setCentralWidget (m_view);
0105     //connect (m_broadcastconfig, SIGNAL (broadcastStarted()), this, SLOT (broadcastStarted()));
0106     //connect (m_broadcastconfig, SIGNAL (broadcastStopped()), this, SLOT (broadcastStopped()));
0107     initStatusBar();
0108     m_player->init (actionCollection (), "/KMPlayerPart", false);
0109     m_view->initDock (m_view->viewArea ());
0110     //m_player->mediaManager ()->processInfos () ["xvideo"] =
0111     //    new XvProcessInfo (m_player->mediaManager ());
0112     ListsSource * lstsrc = new ListsSource (m_player);
0113     m_player->sources () ["listssource"] = lstsrc;
0114     m_player->sources () ["dvdsource"] = new ::KMPlayerDVDSource(this);
0115     m_player->sources () ["vcdsource"] = new KMPlayerVCDSource(this);
0116     m_player->sources () ["audiocdsource"] = new KMPlayerAudioCDSource(this);
0117     m_player->sources () ["pipesource"] = new KMPlayerPipeSource (this);
0118     m_player->sources () ["tvsource"] = new KMPlayerTVSource(this);
0119     //m_player->sources () ["vdrsource"] = new KMPlayerVDRSource (this);
0120     m_player->setSource (m_player->sources () ["urlsource"]);
0121     initActions();
0122     initView();
0123 
0124     //setAutoSaveSettings();
0125     playlist = new Playlist (this, lstsrc);
0126     playlist_id = m_player->playModel()->addTree (playlist, "listssource", "view-media-playlist", KMPlayer::PlayModel::AllowDrag | KMPlayer::PlayModel::AllowDrops | KMPlayer::PlayModel::TreeEdit | KMPlayer::PlayModel::Moveable | KMPlayer::PlayModel::Deleteable);
0127     readOptions();
0128 }
0129 
0130 KDE_NO_CDTOR_EXPORT KMPlayerApp::~KMPlayerApp () {
0131     //delete m_broadcastconfig;
0132     if (recents)
0133         recents->document ()->dispose ();
0134     if (playlist)
0135         playlist->document ()->dispose ();
0136 
0137     if (current_generator && current_generator->active ()) {
0138         current_generator->deactivate ();
0139         current_generator = NULL;
0140     }
0141     while (generators.first ()) {
0142         generators.first ()->data->document ()->dispose ();
0143         generators.remove (generators.first ());
0144     }
0145 }
0146 
0147 
0148 KDE_NO_EXPORT void KMPlayerApp::initActions () {
0149     KActionCollection * ac = actionCollection ();
0150     fileNewWindow = ac->addAction ("new_window");
0151     fileNewWindow->setText( i18n( "New window" ) );
0152     //fileNewWindow->setIcon (QIcon::fromTheme("window-new"));
0153     connect (fileNewWindow, SIGNAL (triggered (bool)), this, SLOT (slotFileNewWindow ()));
0154     fileOpen = KStandardAction::open (this, SLOT (slotFileOpen()), ac);
0155     fileOpenRecent = KStandardAction::openRecent(this, SLOT(slotFileOpenRecent(const QUrl&)), ac);
0156     KStandardAction::saveAs (this, SLOT (slotSaveAs ()), ac);
0157     fileClose = KStandardAction::close (this, SLOT (slotFileClose ()), ac);
0158     fileQuit = KStandardAction::quit (this, SLOT (slotFileQuit ()), ac);
0159     viewEditMode = ac->addAction ("edit_mode");
0160     viewEditMode->setCheckable (true);
0161     viewEditMode->setText (i18n ("&Edit mode"));
0162     connect (viewEditMode, SIGNAL (triggered (bool)), this, SLOT (editMode ()));
0163     QAction *viewplaylist = ac->addAction ( "view_playlist");
0164     viewplaylist->setText (i18n ("Pla&y List"));
0165     //viewplaylist->setIcon (QIcon::fromTheme("media-playlist"));
0166     connect (viewplaylist, SIGNAL(triggered(bool)), m_player, SLOT(showPlayListWindow()));
0167     KStandardAction::preferences (m_player, SLOT (showConfigDialog ()), ac);
0168     QAction *playmedia = ac->addAction ("play");
0169     playmedia->setText (i18n ("P&lay"));
0170     connect (playmedia, SIGNAL (triggered (bool)), m_player, SLOT (play ()));
0171     QAction *pausemedia = ac->addAction ("pause");
0172     pausemedia->setText (i18n ("&Pause"));
0173     connect (pausemedia, SIGNAL (triggered (bool)), m_player, SLOT (pause ()));
0174     QAction *stopmedia = ac->addAction ("stop");
0175     stopmedia->setText (i18n ("&Stop"));
0176     connect (stopmedia, SIGNAL (triggered (bool)), m_player, SLOT (stop ()));
0177     KStandardAction::keyBindings (this, SLOT (slotConfigureKeys()), ac);
0178     //KStandardAction::configureToolbars (this, SLOT (slotConfigureToolbars ()), ac);
0179     viewFullscreen = ac->addAction ("view_fullscreen");
0180     viewFullscreen->setCheckable (true);
0181     viewFullscreen->setText (i18n("Fullscreen"));
0182     connect (viewFullscreen, SIGNAL (triggered (bool)), this, SLOT (fullScreen ()));
0183     toggleView = ac->addAction ("view_video");
0184     toggleView->setText (i18n ("C&onsole"));
0185     toggleView->setIcon (QIcon::fromTheme("utilities-terminal"));
0186     connect (toggleView, SIGNAL (triggered (bool)),
0187             m_player->view (), SLOT (toggleVideoConsoleWindow ()));
0188     viewSyncEditMode = ac->addAction ("sync_edit_mode");
0189     viewSyncEditMode->setText (i18n ("Reload"));
0190     viewSyncEditMode->setIcon (QIcon::fromTheme("view-refresh"));
0191     connect (viewSyncEditMode, SIGNAL (triggered (bool)), this, SLOT (syncEditMode ()));
0192     viewSyncEditMode->setEnabled (false);
0193     viewToolBar = KStandardAction::create (KStandardAction::ShowToolbar,
0194             this, SLOT (slotViewToolBar ()), ac);
0195     viewStatusBar = KStandardAction::create (KStandardAction::ShowStatusbar,
0196             this,SLOT (slotViewStatusBar ()),ac);
0197     viewMenuBar = KStandardAction::create (KStandardAction::ShowMenubar,
0198             this, SLOT (slotViewMenuBar ()), ac);
0199     QAction *act = ac->addAction ("clear_history");
0200     act->setText (i18n ("Clear &History"));
0201     connect (act, SIGNAL (triggered (bool)), this, SLOT (slotClearHistory ()));
0202 #if defined(KMPLAYER_WITH_NPP) && defined(KMPLAYER_WITH_CAIRO)
0203     act = ac->addAction ("generators");
0204     act->setText (i18n ("&Generators"));
0205     m_generatormenu = new QMenu (this);
0206     connect (m_generatormenu, SIGNAL (aboutToShow ()),
0207              this, SLOT (slotGeneratorMenu ()));
0208     act->setMenu (m_generatormenu);
0209 #endif
0210 
0211 
0212     /*fileNewWindow = new KAction(i18n("New &Window"), 0, 0, this, SLOT(slotFileNewWindow()), ac, "new_window");
0213     new KAction (i18n ("&Open DVD"), QString ("dvd_mount"), KShortcut (), this, SLOT(openDVD ()), ac, "opendvd");
0214     new KAction (i18n ("&Open VCD"), QString ("cdrom_mount"), KShortcut (), this, SLOT(openVCD ()), ac, "openvcd");
0215     new KAction (i18n ("&Open Audio CD"), QString ("cdrom_mount"), KShortcut (), this, SLOT(openAudioCD ()), ac, "openaudiocd");
0216     new KAction (i18n ("&Open Pipe..."), QString ("pipe"), KShortcut (), this, SLOT(openPipe ()), ac, "source_pipe");
0217     //KIconLoader::global ()->loadIconSet (QString ("video-television"), K3Icon::Small, 0,true)
0218     new KAction (i18n ("&Connect"), QString ("connect_established"), KShortcut (), this, SLOT (openVDR ()), ac, "vdr_connect");
0219     editVolumeInc = new KAction (i18n ("Increase Volume"), QString ("player_volume"), KShortcut (), m_player, SLOT (increaseVolume ()), ac, "edit_volume_up");
0220     editVolumeDec = new KAction (i18n ("Decrease Volume"), QString ("player_volume"), KShortcut (), m_player, SLOT(decreaseVolume ()), ac, "edit_volume_down");
0221     //new KAction (i18n ("V&ideo"), QString ("video"), KShortcut (), m_view, SLOT (toggleVideoConsoleWindow ()), ac, "view_video");
0222     new KAction (i18n ("Pla&y List"), QString ("player_playlist"), KShortcut (), m_player, SLOT (showPlayListWindow ()), ac, "view_playlist");
0223     new KAction (i18n ("Minimal mode"), QString ("empty"), KShortcut (), this, SLOT (slotMinimalMode ()), ac, "view_minimal");
0224     new KAction (i18n ("50%"), 0, 0, this, SLOT (zoom50 ()), ac, "view_zoom_50");
0225     new KAction (i18n ("100%"), QString ("viewmagfit"), KShortcut (), this, SLOT (zoom100 ()), ac, "view_zoom_100");
0226     new KAction (i18n ("150%"), 0, 0, this, SLOT (zoom150 ()), ac, "view_zoom_150");
0227     new KAction (i18n ("Show Popup Menu"), KShortcut (), m_view->controlPanel (), SLOT (showPopupMenu ()), ac, "view_show_popup_menu");
0228     new KAction (i18n ("Show Language Menu"), KShortcut (Qt::Key_L), m_view->controlPanel (), SLOT (showLanguageMenu ()), ac, "view_show_lang_menu");
0229     viewKeepRatio = new KToggleAction (i18n ("&Keep Width/Height Ratio"), 0, this, SLOT (keepSizeRatio ()), ac, "view_keep_ratio");
0230     fileNewWindow->setStatusText(i18n("Opens a new application window"));
0231     fileOpen->setStatusText(i18n("Opens an existing file"));
0232     fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
0233     fileClose->setStatusText(i18n("Closes the actual source"));
0234     fileQuit->setStatusText(i18n("Quits the application"));*/
0235     viewStatusBar->setStatusTip (i18n ("Enables/disables the status bar"));
0236     viewMenuBar->setStatusTip (i18n ("Enables/disables the menu bar"));
0237     viewToolBar->setStatusTip (i18n ("Enables/disables the toolbar"));
0238 }
0239 
0240 KDE_NO_EXPORT void KMPlayerApp::initStatusBar () {
0241     QStatusBar *sb = statusBar();
0242     playtime_info = new QLabel("--:--");
0243     sb->addPermanentWidget(playtime_info);
0244     sb->showMessage(i18n ("Ready."));
0245 }
0246 
0247 KDE_NO_EXPORT void KMPlayerApp::initMenu () {
0248     createGUI ("kmplayerui.rc"); // first build the one from the kmplayerui.rc
0249 
0250     //QAction *bookmark_action = actionCollection ()->addAction ("bookmarks");
0251     QList<QAction *> acts = menuBar()->actions();
0252     if (acts.size () > 2) {
0253         QMenu *bookmark_menu = new QMenu(this);
0254         QAction *bookmark_action = menuBar()->insertMenu (acts.at(2), bookmark_menu);
0255         bookmark_action->setText (i18n( "&Bookmarks"));
0256         m_player->createBookmarkMenu (bookmark_menu, actionCollection ());
0257     }
0258 
0259 }
0260 
0261 KDE_NO_EXPORT void KMPlayerApp::initView () {
0262     KSharedConfigPtr config = KSharedConfig::openConfig ();
0263     //m_view->docArea ()->readDockConfig (config.data (), QString ("Window Layout"));
0264     m_player->connectPanel (m_view->controlPanel ());
0265     initMenu ();
0266     //new KAction (i18n ("Increase Volume"), editVolumeInc->shortcut (), m_player, SLOT (increaseVolume ()), m_view->viewArea ()->actionCollection (), "edit_volume_up");
0267     //new KAction (i18n ("Decrease Volume"), editVolumeDec->shortcut (), m_player, SLOT(decreaseVolume ()), m_view->viewArea ()->actionCollection (), "edit_volume_down");
0268     connect (m_player->settings (), SIGNAL (configChanged ()),
0269              this, SLOT (configChanged ()));
0270     connect (m_player, SIGNAL (loading (int)),
0271              this, SLOT (loadingProgress (int)));
0272     connect (m_player, SIGNAL (positioned (int, int)),
0273              this, SLOT (positioned (int, int)));
0274     connect (m_player, SIGNAL (statusUpdated (const QString &)),
0275              this, SLOT (slotStatusMsg (const QString &)));
0276     connect (m_view, SIGNAL (windowVideoConsoleToggled (bool)),
0277              this, SLOT (windowVideoConsoleToggled (bool)));
0278     connect (m_player, SIGNAL (sourceChanged (KMPlayer::Source *, KMPlayer::Source *)), this, SLOT (slotSourceChanged(KMPlayer::Source *, KMPlayer::Source *)));
0279     /*m_view->controlPanel ()->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom50,
0280             this, SLOT (zoom50 ()));
0281     m_view->controlPanel ()->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom100,
0282             this, SLOT (zoom100 ()));
0283     m_view->controlPanel ()->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom150,
0284             this, SLOT (zoom150 ()));
0285     connect (m_view->controlPanel()->broadcastButton (), SIGNAL (clicked ()),
0286             this, SLOT (broadcastClicked ()));*/
0287     m_auto_resize = m_player->settings ()->autoresize;
0288     if (m_auto_resize)
0289         connect (m_player, SIGNAL (sourceDimensionChanged ()),
0290                  this, SLOT (zoom100 ()));
0291     connect (m_view, SIGNAL (fullScreenChanged ()),
0292             this, SLOT (fullScreen ()));
0293     connect (m_view->playList (), SIGNAL (activated (const QModelIndex&)),
0294             this, SLOT (playListItemActivated (const QModelIndex&)));
0295     connect (m_view->playList(), SIGNAL (dropped (QDropEvent*, KMPlayer::PlayItem*)),
0296             this, SLOT (playListItemDropped (QDropEvent *, KMPlayer::PlayItem *)));
0297     connect (m_view->playList(), SIGNAL (prepareMenu (KMPlayer::PlayItem *, QMenu *)), this, SLOT (preparePlaylistMenu (KMPlayer::PlayItem *, QMenu *)));
0298     m_dropmenu = new QMenu (m_view->playList ());
0299     dropAdd = m_dropmenu->addAction(QIcon::fromTheme("view-media-playlist"),
0300                 i18n ("&Add to list"), this, SLOT (menuDropInList ()));
0301     dropAddGroup = m_dropmenu->addAction(QIcon::fromTheme("folder-grey"),
0302         i18n ("Add in new &Group"), this, SLOT (menuDropInGroup ()));
0303     dropCopy = m_dropmenu->addAction(QIcon::fromTheme("edit-copy"),
0304             i18n ("&Copy here"), this, SLOT (menuCopyDrop ()));
0305     dropDelete = m_dropmenu->addAction(QIcon::fromTheme("edit-delete"),
0306             i18n ("&Delete"), this, SLOT (menuDeleteNode ()));
0307     /*QMenu * viewmenu = new QMenu;
0308     viewmenu->addAction(i18n ("Full Screen"), this, SLOT(fullScreen ()),
0309                           QKeySequence ("CTRL + Key_F"));
0310     menuBar ()->addAction(i18n ("&View"), viewmenu, -1, 2);*/
0311     //toolBar("mainToolBar")->hide();
0312     setAcceptDrops (true);
0313 }
0314 
0315 KDE_NO_EXPORT void KMPlayerApp::loadingProgress (int perc) {
0316     if (perc < 100)
0317         playtime_info->setText(QString ("%1%").arg (perc));
0318     else
0319         playtime_info->setText(QString ("--:--"));
0320 }
0321 
0322 KDE_NO_EXPORT void KMPlayerApp::positioned (int pos, int length) {
0323     int left = (length - pos) / 10;
0324     if (left != last_time_left) {
0325         last_time_left = left;
0326         QString text ("--:--");
0327         if (left > 0) {
0328             int h = left / 3600;
0329             int m = (left % 3600) / 60;
0330             int s = left % 60;
0331             if (h > 0)
0332                 text.sprintf ("%d:%02d:%02d", h, m, s);
0333             else
0334                 text.sprintf ("%02d:%02d", m, s);
0335         }
0336         playtime_info->setText(text);
0337     }
0338 }
0339 
0340 KDE_NO_EXPORT void KMPlayerApp::windowVideoConsoleToggled (bool show) {
0341     if (show) {
0342         toggleView->setText (i18n ("V&ideo"));
0343         toggleView->setIcon (QIcon::fromTheme("video-display"));
0344     } else {
0345         toggleView->setText (i18n ("C&onsole"));
0346         toggleView->setIcon (QIcon::fromTheme("utilities-terminal"));
0347     }
0348 }
0349 
0350 KDE_NO_EXPORT void KMPlayerApp::playerStarted () {
0351     KMPlayer::Source * source = m_player->source ();
0352     if (!strcmp (source->name (), "urlsource")) {
0353         KUrl url = source->url ();
0354         QString surl = url.url ();
0355         QString nurl = url.isLocalFile()
0356             ? url.toLocalFile()
0357             : QUrl::fromPercentEncoding (surl.toUtf8 ());
0358         if (url.isEmpty () || surl.startsWith ("lists"))
0359             return;
0360         //if (url.isEmpty () && m_player->process ()->mrl ())
0361         //    url = KUrl (m_player->process ()->mrl ()->mrl ()->src);
0362         recentFiles ()->addUrl (url);
0363         recents->defer (); // make sure it's loaded
0364         recents->insertBefore (new Recent (recents, this, nurl),
0365                                recents->firstChild ());
0366         KMPlayer::Node *c = recents->firstChild ()->nextSibling ();
0367         int count = 1;
0368         KMPlayer::Node *more = NULL;
0369         while (c) {
0370             if (c->id == id_node_recent_node &&
0371                     (c->mrl ()->src == surl || c->mrl ()->src == nurl)) {
0372                 KMPlayer::Node *tmp = c->nextSibling ();
0373                 recents->removeChild (c);
0374                 c = tmp;
0375             } else {
0376                 if (c->id == KMPlayer::id_node_group_node)
0377                     more = c;
0378                 c = c->nextSibling ();
0379                 count++;
0380             }
0381         }
0382         if (!more && count > 10) {
0383             more = new Group (recents, this, i18n ("More..."));
0384             recents->appendChild (more);
0385         }
0386         if (more) {
0387             if (count > 10) {
0388                 KMPlayer::NodePtr item = more->previousSibling ();
0389                 recents->removeChild (item);
0390                 more->insertBefore (item, more->firstChild ());
0391             }
0392             if (more->firstChild ())
0393                 c = more->firstChild ()->nextSibling ();
0394             count = 0;
0395             while (c) {
0396                 if (c->id == id_node_recent_node &&
0397                         (c->mrl ()->src == surl || c->mrl ()->src == nurl)) {
0398                     KMPlayer::Node *tmp = c->nextSibling ();
0399                     more->removeChild (c);
0400                     c = tmp;
0401                 } else {
0402                     c = c->nextSibling ();
0403                     count++;
0404                 }
0405             }
0406             if (count > 50)
0407                 more->removeChild (more->lastChild ());
0408         }
0409         m_player->playModel()->updateTree (recents_id, recents, 0, false, false);
0410     }
0411 }
0412 
0413 KDE_NO_EXPORT void KMPlayerApp::slotSourceChanged (KMPlayer::Source *olds, KMPlayer::Source * news) {
0414     if (olds) {
0415         disconnect (olds, SIGNAL (titleChanged (const QString &)), this,
0416                     SLOT (setCaption (const QString &)));
0417         disconnect (olds, SIGNAL (startPlaying ()),
0418                     this, SLOT (playerStarted ()));
0419     }
0420     if (news) {
0421         setCaption (news->prettyName (), false);
0422         connect (news, SIGNAL (titleChanged (const QString &)),
0423                  this, SLOT (setCaption (const QString &)));
0424         connect (news, SIGNAL (startPlaying ()),
0425                  this, SLOT (playerStarted ()));
0426         viewSyncEditMode->setEnabled (m_view->editMode () ||
0427                 !strcmp (m_player->source ()->name (), "urlsource"));
0428     }
0429 }
0430 
0431 KDE_NO_EXPORT void KMPlayerApp::openDVD () {
0432     slotStatusMsg(i18n("Opening DVD..."));
0433     m_player->setSource (m_player->sources () ["dvdsource"]);
0434 }
0435 
0436 KDE_NO_EXPORT void KMPlayerApp::openVCD () {
0437     slotStatusMsg(i18n("Opening VCD..."));
0438     m_player->setSource (m_player->sources () ["vcdsource"]);
0439 }
0440 
0441 KDE_NO_EXPORT void KMPlayerApp::openAudioCD () {
0442     slotStatusMsg(i18n("Opening Audio CD..."));
0443     m_player->setSource (m_player->sources () ["audiocdsource"]);
0444 }
0445 
0446 KDE_NO_EXPORT void KMPlayerApp::openPipe () {
0447     slotStatusMsg(i18n("Opening pipe..."));
0448     bool ok;
0449     QString cmd = QInputDialog::getText(m_player->view(), i18n("Read From Pipe"),
0450       i18n ("Enter a command that will output an audio/video stream\nto the stdout. This will be piped to a player's stdin.\n\nCommand:"), QLineEdit::Normal, m_player->sources() ["pipesource"]->pipeCmd(), &ok);
0451     if (!ok) {
0452         slotStatusMsg (i18n ("Ready."));
0453         return;
0454     }
0455     static_cast <KMPlayerPipeSource *> (m_player->sources () ["pipesource"])->setCommand (cmd);
0456     m_player->setSource (m_player->sources () ["pipesource"]);
0457 }
0458 
0459 KDE_NO_EXPORT void KMPlayerApp::openVDR () {
0460     /*slotStatusMsg(i18n("Opening VDR..."));
0461     if (!strcmp (m_player->source ()->name (), "vdrsource") && m_player->playing ())
0462         static_cast<KMPlayerVDRSource *>(m_player->source())->toggleConnected();
0463     else
0464         m_player->setSource (m_player->sources () ["vdrsource"]);*/
0465 }
0466 
0467 #ifdef KMPLAYER_WITH_CAIRO
0468 static const char *svg_bat =
0469     "<svg width='64' height='64'>"
0470     "<path style='fill:#000000;'"
0471     " d='M 32.120,14.655"
0472     " C 31.374,14.777 30.356,14.660 30.073,14.204"
0473     " C 29.358,12.759 29.294,12.087 28.475,10.922"
0474     " C 27.216,9.132 29.242,23.435 25.250,22.485"
0475     " C 22.700,22.632 22.131,22.902 20.038,22.518"
0476     " C 14.017,21.412 11.310,19.129 17.209,12.808"
0477     " C 0.858,20.547 -1.279,37.053 14.151,48.311"
0478     " C 8.665,41.481 16.731,35.528 20.131,44.676"
0479     " C 26.243,38.164 29.892,38.528 32.120,50.180"
0480     " C 34.405,38.488 38.054,38.124 44.167,44.635"
0481     " C 47.567,35.487 55.633,41.441 50.146,48.271"
0482     " C 65.577,37.013 63.439,20.507 47.089,12.768"
0483     " C 52.987,19.089 50.281,21.372 44.260,22.477"
0484     " C 42.166,22.862 41.597,22.592 39.047,22.445"
0485     " C 35.056,23.395 37.070,9.162 35.806,10.949"
0486     " C 34.970,12.130 35.321,12.669 34.242,14.147"
0487     " C 33.975,14.570 32.841,14.787 31.374,14.777 z'/>"
0488     "</svg>";
0489 
0490 static const char *svg_rat =
0491     "<svg width='64' height='64'>"
0492     "<path style='fill:#000000'"
0493     " d='M 37.966,10.702"
0494     " C 32.946,10.674 26.432,11.605 20.582,16.078"
0495     " C 19.781,16.691 20.028,14.288 19.307,14.084"
0496     " C 16.546,12.762 16.018,13.323 15.487,15.518"
0497     " C 15.440,15.712 14.021,15.893 13.561,15.455"
0498     " C 13.561,15.455 13.079,12.719 12.164,14.205"
0499     " C 11.787,14.818 11.688,13.574 10.500,15.472"
0500     " C 10.195,15.959 11.279,16.212 11.279,16.212"
0501     " C 11.279,16.212 7.825,19.421 7.869,20.140"
0502     " C 7.817,20.879 3.397,23.614 3.003,24.316"
0503     " C 2.285,25.598 5.593,27.321 9.036,26.688"
0504     " C 15.133,24.334 13.390,27.117 20.559,32.120"
0505     " C 20.559,32.120 20.490,33.826 20.491,34.474"
0506     " C 20.491,35.221 17.934,35.078 17.999,35.470"
0507     " C 18.077,35.949 17.590,35.794 17.702,36.316"
0508     " C 17.702,36.316 17.698,36.693 17.769,37.147"
0509     " C 17.685,37.334 19.341,36.803 19.472,37.475"
0510     " C 19.721,37.833 20.264,36.338 20.264,36.338"
0511     " C 20.544,35.759 21.054,35.192 21.890,36.278"
0512     " C 22.329,36.847 21.930,32.105 21.930,32.105"
0513     " C 21.930,32.105 27.859,33.031 27.478,34.460"
0514     " C 27.017,36.193 25.302,37.245 25.302,37.245"
0515     " C 23.675,37.429 23.683,37.998 23.440,38.876"
0516     " C 23.257,39.298 24.390,39.555 25.819,39.147"
0517     " C 26.419,38.871 26.508,39.644 26.726,39.392"
0518     " C 26.832,38.455 26.835,38.181 27.518,38.994"
0519     " C 27.263,36.857 29.360,35.554 29.435,35.442"
0520     " C 30.664,35.520 31.209,35.547 31.638,35.304"
0521     " C 32.010,34.551 33.203,34.079 35.435,33.716"
0522     " C 38.129,34.629 41.428,35.382 41.335,35.737"
0523     " C 41.206,36.225 36.891,35.726 37.019,37.589"
0524     " C 37.037,37.999 38.802,37.810 39.455,38.240"
0525     " C 39.756,38.296 41.215,37.707 42.661,36.513"
0526     " C 47.291,36.531 45.592,36.114 46.395,34.658"
0527     " C 46.623,34.246 54.256,35.533 55.788,33.790"
0528     " C 71.658,42.231 45.020,46.142 35.779,49.254"
0529     " C 31.072,50.987 13.462,51.472 12.112,52.822"
0530     " C 11.971,52.964 29.064,52.059 36.085,50.330"
0531     " C 79.669,41.497 56.851,34.139 56.427,30.933"
0532     " C 52.013,19.888 51.186,14.211 37.966,10.702 z'/>"
0533     "</svg>";
0534 
0535 struct IntroSource : public KMPlayer::Source {
0536     KMPlayerApp * m_app;
0537     IntroSource (KMPlayer::PartBase *p, KMPlayerApp * a)
0538         : KMPlayer::Source (i18n ("Intro"), p, "introsource"), m_app (a) {}
0539     KDE_NO_EXPORT bool hasLength () { return false; }
0540     KDE_NO_EXPORT bool isSeekable () { return false; }
0541     KDE_NO_EXPORT QString prettyName () { return i18n ("Intro"); }
0542     void activate ();
0543     void deactivate ();
0544     void stateElementChanged (KMPlayer::Node * node, KMPlayer::Node::State os, KMPlayer::Node::State ns);
0545     bool deactivated;
0546     bool finished;
0547 };
0548 
0549 QString makeNumber (int i) {
0550     return QString (
0551             "<svg width='64' height='64'>"
0552             "<circle id='circle0' cx='32' cy='32' r='30' stroke='#B0B0B0'"
0553             "stroke-width='4' fill='#A0A0A0'/>"
0554             "<text x='15' y='50'"
0555             "font-family='Sans' font-size='55' fill='black'>%1</text>"
0556             "</svg>").arg (i);
0557 }
0558 
0559 KDE_NO_EXPORT void IntroSource::activate () {
0560     if (m_player->settings ()->autoresize)
0561         m_app->disconnect(m_player, SIGNAL(sourceDimensionChanged()),m_app,SLOT(zoom100()));
0562     m_document = new KMPlayer::SourceDocument (this, QString ());
0563     QString introfile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmplayer/intro.xml");
0564     QFile file (introfile);
0565     if (file.exists () && file.open(QIODevice::ReadOnly)) {
0566         QTextStream ts (&file);
0567         KMPlayer::readXML (m_document, ts, QString (), false);
0568     } else {
0569         QString buf;
0570         QTextStream out(&buf, QIODevice::WriteOnly);
0571         out << "<smil><head><layout>"
0572             "<root-layout width='320' height='240' background-color='black'/>"
0573             "<region id='stage1' left='16' top='12' width='288' height='216'/>"
0574             "<region id='stage2' top='40' height='160'/>"
0575             "<region id='switch' top='30' width='20' height='20' right='20'/>"
0576             "<region id='reg' left='128' width='64' top='88' height='64' z-index='1'>"
0577             "<region id='icon' z-index='1'/>"
0578             "<region id='two' z-index='3'/>"
0579             "<region id='one' z-index='2'/>"
0580             "</region>"
0581             "<region id='spot' width='80' top='80' height='80'/>"
0582             "<region id='bat' left='208' width='64' top='48' height='64'/>"
0583             "<region id='rat' left='18' width='64' top='128' height='64'/>"
0584             "</layout>"
0585             "<transition id='clock1' dur='.3' type='clockWipe' direction='reverse'/>"
0586             "<transition id='fade1' dur='.1' type='fade'/>"
0587             "<transition id='fade2' dur='.2' type='fade'/>"
0588             "</head><body><excl><par>"
0589             "<brush region='stage1' dur='1' color='#303030'/>"
0590             "<img region='two' dur='.4' transIn='fade1' transOut='clock1'>" <<
0591             makeNumber (2) <<
0592             "</img><img region='switch' begin='0.08' dur='.1'>"
0593             "<svg width='20' height='20'>"
0594             "<path fill='white' d='M 2 2 L 18 2 L 9 12.7 z'/>"
0595             "</svg></img>"
0596             "<img region='one' begin='.1' dur='.8' transOut='clock1'>" <<
0597             makeNumber (1) <<
0598             "</img><img region='switch' begin='.7' dur='.1'>"
0599             "<svg width='20' height='20'>"
0600             "<circle fill='white' cx='9' cy='9' r='9'/>"
0601             "</svg></img>"
0602             "<brush region='stage2' begin='1.5' dur='.4' color='#101020'/>"
0603             "<img region='spot' begin='1' dur='.3' transIn='fade1' repeat='3'>"
0604             "<svg width='80' height='80'>"
0605             "<circle id='light' fill='red' cx='40' cy='40' r='40'/>"
0606             "</svg>"
0607             "</img>"
0608             "<img region='bat' begin='1' dur='.9'>" <<
0609             svg_bat <<
0610             "</img>"
0611             "<img region='rat' begin='1.2' dur='.7'>" <<
0612             svg_rat <<
0613             "</img>"
0614             "<animateMotion target='spot' begin='1' dur='.9' "
0615             "calcMode='discrete' values='200,40;10,120;120,80'/>"
0616             "<animate target='light' begin='1' dur='.9' calcMode='discrete'"
0617             "attribute='fill' values='#A04040;#40A040;#4040A0'/>"
0618             "<img region='icon' begin='1.5' dur='0.4' transIn='fade2' "
0619             "transOut='fade1' fit='meet' src='" <<
0620             KIconLoader::global()->iconPath (QString::fromLatin1 ("kmplayer"), -128) <<
0621             "'/></par><seq begin='stage1.activateEvent'/>"
0622             "</excl></body></smil>";
0623 
0624         QTextStream ts(&buf, QIODevice::ReadOnly);
0625         KMPlayer::readXML (m_document, ts, QString (), false);
0626     }
0627     //m_document->normalize ();
0628     m_current = m_document; //mrl->self ();
0629     if (m_document && m_document->firstChild ()) {
0630         KMPlayer::Mrl * mrl = m_document->firstChild ()->mrl ();
0631         if (mrl) {
0632             Source::setDimensions (m_document->firstChild (), mrl->size.width, mrl->size.height);
0633             m_player->updateTree ();
0634             m_current->activate ();
0635             emit startPlaying ();
0636         }
0637     }
0638     deactivated = finished = false;
0639 }
0640 
0641 KDE_NO_EXPORT void IntroSource::stateElementChanged (KMPlayer::Node * node, KMPlayer::Node::State, KMPlayer::Node::State new_state) {
0642     if (new_state == KMPlayer::Node::state_deactivated &&
0643             m_document == node) {
0644         m_document->reset ();
0645         finished = true;
0646         if (m_player->view ())
0647             m_app->restoreFromConfig ();
0648         emit stopPlaying ();
0649         if (!deactivated) // replace introsource with urlsource
0650             m_player->openUrl (KUrl ());
0651     }
0652 }
0653 
0654 KDE_NO_EXPORT void IntroSource::deactivate () {
0655     deactivated = true;
0656     if (m_player->settings ()->autoresize)
0657         m_app->connect(m_player, SIGNAL(sourceDimensionChanged()),m_app,SLOT(zoom100()));
0658     if (!finished && m_document) // user opens a source while introducing
0659         m_document->reset ();
0660 }
0661 #endif
0662 
0663 KDE_NO_EXPORT void KMPlayerApp::restoreFromConfig () {
0664     if (m_player->view ()) {
0665         m_view->dockArea ()->hide ();
0666         KConfigGroup dock_cfg (KSharedConfig::openConfig(), "Window Layout");
0667         m_view->dockArea ()->restoreState (dock_cfg.readEntry ("Layout", QByteArray ()));
0668         m_view->dockPlaylist ()->setVisible (dock_cfg.readEntry ("Show playlist", false));
0669         m_view->dockArea ()->show ();
0670         m_view->layout ()->activate ();
0671     }
0672 }
0673 
0674 KDE_NO_EXPORT void KMPlayerApp::openDocumentFile (const KUrl& url)
0675 {
0676     if (!m_played_intro) {
0677         m_played_intro = true;
0678         KMPlayer::Source * src = m_player->sources () ["urlsource"];
0679         if (url.isEmpty () && src->document () &&
0680                 src->document ()->hasChildNodes ()) {
0681             restoreFromConfig ();
0682             m_player->setSource (src);
0683             return;
0684 #ifdef KMPLAYER_WITH_CAIRO
0685         } else if (!m_player->settings ()->no_intro && url.isEmpty ()) {
0686             m_player->setSource (new IntroSource (m_player, this));
0687             return;
0688 #endif
0689         } else {
0690             m_played_exit = true; // no intro, so no exit as well
0691             restoreFromConfig ();
0692         }
0693     }
0694     slotStatusMsg(i18n("Opening file..."));
0695     m_player->openUrl (url);
0696     /*if (m_broadcastconfig->broadcasting () && url.url() == m_broadcastconfig->serverURL ()) {
0697         // speed up replay
0698         FFServerSetting & ffs = m_broadcastconfig->ffserversettings;
0699         KMPlayer::Source * source = m_player->source ();
0700         if (!ffs.width.isEmpty () && !ffs.height.isEmpty ()) {
0701             source->setWidth (ffs.width.toInt ());
0702             source->setHeight (ffs.height.toInt ());
0703         }
0704         source->setIdentified ();
0705     }*/
0706     slotStatusMsg (i18n ("Ready."));
0707 }
0708 
0709 KDE_NO_EXPORT void KMPlayerApp::addUrl (const KUrl& url) {
0710     KMPlayer::Source * src = m_player->sources () ["urlsource"];
0711     KMPlayer::NodePtr d = src->document ();
0712     if (d)
0713         d->appendChild (new KMPlayer::GenericURL (d,
0714                     url.isLocalFile() ? url.toLocalFile() : url.url()));
0715 }
0716 
0717 KDE_NO_EXPORT void KMPlayerApp::saveProperties (KConfigGroup &def_cfg) {
0718     def_cfg.writeEntry ("URL", m_player->source ()->url ().url ());
0719     def_cfg.writeEntry ("Visible", isVisible ());
0720 }
0721 
0722 KDE_NO_EXPORT void KMPlayerApp::readProperties (const KConfigGroup &def_cfg) {
0723     KUrl url (def_cfg.readEntry ("URL", QString ()));
0724     openDocumentFile (url);
0725     if (!def_cfg.readEntry ("Visible", true) && m_systray)
0726         hide ();
0727 }
0728 
0729 KDE_NO_EXPORT void KMPlayerApp::resizePlayer (int /*percentage*/) {
0730     /*KMPlayer::Source * source = m_player->source ();
0731     if (!source)
0732         return;
0733     int w, h;
0734     source->dimensions (w, h);
0735     if (w == 0 && h == 0) {
0736         w = 320;
0737         h = 240;
0738     } else
0739         h = m_view->viewer ()->heightForWidth (w);
0740     //kDebug () << "KMPlayerApp::resizePlayer (" << w << "," << h << ")";
0741     if (w > 0 && h > 0) {
0742         if (m_view->controlPanel ()->isVisible ())
0743             h += m_view->controlPanel ()->size ().height ();
0744         QSize s1 = size ();
0745         QSize s2 = m_view->viewArea ()->size ();
0746         w += s1.width () - s2.width ();
0747         h += s1.height () - s2.height ();
0748         w = int (1.0 * w * percentage/100.0);
0749         h = int (1.0 * h * percentage/100.0);
0750         QSize s = sizeForCentralWidgetSize (QSize (w, h));
0751         if (s.width () != width () || s.height () != height ()) {
0752             QSize oldsize = m_view->viewArea ()->size ();
0753             resize (s);
0754         }
0755     }*/
0756 }
0757 
0758 KDE_NO_EXPORT void KMPlayerApp::zoom50 () {
0759     resizePlayer (50);
0760 }
0761 
0762 KDE_NO_EXPORT void KMPlayerApp::zoom100 () {
0763     resizePlayer (100);
0764 }
0765 
0766 KDE_NO_EXPORT void KMPlayerApp::zoom150 () {
0767     resizePlayer (150);
0768 }
0769 
0770 KDE_NO_EXPORT void KMPlayerApp::editMode () {
0771     //m_view->dockArea ()->hide ();
0772     bool editmode = !m_view->editMode ();
0773     KMPlayer::PlayItem * pi = m_view->playList ()->selectedItem ();
0774     if (!pi || !pi->node)
0775         editmode = false;
0776     //m_view->dockArea ()->show ();
0777     viewEditMode->setChecked (editmode);
0778     KMPlayer::TopPlayItem * ri = (edit_tree_id > 0 && !editmode)
0779         ? m_view->playList ()->rootItem (edit_tree_id)
0780         : pi->rootItem ();
0781     if (editmode) {
0782         edit_tree_id = ri->id;
0783         m_view->setEditMode (ri, true);
0784         m_view->setInfoMessage (pi->node->innerXML ());
0785         viewSyncEditMode->setEnabled (true);
0786     } else {
0787         m_view->setEditMode (ri, false);
0788         edit_tree_id = -1;
0789         viewSyncEditMode->setEnabled (!strcmp (m_player->source()->name (), "urlsource"));
0790     }
0791 }
0792 
0793 KDE_NO_EXPORT void KMPlayerApp::syncEditMode () {
0794     if (edit_tree_id > -1) {
0795         KMPlayer::PlayItem *si = m_view->playList()->selectedItem();
0796         if (si && si->node) {
0797             si->node->clearChildren ();
0798             QString txt = m_view->infoPanel ()->toPlainText();
0799             QTextStream ts (&txt, QIODevice::ReadOnly);
0800             KMPlayer::readXML (si->node, ts, QString (), false);
0801             m_player->playModel()->updateTree (edit_tree_id, si->node->document(), si->node, true, false);
0802         }
0803     } else
0804         m_player->openUrl (m_player->source ()->url ());
0805 }
0806 
0807 KDE_NO_EXPORT void KMPlayerApp::showBroadcastConfig () {
0808     /*m_player->settings ()->addPage (m_broadcastconfig);
0809     m_player->settings ()->addPage (m_ffserverconfig);*/
0810 }
0811 
0812 KDE_NO_EXPORT void KMPlayerApp::hideBroadcastConfig () {
0813     /*m_player->settings ()->removePage (m_broadcastconfig);
0814     m_player->settings ()->removePage (m_ffserverconfig);*/
0815 }
0816 
0817 KDE_NO_EXPORT void KMPlayerApp::broadcastClicked () {
0818     /*if (m_broadcastconfig->broadcasting ())
0819         m_broadcastconfig->stopServer ();
0820     else {
0821         m_player->settings ()->show ("BroadcastPage");
0822         m_view->controlPanel()->broadcastButton ()->toggle ();
0823     }*/
0824 }
0825 
0826 KDE_NO_EXPORT void KMPlayerApp::broadcastStarted () {
0827     /*if (!m_view->controlPanel()->broadcastButton ()->isOn ())
0828         m_view->controlPanel()->broadcastButton ()->toggle ();*/
0829 }
0830 
0831 KDE_NO_EXPORT void KMPlayerApp::broadcastStopped () {
0832     /*if (m_view->controlPanel()->broadcastButton ()->isOn ())
0833         m_view->controlPanel()->broadcastButton ()->toggle ();
0834     if (m_player->source () != m_player->sources () ["tvsource"])
0835         m_view->controlPanel()->broadcastButton ()->hide ();
0836     setCursor (QCursor (Qt::ArrowCursor));*/
0837 }
0838 
0839 KDE_NO_EXPORT bool KMPlayerApp::broadcasting () const {
0840     //return m_broadcastconfig->broadcasting ();
0841     return false;
0842 }
0843 
0844 KDE_NO_EXPORT void KMPlayerApp::saveOptions()
0845 {
0846     KSharedConfigPtr config = KSharedConfig::openConfig ();
0847     KConfigGroup general (config, "General Options");
0848     if (m_player->settings ()->remembersize)
0849         general.writeEntry ("Geometry", size ());
0850     general.writeEntry ("Show Toolbar", viewToolBar->isChecked());
0851     general.writeEntry ("Show Statusbar", viewStatusBar->isChecked ());
0852     general.writeEntry ("Show Menubar", viewMenuBar->isChecked ());
0853     if (!m_player->sources () ["pipesource"]->pipeCmd ().isEmpty ()) {
0854         KConfigGroup (config, "Pipe Command").writeEntry (
0855                 "Command1", m_player->sources () ["pipesource"]->pipeCmd ());
0856     }
0857     m_view->setInfoMessage (QString ());
0858     KConfigGroup dock_cfg (KSharedConfig::openConfig(), "Window Layout");
0859     dock_cfg.writeEntry ("Layout", m_view->dockArea ()->saveState ());
0860     dock_cfg.writeEntry ("Show playlist", m_view->dockPlaylist ()->isVisible ());
0861     KConfigGroup toolbar_cfg (KSharedConfig::openConfig(), "Main Toolbar");
0862     toolBar("mainToolBar")->saveSettings (toolbar_cfg);
0863     Recents * rc = static_cast <Recents *> (recents.ptr ());
0864     if (rc && rc->resolved) {
0865         fileOpenRecent->saveEntries (KConfigGroup (config, "Recent Files"));
0866         rc->sync(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kmplayer/recent.xml");
0867     }
0868     Playlist * pl = static_cast <Playlist *> (playlist.ptr ());
0869     if (pl && pl->resolved)
0870         pl->sync(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kmplayer/playlist.xml");
0871 }
0872 
0873 
0874 KDE_NO_EXPORT void KMPlayerApp::readOptions() {
0875     KSharedConfigPtr config = KSharedConfig::openConfig ();
0876 
0877     KConfigGroup gen_cfg (config, "General Options");
0878 
0879     // bar status settings
0880     viewToolBar->setChecked (gen_cfg.readEntry("Show Toolbar", true));
0881     slotViewToolBar();
0882 
0883     bool bViewStatusbar = gen_cfg.readEntry("Show Statusbar", true);
0884     viewStatusBar->setChecked(bViewStatusbar);
0885     slotViewStatusBar();
0886 
0887     viewMenuBar->setChecked (gen_cfg.readEntry("Show Menubar", true));
0888     slotViewMenuBar();
0889 
0890     QSize size = gen_cfg.readEntry ("Geometry", QSize ());
0891     if (!size.isEmpty ())
0892         resize (size);
0893     else if (m_player->settings ()->remembersize)
0894         resize (QSize (640, 480));
0895 
0896     KConfigGroup toolbar_cfg (KSharedConfig::openConfig(), "Main Toolbar");
0897     toolBar("mainToolBar")->applySettings (toolbar_cfg);
0898     KConfigGroup pipe_cfg (config, "Pipe Command");
0899     static_cast <KMPlayerPipeSource *> (m_player->sources () ["pipesource"])->setCommand (
0900             pipe_cfg.readEntry ("Command1", QString ()));
0901     // initialize the recent file list
0902     if (!recents) {
0903         QDir dir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
0904         dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kmplayer");
0905         fileOpenRecent->loadEntries (KConfigGroup (config, "Recent Files"));
0906         recents = new Recents (this);
0907         recents_id = m_player->playModel()->addTree (recents, "listssource", "view-history", KMPlayer::PlayModel::AllowDrag);
0908     }
0909     configChanged ();
0910 }
0911 
0912 #include <netwm.h>
0913 #undef Always
0914 #undef Never
0915 #undef Status
0916 #undef Unsorted
0917 #undef Bool
0918 
0919 KDE_NO_EXPORT void KMPlayerApp::minimalMode (bool by_user) {
0920     /*unsigned long props = NET::WMWindowType;
0921     NETWinInfo winfo (QX11Info::display (), winId (), QX11Info::appRootWindow(), props);
0922     if (m_minimal_mode) {
0923         winfo.setWindowType (NET::Normal);
0924         readOptions ();
0925         if (by_user)
0926             disconnect (m_view->controlPanel ()->button (KMPlayer::ControlPanel::button_playlist), SIGNAL (clicked ()), this, SLOT (slotMinimalMode ()));
0927         restoreFromConfig ();
0928     } else {
0929         saveOptions ();
0930         menuBar()->hide();
0931         toolBar("mainToolBar")->hide();
0932         statusBar()->hide();
0933         if (by_user)
0934             connect (m_view->controlPanel ()->button (KMPlayer::ControlPanel::button_playlist), SIGNAL (clicked ()), this, SLOT (slotMinimalMode ()));
0935         if (by_user)
0936             winfo.setWindowType (NET::Utility);
0937     }
0938     m_view->viewArea ()->minimalMode ();
0939     if (by_user) {
0940         QRect rect = m_view->viewArea ()->topWindowRect ();
0941         hide ();
0942         QTimer::singleShot (0, this, SLOT (zoom100 ()));
0943         show ();
0944         move (rect.x (), rect.y ());
0945     }
0946     m_minimal_mode = !m_minimal_mode;*/
0947 }
0948 
0949 KDE_NO_EXPORT void KMPlayerApp::slotMinimalMode () {
0950     minimalMode (true);
0951 }
0952 
0953 #ifdef KMPLAYER_WITH_CAIRO
0954 struct ExitSource : public KMPlayer::Source {
0955     KDE_NO_CDTOR_EXPORT ExitSource (KMPlayer::PartBase *p)
0956         : KMPlayer::Source (i18n ("Exit"), p, "exitsource") {}
0957     KDE_NO_EXPORT QString prettyName () { return i18n ("Exit"); }
0958     KDE_NO_EXPORT bool hasLength () { return false; }
0959     KDE_NO_EXPORT bool isSeekable () { return false; }
0960     void activate ();
0961     KDE_NO_EXPORT void deactivate () {}
0962     void stateElementChanged (KMPlayer::Node * node, KMPlayer::Node::State os, KMPlayer::Node::State ns);
0963 };
0964 
0965 KDE_NO_EXPORT void ExitSource::activate () {
0966     m_document = new KMPlayer::SourceDocument (this, QString ());
0967     QString exitfile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmplayer/exit.xml");
0968     QFile file (exitfile);
0969     if (file.exists () && file.open (QIODevice::ReadOnly)) {
0970         QTextStream ts (&file);
0971         KMPlayer::readXML (m_document, ts, QString (), false);
0972     } else {
0973         QString smil = QString::fromLatin1 ("<smil><head><layout>"
0974           "<root-layout width='320' height='240' background-color='black'/>"
0975           "<region top='40' height='160' background-color='#101020'>"
0976           "<region id='image' left='128' top='28' width='64' bottom='28'/>"
0977           "</region></layout>"
0978           "<transition id='pw' dur='0.3' type='pushWipe' subtype='fromBottom'/>"
0979           "</head><body>"
0980           "<par>"
0981           //"<animate target='reg1' attribute='background-color' calcMode='discrete' values='#FFFFFF;#E4E4E4;#CCCCCC;#B4B4B4;#9E9E9E;#8A8A8A;#777777;#656565;#555555;#464646;#393939;#2D2D2D;#222222;#191919;#111111;#0B0B0B;#060606;#020202;#000000;#000000' dur='0.6'/>"
0982           "<img src='%2' id='img1' region='image' dur='0.4' fit='hidden' transOut='pw'/>"
0983           "</par>"
0984           "</body></smil>").arg (KIconLoader::global()->iconPath (QString::fromLatin1 ("kmplayer"), -64));
0985         QByteArray ba = smil.toUtf8 ();
0986         QTextStream ts (&ba, QIODevice::ReadOnly);
0987         KMPlayer::readXML (m_document, ts, QString (), false);
0988     }
0989     //m_document->normalize ();
0990     m_current = m_document;
0991     if (m_document && m_document->firstChild ()) {
0992         KMPlayer::Mrl * mrl = m_document->firstChild ()->mrl ();
0993         if (mrl) {
0994             setDimensions (m_document->firstChild (), mrl->size.width, mrl->size.height);
0995             m_player->updateTree ();
0996             m_current->activate ();
0997             emit startPlaying ();
0998             return;
0999         }
1000     }
1001     qApp->quit ();
1002 }
1003 
1004 KDE_NO_EXPORT void ExitSource::stateElementChanged (KMPlayer::Node * node, KMPlayer::Node::State, KMPlayer::Node::State new_state) {
1005     if (new_state == KMPlayer::Node::state_deactivated &&
1006             m_document == node &&
1007             m_player->view ())
1008        m_player->view ()->topLevelWidget ()->close ();
1009 }
1010 #endif
1011 
1012 KDE_NO_EXPORT bool KMPlayerApp::queryClose () {
1013     // KMPlayerVDRSource has to wait for pending commands like mute and quit
1014     m_player->stop ();
1015     //static_cast <KMPlayerVDRSource *> (m_player->sources () ["vdrsource"])->waitForConnectionClose ();
1016     if (m_played_exit || m_player->settings ()->no_intro || qApp->isSavingSession()) {
1017         aboutToCloseWindow();
1018         return true;
1019     }
1020     if (m_auto_resize)
1021         disconnect(m_player, SIGNAL(sourceDimensionChanged()),this,SLOT(zoom100()));
1022     m_played_exit = true;
1023     if (!m_minimal_mode)
1024         minimalMode (false);
1025 #ifdef KMPLAYER_WITH_CAIRO
1026     m_player->setSource (new ExitSource (m_player));
1027     return false;
1028 #else
1029     aboutToCloseWindow();
1030     return true;
1031 #endif
1032 }
1033 
1034 KDE_NO_EXPORT void KMPlayerApp::aboutToCloseWindow()
1035 {
1036     if (!m_minimal_mode)
1037         saveOptions();
1038     disconnect (m_player->settings (), SIGNAL (configChanged ()),
1039                 this, SLOT (configChanged ()));
1040     m_player->settings ()->writeConfig ();
1041 }
1042 
1043 KDE_NO_EXPORT void KMPlayerApp::slotFileNewWindow()
1044 {
1045     slotStatusMsg(i18n("Opening a new application window..."));
1046 
1047     KMPlayerApp *new_window= new KMPlayerApp();
1048     new_window->show();
1049 
1050     slotStatusMsg(i18n("Ready."));
1051 }
1052 
1053 static bool findOpenLocation(QStandardPaths::StandardLocation type, QString* dir)
1054 {
1055     QStringList dirs = QStandardPaths::standardLocations(type);
1056     for (int i = 0; i < dirs.size(); ++i) {
1057         if (QDir(dirs[i]).exists()) {
1058             *dir = dirs[i];
1059             return true;
1060         }
1061     }
1062     return false;
1063 }
1064 
1065 KDE_NO_EXPORT void KMPlayerApp::slotFileOpen () {
1066     QString dir;
1067     if (!(findOpenLocation(QStandardPaths::MoviesLocation, &dir)
1068                 || findOpenLocation(QStandardPaths::MusicLocation, &dir)
1069                 || findOpenLocation(QStandardPaths::DesktopLocation, &dir)
1070                 || findOpenLocation(QStandardPaths::HomeLocation, &dir))) {
1071         dir = QString("/");
1072     }
1073     QList<QUrl> urls = QFileDialog::getOpenFileUrls(this, i18n("Open File"),
1074             QUrl::fromLocalFile(dir), i18n ("*|All Files"));
1075     if (urls.size () == 1) {
1076         openDocumentFile (urls [0]);
1077     } else if (urls.size () > 1) {
1078         m_player->openUrl (KUrl ());
1079         for (int i = 0; i < urls.size (); i++)
1080             addUrl (urls [i]);
1081     }
1082 }
1083 
1084 KDE_NO_EXPORT void KMPlayerApp::slotFileOpenRecent(const QUrl& url)
1085 {
1086     slotStatusMsg(i18n("Opening file..."));
1087 
1088     openDocumentFile (url);
1089 
1090 }
1091 
1092 static bool findSaveLocation(QStandardPaths::StandardLocation type, QString* dir)
1093 {
1094     *dir = QStandardPaths::writableLocation(type);
1095     return !dir->isEmpty() && QDir(*dir).exists();
1096 }
1097 
1098 KDE_NO_EXPORT void KMPlayerApp::slotSaveAs () {
1099     QString dir;
1100     if (!(findSaveLocation(QStandardPaths::MoviesLocation, &dir)
1101                 || findSaveLocation(QStandardPaths::MusicLocation, &dir)
1102                 || findSaveLocation(QStandardPaths::DesktopLocation, &dir)
1103                 || findSaveLocation(QStandardPaths::HomeLocation, &dir))) {
1104         dir = QString("/tmp");
1105     }
1106     QString url = QFileDialog::getSaveFileName(this, i18n("Save File"), dir + QChar('/'));
1107     if (!url.isEmpty ()) {
1108         QFile file (url);
1109         if (!file.open (QIODevice::WriteOnly | QIODevice::Truncate)) {
1110             KMessageBox::error (this, i18n ("Error opening file %1.\n%2.",url,file.errorString ()), i18n("Error"));
1111             return;
1112         }
1113         if (m_player->source ()) {
1114             KMPlayer::NodePtr doc = m_player->source ()->document ();
1115             if (doc) {
1116                 QTextStream ts (&file);
1117                 ts.setCodec("UTF-8");
1118                 ts << QString ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1119                 if (doc->childNodes ().length () == 1)
1120                     ts << doc->innerXML ();
1121                 else
1122                     ts << doc->outerXML ();
1123             }
1124         }
1125         file.close ();
1126     }
1127 }
1128 
1129 KDE_NO_EXPORT void KMPlayerApp::slotClearHistory () {
1130     fileOpenRecent->clear ();
1131     int mi = fileOpenRecent->maxItems ();
1132     fileOpenRecent->setMaxItems (0);
1133     fileOpenRecent->setMaxItems (mi);
1134     m_player->settings ()->urllist.clear ();
1135     m_player->settings ()->sub_urllist.clear ();
1136     if (recents) { // small window this check fails and thus ClearHistory fails
1137         recents->defer (); // make sure it's loaded
1138         recents->clear ();
1139         m_player->playModel()->updateTree (recents_id, recents, 0, false, false);
1140     }
1141 }
1142 
1143 KDE_NO_EXPORT void KMPlayerApp::slotGeneratorMenu () {
1144     if (!generators.first ()) {
1145         const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "kmplayer/generators", QStandardPaths::LocateDirectory);
1146         for (int i = 0; i < dirs.size(); ++i) {
1147             QDirIterator it(dirs[i], QStringList() << QStringLiteral("*.xml"));
1148             while (it.hasNext()) {
1149                 QString file = it.next();
1150                 Generator *gen = new Generator(this);
1151                 KMPlayer::NodePtr doc = gen;
1152                 gen->readFromFile(file);
1153                 KMPlayer::Node *n = gen->firstChild();
1154                 if (n && n->isElementNode()) {
1155                     QString name = static_cast<KMPlayer::Element*>(n)->getAttribute(
1156                             KMPlayer::Ids::attr_name);
1157                     if (name.isEmpty())
1158                         name = QFile(file).fileName();
1159                     generators.append(new KMPlayer::NodeStoreItem(doc));
1160                     m_generatormenu->addAction(name, this, SLOT(slotGenerator()));
1161                 } else {
1162                     gen->dispose();
1163                 }
1164             }
1165         }
1166     }
1167 }
1168 
1169 KDE_NO_EXPORT void KMPlayerApp::slotGenerator () {
1170     const QAction *act = qobject_cast <QAction *> (sender ());
1171     KMPlayer::NodeStoreItem *store = generators.first ();
1172     QObjectList chlds = m_generatormenu->children ();
1173 
1174     if (current_generator && current_generator->active ()) {
1175         current_generator->deactivate ();
1176         current_generator = NULL;
1177     }
1178 
1179     for (int i = 0; store && i < chlds.size (); ++i) {
1180         const QAction *ca = qobject_cast <QAction *> (chlds[i]);
1181         if (ca && !ca->text ().isEmpty ()) {
1182             if (ca == act) {
1183                 current_generator = store->data;
1184                 break;
1185             }
1186             store = store->nextSibling ();
1187         }
1188     }
1189     if (current_generator)
1190         current_generator->activate ();
1191 }
1192 
1193 KDE_NO_EXPORT void KMPlayerApp::slotFileClose()
1194 {
1195     slotStatusMsg(i18n("Closing file..."));
1196 
1197     m_player->stop ();
1198 
1199     slotStatusMsg(i18n("Ready."));
1200 }
1201 
1202 KDE_NO_EXPORT void KMPlayerApp::slotFileQuit()
1203 {
1204     close();
1205 }
1206 
1207 KDE_NO_EXPORT void KMPlayerApp::slotPreferences () {
1208     m_player->showConfigDialog ();
1209 }
1210 
1211 KDE_NO_EXPORT void KMPlayerApp::slotConfigureKeys () {
1212   KShortcutsDialog::configure (actionCollection ());
1213 }
1214 
1215 KDE_NO_EXPORT void KMPlayerApp::slotConfigureToolbars () {
1216     //KEditToolbar dlg (actionCollection ());
1217     //if (dlg.exec ())
1218     //    initMenu (); // also add custom popups //createGUI ();
1219 }
1220 
1221 KDE_NO_EXPORT void KMPlayerApp::slotViewToolBar() {
1222     m_showToolbar = viewToolBar->isChecked();
1223     if(m_showToolbar)
1224         toolBar("mainToolBar")->show();
1225     else
1226         toolBar("mainToolBar")->hide();
1227 }
1228 
1229 KDE_NO_EXPORT void KMPlayerApp::slotViewStatusBar() {
1230     m_showStatusbar = viewStatusBar->isChecked();
1231     statusBar()->setVisible (m_showStatusbar);
1232 }
1233 
1234 KDE_NO_EXPORT void KMPlayerApp::slotViewMenuBar() {
1235     m_showMenubar = viewMenuBar->isChecked();
1236     if (m_showMenubar) {
1237         menuBar()->show();
1238         slotStatusMsg(i18n("Ready"));
1239     } else {
1240         menuBar()->hide();
1241         slotStatusMsg (i18n ("Show Menu Bar with %1",
1242                     viewMenuBar->shortcut ().toString ()));
1243         if (!m_showStatusbar) {
1244             statusBar()->show();
1245             QTimer::singleShot (3000, statusBar(), SLOT (hide ()));
1246         }
1247     }
1248 }
1249 
1250 KDE_NO_EXPORT void KMPlayerApp::slotStatusMsg (const QString &text) {
1251     QStatusBar * sb = statusBar ();
1252     sb->showMessage(text);
1253 }
1254 
1255 KDE_NO_EXPORT void KMPlayerApp::fullScreen () {
1256     if (qobject_cast <QAction *> (sender ()))
1257         m_view->fullScreen();
1258     viewFullscreen->setChecked (m_view->isFullScreen ());
1259     if (m_view->isFullScreen())
1260         hide ();
1261     else {
1262         show ();
1263         setGeometry (m_view->viewArea ()->topWindowRect ());
1264     }
1265 }
1266 
1267 KDE_NO_EXPORT void KMPlayerApp::playListItemActivated (const QModelIndex& index) {
1268     KMPlayer::PlayItem * vi = static_cast <KMPlayer::PlayItem *> (index.internalPointer ());
1269     if (edit_tree_id > -1) {
1270         if (vi->rootItem ()->id != edit_tree_id)
1271             editMode ();
1272         m_view->setInfoMessage (edit_tree_id > -1 && vi->node
1273                 ? vi->node->innerXML () : QString ());
1274     }
1275     viewEditMode->setEnabled (vi->rootItem ()->itemFlags() & KMPlayer::PlayModel::TreeEdit);
1276 }
1277 
1278 KDE_NO_EXPORT
1279 void KMPlayerApp::playListItemDropped (QDropEvent *de, KMPlayer::PlayItem *item) {
1280     KMPlayer::TopPlayItem *ritem = item->rootItem();
1281     KUrl url;
1282 
1283     manip_node = 0L;
1284     m_drop_list.clear ();
1285 
1286     if (de->mimeData()->hasFormat ("text/uri-list")) {
1287         m_drop_list = de->mimeData()->urls();
1288     } else if (de->mimeData ()->hasFormat ("application/x-qabstractitemmodeldatalist")) {
1289         KMPlayer::PlayItem* pli = m_view->playList()->selectedItem ();
1290         if (pli && pli->node) {
1291             manip_node = pli->node;
1292             if (pli->node->mrl ()) {
1293                 KUrl url (pli->node->mrl ()->src);
1294                 if (url.isValid ())
1295                     m_drop_list.push_back (url);
1296             }
1297         }
1298     }
1299     if (m_drop_list.isEmpty ()) {
1300         KUrl url (de->mimeData ()->text ());
1301         if (url.isValid ())
1302             m_drop_list.push_back (url);
1303     }
1304     if (ritem->id == 0) {
1305         if (m_drop_list.size () > 0) {
1306             if (m_drop_list.size () == 1) {
1307                 url = m_drop_list[0];
1308             } else if (m_drop_list.size () > 1) {
1309                 m_player->sources () ["urlsource"]->setUrl (QString ());
1310                 for (int i = 0; i < m_drop_list.size (); i++)
1311                     addUrl (m_drop_list[i]);
1312             }
1313             openDocumentFile (url);
1314         }
1315     } else {
1316         m_drop_after = item;
1317         KMPlayer::NodePtr after_node = static_cast<KMPlayer::PlayItem*> (item)->node;
1318         if (after_node->id == KMPlayer::id_node_playlist_document ||
1319                 after_node->id == KMPlayer::id_node_group_node)
1320             after_node->defer (); // make sure it has loaded
1321         dropAdd->setText(!!manip_node ? i18n ("Move here") : i18n ("&Add to list"));
1322         dropDelete->setVisible(!!manip_node);
1323         dropCopy->setVisible(manip_node && manip_node->isPlayable ());
1324         if (manip_node || m_drop_list.size () > 0)
1325             m_dropmenu->exec (m_view->playList ()->mapToGlobal (de->pos ()));
1326     }
1327 }
1328 
1329 KDE_NO_EXPORT void KMPlayerApp::menuDropInList () {
1330     KMPlayer::NodePtr n = m_drop_after->node;
1331     KMPlayer::NodePtr pi;
1332     for (int i = m_drop_list.size (); n && (i > 0 || manip_node); i--) {
1333         if (manip_node && manip_node->parentNode ()) {
1334             pi = manip_node;
1335             manip_node = 0L;
1336             pi->parentNode ()->removeChild (pi);
1337         } else
1338             pi = new PlaylistItem(playlist, this,false, m_drop_list[i-1].url());
1339         if (n == playlist
1340                 || (KMPlayer::id_node_playlist_item != n->id
1341                     && m_view->playList()->isExpanded (m_view->playList()->index(m_drop_after)))) {
1342             n->insertBefore (pi, n->firstChild ());
1343         } else if (n->parentNode ()) {
1344             n->parentNode ()->insertBefore (pi, n->nextSibling ());
1345         }
1346     }
1347     m_player->playModel()->updateTree (playlist_id, playlist, pi, true, false);
1348 }
1349 
1350 KDE_NO_EXPORT void KMPlayerApp::menuDropInGroup () {
1351     KMPlayer::NodePtr n = m_drop_after->node;
1352     if (!n)
1353         return;
1354     KMPlayer::NodePtr g = new PlaylistGroup (playlist, this, i18n("New group"));
1355     if (n == playlist
1356             || (KMPlayer::id_node_playlist_item != n->id
1357                 && m_view->playList()->isExpanded (m_view->playList()->index(m_drop_after)))) {
1358         n->insertBefore (g, n->firstChild ());
1359     } else {
1360         n->parentNode ()->insertBefore (g, n->nextSibling ());
1361     }
1362     KMPlayer::NodePtr pi;
1363     for (int i = 0; i < m_drop_list.size () || manip_node; ++i) {
1364         if (manip_node && manip_node->parentNode ()) {
1365             pi = manip_node;
1366             manip_node = 0L;
1367             pi->parentNode ()->removeChild (pi);
1368         } else
1369             pi = new PlaylistItem (playlist,this, false, m_drop_list[i].url ());
1370         g->appendChild (pi);
1371     }
1372     m_player->playModel()->updateTree (playlist_id, playlist, pi, true, false);
1373 }
1374 
1375 KDE_NO_EXPORT void KMPlayerApp::menuCopyDrop () {
1376     KMPlayer::NodePtr n = m_drop_after->node;
1377     if (n && manip_node) {
1378         KMPlayer::NodePtr pi = new PlaylistItem (playlist, this, false, manip_node->mrl ()->src);
1379         if (n == playlist
1380                 || (KMPlayer::id_node_playlist_item != n->id
1381                     && m_view->playList()->isExpanded (m_view->playList()->index(m_drop_after)))) {
1382             n->insertBefore (pi, n->firstChild ());
1383         } else {
1384             n->parentNode ()->insertBefore (pi, n->nextSibling ());
1385         }
1386         m_player->playModel()->updateTree (playlist_id, playlist, pi, true, false);
1387     }
1388 }
1389 
1390 KDE_NO_EXPORT void KMPlayerApp::menuDeleteNode () {
1391     KMPlayer::Node *n = NULL;
1392     if (manip_node && manip_node->parentNode ()) {
1393         n = manip_node->previousSibling() ? manip_node->previousSibling() : manip_node->parentNode ();
1394         manip_node->parentNode ()->removeChild (manip_node);
1395     }
1396     m_player->playModel()->updateTree (manip_tree_id, 0L, n, true, false);
1397 }
1398 
1399 KDE_NO_EXPORT void KMPlayerApp::menuMoveUpNode () {
1400     KMPlayer::NodePtr n = manip_node.ptr ();
1401     if (n && n->parentNode () && n->previousSibling ()) {
1402         KMPlayer::Node *prev = n->previousSibling ();
1403         n->parentNode ()->removeChild (n);
1404         prev->parentNode ()->insertBefore (n, prev);
1405     }
1406     m_player->playModel()->updateTree (manip_tree_id, 0L, n, true, false);
1407 }
1408 
1409 KDE_NO_EXPORT void KMPlayerApp::menuMoveDownNode () {
1410     KMPlayer::NodePtr n = manip_node.ptr ();
1411     if (n && n->parentNode () && n->nextSibling ()) {
1412         KMPlayer::Node *next = n->nextSibling ();
1413         n->parentNode ()->removeChild (n);
1414         next->parentNode ()->insertBefore (n, next->nextSibling ());
1415     }
1416     m_player->playModel()->updateTree (manip_tree_id, 0L, n, true, false);
1417 }
1418 
1419 KDE_NO_EXPORT void KMPlayerApp::playListItemMoved () {
1420     KMPlayer::PlayItem *si = m_view->playList ()->selectedItem ();
1421     KMPlayer::TopPlayItem * ri = si->rootItem ();
1422     kDebug() << "playListItemMoved " << (ri->id == playlist_id) << !! si->node;
1423     if (ri->id == playlist_id && si->node) {
1424         KMPlayer::Node *p = si->node->parentNode ();
1425         if (p) {
1426             p->removeChild (si->node);
1427             m_player->playModel()->updateTree(playlist_id,playlist,0L,false,false);
1428         }
1429     }
1430 }
1431 
1432 KDE_NO_EXPORT void KMPlayerApp::preparePlaylistMenu (KMPlayer::PlayItem * item, QMenu * pm) {
1433     KMPlayer::TopPlayItem *ri = item->rootItem ();
1434     if (ri != item
1435             && item->node
1436             && ri->item_flags & (KMPlayer::PlayModel::Moveable | KMPlayer::PlayModel::Deleteable)) {
1437         manip_tree_id = ri->id;
1438         pm->addSeparator();
1439         manip_node = item->node;
1440         if (ri->item_flags & KMPlayer::PlayModel::Deleteable)
1441             pm->addAction(QIcon::fromTheme("edit-delete"), i18n("&Delete item"), this, SLOT(menuDeleteNode()));
1442         if (ri->item_flags & KMPlayer::PlayModel::Moveable) {
1443             if (manip_node->previousSibling ())
1444                 pm->addAction(QIcon::fromTheme("go-up"), i18n("&Move up"), this, SLOT(menuMoveUpNode()));
1445             if (manip_node->nextSibling ())
1446                 pm->addAction(QIcon::fromTheme("go-down"), i18n("Move &down"), this, SLOT(menuMoveDownNode()));
1447         }
1448     }
1449 }
1450 
1451 KDE_NO_EXPORT void KMPlayerApp::configChanged () {
1452     //viewKeepRatio->setChecked (m_player->settings ()->sizeratio);
1453     if (m_player->settings ()->docksystray && !m_systray) {
1454         m_systray = new KSystemTrayIcon (QIcon::fromTheme("kmplayer"), this);
1455         m_systray->show ();
1456     } else if (!m_player->settings ()->docksystray && m_systray) {
1457         delete m_systray;
1458         m_systray = 0L;
1459     }
1460     if (m_player->settings ()->autoresize && !m_auto_resize)
1461         connect(m_player,SIGNAL(sourceDimensionChanged()),this,SLOT(zoom100()));
1462     else if (!m_player->settings ()->autoresize && m_auto_resize)
1463         disconnect(m_player, SIGNAL(sourceDimensionChanged()),this,SLOT(zoom100()));
1464     m_auto_resize = m_player->settings ()->autoresize;
1465 }
1466 
1467 KDE_NO_EXPORT void KMPlayerApp::keepSizeRatio () {
1468     m_view->setKeepSizeRatio (!m_view->keepSizeRatio ());
1469     m_player->settings ()->sizeratio = m_view->keepSizeRatio ();
1470     //viewKeepRatio->setChecked (m_view->keepSizeRatio ());
1471 }
1472 
1473 //-----------------------------------------------------------------------------
1474 
1475 KDE_NO_CDTOR_EXPORT KMPlayerPrefSourcePageDVD::KMPlayerPrefSourcePageDVD (QWidget * parent)
1476  : QFrame(parent) {
1477     QVBoxLayout *layout = new QVBoxLayout;
1478     autoPlayDVD = new QCheckBox (i18n ("Auto play after opening DVD"));
1479     autoPlayDVD->setWhatsThis(i18n("Start playing DVD right after opening DVD"));
1480     QLabel *dvdDevicePathLabel = new QLabel (i18n("DVD device:"));
1481     dvddevice = new KUrlRequester (KUrl ("/dev/dvd"));
1482     dvddevice->setWhatsThis(i18n("Path to your DVD device, you must have read rights to this device"));
1483     layout->addWidget (autoPlayDVD);
1484     layout->addItem (new QSpacerItem (0, 10, QSizePolicy::Minimum, QSizePolicy::Minimum));
1485     layout->addWidget (dvdDevicePathLabel);
1486     layout->addWidget (dvddevice);
1487     layout->addItem (new QSpacerItem (0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
1488     setLayout(layout);
1489 }
1490 
1491 //-----------------------------------------------------------------------------
1492 
1493 class KMPLAYER_NO_EXPORT Disks : public KMPlayer::Document {
1494 public:
1495     Disks (KMPlayerApp * a);
1496     void message (KMPlayer::MessageType msg, void *data);
1497     KMPlayerApp * app;
1498 };
1499 
1500 class KMPLAYER_NO_EXPORT Disk : public KMPlayer::Mrl {
1501 public:
1502     Disk (KMPlayer::NodePtr & doc, KMPlayerApp *a, const QString &url, const QString &pn);
1503     void activate ();
1504     KMPlayerApp * app;
1505 };
1506 
1507 KDE_NO_CDTOR_EXPORT Disks::Disks (KMPlayerApp * a)
1508                 : KMPlayer::Document ("disks://", 0L), app (a) {
1509     id = id_node_disk_document;
1510     resolved = true;
1511     bookmarkable = false;
1512     title = i18n ("Optical Disks");
1513 }
1514 
1515 KDE_NO_EXPORT void Disks::message (KMPlayer::MessageType msg, void *data) {
1516     if (KMPlayer::MsgChildFinished)
1517         finish ();
1518     else
1519         return KMPlayer::Document::message (msg, data);
1520 }
1521 
1522 KDE_NO_CDTOR_EXPORT Disk::Disk (KMPlayer::NodePtr & doc, KMPlayerApp * a, const QString &url, const QString &pn)
1523   : KMPlayer::Mrl (doc, id_node_disk_node), app (a) {
1524     src = url;
1525     title = pn;
1526     bookmarkable = false;
1527 }
1528 
1529 KDE_NO_EXPORT void Disk::activate () {
1530     const char * sn;
1531     if (src.startsWith ("cdda"))
1532         sn = "audiocdsource";
1533     else if (src.startsWith ("vcd"))
1534         sn = "vcdsource";
1535     else
1536         sn = "dvdsource";
1537     app->player ()->setSource (app->player ()->sources () [sn]);
1538 }
1539 
1540 //-----------------------------------------------------------------------------
1541 
1542 KDE_NO_CDTOR_EXPORT KMPlayerDVDSource::KMPlayerDVDSource(KMPlayerApp* a)
1543     : KMPlayer::Source(i18n ("DVD"), a->player(), "dvdsource"), m_app(a), m_configpage(0L) {
1544     // FIXME: these menus are void currently
1545     setUrl ("dvd://");
1546     m_player->settings ()->addPage (this);
1547     disks = new Disks (a);
1548     disks->appendChild (new Disk (disks, a, "cdda://", i18n ("CDROM - Audio Compact Disk")));
1549     disks->appendChild (new Disk (disks, a, "vcd://", i18n ("VCD - Video Compact Disk")));
1550     disks->appendChild (new Disk (disks, a, "dvd://", i18n ("DVD - Digital Video Disk")));
1551     m_player->playModel()->addTree (disks, "listssource", "media-optical", 0);
1552 }
1553 
1554 KDE_NO_CDTOR_EXPORT KMPlayerDVDSource::~KMPlayerDVDSource () {
1555     disks->document ()->dispose ();
1556 }
1557 
1558 KDE_NO_EXPORT bool KMPlayerDVDSource::processOutput (const QString & str) {
1559     if (KMPlayer::Source::processOutput (str))
1560         return true;
1561     if (m_identified)
1562         return false;
1563     if (str.startsWith ("ID_DVD_TITLES=")) {
1564         int nt = str.mid (14).toInt ();
1565         for (int i = 0; i < nt; i++)
1566             m_document->appendChild (new KMPlayer::GenericMrl (m_document,
1567                         QString ("dvd://%1").arg (i+1),
1568                         i18n ("Track %1", QString::number (i+1))));
1569         return true;
1570     }
1571     return false;
1572 }
1573 
1574 KDE_NO_EXPORT void KMPlayerDVDSource::activate () {
1575     m_start_play = m_auto_play;
1576     setUrl ("dvd://");
1577     QTimer::singleShot (0, m_player, SLOT (play ()));
1578 }
1579 
1580 KDE_NO_EXPORT void KMPlayerDVDSource::setIdentified (bool b) {
1581     KMPlayer::Source::setIdentified (b);
1582     m_start_play = true;
1583     m_player->updateTree ();
1584     m_app->slotStatusMsg (i18n ("Ready."));
1585 }
1586 
1587 KDE_NO_EXPORT void KMPlayerDVDSource::deactivate () {
1588 }
1589 
1590 KDE_NO_EXPORT void KMPlayerDVDSource::setCurrent (KMPlayer::Mrl *cur) {
1591     KMPlayer::Source::setCurrent (cur);
1592     QString url ("dvd://");
1593     if (m_document)
1594         m_document->mrl ()->src = url;
1595     else
1596         setUrl (url);
1597     m_options = QString (m_identified ? "" : "-v ");
1598     if (m_player->settings ()->dvddevice.size () > 0)
1599         m_options += QString(" -dvd-device ") + m_player->settings()->dvddevice;
1600     if (!m_start_play)
1601         m_options += " -frames 0";
1602     m_recordcmd = m_options + QString (" -vf scale -zoom");
1603 }
1604 
1605 KDE_NO_EXPORT QString KMPlayerDVDSource::filterOptions () {
1606     KMPlayer::Settings * settings = m_player->settings ();
1607     if (!settings->disableppauto)
1608         return KMPlayer::Source::filterOptions ();
1609     return QString ("");
1610 }
1611 
1612 KDE_NO_EXPORT void KMPlayerDVDSource::play (KMPlayer::Mrl *mrl) {
1613     KMPlayer::Source::play (mrl);
1614 }
1615 
1616 KDE_NO_EXPORT QString KMPlayerDVDSource::prettyName () {
1617     return i18n ("DVD");
1618 }
1619 
1620 static const char * strPlayDVD = "Immediately Play DVD";
1621 
1622 KDE_NO_EXPORT void KMPlayerDVDSource::write (KSharedConfigPtr config) {
1623     KConfigGroup (config, strMPlayerGroup).writeEntry (strPlayDVD, m_auto_play);
1624 }
1625 
1626 KDE_NO_EXPORT void KMPlayerDVDSource::read (KSharedConfigPtr config) {
1627     m_auto_play = KConfigGroup (config, strMPlayerGroup).readEntry (strPlayDVD, true);
1628 }
1629 
1630 KDE_NO_EXPORT void KMPlayerDVDSource::sync (bool fromUI) {
1631     if (fromUI) {
1632         m_auto_play = m_configpage->autoPlayDVD->isChecked ();
1633         m_player->settings ()->dvddevice = m_configpage->dvddevice->lineEdit()->text ();
1634     } else {
1635         m_configpage->autoPlayDVD->setChecked (m_auto_play);
1636         m_configpage->dvddevice->lineEdit()->setText (m_player->settings ()->dvddevice);
1637     }
1638 }
1639 
1640 KDE_NO_EXPORT void KMPlayerDVDSource::prefLocation (QString & item, QString & icon, QString & tab) {
1641     item = i18n ("Source");
1642     icon = QString ("source");
1643     tab = i18n ("DVD");
1644 }
1645 
1646 KDE_NO_EXPORT QFrame * KMPlayerDVDSource::prefPage (QWidget * parent) {
1647     m_configpage = new KMPlayerPrefSourcePageDVD (parent);
1648     return m_configpage;
1649 }
1650 
1651 //-----------------------------------------------------------------------------
1652 
1653 KDE_NO_CDTOR_EXPORT KMPlayerPrefSourcePageVCD::KMPlayerPrefSourcePageVCD (QWidget * parent)
1654  : QFrame (parent) {
1655      QVBoxLayout *layout = new QVBoxLayout;
1656      autoPlayVCD = new QCheckBox (i18n ("Auto play after opening a VCD"));
1657      autoPlayVCD->setWhatsThis(i18n("Start playing VCD right after opening VCD"));
1658      QLabel *vcdDevicePathLabel = new QLabel (i18n ("VCD (CDROM) device:"));
1659      vcddevice= new KUrlRequester (KUrl ("/dev/cdrom"));
1660      vcddevice->setWhatsThis(i18n("Path to your CDROM/DVD device, you must have read rights to this device"));
1661      layout->addWidget (autoPlayVCD);
1662      layout->addItem (new QSpacerItem (0, 10, QSizePolicy::Minimum, QSizePolicy::Minimum));
1663      layout->addWidget (vcdDevicePathLabel);
1664      layout->addWidget (vcddevice);
1665      layout->addItem (new QSpacerItem (0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
1666      setLayout(layout);
1667 }
1668 
1669 //-----------------------------------------------------------------------------
1670 
1671 KDE_NO_CDTOR_EXPORT KMPlayerVCDSource::KMPlayerVCDSource(KMPlayerApp* a)
1672     : KMPlayer::Source(i18n("VCD"), a->player(), "vcdsource"), m_app(a), m_configpage(0L) {
1673     m_player->settings ()->addPage (this);
1674     setUrl ("vcd://");
1675 }
1676 
1677 KDE_NO_CDTOR_EXPORT KMPlayerVCDSource::~KMPlayerVCDSource () {
1678 }
1679 
1680 KDE_NO_EXPORT bool KMPlayerVCDSource::processOutput (const QString & str) {
1681     if (KMPlayer::Source::processOutput (str))
1682         return true;
1683     if (m_identified)
1684         return false;
1685     //kDebug () << "scanning " << cstr;
1686     QRegExp * patterns = static_cast <KMPlayer::MPlayerPreferencesPage *> (m_player->mediaManager ()->processInfos () ["mplayer"]->config_page)->m_patterns;
1687     QRegExp & trackRegExp = patterns [KMPlayer::MPlayerPreferencesPage::pat_vcdtrack];
1688     if (trackRegExp.indexIn(str) > -1) {
1689         m_document->state = KMPlayer::Element::state_deferred;
1690         m_document->appendChild (new KMPlayer::GenericMrl (m_document, QString ("vcd://") + trackRegExp.cap (1), i18n ("Track ") + trackRegExp.cap (1)));
1691         kDebug () << "track " << trackRegExp.cap (1);
1692         return true;
1693     }
1694     return false;
1695 }
1696 
1697 KDE_NO_EXPORT void KMPlayerVCDSource::activate () {
1698     m_player->stop ();
1699     init ();
1700     m_start_play = m_auto_play;
1701     setUrl ("vcd://");
1702     if (m_start_play)
1703         QTimer::singleShot (0, m_player, SLOT (play ()));
1704 }
1705 
1706 KDE_NO_EXPORT void KMPlayerVCDSource::deactivate () {
1707 }
1708 
1709 KDE_NO_EXPORT void KMPlayerVCDSource::setIdentified (bool b) {
1710     KMPlayer::Source::setIdentified (b);
1711     setCurrent (!m_current || !m_document->hasChildNodes ()
1712             ? m_document->mrl () : m_current->mrl ());
1713     m_player->updateTree ();
1714     if (m_current->state == KMPlayer::Element::state_deferred)
1715         m_current->undefer ();
1716     m_app->slotStatusMsg (i18n ("Ready."));
1717 }
1718 
1719 KDE_NO_EXPORT void KMPlayerVCDSource::setCurrent (KMPlayer::Mrl *cur) {
1720     KMPlayer::Source::setCurrent (cur);
1721     QString url ("vcd://");
1722     if (m_current && m_current != m_document)
1723         url += m_current->mrl ()->src;
1724     m_options.truncate (0);
1725     if (m_player->settings ()->vcddevice.size () > 0)
1726         m_options+=QString(" -cdrom-device ") + m_player->settings()->vcddevice;
1727     m_recordcmd = m_options;
1728 }
1729 
1730 KDE_NO_EXPORT QString KMPlayerVCDSource::prettyName () {
1731     return i18n ("VCD");
1732 }
1733 
1734 static const char * strPlayVCD = "Immediately Play VCD";
1735 
1736 KDE_NO_EXPORT void KMPlayerVCDSource::write (KSharedConfigPtr config) {
1737     KConfigGroup (config, strMPlayerGroup).writeEntry (strPlayVCD, m_auto_play);
1738 }
1739 
1740 KDE_NO_EXPORT void KMPlayerVCDSource::read (KSharedConfigPtr config) {
1741     m_auto_play = KConfigGroup (config, strMPlayerGroup).readEntry (strPlayVCD, true);
1742 }
1743 
1744 KDE_NO_EXPORT void KMPlayerVCDSource::sync (bool fromUI) {
1745     if (fromUI) {
1746         m_auto_play = m_configpage->autoPlayVCD->isChecked ();
1747         m_player->settings ()->vcddevice = m_configpage->vcddevice->lineEdit()->text ();
1748     } else {
1749         m_configpage->autoPlayVCD->setChecked (m_auto_play);
1750         m_configpage->vcddevice->lineEdit()->setText (m_player->settings ()->vcddevice);
1751     }
1752 }
1753 
1754 KDE_NO_EXPORT void KMPlayerVCDSource::prefLocation (QString & item, QString & icon, QString & tab) {
1755     item = i18n ("Source");
1756     icon = QString ("source");
1757     tab = i18n ("VCD");
1758 }
1759 
1760 KDE_NO_EXPORT QFrame * KMPlayerVCDSource::prefPage (QWidget * parent) {
1761     m_configpage = new KMPlayerPrefSourcePageVCD (parent);
1762     return m_configpage;
1763 }
1764 
1765 //-----------------------------------------------------------------------------
1766 
1767 KDE_NO_CDTOR_EXPORT KMPlayerAudioCDSource::KMPlayerAudioCDSource(KMPlayerApp* a)
1768     : KMPlayer::Source(i18n("Audio CD"), a->player(), "audiocdsource"), m_app(a) {
1769     setUrl ("cdda://");
1770 }
1771 
1772 KDE_NO_CDTOR_EXPORT KMPlayerAudioCDSource::~KMPlayerAudioCDSource () {
1773 }
1774 
1775 KDE_NO_EXPORT bool KMPlayerAudioCDSource::processOutput (const QString & str) {
1776     if (KMPlayer::Source::processOutput (str))
1777         return true;
1778     if (m_identified)
1779         return false;
1780     //kDebug () << "scanning " << str;
1781     QRegExp * patterns = static_cast <KMPlayer::MPlayerPreferencesPage *> (m_player->mediaManager ()->processInfos () ["mplayer"]->config_page)->m_patterns;
1782     QRegExp & trackRegExp = patterns [KMPlayer::MPlayerPreferencesPage::pat_cdromtracks];
1783     if (trackRegExp.indexIn(str) > -1) {
1784         //if (m_document->state != KMPlayer::Element::state_deferred)
1785         //    m_document->defer ();
1786         int nt = trackRegExp.cap (1).toInt ();
1787         kDebug () << "tracks " << trackRegExp.cap (1);
1788         for (int i = 0; i < nt; i++)
1789             m_document->appendChild (new KMPlayer::GenericMrl (m_document, QString ("cdda://%1").arg (i+1), i18n ("Track %1",QString::number(i+1))));
1790         return true;
1791     }
1792     return false;
1793 }
1794 
1795 KDE_NO_EXPORT void KMPlayerAudioCDSource::activate () {
1796     m_player->stop ();
1797     init ();
1798     //m_start_play = m_auto_play;
1799     setUrl ("cdda://");
1800     //if (m_start_play)
1801         QTimer::singleShot (0, m_player, SLOT (play ()));
1802 }
1803 
1804 KDE_NO_EXPORT void KMPlayerAudioCDSource::deactivate () {
1805 }
1806 
1807 KDE_NO_EXPORT void KMPlayerAudioCDSource::setIdentified (bool b) {
1808     KMPlayer::Source::setIdentified (b);
1809     setCurrent (!m_current || !m_document->hasChildNodes ()
1810             ? m_document->mrl () : m_current->mrl ());
1811     if (m_current == m_document && m_document->hasChildNodes ()) {
1812         //m_back_request = m_document->firstChild ();
1813         //m_player->process ()->stop ();
1814     }
1815     m_player->updateTree ();
1816     //if (m_current->state == KMPlayer::Element::state_deferred)
1817     //    m_current->undefer ();
1818     m_app->slotStatusMsg (i18n ("Ready."));
1819 }
1820 
1821 KDE_NO_EXPORT void KMPlayerAudioCDSource::setCurrent (KMPlayer::Mrl *cur) {
1822     KMPlayer::Source::setCurrent (cur);
1823     QString url ("cdda://");
1824     if (m_current && m_current != m_document)
1825         url += m_current->mrl ()->src;
1826     m_options = "-cdda speed=3";
1827     if (m_player->settings ()->vcddevice.size () > 0)
1828         m_options+=QString(" -cdrom-device ") + m_player->settings()->vcddevice;
1829     m_recordcmd = m_options;
1830 }
1831 
1832 KDE_NO_EXPORT QString KMPlayerAudioCDSource::prettyName () {
1833     return i18n ("Audio CD");
1834 }
1835 
1836 //-----------------------------------------------------------------------------
1837 
1838 KDE_NO_CDTOR_EXPORT KMPlayerPipeSource::KMPlayerPipeSource (KMPlayerApp * a)
1839  : KMPlayer::Source (i18n ("Pipe"), a->player (), "pipesource"), m_app (a) {
1840 }
1841 
1842 KDE_NO_CDTOR_EXPORT KMPlayerPipeSource::~KMPlayerPipeSource () {
1843 }
1844 
1845 KDE_NO_EXPORT bool KMPlayerPipeSource::hasLength () {
1846     return false;
1847 }
1848 
1849 KDE_NO_EXPORT bool KMPlayerPipeSource::isSeekable () {
1850     return false;
1851 }
1852 
1853 KDE_NO_EXPORT void KMPlayerPipeSource::activate () {
1854     // dangerous !! if (!m_url.protocol ().compare ("kmplayer"))
1855     //    m_pipecmd = KUrl::decode_string (m_url.path ()).mid (1);
1856     setUrl ("stdin://");
1857     KMPlayer::GenericMrl * gen = new KMPlayer::GenericMrl (m_document, QString ("stdin://"), m_pipecmd);
1858     gen->bookmarkable = false;
1859     m_document->appendChild (gen);
1860     m_recordcmd = m_options = QString ("-"); // or m_url?
1861     m_identified = true;
1862     reset ();
1863     QTimer::singleShot (0, m_player, SLOT (play ()));
1864     m_app->slotStatusMsg (i18n ("Ready."));
1865 }
1866 
1867 KDE_NO_EXPORT void KMPlayerPipeSource::deactivate () {
1868 }
1869 
1870 KDE_NO_EXPORT QString KMPlayerPipeSource::prettyName () {
1871     return i18n ("Pipe - %1",m_pipecmd);
1872 }
1873 
1874 KDE_NO_EXPORT void KMPlayerPipeSource::setCommand (const QString & cmd) {
1875     m_pipecmd = cmd;
1876     if (m_document)
1877         m_document->mrl ()->title = cmd;
1878 }
1879 
1880 #include "kmplayer.moc"