1 #include "MainWindow.h"
4 #include "iconloader/qticonloader.h"
6 #include "videodefinition.h"
8 #include "globalshortcuts.h"
10 #include "gnomeglobalshortcutbackend.h"
13 // #include "local/mac/mac_startup.h"
15 #include "downloadmanager.h"
17 MainWindow::MainWindow() :
25 history = new QStack<QWidget*>();
26 views = new QStackedWidget(this);
27 setCentralWidget(views);
30 searchView = new SearchView(this);
31 connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
32 views->addWidget(searchView);
34 mediaView = new MediaView(this);
35 views->addWidget(mediaView);
37 toolbarSearch = new SearchLineEdit(this);
38 toolbarSearch->setMinimumWidth(toolbarSearch->fontInfo().pixelSize()*15);
39 connect(toolbarSearch, SIGNAL(search(const QString&)), searchView, SLOT(watch(const QString&)));
48 mediaView->setMediaObject(mediaObject);
50 // remove that useless menu/toolbar context menu
51 this->setContextMenuPolicy(Qt::NoContextMenu);
53 // mediaView init stuff thats needs actions
54 mediaView->initialize();
56 // event filter to block ugly toolbar tooltips
57 qApp->installEventFilter(this);
59 // restore window position
62 // show the initial view
63 showWidget(searchView);
66 GlobalShortcuts &shortcuts = GlobalShortcuts::instance();
68 if (GnomeGlobalShortcutBackend::IsGsdAvailable())
69 shortcuts.setBackend(new GnomeGlobalShortcutBackend(&shortcuts));
74 connect(&shortcuts, SIGNAL(PlayPause()), pauseAct, SLOT(trigger()));
75 connect(&shortcuts, SIGNAL(Stop()), this, SLOT(stop()));
76 connect(&shortcuts, SIGNAL(Next()), skipAct, SLOT(trigger()));
78 connect(DownloadManager::instance(), SIGNAL(statusMessageChanged(QString)),
79 SLOT(updateDownloadMessage(QString)));
80 connect(DownloadManager::instance(), SIGNAL(finished()),
81 SLOT(downloadsFinished()));
84 MainWindow::~MainWindow() {
88 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
89 if (event->type() == QEvent::ToolTip) {
93 // standard event processing
94 return QObject::eventFilter(obj, event);
98 void MainWindow::createActions() {
100 QMap<QString, QAction*> *actions = The::globalActions();
102 stopAct = new QAction(QtIconLoader::icon("media-playback-stop"), tr("&Stop"), this);
103 stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
104 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
105 stopAct->setEnabled(false);
106 actions->insert("stop", stopAct);
107 connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
109 skipAct = new QAction(QtIconLoader::icon("media-skip-forward"), tr("S&kip"), this);
110 skipAct->setStatusTip(tr("Skip to the next video"));
111 skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
112 skipAct->setEnabled(false);
113 actions->insert("skip", skipAct);
114 connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
116 pauseAct = new QAction(QtIconLoader::icon("media-playback-pause"), tr("&Pause"), this);
117 pauseAct->setStatusTip(tr("Pause playback"));
118 pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
119 pauseAct->setEnabled(false);
120 actions->insert("pause", pauseAct);
121 connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
123 fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen"), tr("&Full Screen"), this);
124 fullscreenAct->setStatusTip(tr("Go full screen"));
125 fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
126 fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
127 #if QT_VERSION >= 0x040600
128 fullscreenAct->setPriority(QAction::LowPriority);
130 actions->insert("fullscreen", fullscreenAct);
131 connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
133 compactViewAct = new QAction(tr("&Compact mode"), this);
134 compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
135 compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
136 compactViewAct->setCheckable(true);
137 compactViewAct->setChecked(false);
138 compactViewAct->setEnabled(false);
139 actions->insert("compactView", compactViewAct);
140 connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
142 webPageAct = new QAction(tr("Open the &YouTube page"), this);
143 webPageAct->setStatusTip(tr("Go to the YouTube video page and pause playback"));
144 webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
145 webPageAct->setEnabled(false);
146 actions->insert("webpage", webPageAct);
147 connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
149 copyPageAct = new QAction(tr("Copy the YouTube &link"), this);
150 copyPageAct->setStatusTip(tr("Copy the current video YouTube link to the clipboard"));
151 copyPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
152 copyPageAct->setEnabled(false);
153 actions->insert("pagelink", copyPageAct);
154 connect(copyPageAct, SIGNAL(triggered()), mediaView, SLOT(copyWebPage()));
156 copyLinkAct = new QAction(tr("Copy the video stream &URL"), this);
157 copyLinkAct->setStatusTip(tr("Copy the current video stream URL to the clipboard"));
158 copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
159 copyLinkAct->setEnabled(false);
160 actions->insert("videolink", copyLinkAct);
161 connect(copyLinkAct, SIGNAL(triggered()), mediaView, SLOT(copyVideoLink()));
163 removeAct = new QAction(tr("&Remove"), this);
164 removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
165 removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
166 removeAct->setEnabled(false);
167 actions->insert("remove", removeAct);
168 connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
170 moveUpAct = new QAction(tr("Move &Up"), this);
171 moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
172 moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
173 moveUpAct->setEnabled(false);
174 actions->insert("moveUp", moveUpAct);
175 connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
177 moveDownAct = new QAction(tr("Move &Down"), this);
178 moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
179 moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
180 moveDownAct->setEnabled(false);
181 actions->insert("moveDown", moveDownAct);
182 connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
184 clearAct = new QAction(tr("&Clear recent keywords"), this);
185 clearAct->setMenuRole(QAction::ApplicationSpecificRole);
186 clearAct->setShortcuts(QList<QKeySequence>()
187 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete)
188 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
189 clearAct->setStatusTip(tr("Clear the search history. Cannot be undone."));
190 clearAct->setEnabled(true);
191 actions->insert("clearRecentKeywords", clearAct);
192 connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
194 quitAct = new QAction(tr("&Quit"), this);
195 quitAct->setMenuRole(QAction::QuitRole);
196 quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
197 quitAct->setStatusTip(tr("Bye"));
198 actions->insert("quit", quitAct);
199 connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
201 siteAct = new QAction(tr("&Website"), this);
202 siteAct->setShortcut(QKeySequence::HelpContents);
203 siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
204 actions->insert("site", siteAct);
205 connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
207 donateAct = new QAction(tr("Make a &donation"), this);
208 donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
209 actions->insert("donate", donateAct);
210 connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
212 aboutAct = new QAction(tr("&About"), this);
213 aboutAct->setMenuRole(QAction::AboutRole);
214 aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
215 actions->insert("about", aboutAct);
216 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
220 searchFocusAct = new QAction(this);
221 searchFocusAct->setShortcut(QKeySequence::Find);
222 searchFocusAct->setStatusTip(tr("Search"));
223 actions->insert("search", searchFocusAct);
224 connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
225 addAction(searchFocusAct);
227 volumeUpAct = new QAction(this);
228 volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
229 actions->insert("volume-up", volumeUpAct);
230 connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
231 addAction(volumeUpAct);
233 volumeDownAct = new QAction(this);
234 volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
235 actions->insert("volume-down", volumeDownAct);
236 connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
237 addAction(volumeDownAct);
239 volumeMuteAct = new QAction(this);
240 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
241 volumeMuteAct->setStatusTip(tr("Mute volume"));
242 volumeMuteAct->setShortcuts(QList<QKeySequence>()
243 << QKeySequence(tr("Ctrl+M"))
244 << QKeySequence(Qt::Key_VolumeMute));
245 actions->insert("volume-mute", volumeMuteAct);
246 connect(volumeMuteAct, SIGNAL(triggered()), SLOT(volumeMute()));
247 addAction(volumeMuteAct);
249 QAction *definitionAct = new QAction(this);
250 definitionAct->setIcon(QtIconLoader::icon("video-display"));
251 definitionAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
253 QMenu *definitionMenu = new QMenu(this);
254 foreach (QString definition, VideoDefinition::getDefinitionNames()) {
255 definitionMenu->addAction(definition);
257 definitionAct->setMenu(definitionMenu);
259 actions->insert("definition", definitionAct);
260 connect(definitionAct, SIGNAL(triggered()), SLOT(toggleDefinitionMode()));
261 addAction(definitionAct);
266 action = new QAction(tr("&Autoplay"), this);
267 action->setStatusTip(tr("Automatically start playing videos"));
268 action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
269 action->setCheckable(true);
270 connect(action, SIGNAL(toggled(bool)), SLOT(setAutoplay(bool)));
271 actions->insert("autoplay", action);
274 action = new QAction(tr("&Downloads"), this);
275 action->setStatusTip(tr("Show details about video downloads"));
276 action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_J));
277 action->setCheckable(true);
278 action->setIcon(QtIconLoader::icon("go-down"));
279 action->setVisible(false);
280 connect(action, SIGNAL(toggled(bool)), SLOT(toggleDownloads(bool)));
281 actions->insert("downloads", action);
283 action = new QAction(tr("&Download"), this);
284 action->setStatusTip(tr("Download the current video"));
285 action->setShortcut(QKeySequence::Save);
286 action->setIcon(QtIconLoader::icon("go-down"));
287 action->setEnabled(false);
288 #if QT_VERSION >= 0x040600
289 action->setPriority(QAction::LowPriority);
291 connect(action, SIGNAL(triggered()), mediaView, SLOT(downloadVideo()));
292 actions->insert("download", action);
294 // common action properties
295 foreach (QAction *action, actions->values()) {
297 // add actions to the MainWindow so that they work
298 // when the menu is hidden
302 // unexperienced users tend to keep keys pressed for a "long" time
303 action->setAutoRepeat(false);
305 // set to something more meaningful then the toolbar text
306 // HELP! how to remove tooltips altogether?!
307 if (!action->statusTip().isEmpty())
308 action->setToolTip(action->statusTip());
310 // show keyboard shortcuts in the status bar
311 if (!action->shortcut().isEmpty())
312 action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
315 action->setIconVisibleInMenu(false);
321 void MainWindow::createMenus() {
323 QMap<QString, QMenu*> *menus = The::globalMenus();
325 fileMenu = menuBar()->addMenu(tr("&Application"));
326 // menus->insert("file", fileMenu);
327 fileMenu->addAction(clearAct);
329 fileMenu->addSeparator();
331 fileMenu->addAction(quitAct);
333 playlistMenu = menuBar()->addMenu(tr("&Playlist"));
334 menus->insert("playlist", playlistMenu);
335 playlistMenu->addAction(removeAct);
336 playlistMenu->addSeparator();
337 playlistMenu->addAction(moveUpAct);
338 playlistMenu->addAction(moveDownAct);
340 viewMenu = menuBar()->addMenu(tr("&Video"));
341 menus->insert("video", viewMenu);
342 viewMenu->addAction(stopAct);
343 viewMenu->addAction(pauseAct);
344 viewMenu->addAction(skipAct);
345 viewMenu->addSeparator();
346 viewMenu->addAction(The::globalActions()->value("download"));
347 viewMenu->addSeparator();
348 viewMenu->addAction(webPageAct);
349 viewMenu->addAction(copyPageAct);
350 viewMenu->addAction(copyLinkAct);
351 viewMenu->addSeparator();
352 viewMenu->addAction(compactViewAct);
353 viewMenu->addAction(fullscreenAct);
355 extern void qt_mac_set_dock_menu(QMenu *);
356 qt_mac_set_dock_menu(viewMenu);
359 helpMenu = menuBar()->addMenu(tr("&Help"));
360 helpMenu->addAction(siteAct);
361 helpMenu->addAction(donateAct);
362 helpMenu->addAction(aboutAct);
365 void MainWindow::createToolBars() {
367 setUnifiedTitleAndToolBarOnMac(true);
369 mainToolBar = new QToolBar(this);
370 #if QT_VERSION < 0x040600 | defined(APP_MAC)
371 mainToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
373 mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
375 mainToolBar->setFloatable(false);
376 mainToolBar->setMovable(false);
379 mainToolBar->setIconSize(QSize(32, 32));
382 mainToolBar->addAction(stopAct);
383 mainToolBar->addAction(pauseAct);
384 mainToolBar->addAction(skipAct);
385 mainToolBar->addAction(fullscreenAct);
386 mainToolBar->addAction(The::globalActions()->value("download"));
388 mainToolBar->addWidget(new Spacer());
390 QFont smallerFont = FontUtils::small();
391 currentTime = new QLabel(mainToolBar);
392 currentTime->setFont(smallerFont);
393 mainToolBar->addWidget(currentTime);
395 mainToolBar->addWidget(new Spacer());
397 seekSlider = new Phonon::SeekSlider(this);
398 seekSlider->setIconVisible(false);
399 seekSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
400 mainToolBar->addWidget(seekSlider);
402 mainToolBar->addWidget(new Spacer());
404 totalTime = new QLabel(mainToolBar);
405 totalTime->setFont(smallerFont);
406 mainToolBar->addWidget(totalTime);
408 mainToolBar->addWidget(new Spacer());
410 mainToolBar->addAction(volumeMuteAct);
412 volumeSlider = new Phonon::VolumeSlider(this);
413 volumeSlider->setMuteVisible(false);
414 // qDebug() << volumeSlider->children();
415 // status tip for the volume slider
416 QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
418 volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
419 volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
420 // this makes the volume slider smaller
421 volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
422 mainToolBar->addWidget(volumeSlider);
424 mainToolBar->addWidget(new Spacer());
426 toolbarSearch->setStatusTip(searchFocusAct->statusTip());
427 mainToolBar->addWidget(toolbarSearch);
429 mainToolBar->addWidget(new Spacer());
431 addToolBar(mainToolBar);
434 void MainWindow::createStatusBar() {
436 // remove ugly borders on OSX
437 // also remove excessive spacing
438 statusBar()->setStyleSheet("::item{border:0 solid} QToolBar {padding:0;spacing:0;margin:0}");
440 QToolBar *toolBar = new QToolBar(this);
441 toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
442 toolBar->setIconSize(QSize(16, 16));
443 toolBar->addAction(The::globalActions()->value("downloads"));
444 // toolBar->addAction(The::globalActions()->value("autoplay"));
445 toolBar->addAction(The::globalActions()->value("definition"));
446 statusBar()->addPermanentWidget(toolBar);
451 void MainWindow::readSettings() {
453 restoreGeometry(settings.value("geometry").toByteArray());
456 move(x(), y() + mainToolBar->height() + 8);
458 setDefinitionMode(settings.value("definition", VideoDefinition::getDefinitionNames().first()).toString());
459 audioOutput->setVolume(settings.value("volume", 1).toDouble());
460 audioOutput->setMuted(settings.value("volumeMute").toBool());
463 void MainWindow::writeSettings() {
467 // do not save geometry when in full screen
469 settings.setValue("geometry", saveGeometry());
472 settings.setValue("volume", audioOutput->volume());
473 settings.setValue("volumeMute", audioOutput->isMuted());
474 mediaView->saveSplitterState();
477 void MainWindow::goBack() {
478 if ( history->size() > 1 ) {
480 QWidget *widget = history->pop();
485 void MainWindow::showWidget ( QWidget* widget ) {
487 setUpdatesEnabled(false);
489 // call hide method on the current view
490 View* oldView = dynamic_cast<View *> (views->currentWidget());
492 oldView->disappear();
495 // call show method on the new view
496 View* newView = dynamic_cast<View *> (widget);
499 QMap<QString,QVariant> metadata = newView->metadata();
500 QString windowTitle = metadata.value("title").toString();
501 if (windowTitle.length())
502 windowTitle += " - ";
503 setWindowTitle(windowTitle + Constants::APP_NAME);
504 statusBar()->showMessage((metadata.value("description").toString()));
507 stopAct->setEnabled(widget == mediaView);
508 fullscreenAct->setEnabled(widget == mediaView);
509 compactViewAct->setEnabled(widget == mediaView);
510 webPageAct->setEnabled(widget == mediaView);
511 copyPageAct->setEnabled(widget == mediaView);
512 copyLinkAct->setEnabled(widget == mediaView);
513 aboutAct->setEnabled(widget != aboutView);
514 The::globalActions()->value("download")->setEnabled(widget == mediaView);
515 The::globalActions()->value("downloads")->setChecked(widget == downloadView);
517 // toolbar only for the mediaView
518 /* mainToolBar->setVisible(
519 (widget == mediaView && !compactViewAct->isChecked())
520 || widget == downloadView
523 setUpdatesEnabled(true);
525 QWidget *oldWidget = views->currentWidget();
526 views->setCurrentWidget(widget);
529 // crossfade only on OSX
530 // where we can be sure of video performance
531 fadeInWidget(oldWidget, widget);
534 history->push(widget);
537 void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
538 if (faderWidget) faderWidget->close();
539 if (!oldWidget || !newWidget) {
540 // qDebug() << "no widgets";
543 faderWidget = new FaderWidget(newWidget);
544 faderWidget->start(QPixmap::grabWidget(oldWidget));
547 void MainWindow::about() {
549 aboutView = new AboutView(this);
550 views->addWidget(aboutView);
552 showWidget(aboutView);
555 void MainWindow::visitSite() {
556 QUrl url(Constants::WEBSITE);
557 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
558 QDesktopServices::openUrl(url);
561 void MainWindow::donate() {
562 QUrl url(QString(Constants::WEBSITE) + "#donate");
563 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
564 QDesktopServices::openUrl(url);
567 void MainWindow::quit() {
572 void MainWindow::closeEvent(QCloseEvent *event) {
573 if (DownloadManager::instance()->activeItems() > 0) {
575 msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
576 msgBox.setText(tr("Do you want to exit %1 with a download in progress?").arg(Constants::APP_NAME));
577 msgBox.setInformativeText(tr("If you close %1 now, this download will be cancelled.").arg(Constants::APP_NAME));
578 msgBox.setModal(true);
580 msgBox.addButton(tr("Close and cancel download"), QMessageBox::RejectRole);
581 QPushButton *waitButton = msgBox.addButton(tr("Wait for download to finish"), QMessageBox::ActionRole);
585 if (msgBox.clickedButton() == waitButton) {
592 QWidget::closeEvent(event);
595 void MainWindow::showSearch() {
596 showWidget(searchView);
597 currentTime->clear();
601 void MainWindow::showMedia(QString query) {
602 SearchParams *searchParams = new SearchParams();
603 searchParams->setKeywords(query);
604 mediaView->search(searchParams);
605 showWidget(mediaView);
608 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
610 // qDebug() << "Phonon state: " << newState;
614 case Phonon::ErrorState:
615 if (mediaObject->errorType() == Phonon::FatalError) {
616 statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
618 statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
622 case Phonon::PlayingState:
623 pauseAct->setEnabled(true);
624 pauseAct->setIcon(QtIconLoader::icon("media-playback-pause"));
625 pauseAct->setText(tr("&Pause"));
626 pauseAct->setStatusTip(tr("Pause playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
627 skipAct->setEnabled(true);
628 // stopAct->setEnabled(true);
631 case Phonon::StoppedState:
632 pauseAct->setEnabled(false);
633 skipAct->setEnabled(false);
634 // stopAct->setEnabled(false);
637 case Phonon::PausedState:
638 skipAct->setEnabled(true);
639 pauseAct->setEnabled(true);
640 pauseAct->setIcon(QtIconLoader::icon("media-playback-start"));
641 pauseAct->setText(tr("&Play"));
642 pauseAct->setStatusTip(tr("Resume playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
643 // stopAct->setEnabled(true);
646 case Phonon::BufferingState:
647 case Phonon::LoadingState:
648 skipAct->setEnabled(true);
649 pauseAct->setEnabled(false);
650 currentTime->clear();
652 // stopAct->setEnabled(true);
660 void MainWindow::stop() {
665 void MainWindow::fullscreen() {
667 // No compact view action when in full screen
668 compactViewAct->setVisible(m_fullscreen);
669 compactViewAct->setChecked(false);
671 // Also no Youtube action since it opens a new window
672 webPageAct->setVisible(m_fullscreen);
673 copyPageAct->setVisible(m_fullscreen);
674 copyLinkAct->setVisible(m_fullscreen);
676 stopAct->setVisible(m_fullscreen);
678 // workaround: prevent focus on the search bar
679 // it steals the Space key needed for Play/Pause
680 toolbarSearch->setEnabled(m_fullscreen);
682 // Hide anything but the video
683 mediaView->setPlaylistVisible(m_fullscreen);
684 statusBar()->setVisible(m_fullscreen);
687 menuBar()->setVisible(m_fullscreen);
691 // make the actions work when video is fullscreen (on the Mac)
692 QMap<QString, QAction*> *actions = The::globalActions();
693 foreach (QAction *action, actions->values()) {
695 action->setShortcutContext(Qt::WindowShortcut);
697 action->setShortcutContext(Qt::ApplicationShortcut);
706 // use setShortcuts instead of setShortcut
707 // the latter seems not to work
708 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
709 fullscreenAct->setText(tr("&Full Screen"));
710 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
713 setCentralWidget(views);
716 mediaView->setFocus();
719 if (m_maximized) showMaximized();
723 // Make sure the window has focus
730 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
731 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
732 fullscreenAct->setText(tr("Exit &Full Screen"));
733 m_maximized = isMaximized();
735 // save geometry now, if the user quits when in full screen
736 // geometry won't be saved
742 QTimer::singleShot(0, views, SLOT(showFullScreen()));
750 m_fullscreen = !m_fullscreen;
754 void MainWindow::compactView(bool enable) {
756 mediaView->setPlaylistVisible(!enable);
757 statusBar()->setVisible(!enable);
760 menuBar()->setVisible(!enable);
764 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
765 compactViewAct->setShortcuts(
766 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Return)
767 << QKeySequence(Qt::Key_Escape));
769 // ensure focus does not end up to the search box
770 // as it would steal the Space shortcut
771 mediaView->setFocus();
773 compactViewAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Return));
774 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
779 void MainWindow::searchFocus() {
780 QWidget *view = views->currentWidget();
781 if (view == mediaView) {
782 toolbarSearch->selectAll();
783 toolbarSearch->setFocus();
787 void MainWindow::initPhonon() {
788 // Phonon initialization
789 if (mediaObject) delete mediaObject;
790 if (audioOutput) delete audioOutput;
791 mediaObject = new Phonon::MediaObject(this);
792 mediaObject->setTickInterval(100);
793 connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
794 this, SLOT(stateChanged(Phonon::State, Phonon::State)));
795 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
796 connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
797 seekSlider->setMediaObject(mediaObject);
798 audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
799 connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
800 connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
801 volumeSlider->setAudioOutput(audioOutput);
802 Phonon::createPath(mediaObject, audioOutput);
805 void MainWindow::tick(qint64 time) {
807 currentTime->clear();
811 currentTime->setText(formatTime(time));
814 const qint64 remainingTime = mediaObject->remainingTime();
815 currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
819 void MainWindow::totalTimeChanged(qint64 time) {
824 totalTime->setText(formatTime(time));
827 QString MainWindow::formatTime(qint64 time) {
829 displayTime = displayTime.addMSecs(time);
831 // 60 * 60 * 1000 = 3600000
833 timeString = displayTime.toString("h:mm:ss");
835 timeString = displayTime.toString("m:ss");
839 void MainWindow::volumeUp() {
840 qreal newVolume = volumeSlider->audioOutput()->volume() + .1;
841 if (newVolume > volumeSlider->maximumVolume())
842 newVolume = volumeSlider->maximumVolume();
843 volumeSlider->audioOutput()->setVolume(newVolume);
846 void MainWindow::volumeDown() {
847 qreal newVolume = volumeSlider->audioOutput()->volume() - .1;
850 volumeSlider->audioOutput()->setVolume(newVolume);
853 void MainWindow::volumeMute() {
854 volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
857 void MainWindow::volumeChanged(qreal newVolume) {
858 // automatically unmute when volume changes
859 if (volumeSlider->audioOutput()->isMuted())
860 volumeSlider->audioOutput()->setMuted(false);
861 statusBar()->showMessage(tr("Volume at %1%").arg(newVolume*100));
864 void MainWindow::volumeMutedChanged(bool muted) {
866 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-muted"));
867 statusBar()->showMessage(tr("Volume is muted"));
869 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
870 statusBar()->showMessage(tr("Volume is unmuted"));
874 void MainWindow::setDefinitionMode(QString definitionName) {
875 QAction *definitionAct = The::globalActions()->value("definition");
876 definitionAct->setText(definitionName);
877 definitionAct->setStatusTip(tr("Maximum video definition set to %1").arg(definitionAct->text())
878 + " (" + definitionAct->shortcut().toString(QKeySequence::NativeText) + ")");
879 statusBar()->showMessage(definitionAct->statusTip());
881 settings.setValue("definition", definitionName);
884 void MainWindow::toggleDefinitionMode() {
886 QString currentDefinition = settings.value("definition").toString();
887 QStringList definitionNames = VideoDefinition::getDefinitionNames();
888 int currentIndex = definitionNames.indexOf(currentDefinition);
890 if (currentIndex != definitionNames.size() - 1) {
891 nextIndex = currentIndex + 1;
893 QString nextDefinition = definitionNames.at(nextIndex);
894 setDefinitionMode(nextDefinition);
897 void MainWindow::showFullscreenToolbar(bool show) {
898 if (!m_fullscreen) return;
899 mainToolBar->setVisible(show);
902 void MainWindow::showFullscreenPlaylist(bool show) {
903 if (!m_fullscreen) return;
904 mediaView->setPlaylistVisible(show);
907 void MainWindow::clearRecentKeywords() {
909 settings.remove("recentKeywords");
910 searchView->updateRecentKeywords();
911 statusBar()->showMessage(tr("Your privacy is now safe"));
915 void MainWindow::setAutoplay(bool enabled) {
917 settings.setValue("autoplay", QVariant::fromValue(enabled));
921 void MainWindow::updateDownloadMessage(QString message) {
922 The::globalActions()->value("downloads")->setText(message);
925 void MainWindow::downloadsFinished() {
926 The::globalActions()->value("downloads")->setText(tr("&Downloads"));
927 statusBar()->showMessage(tr("Downloads complete"));
930 void MainWindow::toggleDownloads(bool show) {
933 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
934 The::globalActions()->value("downloads")->setShortcuts(
935 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J)
936 << QKeySequence(Qt::Key_Escape));
938 The::globalActions()->value("downloads")->setShortcuts(
939 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J));
940 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
944 downloadView = new DownloadView(this);
945 views->addWidget(downloadView);
947 if (show) showWidget(downloadView);