]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/phononwidget.cpp
Allow dolphin to auto-play previewed media file, click on preview to play/pause video...
[dolphin.git] / src / panels / information / phononwidget.cpp
1 /* This file is part of the KDE project
2 Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of
7 the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18
19 */
20
21 #include "phononwidget.h"
22
23 #include <KIconLoader>
24 #include <KLocalizedString>
25 #include <Phonon/AudioOutput>
26 #include <Phonon/MediaObject>
27 #include <Phonon/SeekSlider>
28 #include <Phonon/VideoWidget>
29
30 #include <QShowEvent>
31 #include <QToolButton>
32 #include <QVBoxLayout>
33
34 class EmbeddedVideoPlayer : public Phonon::VideoWidget
35 {
36 Q_OBJECT
37
38 public:
39 EmbeddedVideoPlayer(QWidget *parent = nullptr) :
40 Phonon::VideoWidget(parent)
41 {
42 }
43
44 void setSizeHint(const QSize& size)
45 {
46 m_sizeHint = size;
47 updateGeometry();
48 }
49
50 QSize sizeHint() const override
51 {
52 return m_sizeHint.isValid() ? m_sizeHint : Phonon::VideoWidget::sizeHint();
53 }
54
55 private:
56 QSize m_sizeHint;
57 };
58
59 PhononWidget::PhononWidget(QWidget *parent)
60 : QWidget(parent),
61 m_url(),
62 m_playButton(nullptr),
63 m_stopButton(nullptr),
64 m_topLayout(nullptr),
65 m_media(nullptr),
66 m_seekSlider(nullptr),
67 m_audioOutput(nullptr),
68 m_videoPlayer(nullptr)
69 {
70 }
71
72 void PhononWidget::setUrl(const QUrl &url, MediaKind kind)
73 {
74 if (m_url != url) {
75 m_url = url;
76 m_isVideo = kind == MediaKind::Video;
77 }
78 if (m_autoPlay) {
79 play();
80 } else {
81 stop();
82 }
83 }
84
85 void PhononWidget::setAutoPlay(bool autoPlay)
86 {
87 m_autoPlay = autoPlay;
88 if (!m_url.isEmpty() && (m_media == nullptr || m_media->state() != Phonon::State::PlayingState) && m_autoPlay && isVisible()) {
89 play();
90 }
91 }
92
93 QUrl PhononWidget::url() const
94 {
95 return m_url;
96 }
97
98 void PhononWidget::setVideoSize(const QSize& size)
99 {
100 if (m_videoSize != size) {
101 m_videoSize = size;
102 applyVideoSize();
103 }
104 }
105
106 QSize PhononWidget::videoSize() const
107 {
108 return m_videoSize;
109 }
110
111 void PhononWidget::showEvent(QShowEvent *event)
112 {
113 if (event->spontaneous()) {
114 QWidget::showEvent(event);
115 return;
116 }
117
118 if (!m_topLayout) {
119 m_topLayout = new QVBoxLayout(this);
120 m_topLayout->setContentsMargins(0, 0, 0, 0);
121
122 QHBoxLayout *controlsLayout = new QHBoxLayout();
123 controlsLayout->setContentsMargins(0, 0, 0, 0);
124 controlsLayout->setSpacing(0);
125
126 m_playButton = new QToolButton(this);
127 m_stopButton = new QToolButton(this);
128 m_seekSlider = new Phonon::SeekSlider(this);
129
130 controlsLayout->addWidget(m_playButton);
131 controlsLayout->addWidget(m_stopButton);
132 controlsLayout->addWidget(m_seekSlider);
133
134 m_topLayout->addLayout(controlsLayout);
135
136 const int smallIconSize = IconSize(KIconLoader::Small);
137 const QSize buttonSize(smallIconSize, smallIconSize);
138
139 m_playButton->setToolTip(i18n("play"));
140 m_playButton->setIconSize(buttonSize);
141 m_playButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
142 m_playButton->setAutoRaise(true);
143 connect(m_playButton, &QToolButton::clicked, this, &PhononWidget::play);
144
145 m_stopButton->setToolTip(i18n("stop"));
146 m_stopButton->setIconSize(buttonSize);
147 m_stopButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop")));
148 m_stopButton->setAutoRaise(true);
149 m_stopButton->hide();
150 connect(m_stopButton, &QToolButton::clicked, this, &PhononWidget::stop);
151
152 m_seekSlider->setIconVisible(false);
153
154 // Creating an audio player or video player instance might take up to
155 // 2 seconds when doing it the first time. To prevent that the user
156 // interface gets noticeable blocked, the creation is delayed until
157 // the play button has been pressed (see PhononWidget::play()).
158 }
159 }
160
161 void PhononWidget::hideEvent(QHideEvent *event)
162 {
163 QWidget::hideEvent(event);
164 if (!event->spontaneous()) {
165 stop();
166 }
167 }
168
169 void PhononWidget::stateChanged(Phonon::State newstate)
170 {
171 setUpdatesEnabled(false);
172 switch (newstate) {
173 case Phonon::PlayingState:
174 case Phonon::BufferingState:
175 m_stopButton->show();
176 m_playButton->hide();
177 break;
178 default:
179 m_stopButton->hide();
180 m_playButton->show();
181 break;
182 }
183 setUpdatesEnabled(true);
184 }
185
186 void PhononWidget::play()
187 {
188 if (!m_media) {
189 m_media = new Phonon::MediaObject(this);
190 connect(m_media, &Phonon::MediaObject::stateChanged,
191 this, &PhononWidget::stateChanged);
192 connect(m_media, &Phonon::MediaObject::finished,
193 this, &PhononWidget::finished);
194 m_seekSlider->setMediaObject(m_media);
195 }
196
197 if (!m_videoPlayer) {
198 m_videoPlayer = new EmbeddedVideoPlayer(this);
199 m_videoPlayer->installEventFilter(this);
200 m_topLayout->insertWidget(0, m_videoPlayer);
201 Phonon::createPath(m_media, m_videoPlayer);
202 applyVideoSize();
203 }
204
205 if (!m_audioOutput) {
206 m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
207 Phonon::createPath(m_media, m_audioOutput);
208 }
209
210 if (m_isVideo) {
211 emit hasVideoChanged(true);
212 }
213
214 if (m_url != m_media->currentSource().url()) {
215 m_media->setCurrentSource(m_url);
216 }
217 m_media->play();
218
219 m_videoPlayer->setVisible(m_isVideo);
220 }
221
222 void PhononWidget::finished()
223 {
224 if (m_isVideo) {
225 m_videoPlayer->hide();
226 emit hasVideoChanged(false);
227 }
228 }
229
230 void PhononWidget::stop()
231 {
232 if (m_media) {
233 m_media->stop();
234 m_videoPlayer->hide();
235 emit hasVideoChanged(false);
236 }
237 }
238
239 void PhononWidget::applyVideoSize()
240 {
241 if ((m_videoPlayer) && m_videoSize.isValid()) {
242 m_videoPlayer->setSizeHint(m_videoSize);
243 }
244 }
245
246 #include "phononwidget.moc"