diff --git a/src/panels/information/dolphin_informationpanelsettings.kcfg b/src/panels/information/dolphin_informationpanelsettings.kcfg --- 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 --- a/src/panels/information/informationpanel.cpp +++ b/src/panels/information/informationpanel.cpp @@ -176,6 +176,11 @@ 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"))); @@ -209,12 +214,14 @@ dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); connect(dialog, &FileMetaDataConfigurationDialog::destroyed, m_content, &InformationPanelContent::refreshMetaData); - } - if (action == dateformatAction) { + } else if (action == dateformatAction) { int dateFormat = static_cast(isChecked ? Baloo::DateFormats::ShortFormat : Baloo::DateFormats::LongFormat); InformationPanelSettings::setDateFormat(dateFormat); m_content->refreshMetaData(); + } else if (action == previewAutoPlayAction) { + InformationPanelSettings::setPreviewsAutoPlay(isChecked); + m_content->setPreviewAutoPlay(isChecked); } } diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -79,6 +79,13 @@ */ void refreshPreview(); + /** + * Set the auto play media mode for the file previewed + * Eventualy 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 ); diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -85,6 +85,7 @@ 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); @@ -141,10 +142,12 @@ void InformationPanelContent::showItem(const KFileItem& item) { - m_item = item; + if (item != m_item) { + m_item = item; - refreshPreview(); - refreshMetaData(); + refreshPreview(); + refreshMetaData(); + } } void InformationPanelContent::refreshPreview() { @@ -155,12 +158,13 @@ } if (InformationPanelSettings::previewsShown()) { - m_preview->show(); const QUrl itemUrl = m_item.url(); const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty(); setNameLabelText(m_item.text()); 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( @@ -194,13 +198,32 @@ 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) { + // Clicking on the preview can toggle media preview playback + m_preview->installEventFilter(m_phononWidget); + m_preview->setToolTip(i18n("Click to play")); + + 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(); + + m_preview->removeEventFilter(m_phononWidget); + m_preview->setToolTip(QString()); } } } else { @@ -306,6 +329,10 @@ 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/phononwidget.h b/src/panels/information/phononwidget.h --- a/src/panels/information/phononwidget.h +++ b/src/panels/information/phononwidget.h @@ -43,14 +43,22 @@ { 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,19 @@ */ void hasVideoChanged(bool hasVideo); + public slots: + void togglePlay(); + void play(); + protected: + bool eventFilter(QObject *obj, QEvent *event) override; 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 +99,8 @@ Phonon::SeekSlider *m_seekSlider; Phonon::AudioOutput *m_audioOutput; EmbeddedVideoPlayer *m_videoPlayer; + bool m_autoPlay; + bool m_isVideo; }; #endif // PHONONWIDGET_H diff --git a/src/panels/information/phononwidget.cpp b/src/panels/information/phononwidget.cpp --- a/src/panels/information/phononwidget.cpp +++ b/src/panels/information/phononwidget.cpp @@ -69,11 +69,38 @@ { } -void PhononWidget::setUrl(const QUrl &url) +bool PhononWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::MouseButton::LeftButton) { + // a click has been detected, toggle preview playback + togglePlay(); + return true; + } + } + // standard event processing + return QObject::eventFilter(obj, event); +} + +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(); } } @@ -145,6 +172,29 @@ } } +void PhononWidget::togglePlay() +{ + if (m_media) { + auto media_state = m_media->state(); + if (media_state == Phonon::PlayingState) { + // the media was playing pause it + if (m_isVideo) { + // change the tooltip accordingly + m_videoPlayer->setToolTip(i18n("Play")); + } + m_media->pause(); + } else { + // in any other cases, it is time to play + if (m_isVideo) { + m_videoPlayer->setToolTip(i18n("Pause")); + } + play(); + } + } else { + play(); + } +} + void PhononWidget::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); @@ -163,10 +213,6 @@ m_playButton->hide(); break; case Phonon::StoppedState: - if (m_videoPlayer) { - m_videoPlayer->hide(); - } - emit hasVideoChanged(false); Q_FALLTHROUGH(); default: m_stopButton->hide(); @@ -182,13 +228,14 @@ 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 +246,33 @@ Phonon::createPath(m_media, m_audioOutput); } - emit hasVideoChanged(false); + if (m_isVideo) { + m_videoPlayer->setToolTip(i18n("Pause")); + 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/pixmapviewer.cpp b/src/panels/information/pixmapviewer.cpp --- a/src/panels/information/pixmapviewer.cpp +++ b/src/panels/information/pixmapviewer.cpp @@ -23,6 +23,7 @@ #include #include +#include PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) : QWidget(parent),