[dolphin] src/panels/information: Allow dolphin to auto-play previewed media file, click on preview to play/pause videos or audio

Méven Car null at kde.org
Sun Jun 23 15:38:12 BST 2019


Git commit e6c1b97d67f6b6c6d4ad935db14241b041b3fca4 by Méven Car.
Committed on 23/06/2019 at 14:38.
Pushed by meven into branch 'master'.

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

M  +4    -0    src/panels/information/dolphin_informationpanelsettings.kcfg
M  +8    -0    src/panels/information/informationpanel.cpp
M  +27   -6    src/panels/information/informationpanelcontent.cpp
M  +7    -0    src/panels/information/informationpanelcontent.h
M  +35   -21   src/panels/information/phononwidget.cpp
M  +16   -4    src/panels/information/phononwidget.h

https://commits.kde.org/dolphin/e6c1b97d67f6b6c6d4ad935db14241b041b3fca4

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 @@
             <label>Previews shown</label>
             <default>true</default>
         </entry>
+        <entry name="previewsAutoPlay" type="Bool">
+            <label>Auto-Play media files</label>
+            <default>false</default>
+        </entry>
         <entry name="dateFormat" type="Enum">
             <label>Date display format</label>
             <choices>
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::stop()
+void PhononWidget::finished()
 {
-    if (m_media) {
-        m_media->stop();
+    if (m_isVideo) {
+        m_videoPlayer->hide();
+        emit hasVideoChanged(false);
     }
 }
 
-void PhononWidget::slotHasVideoChanged(bool hasVideo)
+void PhononWidget::stop()
 {
-    emit hasVideoChanged(hasVideo);
-
-    if (hasVideo) {
-        m_videoPlayer->show();
+    if (m_media) {
+        m_media->stop();
+        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


More information about the kde-doc-english mailing list