mirror of
https://invent.kde.org/system/dolphin
synced 2024-10-28 03:21:56 +00:00
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:
parent
cdad6a513e
commit
e6c1b97d67
|
@ -10,6 +10,10 @@
|
||||||
<label>Previews shown</label>
|
<label>Previews shown</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="previewsAutoPlay" type="Bool">
|
||||||
|
<label>Auto-Play media files</label>
|
||||||
|
<default>false</default>
|
||||||
|
</entry>
|
||||||
<entry name="dateFormat" type="Enum">
|
<entry name="dateFormat" type="Enum">
|
||||||
<label>Date display format</label>
|
<label>Date display format</label>
|
||||||
<choices>
|
<choices>
|
||||||
|
|
|
@ -176,6 +176,11 @@ void InformationPanel::showContextMenu(const QPoint &pos)
|
||||||
previewAction->setCheckable(true);
|
previewAction->setCheckable(true);
|
||||||
previewAction->setChecked(InformationPanelSettings::previewsShown());
|
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..."));
|
QAction* configureAction = popup.addAction(i18nc("@action:inmenu", "Configure..."));
|
||||||
configureAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
|
configureAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
|
||||||
if (m_inConfigurationMode) {
|
if (m_inConfigurationMode) {
|
||||||
|
@ -213,6 +218,9 @@ void InformationPanel::showContextMenu(const QPoint &pos)
|
||||||
|
|
||||||
InformationPanelSettings::setDateFormat(dateFormat);
|
InformationPanelSettings::setDateFormat(dateFormat);
|
||||||
m_content->refreshMetaData();
|
m_content->refreshMetaData();
|
||||||
|
} else if (action == previewAutoPlayAction) {
|
||||||
|
InformationPanelSettings::setPreviewsAutoPlay(isChecked);
|
||||||
|
m_content->setPreviewAutoPlay(isChecked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
|
||||||
m_phononWidget = new PhononWidget(parent);
|
m_phononWidget = new PhononWidget(parent);
|
||||||
m_phononWidget->hide();
|
m_phononWidget->hide();
|
||||||
m_phononWidget->setMinimumWidth(minPreviewWidth);
|
m_phononWidget->setMinimumWidth(minPreviewWidth);
|
||||||
|
m_phononWidget->setAutoPlay(InformationPanelSettings::previewsAutoPlay());
|
||||||
connect(m_phononWidget, &PhononWidget::hasVideoChanged,
|
connect(m_phononWidget, &PhononWidget::hasVideoChanged,
|
||||||
this, &InformationPanelContent::slotHasVideoChanged);
|
this, &InformationPanelContent::slotHasVideoChanged);
|
||||||
|
|
||||||
|
@ -157,10 +158,12 @@ InformationPanelContent::~InformationPanelContent()
|
||||||
|
|
||||||
void InformationPanelContent::showItem(const KFileItem& item)
|
void InformationPanelContent::showItem(const KFileItem& item)
|
||||||
{
|
{
|
||||||
m_item = item;
|
if (item != m_item) {
|
||||||
|
m_item = item;
|
||||||
|
|
||||||
refreshPreview();
|
refreshPreview();
|
||||||
refreshMetaData();
|
refreshMetaData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InformationPanelContent::refreshPreview()
|
void InformationPanelContent::refreshPreview()
|
||||||
|
@ -173,11 +176,12 @@ void InformationPanelContent::refreshPreview()
|
||||||
|
|
||||||
setNameLabelText(m_item.text());
|
setNameLabelText(m_item.text());
|
||||||
if (InformationPanelSettings::previewsShown()) {
|
if (InformationPanelSettings::previewsShown()) {
|
||||||
m_preview->show();
|
|
||||||
|
|
||||||
const QUrl itemUrl = m_item.url();
|
const QUrl itemUrl = m_item.url();
|
||||||
const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty();
|
const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty();
|
||||||
if (isSearchUrl) {
|
if (isSearchUrl) {
|
||||||
|
m_preview->show();
|
||||||
|
|
||||||
// in the case of a search-URL the URL is not readable for humans
|
// in the case of a search-URL the URL is not readable for humans
|
||||||
// (at least not useful to show in the Information Panel)
|
// (at least not useful to show in the Information Panel)
|
||||||
m_preview->setPixmap(
|
m_preview->setPixmap(
|
||||||
|
@ -211,13 +215,26 @@ void InformationPanelContent::refreshPreview()
|
||||||
this, &InformationPanelContent::showIcon);
|
this, &InformationPanelContent::showIcon);
|
||||||
|
|
||||||
const QString mimeType = m_item.mimetype();
|
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 (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->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());
|
m_phononWidget->setVideoSize(m_preview->size());
|
||||||
} else {
|
} else {
|
||||||
|
// When we don't need it, hide the phonon widget first to avoid flickering
|
||||||
m_phononWidget->hide();
|
m_phononWidget->hide();
|
||||||
|
m_preview->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -328,6 +345,10 @@ void InformationPanelContent::slotHasVideoChanged(bool hasVideo)
|
||||||
m_preview->setVisible(InformationPanelSettings::previewsShown() && !hasVideo);
|
m_preview->setVisible(InformationPanelSettings::previewsShown() && !hasVideo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InformationPanelContent::setPreviewAutoPlay(bool autoPlay) {
|
||||||
|
m_phononWidget->setAutoPlay(autoPlay);
|
||||||
|
}
|
||||||
|
|
||||||
void InformationPanelContent::setNameLabelText(const QString& text)
|
void InformationPanelContent::setNameLabelText(const QString& text)
|
||||||
{
|
{
|
||||||
QTextOption textOption;
|
QTextOption textOption;
|
||||||
|
|
|
@ -81,6 +81,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void configureShownProperties();
|
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:
|
signals:
|
||||||
void urlActivated( const QUrl& url );
|
void urlActivated( const QUrl& url );
|
||||||
void configurationFinished();
|
void configurationFinished();
|
||||||
|
|
|
@ -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) {
|
if (m_url != url) {
|
||||||
stop(); // emits playingStopped() signal
|
|
||||||
m_url = url;
|
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_stopButton->show();
|
||||||
m_playButton->hide();
|
m_playButton->hide();
|
||||||
break;
|
break;
|
||||||
case Phonon::StoppedState:
|
|
||||||
if (m_videoPlayer) {
|
|
||||||
m_videoPlayer->hide();
|
|
||||||
}
|
|
||||||
emit hasVideoChanged(false);
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
default:
|
default:
|
||||||
m_stopButton->hide();
|
m_stopButton->hide();
|
||||||
m_playButton->show();
|
m_playButton->show();
|
||||||
|
@ -182,13 +189,14 @@ void PhononWidget::play()
|
||||||
m_media = new Phonon::MediaObject(this);
|
m_media = new Phonon::MediaObject(this);
|
||||||
connect(m_media, &Phonon::MediaObject::stateChanged,
|
connect(m_media, &Phonon::MediaObject::stateChanged,
|
||||||
this, &PhononWidget::stateChanged);
|
this, &PhononWidget::stateChanged);
|
||||||
connect(m_media, &Phonon::MediaObject::hasVideoChanged,
|
connect(m_media, &Phonon::MediaObject::finished,
|
||||||
this, &PhononWidget::slotHasVideoChanged);
|
this, &PhononWidget::finished);
|
||||||
m_seekSlider->setMediaObject(m_media);
|
m_seekSlider->setMediaObject(m_media);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_videoPlayer) {
|
if (!m_videoPlayer) {
|
||||||
m_videoPlayer = new EmbeddedVideoPlayer(this);
|
m_videoPlayer = new EmbeddedVideoPlayer(this);
|
||||||
|
m_videoPlayer->installEventFilter(this);
|
||||||
m_topLayout->insertWidget(0, m_videoPlayer);
|
m_topLayout->insertWidget(0, m_videoPlayer);
|
||||||
Phonon::createPath(m_media, m_videoPlayer);
|
Phonon::createPath(m_media, m_videoPlayer);
|
||||||
applyVideoSize();
|
applyVideoSize();
|
||||||
|
@ -199,26 +207,32 @@ void PhononWidget::play()
|
||||||
Phonon::createPath(m_media, m_audioOutput);
|
Phonon::createPath(m_media, m_audioOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit hasVideoChanged(false);
|
if (m_isVideo) {
|
||||||
|
emit hasVideoChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
m_media->setCurrentSource(m_url);
|
if (m_url != m_media->currentSource().url()) {
|
||||||
m_media->hasVideo();
|
m_media->setCurrentSource(m_url);
|
||||||
|
}
|
||||||
m_media->play();
|
m_media->play();
|
||||||
|
|
||||||
|
m_videoPlayer->setVisible(m_isVideo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhononWidget::finished()
|
||||||
|
{
|
||||||
|
if (m_isVideo) {
|
||||||
|
m_videoPlayer->hide();
|
||||||
|
emit hasVideoChanged(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhononWidget::stop()
|
void PhononWidget::stop()
|
||||||
{
|
{
|
||||||
if (m_media) {
|
if (m_media) {
|
||||||
m_media->stop();
|
m_media->stop();
|
||||||
}
|
m_videoPlayer->hide();
|
||||||
}
|
emit hasVideoChanged(false);
|
||||||
|
|
||||||
void PhononWidget::slotHasVideoChanged(bool hasVideo)
|
|
||||||
{
|
|
||||||
emit hasVideoChanged(hasVideo);
|
|
||||||
|
|
||||||
if (hasVideo) {
|
|
||||||
m_videoPlayer->show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,22 @@ class PhononWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum MediaKind {
|
||||||
|
Video,
|
||||||
|
Audio
|
||||||
|
};
|
||||||
|
|
||||||
explicit PhononWidget(QWidget *parent = nullptr);
|
explicit PhononWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setUrl(const QUrl &url);
|
void setUrl(const QUrl &url, MediaKind kind);
|
||||||
QUrl url() const;
|
QUrl url() const;
|
||||||
|
|
||||||
void setVideoSize(const QSize& size);
|
void setVideoSize(const QSize& size);
|
||||||
QSize videoSize() const;
|
QSize videoSize() const;
|
||||||
|
|
||||||
|
void setAutoPlay(bool autoPlay);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* Is emitted whenever the video-state
|
* Is emitted whenever the video-state
|
||||||
|
@ -62,15 +70,17 @@ class PhononWidget : public QWidget
|
||||||
*/
|
*/
|
||||||
void hasVideoChanged(bool hasVideo);
|
void hasVideoChanged(bool hasVideo);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void play();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
void hideEvent(QHideEvent *event) override;
|
void hideEvent(QHideEvent *event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void stateChanged(Phonon::State);
|
void stateChanged(Phonon::State newstate);
|
||||||
void play();
|
|
||||||
void stop();
|
void stop();
|
||||||
void slotHasVideoChanged(bool);
|
void finished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void applyVideoSize();
|
void applyVideoSize();
|
||||||
|
@ -87,6 +97,8 @@ class PhononWidget : public QWidget
|
||||||
Phonon::SeekSlider *m_seekSlider;
|
Phonon::SeekSlider *m_seekSlider;
|
||||||
Phonon::AudioOutput *m_audioOutput;
|
Phonon::AudioOutput *m_audioOutput;
|
||||||
EmbeddedVideoPlayer *m_videoPlayer;
|
EmbeddedVideoPlayer *m_videoPlayer;
|
||||||
|
bool m_autoPlay;
|
||||||
|
bool m_isVideo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PHONONWIDGET_H
|
#endif // PHONONWIDGET_H
|
||||||
|
|
Loading…
Reference in a new issue