]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/phononwidget.cpp
Merge branch 'release/20.08' into master
[dolphin.git] / src / panels / information / phononwidget.cpp
1 /*
2 SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "phononwidget.h"
8
9 #include <KLocalizedString>
10 #include <Phonon/AudioOutput>
11 #include <Phonon/MediaObject>
12 #include <Phonon/SeekSlider>
13 #include <Phonon/VideoWidget>
14
15 #include <QShowEvent>
16 #include <QStyle>
17 #include <QToolButton>
18 #include <QVBoxLayout>
19
20 class EmbeddedVideoPlayer : public Phonon::VideoWidget
21 {
22 Q_OBJECT
23
24 public:
25 EmbeddedVideoPlayer(QWidget *parent = nullptr) :
26 Phonon::VideoWidget(parent)
27 {
28 }
29
30 void setSizeHint(const QSize& size)
31 {
32 m_sizeHint = size;
33 updateGeometry();
34 }
35
36 QSize sizeHint() const override
37 {
38 return m_sizeHint.isValid() ? m_sizeHint : Phonon::VideoWidget::sizeHint();
39 }
40
41 private:
42 QSize m_sizeHint;
43 };
44
45 PhononWidget::PhononWidget(QWidget *parent)
46 : QWidget(parent),
47 m_url(),
48 m_playButton(nullptr),
49 m_pauseButton(nullptr),
50 m_topLayout(nullptr),
51 m_media(nullptr),
52 m_seekSlider(nullptr),
53 m_audioOutput(nullptr),
54 m_videoPlayer(nullptr)
55 {
56 }
57
58 void PhononWidget::setUrl(const QUrl &url, MediaKind kind)
59 {
60 if (m_url != url) {
61 m_url = url;
62 m_isVideo = kind == MediaKind::Video;
63 }
64 if (m_autoPlay) {
65 play();
66 } else {
67 stop();
68 }
69 }
70
71 void PhononWidget::setAutoPlay(bool autoPlay)
72 {
73 m_autoPlay = autoPlay;
74 if (!m_url.isEmpty() && (m_media == nullptr || m_media->state() != Phonon::State::PlayingState) && m_autoPlay && isVisible()) {
75 play();
76 }
77 }
78
79 QUrl PhononWidget::url() const
80 {
81 return m_url;
82 }
83
84 void PhononWidget::clearUrl()
85 {
86 m_url.clear();
87 }
88
89 void PhononWidget::togglePlayback()
90 {
91 if (m_media && m_media->state() == Phonon::State::PlayingState) {
92 m_media->pause();
93 } else {
94 play();
95 }
96 }
97
98 bool PhononWidget::eventFilter(QObject *object, QEvent *event)
99 {
100 Q_UNUSED(object)
101 if (event->type() == QEvent::MouseButtonPress) {
102 const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
103 if (mouseEvent->button() == Qt::LeftButton) {
104 // toggle playback
105 togglePlayback();
106 return true;
107 }
108 }
109 return false;
110 }
111
112 void PhononWidget::setVideoSize(const QSize& size)
113 {
114 if (m_videoSize != size) {
115 m_videoSize = size;
116 applyVideoSize();
117 }
118 }
119
120 QSize PhononWidget::videoSize() const
121 {
122 return m_videoSize;
123 }
124
125 void PhononWidget::showEvent(QShowEvent *event)
126 {
127 if (event->spontaneous()) {
128 QWidget::showEvent(event);
129 return;
130 }
131
132 if (!m_topLayout) {
133 m_topLayout = new QVBoxLayout(this);
134 m_topLayout->setContentsMargins(0, 0, 0, 0);
135
136 QHBoxLayout *controlsLayout = new QHBoxLayout();
137 controlsLayout->setContentsMargins(0, 0, 0, 0);
138 controlsLayout->setSpacing(0);
139
140 m_playButton = new QToolButton(this);
141 m_pauseButton = new QToolButton(this);
142 m_seekSlider = new Phonon::SeekSlider(this);
143
144 controlsLayout->addWidget(m_playButton);
145 controlsLayout->addWidget(m_pauseButton);
146 controlsLayout->addWidget(m_seekSlider);
147
148 m_topLayout->addLayout(controlsLayout);
149
150 const int smallIconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
151 const QSize buttonSize(smallIconSize, smallIconSize);
152
153 m_playButton->setToolTip(i18n("play"));
154 m_playButton->setIconSize(buttonSize);
155 m_playButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
156 m_playButton->setAutoRaise(true);
157 connect(m_playButton, &QToolButton::clicked, this, &PhononWidget::play);
158
159 m_pauseButton->setToolTip(i18n("pause"));
160 m_pauseButton->setIconSize(buttonSize);
161 m_pauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
162 m_pauseButton->setAutoRaise(true);
163 m_pauseButton->hide();
164 connect(m_pauseButton, &QToolButton::clicked, this, &PhononWidget::togglePlayback);
165
166 m_seekSlider->setIconVisible(false);
167
168 // Creating an audio player or video player instance might take up to
169 // 2 seconds when doing it the first time. To prevent that the user
170 // interface gets noticeable blocked, the creation is delayed until
171 // the play button has been pressed (see PhononWidget::play()).
172 }
173 }
174
175 void PhononWidget::hideEvent(QHideEvent *event)
176 {
177 QWidget::hideEvent(event);
178 if (!event->spontaneous()) {
179 stop();
180 }
181 }
182
183 void PhononWidget::stateChanged(Phonon::State newstate)
184 {
185 setUpdatesEnabled(false);
186 switch (newstate) {
187 case Phonon::PlayingState:
188 case Phonon::BufferingState:
189 m_playButton->hide();
190 m_pauseButton->show();
191 break;
192 default:
193 m_pauseButton->hide();
194 m_playButton->show();
195 break;
196 }
197 setUpdatesEnabled(true);
198 }
199
200 void PhononWidget::play()
201 {
202 if (!m_media) {
203 m_media = new Phonon::MediaObject(this);
204 connect(m_media, &Phonon::MediaObject::stateChanged,
205 this, &PhononWidget::stateChanged);
206 connect(m_media, &Phonon::MediaObject::finished,
207 this, &PhononWidget::finished);
208 m_seekSlider->setMediaObject(m_media);
209 }
210
211 if (!m_videoPlayer) {
212 m_videoPlayer = new EmbeddedVideoPlayer(this);
213 m_videoPlayer->setCursor(Qt::PointingHandCursor);
214 m_videoPlayer->installEventFilter(this);
215 m_topLayout->insertWidget(0, m_videoPlayer);
216 Phonon::createPath(m_media, m_videoPlayer);
217 applyVideoSize();
218 }
219
220 if (!m_audioOutput) {
221 m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
222 Phonon::createPath(m_media, m_audioOutput);
223 }
224
225 if (m_isVideo) {
226 emit hasVideoChanged(true);
227 }
228
229 if (m_url != m_media->currentSource().url()) {
230 m_media->setCurrentSource(m_url);
231 }
232 m_media->play();
233
234 m_videoPlayer->setVisible(m_isVideo);
235 }
236
237 void PhononWidget::finished()
238 {
239 if (m_isVideo) {
240 m_videoPlayer->hide();
241 emit hasVideoChanged(false);
242 }
243 }
244
245 Phonon::State PhononWidget::state() const
246 {
247 return m_media == nullptr ? Phonon::State::StoppedState : m_media->state();
248 }
249
250 void PhononWidget::stop()
251 {
252 if (m_media) {
253 m_media->stop();
254 m_videoPlayer->hide();
255 emit hasVideoChanged(false);
256 }
257 }
258
259 void PhononWidget::applyVideoSize()
260 {
261 if ((m_videoPlayer) && m_videoSize.isValid()) {
262 m_videoPlayer->setSizeHint(m_videoSize);
263 }
264 }
265
266 #include "phononwidget.moc"