1 #include "MainWindow.h"
4 #include "iconloader/qticonloader.h"
7 MainWindow::MainWindow() :
15 history = new QStack<QWidget*>();
16 views = new QStackedWidget(this);
19 searchView = new SearchView(this);
20 connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
21 views->addWidget(searchView);
23 mediaView = new MediaView(this);
24 views->addWidget(mediaView);
26 toolbarSearch = new SearchLineEdit(this);
27 toolbarSearch->setFont(qApp->font());
28 toolbarSearch->setMinimumWidth(toolbarSearch->fontInfo().pixelSize()*15);
29 connect(toolbarSearch, SIGNAL(search(const QString&)), searchView, SLOT(watch(const QString&)));
38 mediaView->setMediaObject(mediaObject);
40 // remove that useless menu/toolbar context menu
41 this->setContextMenuPolicy(Qt::NoContextMenu);
43 // mediaView init stuff thats needs actions
44 mediaView->initialize();
46 // restore window position
49 // cool toolbar on the Mac
50 // this is too buggy to be enabled
51 // setUnifiedTitleAndToolBarOnMac(true);
53 // event filter to block ugly toolbar tooltips
54 qApp->installEventFilter(this);
56 // show the initial view
57 showWidget(searchView);
59 setCentralWidget(views);
62 MainWindow::~MainWindow() {
66 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
67 if (event->type() == QEvent::ToolTip) {
71 // standard event processing
72 return QObject::eventFilter(obj, event);
76 void MainWindow::createActions() {
78 QMap<QString, QAction*> *actions = The::globalActions();
80 stopAct = new QAction(QtIconLoader::icon("media-playback-stop", QIcon(":/images/media-playback-stop.png")), tr("&Stop"), this);
81 stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
82 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
83 actions->insert("stop", stopAct);
84 connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
86 skipAct = new QAction(QtIconLoader::icon("media-skip-forward", QIcon(":/images/media-skip-forward.png")), tr("S&kip"), this);
87 skipAct->setStatusTip(tr("Skip to the next video"));
88 skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
89 skipAct->setEnabled(false);
90 actions->insert("skip", skipAct);
91 connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
93 pauseAct = new QAction(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")), tr("&Pause"), this);
94 pauseAct->setStatusTip(tr("Pause playback"));
95 pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
96 pauseAct->setEnabled(false);
97 actions->insert("pause", pauseAct);
98 connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
100 fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen", QIcon(":/images/view-fullscreen.png")), tr("&Full Screen"), this);
101 fullscreenAct->setStatusTip(tr("Go full screen"));
102 fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
103 fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
104 actions->insert("fullscreen", fullscreenAct);
105 connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
107 compactViewAct = new QAction(tr("&Compact mode"), this);
108 compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
109 compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
110 compactViewAct->setCheckable(true);
111 compactViewAct->setChecked(false);
112 compactViewAct->setEnabled(false);
113 actions->insert("compactView", compactViewAct);
114 connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
116 webPageAct = new QAction(tr("Open the &YouTube page"), this);
117 webPageAct->setStatusTip(tr("Go to the YouTube video page and pause playback"));
118 webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
119 webPageAct->setEnabled(false);
120 actions->insert("webpage", webPageAct);
121 connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
123 copyPageAct = new QAction(tr("Copy the YouTube &link"), this);
124 copyPageAct->setStatusTip(tr("Copy the current video YouTube link to the clipboard"));
125 copyPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
126 copyPageAct->setEnabled(false);
127 actions->insert("pagelink", copyPageAct);
128 connect(copyPageAct, SIGNAL(triggered()), mediaView, SLOT(copyWebPage()));
130 copyLinkAct = new QAction(tr("Copy the video stream &URL"), this);
131 copyLinkAct->setStatusTip(tr("Copy the current video stream URL to the clipboard"));
132 copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
133 copyLinkAct->setEnabled(false);
134 actions->insert("videolink", copyLinkAct);
135 connect(copyLinkAct, SIGNAL(triggered()), mediaView, SLOT(copyVideoLink()));
137 removeAct = new QAction(tr("&Remove"), this);
138 removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
139 removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
140 removeAct->setEnabled(false);
141 actions->insert("remove", removeAct);
142 connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
144 moveUpAct = new QAction(tr("Move &Up"), this);
145 moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
146 moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
147 moveUpAct->setEnabled(false);
148 actions->insert("moveUp", moveUpAct);
149 connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
151 moveDownAct = new QAction(tr("Move &Down"), this);
152 moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
153 moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
154 moveDownAct->setEnabled(false);
155 actions->insert("moveDown", moveDownAct);
156 connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
158 clearAct = new QAction(tr("&Clear recent keywords"), this);
159 clearAct->setMenuRole(QAction::ApplicationSpecificRole);
160 clearAct->setShortcuts(QList<QKeySequence>()
161 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete)
162 << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
163 clearAct->setStatusTip(tr("Clear the search history. Cannot be undone."));
164 clearAct->setEnabled(true);
165 actions->insert("clearRecentKeywords", clearAct);
166 connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
168 quitAct = new QAction(tr("&Quit"), this);
169 quitAct->setMenuRole(QAction::QuitRole);
170 quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
171 quitAct->setStatusTip(tr("Bye"));
172 actions->insert("quit", quitAct);
173 connect(quitAct, SIGNAL(triggered()), this, SLOT(quit()));
175 siteAct = new QAction(tr("&Website"), this);
176 siteAct->setShortcut(QKeySequence::HelpContents);
177 siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
178 actions->insert("site", siteAct);
179 connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
181 donateAct = new QAction(tr("&Donate"), this);
182 donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
183 actions->insert("donate", donateAct);
184 connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
186 aboutAct = new QAction(tr("&About"), this);
187 aboutAct->setMenuRole(QAction::AboutRole);
188 aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
189 actions->insert("about", aboutAct);
190 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
194 searchFocusAct = new QAction(this);
195 searchFocusAct->setShortcut(QKeySequence::Find);
196 searchFocusAct->setStatusTip(tr("Search"));
197 actions->insert("search", searchFocusAct);
198 connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
199 addAction(searchFocusAct);
201 volumeUpAct = new QAction(this);
202 volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
203 actions->insert("volume-up", volumeUpAct);
204 connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
205 addAction(volumeUpAct);
207 volumeDownAct = new QAction(this);
208 volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
209 actions->insert("volume-down", volumeDownAct);
210 connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
211 addAction(volumeDownAct);
213 volumeMuteAct = new QAction(this);
214 volumeMuteAct->setStatusTip(tr("Mute volume"));
215 volumeMuteAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+M")) << QKeySequence(Qt::Key_VolumeMute));
216 actions->insert("volume-mute", volumeMuteAct);
217 connect(volumeMuteAct, SIGNAL(triggered()), this, SLOT(volumeMute()));
218 addAction(volumeMuteAct);
220 QAction *hdAct = new QAction(this);
221 hdAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
222 hdAct->setIcon(createHDIcon());
223 hdAct->setCheckable(true);
224 actions->insert("hd", hdAct);
225 connect(hdAct, SIGNAL(toggled(bool)), this, SLOT(hdMode(bool)));
228 // common action properties
229 foreach (QAction *action, actions->values()) {
231 // add actions to the MainWindow so that they work
232 // when the menu is hidden
236 // unexperienced users tend to keep keys pressed for a "long" time
237 action->setAutoRepeat(false);
239 // set to something more meaningful then the toolbar text
240 // HELP! how to remove tooltips altogether?!
241 if (!action->statusTip().isEmpty())
242 action->setToolTip(action->statusTip());
244 // show keyboard shortcuts in the status bar
245 if (!action->shortcut().isEmpty())
246 action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
249 action->setIconVisibleInMenu(false);
255 void MainWindow::createMenus() {
257 QMap<QString, QMenu*> *menus = The::globalMenus();
259 fileMenu = menuBar()->addMenu(tr("&Application"));
260 // menus->insert("file", fileMenu);
261 fileMenu->addAction(clearAct);
263 fileMenu->addSeparator();
265 fileMenu->addAction(quitAct);
267 playlistMenu = menuBar()->addMenu(tr("&Playlist"));
268 menus->insert("playlist", playlistMenu);
269 playlistMenu->addAction(removeAct);
270 playlistMenu->addSeparator();
271 playlistMenu->addAction(moveUpAct);
272 playlistMenu->addAction(moveDownAct);
274 viewMenu = menuBar()->addMenu(tr("&Video"));
275 menus->insert("video", viewMenu);
276 viewMenu->addAction(stopAct);
277 viewMenu->addAction(pauseAct);
278 viewMenu->addAction(skipAct);
279 viewMenu->addSeparator();
280 viewMenu->addAction(webPageAct);
281 viewMenu->addAction(copyPageAct);
282 viewMenu->addAction(copyLinkAct);
283 viewMenu->addSeparator();
284 viewMenu->addAction(compactViewAct);
285 viewMenu->addAction(fullscreenAct);
287 helpMenu = menuBar()->addMenu(tr("&Help"));
288 helpMenu->addAction(siteAct);
289 helpMenu->addAction(donateAct);
290 helpMenu->addAction(aboutAct);
293 void MainWindow::createToolBars() {
295 mainToolBar = new QToolBar(this);
296 #if QT_VERSION < 0x040600 || defined(Q_WS_MAC)
297 mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
299 mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
301 mainToolBar->setFloatable(false);
302 mainToolBar->setMovable(false);
305 smallerFont.setPointSize(smallerFont.pointSize()*.85);
306 QFontInfo fontInfo(smallerFont);
307 if (fontInfo.pixelSize() < 10) {
308 smallerFont.setPixelSize(10);
310 mainToolBar->setFont(smallerFont);
313 mainToolBar->setIconSize(QSize(32, 32));
316 mainToolBar->addAction(stopAct);
317 mainToolBar->addAction(pauseAct);
318 mainToolBar->addAction(skipAct);
319 mainToolBar->addAction(fullscreenAct);
321 seekSlider = new Phonon::SeekSlider(this);
322 seekSlider->setIconVisible(false);
323 Spacer *seekSliderSpacer = new Spacer(mainToolBar, seekSlider);
324 seekSliderSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
325 mainToolBar->addWidget(seekSliderSpacer);
327 volumeSlider = new Phonon::VolumeSlider(this);
328 // qDebug() << volumeSlider->children();
329 // status tip for the volume slider
330 QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
332 volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
333 volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
334 // status tip for the mute button
335 QToolButton* muteToolButton = volumeSlider->findChild<QToolButton*>();
337 muteToolButton->setStatusTip(volumeMuteAct->statusTip());
338 // this makes the volume slider smaller
339 volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
340 mainToolBar->addWidget(new Spacer(mainToolBar, volumeSlider));
342 toolbarSearch->setStatusTip(searchFocusAct->statusTip());
343 mainToolBar->addWidget(new Spacer(mainToolBar, toolbarSearch));
345 addToolBar(mainToolBar);
348 void MainWindow::createStatusBar() {
349 currentTime = new QLabel(this);
350 statusBar()->addPermanentWidget(currentTime);
352 totalTime = new QLabel(this);
353 statusBar()->addPermanentWidget(totalTime);
355 // remove ugly borders on OSX
356 // and remove some excessive padding
357 statusBar()->setStyleSheet("::item{border:0 solid} "
358 "QStatusBar, QToolBar, QToolButton {spacing:0;padding:0;margin:0} "
361 QToolBar *toolBar = new QToolBar(this);
362 int iconHeight = 24; // statusBar()->height();
363 int iconWidth = 36; // iconHeight * 3 / 2;
364 toolBar->setIconSize(QSize(iconWidth, iconHeight));
365 toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
366 toolBar->addAction(The::globalActions()->value("hd"));
367 statusBar()->addPermanentWidget(toolBar);
372 void MainWindow::readSettings() {
374 restoreGeometry(settings.value("geometry").toByteArray());
375 hdMode(settings.value("hd").toBool());
376 audioOutput->setVolume(settings.value("volume", 1).toDouble());
377 audioOutput->setMuted(settings.value("volumeMute").toBool());
380 void MainWindow::writeSettings() {
381 // do not save geometry when in full screen
385 settings.setValue("geometry", saveGeometry());
386 settings.setValue("hd", The::globalActions()->value("hd")->isChecked());
387 settings.setValue("volume", audioOutput->volume());
388 settings.setValue("volumeMute", audioOutput->isMuted());
389 mediaView->saveSplitterState();
392 void MainWindow::goBack() {
393 if ( history->size() > 1 ) {
395 QWidget *widget = history->pop();
400 void MainWindow::showWidget ( QWidget* widget ) {
402 setUpdatesEnabled(false);
404 // call hide method on the current view
405 View* oldView = dynamic_cast<View *> (views->currentWidget());
407 oldView->disappear();
410 // call show method on the new view
411 View* newView = dynamic_cast<View *> (widget);
414 QMap<QString,QVariant> metadata = newView->metadata();
415 QString windowTitle = metadata.value("title").toString();
416 if (windowTitle.length())
417 windowTitle += " - ";
418 setWindowTitle(windowTitle + Constants::APP_NAME);
419 statusBar()->showMessage((metadata.value("description").toString()));
422 stopAct->setEnabled(widget == mediaView);
423 fullscreenAct->setEnabled(widget == mediaView);
424 compactViewAct->setEnabled(widget == mediaView);
425 webPageAct->setEnabled(widget == mediaView);
426 copyPageAct->setEnabled(widget == mediaView);
427 copyLinkAct->setEnabled(widget == mediaView);
428 aboutAct->setEnabled(widget != aboutView);
430 // toolbar only for the mediaView
431 mainToolBar->setVisible(widget == mediaView && !compactViewAct->isChecked());
433 setUpdatesEnabled(true);
435 QWidget *oldWidget = views->currentWidget();
436 views->setCurrentWidget(widget);
439 // crossfade only on OSX
440 // where we can be sure of video performance
441 fadeInWidget(oldWidget, widget);
444 history->push(widget);
447 void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
448 if (faderWidget) faderWidget->close();
449 if (!oldWidget || !newWidget) {
450 // qDebug() << "no widgets";
453 faderWidget = new FaderWidget(newWidget);
454 faderWidget->start(QPixmap::grabWidget(oldWidget));
457 void MainWindow::about() {
459 aboutView = new AboutView(this);
460 views->addWidget(aboutView);
462 showWidget(aboutView);
465 void MainWindow::visitSite() {
466 QUrl url(Constants::WEBSITE);
467 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
468 QDesktopServices::openUrl(url);
471 void MainWindow::donate() {
472 QUrl url(QString(Constants::WEBSITE) + "#donate");
473 statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
474 QDesktopServices::openUrl(url);
477 void MainWindow::quit() {
482 void MainWindow::closeEvent(QCloseEvent *event) {
484 QWidget::closeEvent(event);
488 void MainWindow::showSettings() {
490 settingsView = new SettingsView(this);
491 views->addWidget(settingsView);
493 showWidget(settingsView);
496 void MainWindow::showSearch() {
497 showWidget(searchView);
498 currentTime->clear();
502 void MainWindow::showMedia(QString query) {
503 SearchParams *searchParams = new SearchParams();
504 searchParams->setKeywords(query);
505 mediaView->search(searchParams);
506 showWidget(mediaView);
509 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
511 // qDebug() << "Phonon state: " << newState;
515 case Phonon::ErrorState:
516 if (mediaObject->errorType() == Phonon::FatalError) {
517 statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
519 statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
523 case Phonon::PlayingState:
524 pauseAct->setEnabled(true);
525 pauseAct->setIcon(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")));
526 pauseAct->setText(tr("&Pause"));
527 pauseAct->setStatusTip(tr("Pause playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
528 skipAct->setEnabled(true);
531 case Phonon::StoppedState:
532 pauseAct->setEnabled(false);
533 skipAct->setEnabled(false);
536 case Phonon::PausedState:
537 skipAct->setEnabled(true);
538 pauseAct->setEnabled(true);
539 pauseAct->setIcon(QtIconLoader::icon("media-playback-start", QIcon(":/images/media-playback-start.png")));
540 pauseAct->setText(tr("&Play"));
541 pauseAct->setStatusTip(tr("Resume playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
544 case Phonon::BufferingState:
545 case Phonon::LoadingState:
546 skipAct->setEnabled(true);
547 pauseAct->setEnabled(false);
548 currentTime->clear();
557 void MainWindow::stop() {
562 void MainWindow::fullscreen() {
564 setUpdatesEnabled(false);
566 // No compact view action when in full screen
567 compactViewAct->setVisible(m_fullscreen);
568 compactViewAct->setChecked(false);
570 // Also no Youtube action since it opens a new window
571 webPageAct->setVisible(m_fullscreen);
572 copyPageAct->setVisible(m_fullscreen);
573 copyLinkAct->setVisible(m_fullscreen);
575 stopAct->setVisible(m_fullscreen);
577 // workaround: prevent focus on the search bar
578 // it steals the Space key needed for Play/Pause
579 mainToolBar->setEnabled(m_fullscreen);
581 // Hide anything but the video
582 mediaView->setPlaylistVisible(m_fullscreen);
583 statusBar()->setVisible(m_fullscreen);
586 menuBar()->setVisible(m_fullscreen);
590 // make the actions work when video is fullscreen (on the Mac)
591 QMap<QString, QAction*> *actions = The::globalActions();
592 foreach (QAction *action, actions->values()) {
594 action->setShortcutContext(Qt::WindowShortcut);
596 action->setShortcutContext(Qt::ApplicationShortcut);
602 // use setShortucs instead of setShortcut
603 // the latter seems not to work
604 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
605 fullscreenAct->setText(tr("&Full Screen"));
606 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
609 if (m_maximized) showMaximized();
612 // Make sure the window has focus (Mac)
616 stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
617 fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
618 fullscreenAct->setText(tr("Exit &Full Screen"));
619 m_maximized = isMaximized();
621 // save geometry now, if the user quits when in full screen
622 // geometry won't be saved
629 m_fullscreen = !m_fullscreen;
631 setUpdatesEnabled(true);
634 void MainWindow::compactView(bool enable) {
636 setUpdatesEnabled(false);
638 mainToolBar->setVisible(!enable);
639 mainToolBar->setEnabled(!enable);
640 mediaView->setPlaylistVisible(!enable);
641 statusBar()->setVisible(!enable);
644 menuBar()->setVisible(!enable);
647 // ensure focus does not end up to the search box
648 // as it would steal the Space shortcut
649 // toolbarSearch->setEnabled(!enable);
652 stopAct->setShortcut(QString(""));
653 QList<QKeySequence> shortcuts;
654 // for some reason it is important that ESC comes first
655 shortcuts << QKeySequence(Qt::CTRL + Qt::Key_Return) << QKeySequence(Qt::Key_Escape);
656 compactViewAct->setShortcuts(shortcuts);
658 compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
659 stopAct->setShortcut(QKeySequence(Qt::Key_Escape));
662 setUpdatesEnabled(true);
665 void MainWindow::searchFocus() {
666 QWidget *view = views->currentWidget();
667 if (view == mediaView) {
668 toolbarSearch->selectAll();
669 toolbarSearch->setFocus();
673 void MainWindow::initPhonon() {
674 // Phonon initialization
675 if (mediaObject) delete mediaObject;
676 if (audioOutput) delete audioOutput;
677 mediaObject = new Phonon::MediaObject(this);
678 mediaObject->setTickInterval(100);
679 connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
680 this, SLOT(stateChanged(Phonon::State, Phonon::State)));
681 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
682 connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
683 seekSlider->setMediaObject(mediaObject);
684 audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
685 connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
686 connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
687 volumeSlider->setAudioOutput(audioOutput);
688 Phonon::createPath(mediaObject, audioOutput);
691 void MainWindow::tick(qint64 time) {
693 currentTime->clear();
697 currentTime->setText(formatTime(time));
700 const qint64 remainingTime = mediaObject->remainingTime();
701 currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
705 void MainWindow::totalTimeChanged(qint64 time) {
710 totalTime->setText("/ " + formatTime(time));
713 QString MainWindow::formatTime(qint64 time) {
715 displayTime = displayTime.addMSecs(time);
717 // 60 * 60 * 1000 = 3600000
719 timeString = displayTime.toString("h:mm:ss");
721 timeString = displayTime.toString("m:ss");
725 void MainWindow::volumeUp() {
726 qreal newVolume = volumeSlider->audioOutput()->volume() + .1;
727 if (newVolume > volumeSlider->maximumVolume())
728 newVolume = volumeSlider->maximumVolume();
729 volumeSlider->audioOutput()->setVolume(newVolume);
732 void MainWindow::volumeDown() {
733 qreal newVolume = volumeSlider->audioOutput()->volume() - .1;
736 volumeSlider->audioOutput()->setVolume(newVolume);
739 void MainWindow::volumeMute() {
740 volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
743 void MainWindow::volumeChanged(qreal newVolume) {
744 // automatically unmute when volume changes
745 if (volumeSlider->audioOutput()->isMuted())
746 volumeSlider->audioOutput()->setMuted(false);
747 statusBar()->showMessage(tr("Volume at %1%").arg(newVolume*100));
750 void MainWindow::volumeMutedChanged(bool muted) {
752 statusBar()->showMessage(tr("Volume is muted"));
754 statusBar()->showMessage(tr("Volume is unmuted"));
757 QPixmap MainWindow::createHDPixmap(bool enabled) {
758 QPixmap pixmap = QPixmap(24,24);
759 pixmap.fill(Qt::transparent);
760 QPainter painter(&pixmap);
761 painter.setRenderHints(QPainter::Antialiasing, true);
763 QRect rect(0, 3, 24, 18);
766 pen.setColor(Qt::black);
771 painter.setBrush(palette().highlight());
773 QLinearGradient gradient(QPointF(0, 0), QPointF(0, rect.height() / 2));
774 gradient.setColorAt(0, QColor(0x6d, 0x6d, 0x6d));
775 gradient.setColorAt(1, QColor(0x25, 0x25, 0x25));
776 painter.setBrush(QBrush(gradient));
778 painter.drawRoundedRect(rect, 5, 5);
781 pen.setColor(palette().highlightedText().color());
783 pen.setColor(Qt::white);
788 font.setPixelSize(12);
790 painter.setFont(font);
791 painter.drawText(rect, Qt::AlignCenter, "HD");
796 static QIcon hdOnIcon;
797 static QIcon hdOffIcon;
799 QIcon MainWindow::createHDIcon() {
800 hdOffIcon.addPixmap(createHDPixmap(false));
801 hdOnIcon.addPixmap(createHDPixmap(true));
805 void MainWindow::hdMode(bool enabled) {
806 QAction *hdAct = The::globalActions()->value("hd");
807 hdAct->setChecked(enabled);
809 hdAct->setStatusTip(tr("High Definition video is enabled") + " (" + hdAct->shortcut().toString(QKeySequence::NativeText) + ")");
811 hdAct->setStatusTip(tr("High Definition video is not enabled") + " (" + hdAct->shortcut().toString(QKeySequence::NativeText) + ")");
813 statusBar()->showMessage(hdAct->statusTip());
815 settings.setValue("hd", enabled);
818 void MainWindow::hdIndicator(bool isHd) {
819 QAction *hdAct = The::globalActions()->value("hd");
821 hdAct->setIcon(hdOnIcon);
822 hdAct->setToolTip(tr("The current video is in High Definition"));
824 hdAct->setIcon(hdOffIcon);
825 hdAct->setToolTip(tr("The current video is not in High Definition"));
829 void MainWindow::showFullscreenToolbar(bool show) {
830 if (!m_fullscreen) return;
837 mainToolBar->setEnabled(show);
840 void MainWindow::showFullscreenPlaylist(bool show) {
841 if (!m_fullscreen) return;
842 mediaView->setPlaylistVisible(show);
845 void MainWindow::clearRecentKeywords() {
847 settings.remove("recentKeywords");
848 searchView->updateRecentKeywords();
849 statusBar()->showMessage(tr("Your privacy is now safe"));