From e6c1b97d67f6b6c6d4ad935db14241b041b3fca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9ven=20Car?= Date: Sun, 14 Apr 2019 16:54:54 +0200 Subject: [PATCH] Allow dolphin to auto-play previewed media file, click on preview to play/pause videos or audio Summary: It is based on D19844. I did my best to avoid glitches hence the amount of code touched. Retry after @pekkah D7539 Moved the setting to the information panel context menu, no more timer Settings screenshot : {F6700220} This would mach the same feature in the open/save dialog (although not equivalent) {F6696456} FEATURE: 378613 FIXED-IN: 19.08.0 GUI: New information panel context menu option Test Plan: Without auto play - in dolphin with the information panel opened, and the auto media play feature is disabled (right on the information panel) - hover over media files - the behavior is the same as before the patch With auto play - in dolphin with the information panel opened, and the auto media play feature is enabled - hover over media files - media is played automatically - hover over another media file, the new media is previewed Use audio or video file as media. Reviewers: #dolphin, elvisangelaccio, ngraham Reviewed By: #dolphin, elvisangelaccio, ngraham Subscribers: ngraham, broulik, kfm-devel, pekkah Tags: #dolphin Differential Revision: https://phabricator.kde.org/D19782 --- .../dolphin_informationpanelsettings.kcfg | 4 ++ src/panels/information/informationpanel.cpp | 8 +++ .../information/informationpanelcontent.cpp | 33 +++++++++-- .../information/informationpanelcontent.h | 7 +++ src/panels/information/phononwidget.cpp | 58 ++++++++++++------- src/panels/information/phononwidget.h | 20 +++++-- 6 files changed, 98 insertions(+), 32 deletions(-) diff --git a/src/panels/information/dolphin_informationpanelsettings.kcfg b/src/panels/information/dolphin_informationpanelsettings.kcfg index dbc1ab6d29..7a5d29728f 100644 --- a/src/panels/information/dolphin_informationpanelsettings.kcfg +++ b/src/panels/information/dolphin_informationpanelsettings.kcfg @@ -10,6 +10,10 @@ true + + + false + diff --git a/src/panels/information/informationpanel.cpp b/src/panels/information/informationpanel.cpp index 9a0358df07..e6c3bf32ad 100644 --- a/src/panels/information/informationpanel.cpp +++ b/src/panels/information/informationpanel.cpp @@ -176,6 +176,11 @@ void InformationPanel::showContextMenu(const QPoint &pos) previewAction->setCheckable(true); previewAction->setChecked(InformationPanelSettings::previewsShown()); + QAction* previewAutoPlayAction = popup.addAction(i18nc("@action:inmenu", "Auto-Play media files")); + previewAutoPlayAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); + previewAutoPlayAction->setCheckable(true); + previewAutoPlayAction->setChecked(InformationPanelSettings::previewsAutoPlay()); + QAction* configureAction = popup.addAction(i18nc("@action:inmenu", "Configure...")); configureAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); if (m_inConfigurationMode) { @@ -213,6 +218,9 @@ void InformationPanel::showContextMenu(const QPoint &pos) InformationPanelSettings::setDateFormat(dateFormat); m_content->refreshMetaData(); + } else if (action == previewAutoPlayAction) { + InformationPanelSettings::setPreviewsAutoPlay(isChecked); + m_content->setPreviewAutoPlay(isChecked); } } diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp index 5b7dbbfe90..444261eff0 100644 --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -86,6 +86,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : m_phononWidget = new PhononWidget(parent); m_phononWidget->hide(); m_phononWidget->setMinimumWidth(minPreviewWidth); + m_phononWidget->setAutoPlay(InformationPanelSettings::previewsAutoPlay()); connect(m_phononWidget, &PhononWidget::hasVideoChanged, this, &InformationPanelContent::slotHasVideoChanged); @@ -157,10 +158,12 @@ InformationPanelContent::~InformationPanelContent() void InformationPanelContent::showItem(const KFileItem& item) { - m_item = item; + if (item != m_item) { + m_item = item; - refreshPreview(); - refreshMetaData(); + refreshPreview(); + refreshMetaData(); + } } void InformationPanelContent::refreshPreview() @@ -173,11 +176,12 @@ void InformationPanelContent::refreshPreview() setNameLabelText(m_item.text()); if (InformationPanelSettings::previewsShown()) { - m_preview->show(); const QUrl itemUrl = m_item.url(); const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty(); if (isSearchUrl) { + m_preview->show(); + // in the case of a search-URL the URL is not readable for humans // (at least not useful to show in the Information Panel) m_preview->setPixmap( @@ -211,13 +215,26 @@ void InformationPanelContent::refreshPreview() this, &InformationPanelContent::showIcon); const QString mimeType = m_item.mimetype(); - const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || mimeType.startsWith(QLatin1String("video/")); + const bool isVideo = mimeType.startsWith(QLatin1String("video/")); + const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; + if (usePhonon) { + + if (InformationPanelSettings::previewsAutoPlay() && isVideo) { + // hides the preview now to avoid flickering when the autoplay video starts + m_preview->hide(); + } else { + // the video won't play before the preview is displayed + m_preview->show(); + } + m_phononWidget->show(); - m_phononWidget->setUrl(m_item.targetUrl()); + m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio); m_phononWidget->setVideoSize(m_preview->size()); } else { + // When we don't need it, hide the phonon widget first to avoid flickering m_phononWidget->hide(); + m_preview->show(); } } } else { @@ -328,6 +345,10 @@ void InformationPanelContent::slotHasVideoChanged(bool hasVideo) m_preview->setVisible(InformationPanelSettings::previewsShown() && !hasVideo); } +void InformationPanelContent::setPreviewAutoPlay(bool autoPlay) { + m_phononWidget->setAutoPlay(autoPlay); +} + void InformationPanelContent::setNameLabelText(const QString& text) { QTextOption textOption; diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h index 43410ddfae..0d838b2688 100644 --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -81,6 +81,13 @@ public: */ void configureShownProperties(); + /* + * Set the auto play media mode for the file previewed + * Eventually starting media playback when turning it on + * But not stopping it when turning it off + */ + void setPreviewAutoPlay(bool autoPlay); + signals: void urlActivated( const QUrl& url ); void configurationFinished(); diff --git a/src/panels/information/phononwidget.cpp b/src/panels/information/phononwidget.cpp index 77e066d372..4ea2e6666a 100644 --- a/src/panels/information/phononwidget.cpp +++ b/src/panels/information/phononwidget.cpp @@ -69,11 +69,24 @@ PhononWidget::PhononWidget(QWidget *parent) { } -void PhononWidget::setUrl(const QUrl &url) +void PhononWidget::setUrl(const QUrl &url, MediaKind kind) { if (m_url != url) { - stop(); // emits playingStopped() signal m_url = url; + m_isVideo = kind == MediaKind::Video; + } + if (m_autoPlay) { + play(); + } else { + stop(); + } +} + +void PhononWidget::setAutoPlay(bool autoPlay) +{ + m_autoPlay = autoPlay; + if (!m_url.isEmpty() && (m_media == nullptr || m_media->state() != Phonon::State::PlayingState) && m_autoPlay && isVisible()) { + play(); } } @@ -162,12 +175,6 @@ void PhononWidget::stateChanged(Phonon::State newstate) m_stopButton->show(); m_playButton->hide(); break; - case Phonon::StoppedState: - if (m_videoPlayer) { - m_videoPlayer->hide(); - } - emit hasVideoChanged(false); - Q_FALLTHROUGH(); default: m_stopButton->hide(); m_playButton->show(); @@ -182,13 +189,14 @@ void PhononWidget::play() m_media = new Phonon::MediaObject(this); connect(m_media, &Phonon::MediaObject::stateChanged, this, &PhononWidget::stateChanged); - connect(m_media, &Phonon::MediaObject::hasVideoChanged, - this, &PhononWidget::slotHasVideoChanged); + connect(m_media, &Phonon::MediaObject::finished, + this, &PhononWidget::finished); m_seekSlider->setMediaObject(m_media); } if (!m_videoPlayer) { m_videoPlayer = new EmbeddedVideoPlayer(this); + m_videoPlayer->installEventFilter(this); m_topLayout->insertWidget(0, m_videoPlayer); Phonon::createPath(m_media, m_videoPlayer); applyVideoSize(); @@ -199,26 +207,32 @@ void PhononWidget::play() Phonon::createPath(m_media, m_audioOutput); } - emit hasVideoChanged(false); + if (m_isVideo) { + emit hasVideoChanged(true); + } - m_media->setCurrentSource(m_url); - m_media->hasVideo(); + if (m_url != m_media->currentSource().url()) { + m_media->setCurrentSource(m_url); + } m_media->play(); + + m_videoPlayer->setVisible(m_isVideo); +} + +void PhononWidget::finished() +{ + if (m_isVideo) { + m_videoPlayer->hide(); + emit hasVideoChanged(false); + } } void PhononWidget::stop() { if (m_media) { m_media->stop(); - } -} - -void PhononWidget::slotHasVideoChanged(bool hasVideo) -{ - emit hasVideoChanged(hasVideo); - - if (hasVideo) { - m_videoPlayer->show(); + m_videoPlayer->hide(); + emit hasVideoChanged(false); } } diff --git a/src/panels/information/phononwidget.h b/src/panels/information/phononwidget.h index 971e8c7312..b9e7d4f05a 100644 --- a/src/panels/information/phononwidget.h +++ b/src/panels/information/phononwidget.h @@ -43,14 +43,22 @@ class PhononWidget : public QWidget { Q_OBJECT public: + + enum MediaKind { + Video, + Audio + }; + explicit PhononWidget(QWidget *parent = nullptr); - void setUrl(const QUrl &url); + void setUrl(const QUrl &url, MediaKind kind); QUrl url() const; void setVideoSize(const QSize& size); QSize videoSize() const; + void setAutoPlay(bool autoPlay); + signals: /** * Is emitted whenever the video-state @@ -62,15 +70,17 @@ class PhononWidget : public QWidget */ void hasVideoChanged(bool hasVideo); + public slots: + void play(); + protected: void showEvent(QShowEvent *event) override; void hideEvent(QHideEvent *event) override; private slots: - void stateChanged(Phonon::State); - void play(); + void stateChanged(Phonon::State newstate); void stop(); - void slotHasVideoChanged(bool); + void finished(); private: void applyVideoSize(); @@ -87,6 +97,8 @@ class PhononWidget : public QWidget Phonon::SeekSlider *m_seekSlider; Phonon::AudioOutput *m_audioOutput; EmbeddedVideoPlayer *m_videoPlayer; + bool m_autoPlay; + bool m_isVideo; }; #endif // PHONONWIDGET_H