]> git.sur5r.net Git - minitube/blob - src/MainWindow.cpp
f9dd824ee64dab76dbd6cb8aced908ed4cfeb0e6
[minitube] / src / MainWindow.cpp
1 #include "MainWindow.h"
2 #include "spacer.h"
3 #include "Constants.h"
4 #include "iconloader/qticonloader.h"
5 #include "global.h"
6
7 MainWindow::MainWindow() :
8         mediaObject(0),
9         audioOutput(0),
10         aboutView(0) {
11
12     m_fullscreen = false;
13     
14     // views mechanism
15     history = new QStack<QWidget*>();
16     views = new QStackedWidget(this);
17     
18     // views
19     searchView = new SearchView(this);
20     connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
21     views->addWidget(searchView);
22     
23     mediaView = new MediaView(this);
24     views->addWidget(mediaView);
25     
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&)));
30     
31     // build ui
32     createActions();
33     createMenus();
34     createToolBars();
35     createStatusBar();
36     
37     initPhonon();
38     mediaView->setMediaObject(mediaObject);
39     
40     // remove that useless menu/toolbar context menu
41     this->setContextMenuPolicy(Qt::NoContextMenu);
42     
43     // mediaView init stuff thats needs actions
44     mediaView->initialize();
45     
46     // restore window position
47     readSettings();
48     
49     // show the initial view
50     showWidget(searchView);
51     
52     setCentralWidget(views);
53 }
54
55 MainWindow::~MainWindow() {
56     delete history;
57 }
58
59 void MainWindow::createActions() {
60     
61     QMap<QString, QAction*> *actions = The::globalActions();
62     
63     /*
64     settingsAct = new QAction(tr("&Preferences..."), this);
65     settingsAct->setStatusTip(tr(QString("Configure ").append(Constants::APP_NAME).toUtf8()));
66     // Mac integration
67     settingsAct->setMenuRole(QAction::PreferencesRole);
68     actions->insert("settings", settingsAct);
69     connect(settingsAct, SIGNAL(triggered()), this, SLOT(showSettings()));
70     */
71     
72     backAct = new QAction(tr("&Back"), this);
73     backAct->setEnabled(false);
74     backAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Left));
75     backAct->setStatusTip(tr("Go to the previous view"));
76     actions->insert("back", backAct);
77     connect(backAct, SIGNAL(triggered()), this, SLOT(goBack()));
78     
79     stopAct = new QAction(QtIconLoader::icon("media-playback-stop", QIcon(":/images/media-playback-stop.png")), tr("&Stop"), this);
80     stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
81     stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
82     actions->insert("stop", stopAct);
83     connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
84     
85     skipAct = new QAction(QtIconLoader::icon("media-skip-forward", QIcon(":/images/media-skip-forward.png")), tr("S&kip"), this);
86     skipAct->setStatusTip(tr("Skip to the next video"));
87     skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
88     skipAct->setEnabled(false);
89     actions->insert("skip", skipAct);
90     connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
91     
92     pauseAct = new QAction(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")), tr("&Pause"), this);
93     pauseAct->setStatusTip(tr("Pause playback"));
94     pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
95     pauseAct->setEnabled(false);
96     actions->insert("pause", pauseAct);
97     connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
98     
99     fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen", QIcon(":/images/view-fullscreen.png")), tr("&Full Screen"), this);
100     fullscreenAct->setStatusTip(tr("Go full screen"));
101     fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
102     fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
103     actions->insert("fullscreen", fullscreenAct);
104     connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
105     
106     compactViewAct = new QAction(tr("&Compact mode"), this);
107     compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
108     compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
109     compactViewAct->setCheckable(true);
110     compactViewAct->setChecked(false);
111     compactViewAct->setEnabled(false);
112     actions->insert("compactView", compactViewAct);
113     connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
114     
115     /*
116     // icon should be document-save but it is ugly
117     downloadAct = new QAction(QtIconLoader::icon("go-down", QIcon(":/images/go-down.png")), tr("&Download"), this);
118     downloadAct->setStatusTip(tr("Download this video"));
119     downloadAct->setShortcut(tr("Ctrl+S"));
120     downloadAct->setEnabled(false);
121     actions->insert("download", downloadAct);
122     connect(downloadAct, SIGNAL(triggered()), this, SLOT(download()));
123     */
124     
125     webPageAct = new QAction(tr("&YouTube"), this);
126     webPageAct->setStatusTip(tr("Open the YouTube video page"));
127     webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
128     webPageAct->setEnabled(false);
129     actions->insert("webpage", webPageAct);
130     connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
131     
132     removeAct = new QAction(tr("&Remove"), this);
133     removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
134     removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
135     removeAct->setEnabled(false);
136     actions->insert("remove", removeAct);
137     connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
138     
139     moveUpAct = new QAction(tr("Move &Up"), this);
140     moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
141     moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
142     moveUpAct->setEnabled(false);
143     actions->insert("moveUp", moveUpAct);
144     connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
145     
146     moveDownAct = new QAction(tr("Move &Down"), this);
147     moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
148     moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
149     moveDownAct->setEnabled(false);
150     actions->insert("moveDown", moveDownAct);
151     connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
152
153     clearAct = new QAction(tr("&Clear recent keywords"), this);
154     clearAct->setMenuRole(QAction::ApplicationSpecificRole);
155     clearAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete) << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
156     clearAct->setEnabled(true);
157     actions->insert("clearRecentKeywords", clearAct);
158     connect(clearAct, SIGNAL(triggered()), searchView, SLOT(clearRecentKeywords()));
159
160     quitAct = new QAction(tr("&Quit"), this);
161     quitAct->setMenuRole(QAction::QuitRole);
162     quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
163     quitAct->setStatusTip(tr("Bye"));
164     actions->insert("quit", quitAct);
165     connect(quitAct, SIGNAL(triggered()), this, SLOT(quit()));
166     
167     siteAct = new QAction(tr("&Website"), this);
168     siteAct->setShortcut(QKeySequence::HelpContents);
169     siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
170     actions->insert("site", siteAct);
171     connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
172     
173     donateAct = new QAction(tr("&Donate via PayPal"), this);
174     donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
175     actions->insert("donate", donateAct);
176     connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
177     
178     aboutAct = new QAction(tr("&About"), this);
179     aboutAct->setMenuRole(QAction::AboutRole);
180     aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
181     actions->insert("about", aboutAct);
182     connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
183     
184     // Invisible actions
185     
186     searchFocusAct = new QAction(this);
187     searchFocusAct->setShortcut(QKeySequence::Find);
188     searchFocusAct->setStatusTip(tr("Search"));
189     actions->insert("search", searchFocusAct);
190     connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
191     addAction(searchFocusAct);
192     
193     volumeUpAct = new QAction(this);
194     volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
195     actions->insert("volume-up", volumeUpAct);
196     connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
197     addAction(volumeUpAct);
198     
199     volumeDownAct = new QAction(this);
200     volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
201     actions->insert("volume-down", volumeDownAct);
202     connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
203     addAction(volumeDownAct);
204     
205     volumeMuteAct = new QAction(this);
206     volumeMuteAct->setStatusTip(tr("Mute volume"));
207     volumeMuteAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+M")) << QKeySequence(Qt::Key_VolumeMute));
208     actions->insert("volume-mute", volumeMuteAct);
209     connect(volumeMuteAct, SIGNAL(triggered()), this, SLOT(volumeMute()));
210     addAction(volumeMuteAct);
211     
212     QAction *hdAct = new QAction(this);
213     hdAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
214     hdAct->setIcon(createHDIcon());
215     hdAct->setCheckable(true);
216     actions->insert("hd", hdAct);
217     connect(hdAct, SIGNAL(toggled(bool)), this, SLOT(hdMode(bool)));
218     addAction(hdAct);
219     
220     // common action properties
221     foreach (QAction *action, actions->values()) {
222         
223         // add actions to the MainWindow so that they work
224         // when the menu is hidden
225         addAction(action);
226         
227         // never autorepeat.
228         // unexperienced users tend to keep keys pressed for a "long" time
229         action->setAutoRepeat(false);
230         
231         // set to something more meaningful then the toolbar text
232         // HELP! how to remove tooltips altogether?!
233         if (!action->statusTip().isEmpty())
234             action->setToolTip(action->statusTip());
235         
236         // show keyboard shortcuts in the status bar
237         if (!action->shortcut().isEmpty())
238             action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
239         
240         // make the actions work when video is fullscreen
241         action->setShortcutContext(Qt::ApplicationShortcut);
242         
243         // no icons in menus
244         action->setIconVisibleInMenu(false);
245         
246     }
247     
248 }
249
250 void MainWindow::createMenus() {
251     
252     QMap<QString, QMenu*> *menus = The::globalMenus();
253     
254     fileMenu = menuBar()->addMenu(tr("&Application"));
255     // menus->insert("file", fileMenu);
256     // fileMenu->addAction(settingsAct);
257     fileMenu->addAction(clearAct);
258     fileMenu->addSeparator();
259     fileMenu->addAction(quitAct);
260
261     
262     playlistMenu = menuBar()->addMenu(tr("&Playlist"));
263     menus->insert("playlist", playlistMenu);
264     playlistMenu->addAction(removeAct);
265     playlistMenu->addSeparator();
266     playlistMenu->addAction(moveUpAct);
267     playlistMenu->addAction(moveDownAct);
268     
269     viewMenu = menuBar()->addMenu(tr("&Video"));
270     menus->insert("video", viewMenu);
271     // viewMenu->addAction(backAct);
272     viewMenu->addAction(stopAct);
273     viewMenu->addAction(pauseAct);
274     viewMenu->addAction(skipAct);
275     viewMenu->addSeparator();
276     viewMenu->addAction(webPageAct);
277     viewMenu->addSeparator();
278     // viewMenu->addAction(downloadAct);
279     viewMenu->addAction(compactViewAct);
280     viewMenu->addAction(fullscreenAct);
281     
282     helpMenu = menuBar()->addMenu(tr("&Help"));
283     helpMenu->addAction(siteAct);
284     helpMenu->addAction(donateAct);
285     helpMenu->addAction(aboutAct);
286 }
287
288 void MainWindow::createToolBars() {
289     
290     mainToolBar = new QToolBar(this);
291     mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
292     mainToolBar->setFloatable(false);
293     mainToolBar->setMovable(false);
294     // cool toolbar on the Mac
295     // setUnifiedTitleAndToolBarOnMac(true);
296     
297     QFont smallerFont;
298     smallerFont.setPointSize(smallerFont.pointSize()*.85);
299     QFontInfo fontInfo(smallerFont);
300     if (fontInfo.pixelSize() < 10) {
301         smallerFont.setPixelSize(10);
302     }
303     mainToolBar->setFont(smallerFont);
304     
305     mainToolBar->setIconSize(QSize(32,32));
306     // mainToolBar->addAction(backAct);
307     mainToolBar->addAction(stopAct);
308     mainToolBar->addAction(pauseAct);
309     mainToolBar->addAction(skipAct);
310     mainToolBar->addAction(fullscreenAct);
311     
312     seekSlider = new Phonon::SeekSlider(this);
313     seekSlider->setIconVisible(false);
314     Spacer *seekSliderSpacer = new Spacer(mainToolBar, seekSlider);
315     seekSliderSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
316     mainToolBar->addWidget(seekSliderSpacer);
317     
318     volumeSlider = new Phonon::VolumeSlider(this);
319     // qDebug() << volumeSlider->children();
320     // status tip for the volume slider
321     QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
322     if (volumeQSlider)
323         volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
324                 volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
325     // status tip for the mute button
326     QToolButton* muteToolButton = volumeSlider->findChild<QToolButton*>();
327     if (muteToolButton)
328         muteToolButton->setStatusTip(volumeMuteAct->statusTip());
329     // this makes the volume slider smaller
330     volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
331     mainToolBar->addWidget(new Spacer(mainToolBar, volumeSlider));
332     
333     toolbarSearch->setStatusTip(searchFocusAct->statusTip());
334     mainToolBar->addWidget(new Spacer(mainToolBar, toolbarSearch));
335     
336     addToolBar(mainToolBar);
337 }
338
339 void MainWindow::createStatusBar() {
340     currentTime = new QLabel(this);
341     statusBar()->addPermanentWidget(currentTime);
342     
343     totalTime = new QLabel(this);
344     statusBar()->addPermanentWidget(totalTime);
345     
346     // remove ugly borders on OSX
347     // and remove some excessive padding
348     statusBar()->setStyleSheet("::item{border:0 solid} "
349                                "QStatusBar, QToolBar, QToolButton {spacing:0;padding:0;margin:0} "
350                                );
351     
352     QToolBar *toolBar = new QToolBar(this);
353     int iconHeight = 24; // statusBar()->height();
354     int iconWidth = 36; // iconHeight * 3 / 2;
355     toolBar->setIconSize(QSize(iconWidth, iconHeight));
356     toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
357     toolBar->addAction(The::globalActions()->value("hd"));
358     statusBar()->addPermanentWidget(toolBar);
359     
360     statusBar()->show();
361 }
362
363 void MainWindow::readSettings() {
364     QSettings settings;
365     restoreGeometry(settings.value("geometry").toByteArray());
366     hdMode(settings.value("hd").toBool());
367     audioOutput->setVolume(settings.value("volume", 1).toDouble());
368     audioOutput->setMuted(settings.value("volumeMute").toBool());
369 }
370
371 void MainWindow::writeSettings() {
372     // do not save geometry when in full screen
373     if (m_fullscreen)
374         return;
375     QSettings settings;
376     settings.setValue("geometry", saveGeometry());
377     settings.setValue("hd", The::globalActions()->value("hd")->isChecked());
378     settings.setValue("volume", audioOutput->volume());
379     settings.setValue("volumeMute", audioOutput->isMuted());
380     mediaView->saveSplitterState();
381 }
382
383 void MainWindow::goBack() {
384     if ( history->size() > 1 ) {
385         history->pop();
386         QWidget *widget = history->pop();
387         showWidget(widget);
388     }
389 }
390
391 void MainWindow::showWidget ( QWidget* widget ) {
392     
393     setUpdatesEnabled(false);
394     
395     // call hide method on the current view
396     View* oldView = dynamic_cast<View *> (views->currentWidget());
397     if (oldView) {
398         oldView->disappear();
399     }
400     
401     // call show method on the new view
402     View* newView = dynamic_cast<View *> (widget);
403     if (newView) {
404         newView->appear();
405         QMap<QString,QVariant> metadata = newView->metadata();
406         QString windowTitle = metadata.value("title").toString();
407         if (windowTitle.length())
408             windowTitle += " - ";
409         setWindowTitle(windowTitle + Constants::APP_NAME);
410         statusBar()->showMessage((metadata.value("description").toString()));
411     }
412     
413     // backAct->setEnabled(history->size() > 1);
414     // settingsAct->setEnabled(widget != settingsView);
415     stopAct->setEnabled(widget == mediaView);
416     fullscreenAct->setEnabled(widget == mediaView);
417     compactViewAct->setEnabled(widget == mediaView);
418     webPageAct->setEnabled(widget == mediaView);    
419     aboutAct->setEnabled(widget != aboutView);
420     
421     /*
422     // this is not the best place to enable downloads, but the user is informed
423     // if there really is no video is playing
424     downloadAct->setEnabled(widget == mediaView);
425     */
426     
427     // toolbar only for the mediaView
428     mainToolBar->setVisible(widget == mediaView && !compactViewAct->isChecked());
429
430     setUpdatesEnabled(true);
431     
432     QWidget *oldWidget = views->currentWidget();
433     views->setCurrentWidget(widget);
434     
435 #ifdef Q_WS_MAC
436     // crossfade only on OSX
437     // where we can be sure of video performance
438     fadeInWidget(oldWidget, widget);
439 #endif
440     
441     history->push(widget);
442 }
443
444 void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
445     if (faderWidget) faderWidget->close();
446     if (!oldWidget || !newWidget) {
447         qDebug() << "no widgets";
448         return;
449     }
450     faderWidget = new FaderWidget(newWidget);
451     faderWidget->start(QPixmap::grabWidget(oldWidget));
452 }
453
454 void MainWindow::about() {
455     if (!aboutView) {
456         aboutView = new AboutView(this);
457         views->addWidget(aboutView);
458     }
459     showWidget(aboutView);
460 }
461
462 void MainWindow::visitSite() {
463     QUrl url(Constants::WEBSITE);
464     statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
465     QDesktopServices::openUrl(url);
466 }
467
468 void MainWindow::donate() {
469     QUrl url(QString(Constants::WEBSITE) + "#donate");
470     statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
471     QDesktopServices::openUrl(url);
472 }
473
474 void MainWindow::quit() {
475     writeSettings();
476     qApp->quit();
477 }
478
479 void MainWindow::closeEvent(QCloseEvent *event) {
480     quit();
481     QWidget::closeEvent(event);
482 }
483
484 /*
485 void MainWindow::showSettings() {
486     if (!settingsView) {
487         settingsView = new SettingsView(this);
488         views->addWidget(settingsView);
489     }
490     showWidget(settingsView);
491 }*/
492
493 void MainWindow::showSearch() {
494     showWidget(searchView);
495     currentTime->clear();
496     totalTime->clear();
497 }
498
499 void MainWindow::showMedia(QString query) {
500     SearchParams *searchParams = new SearchParams();
501     searchParams->setKeywords(query);
502     mediaView->search(searchParams);
503     showWidget(mediaView);
504 }
505
506 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
507     
508     // qDebug() << "Phonon state: " << newState;
509     
510     switch (newState) {
511         
512     case Phonon::ErrorState:
513         if (mediaObject->errorType() == Phonon::FatalError) {
514             statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
515         } else {
516             statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
517         }
518         break;
519         
520          case Phonon::PlayingState:
521         pauseAct->setEnabled(true);
522         pauseAct->setIcon(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")));
523         pauseAct->setText(tr("&Pause"));
524         pauseAct->setStatusTip(tr("Pause playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
525         skipAct->setEnabled(true);
526         break;
527         
528          case Phonon::StoppedState:
529         pauseAct->setEnabled(false);
530         skipAct->setEnabled(false);
531         break;
532         
533          case Phonon::PausedState:
534         skipAct->setEnabled(true);
535         pauseAct->setEnabled(true);
536         pauseAct->setIcon(QtIconLoader::icon("media-playback-start", QIcon(":/images/media-playback-start.png")));
537         pauseAct->setText(tr("&Play"));
538         pauseAct->setStatusTip(tr("Resume playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
539         break;
540         
541          case Phonon::BufferingState:
542          case Phonon::LoadingState:
543         skipAct->setEnabled(true);
544         pauseAct->setEnabled(false);
545         currentTime->clear();
546         totalTime->clear();
547         break;
548         
549          default:
550         ;
551     }
552 }
553
554 void MainWindow::stop() {
555     mediaView->stop();
556     showSearch();
557 }
558
559 void MainWindow::fullscreen() {
560     
561     setUpdatesEnabled(false);
562     
563     if (m_fullscreen) {
564         // use setShortucs instead of setShortcut
565         // the latter seems not to work
566         fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
567         fullscreenAct->setText(tr("&Full Screen"));
568         stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
569         if (m_maximized) showMaximized();
570         else showNormal();
571         // Make sure the window has focus (Mac)
572         activateWindow();
573     } else {
574         stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
575         fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
576         fullscreenAct->setText(tr("Exit &Full Screen"));
577         m_maximized = isMaximized();
578         
579         // save geometry now, if the user quits when in full screen
580         // geometry won't be saved
581         writeSettings();
582         
583         showFullScreen();
584     }
585     
586     // No compact view action when in full screen
587     compactViewAct->setVisible(m_fullscreen);
588     compactViewAct->setChecked(false);
589     
590     // Also no Youtube action since it opens a new window
591     webPageAct->setVisible(m_fullscreen);
592     
593     // Hide anything but the video
594     mediaView->setPlaylistVisible(m_fullscreen);
595     mainToolBar->setVisible(m_fullscreen);
596     statusBar()->setVisible(m_fullscreen);
597     menuBar()->setVisible(m_fullscreen);
598     
599     // workaround: prevent focus on the search bar
600     // it steals the Space key needed for Play/Pause
601     mainToolBar->setEnabled(m_fullscreen);
602
603     m_fullscreen = !m_fullscreen;
604     
605     setUpdatesEnabled(true);
606 }
607
608 void MainWindow::compactView(bool enable) {
609     
610     setUpdatesEnabled(false);
611     
612     // setUnifiedTitleAndToolBarOnMac(!enable);
613     mediaView->setPlaylistVisible(!enable);
614     mainToolBar->setVisible(!enable);
615     statusBar()->setVisible(!enable);
616     menuBar()->setVisible(!enable);
617
618     // ensure focus does not end up to the search box
619     // as it would steal the Space shortcut
620     toolbarSearch->setEnabled(!enable);
621     
622     if (enable) {
623         stopAct->setShortcut(QString(""));
624         QList<QKeySequence> shortcuts;
625         // for some reason it is important that ESC comes first
626         shortcuts << QKeySequence(Qt::CTRL + Qt::Key_Return) << QKeySequence(Qt::Key_Escape);
627         compactViewAct->setShortcuts(shortcuts);
628     } else {
629         compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
630         stopAct->setShortcut(QKeySequence(Qt::Key_Escape));
631     }
632
633     setUpdatesEnabled(true);
634 }
635
636 void MainWindow::searchFocus() {
637     QWidget *view = views->currentWidget();
638     if (view == mediaView) {
639         toolbarSearch->selectAll();
640         toolbarSearch->setFocus();
641     }
642 }
643
644 void MainWindow::initPhonon() {
645     // Phonon initialization
646     if (mediaObject) delete mediaObject;
647     if (audioOutput) delete audioOutput;
648     mediaObject = new Phonon::MediaObject(this);
649     mediaObject->setTickInterval(100);
650     connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
651             this, SLOT(stateChanged(Phonon::State, Phonon::State)));
652     connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
653     connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
654     seekSlider->setMediaObject(mediaObject);
655     audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
656     connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
657     connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
658     volumeSlider->setAudioOutput(audioOutput);
659     Phonon::createPath(mediaObject, audioOutput);
660 }
661
662 void MainWindow::tick(qint64 time) {
663     if (time <= 0) {
664         currentTime->clear();
665         return;
666     }
667
668     currentTime->setText(formatTime(time));
669
670     // remaining time
671     const qint64 remainingTime = mediaObject->remainingTime();
672     currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
673
674 }
675
676 void MainWindow::totalTimeChanged(qint64 time) {
677     if (time <= 0) {
678         totalTime->clear();
679         return;
680     }
681     totalTime->setText("/ " + formatTime(time));
682 }
683
684 QString MainWindow::formatTime(qint64 time) {
685     QTime displayTime;
686     displayTime = displayTime.addMSecs(time);
687     QString timeString;
688     // 60 * 60 * 1000 = 3600000
689     if (time > 3600000)
690         timeString = displayTime.toString("h:mm:ss");
691     else
692         timeString = displayTime.toString("m:ss");
693     return timeString;
694 }
695
696 void MainWindow::volumeUp() {
697     qreal newVolume = volumeSlider->audioOutput()->volume() + .1;
698     if (newVolume > volumeSlider->maximumVolume())
699         newVolume = volumeSlider->maximumVolume();
700     volumeSlider->audioOutput()->setVolume(newVolume);
701 }
702
703 void MainWindow::volumeDown() {
704     qreal newVolume = volumeSlider->audioOutput()->volume() - .1;
705     if (newVolume < 0)
706         newVolume = 0;
707     volumeSlider->audioOutput()->setVolume(newVolume);
708 }
709
710 void MainWindow::volumeMute() {
711     volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
712 }
713
714 void MainWindow::volumeChanged(qreal newVolume) {
715     // automatically unmute when volume changes
716     if (volumeSlider->audioOutput()->isMuted())
717         volumeSlider->audioOutput()->setMuted(false);
718     statusBar()->showMessage(tr("Volume at %1%").arg(newVolume*100));
719 }
720
721 void MainWindow::volumeMutedChanged(bool muted) {
722     if (muted)
723         statusBar()->showMessage(tr("Volume is muted"));
724     else
725         statusBar()->showMessage(tr("Volume is unmuted"));
726 }
727
728 QPixmap MainWindow::createHDPixmap(bool enabled) {
729     QPixmap pixmap = QPixmap(24,24);
730     pixmap.fill(Qt::transparent);
731     QPainter painter(&pixmap);
732     painter.setRenderHints(QPainter::Antialiasing, true);
733     
734     QRect rect(0, 3, 24, 18);
735     
736     QPen pen;
737     pen.setColor(Qt::black);
738     pen.setWidth(1);
739     painter.setPen(pen);
740     
741     if (enabled) {
742         painter.setBrush(palette().highlight());
743     } else {
744         QLinearGradient gradient(QPointF(0, 0), QPointF(0, rect.height() / 2));
745         gradient.setColorAt(0, QColor(0x6d, 0x6d, 0x6d));
746         gradient.setColorAt(1, QColor(0x25, 0x25, 0x25));
747         painter.setBrush(QBrush(gradient));
748     }
749     painter.drawRoundedRect(rect, 5, 5);
750     
751     if (enabled) {
752         pen.setColor(palette().highlightedText().color());
753     } else {
754         pen.setColor(Qt::white);
755     }
756     painter.setPen(pen);
757     
758     QFont font;
759     font.setPixelSize(12);
760     font.setBold(true);
761     painter.setFont(font);
762     painter.drawText(rect, Qt::AlignCenter, "HD");
763     
764     return pixmap;
765 }
766
767 static QIcon hdOnIcon;
768 static QIcon hdOffIcon;
769
770 QIcon MainWindow::createHDIcon() {
771     hdOffIcon.addPixmap(createHDPixmap(false));
772     hdOnIcon.addPixmap(createHDPixmap(true));
773     return hdOffIcon;
774 }
775
776 void MainWindow::hdMode(bool enabled) {
777     QAction *hdAct = The::globalActions()->value("hd");
778     hdAct->setChecked(enabled);
779     if (enabled) {
780         hdAct->setStatusTip(tr("High Definition video is enabled") + " (" +  hdAct->shortcut().toString(QKeySequence::NativeText) + ")");
781     } else {
782         hdAct->setStatusTip(tr("High Definition video is not enabled") + " (" +  hdAct->shortcut().toString(QKeySequence::NativeText) + ")");
783     }
784     statusBar()->showMessage(hdAct->statusTip());
785     QSettings settings;
786     settings.setValue("hd", enabled);
787 }
788
789 void MainWindow::hdIndicator(bool isHd) {
790     QAction *hdAct = The::globalActions()->value("hd");
791     if (isHd) {
792         hdAct->setIcon(hdOnIcon);
793         hdAct->setToolTip(tr("The current video is in High Definition"));
794     } else {
795         hdAct->setIcon(hdOffIcon);
796         hdAct->setToolTip(tr("The current video is not in High Definition"));
797     }
798 }
799
800 void MainWindow::showFullscreenToolbar(bool show) {
801     if (!m_fullscreen) return;
802
803     if (show) {
804         mainToolBar->show();
805     } else {
806         mainToolBar->hide();
807     }
808     mainToolBar->setEnabled(show);
809 }
810
811 void MainWindow::showFullscreenPlaylist(bool show) {
812     if (!m_fullscreen) return;    
813     mediaView->setPlaylistVisible(show);
814 }
815