File indexing completed on 2024-05-19 05:48:21
0001 /* 0002 SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "phononwidget.h" 0008 0009 #include <KLocalizedString> 0010 #include <phonon/AudioOutput> 0011 #include <phonon/MediaObject> 0012 #include <phonon/SeekSlider> 0013 #include <phonon/VideoWidget> 0014 0015 #include <QShowEvent> 0016 #include <QStyle> 0017 #include <QToolButton> 0018 #include <QVBoxLayout> 0019 0020 class EmbeddedVideoPlayer : public Phonon::VideoWidget 0021 { 0022 Q_OBJECT 0023 0024 public: 0025 EmbeddedVideoPlayer(QWidget *parent = nullptr) 0026 : Phonon::VideoWidget(parent) 0027 { 0028 } 0029 0030 void setSizeHint(const QSize &size) 0031 { 0032 m_sizeHint = size; 0033 updateGeometry(); 0034 } 0035 0036 QSize sizeHint() const override 0037 { 0038 return m_sizeHint.isValid() ? m_sizeHint : Phonon::VideoWidget::sizeHint(); 0039 } 0040 0041 private: 0042 QSize m_sizeHint; 0043 }; 0044 0045 PhononWidget::PhononWidget(QWidget *parent) 0046 : QWidget(parent) 0047 , m_url() 0048 , m_playButton(nullptr) 0049 , m_pauseButton(nullptr) 0050 , m_topLayout(nullptr) 0051 , m_media(nullptr) 0052 , m_seekSlider(nullptr) 0053 , m_audioOutput(nullptr) 0054 , m_videoPlayer(nullptr) 0055 { 0056 } 0057 0058 void PhononWidget::setUrl(const QUrl &url, MediaKind kind) 0059 { 0060 if (m_url != url) { 0061 m_url = url; 0062 m_isVideo = kind == MediaKind::Video; 0063 } 0064 if (m_autoPlay) { 0065 play(); 0066 } else { 0067 stop(); 0068 } 0069 } 0070 0071 void PhononWidget::setAutoPlay(bool autoPlay) 0072 { 0073 m_autoPlay = autoPlay; 0074 if (!m_url.isEmpty() && (m_media == nullptr || m_media->state() != Phonon::State::PlayingState) && m_autoPlay && isVisible()) { 0075 play(); 0076 } 0077 } 0078 0079 QUrl PhononWidget::url() const 0080 { 0081 return m_url; 0082 } 0083 0084 void PhononWidget::clearUrl() 0085 { 0086 m_url.clear(); 0087 } 0088 0089 void PhononWidget::togglePlayback() 0090 { 0091 if (m_media && m_media->state() == Phonon::State::PlayingState) { 0092 m_media->pause(); 0093 } else { 0094 play(); 0095 } 0096 } 0097 0098 bool PhononWidget::eventFilter(QObject *object, QEvent *event) 0099 { 0100 Q_UNUSED(object) 0101 if (event->type() == QEvent::MouseButtonPress) { 0102 const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); 0103 if (mouseEvent->button() == Qt::LeftButton) { 0104 // toggle playback 0105 togglePlayback(); 0106 return true; 0107 } 0108 } 0109 return false; 0110 } 0111 0112 void PhononWidget::setVideoSize(const QSize &size) 0113 { 0114 if (m_videoSize != size) { 0115 m_videoSize = size; 0116 applyVideoSize(); 0117 } 0118 } 0119 0120 QSize PhononWidget::videoSize() const 0121 { 0122 return m_videoSize; 0123 } 0124 0125 void PhononWidget::showEvent(QShowEvent *event) 0126 { 0127 if (event->spontaneous()) { 0128 QWidget::showEvent(event); 0129 return; 0130 } 0131 0132 if (!m_topLayout) { 0133 m_topLayout = new QVBoxLayout(this); 0134 m_topLayout->setContentsMargins(0, 0, 0, 0); 0135 0136 QHBoxLayout *controlsLayout = new QHBoxLayout(); 0137 controlsLayout->setContentsMargins(0, 0, 0, 0); 0138 controlsLayout->setSpacing(0); 0139 0140 m_playButton = new QToolButton(this); 0141 m_pauseButton = new QToolButton(this); 0142 m_seekSlider = new Phonon::SeekSlider(this); 0143 0144 controlsLayout->addWidget(m_playButton); 0145 controlsLayout->addWidget(m_pauseButton); 0146 controlsLayout->addWidget(m_seekSlider); 0147 0148 m_topLayout->addLayout(controlsLayout); 0149 0150 const int smallIconSize = style()->pixelMetric(QStyle::PM_SmallIconSize); 0151 const QSize buttonSize(smallIconSize, smallIconSize); 0152 0153 m_playButton->setToolTip(i18n("play")); 0154 m_playButton->setIconSize(buttonSize); 0155 m_playButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); 0156 m_playButton->setAutoRaise(true); 0157 connect(m_playButton, &QToolButton::clicked, this, &PhononWidget::play); 0158 0159 m_pauseButton->setToolTip(i18n("pause")); 0160 m_pauseButton->setIconSize(buttonSize); 0161 m_pauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); 0162 m_pauseButton->setAutoRaise(true); 0163 m_pauseButton->hide(); 0164 connect(m_pauseButton, &QToolButton::clicked, this, &PhononWidget::togglePlayback); 0165 0166 m_seekSlider->setIconVisible(false); 0167 0168 // Creating an audio player or video player instance might take up to 0169 // 2 seconds when doing it the first time. To prevent that the user 0170 // interface gets noticeable blocked, the creation is delayed until 0171 // the play button has been pressed (see PhononWidget::play()). 0172 } 0173 } 0174 0175 void PhononWidget::hideEvent(QHideEvent *event) 0176 { 0177 QWidget::hideEvent(event); 0178 if (!event->spontaneous()) { 0179 stop(); 0180 } 0181 } 0182 0183 void PhononWidget::stateChanged(Phonon::State newstate) 0184 { 0185 setUpdatesEnabled(false); 0186 switch (newstate) { 0187 case Phonon::PlayingState: 0188 case Phonon::BufferingState: 0189 m_playButton->hide(); 0190 m_pauseButton->show(); 0191 break; 0192 default: 0193 m_pauseButton->hide(); 0194 m_playButton->show(); 0195 break; 0196 } 0197 setUpdatesEnabled(true); 0198 } 0199 0200 void PhononWidget::play() 0201 { 0202 if (!m_media) { 0203 m_media = new Phonon::MediaObject(this); 0204 connect(m_media, &Phonon::MediaObject::stateChanged, this, &PhononWidget::stateChanged); 0205 connect(m_media, &Phonon::MediaObject::finished, this, &PhononWidget::finished); 0206 m_seekSlider->setMediaObject(m_media); 0207 } 0208 0209 if (!m_videoPlayer) { 0210 m_videoPlayer = new EmbeddedVideoPlayer(this); 0211 m_videoPlayer->setCursor(Qt::PointingHandCursor); 0212 m_videoPlayer->installEventFilter(this); 0213 m_topLayout->insertWidget(0, m_videoPlayer); 0214 Phonon::createPath(m_media, m_videoPlayer); 0215 applyVideoSize(); 0216 } 0217 0218 if (!m_audioOutput) { 0219 m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); 0220 Phonon::createPath(m_media, m_audioOutput); 0221 } 0222 0223 if (m_isVideo) { 0224 Q_EMIT hasVideoChanged(true); 0225 } 0226 0227 if (m_url != m_media->currentSource().url()) { 0228 m_media->setCurrentSource(m_url); 0229 } 0230 m_media->play(); 0231 0232 m_videoPlayer->setVisible(m_isVideo); 0233 } 0234 0235 void PhononWidget::finished() 0236 { 0237 if (m_isVideo) { 0238 m_videoPlayer->hide(); 0239 Q_EMIT hasVideoChanged(false); 0240 } 0241 } 0242 0243 Phonon::State PhononWidget::state() const 0244 { 0245 return m_media == nullptr ? Phonon::State::StoppedState : m_media->state(); 0246 } 0247 0248 void PhononWidget::stop() 0249 { 0250 if (m_media) { 0251 m_media->stop(); 0252 m_videoPlayer->hide(); 0253 Q_EMIT hasVideoChanged(false); 0254 } 0255 } 0256 0257 void PhononWidget::applyVideoSize() 0258 { 0259 if ((m_videoPlayer) && m_videoSize.isValid()) { 0260 m_videoPlayer->setSizeHint(m_videoSize); 0261 } 0262 } 0263 0264 #include "moc_phononwidget.cpp" 0265 #include "phononwidget.moc"