]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/phononwidget.cpp
3365998f4845249dc13d2e6c6ccad1eb3621a991
[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, this, &PhononWidget::stateChanged);
205 connect(m_media, &Phonon::MediaObject::finished, this, &PhononWidget::finished);
206 m_seekSlider->setMediaObject(m_media);
207 }
208
209 if (!m_videoPlayer) {
210 m_videoPlayer = new EmbeddedVideoPlayer(this);
211 m_videoPlayer->setCursor(Qt::PointingHandCursor);
212 m_videoPlayer->installEventFilter(this);
213 m_topLayout->insertWidget(0, m_videoPlayer);
214 Phonon::createPath(m_media, m_videoPlayer);
215 applyVideoSize();
216 }
217
218 if (!m_audioOutput) {
219 m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
220 Phonon::createPath(m_media, m_audioOutput);
221 }
222
223 if (m_isVideo) {
224 Q_EMIT hasVideoChanged(true);
225 }
226
227 if (m_url != m_media->currentSource().url()) {
228 m_media->setCurrentSource(m_url);
229 }
230 m_media->play();
231
232 m_videoPlayer->setVisible(m_isVideo);
233 }
234
235 void PhononWidget::finished()
236 {
237 if (m_isVideo) {
238 m_videoPlayer->hide();
239 Q_EMIT hasVideoChanged(false);
240 }
241 }
242
243 Phonon::State PhononWidget::state() const
244 {
245 return m_media == nullptr ? Phonon::State::StoppedState : m_media->state();
246 }
247
248 void PhononWidget::stop()
249 {
250 if (m_media) {
251 m_media->stop();
252 m_videoPlayer->hide();
253 Q_EMIT hasVideoChanged(false);
254 }
255 }
256
257 void PhononWidget::applyVideoSize()
258 {
259 if ((m_videoPlayer) && m_videoSize.isValid()) {
260 m_videoPlayer->setSizeHint(m_videoSize);
261 }
262 }
263
264 #include "moc_phononwidget.cpp"
265 #include "phononwidget.moc"