┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/panels
diff options
context:
space:
mode:
authorMéven Car <[email protected]>2019-06-23 17:36:38 +0200
committerMéven Car <[email protected]>2025-06-28 11:55:38 +0200
commit8216a67d58af0fd709bb3bfb8d0b6073b11cdfed (patch)
tree7e1e1d47da3df191b0443341e42e0dcb800907bd /src/panels
parent781e8e9e18579c0fe368ed9fe295f908493272b3 (diff)
InformationPanel: Port from Phonon to QtMultimedia
Diffstat (limited to 'src/panels')
-rw-r--r--src/panels/information/informationpanelcontent.cpp50
-rw-r--r--src/panels/information/informationpanelcontent.h4
-rw-r--r--src/panels/information/mediawidget.cpp368
-rw-r--r--src/panels/information/mediawidget.h (renamed from src/panels/information/phononwidget.h)39
-rw-r--r--src/panels/information/phononwidget.cpp265
5 files changed, 412 insertions, 314 deletions
diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp
index 14a470b11..1ab57c0e7 100644
--- a/src/panels/information/informationpanelcontent.cpp
+++ b/src/panels/information/informationpanelcontent.cpp
@@ -24,9 +24,6 @@
#include <Baloo/FileMetaDataWidget>
-#include <phonon/BackendCapabilities>
-#include <phonon/MediaObject>
-
#include <QDialogButtonBox>
#include <QGesture>
#include <QLabel>
@@ -40,7 +37,7 @@
#include <QVBoxLayout>
#include "dolphin_informationpanelsettings.h"
-#include "phononwidget.h"
+#include "mediawidget.h"
#include "pixmapviewer.h"
const int PLAY_ARROW_SIZE = 24;
@@ -52,7 +49,7 @@ InformationPanelContent::InformationPanelContent(QWidget *parent)
, m_previewJob(nullptr)
, m_outdatedPreviewTimer(nullptr)
, m_preview(nullptr)
- , m_phononWidget(nullptr)
+ , m_mediaWidget(nullptr)
, m_nameLabel(nullptr)
, m_metaDataWidget(nullptr)
, m_metaDataArea(nullptr)
@@ -77,11 +74,11 @@ InformationPanelContent::InformationPanelContent(QWidget *parent)
m_preview->setMinimumWidth(minPreviewWidth);
m_preview->setMinimumHeight(KIconLoader::SizeEnormous);
- 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);
+ m_mediaWidget = new MediaWidget(parent);
+ m_mediaWidget->hide();
+ m_mediaWidget->setMinimumWidth(minPreviewWidth);
+ m_mediaWidget->setAutoPlay(InformationPanelSettings::previewsAutoPlay());
+ connect(m_mediaWidget, &MediaWidget::hasVideoChanged, this, &InformationPanelContent::slotHasVideoChanged);
// name
m_nameLabel = new QLabel(parent);
@@ -132,7 +129,7 @@ InformationPanelContent::InformationPanelContent(QWidget *parent)
viewport->installEventFilter(this);
layout->addWidget(m_preview);
- layout->addWidget(m_phononWidget);
+ layout->addWidget(m_mediaWidget);
layout->addWidget(m_nameLabel);
layout->addWidget(new KSeparator());
layout->addWidget(m_configureLabel);
@@ -203,7 +200,7 @@ void InformationPanelContent::refreshPreview()
const bool isSearchUrl = itemUrl.scheme().contains(QLatin1String("search")) && m_item.localPath().isEmpty();
if (isSearchUrl) {
m_preview->show();
- m_phononWidget->hide();
+ m_mediaWidget->hide();
// in the case of a search-URL the URL is not readable for humans
// (at least not useful to show in the Information Panel)
@@ -219,16 +216,17 @@ void InformationPanelContent::refreshPreview()
if (usePhonon) {
// change the cursor of the preview
m_preview->setCursor(Qt::PointingHandCursor);
- m_preview->installEventFilter(m_phononWidget);
- m_phononWidget->show();
+ m_preview->installEventFilter(m_mediaWidget);
+
+ m_mediaWidget->show();
// if the video is playing, has been paused or stopped
// we don't need to update the preview/phonon widget states
// unless the previewed file has changed,
// or the setting previewshown has changed
- if ((m_phononWidget->state() != Phonon::State::PlayingState && m_phononWidget->state() != Phonon::State::PausedState
- && m_phononWidget->state() != Phonon::State::StoppedState)
- || m_item.targetUrl() != m_phononWidget->url() || (!m_preview->isVisible() && !m_phononWidget->isVisible())) {
+ if ((m_mediaWidget->state() != QMediaPlayer::PlayingState && m_mediaWidget->state() != QMediaPlayer::PausedState
+ && m_mediaWidget->state() != QMediaPlayer::StoppedState)
+ || m_item.targetUrl() != m_mediaWidget->url() || (!m_preview->isVisible() && !m_mediaWidget->isVisible())) {
if (InformationPanelSettings::previewsAutoPlay() && m_isVideo) {
// hides the preview now to avoid flickering when the autoplay video starts
m_preview->hide();
@@ -237,7 +235,7 @@ void InformationPanelContent::refreshPreview()
m_preview->show();
}
- m_phononWidget->setUrl(m_item.targetUrl(), m_isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio);
+ m_mediaWidget->setUrl(m_item.targetUrl(), m_isVideo ? MediaWidget::MediaKind::Video : MediaWidget::MediaKind::Audio);
adjustWidgetSizes(parentWidget()->width());
}
} else {
@@ -245,16 +243,16 @@ void InformationPanelContent::refreshPreview()
m_preview->setAnimatedImageFileName(itemUrl.toLocalFile());
}
// When we don't need it, hide the phonon widget first to avoid flickering
- m_phononWidget->hide();
+ m_mediaWidget->hide();
m_preview->show();
- m_preview->removeEventFilter(m_phononWidget);
- m_phononWidget->clearUrl();
+ m_preview->removeEventFilter(m_mediaWidget);
+ m_mediaWidget->clearUrl();
}
}
} else {
m_preview->stopAnimatedImage();
m_preview->hide();
- m_phononWidget->hide();
+ m_mediaWidget->hide();
}
}
@@ -287,7 +285,7 @@ void InformationPanelContent::showItems(const KFileItemList &items)
m_metaDataWidget->setItems(items);
- m_phononWidget->hide();
+ m_mediaWidget->hide();
m_item = KFileItem();
}
@@ -451,7 +449,7 @@ void InformationPanelContent::slotHasVideoChanged(bool hasVideo)
void InformationPanelContent::setPreviewAutoPlay(bool autoPlay)
{
- m_phononWidget->setAutoPlay(autoPlay);
+ m_mediaWidget->setAutoPlay(autoPlay);
}
void InformationPanelContent::setNameLabelText(const QString &text)
@@ -502,9 +500,9 @@ void InformationPanelContent::adjustWidgetSizes(int width)
// try to increase the preview as large as possible
m_preview->setSizeHint(QSize(maxWidth, maxWidth));
- if (m_phononWidget->isVisible()) {
+ if (m_mediaWidget->isVisible()) {
// assure that the size of the video player is the same as the preview size
- m_phononWidget->setVideoSize(QSize(maxWidth, maxWidth));
+ m_mediaWidget->setVideoSize(QSize(maxWidth, maxWidth));
}
}
diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h
index 0ea05d990..333b26608 100644
--- a/src/panels/information/informationpanelcontent.h
+++ b/src/panels/information/informationpanelcontent.h
@@ -15,7 +15,7 @@
#include <QWidget>
class KFileItemList;
-class PhononWidget;
+class MediaWidget;
class PixmapViewer;
class QPixmap;
class QDialogButtonBox;
@@ -145,7 +145,7 @@ private:
QTimer *m_outdatedPreviewTimer;
PixmapViewer *m_preview;
- PhononWidget *m_phononWidget;
+ MediaWidget *m_mediaWidget;
QLabel *m_nameLabel;
Baloo::FileMetaDataWidget *m_metaDataWidget;
QScrollArea *m_metaDataArea;
diff --git a/src/panels/information/mediawidget.cpp b/src/panels/information/mediawidget.cpp
new file mode 100644
index 000000000..345cb0201
--- /dev/null
+++ b/src/panels/information/mediawidget.cpp
@@ -0,0 +1,368 @@
+/*
+ SPDX-FileCopyrightText: 2007 Matthias Kretz <[email protected]>
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include "mediawidget.h"
+
+#include <KLocalizedString>
+
+#include <QAudioOutput>
+#include <QMediaPlayer>
+#include <QVideoWidget>
+
+#include <QShowEvent>
+#include <QSlider>
+#include <QStyle>
+#include <QStyleOptionSlider>
+#include <QToolButton>
+#include <QVBoxLayout>
+
+class EmbeddedVideoPlayer : public QVideoWidget
+{
+ Q_OBJECT
+
+public:
+ EmbeddedVideoPlayer(QWidget *parent = nullptr)
+ : QVideoWidget(parent)
+ {
+ }
+
+ void setSizeHint(const QSize &size)
+ {
+ m_sizeHint = size;
+ updateGeometry();
+ }
+
+ QSize sizeHint() const override
+ {
+ return m_sizeHint.isValid() ? m_sizeHint : QVideoWidget::sizeHint();
+ }
+
+private:
+ QSize m_sizeHint;
+};
+
+class SeekSlider : public QSlider
+{
+ Q_OBJECT
+
+public:
+ SeekSlider(Qt::Orientation orientation, QWidget *parent = nullptr)
+ : QSlider(orientation, parent)
+ {
+ }
+
+protected:
+ // Function copied from qslider.cpp
+ inline int pick(const QPoint &pt) const
+ {
+ return orientation() == Qt::Horizontal ? pt.x() : pt.y();
+ }
+
+ // Function copied from qslider.cpp and modified to make it compile
+ int pixelPosToRangeValue(int pos) const
+ {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this);
+ QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+ int sliderMin, sliderMax, sliderLength;
+
+ if (orientation() == Qt::Horizontal) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+ return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, sliderMax - sliderMin, opt.upsideDown);
+ }
+
+ // Based on code from qslider.cpp
+ void mousePressEvent(QMouseEvent *event) override
+ {
+ if (event->button() == Qt::LeftButton) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+ const QPoint center = sliderRect.center() - sliderRect.topLeft();
+ // to take half of the slider off for the setSliderPosition call we use the center - topLeft
+
+ if (!sliderRect.contains(event->pos())) {
+ event->accept();
+
+ int position = pixelPosToRangeValue(pick(event->pos() - center));
+ setSliderPosition(position);
+ triggerAction(SliderMove);
+ setRepeatAction(SliderNoAction);
+
+ Q_EMIT sliderMoved(position);
+ } else {
+ QSlider::mousePressEvent(event);
+ }
+ } else {
+ QSlider::mousePressEvent(event);
+ }
+ }
+};
+
+MediaWidget::MediaWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_url()
+ , m_playButton(nullptr)
+ , m_pauseButton(nullptr)
+ , m_topLayout(nullptr)
+ , m_player(nullptr)
+ , m_seekSlider(nullptr)
+ , m_videoWidget(nullptr)
+{
+}
+
+void MediaWidget::setUrl(const QUrl &url, MediaKind kind)
+{
+ if (m_url != url) {
+ m_url = url;
+ m_isVideo = kind == MediaKind::Video;
+ m_seekSlider->setValue(0);
+ }
+ if (m_autoPlay) {
+ play();
+ } else {
+ stop();
+ }
+}
+
+void MediaWidget::setAutoPlay(bool autoPlay)
+{
+ m_autoPlay = autoPlay;
+ if (!m_url.isEmpty() && (m_player == nullptr || m_player->playbackState() != QMediaPlayer::PlayingState) && m_autoPlay && isVisible()) {
+ play();
+ }
+}
+
+QUrl MediaWidget::url() const
+{
+ return m_url;
+}
+
+void MediaWidget::clearUrl()
+{
+ m_url.clear();
+}
+
+void MediaWidget::togglePlayback()
+{
+ if (m_player && m_player->playbackState() == QMediaPlayer::PlayingState) {
+ m_player->pause();
+ } else {
+ play();
+ }
+}
+
+bool MediaWidget::eventFilter(QObject *object, QEvent *event)
+{
+ Q_UNUSED(object)
+ if (event->type() == QEvent::MouseButtonPress) {
+ const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->button() == Qt::LeftButton) {
+ // toggle playback
+ togglePlayback();
+ return true;
+ }
+ }
+ return false;
+}
+
+void MediaWidget::setVideoSize(const QSize &size)
+{
+ if (m_videoSize != size) {
+ m_videoSize = size;
+ applyVideoSize();
+ }
+}
+
+QSize MediaWidget::videoSize() const
+{
+ return m_videoSize;
+}
+
+void MediaWidget::showEvent(QShowEvent *event)
+{
+ if (event->spontaneous()) {
+ QWidget::showEvent(event);
+ return;
+ }
+
+ if (!m_topLayout) {
+ m_topLayout = new QVBoxLayout(this);
+ m_topLayout->setContentsMargins(0, 0, 0, 0);
+
+ QHBoxLayout *controlsLayout = new QHBoxLayout();
+ controlsLayout->setContentsMargins(0, 0, 0, 0);
+ controlsLayout->setSpacing(0);
+
+ m_playButton = new QToolButton(this);
+ m_pauseButton = new QToolButton(this);
+ m_seekSlider = new SeekSlider(Qt::Orientation::Horizontal, this);
+ connect(m_seekSlider, &QAbstractSlider::sliderMoved, this, &MediaWidget::setPosition);
+
+ controlsLayout->addWidget(m_playButton);
+ controlsLayout->addWidget(m_pauseButton);
+ controlsLayout->addWidget(m_seekSlider);
+
+ m_topLayout->addLayout(controlsLayout);
+
+ const int smallIconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
+ const QSize buttonSize(smallIconSize, smallIconSize);
+
+ m_playButton->setToolTip(i18n("play"));
+ m_playButton->setIconSize(buttonSize);
+ m_playButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
+ m_playButton->setAutoRaise(true);
+ connect(m_playButton, &QToolButton::clicked, this, &MediaWidget::play);
+
+ m_pauseButton->setToolTip(i18n("pause"));
+ m_pauseButton->setIconSize(buttonSize);
+ m_pauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
+ m_pauseButton->setAutoRaise(true);
+ m_pauseButton->hide();
+ connect(m_pauseButton, &QToolButton::clicked, this, &MediaWidget::togglePlayback);
+
+ // Creating an audio player or video player instance might take up to
+ // 2 seconds when doing it the first time. To prevent that the user
+ // interface gets noticeable blocked, the creation is delayed until
+ // the play button has been pressed (see PhononWidget::play()).
+ }
+}
+
+void MediaWidget::hideEvent(QHideEvent *event)
+{
+ QWidget::hideEvent(event);
+ if (!event->spontaneous()) {
+ stop();
+ }
+}
+
+void MediaWidget::onStateChanged(QMediaPlayer::PlaybackState newState)
+{
+ setUpdatesEnabled(false);
+ switch (newState) {
+ case QMediaPlayer::PlaybackState::PlayingState:
+ m_playButton->hide();
+ m_pauseButton->show();
+ break;
+ default:
+ m_pauseButton->hide();
+ m_playButton->show();
+ break;
+ }
+ setUpdatesEnabled(true);
+}
+
+void MediaWidget::initPlayer()
+{
+ if (!m_player) {
+ m_player = new QMediaPlayer;
+ m_player->setAudioOutput(new QAudioOutput);
+
+ m_videoWidget = new EmbeddedVideoPlayer(this);
+ m_videoWidget->setCursor(Qt::PointingHandCursor);
+
+ m_videoWidget->installEventFilter(this);
+ m_player->setVideoOutput(m_videoWidget);
+ m_topLayout->insertWidget(0, m_videoWidget);
+
+ applyVideoSize();
+
+ connect(m_player, &QMediaPlayer::playbackStateChanged, this, &MediaWidget::onStateChanged);
+ connect(m_player, &QMediaPlayer::positionChanged, this, &MediaWidget::onPositionChanged);
+ connect(m_player, &QMediaPlayer::durationChanged, this, &MediaWidget::onDurationChanged);
+ }
+
+ if (m_url != m_player->source()) {
+ m_player->setSource(m_url);
+ m_seekSlider->setSliderPosition(0);
+ }
+
+ Q_EMIT hasVideoChanged(m_isVideo);
+
+ m_videoWidget->setVisible(m_isVideo);
+}
+
+void MediaWidget::play()
+{
+ initPlayer();
+
+ m_player->play();
+}
+
+void MediaWidget::finished()
+{
+ if (m_isVideo) {
+ m_videoWidget->hide();
+ Q_EMIT hasVideoChanged(false);
+ }
+}
+
+QMediaPlayer::PlaybackState MediaWidget::state() const
+{
+ return m_player == nullptr ? QMediaPlayer::PlaybackState::StoppedState : m_player->playbackState();
+}
+
+void MediaWidget::stop()
+{
+ if (m_player) {
+ m_player->stop();
+ m_videoWidget->hide();
+ Q_EMIT hasVideoChanged(false);
+ }
+}
+
+void MediaWidget::applyVideoSize()
+{
+ if ((m_videoWidget) && m_videoSize.isValid()) {
+ m_videoWidget->setSizeHint(m_videoSize);
+ }
+}
+
+void MediaWidget::setPosition(qint64 position)
+{
+ if (!m_player || m_player->playbackState() == QMediaPlayer::StoppedState) {
+ initPlayer();
+
+ auto prevDuration = m_seekSlider->maximum();
+
+ connect(
+ m_player,
+ &QMediaPlayer::mediaStatusChanged,
+ this,
+ [prevDuration, position, this](QMediaPlayer::MediaStatus status) {
+ if (status == QMediaPlayer::BufferedMedia) {
+ m_player->setPosition(float(position) / prevDuration * m_player->duration());
+ m_player->pause();
+ }
+ },
+ Qt::SingleShotConnection);
+
+ m_player->play();
+ } else {
+ m_player->setPosition(position);
+ }
+}
+
+void MediaWidget::onPositionChanged(qint64 position)
+{
+ m_seekSlider->setValue(static_cast<int>(position));
+}
+
+void MediaWidget::onDurationChanged(qint64 duration)
+{
+ m_seekSlider->setMaximum(static_cast<int>(duration));
+}
+
+#include "mediawidget.moc"
+#include "moc_mediawidget.cpp"
diff --git a/src/panels/information/phononwidget.h b/src/panels/information/mediawidget.h
index a0a913b4f..bd04266e6 100644
--- a/src/panels/information/phononwidget.h
+++ b/src/panels/information/mediawidget.h
@@ -4,34 +4,30 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
-#ifndef PHONONWIDGET_H
-#define PHONONWIDGET_H
-
-#include <phonon/Global>
+#ifndef MEDIAWIDGET_H
+#define MEDIAWIDGET_H
#include <QSize>
+#include <QSlider>
#include <QUrl>
#include <QWidget>
-namespace Phonon
-{
-class AudioOutput;
-class MediaObject;
+#include <QMediaPlayer>
+
+class QMediaPlayer;
class SeekSlider;
-class VideoPlayer;
-} // namespace Phonon
class EmbeddedVideoPlayer;
class QToolButton;
class QVBoxLayout;
-class PhononWidget : public QWidget
+class MediaWidget : public QWidget
{
Q_OBJECT
public:
enum MediaKind { Video, Audio };
- explicit PhononWidget(QWidget *parent = nullptr);
+ explicit MediaWidget(QWidget *parent = nullptr);
void setUrl(const QUrl &url, MediaKind kind);
QUrl url() const;
@@ -39,7 +35,7 @@ public:
void setVideoSize(const QSize &size);
QSize videoSize() const;
- Phonon::State state() const;
+ QMediaPlayer::PlaybackState state() const;
void setAutoPlay(bool autoPlay);
bool eventFilter(QObject *object, QEvent *event) override;
@@ -63,15 +59,17 @@ protected:
void hideEvent(QHideEvent *event) override;
private Q_SLOTS:
- void stateChanged(Phonon::State newstate);
void stop();
void finished();
+ void setPosition(qint64 position);
+ void onStateChanged(QMediaPlayer::PlaybackState newState);
+ void onPositionChanged(qint64 position);
+ void onDurationChanged(qint64 position);
private:
void applyVideoSize();
-
-private:
void togglePlayback();
+ void initPlayer();
QUrl m_url;
QSize m_videoSize;
@@ -80,12 +78,11 @@ private:
QToolButton *m_pauseButton;
QVBoxLayout *m_topLayout;
- Phonon::MediaObject *m_media;
- Phonon::SeekSlider *m_seekSlider;
- Phonon::AudioOutput *m_audioOutput;
- EmbeddedVideoPlayer *m_videoPlayer;
+ QMediaPlayer *m_player;
+ QSlider *m_seekSlider;
+ EmbeddedVideoPlayer *m_videoWidget;
bool m_autoPlay;
bool m_isVideo;
};
-#endif // PHONONWIDGET_H
+#endif // MEDIAWIDGET_H
diff --git a/src/panels/information/phononwidget.cpp b/src/panels/information/phononwidget.cpp
deleted file mode 100644
index 3365998f4..000000000
--- a/src/panels/information/phononwidget.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- SPDX-FileCopyrightText: 2007 Matthias Kretz <[email protected]>
-
- SPDX-License-Identifier: GPL-2.0-or-later
-*/
-
-#include "phononwidget.h"
-
-#include <KLocalizedString>
-#include <phonon/AudioOutput>
-#include <phonon/MediaObject>
-#include <phonon/SeekSlider>
-#include <phonon/VideoWidget>
-
-#include <QShowEvent>
-#include <QStyle>
-#include <QToolButton>
-#include <QVBoxLayout>
-
-class EmbeddedVideoPlayer : public Phonon::VideoWidget
-{
- Q_OBJECT
-
-public:
- EmbeddedVideoPlayer(QWidget *parent = nullptr)
- : Phonon::VideoWidget(parent)
- {
- }
-
- void setSizeHint(const QSize &size)
- {
- m_sizeHint = size;
- updateGeometry();
- }
-
- QSize sizeHint() const override
- {
- return m_sizeHint.isValid() ? m_sizeHint : Phonon::VideoWidget::sizeHint();
- }
-
-private:
- QSize m_sizeHint;
-};
-
-PhononWidget::PhononWidget(QWidget *parent)
- : QWidget(parent)
- , m_url()
- , m_playButton(nullptr)
- , m_pauseButton(nullptr)
- , m_topLayout(nullptr)
- , m_media(nullptr)
- , m_seekSlider(nullptr)
- , m_audioOutput(nullptr)
- , m_videoPlayer(nullptr)
-{
-}
-
-void PhononWidget::setUrl(const QUrl &url, MediaKind kind)
-{
- if (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();
- }
-}
-
-QUrl PhononWidget::url() const
-{
- return m_url;
-}
-
-void PhononWidget::clearUrl()
-{
- m_url.clear();
-}
-
-void PhononWidget::togglePlayback()
-{
- if (m_media && m_media->state() == Phonon::State::PlayingState) {
- m_media->pause();
- } else {
- play();
- }
-}
-
-bool PhononWidget::eventFilter(QObject *object, QEvent *event)
-{
- Q_UNUSED(object)
- if (event->type() == QEvent::MouseButtonPress) {
- const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- if (mouseEvent->button() == Qt::LeftButton) {
- // toggle playback
- togglePlayback();
- return true;
- }
- }
- return false;
-}
-
-void PhononWidget::setVideoSize(const QSize &size)
-{
- if (m_videoSize != size) {
- m_videoSize = size;
- applyVideoSize();
- }
-}
-
-QSize PhononWidget::videoSize() const
-{
- return m_videoSize;
-}
-
-void PhononWidget::showEvent(QShowEvent *event)
-{
- if (event->spontaneous()) {
- QWidget::showEvent(event);
- return;
- }
-
- if (!m_topLayout) {
- m_topLayout = new QVBoxLayout(this);
- m_topLayout->setContentsMargins(0, 0, 0, 0);
-
- QHBoxLayout *controlsLayout = new QHBoxLayout();
- controlsLayout->setContentsMargins(0, 0, 0, 0);
- controlsLayout->setSpacing(0);
-
- m_playButton = new QToolButton(this);
- m_pauseButton = new QToolButton(this);
- m_seekSlider = new Phonon::SeekSlider(this);
-
- controlsLayout->addWidget(m_playButton);
- controlsLayout->addWidget(m_pauseButton);
- controlsLayout->addWidget(m_seekSlider);
-
- m_topLayout->addLayout(controlsLayout);
-
- const int smallIconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
- const QSize buttonSize(smallIconSize, smallIconSize);
-
- m_playButton->setToolTip(i18n("play"));
- m_playButton->setIconSize(buttonSize);
- m_playButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
- m_playButton->setAutoRaise(true);
- connect(m_playButton, &QToolButton::clicked, this, &PhononWidget::play);
-
- m_pauseButton->setToolTip(i18n("pause"));
- m_pauseButton->setIconSize(buttonSize);
- m_pauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
- m_pauseButton->setAutoRaise(true);
- m_pauseButton->hide();
- connect(m_pauseButton, &QToolButton::clicked, this, &PhononWidget::togglePlayback);
-
- m_seekSlider->setIconVisible(false);
-
- // Creating an audio player or video player instance might take up to
- // 2 seconds when doing it the first time. To prevent that the user
- // interface gets noticeable blocked, the creation is delayed until
- // the play button has been pressed (see PhononWidget::play()).
- }
-}
-
-void PhononWidget::hideEvent(QHideEvent *event)
-{
- QWidget::hideEvent(event);
- if (!event->spontaneous()) {
- stop();
- }
-}
-
-void PhononWidget::stateChanged(Phonon::State newstate)
-{
- setUpdatesEnabled(false);
- switch (newstate) {
- case Phonon::PlayingState:
- case Phonon::BufferingState:
- m_playButton->hide();
- m_pauseButton->show();
- break;
- default:
- m_pauseButton->hide();
- m_playButton->show();
- break;
- }
- setUpdatesEnabled(true);
-}
-
-void PhononWidget::play()
-{
- if (!m_media) {
- m_media = new Phonon::MediaObject(this);
- connect(m_media, &Phonon::MediaObject::stateChanged, this, &PhononWidget::stateChanged);
- connect(m_media, &Phonon::MediaObject::finished, this, &PhononWidget::finished);
- m_seekSlider->setMediaObject(m_media);
- }
-
- if (!m_videoPlayer) {
- m_videoPlayer = new EmbeddedVideoPlayer(this);
- m_videoPlayer->setCursor(Qt::PointingHandCursor);
- m_videoPlayer->installEventFilter(this);
- m_topLayout->insertWidget(0, m_videoPlayer);
- Phonon::createPath(m_media, m_videoPlayer);
- applyVideoSize();
- }
-
- if (!m_audioOutput) {
- m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
- Phonon::createPath(m_media, m_audioOutput);
- }
-
- if (m_isVideo) {
- Q_EMIT hasVideoChanged(true);
- }
-
- 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();
- Q_EMIT hasVideoChanged(false);
- }
-}
-
-Phonon::State PhononWidget::state() const
-{
- return m_media == nullptr ? Phonon::State::StoppedState : m_media->state();
-}
-
-void PhononWidget::stop()
-{
- if (m_media) {
- m_media->stop();
- m_videoPlayer->hide();
- Q_EMIT hasVideoChanged(false);
- }
-}
-
-void PhononWidget::applyVideoSize()
-{
- if ((m_videoPlayer) && m_videoSize.isValid()) {
- m_videoPlayer->setSizeHint(m_videoSize);
- }
-}
-
-#include "moc_phononwidget.cpp"
-#include "phononwidget.moc"