]> git.sur5r.net Git - minitube/blobdiff - src/mainwindow.cpp
Change VideoDefinition class interface.
[minitube] / src / mainwindow.cpp
index 9ea7777b1c29fa42f7c58a832dcd258ba5219a85..29794cff7fe530cce47460d982765b2aa0f3926a 100644 (file)
@@ -26,7 +26,7 @@ $END_LICENSE */
 #include "downloadview.h"
 #include "spacer.h"
 #include "constants.h"
-#include "utils.h"
+#include "iconutils.h"
 #include "global.h"
 #include "videodefinition.h"
 #include "fontutils.h"
@@ -70,11 +70,15 @@ $END_LICENSE */
 #include "videoareawidget.h"
 #include "jsfunctions.h"
 #include "seekslider.h"
+#ifdef APP_YT3
+#include "yt3.h"
+#endif
 
+namespace {
 static MainWindow *singleton = 0;
+}
 
 MainWindow* MainWindow::instance() {
-    if (!singleton) singleton = new MainWindow();
     return singleton;
 }
 
@@ -92,6 +96,10 @@ MainWindow::MainWindow() :
 
     singleton = this;
 
+#ifdef APP_EXTRA
+    Extra::windowSetup(this);
+#endif
+
     // views mechanism
     history = new QStack<QWidget*>();
     views = new QStackedWidget();
@@ -139,10 +147,6 @@ MainWindow::MainWindow() :
 
     views->show();
 
-#ifdef APP_EXTRA
-    Extra::windowSetup(this);
-#endif
-
     qApp->processEvents();
     QTimer::singleShot(50, this, SLOT(lazyInit()));
 }
@@ -204,8 +208,6 @@ void MainWindow::lazyInit() {
     JsFunctions::instance();
 
     checkForUpdate();
-
-    ChannelAggregator::instance()->start();
 }
 
 void MainWindow::changeEvent(QEvent* event) {
@@ -230,7 +232,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
 
         // qDebug() << obj << mouseEvent->pos() << isHoveringVideo << mediaView->isPlaylistVisible();
 
-        if (mediaView->isPlaylistVisible()) {
+        if (mediaView && mediaView->isPlaylistVisible()) {
             if (isHoveringVideo && x > 5) mediaView->setPlaylistVisible(false);
         } else {
             if (isHoveringVideo && x >= 0 && x < 5) mediaView->setPlaylistVisible(true);
@@ -264,7 +266,7 @@ void MainWindow::createActions() {
 
     QHash<QString, QAction*> *actions = The::globalActions();
 
-    stopAct = new QAction(Utils::icon("media-playback-stop"), tr("&Stop"), this);
+    stopAct = new QAction(IconUtils::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);
@@ -272,7 +274,7 @@ void MainWindow::createActions() {
     connect(stopAct, SIGNAL(triggered()), SLOT(stop()));
 
     skipBackwardAct = new QAction(
-                Utils::icon("media-skip-backward"),
+                IconUtils::icon("media-skip-backward"),
                 tr("P&revious"), this);
     skipBackwardAct->setStatusTip(tr("Go back to the previous track"));
     skipBackwardAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left));
@@ -280,21 +282,21 @@ void MainWindow::createActions() {
     actions->insert("previous", skipBackwardAct);
     connect(skipBackwardAct, SIGNAL(triggered()), mediaView, SLOT(skipBackward()));
 
-    skipAct = new QAction(Utils::icon("media-skip-forward"), tr("S&kip"), this);
+    skipAct = new QAction(IconUtils::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(Utils::icon("media-playback-pause"), tr("&Pause"), this);
-    pauseAct->setStatusTip(tr("Pause playback"));
+    pauseAct = new QAction(IconUtils::icon("media-playback-start"), tr("&Play"), this);
+    pauseAct->setStatusTip(tr("Resume 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(Utils::icon("view-fullscreen"), tr("&Full Screen"), this);
+    fullscreenAct = new QAction(IconUtils::icon("view-fullscreen"), tr("&Full Screen"), this);
     fullscreenAct->setStatusTip(tr("Go full screen"));
     QList<QKeySequence> fsShortcuts;
 #ifdef APP_MAC
@@ -428,7 +430,7 @@ void MainWindow::createActions() {
     addAction(volumeDownAct);
 
     volumeMuteAct = new QAction(this);
-    volumeMuteAct->setIcon(Utils::icon("audio-volume-high"));
+    volumeMuteAct->setIcon(IconUtils::icon("audio-volume-high"));
     volumeMuteAct->setStatusTip(tr("Mute volume"));
     volumeMuteAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_K));
     actions->insert("volume-mute", volumeMuteAct);
@@ -437,10 +439,10 @@ void MainWindow::createActions() {
 
     QAction *definitionAct = new QAction(this);
 #ifdef Q_OS_LINUX
-    definitionAct->setIcon(Utils::tintedIcon("video-display", QColor(0, 0, 0),
-                                             QList<QSize>() << QSize(16, 16)));
+    definitionAct->setIcon(IconUtils::tintedIcon("video-display", QColor(0, 0, 0),
+                                                 QList<QSize>() << QSize(16, 16)));
 #else
-    definitionAct->setIcon(Utils::icon("video-display"));
+    definitionAct->setIcon(IconUtils::icon("video-display"));
 #endif
     definitionAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
     /*
@@ -456,7 +458,7 @@ void MainWindow::createActions() {
 
     QAction *action;
 
-    action = new QAction(Utils::icon("media-playback-start"), tr("&Manually Start Playing"), this);
+    action = new QAction(IconUtils::icon("media-playback-start"), tr("&Manually Start Playing"), this);
     action->setStatusTip(tr("Manually start playing videos"));
     action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T));
     action->setCheckable(true);
@@ -467,7 +469,7 @@ void MainWindow::createActions() {
     action->setStatusTip(tr("Show details about video downloads"));
     action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_J));
     action->setCheckable(true);
-    action->setIcon(Utils::icon("document-save"));
+    action->setIcon(IconUtils::icon("document-save"));
     action->setVisible(false);
     connect(action, SIGNAL(toggled(bool)), SLOT(toggleDownloads(bool)));
     actions->insert("downloads", action);
@@ -475,7 +477,7 @@ void MainWindow::createActions() {
     action = new QAction(tr("&Download"), this);
     action->setStatusTip(tr("Download the current video"));
     action->setShortcut(QKeySequence::Save);
-    action->setIcon(Utils::icon("document-save"));
+    action->setIcon(IconUtils::icon("document-save"));
     action->setEnabled(false);
     action->setVisible(false);
     action->setPriority(QAction::LowPriority);
@@ -534,12 +536,12 @@ void MainWindow::createActions() {
     actions->insert("restore", action);
     connect(action, SIGNAL(triggered()), SLOT(restore()));
 
-    action = new QAction(Utils::icon("go-top"), tr("&Float on Top"), this);
+    action = new QAction(IconUtils::icon("go-top"), tr("&Float on Top"), this);
     action->setCheckable(true);
     actions->insert("ontop", action);
     connect(action, SIGNAL(toggled(bool)), SLOT(floatOnTop(bool)));
 
-    action = new QAction(Utils::icon("media-playback-stop"), tr("&Stop After This Video"), this);
+    action = new QAction(IconUtils::icon("media-playback-stop"), tr("&Stop After This Video"), this);
     action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Escape));
     action->setCheckable(true);
     action->setEnabled(false);
@@ -565,7 +567,7 @@ void MainWindow::createActions() {
     action = new QAction(tr("More..."), this);
     actions->insert("more-region", action);
 
-    action = new QAction(Utils::icon(QStringList() << "view-list-symbolic" << "view-list" << "format-justify-fill"), tr("&Related Videos"), this);
+    action = new QAction(IconUtils::icon("view-list"), tr("&Related Videos"), this);
     action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
     action->setStatusTip(tr("Watch videos related to the current one"));
     action->setEnabled(false);
@@ -594,7 +596,7 @@ void MainWindow::createActions() {
         // add actions to the MainWindow so that they work
         // when the menu is hidden
         addAction(action);
-        Utils::setupAction(action);
+        IconUtils::setupAction(action);
     }
 }
 
@@ -727,6 +729,7 @@ void MainWindow::createToolBars() {
 
 #ifdef APP_PHONON_SEEK
     seekSlider = new Phonon::SeekSlider(this);
+    seekSlider->setTracking(true);
     seekSlider->setIconVisible(false);
     seekSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
     mainToolBar->addWidget(seekSlider);
@@ -749,6 +752,10 @@ void MainWindow::createToolBars() {
 
     mainToolBar->addWidget(new Spacer());
     mainToolBar->addAction(volumeMuteAct);
+#ifdef Q_WS_X11
+    QToolButton *volumeMuteButton = qobject_cast<QToolButton *>(mainToolBar->widgetForAction(volumeMuteAct));
+    volumeMuteButton->setIcon(volumeMuteButton->icon().pixmap(16));
+#endif
 
 #ifdef APP_PHONON
     volumeSlider = new Phonon::VolumeSlider(this);
@@ -774,8 +781,8 @@ void MainWindow::createToolBars() {
 #endif
     toolbarSearch->setMinimumWidth(toolbarSearch->fontInfo().pixelSize()*15);
     toolbarSearch->setSuggester(new YTSuggester(this));
-    connect(toolbarSearch, SIGNAL(search(const QString&)), this, SLOT(startToolbarSearch(const QString&)));
-    connect(toolbarSearch, SIGNAL(suggestionAccepted(const QString&)), SLOT(startToolbarSearch(const QString&)));
+    connect(toolbarSearch, SIGNAL(search(const QString&)), SLOT(search(const QString&)));
+    connect(toolbarSearch, SIGNAL(suggestionAccepted(Suggestion*)), SLOT(suggestionAccepted(Suggestion*)));
     toolbarSearch->setStatusTip(searchFocusAct->statusTip());
 #ifdef APP_MAC
     mainToolBar->addWidget(searchWrapper);
@@ -852,7 +859,8 @@ void MainWindow::readSettings() {
     } else {
         setGeometry(100, 100, 1000, 500);
     }
-    setDefinitionMode(settings.value("definition", VideoDefinition::getDefinitionNames().first()).toString());
+    const VideoDefinition& firstDefinition = VideoDefinition::getDefinitions().first();
+    setDefinitionMode(settings.value("definition", firstDefinition.getName()).toString());
     The::globalActions()->value("manualplay")->setChecked(settings.value("manualplay", false).toBool());
 }
 
@@ -977,7 +985,7 @@ void MainWindow::quit() {
     if (!m_fullscreen && !compactViewAct->isChecked()) {
         writeSettings();
     }
-    mediaView->stop();
+    // mediaView->stop();
     Temporary::deleteAll();
     ChannelAggregator::instance()->stop();
     ChannelAggregator::instance()->cleanup();
@@ -1056,7 +1064,7 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState
 
     case Phonon::PlayingState:
         pauseAct->setEnabled(true);
-        pauseAct->setIcon(Utils::icon("media-playback-pause"));
+        pauseAct->setIcon(IconUtils::icon("media-playback-pause"));
         pauseAct->setText(tr("&Pause"));
         pauseAct->setStatusTip(tr("Pause playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
         // stopAct->setEnabled(true);
@@ -1064,18 +1072,27 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState
 
     case Phonon::StoppedState:
         pauseAct->setEnabled(false);
+        pauseAct->setIcon(IconUtils::icon("media-playback-start"));
+        pauseAct->setText(tr("&Play"));
+        pauseAct->setStatusTip(tr("Resume playback") + " (" +  pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
         // stopAct->setEnabled(false);
         break;
 
     case Phonon::PausedState:
         pauseAct->setEnabled(true);
-        pauseAct->setIcon(Utils::icon("media-playback-start"));
+        pauseAct->setIcon(IconUtils::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:
+        pauseAct->setEnabled(false);
+        pauseAct->setIcon(IconUtils::icon("content-loading"));
+        pauseAct->setText(tr("&Loading..."));
+        pauseAct->setStatusTip(QString());
+        break;
+
     case Phonon::LoadingState:
         pauseAct->setEnabled(false);
         currentTime->clear();
@@ -1172,11 +1189,11 @@ void MainWindow::updateUIForFullscreen() {
         fullscreenAct->setShortcuts(QList<QKeySequence>(fsShortcuts)
                                     << QKeySequence(Qt::Key_Escape));
         fullscreenAct->setText(tr("Leave &Full Screen"));
-        fullscreenAct->setIcon(Utils::icon("view-restore"));
+        fullscreenAct->setIcon(IconUtils::icon("view-restore"));
     } else {
         fullscreenAct->setShortcuts(fsShortcuts);
         fullscreenAct->setText(fsText);
-        fullscreenAct->setIcon(Utils::icon("view-fullscreen"));
+        fullscreenAct->setIcon(IconUtils::icon("view-fullscreen"));
     }
 
     // No compact view action when in full screen
@@ -1300,20 +1317,25 @@ void MainWindow::initPhonon() {
     mediaObject = new Phonon::MediaObject(this);
     mediaObject->setTickInterval(100);
     connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
-            this, SLOT(stateChanged(Phonon::State, Phonon::State)));
-    connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
-    connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
+            SLOT(stateChanged(Phonon::State, Phonon::State)));
+    connect(mediaObject, SIGNAL(tick(qint64)), SLOT(tick(qint64)));
+    connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64)));
+
+    audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
+    connect(audioOutput, SIGNAL(volumeChanged(qreal)), SLOT(volumeChanged(qreal)));
+    connect(audioOutput, SIGNAL(mutedChanged(bool)), SLOT(volumeMutedChanged(bool)));
+    Phonon::createPath(mediaObject, audioOutput);
+    volumeSlider->setAudioOutput(audioOutput);
+
 #ifdef APP_PHONON_SEEK
     seekSlider->setMediaObject(mediaObject);
 #endif
-    audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
-    connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
-    connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
-    volumeSlider->setAudioOutput(audioOutput);
-    Phonon::createPath(mediaObject, audioOutput);
+
     QSettings settings;
-    audioOutput->setVolume(settings.value("volume", 1).toDouble());
+    audioOutput->setVolume(settings.value("volume", 1.).toReal());
     // audioOutput->setMuted(settings.value("volumeMute").toBool());
+
+    mediaObject->stop();
 }
 #endif
 
@@ -1391,15 +1413,20 @@ void MainWindow::volumeDown() {
 
 void MainWindow::volumeMute() {
 #ifdef APP_PHONON
-    volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
+    bool muted = volumeSlider->audioOutput()->isMuted();
+    volumeSlider->audioOutput()->setMuted(!muted);
+    qApp->processEvents();
+    if (muted && volumeSlider->audioOutput()->volume() == 0) {
+        volumeSlider->audioOutput()->setVolume(volumeSlider->maximumVolume());
+    }
+    qDebug() << volumeSlider->audioOutput()->isMuted() << volumeSlider->audioOutput()->volume();
 #endif
 }
 
 void MainWindow::volumeChanged(qreal newVolume) {
 #ifdef APP_PHONON
     // automatically unmute when volume changes
-    if (volumeSlider->audioOutput()->isMuted())
-        volumeSlider->audioOutput()->setMuted(false);
+    if (volumeSlider->audioOutput()->isMuted()) volumeSlider->audioOutput()->setMuted(false);
 
     bool isZero = volumeSlider->property("zero").toBool();
     bool styleChanged = false;
@@ -1421,12 +1448,16 @@ void MainWindow::volumeChanged(qreal newVolume) {
 
 void MainWindow::volumeMutedChanged(bool muted) {
     if (muted) {
-        volumeMuteAct->setIcon(Utils::icon("audio-volume-muted"));
+        volumeMuteAct->setIcon(IconUtils::icon("audio-volume-muted"));
         statusBar()->showMessage(tr("Volume is muted"));
     } else {
-        volumeMuteAct->setIcon(Utils::icon("audio-volume-high"));
+        volumeMuteAct->setIcon(IconUtils::icon("audio-volume-high"));
         statusBar()->showMessage(tr("Volume is unmuted"));
     }
+#ifdef Q_WS_X11
+    QToolButton *volumeMuteButton = qobject_cast<QToolButton *>(mainToolBar->widgetForAction(volumeMuteAct));
+    volumeMuteButton->setIcon(volumeMuteButton->icon().pixmap(16));
+#endif
 }
 
 void MainWindow::setDefinitionMode(QString definitionName) {
@@ -1440,16 +1471,22 @@ void MainWindow::setDefinitionMode(QString definitionName) {
 }
 
 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;
+    const QString definitionName = QSettings().value("definition").toString();
+    const QList<VideoDefinition>& definitions = VideoDefinition::getDefinitions();
+    const VideoDefinition& currentDefinition = VideoDefinition::getDefinitionFor(definitionName);
+    if (currentDefinition.isEmpty()) {
+        setDefinitionMode(definitions.first().getName());
+        return;
+    }
+
+    int index = definitions.indexOf(currentDefinition);
+    if (index != definitions.size() - 1) {
+        index++;
+    } else {
+        index = 0;
     }
-    QString nextDefinition = definitionNames.at(nextIndex);
-    setDefinitionMode(nextDefinition);
+    // TODO: pass a VideoDefinition instead of QString.
+    setDefinitionMode(definitions.at(index).getName());
 }
 
 void MainWindow::showFullscreenToolbar(bool show) {
@@ -1512,29 +1549,25 @@ void MainWindow::toggleDownloads(bool show) {
     else goBack();
 }
 
-void MainWindow::startToolbarSearch(QString query) {
-    query = query.trimmed();
-
-    // check for empty query
-    if (query.length() == 0) {
-        return;
-    }
+void MainWindow::suggestionAccepted(Suggestion *suggestion) {
+    search(suggestion->value);
+}
 
+void MainWindow::search(const QString &query) {
+    QString q = query.trimmed();
+    if (q.length() == 0) return;
     SearchParams *searchParams = new SearchParams();
-    searchParams->setKeywords(query);
-
-    // go!
+    searchParams->setKeywords(q);
     showMedia(searchParams);
 }
 
 void MainWindow::dragEnterEvent(QDragEnterEvent *event) {
     if (event->mimeData()->hasFormat("text/uri-list")) {
         QList<QUrl> urls = event->mimeData()->urls();
-        if (urls.isEmpty())
-            return;
+        if (urls.isEmpty()) return;
         QUrl url = urls.first();
         QString videoId = YTSearch::videoIdFromUrl(url.toString());
-        if (!videoId.isNull())
+        if (!videoId.isEmpty())
             event->acceptProposedAction();
     }
 }
@@ -1547,7 +1580,7 @@ void MainWindow::dropEvent(QDropEvent *event) {
         return;
     QUrl url = urls.first();
     QString videoId = YTSearch::videoIdFromUrl(url.toString());
-    if (!videoId.isNull()) {
+    if (!videoId.isEmpty()) {
         setWindowTitle(url.toString());
         SearchParams *searchParams = new SearchParams();
         searchParams->setKeywords(videoId);
@@ -1585,12 +1618,14 @@ void MainWindow::gotNewVersion(QString version) {
     QString checkedVersion = settings.value("checkedVersion").toString();
     if (checkedVersion == version) return;
 
-#ifdef APP_SIMPLEUPDATE
-    simpleUpdateDialog(version);
-#elif defined(APP_ACTIVATION) && !defined(APP_MAC)
+#ifdef APP_EXTRA
+#ifndef APP_MAC
     UpdateDialog *dialog = new UpdateDialog(version, this);
     dialog->show();
 #endif
+#else
+    simpleUpdateDialog(version);
+#endif
 }
 
 void MainWindow::simpleUpdateDialog(QString version) {