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->setSlider(slider);
49 mediaView->setMediaObject(mediaObject);
51 // remove that useless menu/toolbar context menu
52 this->setContextMenuPolicy(Qt::NoContextMenu);
54 // mediaView init stuff thats needs actions
55 mediaView->initialize();
57 // event filter to block ugly toolbar tooltips
58 qApp->installEventFilter(this);
60 // restore window position
63 // show the initial view
64 showWidget(searchView);
67 GlobalShortcuts &shortcuts = GlobalShortcuts::instance();
69 if (GnomeGlobalShortcutBackend::IsGsdAvailable())
70 shortcuts.setBackend(new GnomeGlobalShortcutBackend(&shortcuts));
75 connect(&shortcuts, SIGNAL(PlayPause()), pauseAct, SLOT(trigger()));
76 connect(&shortcuts, SIGNAL(Stop()), this, SLOT(stop()));
77 connect(&shortcuts, SIGNAL(Next()), skipAct, SLOT(trigger()));
79 connect(DownloadManager::instance(), SIGNAL(statusMessageChanged(QString)),
80 SLOT(updateDownloadMessage(QString)));
81 connect(DownloadManager::instance(), SIGNAL(finished()),
82 SLOT(downloadsFinished()));
85 MainWindow::~MainWindow() {
89 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
90 if (event->type() == QEvent::ToolTip) {
94 // standard event processing
95 return QObject::eventFilter(obj, event);
99 void MainWindow::createActions() {
101 QMap<QString, QAction*> *actions = The::globalActions();
103 stopAct = new QAction(QtIconLoader::icon("media-playback-stop"), tr("&Stop"), this);
104 stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
105 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
106 stopAct->setEnabled(false);
107 actions->insert("stop", stopAct);
108 connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
110 skipAct = new QAction(QtIconLoader::icon("media-skip-forward"), tr("S&kip"), this);
111 skipAct->setStatusTip(tr("Skip to the next video"));
112 skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
113 skipAct->setEnabled(false);
114 actions->insert("skip", skipAct);
115 connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
117 pauseAct = new QAction(QtIconLoader::icon("media-playback-pause"), tr("&Pause"), this);
118 pauseAct->setStatusTip(tr("Pause playback"));
119 pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
120 pauseAct->setEnabled(false);
121 actions->insert("pause", pauseAct);
122 connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
124 fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen"), tr("&Full Screen"), this);
125 fullscreenAct->setStatusTip(tr("Go full screen"));
126 fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
127 fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
128 #if QT_VERSION >= 0x040600
129 fullscreenAct->setPriority(QAction::LowPriority);
131 actions->insert("fullscreen", fullscreenAct);
132 connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
134 compactViewAct = new QAction(tr("&Compact mode"), this);
135 compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
136 compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
137 compactViewAct->setCheckable(true);
138 compactViewAct->setChecked(false);
139 compactViewAct->setEnabled(false);
140 actions->insert("compactView", compactViewAct);
141 connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
143 webPageAct = new QAction(tr("Open the &YouTube page"), this);
144 webPageAct->setStatusTip(tr("Go to the YouTube video page and pause playback"));
145 webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
146 webPageAct->setEnabled(false);
147 actions->insert("webpage", webPageAct);
148 connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
150 copyPageAct = new QAction(tr("Copy the YouTube &link"), this);
151 copyPageAct->setStatusTip(tr("Copy the current video YouTube link to the clipboard"));
152 copyPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
153 copyPageAct->setEnabled(false);
154 actions->insert("pagelink", copyPageAct);
155 connect(copyPageAct, SIGNAL(triggered()), mediaView, SLOT(copyWebPage()));
157 copyLinkAct = new QAction(tr("Copy the video stream &URL"), this);
158 copyLinkAct->setStatusTip(tr("Copy the current video stream URL to the clipboard"));
159 copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
160 copyLinkAct->setEnabled(false);
161 actions->insert("videolink", copyLinkAct);
162 connect(copyLinkAct, SIGNAL(triggered()), mediaView, SLOT(copyVideoLink()));
164 removeAct = new QAction(tr("&Remove"), this);
165 removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
166 removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
167 removeAct->setEnabled(false);
168 actions->insert("remove", removeAct);
169 connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
171 moveUpAct = new QAction(tr("Move &Up"), this);
172 moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
173 moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
174 moveUpAct->setEnabled(false);
175 actions->insert("moveUp", moveUpAct);
176 connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
178 moveDownAct = new QAction(tr("Move &Down"), this);
179 moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
180 moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
181 moveDownAct->setEnabled(false);
182 actions->insert("moveDown", moveDownAct);
183 connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
185 clearAct = new QAction(tr("&Clear recent keywords"), this);
186 clearAct->setMenuRole(QAction::ApplicationSpecificRole);
187 clearAct->setShortcuts(QList<QKeySequence>()
188 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete)
189 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
190 clearAct->setStatusTip(tr("Clear the search history. Cannot be undone."));
191 clearAct->setEnabled(true);
192 actions->insert("clearRecentKeywords", clearAct);
193 connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
195 quitAct = new QAction(tr("&Quit"), this);
196 quitAct->setMenuRole(QAction::QuitRole);
197 quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
198 quitAct->setStatusTip(tr("Bye"));
199 actions->insert("quit", quitAct);
200 connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
202 siteAct = new QAction(tr("&Website"), this);
203 siteAct->setShortcut(QKeySequence::HelpContents);
204 siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
205 actions->insert("site", siteAct);
206 connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
208 donateAct = new QAction(tr("Make a &donation"), this);
209 donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
210 actions->insert("donate", donateAct);
211 connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
213 aboutAct = new QAction(tr("&About"), this);
214 aboutAct->setMenuRole(QAction::AboutRole);
215 aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
216 actions->insert("about", aboutAct);
217 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
221 searchFocusAct = new QAction(this);
222 searchFocusAct->setShortcut(QKeySequence::Find);
223 searchFocusAct->setStatusTip(tr("Search"));
224 actions->insert("search", searchFocusAct);
225 connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
226 addAction(searchFocusAct);
228 volumeUpAct = new QAction(this);
229 volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
230 actions->insert("volume-up", volumeUpAct);
231 connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
232 addAction(volumeUpAct);
234 volumeDownAct = new QAction(this);
235 volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
236 actions->insert("volume-down", volumeDownAct);
237 connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
238 addAction(volumeDownAct);
240 volumeMuteAct = new QAction(this);
241 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
242 volumeMuteAct->setStatusTip(tr("Mute volume"));
243 volumeMuteAct->setShortcuts(QList<QKeySequence>()
244 << QKeySequence(tr("Ctrl+M"))
245 << QKeySequence(Qt::Key_VolumeMute));
246 actions->insert("volume-mute", volumeMuteAct);
247 connect(volumeMuteAct, SIGNAL(triggered()), SLOT(volumeMute()));
248 addAction(volumeMuteAct);
250 QAction *definitionAct = new QAction(this);
251 definitionAct->setIcon(QtIconLoader::icon("video-display"));
252 definitionAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
254 QMenu *definitionMenu = new QMenu(this);
255 foreach (QString definition, VideoDefinition::getDefinitionNames()) {
256 definitionMenu->addAction(definition);
258 definitionAct->setMenu(definitionMenu);
260 actions->insert("definition", definitionAct);
261 connect(definitionAct, SIGNAL(triggered()), SLOT(toggleDefinitionMode()));
262 addAction(definitionAct);
267 action = new QAction(tr("&Autoplay"), this);
268 action->setStatusTip(tr("Automatically start playing videos"));
269 action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
270 action->setCheckable(true);
271 connect(action, SIGNAL(toggled(bool)), SLOT(setAutoplay(bool)));
272 actions->insert("autoplay", action);
275 action = new QAction(tr("&Downloads"), this);
276 action->setStatusTip(tr("Show details about video downloads"));
277 action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_J));
278 action->setCheckable(true);
279 action->setIcon(QtIconLoader::icon("go-down"));
280 action->setVisible(false);
281 connect(action, SIGNAL(toggled(bool)), SLOT(toggleDownloads(bool)));
282 actions->insert("downloads", action);
284 action = new QAction(tr("&Download"), this);
285 action->setStatusTip(tr("Download the current video"));
286 action->setShortcut(QKeySequence::Save);
287 action->setIcon(QtIconLoader::icon("go-down"));
288 action->setEnabled(false);
289 #if QT_VERSION >= 0x040600
290 action->setPriority(QAction::LowPriority);
292 connect(action, SIGNAL(triggered()), mediaView, SLOT(downloadVideo()));
293 actions->insert("download", action);
295 // common action properties
296 foreach (QAction *action, actions->values()) {
298 // add actions to the MainWindow so that they work
299 // when the menu is hidden
303 // unexperienced users tend to keep keys pressed for a "long" time
304 action->setAutoRepeat(false);
306 // set to something more meaningful then the toolbar text
307 // HELP! how to remove tooltips altogether?!
308 if (!action->statusTip().isEmpty())
309 action->setToolTip(action->statusTip());
311 // show keyboard shortcuts in the status bar
312 if (!action->shortcut().isEmpty())
313 action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
316 action->setIconVisibleInMenu(false);
322 void MainWindow::createMenus() {
324 QMap<QString, QMenu*> *menus = The::globalMenus();
326 fileMenu = menuBar()->addMenu(tr("&Application"));
327 // menus->insert("file", fileMenu);
328 fileMenu->addAction(clearAct);
330 fileMenu->addSeparator();
332 fileMenu->addAction(quitAct);
334 playlistMenu = menuBar()->addMenu(tr("&Playlist"));
335 menus->insert("playlist", playlistMenu);
336 playlistMenu->addAction(removeAct);
337 playlistMenu->addSeparator();
338 playlistMenu->addAction(moveUpAct);
339 playlistMenu->addAction(moveDownAct);
341 viewMenu = menuBar()->addMenu(tr("&Video"));
342 menus->insert("video", viewMenu);
343 viewMenu->addAction(stopAct);
344 viewMenu->addAction(pauseAct);
345 viewMenu->addAction(skipAct);
346 viewMenu->addSeparator();
347 viewMenu->addAction(The::globalActions()->value("download"));
348 viewMenu->addSeparator();
349 viewMenu->addAction(webPageAct);
350 viewMenu->addAction(copyPageAct);
351 viewMenu->addAction(copyLinkAct);
352 viewMenu->addSeparator();
353 viewMenu->addAction(compactViewAct);
354 viewMenu->addAction(fullscreenAct);
356 extern void qt_mac_set_dock_menu(QMenu *);
357 qt_mac_set_dock_menu(viewMenu);
360 helpMenu = menuBar()->addMenu(tr("&Help"));
361 helpMenu->addAction(siteAct);
362 helpMenu->addAction(donateAct);
363 helpMenu->addAction(aboutAct);
366 void MainWindow::createToolBars() {
368 setUnifiedTitleAndToolBarOnMac(true);
370 mainToolBar = new QToolBar(this);
371 #if QT_VERSION < 0x040600 | defined(APP_MAC)
372 mainToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
374 mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
376 mainToolBar->setFloatable(false);
377 mainToolBar->setMovable(false);
380 mainToolBar->setIconSize(QSize(32, 32));
383 mainToolBar->addAction(stopAct);
384 mainToolBar->addAction(pauseAct);
385 mainToolBar->addAction(skipAct);
386 mainToolBar->addAction(fullscreenAct);
387 mainToolBar->addAction(The::globalActions()->value("download"));
389 mainToolBar->addWidget(new Spacer());
391 QFont smallerFont = FontUtils::small();
392 currentTime = new QLabel(mainToolBar);
393 currentTime->setFont(smallerFont);
394 mainToolBar->addWidget(currentTime);
396 mainToolBar->addWidget(new Spacer());
398 seekSlider = new Phonon::SeekSlider(this);
400 seekSlider->setDisabled(true);
402 seekSlider->setIconVisible(false);
403 seekSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
404 mainToolBar->addWidget(seekSlider);
406 mainToolBar->addWidget(new Spacer());
409 slider = new QSlider(this);
410 slider->setOrientation(Qt::Horizontal);
411 slider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
412 mainToolBar->addWidget(slider);
415 mainToolBar->addWidget(new Spacer());
417 totalTime = new QLabel(mainToolBar);
418 totalTime->setFont(smallerFont);
419 mainToolBar->addWidget(totalTime);
421 mainToolBar->addWidget(new Spacer());
423 mainToolBar->addAction(volumeMuteAct);
425 volumeSlider = new Phonon::VolumeSlider(this);
426 volumeSlider->setMuteVisible(false);
427 // qDebug() << volumeSlider->children();
428 // status tip for the volume slider
429 QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
431 volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
432 volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
433 // this makes the volume slider smaller
434 volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
435 mainToolBar->addWidget(volumeSlider);
437 mainToolBar->addWidget(new Spacer());
439 toolbarSearch->setStatusTip(searchFocusAct->statusTip());
440 mainToolBar->addWidget(toolbarSearch);
442 mainToolBar->addWidget(new Spacer());
444 addToolBar(mainToolBar);
447 void MainWindow::createStatusBar() {
449 // remove ugly borders on OSX
450 // also remove excessive spacing
451 statusBar()->setStyleSheet("::item{border:0 solid} QToolBar {padding:0;spacing:0;margin:0}");
453 QToolBar *toolBar = new QToolBar(this);
454 toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
455 toolBar->setIconSize(QSize(16, 16));
456 toolBar->addAction(The::globalActions()->value("downloads"));
457 // toolBar->addAction(The::globalActions()->value("autoplay"));
458 toolBar->addAction(The::globalActions()->value("definition"));
459 statusBar()->addPermanentWidget(toolBar);
464 void MainWindow::readSettings() {
466 restoreGeometry(settings.value("geometry").toByteArray());
471 setDefinitionMode(settings.value("definition", VideoDefinition::getDefinitionNames().first()).toString());
472 audioOutput->setVolume(settings.value("volume", 1).toDouble());
473 audioOutput->setMuted(settings.value("volumeMute").toBool());
476 void MainWindow::writeSettings() {
480 // do not save geometry when in full screen
482 settings.setValue("geometry", saveGeometry());
485 settings.setValue("volume", audioOutput->volume());
486 settings.setValue("volumeMute", audioOutput->isMuted());
487 mediaView->saveSplitterState();
490 void MainWindow::goBack() {
491 if ( history->size() > 1 ) {
493 QWidget *widget = history->pop();
498 void MainWindow::showWidget ( QWidget* widget ) {
500 setUpdatesEnabled(false);
502 // call hide method on the current view
503 View* oldView = dynamic_cast<View *> (views->currentWidget());
505 oldView->disappear();
508 // call show method on the new view
509 View* newView = dynamic_cast<View *> (widget);
512 QMap<QString,QVariant> metadata = newView->metadata();
513 QString windowTitle = metadata.value("title").toString();
514 if (windowTitle.length())
515 windowTitle += " - ";
516 setWindowTitle(windowTitle + Constants::APP_NAME);
517 statusBar()->showMessage((metadata.value("description").toString()));
520 stopAct->setEnabled(widget == mediaView);
521 fullscreenAct->setEnabled(widget == mediaView);
522 compactViewAct->setEnabled(widget == mediaView);
523 webPageAct->setEnabled(widget == mediaView);
524 copyPageAct->setEnabled(widget == mediaView);
525 copyLinkAct->setEnabled(widget == mediaView);
526 aboutAct->setEnabled(widget != aboutView);
527 The::globalActions()->value("download")->setEnabled(widget == mediaView);
528 The::globalActions()->value("downloads")->setChecked(widget == downloadView);
530 // toolbar only for the mediaView
531 /* mainToolBar->setVisible(
532 (widget == mediaView && !compactViewAct->isChecked())
533 || widget == downloadView
536 setUpdatesEnabled(true);
538 QWidget *oldWidget = views->currentWidget();
539 views->setCurrentWidget(widget);
542 // crossfade only on OSX
543 // where we can be sure of video performance
544 fadeInWidget(oldWidget, widget);
547 history->push(widget);
550 void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
551 if (faderWidget) faderWidget->close();
552 if (!oldWidget || !newWidget) {
553 // qDebug() << "no widgets";
556 faderWidget = new FaderWidget(newWidget);
557 faderWidget->start(QPixmap::grabWidget(oldWidget));
560 void MainWindow::about() {
562 aboutView = new AboutView(this);
563 views->addWidget(aboutView);
565 showWidget(aboutView);
568 void MainWindow::visitSite() {
569 QUrl url(Constants::WEBSITE);
570 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
571 QDesktopServices::openUrl(url);
574 void MainWindow::donate() {
575 QUrl url(QString(Constants::WEBSITE) + "#donate");
576 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
577 QDesktopServices::openUrl(url);
580 void MainWindow::quit() {
585 void MainWindow::closeEvent(QCloseEvent *event) {
586 if (DownloadManager::instance()->activeItems() > 0) {
588 msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
589 msgBox.setText(tr("Do you want to exit %1 with a download in progress?").arg(Constants::APP_NAME));
590 msgBox.setInformativeText(tr("If you close %1 now, this download will be cancelled.").arg(Constants::APP_NAME));
591 msgBox.setModal(true);
593 msgBox.addButton(tr("Close and cancel download"), QMessageBox::RejectRole);
594 QPushButton *waitButton = msgBox.addButton(tr("Wait for download to finish"), QMessageBox::ActionRole);
598 if (msgBox.clickedButton() == waitButton) {
605 QWidget::closeEvent(event);
608 void MainWindow::showSearch() {
609 showWidget(searchView);
610 currentTime->clear();
614 void MainWindow::showMedia(QString query) {
615 SearchParams *searchParams = new SearchParams();
616 searchParams->setKeywords(query);
617 mediaView->search(searchParams);
618 showWidget(mediaView);
621 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
623 // qDebug() << "Phonon state: " << newState;
627 case Phonon::ErrorState:
628 if (mediaObject->errorType() == Phonon::FatalError) {
629 statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
631 statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
635 case Phonon::PlayingState:
636 pauseAct->setEnabled(true);
637 pauseAct->setIcon(QtIconLoader::icon("media-playback-pause"));
638 pauseAct->setText(tr("&Pause"));
639 pauseAct->setStatusTip(tr("Pause playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
640 skipAct->setEnabled(true);
641 // stopAct->setEnabled(true);
644 case Phonon::StoppedState:
645 pauseAct->setEnabled(false);
646 skipAct->setEnabled(false);
647 // stopAct->setEnabled(false);
650 case Phonon::PausedState:
651 skipAct->setEnabled(true);
652 pauseAct->setEnabled(true);
653 pauseAct->setIcon(QtIconLoader::icon("media-playback-start"));
654 pauseAct->setText(tr("&Play"));
655 pauseAct->setStatusTip(tr("Resume playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
656 // stopAct->setEnabled(true);
659 case Phonon::BufferingState:
660 case Phonon::LoadingState:
661 skipAct->setEnabled(true);
662 pauseAct->setEnabled(false);
663 currentTime->clear();
665 // stopAct->setEnabled(true);
673 void MainWindow::stop() {
678 void MainWindow::fullscreen() {
680 // No compact view action when in full screen
681 compactViewAct->setVisible(m_fullscreen);
682 compactViewAct->setChecked(false);
684 // Also no Youtube action since it opens a new window
685 webPageAct->setVisible(m_fullscreen);
686 copyPageAct->setVisible(m_fullscreen);
687 copyLinkAct->setVisible(m_fullscreen);
689 stopAct->setVisible(m_fullscreen);
691 // workaround: prevent focus on the search bar
692 // it steals the Space key needed for Play/Pause
693 toolbarSearch->setEnabled(m_fullscreen);
695 // Hide anything but the video
696 mediaView->setPlaylistVisible(m_fullscreen);
697 statusBar()->setVisible(m_fullscreen);
700 menuBar()->setVisible(m_fullscreen);
704 // make the actions work when video is fullscreen (on the Mac)
705 QMap<QString, QAction*> *actions = The::globalActions();
706 foreach (QAction *action, actions->values()) {
708 action->setShortcutContext(Qt::WindowShortcut);
710 action->setShortcutContext(Qt::ApplicationShortcut);
719 // use setShortcuts instead of setShortcut
720 // the latter seems not to work
721 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
722 fullscreenAct->setText(tr("&Full Screen"));
723 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
726 setCentralWidget(views);
729 mediaView->setFocus();
732 if (m_maximized) showMaximized();
736 // Make sure the window has focus
743 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
744 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
745 fullscreenAct->setText(tr("Exit &Full Screen"));
746 m_maximized = isMaximized();
748 // save geometry now, if the user quits when in full screen
749 // geometry won't be saved
755 QTimer::singleShot(0, views, SLOT(showFullScreen()));
763 m_fullscreen = !m_fullscreen;
767 void MainWindow::compactView(bool enable) {
769 mediaView->setPlaylistVisible(!enable);
770 statusBar()->setVisible(!enable);
773 menuBar()->setVisible(!enable);
777 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
778 compactViewAct->setShortcuts(
779 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Return)
780 << QKeySequence(Qt::Key_Escape));
782 // ensure focus does not end up to the search box
783 // as it would steal the Space shortcut
784 mediaView->setFocus();
786 compactViewAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Return));
787 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
792 void MainWindow::searchFocus() {
793 QWidget *view = views->currentWidget();
794 if (view == mediaView) {
795 toolbarSearch->selectAll();
796 toolbarSearch->setFocus();
800 void MainWindow::initPhonon() {
801 // Phonon initialization
802 if (mediaObject) delete mediaObject;
803 if (audioOutput) delete audioOutput;
804 mediaObject = new Phonon::MediaObject(this);
805 mediaObject->setTickInterval(100);
806 connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
807 this, SLOT(stateChanged(Phonon::State, Phonon::State)));
808 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
809 connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
810 seekSlider->setMediaObject(mediaObject);
811 audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
812 connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
813 connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
814 volumeSlider->setAudioOutput(audioOutput);
815 Phonon::createPath(mediaObject, audioOutput);
818 void MainWindow::tick(qint64 time) {
820 currentTime->clear();
824 currentTime->setText(formatTime(time));
827 const qint64 remainingTime = mediaObject->remainingTime();
828 currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
831 slider->blockSignals(true);
832 slider->setValue(time/1000);
833 slider->blockSignals(false);
837 void MainWindow::totalTimeChanged(qint64 time) {
842 totalTime->setText(formatTime(time));
845 slider->blockSignals(true);
846 slider->setMaximum(time/1000);
847 slider->blockSignals(false);
852 QString MainWindow::formatTime(qint64 time) {
854 displayTime = displayTime.addMSecs(time);
856 // 60 * 60 * 1000 = 3600000
858 timeString = displayTime.toString("h:mm:ss");
860 timeString = displayTime.toString("m:ss");
864 void MainWindow::volumeUp() {
865 qreal newVolume = volumeSlider->audioOutput()->volume() + .1;
866 if (newVolume > volumeSlider->maximumVolume())
867 newVolume = volumeSlider->maximumVolume();
868 volumeSlider->audioOutput()->setVolume(newVolume);
871 void MainWindow::volumeDown() {
872 qreal newVolume = volumeSlider->audioOutput()->volume() - .1;
875 volumeSlider->audioOutput()->setVolume(newVolume);
878 void MainWindow::volumeMute() {
879 volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
882 void MainWindow::volumeChanged(qreal newVolume) {
883 // automatically unmute when volume changes
884 if (volumeSlider->audioOutput()->isMuted())
885 volumeSlider->audioOutput()->setMuted(false);
886 statusBar()->showMessage(tr("Volume at %1%").arg(newVolume*100));
889 void MainWindow::volumeMutedChanged(bool muted) {
891 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-muted"));
892 statusBar()->showMessage(tr("Volume is muted"));
894 volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
895 statusBar()->showMessage(tr("Volume is unmuted"));
899 void MainWindow::setDefinitionMode(QString definitionName) {
900 QAction *definitionAct = The::globalActions()->value("definition");
901 definitionAct->setText(definitionName);
902 definitionAct->setStatusTip(tr("Maximum video definition set to %1").arg(definitionAct->text())
903 + " (" + definitionAct->shortcut().toString(QKeySequence::NativeText) + ")");
904 statusBar()->showMessage(definitionAct->statusTip());
906 settings.setValue("definition", definitionName);
909 void MainWindow::toggleDefinitionMode() {
911 QString currentDefinition = settings.value("definition").toString();
912 QStringList definitionNames = VideoDefinition::getDefinitionNames();
913 int currentIndex = definitionNames.indexOf(currentDefinition);
915 if (currentIndex != definitionNames.size() - 1) {
916 nextIndex = currentIndex + 1;
918 QString nextDefinition = definitionNames.at(nextIndex);
919 setDefinitionMode(nextDefinition);
922 void MainWindow::showFullscreenToolbar(bool show) {
923 if (!m_fullscreen) return;
924 mainToolBar->setVisible(show);
927 void MainWindow::showFullscreenPlaylist(bool show) {
928 if (!m_fullscreen) return;
929 mediaView->setPlaylistVisible(show);
932 void MainWindow::clearRecentKeywords() {
934 settings.remove("recentKeywords");
935 searchView->updateRecentKeywords();
936 statusBar()->showMessage(tr("Your privacy is now safe"));
940 void MainWindow::setAutoplay(bool enabled) {
942 settings.setValue("autoplay", QVariant::fromValue(enabled));
946 void MainWindow::updateDownloadMessage(QString message) {
947 The::globalActions()->value("downloads")->setText(message);
950 void MainWindow::downloadsFinished() {
951 The::globalActions()->value("downloads")->setText(tr("&Downloads"));
952 statusBar()->showMessage(tr("Downloads complete"));
955 void MainWindow::toggleDownloads(bool show) {
958 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
959 The::globalActions()->value("downloads")->setShortcuts(
960 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J)
961 << QKeySequence(Qt::Key_Escape));
963 The::globalActions()->value("downloads")->setShortcuts(
964 QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J));
965 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
969 downloadView = new DownloadView(this);
970 views->addWidget(downloadView);
972 if (show) showWidget(downloadView);