aboutView(0) {
m_fullscreen = false;
-
+
// views mechanism
history = new QStack<QWidget*>();
views = new QStackedWidget(this);
-
+
// views
searchView = new SearchView(this);
connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
views->addWidget(searchView);
-
+
mediaView = new MediaView(this);
views->addWidget(mediaView);
-
+
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&)));
-
+
// build ui
createActions();
createMenus();
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();
-
+
// restore window position
readSettings();
-
+
+ // cool toolbar on the Mac
+ // this is too buggy to be enabled
+ // setUnifiedTitleAndToolBarOnMac(true);
+
// event filter to block ugly toolbar tooltips
qApp->installEventFilter(this);
// show the initial view
showWidget(searchView);
-
+
setCentralWidget(views);
}
}
void MainWindow::createActions() {
-
+
QMap<QString, QAction*> *actions = The::globalActions();
-
+
backAct = new QAction(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/media-playback-stop.png")), 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));
actions->insert("stop", stopAct);
connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
-
+
skipAct = new QAction(QtIconLoader::icon("media-skip-forward", QIcon(":/images/media-skip-forward.png")), 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/media-playback-pause.png")), 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->setStatusTip(tr("Go full screen"));
fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
actions->insert("fullscreen", fullscreenAct);
connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
-
+
compactViewAct = new QAction(tr("&Compact mode"), this);
compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
compactViewAct->setEnabled(false);
actions->insert("compactView", compactViewAct);
connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
-
- webPageAct = new QAction(tr("&YouTube"), this);
- webPageAct->setStatusTip(tr("Open the YouTube video page"));
+
+ webPageAct = new QAction(tr("Open &YouTube page"), this);
+ webPageAct->setStatusTip(tr("Open 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()));
-
+
+ copyLinkAct = new QAction(tr("Copy video &link"), this);
+ copyLinkAct->setStatusTip(tr("Copy the current stream URL to the clipboard"));
+ copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
+ 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"));
removeAct->setEnabled(false);
actions->insert("remove", removeAct);
connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
-
+
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(tr("Move &Down"), this);
moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
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->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()), searchView, SLOT(clearRecentKeywords()));
+ connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
quitAct = new QAction(tr("&Quit"), this);
quitAct->setMenuRole(QAction::QuitRole);
quitAct->setStatusTip(tr("Bye"));
actions->insert("quit", quitAct);
connect(quitAct, SIGNAL(triggered()), this, SLOT(quit()));
-
+
siteAct = new QAction(tr("&Website"), this);
siteAct->setShortcut(QKeySequence::HelpContents);
siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
actions->insert("site", siteAct);
connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
-
+
donateAct = new QAction(tr("&Donate via PayPal"), 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()));
-
+
aboutAct = new QAction(tr("&About"), this);
aboutAct->setMenuRole(QAction::AboutRole);
aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
actions->insert("about", aboutAct);
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
-
+
// Invisible actions
-
+
searchFocusAct = new QAction(this);
searchFocusAct->setShortcut(QKeySequence::Find);
searchFocusAct->setStatusTip(tr("Search"));
actions->insert("search", searchFocusAct);
connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
addAction(searchFocusAct);
-
+
volumeUpAct = new QAction(this);
volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
actions->insert("volume-up", volumeUpAct);
connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
addAction(volumeUpAct);
-
+
volumeDownAct = new QAction(this);
volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
actions->insert("volume-down", volumeDownAct);
connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
addAction(volumeDownAct);
-
+
volumeMuteAct = new QAction(this);
volumeMuteAct->setStatusTip(tr("Mute volume"));
volumeMuteAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+M")) << QKeySequence(Qt::Key_VolumeMute));
actions->insert("volume-mute", volumeMuteAct);
connect(volumeMuteAct, SIGNAL(triggered()), this, SLOT(volumeMute()));
addAction(volumeMuteAct);
-
+
QAction *hdAct = new QAction(this);
hdAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
hdAct->setIcon(createHDIcon());
actions->insert("hd", hdAct);
connect(hdAct, SIGNAL(toggled(bool)), this, SLOT(hdMode(bool)));
addAction(hdAct);
-
+
// common action properties
foreach (QAction *action, actions->values()) {
-
+
// add actions to the MainWindow so that they work
// when the menu is hidden
addAction(action);
-
+
// never autorepeat.
// unexperienced users tend to keep keys pressed for a "long" time
action->setAutoRepeat(false);
-
+
// 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) + ")");
// no icons in menus
action->setIconVisibleInMenu(false);
-
+
}
-
+
}
void MainWindow::createMenus() {
-
+
QMap<QString, QMenu*> *menus = The::globalMenus();
fileMenu = menuBar()->addMenu(tr("&Application"));
playlistMenu->addSeparator();
playlistMenu->addAction(moveUpAct);
playlistMenu->addAction(moveDownAct);
-
+
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(webPageAct);
+ viewMenu->addAction(copyLinkAct);
viewMenu->addSeparator();
- // viewMenu->addAction(downloadAct);
viewMenu->addAction(compactViewAct);
viewMenu->addAction(fullscreenAct);
-
+
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(siteAct);
helpMenu->addAction(donateAct);
}
void MainWindow::createToolBars() {
-
+
mainToolBar = new QToolBar(this);
-#if QT_VERSION < 0x040600
+#if QT_VERSION < 0x040600 || defined(Q_WS_MAC)
mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
#else
mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
#endif
mainToolBar->setFloatable(false);
mainToolBar->setMovable(false);
- // cool toolbar on the Mac
- // setUnifiedTitleAndToolBarOnMac(true);
-
+
QFont smallerFont;
smallerFont.setPointSize(smallerFont.pointSize()*.85);
QFontInfo fontInfo(smallerFont);
smallerFont.setPixelSize(10);
}
mainToolBar->setFont(smallerFont);
-
- mainToolBar->setIconSize(QSize(32,32));
- // mainToolBar->addAction(backAct);
+
+ mainToolBar->setIconSize(QSize(32, 32));
mainToolBar->addAction(stopAct);
mainToolBar->addAction(pauseAct);
mainToolBar->addAction(skipAct);
mainToolBar->addAction(fullscreenAct);
-
+
seekSlider = new Phonon::SeekSlider(this);
seekSlider->setIconVisible(false);
Spacer *seekSliderSpacer = new Spacer(mainToolBar, seekSlider);
seekSliderSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
mainToolBar->addWidget(seekSliderSpacer);
-
+
volumeSlider = new Phonon::VolumeSlider(this);
// qDebug() << volumeSlider->children();
// status tip for the volume slider
// this makes the volume slider smaller
volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
mainToolBar->addWidget(new Spacer(mainToolBar, volumeSlider));
-
+
toolbarSearch->setStatusTip(searchFocusAct->statusTip());
mainToolBar->addWidget(new Spacer(mainToolBar, toolbarSearch));
-
+
addToolBar(mainToolBar);
}
void MainWindow::createStatusBar() {
currentTime = new QLabel(this);
statusBar()->addPermanentWidget(currentTime);
-
+
totalTime = new QLabel(this);
statusBar()->addPermanentWidget(totalTime);
-
+
// remove ugly borders on OSX
// and remove some excessive padding
statusBar()->setStyleSheet("::item{border:0 solid} "
"QStatusBar, QToolBar, QToolButton {spacing:0;padding:0;margin:0} "
);
-
+
QToolBar *toolBar = new QToolBar(this);
int iconHeight = 24; // statusBar()->height();
int iconWidth = 36; // iconHeight * 3 / 2;
toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
toolBar->addAction(The::globalActions()->value("hd"));
statusBar()->addPermanentWidget(toolBar);
-
+
statusBar()->show();
}
}
void MainWindow::showWidget ( QWidget* widget ) {
-
+
setUpdatesEnabled(false);
-
+
// call hide method on the current view
View* oldView = dynamic_cast<View *> (views->currentWidget());
if (oldView) {
oldView->disappear();
}
-
+
// call show method on the new view
View* newView = dynamic_cast<View *> (widget);
if (newView) {
setWindowTitle(windowTitle + Constants::APP_NAME);
statusBar()->showMessage((metadata.value("description").toString()));
}
-
+
// backAct->setEnabled(history->size() > 1);
stopAct->setEnabled(widget == mediaView);
fullscreenAct->setEnabled(widget == mediaView);
compactViewAct->setEnabled(widget == mediaView);
- webPageAct->setEnabled(widget == mediaView);
+ webPageAct->setEnabled(widget == mediaView);
+ copyLinkAct->setEnabled(widget == mediaView);
aboutAct->setEnabled(widget != aboutView);
// toolbar only for the mediaView
mainToolBar->setVisible(widget == mediaView && !compactViewAct->isChecked());
setUpdatesEnabled(true);
-
+
QWidget *oldWidget = views->currentWidget();
views->setCurrentWidget(widget);
-
+
#ifdef Q_WS_MAC
// crossfade only on OSX
// where we can be sure of video performance
fadeInWidget(oldWidget, widget);
#endif
-
+
history->push(widget);
}
}
void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
-
+
// qDebug() << "Phonon state: " << newState;
-
+
switch (newState) {
-
+
case Phonon::ErrorState:
if (mediaObject->errorType() == Phonon::FatalError) {
statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
}
break;
-
+
case Phonon::PlayingState:
pauseAct->setEnabled(true);
pauseAct->setIcon(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")));
pauseAct->setStatusTip(tr("Pause playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
skipAct->setEnabled(true);
break;
-
+
case Phonon::StoppedState:
pauseAct->setEnabled(false);
skipAct->setEnabled(false);
break;
-
+
case Phonon::PausedState:
skipAct->setEnabled(true);
pauseAct->setEnabled(true);
pauseAct->setText(tr("&Play"));
pauseAct->setStatusTip(tr("Resume playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
break;
-
+
case Phonon::BufferingState:
case Phonon::LoadingState:
skipAct->setEnabled(true);
currentTime->clear();
totalTime->clear();
break;
-
+
default:
;
}
}
void MainWindow::fullscreen() {
-
+
setUpdatesEnabled(false);
-
- if (m_fullscreen) {
- // use setShortucs 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));
- if (m_maximized) showMaximized();
- else showNormal();
- // Make sure the window has focus (Mac)
- activateWindow();
- } else {
- 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"));
- m_maximized = isMaximized();
-
- // save geometry now, if the user quits when in full screen
- // geometry won't be saved
- writeSettings();
-
- showFullScreen();
- }
-
+
// 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);
+ copyLinkAct->setVisible(m_fullscreen);
stopAct->setVisible(m_fullscreen);
-
+
+ // workaround: prevent focus on the search bar
+ // it steals the Space key needed for Play/Pause
+ mainToolBar->setEnabled(m_fullscreen);
+
// Hide anything but the video
mediaView->setPlaylistVisible(m_fullscreen);
- mainToolBar->setVisible(m_fullscreen);
statusBar()->setVisible(m_fullscreen);
+
+#ifndef Q_WS_MAC
menuBar()->setVisible(m_fullscreen);
-
- // workaround: prevent focus on the search bar
- // it steals the Space key needed for Play/Pause
- mainToolBar->setEnabled(m_fullscreen);
+#endif
#ifdef Q_WS_MAC
// make the actions work when video is fullscreen (on the Mac)
}
#endif
+ if (m_fullscreen) {
+ // use setShortucs 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));
+
+ mainToolBar->show();
+ if (m_maximized) showMaximized();
+ else showNormal();
+
+ // Make sure the window has focus (Mac)
+ activateWindow();
+
+ } else {
+ 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"));
+ m_maximized = isMaximized();
+
+ // save geometry now, if the user quits when in full screen
+ // geometry won't be saved
+ writeSettings();
+
+ mainToolBar->hide();
+ showFullScreen();
+ }
+
m_fullscreen = !m_fullscreen;
setUpdatesEnabled(true);
}
void MainWindow::compactView(bool enable) {
-
+
setUpdatesEnabled(false);
-
- // setUnifiedTitleAndToolBarOnMac(!enable);
- mediaView->setPlaylistVisible(!enable);
+
mainToolBar->setVisible(!enable);
+ mainToolBar->setEnabled(!enable);
+ mediaView->setPlaylistVisible(!enable);
statusBar()->setVisible(!enable);
+
+#ifndef Q_WS_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);
-
+ // toolbarSearch->setEnabled(!enable);
+
if (enable) {
stopAct->setShortcut(QString(""));
QList<QKeySequence> shortcuts;
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHints(QPainter::Antialiasing, true);
-
+
QRect rect(0, 3, 24, 18);
-
+
QPen pen;
pen.setColor(Qt::black);
pen.setWidth(1);
painter.setPen(pen);
-
+
if (enabled) {
painter.setBrush(palette().highlight());
} else {
painter.setBrush(QBrush(gradient));
}
painter.drawRoundedRect(rect, 5, 5);
-
+
if (enabled) {
pen.setColor(palette().highlightedText().color());
} else {
pen.setColor(Qt::white);
}
painter.setPen(pen);
-
+
QFont font;
font.setPixelSize(12);
font.setBold(true);
painter.setFont(font);
painter.drawText(rect, Qt::AlignCenter, "HD");
-
+
return pixmap;
}
}
void MainWindow::showFullscreenPlaylist(bool show) {
- if (!m_fullscreen) return;
+ if (!m_fullscreen) return;
mediaView->setPlaylistVisible(show);
}
+void MainWindow::clearRecentKeywords() {
+ QSettings settings;
+ settings.remove("recentKeywords");
+ searchView->updateRecentKeywords();
+ statusBar()->showMessage(tr("Your privacy is now safe"));
+}