]> git.sur5r.net Git - minitube/blobdiff - src/MainWindow.cpp
Updated translations
[minitube] / src / MainWindow.cpp
index f7d0015a58b5387bfcad7b2aa173a5a09ec4047a..c87c398be0d84b2e8d7c7be7362441f510d65d32 100755 (executable)
@@ -1,32 +1,40 @@
 #include "MainWindow.h"
 #include "spacer.h"
-#include "Constants.h"
+#include "constants.h"
 #include "iconloader/qticonloader.h"
 #include "global.h"
+#include "videodefinition.h"
+#include "fontutils.h"
+#include "globalshortcuts.h"
+#ifdef Q_WS_X11
+#include "gnomeglobalshortcutbackend.h"
+#endif
+#ifdef APP_MAC
+// #include "local/mac/mac_startup.h"
+#endif
+#include "downloadmanager.h"
 
-MainWindow::MainWindow() {
-
-    m_fullscreen = false;
-    mediaObject = 0;
-    audioOutput = 0;
+MainWindow::MainWindow() :
+        aboutView(0),
+        downloadView(0),
+        mediaObject(0),
+        audioOutput(0),
+        m_fullscreen(false) {
 
     // views mechanism
     history = new QStack<QWidget*>();
     views = new QStackedWidget(this);
+    setCentralWidget(views);
 
     // views
     searchView = new SearchView(this);
     connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
     views->addWidget(searchView);
+
     mediaView = new MediaView(this);
     views->addWidget(mediaView);
 
-    // lazily initialized views
-    aboutView = 0;
-    settingsView = 0;
-
     toolbarSearch = new SearchLineEdit(this);
-    toolbarSearch->setFont(qApp->font());
     toolbarSearch->setMinimumWidth(toolbarSearch->fontInfo().pixelSize()*15);
     connect(toolbarSearch, SIGNAL(search(const QString&)), searchView, SLOT(watch(const QString&)));
 
@@ -36,69 +44,89 @@ MainWindow::MainWindow() {
     createToolBars();
     createStatusBar();
 
+    initPhonon();
+    mediaView->setMediaObject(mediaObject);
+
     // remove that useless menu/toolbar context menu
     this->setContextMenuPolicy(Qt::NoContextMenu);
 
     // mediaView init stuff thats needs actions
     mediaView->initialize();
 
+    // event filter to block ugly toolbar tooltips
+    qApp->installEventFilter(this);
+
     // restore window position
     readSettings();
 
     // show the initial view
     showWidget(searchView);
 
-    setCentralWidget(views);
+    // Global shortcuts
+    GlobalShortcuts &shortcuts = GlobalShortcuts::instance();
+#ifdef Q_WS_X11
+    if (GnomeGlobalShortcutBackend::IsGsdAvailable())
+        shortcuts.setBackend(new GnomeGlobalShortcutBackend(&shortcuts));
+#endif
+#ifdef APP_MAC
+    // mac::MacSetup();
+#endif
+    connect(&shortcuts, SIGNAL(PlayPause()), pauseAct, SLOT(trigger()));
+    connect(&shortcuts, SIGNAL(Stop()), this, SLOT(stop()));
+    connect(&shortcuts, SIGNAL(Next()), skipAct, SLOT(trigger()));
+
+    connect(DownloadManager::instance(), SIGNAL(statusMessageChanged(QString)),
+            SLOT(updateDownloadMessage(QString)));
+    connect(DownloadManager::instance(), SIGNAL(finished()),
+            SLOT(downloadsFinished()));
 }
 
 MainWindow::~MainWindow() {
     delete history;
 }
 
+bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
+    if (event->type() == QEvent::ToolTip) {
+        // kill tooltips
+        return true;
+    } else {
+        // standard event processing
+        return QObject::eventFilter(obj, event);
+    }
+}
+
 void MainWindow::createActions() {
 
     QMap<QString, QAction*> *actions = The::globalActions();
 
-    /*
-    settingsAct = new QAction(tr("&Preferences..."), this);
-    settingsAct->setStatusTip(tr(QString("Configure ").append(Constants::APP_NAME).toUtf8()));
-    // Mac integration
-    settingsAct->setMenuRole(QAction::PreferencesRole);
-    actions->insert("settings", settingsAct);
-    connect(settingsAct, SIGNAL(triggered()), this, SLOT(showSettings()));
-    */
-    
-    backAct = new QAction(QIcon(":/images/go-previous.png"), tr("&Back"), this);
-    backAct->setEnabled(false);
-    backAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Left));
-    backAct->setStatusTip(tr("Go to the previous view"));
-    actions->insert("back", backAct);
-    connect(backAct, SIGNAL(triggered()), this, SLOT(goBack()));
-
-    stopAct = new QAction(QtIconLoader::icon("media-playback-stop", QIcon(":/images/stop.png")), tr("&Stop"), this);
+    stopAct = new QAction(QtIconLoader::icon("media-playback-stop"), tr("&Stop"), this);
     stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
     stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
+    stopAct->setEnabled(false);
     actions->insert("stop", stopAct);
     connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
 
-    skipAct = new QAction(QtIconLoader::icon("media-skip-forward", QIcon(":/images/skip.png")), tr("S&kip"), this);
+    skipAct = new QAction(QtIconLoader::icon("media-skip-forward"), tr("S&kip"), this);
     skipAct->setStatusTip(tr("Skip to the next video"));
     skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
     skipAct->setEnabled(false);
     actions->insert("skip", skipAct);
     connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
 
-    pauseAct = new QAction(QtIconLoader::icon("media-playback-pause", QIcon(":/images/pause.png")), tr("&Pause"), this);
+    pauseAct = new QAction(QtIconLoader::icon("media-playback-pause"), tr("&Pause"), this);
     pauseAct->setStatusTip(tr("Pause playback"));
     pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
     pauseAct->setEnabled(false);
     actions->insert("pause", pauseAct);
     connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
 
-    fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen", QIcon(":/images/view-fullscreen.png")), tr("&Full Screen"), this);
+    fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen"), tr("&Full Screen"), this);
     fullscreenAct->setStatusTip(tr("Go full screen"));
     fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
     fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
+#if QT_VERSION >= 0x040600
+    fullscreenAct->setPriority(QAction::LowPriority);
+#endif
     actions->insert("fullscreen", fullscreenAct);
     connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
 
@@ -111,23 +139,27 @@ void MainWindow::createActions() {
     actions->insert("compactView", compactViewAct);
     connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
 
-    /*
-    // icon should be document-save but it is ugly
-    downloadAct = new QAction(QtIconLoader::icon("go-down", QIcon(":/images/go-down.png")), tr("&Download"), this);
-    downloadAct->setStatusTip(tr("Download this video"));
-    downloadAct->setShortcut(tr("Ctrl+S"));
-    downloadAct->setEnabled(false);
-    actions->insert("download", downloadAct);
-    connect(downloadAct, SIGNAL(triggered()), this, SLOT(download()));
-    */
-
-    webPageAct = new QAction(QtIconLoader::icon("internet-web-browser", QIcon(":/images/internet-web-browser.png")), tr("&YouTube"), this);
-    webPageAct->setStatusTip(tr("Open the YouTube video page"));
+    webPageAct = new QAction(tr("Open the &YouTube page"), this);
+    webPageAct->setStatusTip(tr("Go to the YouTube video page and pause playback"));
     webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
     webPageAct->setEnabled(false);
     actions->insert("webpage", webPageAct);
     connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
 
+    copyPageAct = new QAction(tr("Copy the YouTube &link"), this);
+    copyPageAct->setStatusTip(tr("Copy the current video YouTube link to the clipboard"));
+    copyPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
+    copyPageAct->setEnabled(false);
+    actions->insert("pagelink", copyPageAct);
+    connect(copyPageAct, SIGNAL(triggered()), mediaView, SLOT(copyWebPage()));
+
+    copyLinkAct = new QAction(tr("Copy the video stream &URL"), this);
+    copyLinkAct->setStatusTip(tr("Copy the current video stream URL to the clipboard"));
+    copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
+    copyLinkAct->setEnabled(false);
+    actions->insert("videolink", copyLinkAct);
+    connect(copyLinkAct, SIGNAL(triggered()), mediaView, SLOT(copyVideoLink()));
+
     removeAct = new QAction(tr("&Remove"), this);
     removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
     removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
@@ -135,26 +167,36 @@ void MainWindow::createActions() {
     actions->insert("remove", removeAct);
     connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
 
-    moveUpAct = new QAction(QtIconLoader::icon("go-up", QIcon(":/images/go-up.png")), tr("Move &Up"), this);
+    moveUpAct = new QAction(tr("Move &Up"), this);
     moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
     moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
     moveUpAct->setEnabled(false);
     actions->insert("moveUp", moveUpAct);
     connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
 
-    moveDownAct = new QAction(QtIconLoader::icon("go-down", QIcon(":/images/go-down.png")), tr("Move &Down"), this);
+    moveDownAct = new QAction(tr("Move &Down"), this);
     moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
     moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
     moveDownAct->setEnabled(false);
     actions->insert("moveDown", moveDownAct);
     connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
 
+    clearAct = new QAction(tr("&Clear recent keywords"), this);
+    clearAct->setMenuRole(QAction::ApplicationSpecificRole);
+    clearAct->setShortcuts(QList<QKeySequence>()
+                           << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete)
+                           << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
+    clearAct->setStatusTip(tr("Clear the search history. Cannot be undone."));
+    clearAct->setEnabled(true);
+    actions->insert("clearRecentKeywords", clearAct);
+    connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
+
     quitAct = new QAction(tr("&Quit"), this);
     quitAct->setMenuRole(QAction::QuitRole);
     quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
     quitAct->setStatusTip(tr("Bye"));
     actions->insert("quit", quitAct);
-    connect(quitAct, SIGNAL(triggered()), this, SLOT(quit()));
+    connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
 
     siteAct = new QAction(tr("&Website"), this);
     siteAct->setShortcut(QKeySequence::HelpContents);
@@ -162,7 +204,7 @@ void MainWindow::createActions() {
     actions->insert("site", siteAct);
     connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
 
-    donateAct = new QAction(tr("&Donate via PayPal"), this);
+    donateAct = new QAction(tr("Make a &donation"), this);
     donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
     actions->insert("donate", donateAct);
     connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
@@ -195,12 +237,60 @@ void MainWindow::createActions() {
     addAction(volumeDownAct);
 
     volumeMuteAct = new QAction(this);
+    volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
     volumeMuteAct->setStatusTip(tr("Mute volume"));
-    volumeMuteAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+M")) << QKeySequence(Qt::Key_VolumeMute));
+    volumeMuteAct->setShortcuts(QList<QKeySequence>()
+                                << QKeySequence(tr("Ctrl+M"))
+                                << QKeySequence(Qt::Key_VolumeMute));
     actions->insert("volume-mute", volumeMuteAct);
-    connect(volumeMuteAct, SIGNAL(triggered()), this, SLOT(volumeMute()));
+    connect(volumeMuteAct, SIGNAL(triggered()), SLOT(volumeMute()));
     addAction(volumeMuteAct);
 
+    QAction *definitionAct = new QAction(this);
+    definitionAct->setIcon(QtIconLoader::icon("video-display"));
+    definitionAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
+    /*
+    QMenu *definitionMenu = new QMenu(this);
+    foreach (QString definition, VideoDefinition::getDefinitionNames()) {
+        definitionMenu->addAction(definition);
+    }
+    definitionAct->setMenu(definitionMenu);
+    */
+    actions->insert("definition", definitionAct);
+    connect(definitionAct, SIGNAL(triggered()), SLOT(toggleDefinitionMode()));
+    addAction(definitionAct);
+
+    QAction *action;
+
+    /*
+    action = new QAction(tr("&Autoplay"), this);
+    action->setStatusTip(tr("Automatically start playing videos"));
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
+    action->setCheckable(true);
+    connect(action, SIGNAL(toggled(bool)), SLOT(setAutoplay(bool)));
+    actions->insert("autoplay", action);
+    */
+
+    action = new QAction(tr("&Downloads"), this);
+    action->setStatusTip(tr("Show details about video downloads"));
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_J));
+    action->setCheckable(true);
+    action->setIcon(QtIconLoader::icon("go-down"));
+    action->setVisible(false);
+    connect(action, SIGNAL(toggled(bool)), SLOT(toggleDownloads(bool)));
+    actions->insert("downloads", action);
+
+    action = new QAction(tr("&Download"), this);
+    action->setStatusTip(tr("Download the current video"));
+    action->setShortcut(QKeySequence::Save);
+    action->setIcon(QtIconLoader::icon("go-down"));
+    action->setEnabled(false);
+#if QT_VERSION >= 0x040600
+    action->setPriority(QAction::LowPriority);
+#endif
+    connect(action, SIGNAL(triggered()), mediaView, SLOT(downloadVideo()));
+    actions->insert("download", action);
+
     // common action properties
     foreach (QAction *action, actions->values()) {
 
@@ -211,19 +301,18 @@ void MainWindow::createActions() {
         // never autorepeat.
         // unexperienced users tend to keep keys pressed for a "long" time
         action->setAutoRepeat(false);
-        action->setToolTip(action->statusTip());
+
+        // set to something more meaningful then the toolbar text
+        // HELP! how to remove tooltips altogether?!
+        if (!action->statusTip().isEmpty())
+            action->setToolTip(action->statusTip());
 
         // show keyboard shortcuts in the status bar
         if (!action->shortcut().isEmpty())
             action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
 
-        // make the actions work when video is fullscreen
-        action->setShortcutContext(Qt::ApplicationShortcut);
-
-#ifdef Q_WS_MAC
-        // OSX does not use icons in menus
+        // no icons in menus
         action->setIconVisibleInMenu(false);
-#endif
 
     }
 
@@ -233,13 +322,13 @@ void MainWindow::createMenus() {
 
     QMap<QString, QMenu*> *menus = The::globalMenus();
 
-    /*
     fileMenu = menuBar()->addMenu(tr("&Application"));
     // menus->insert("file", fileMenu);
-    // fileMenu->addAction(settingsAct);
+    fileMenu->addAction(clearAct);
+#ifndef APP_MAC
     fileMenu->addSeparator();
+#endif
     fileMenu->addAction(quitAct);
-    */
 
     playlistMenu = menuBar()->addMenu(tr("&Playlist"));
     menus->insert("playlist", playlistMenu);
@@ -250,16 +339,22 @@ void MainWindow::createMenus() {
 
     viewMenu = menuBar()->addMenu(tr("&Video"));
     menus->insert("video", viewMenu);
-    // viewMenu->addAction(backAct);
     viewMenu->addAction(stopAct);
     viewMenu->addAction(pauseAct);
     viewMenu->addAction(skipAct);
     viewMenu->addSeparator();
+    viewMenu->addAction(The::globalActions()->value("download"));
+    viewMenu->addSeparator();
     viewMenu->addAction(webPageAct);
+    viewMenu->addAction(copyPageAct);
+    viewMenu->addAction(copyLinkAct);
     viewMenu->addSeparator();
-    // viewMenu->addAction(downloadAct);
     viewMenu->addAction(compactViewAct);
     viewMenu->addAction(fullscreenAct);
+#ifdef APP_MAC
+    extern void qt_mac_set_dock_menu(QMenu *);
+    qt_mac_set_dock_menu(viewMenu);
+#endif
 
     helpMenu = menuBar()->addMenu(tr("&Help"));
     helpMenu->addAction(siteAct);
@@ -269,59 +364,86 @@ void MainWindow::createMenus() {
 
 void MainWindow::createToolBars() {
 
-    setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+    setUnifiedTitleAndToolBarOnMac(true);
 
     mainToolBar = new QToolBar(this);
+#if QT_VERSION < 0x040600 | defined(APP_MAC)
+    mainToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
+#else
+    mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
+#endif
     mainToolBar->setFloatable(false);
     mainToolBar->setMovable(false);
 
-    QFont smallerFont;
-    smallerFont.setPointSize(smallerFont.pointSize()*.85);
-    mainToolBar->setFont(smallerFont);
+#ifdef APP_MAC
+    mainToolBar->setIconSize(QSize(32, 32));
+#endif
 
-    mainToolBar->setIconSize(QSize(32,32));
-    // mainToolBar->addAction(backAct);
     mainToolBar->addAction(stopAct);
     mainToolBar->addAction(pauseAct);
     mainToolBar->addAction(skipAct);
     mainToolBar->addAction(fullscreenAct);
+    mainToolBar->addAction(The::globalActions()->value("download"));
+
+    mainToolBar->addWidget(new Spacer());
+
+    QFont smallerFont = FontUtils::small();
+    currentTime = new QLabel(mainToolBar);
+    currentTime->setFont(smallerFont);
+    mainToolBar->addWidget(currentTime);
+
+    mainToolBar->addWidget(new Spacer());
 
     seekSlider = new Phonon::SeekSlider(this);
     seekSlider->setIconVisible(false);
-    Spacer *seekSliderSpacer = new Spacer(mainToolBar, seekSlider);
-    seekSliderSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-    mainToolBar->addWidget(seekSliderSpacer);
+    seekSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+    mainToolBar->addWidget(seekSlider);
+
+    mainToolBar->addWidget(new Spacer());
+
+    totalTime = new QLabel(mainToolBar);
+    totalTime->setFont(smallerFont);
+    mainToolBar->addWidget(totalTime);
+
+    mainToolBar->addWidget(new Spacer());
+
+    mainToolBar->addAction(volumeMuteAct);
 
     volumeSlider = new Phonon::VolumeSlider(this);
+    volumeSlider->setMuteVisible(false);
     // qDebug() << volumeSlider->children();
     // status tip for the volume slider
     QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
     if (volumeQSlider)
         volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
                 volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
-    // status tip for the mute button
-    QToolButton* muteToolButton = volumeSlider->findChild<QToolButton*>();
-    if (muteToolButton)
-        muteToolButton->setStatusTip(volumeMuteAct->statusTip());
     // this makes the volume slider smaller
     volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-    mainToolBar->addWidget(new Spacer(mainToolBar, volumeSlider));
+    mainToolBar->addWidget(volumeSlider);
+
+    mainToolBar->addWidget(new Spacer());
 
     toolbarSearch->setStatusTip(searchFocusAct->statusTip());
-    mainToolBar->addWidget(new Spacer(mainToolBar, toolbarSearch));
+    mainToolBar->addWidget(toolbarSearch);
+
+    mainToolBar->addWidget(new Spacer());
 
     addToolBar(mainToolBar);
 }
 
 void MainWindow::createStatusBar() {
-    currentTime = new QLabel(this);
-    statusBar()->addPermanentWidget(currentTime);
-
-    totalTime = new QLabel(this);
-    statusBar()->addPermanentWidget(totalTime);
 
     // remove ugly borders on OSX
-    statusBar()->setStyleSheet("::item{border:0 solid}");
+    // also remove excessive spacing
+    statusBar()->setStyleSheet("::item{border:0 solid} QToolBar {padding:0;spacing:0;margin:0}");
+
+    QToolBar *toolBar = new QToolBar(this);
+    toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    toolBar->setIconSize(QSize(16, 16));
+    toolBar->addAction(The::globalActions()->value("downloads"));
+    // toolBar->addAction(The::globalActions()->value("autoplay"));
+    toolBar->addAction(The::globalActions()->value("definition"));
+    statusBar()->addPermanentWidget(toolBar);
 
     statusBar()->show();
 }
@@ -329,14 +451,26 @@ void MainWindow::createStatusBar() {
 void MainWindow::readSettings() {
     QSettings settings;
     restoreGeometry(settings.value("geometry").toByteArray());
+#ifdef APP_MAC
+    if (!isMaximized())
+        move(x(), y() + mainToolBar->height() + 8);
+#endif
+    setDefinitionMode(settings.value("definition", VideoDefinition::getDefinitionNames().first()).toString());
+    audioOutput->setVolume(settings.value("volume", 1).toDouble());
+    audioOutput->setMuted(settings.value("volumeMute").toBool());
 }
 
 void MainWindow::writeSettings() {
-    // do not save geometry when in full screen
-    if (m_fullscreen)
-        return;
+
     QSettings settings;
-    settings.setValue("geometry", saveGeometry());
+
+    // do not save geometry when in full screen
+    if (!m_fullscreen) {
+        settings.setValue("geometry", saveGeometry());
+    }
+
+    settings.setValue("volume", audioOutput->volume());
+    settings.setValue("volumeMute", audioOutput->isMuted());
     mediaView->saveSplitterState();
 }
 
@@ -354,13 +488,13 @@ void MainWindow::showWidget ( QWidget* widget ) {
 
     // call hide method on the current view
     View* oldView = dynamic_cast<View *> (views->currentWidget());
-    if (oldView != NULL) {
+    if (oldView) {
         oldView->disappear();
     }
 
     // call show method on the new view
     View* newView = dynamic_cast<View *> (widget);
-    if (newView != NULL) {
+    if (newView) {
         newView->appear();
         QMap<QString,QVariant> metadata = newView->metadata();
         QString windowTitle = metadata.value("title").toString();
@@ -368,48 +502,46 @@ void MainWindow::showWidget ( QWidget* widget ) {
             windowTitle += " - ";
         setWindowTitle(windowTitle + Constants::APP_NAME);
         statusBar()->showMessage((metadata.value("description").toString()));
-
     }
 
-    // backAct->setEnabled(history->size() > 1);
-    // settingsAct->setEnabled(widget != settingsView);
     stopAct->setEnabled(widget == mediaView);
     fullscreenAct->setEnabled(widget == mediaView);
     compactViewAct->setEnabled(widget == mediaView);
     webPageAct->setEnabled(widget == mediaView);
+    copyPageAct->setEnabled(widget == mediaView);
+    copyLinkAct->setEnabled(widget == mediaView);
     aboutAct->setEnabled(widget != aboutView);
-
-    /*
-    // this is not the best place to enable downloads, but the user is informed
-    // if there really is no video is playing
-    downloadAct->setEnabled(widget == mediaView);
-    */
-
-    // cool toolbar on the Mac
-    // setUnifiedTitleAndToolBarOnMac(widget == mediaView);
+    The::globalActions()->value("download")->setEnabled(widget == mediaView);
+    The::globalActions()->value("downloads")->setChecked(widget == downloadView);
 
     // toolbar only for the mediaView
-    mainToolBar->setVisible(widget == mediaView && !compactViewAct->isChecked());
+    /* mainToolBar->setVisible(
+            (widget == mediaView && !compactViewAct->isChecked())
+            || widget == downloadView
+            ); */
 
-    history->push(widget);
+    setUpdatesEnabled(true);
+
+    QWidget *oldWidget = views->currentWidget();
+    views->setCurrentWidget(widget);
 
-#ifdef Q_WS_MAC
+#ifdef APP_MAC
     // crossfade only on OSX
     // where we can be sure of video performance
-    fadeInWidget(views->currentWidget(), widget);
+    fadeInWidget(oldWidget, widget);
 #endif
 
-    views->setCurrentWidget(widget);
-
-    setUpdatesEnabled(true);
+    history->push(widget);
 }
 
 void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
     if (faderWidget) faderWidget->close();
-    if (oldWidget == mediaView || newWidget == mediaView) return;
-    QPixmap frozenView = QPixmap::grabWidget(oldWidget);
+    if (!oldWidget || !newWidget) {
+        // qDebug() << "no widgets";
+        return;
+    }
     faderWidget = new FaderWidget(newWidget);
-    faderWidget->start(frozenView);
+    faderWidget->start(QPixmap::grabWidget(oldWidget));
 }
 
 void MainWindow::about() {
@@ -438,16 +570,26 @@ void MainWindow::quit() {
 }
 
 void MainWindow::closeEvent(QCloseEvent *event) {
-    quit();
-    QWidget::closeEvent(event);
-}
+    if (DownloadManager::instance()->activeItems() > 0) {
+        QMessageBox msgBox;
+        msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+        msgBox.setText(tr("Do you want to exit %1 with a download in progress?").arg(Constants::APP_NAME));
+        msgBox.setInformativeText(tr("If you close %1 now, this download will be cancelled.").arg(Constants::APP_NAME));
+        msgBox.setModal(true);
+
+        msgBox.addButton(tr("Close and cancel download"), QMessageBox::RejectRole);
+        QPushButton *waitButton = msgBox.addButton(tr("Wait for download to finish"), QMessageBox::ActionRole);
+
+        msgBox.exec();
+
+        if (msgBox.clickedButton() == waitButton) {
+            event->ignore();
+            return;
+        }
 
-void MainWindow::showSettings() {
-    if (!settingsView) {
-        settingsView = new SettingsView(this);
-        views->addWidget(settingsView);
     }
-    showWidget(settingsView);
+    quit();
+    QWidget::closeEvent(event);
 }
 
 void MainWindow::showSearch() {
@@ -457,8 +599,6 @@ void MainWindow::showSearch() {
 }
 
 void MainWindow::showMedia(QString query) {
-    initPhonon();
-    mediaView->setMediaObject(mediaObject);
     SearchParams *searchParams = new SearchParams();
     searchParams->setKeywords(query);
     mediaView->search(searchParams);
@@ -471,7 +611,7 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState
 
     switch (newState) {
 
-         case Phonon::ErrorState:
+    case Phonon::ErrorState:
         if (mediaObject->errorType() == Phonon::FatalError) {
             statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
         } else {
@@ -481,23 +621,26 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState
 
          case Phonon::PlayingState:
         pauseAct->setEnabled(true);
-        pauseAct->setIcon(QtIconLoader::icon("media-playback-pause", QIcon(":/images/pause.png")));
+        pauseAct->setIcon(QtIconLoader::icon("media-playback-pause"));
         pauseAct->setText(tr("&Pause"));
         pauseAct->setStatusTip(tr("Pause playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
         skipAct->setEnabled(true);
+        // stopAct->setEnabled(true);
         break;
 
          case Phonon::StoppedState:
         pauseAct->setEnabled(false);
         skipAct->setEnabled(false);
+        // stopAct->setEnabled(false);
         break;
 
          case Phonon::PausedState:
         skipAct->setEnabled(true);
         pauseAct->setEnabled(true);
-        pauseAct->setIcon(QtIconLoader::icon("media-playback-start", QIcon(":/images/play.png")));
+        pauseAct->setIcon(QtIconLoader::icon("media-playback-start"));
         pauseAct->setText(tr("&Play"));
         pauseAct->setStatusTip(tr("Resume playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
+        // stopAct->setEnabled(true);
         break;
 
          case Phonon::BufferingState:
@@ -506,6 +649,7 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState
         pauseAct->setEnabled(false);
         currentTime->clear();
         totalTime->clear();
+        // stopAct->setEnabled(true);
         break;
 
          default:
@@ -520,19 +664,69 @@ void MainWindow::stop() {
 
 void MainWindow::fullscreen() {
 
-    setUpdatesEnabled(false);
+    // No compact view action when in full screen
+    compactViewAct->setVisible(m_fullscreen);
+    compactViewAct->setChecked(false);
+
+    // Also no Youtube action since it opens a new window
+    webPageAct->setVisible(m_fullscreen);
+    copyPageAct->setVisible(m_fullscreen);
+    copyLinkAct->setVisible(m_fullscreen);
+
+    stopAct->setVisible(m_fullscreen);
+
+    // workaround: prevent focus on the search bar
+    // it steals the Space key needed for Play/Pause
+    toolbarSearch->setEnabled(m_fullscreen);
+
+    // Hide anything but the video
+    mediaView->setPlaylistVisible(m_fullscreen);
+    statusBar()->setVisible(m_fullscreen);
+
+#ifndef APP_MAC
+    menuBar()->setVisible(m_fullscreen);
+#endif
+
+#ifdef APP_MAC
+    // make the actions work when video is fullscreen (on the Mac)
+    QMap<QString, QAction*> *actions = The::globalActions();
+    foreach (QAction *action, actions->values()) {
+        if (m_fullscreen) {
+            action->setShortcutContext(Qt::WindowShortcut);
+        } else {
+            action->setShortcutContext(Qt::ApplicationShortcut);
+        }
+    }
+#endif
 
     if (m_fullscreen) {
-        // use setShortucs instead of setShortcut
+
+        // Exit full screen
+
+        // use setShortcuts instead of setShortcut
         // the latter seems not to work
         fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
         fullscreenAct->setText(tr("&Full Screen"));
         stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
+
+#ifdef APP_MAC
+        setCentralWidget(views);
+        views->showNormal();
+        show();
+        mediaView->setFocus();
+#else
+        mainToolBar->show();
         if (m_maximized) showMaximized();
         else showNormal();
-        // Make sure the window has focus (Mac)
+#endif
+
+        // Make sure the window has focus
         activateWindow();
+
     } else {
+
+        // Enter full screen
+
         stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
         fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
         fullscreenAct->setText(tr("Exit &Full Screen"));
@@ -542,64 +736,50 @@ void MainWindow::fullscreen() {
         // geometry won't be saved
         writeSettings();
 
+#ifdef APP_MAC
+        hide();
+        views->setParent(0);
+        QTimer::singleShot(0, views, SLOT(showFullScreen()));
+#else
+        mainToolBar->hide();
         showFullScreen();
-    }
-
-    // No compact view action when in full screen
-    compactViewAct->setVisible(m_fullscreen);
-    // Also no Youtube action since it opens a new window
-    webPageAct->setVisible(m_fullscreen);
-
-    // Hide anything but the video
-    mediaView->setPlaylistVisible(m_fullscreen);
-    mainToolBar->setVisible(m_fullscreen);
-    statusBar()->setVisible(m_fullscreen);
-    menuBar()->setVisible(m_fullscreen);
+#endif
 
-    // workaround: prevent focus on the search bar
-    // it steals the Space key needed for Play/Pause
-    mainToolBar->setEnabled(m_fullscreen);
+    }
 
     m_fullscreen = !m_fullscreen;
 
-    setUpdatesEnabled(true);
 }
 
 void MainWindow::compactView(bool enable) {
 
-    setUpdatesEnabled(false);
-
-    // setUnifiedTitleAndToolBarOnMac(!enable);
     mediaView->setPlaylistVisible(!enable);
-    mainToolBar->setVisible(!enable);
     statusBar()->setVisible(!enable);
 
-
-#ifndef Q_WS_MAC
+#ifndef APP_MAC
     menuBar()->setVisible(!enable);
 #endif
 
-    // ensure focus does not end up to the search box
-    // as it would steal the Space shortcut
-    toolbarSearch->setEnabled(!enable);
-
     if (enable) {
-        stopAct->setShortcut(QString(""));
-        QList<QKeySequence> shortcuts;
-        // for some reason it is important that ESC comes first
-        shortcuts << QKeySequence(Qt::CTRL + Qt::Key_Return) << QKeySequence(Qt::Key_Escape);
-        compactViewAct->setShortcuts(shortcuts);
+        stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
+        compactViewAct->setShortcuts(
+                QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Return)
+                << QKeySequence(Qt::Key_Escape));
+
+        // ensure focus does not end up to the search box
+        // as it would steal the Space shortcut
+        mediaView->setFocus();
     } else {
-        compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
-        stopAct->setShortcut(QKeySequence(Qt::Key_Escape));
+        compactViewAct->setShortcuts(QList<QKeySequence>() <<  QKeySequence(Qt::CTRL + Qt::Key_Return));
+        stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
     }
 
-    setUpdatesEnabled(true);
 }
 
 void MainWindow::searchFocus() {
     QWidget *view = views->currentWidget();
     if (view == mediaView) {
+        toolbarSearch->selectAll();
         toolbarSearch->setFocus();
     }
 }
@@ -627,15 +807,13 @@ void MainWindow::tick(qint64 time) {
         currentTime->clear();
         return;
     }
-    QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
-    currentTime->setText(displayTime.toString("mm:ss"));
 
-    // remaining time tooltip
-    int remainingTimeInt = mediaObject->remainingTime();
-    QTime remainingTime(0, (remainingTimeInt / 60000) % 60, (remainingTimeInt / 1000) % 60);
-    currentTime->setStatusTip(tr("Remaining time: %1").arg(remainingTime.toString("mm:ss")));
+    currentTime->setText(formatTime(time));
+
+    // remaining time
+    const qint64 remainingTime = mediaObject->remainingTime();
+    currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
 
-    // qDebug() << "currentTime" << time << displayTime.toString("mm:ss");
 }
 
 void MainWindow::totalTimeChanged(qint64 time) {
@@ -643,9 +821,19 @@ void MainWindow::totalTimeChanged(qint64 time) {
         totalTime->clear();
         return;
     }
-    QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
-    totalTime->setText(displayTime.toString("/ mm:ss"));
-    // qDebug() << "totalTime" << time << displayTime.toString("mm:ss");
+    totalTime->setText(formatTime(time));
+}
+
+QString MainWindow::formatTime(qint64 time) {
+    QTime displayTime;
+    displayTime = displayTime.addMSecs(time);
+    QString timeString;
+    // 60 * 60 * 1000 = 3600000
+    if (time > 3600000)
+        timeString = displayTime.toString("h:mm:ss");
+    else
+        timeString = displayTime.toString("m:ss");
+    return timeString;
 }
 
 void MainWindow::volumeUp() {
@@ -674,94 +862,88 @@ void MainWindow::volumeChanged(qreal newVolume) {
 }
 
 void MainWindow::volumeMutedChanged(bool muted) {
-    if (muted)
+    if (muted) {
+        volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-muted"));
         statusBar()->showMessage(tr("Volume is muted"));
-    else
+    } else {
+        volumeMuteAct->setIcon(QtIconLoader::icon("audio-volume-high"));
         statusBar()->showMessage(tr("Volume is unmuted"));
+    }
 }
 
-/*
-void MainWindow::abortDownload() {
-    QProgressDialog* dlg = dynamic_cast<QProgressDialog*>(this->sender());
-    QMap<QNetworkReply*, DownloadResource>::iterator cur;
-    QMap<QNetworkReply*, DownloadResource>::iterator end;
-    // locate the DownloadResource by its dialog address and trigger abortion
-    for(cur=m_downloads.begin(), end=m_downloads.end(); cur!=end; cur++){
-        if(cur.value().dialog == dlg) cur.key()->abort();
-    }
+void MainWindow::setDefinitionMode(QString definitionName) {
+    QAction *definitionAct = The::globalActions()->value("definition");
+    definitionAct->setText(definitionName);
+    definitionAct->setStatusTip(tr("Maximum video definition set to %1").arg(definitionAct->text())
+                                + " (" +  definitionAct->shortcut().toString(QKeySequence::NativeText) + ")");
+    statusBar()->showMessage(definitionAct->statusTip());
+    QSettings settings;
+    settings.setValue("definition", definitionName);
 }
 
-void MainWindow::download() {
-    if(mediaObject == NULL || mediaObject->currentSource().url().isEmpty()){
-        // complain unless video source apperas to be valid
-        QMessageBox::critical(this, tr("No Video playing"), tr("You must first play the video you intent to download !"));
-        return;
-    }
-    QString filename = QFileDialog::getSaveFileName(this,
-                                                    tr("Save video as..."),
-                                                    tr("minitube video.mp4"),
-                                                    "Video File(*.avi *.mp4)"
-                                                    );
-    if(!filename.isNull()) {
-        // open destination file and initialize download
-        DownloadResource res;
-        res.file = new QFile(filename);
-        if(res.file->open(QFile::WriteOnly) == true) {
-            res.dialog = new QProgressDialog(tr("Downloading: ") + res.file->fileName(),
-                                             tr("Abort Download"), 0, 100, this);
-            connect(res.dialog, SIGNAL(canceled()), this, SLOT(abortDownload()));
-            download(mediaObject->currentSource().url(), res);
-        }else{
-            QMessageBox::critical(this, tr("File creation failed"), res.file->errorString());
-            delete res.file;
-        }
+void MainWindow::toggleDefinitionMode() {
+    QSettings settings;
+    QString currentDefinition = settings.value("definition").toString();
+    QStringList definitionNames = VideoDefinition::getDefinitionNames();
+    int currentIndex = definitionNames.indexOf(currentDefinition);
+    int nextIndex = 0;
+    if (currentIndex != definitionNames.size() - 1) {
+        nextIndex = currentIndex + 1;
     }
+    QString nextDefinition = definitionNames.at(nextIndex);
+    setDefinitionMode(nextDefinition);
 }
 
-void MainWindow::download(const QUrl& url, const DownloadResource& res) {
-    // create and store request and connect the reply signals
-    QNetworkReply *r = The::networkAccessManager()->get(QNetworkRequest(url));
-    m_downloads.insert(r, res);
-    connect(r, SIGNAL(finished()), this, SLOT(replyFinished()));
-    connect(r, SIGNAL(readyRead()), this, SLOT(replyReadyRead()));
-    connect(r, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(replyError(QNetworkReply::NetworkError)));
-    connect(r, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(replyDownloadProgress(qint64,qint64)));
-    connect(r, SIGNAL(metaDataChanged()), this, SLOT(replyMetaDataChanged()));
+void MainWindow::showFullscreenToolbar(bool show) {
+    if (!m_fullscreen) return;
+    mainToolBar->setVisible(show);
 }
 
-void MainWindow::replyReadyRead() {
-    QNetworkReply* r = dynamic_cast<QNetworkReply*>(this->sender());
-    m_downloads[r].file->write(r->readAll());
+void MainWindow::showFullscreenPlaylist(bool show) {
+    if (!m_fullscreen) return;
+    mediaView->setPlaylistVisible(show);
 }
 
-void MainWindow::replyDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
-    QNetworkReply* r = dynamic_cast<QNetworkReply*>(this->sender());
-    if (bytesTotal > 0 && bytesReceived >0)
-        m_downloads[r].dialog->setValue( double(100.0/bytesTotal)*bytesReceived );  // pssst :-X
+void MainWindow::clearRecentKeywords() {
+    QSettings settings;
+    settings.remove("recentKeywords");
+    searchView->updateRecentKeywords();
+    statusBar()->showMessage(tr("Your privacy is now safe"));
 }
 
-void MainWindow::replyError(QNetworkReply::NetworkError code) {
-    QNetworkReply* r = dynamic_cast<QNetworkReply*>(this->sender());
-    QMessageBox::critical(this, tr("Download failed"), r->errorString());
+/*
+ void MainWindow::setAutoplay(bool enabled) {
+     QSettings settings;
+     settings.setValue("autoplay", QVariant::fromValue(enabled));
+ }
+ */
+
+void MainWindow::updateDownloadMessage(QString message) {
+    The::globalActions()->value("downloads")->setText(message);
 }
 
-void MainWindow::replyFinished() {
-    QNetworkReply* r = dynamic_cast<QNetworkReply*>(this->sender());
-    m_downloads[r].dialog->close();
-    m_downloads[r].file->close();
-    delete m_downloads[r].file;
-    m_downloads.remove(r);
+void MainWindow::downloadsFinished() {
+    The::globalActions()->value("downloads")->setText(tr("&Downloads"));
+    statusBar()->showMessage(tr("Downloads complete"));
 }
 
-void MainWindow::replyMetaDataChanged() {
-    QNetworkReply* r = dynamic_cast<QNetworkReply*>(this->sender());
-    QUrl url = r->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
-    if(url.isValid()) {
-        // redirect - request new url, but keep the resources
-        qDebug() << "redirecting to: " << url.toString();
-        download(url, m_downloads[r]);
-        m_downloads.remove(r);
+void MainWindow::toggleDownloads(bool show) {
+
+    if (show) {
+        stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
+        The::globalActions()->value("downloads")->setShortcuts(
+                QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J)
+                << QKeySequence(Qt::Key_Escape));
+    } else {
+        The::globalActions()->value("downloads")->setShortcuts(
+                QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_J));
+        stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
+    }
+
+    if (!downloadView) {
+        downloadView = new DownloadView(this);
+        views->addWidget(downloadView);
     }
+    if (show) showWidget(downloadView);
+    else goBack();
 }
-
-*/