From: Flavio Tordini Date: Sun, 21 Sep 2014 16:46:47 +0000 (+0200) Subject: Snapshots X-Git-Tag: 2.3~21 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=43f77804ae9e4578732dffb8ae819ec39a6583e8;p=minitube Snapshots --- diff --git a/minitube.pro b/minitube.pro index dd6c5c8..4f9bca7 100644 --- a/minitube.pro +++ b/minitube.pro @@ -9,18 +9,19 @@ DEFINES += APP_NAME="$$APP_NAME" APP_UNIX_NAME = minitube DEFINES += APP_UNIX_NAME="$$APP_UNIX_NAME" -DEFINES *= QT_NO_DEBUG_OUTPUT +DEFINES += APP_PHONON +DEFINES += APP_PHONON_SEEK +DEFINES += APP_SNAPSHOT + +#DEFINES *= QT_NO_DEBUG_OUTPUT DEFINES *= QT_USE_QSTRINGBUILDER -DEFINES += QT_STRICT_ITERATORS +DEFINES *= QT_STRICT_ITERATORS TARGET = $${APP_UNIX_NAME} QT += network xml sql script - qt:greaterThan(QT_MAJOR_VERSION, 4) { contains(QT, gui): QT *= widgets -} else { - QT += phonon } include(src/qtsingleapplication/qtsingleapplication.pri) @@ -90,7 +91,10 @@ HEADERS += \ src/channelview.h \ src/channelitemdelegate.h \ src/jsfunctions.h \ - src/seekslider.h + src/seekslider.h \ + src/snapshotsettings.h \ + src/snapshotpreview.h \ + src/datautils.h SOURCES += src/main.cpp \ src/searchlineedit.cpp \ src/urllineedit.cpp \ @@ -153,7 +157,10 @@ SOURCES += src/main.cpp \ src/channelview.cpp \ src/channelitemdelegate.cpp \ src/jsfunctions.cpp \ - src/seekslider.cpp + src/seekslider.cpp \ + src/snapshotsettings.cpp \ + src/snapshotpreview.cpp \ + src/datautils.cpp RESOURCES += resources.qrc DESTDIR = build/target/ OBJECTS_DIR = build/obj/ @@ -168,7 +175,14 @@ include(locale/locale.pri) # deploy DISTFILES += CHANGES COPYING unix:!mac { - INCLUDEPATH += /usr/include/phonon + + qt:greaterThan(QT_MAJOR_VERSION, 4) { + LIBS += -lphonon4qt5 + INCLUDEPATH += /usr/include/phonon4qt5 + } else { + QT += phonon + INCLUDEPATH += /usr/include/phonon + } QT += dbus HEADERS += src/gnomeglobalshortcutbackend.h SOURCES += src/gnomeglobalshortcutbackend.cpp @@ -215,3 +229,6 @@ unix:!mac { icon512.files += data/512x512/minitube.png } mac|win32|contains(DEFINES, APP_UBUNTU):include(local/local.pri) + +OTHER_FILES += \ + sounds/snapshot.wav diff --git a/resources.qrc b/resources.qrc index 2f15768..6353887 100644 --- a/resources.qrc +++ b/resources.qrc @@ -63,5 +63,6 @@ images/badge.png images/badge3.png images/badge4.png + sounds/snapshot.wav diff --git a/sounds/snapshot.wav b/sounds/snapshot.wav new file mode 100755 index 0000000..182f13d Binary files /dev/null and b/sounds/snapshot.wav differ diff --git a/src/loadingwidget.cpp b/src/loadingwidget.cpp index 1a3701e..6ba8af1 100644 --- a/src/loadingwidget.cpp +++ b/src/loadingwidget.cpp @@ -62,13 +62,13 @@ LoadingWidget::LoadingWidget(QWidget *parent) : QWidget(parent) { void LoadingWidget::setVideo(Video *video) { QFont titleFont; - titleFont.setStyleName("Light"); #ifdef APP_MAC titleFont.setFamily("Helvetica Neue"); #endif #ifdef APP_WIN titleFont.setFamily("Segoe UI Light"); #endif + titleFont.setStyleName("Light"); int smallerDimension = qMin(height(), width()); titleFont.setPixelSize(smallerDimension / 12); titleFont.setHintingPreference(QFont::PreferNoHinting); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e0a0fb8..9ea7777 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -269,7 +269,7 @@ void MainWindow::createActions() { stopAct->setShortcuts(QList() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop)); stopAct->setEnabled(false); actions->insert("stop", stopAct); - connect(stopAct, SIGNAL(triggered()), this, SLOT(stop())); + connect(stopAct, SIGNAL(triggered()), SLOT(stop())); skipBackwardAct = new QAction( Utils::icon("media-skip-backward"), @@ -458,7 +458,7 @@ void MainWindow::createActions() { action = new QAction(Utils::icon("media-playback-start"), tr("&Manually Start Playing"), this); action->setStatusTip(tr("Manually start playing videos")); - action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); + action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T)); action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), SLOT(setManualPlay(bool))); actions->insert("manualplay", action); @@ -482,12 +482,13 @@ void MainWindow::createActions() { connect(action, SIGNAL(triggered()), mediaView, SLOT(downloadVideo())); actions->insert("download", action); - /* - action = new QAction(tr("&Snapshot"), this); - action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_S)); +#ifdef APP_SNAPSHOT + action = new QAction(tr("Take &Snapshot"), this); + action->setShortcut(QKeySequence(Qt::Key_F9)); + action->setEnabled(false); actions->insert("snapshot", action); connect(action, SIGNAL(triggered()), mediaView, SLOT(snapshot())); - */ +#endif action = new QAction(tr("&Subscribe to Channel"), this); action->setProperty("originalText", action->text()); @@ -573,6 +574,7 @@ void MainWindow::createActions() { actions->insert("related-videos", action); action = new QAction(tr("Open in &Browser..."), this); + action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); action->setEnabled(false); actions->insert("open-in-browser", action); connect(action, SIGNAL(triggered()), mediaView, SLOT(openInBrowser())); @@ -642,14 +644,16 @@ void MainWindow::createMenus() { videoMenu->addAction(The::globalActions()->value("related-videos")); videoMenu->addAction(findVideoPartsAct); videoMenu->addSeparator(); - videoMenu->addAction(webPageAct); - videoMenu->addSeparator(); videoMenu->addAction(The::globalActions()->value("subscribe-channel")); +#ifdef APP_SNAPSHOT videoMenu->addSeparator(); - videoMenu->addAction(The::globalActions()->value("download")); + videoMenu->addAction(The::globalActions()->value("snapshot")); +#endif + videoMenu->addSeparator(); + videoMenu->addAction(webPageAct); videoMenu->addAction(copyLinkAct); videoMenu->addAction(The::globalActions()->value("open-in-browser")); - // videoMenu->addAction(The::globalActions()->value("snapshot")); + videoMenu->addAction(The::globalActions()->value("download")); QMenu* viewMenu = menuBar()->addMenu(tr("&View")); menus->insert("view", viewMenu); @@ -719,16 +723,14 @@ void MainWindow::createToolBars() { currentTime->setFont(smallerFont); mainToolBar->addWidget(currentTime); -#ifdef APP_PHONON_SEEK mainToolBar->addWidget(new Spacer()); + +#ifdef APP_PHONON_SEEK seekSlider = new Phonon::SeekSlider(this); - seekSlider->setVisible(false); seekSlider->setIconVisible(false); seekSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); mainToolBar->addWidget(seekSlider); -#endif - - mainToolBar->addWidget(new Spacer()); +#else slider = new SeekSlider(this); slider->setEnabled(false); slider->setTracking(false); @@ -736,15 +738,16 @@ void MainWindow::createToolBars() { slider->setOrientation(Qt::Horizontal); slider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); mainToolBar->addWidget(slider); +#endif + /* mainToolBar->addWidget(new Spacer()); - totalTime = new QLabel(mainToolBar); totalTime->setFont(smallerFont); mainToolBar->addWidget(totalTime); + */ mainToolBar->addWidget(new Spacer()); - mainToolBar->addAction(volumeMuteAct); #ifdef APP_PHONON @@ -931,8 +934,8 @@ void MainWindow::showWidget(QWidget* widget, bool transition) { setUpdatesEnabled(true); #ifdef APP_EXTRA - if (transition && (oldWidget != mediaView || - !mediaView->getVideoArea()->isVideoShown())) + // if (transition && (oldWidget != mediaView || !mediaView->getVideoArea()->isVideoShown())) + if (transition) Extra::fadeInWidget(oldWidget, widget); #endif @@ -1021,7 +1024,7 @@ bool MainWindow::confirmQuit() { void MainWindow::showHome(bool transition) { showWidget(homeView, transition); currentTime->clear(); - totalTime->clear(); + // totalTime->clear(); } void MainWindow::showMedia(SearchParams *searchParams) { @@ -1076,7 +1079,7 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState case Phonon::LoadingState: pauseAct->setEnabled(false); currentTime->clear(); - totalTime->clear(); + // totalTime->clear(); // stopAct->setEnabled(true); break; @@ -1087,8 +1090,8 @@ void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState #endif void MainWindow::stop() { - mediaView->stop(); showHome(); + mediaView->stop(); } void MainWindow::resizeEvent(QResizeEvent*) { @@ -1329,21 +1332,24 @@ void MainWindow::tick(qint64 time) { const qint64 remainingTime = mediaObject->remainingTime(); currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime))); - slider->blockSignals(true); +#ifndef APP_PHONON_SEEK const qint64 totalTime = mediaObject->totalTime(); + slider->blockSignals(true); // qWarning() << totalTime << time << time * 100 / totalTime; if (totalTime > 0 && time > 0 && !slider->isSliderDown() && mediaObject->state() == Phonon::PlayingState) slider->setValue(time * slider->maximum() / totalTime); slider->blockSignals(false); #endif + +#endif } void MainWindow::totalTimeChanged(qint64 time) { if (time <= 0) { - totalTime->clear(); + // totalTime->clear(); return; } - totalTime->setText(formatTime(time)); + // totalTime->setText(formatTime(time)); /* slider->blockSignals(true); @@ -1377,8 +1383,8 @@ void MainWindow::volumeUp() { void MainWindow::volumeDown() { #ifdef APP_PHONON qreal newVolume = volumeSlider->audioOutput()->volume() - .1; - if (newVolume < 0) - newVolume = 0; + if (newVolume < 0.) + newVolume = 0.; volumeSlider->audioOutput()->setVolume(newVolume); #endif } @@ -1394,6 +1400,21 @@ void MainWindow::volumeChanged(qreal newVolume) { // automatically unmute when volume changes if (volumeSlider->audioOutput()->isMuted()) volumeSlider->audioOutput()->setMuted(false); + + bool isZero = volumeSlider->property("zero").toBool(); + bool styleChanged = false; + if (newVolume == 0. && !isZero) { + volumeSlider->setProperty("zero", true); + styleChanged = true; + } else if (newVolume > 0. && isZero) { + volumeSlider->setProperty("zero", false); + styleChanged = true; + } + if (styleChanged) { + QSlider* volumeQSlider = volumeSlider->findChild(); + style()->unpolish(volumeQSlider); + style()->polish(volumeQSlider); + } #endif statusBar()->showMessage(tr("Volume at %1%").arg((int)(newVolume*100))); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 67bb0c4..be9ff14 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -51,8 +51,12 @@ public: ~MainWindow(); #ifdef APP_PHONON_SEEK Phonon::SeekSlider* getSeekSlider() { return seekSlider; } -#endif +#else QSlider* getSlider() { return slider; } +#endif +#ifdef APP_PHONON + Phonon::AudioOutput* getAudioOutput() { return audioOutput; } +#endif void readSettings(); void writeSettings(); static void printHelp(); @@ -207,17 +211,18 @@ private: QAction *regionAction; // phonon - QSlider *slider; #ifdef APP_PHONON #ifdef APP_PHONON_SEEK Phonon::SeekSlider *seekSlider; +#else + QSlider *slider; #endif Phonon::VolumeSlider *volumeSlider; Phonon::MediaObject *mediaObject; Phonon::AudioOutput *audioOutput; #endif QLabel *currentTime; - QLabel *totalTime; + // QLabel *totalTime; // fullscreen bool m_fullscreen; diff --git a/src/mediaview.cpp b/src/mediaview.cpp index 5287af0..13691a1 100644 --- a/src/mediaview.cpp +++ b/src/mediaview.cpp @@ -46,6 +46,10 @@ $END_LICENSE */ #include "channelaggregator.h" #include "utils.h" #include "ytuser.h" +#ifdef APP_SNAPSHOT +#include "snapshotsettings.h" +#endif +#include "datautils.h" namespace The { NetworkAccess* http(); @@ -61,6 +65,9 @@ MediaView* MediaView::instance() { MediaView::MediaView(QWidget *parent) : QWidget(parent), stopped(false), + #ifdef APP_SNAPSHOT + snapshotSettings(0), + #endif downloadItem(0) { } void MediaView::initialize() { @@ -145,6 +152,9 @@ void MediaView::initialize() { << The::globalActions()->value("pagelink") << The::globalActions()->value("videolink") << The::globalActions()->value("open-in-browser") + #ifdef APP_SNAPSHOT + << The::globalActions()->value("snapshot") + #endif << The::globalActions()->value("findVideoParts") << The::globalActions()->value("skip") << The::globalActions()->value("previous") @@ -156,8 +166,10 @@ void MediaView::initialize() { << The::globalActions()->value("buffer") << The::globalActions()->value("email"); +#ifndef APP_PHONON_SEEK QSlider *slider = MainWindow::instance()->getSlider(); connect(slider, SIGNAL(valueChanged(int)), SLOT(sliderMoved(int))); +#endif } #ifdef APP_PHONON @@ -196,7 +208,7 @@ void MediaView::search(SearchParams *searchParams) { setVideoSource(new YTSearch(searchParams, this)); } -void MediaView::setVideoSource(VideoSource *videoSource, bool addToHistory) { +void MediaView::setVideoSource(VideoSource *videoSource, bool addToHistory, bool back) { stopped = false; #ifdef APP_ACTIVATION @@ -220,6 +232,11 @@ void MediaView::setVideoSource(VideoSource *videoSource, bool addToHistory) { history.append(videoSource); } +#ifdef APP_EXTRA + if (history.size() > 1) + Extra::slideTransition(playlistView->viewport(), playlistView->viewport(), back); +#endif + playlistModel->setVideoSource(videoSource); sidebar->showPlaylist(); @@ -230,6 +247,8 @@ void MediaView::setVideoSource(VideoSource *videoSource, bool addToHistory) { SearchParams *searchParams = getSearchParams(); bool isChannel = searchParams && !searchParams->author().isEmpty(); playlistView->setClickableAuthors(!isChannel); + + } void MediaView::searchAgain() { @@ -246,7 +265,7 @@ void MediaView::goBack() { int currentIndex = getHistoryIndex(); if (currentIndex > 0) { VideoSource *previousVideoSource = history.at(currentIndex - 1); - setVideoSource(previousVideoSource, false); + setVideoSource(previousVideoSource, false, true); } } } @@ -283,7 +302,11 @@ void MediaView::disappear() { } void MediaView::handleError(QString /* message */) { +#ifdef APP_PHONON_SEEK + mediaObject->play(); +#else QTimer::singleShot(500, this, SLOT(startPlaying())); +#endif } #ifdef APP_PHONON @@ -352,9 +375,16 @@ void MediaView::stop() { #endif currentVideoId.clear(); +#ifndef APP_PHONON_SEEK QSlider *slider = MainWindow::instance()->getSlider(); slider->setEnabled(false); slider->setValue(0); +#endif + + if (snapshotSettings) { + delete snapshotSettings; + snapshotSettings = 0; + } } const QString & MediaView::getCurrentVideoId() { @@ -384,7 +414,7 @@ void MediaView::activeRowChanged(int row) { connect(video, SIGNAL(gotStreamUrl(QUrl)), SLOT(gotStreamUrl(QUrl)), Qt::UniqueConnection); connect(video, SIGNAL(errorStreamUrl(QString)), - SLOT(handleError(QString)), Qt::UniqueConnection); + SLOT(skip()), Qt::UniqueConnection); video->loadStreamUrl(); // video title in titlebar @@ -422,9 +452,16 @@ void MediaView::activeRowChanged(int row) { foreach (QAction *action, currentVideoActions) action->setEnabled(true); +#ifndef APP_PHONON_SEEK QSlider *slider = MainWindow::instance()->getSlider(); slider->setEnabled(false); slider->setValue(0); +#endif + + if (snapshotSettings) { + delete snapshotSettings; + snapshotSettings = 0; + } // see you in gotStreamUrl... } @@ -445,7 +482,7 @@ void MediaView::gotStreamUrl(QUrl streamUrl) { currentVideoId = video->id(); -#ifdef Q_OS_LINUX_NO +#ifdef APP_PHONON_SEEK mediaObject->setCurrentSource(streamUrl); mediaObject->play(); #else @@ -493,8 +530,8 @@ void MediaView::downloadStatusChanged() { break; case Finished: // qDebug() << "Finished" << mediaObject->state(); -#ifdef Q_OS_LINUX - // MainWindow::instance()->getSeekSlider()->setEnabled(mediaObject->isSeekable()); +#ifdef APP_PHONON_SEEK + MainWindow::instance()->getSeekSlider()->setEnabled(mediaObject->isSeekable()); #endif break; case Failed: @@ -524,15 +561,15 @@ void MediaView::startPlaying() { QString source = downloadItem->currentFilename(); qDebug() << "Playing" << source << QFile::exists(source); #ifdef APP_PHONON - mediaObject->setCurrentSource(source); + mediaObject->setCurrentSource(QUrl::fromLocalFile(source)); mediaObject->play(); #endif -#ifdef Q_OS_LINUX - // MainWindow::instance()->getSeekSlider()->setEnabled(false); -#endif - +#ifdef APP_PHONON_SEEK + MainWindow::instance()->getSeekSlider()->setEnabled(false); +#else QSlider *slider = MainWindow::instance()->getSlider(); slider->setEnabled(true); +#endif } void MediaView::itemActivated(const QModelIndex &index) { @@ -791,16 +828,44 @@ void MediaView::downloadVideo() { MainWindow::instance()->showMessage(message); } -/* +#ifdef APP_SNAPSHOT void MediaView::snapshot() { + qint64 currentTime = mediaObject->currentTime() / 1000; + QImage image = videoWidget->snapshot(); - qDebug() << image.size(); + if (image.isNull()) { + qWarning() << "Null snapshot"; + return; + } - const QPixmap& pixmap = QPixmap::grabWindow(videoWidget->winId()); - // qDebug() << pixmap.size(); + // QPixmap pixmap = QPixmap::grabWindow(videoWidget->winId()); + QPixmap pixmap = QPixmap::fromImage(image.scaled(videoWidget->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); videoAreaWidget->showSnapshotPreview(pixmap); + + Video* video = playlistModel->activeVideo(); + if (!video) return; + + QString location = SnapshotSettings::getCurrentLocation(); + QString basename = video->title(); + QString format = video->duration() > 3600 ? "h_mm_ss" : "m_ss"; + basename += " (" + QTime().addSecs(currentTime).toString(format) + ")"; + basename = DataUtils::stringToFilename(basename); + QString filename = location + "/" + basename + ".png"; + qDebug() << filename; + image.save(filename, "PNG"); + + if (snapshotSettings) delete snapshotSettings; + snapshotSettings = new SnapshotSettings(videoWidget); + snapshotSettings->setSnapshot(pixmap, filename); + QStatusBar *statusBar = MainWindow::instance()->statusBar(); +#ifdef APP_EXTRA + Extra::fadeInWidget(statusBar, statusBar); +#endif + statusBar->clearMessage(); + statusBar->insertPermanentWidget(0, snapshotSettings); + snapshotSettings->show(); } -*/ +#endif void MediaView::fullscreen() { videoAreaWidget->setParent(0); @@ -831,6 +896,8 @@ void MediaView::startDownloading() { void MediaView::sliderMoved(int value) { #ifdef APP_PHONON +#ifndef APP_PHONON_SEEK + if (currentVideoSize <= 0 || !downloadItem || !mediaObject->isSeekable()) return; @@ -855,6 +922,7 @@ void MediaView::sliderMoved(int value) { mediaObject->seek(offsetToTime(offset)); } #endif +#endif } qint64 MediaView::offsetToTime(qint64 offset) { diff --git a/src/mediaview.h b/src/mediaview.h index 29dcc5b..84146d7 100644 --- a/src/mediaview.h +++ b/src/mediaview.h @@ -42,6 +42,9 @@ class DownloadItem; class PlaylistView; class SidebarWidget; class VideoSource; +#ifdef APP_SNAPSHOT +class SnapshotSettings; +#endif namespace The { QHash* globalActions(); @@ -70,7 +73,7 @@ public: public slots: void search(SearchParams *searchParams); - void setVideoSource(VideoSource *videoSource, bool addToHistory = true); + void setVideoSource(VideoSource *videoSource, bool addToHistory = true, bool back = false); void pause(); void stop(); void skip(); @@ -91,7 +94,9 @@ public slots: void setPlaylistVisible(bool visible=true); void saveSplitterState(); void downloadVideo(); - // void snapshot(); +#ifdef APP_SNAPSHOT + void snapshot(); +#endif void fullscreen(); void findVideoParts(); void relatedVideos(); @@ -160,6 +165,10 @@ private: QList currentVideoActions; qint64 currentVideoSize; + +#ifdef APP_SNAPSHOT + SnapshotSettings *snapshotSettings; +#endif }; #endif // __MEDIAVIEW_H__ diff --git a/src/snapshotpreview.cpp b/src/snapshotpreview.cpp new file mode 100644 index 0000000..9766a20 --- /dev/null +++ b/src/snapshotpreview.cpp @@ -0,0 +1,104 @@ +/* $BEGIN_LICENSE + +This file is part of Minitube. +Copyright 2009, Flavio Tordini + +Minitube is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Minitube is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitube. If not, see . + +$END_LICENSE */ + +#include "snapshotpreview.h" +#include "mainwindow.h" + +SnapshotPreview::SnapshotPreview(QWidget *parent) : QWidget(parent), +#ifdef APP_PHONON + mediaObject(0), + audioOutput(0) +#endif + { + setAttribute(Qt::WA_ShowWithoutActivating); + setWindowFlags(Qt::FramelessWindowHint); +#if QT_VERSION >= 0x050000 + setWindowFlags(Qt::WindowDoesNotAcceptFocus); +#endif + + setAttribute(Qt::WA_StaticContents); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_NoSystemBackground); + setEnabled(false); + setFocusPolicy(Qt::NoFocus); + + timeLine = new QTimeLine(300, this); + timeLine->setCurveShape(QTimeLine::LinearCurve); + timeLine->setFrameRange(0, 20); + connect(timeLine, SIGNAL(frameChanged(int)), SLOT(update())); + + timer = new QTimer(this); + timer->setSingleShot(true); + timer->setInterval(1500); + connect(timer, SIGNAL(timeout()), SLOT(finish())); + + hide(); +} + +void SnapshotPreview::start(QWidget *widget, const QPixmap &pixmap, bool soundOnly) { +#ifdef APP_PHONON + if (!mediaObject) { + mediaObject = new Phonon::MediaObject(this); + audioOutput = new Phonon::AudioOutput(Phonon::NotificationCategory, this); + Phonon::createPath(mediaObject, audioOutput); + } + mediaObject->setCurrentSource(QUrl("qrc:///sounds/snapshot.wav")); + mediaObject->play(); +#endif + if (soundOnly) return; + + resize(pixmap.size()); +#if defined(APP_MAC) || defined(APP_WIN) + QPoint pos = widget->mapToGlobal(widget->pos()); + pos.setY(pos.y() + ((widget->height() - pixmap.height()) / 2)); + pos.setX(pos.x() + ((widget->width() - pixmap.width()) / 2)); + move(pos); +#else + QPoint pos; + pos.setY((widget->height() - pixmap.height()) / 2); + pos.setX((widget->width() - pixmap.width()) / 2); + move(pos); + setParent(widget); +#endif + + this->pixmap = pixmap; +#ifndef APP_MAC + timeLine->start(); +#endif + timer->start(); + if (isVisible()) update(); + else show(); +} + +void SnapshotPreview::paintEvent(QPaintEvent *e) { + Q_UNUSED(e); + QPainter p(this); + if (timeLine->state() == QTimeLine::Running) { + p.fillRect(rect(), Qt::white); + const qreal opacity = timeLine->currentFrame() / 20.; + p.setOpacity(opacity); + } + p.drawPixmap(0, 0, pixmap); +} + +void SnapshotPreview::finish() { + hide(); + emit done(); +} diff --git a/src/snapshotpreview.h b/src/snapshotpreview.h new file mode 100644 index 0000000..2bb7540 --- /dev/null +++ b/src/snapshotpreview.h @@ -0,0 +1,63 @@ +/* $BEGIN_LICENSE + +This file is part of Minitube. +Copyright 2009, Flavio Tordini + +Minitube is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Minitube is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitube. If not, see . + +$END_LICENSE */ + +#ifndef SNAPSHOTPREVIEW_H +#define SNAPSHOTPREVIEW_H + +#include +#if QT_VERSION >= 0x050000 +#include +#endif + +#ifdef APP_PHONON +#include +#include +#include +#endif + +class SnapshotPreview : public QWidget { + + Q_OBJECT + +public: + SnapshotPreview(QWidget *parent = 0); + void start(QWidget *widget, const QPixmap &pixmap, bool soundOnly); + +signals: + void done(); + +protected: + void paintEvent(QPaintEvent *e); + +private slots: + void finish(); + +private: + QPixmap pixmap; + QTimeLine *timeLine; + QPoint offset; + QTimer *timer; +#ifdef APP_PHONON + Phonon::MediaObject *mediaObject; + Phonon::AudioOutput *audioOutput; +#endif +}; + +#endif // SNAPSHOTPREVIEW_H diff --git a/src/snapshotsettings.cpp b/src/snapshotsettings.cpp new file mode 100644 index 0000000..bfe5275 --- /dev/null +++ b/src/snapshotsettings.cpp @@ -0,0 +1,144 @@ +/* $BEGIN_LICENSE + +This file is part of Minitube. +Copyright 2009, Flavio Tordini + +Minitube is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Minitube is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitube. If not, see . + +$END_LICENSE */ + +#include "snapshotsettings.h" +#include "mainwindow.h" +#include +#ifdef APP_MAC +#include "macutils.h" +#endif + +SnapshotSettings::SnapshotSettings(QWidget *parent) : QWidget(parent) { + QBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(5, 0, 10, 0); + layout->setSpacing(5); + + thumb = new QToolButton(); + thumb->setStyleSheet("border:0"); + thumb->setCursor(Qt::PointingHandCursor); + connect(thumb, SIGNAL(clicked()), SLOT(openFile())); + layout->addWidget(thumb); + + message = new QLabel(); + connect(message, SIGNAL(linkActivated(QString)), this, SLOT(showFile())); + layout->addWidget(message); + + changeFolderButton = new QPushButton(); + changeFolderButton->setAttribute(Qt::WA_MacMiniSize); + changeFolderButton->setText(tr("Change location...")); + connect(changeFolderButton, SIGNAL(clicked()), SLOT(changeFolder())); + layout->addWidget(changeFolderButton); +} + +void SnapshotSettings::setSnapshot(const QPixmap &pixmap, const QString &filename) { + QPixmap p = pixmap.scaledToHeight(message->sizeHint().height()); + QIcon icon(p); + thumb->setIcon(icon); + thumb->setIconSize(p.size()); + // thumb->setPixmap(pixmap.scaledToHeight(message->sizeHint().height())); + + this->filename = filename; + QFileInfo fileInfo(filename); + QString path = fileInfo.absolutePath(); + QString display = displayPath(path); + + QString msg = tr("Snapshot saved to %1") + .arg("%1") + .arg(display); + message->setText(msg); +} + +void SnapshotSettings::setCurrentLocation(const QString &location) { + QSettings settings; + settings.setValue("snapshotsFolder", location); +} + +QString SnapshotSettings::getCurrentLocation() { + QSettings settings; + QString location = settings.value("snapshotsFolder").toString(); + if (location.isEmpty() || !QFile::exists(location)) { +#if QT_VERSION >= 0x050000 + location = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); +#else + location = QDesktopServices::storageLocation(QDesktopServices::PicturesLocation); +#endif + } + return location; +} + +QString SnapshotSettings::displayPath(const QString &path) { +#if QT_VERSION >= 0x050000 + QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); +#else + QString home = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); +#endif + QString displayPath = path; + displayPath = displayPath.remove(home + "/"); + return displayPath; +} + +void SnapshotSettings::changeFolder() { + QString path; +#ifdef APP_MAC + QFileDialog* dialog = new QFileDialog(this); + dialog->setFileMode(QFileDialog::Directory); + dialog->setOptions(QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks | QFileDialog::ReadOnly); +#if QT_VERSION >= 0x050000 + path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); +#else + path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); +#endif + dialog->setDirectory(path); + dialog->open(this, SLOT(folderChosen(const QString &))); +#else + +#if QT_VERSION >= 0x050000 + path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); +#else + path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); +#endif + QString folder = QFileDialog::getExistingDirectory(window(), QString(), + path, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks | QFileDialog::ReadOnly); + folderChosen(folder); +#endif +} + +void SnapshotSettings::folderChosen(const QString &dir) { + if (!dir.isEmpty()) { + setCurrentLocation(dir); + QString status = tr("Snapshots location changed."); + MainWindow::instance()->showMessage(status); + } +} + +void SnapshotSettings::showFile() { + QFileInfo info(filename); +#ifdef APP_MAC + mac::showInFinder(info.absoluteFilePath()); +#else + QUrl url = QUrl::fromLocalFile(info.absolutePath()); + QDesktopServices::openUrl(url); +#endif +} + +void SnapshotSettings::openFile() { + QDesktopServices::openUrl(QUrl::fromLocalFile(filename)); +} diff --git a/src/snapshotsettings.h b/src/snapshotsettings.h new file mode 100644 index 0000000..5a8acfe --- /dev/null +++ b/src/snapshotsettings.h @@ -0,0 +1,55 @@ +/* $BEGIN_LICENSE + +This file is part of Minitube. +Copyright 2009, Flavio Tordini + +Minitube is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Minitube is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitube. If not, see . + +$END_LICENSE */ + +#ifndef SNAPSHOTSETTINGS_H +#define SNAPSHOTSETTINGS_H + +#include +#if QT_VERSION >= 0x050000 +#include +#endif + +class SnapshotSettings : public QWidget { + + Q_OBJECT + +public: + SnapshotSettings(QWidget *parent = 0); + void setSnapshot(const QPixmap &pixmap, const QString &filename); + + static void setCurrentLocation(const QString &location); + static QString getCurrentLocation(); + static QString displayPath(const QString &path); + +private slots: + void changeFolder(); + void folderChosen(const QString &folder); + void showFile(); + void openFile(); + +private: + QToolButton *thumb; + QLabel *message; + QPushButton *changeFolderButton; + QString filename; + +}; + +#endif // SNAPSHOTSETTINGS_H diff --git a/src/videoareawidget.cpp b/src/videoareawidget.cpp index ee64a20..4adc47e 100644 --- a/src/videoareawidget.cpp +++ b/src/videoareawidget.cpp @@ -19,25 +19,21 @@ along with Minitube. If not, see . $END_LICENSE */ #include "videoareawidget.h" +#include "video.h" +#include "loadingwidget.h" +#include "playlistmodel.h" #include "videomimedata.h" #include "mainwindow.h" -#ifdef APP_EXTRA -#include "extra.h" -#endif #ifdef Q_OS_MAC #include "macutils.h" #endif +#include "snapshotpreview.h" VideoAreaWidget::VideoAreaWidget(QWidget *parent) : QWidget(parent), videoWidget(0) { QBoxLayout *vLayout = new QVBoxLayout(this); vLayout->setMargin(0); vLayout->setSpacing(0); - QPalette p = palette(); - p.setBrush(QPalette::Window, Qt::black); - setPalette(p); - setAutoFillBackground(true); - // hidden message widget messageLabel = new QLabel(this); messageLabel->setOpenExternalLinks(true); @@ -52,9 +48,11 @@ VideoAreaWidget::VideoAreaWidget(QWidget *parent) : QWidget(parent), videoWidget stackedLayout = new QStackedLayout(); vLayout->addLayout(stackedLayout); - // snapshotPreview = new QLabel(this); - // stackedLayout->addWidget(snapshotPreview); - +#ifdef APP_SNAPSHOT + snapshotPreview = new SnapshotPreview(); + connect(stackedLayout, SIGNAL(currentChanged(int)), snapshotPreview, SLOT(hide())); +#endif + setAcceptDrops(true); setMouseTracking(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -92,26 +90,24 @@ void VideoAreaWidget::showLoading(Video *video) { loadingWidget->setVideo(video); } -/* -void VideoAreaWidget::showSnapshotPreview(QPixmap pixmap) { - snapshotPreview->setPixmap(pixmap); - stackedLayout->setCurrentWidget(snapshotPreview); -#ifdef APP_EXTRA - Extra::flashInWidget(snapshotPreview); +#ifdef APP_SNAPSHOT +void VideoAreaWidget::showSnapshotPreview(const QPixmap &pixmap) { + bool soundOnly = false; +#ifdef APP_MAC + soundOnly = MainWindow::instance()->isReallyFullScreen(); #endif - QTimer::singleShot(1500, this, SLOT(hideSnapshotPreview())); + snapshotPreview->start(videoWidget, pixmap, soundOnly); } void VideoAreaWidget::hideSnapshotPreview() { - stackedLayout->setCurrentWidget(videoWidget); + } -*/ +#endif void VideoAreaWidget::clear() { loadingWidget->clear(); messageLabel->hide(); messageLabel->clear(); - // snapshotPreview->clear(); stackedLayout->setCurrentWidget(loadingWidget); } diff --git a/src/videoareawidget.h b/src/videoareawidget.h index 3673f69..e40d38f 100644 --- a/src/videoareawidget.h +++ b/src/videoareawidget.h @@ -21,10 +21,15 @@ $END_LICENSE */ #ifndef VIDEOAREAWIDGET_H #define VIDEOAREAWIDGET_H -#include -#include "video.h" -#include "loadingwidget.h" -#include "playlistmodel.h" +#include +#if QT_VERSION >= 0x050000 +#include +#endif + +class Video; +class LoadingWidget; +class PlaylistModel; +class SnapshotPreview; class VideoAreaWidget : public QWidget { @@ -41,7 +46,9 @@ public: void setListModel(PlaylistModel *listModel) { this->listModel = listModel; } - // void showSnapshotPreview(QPixmap pixmap); +#ifdef APP_SNAPSHOT + void showSnapshotPreview(const QPixmap &pixmap); +#endif bool isVideoShown() { return stackedLayout->currentWidget() == videoWidget; } signals: @@ -56,17 +63,23 @@ protected: void dropEvent(QDropEvent *event); private slots: - // void hideSnapshotPreview(); +#ifdef APP_SNAPSHOT + void hideSnapshotPreview(); +#endif private: QStackedLayout *stackedLayout; QWidget *videoWidget; LoadingWidget *loadingWidget; + +#ifdef APP_SNAPSHOT + SnapshotPreview *snapshotPreview; +#endif + PlaylistModel *listModel; QLabel *messageLabel; - // QLabel *snapshotPreview; - QPoint dragPosition; + QPoint dragPosition; }; #endif // VIDEOAREAWIDGET_H