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
This commit is contained in:
Méven Car 2019-04-14 16:54:54 +02:00
parent cdad6a513e
commit e6c1b97d67
6 changed files with 98 additions and 32 deletions

View file

@ -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>

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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