File indexing completed on 2025-02-09 05:31:53
0001 /* This file is part of the KDE project 0002 Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Lesser General Public 0006 License as published by the Free Software Foundation; either 0007 version 2.1 of the License, or (at your option) version 3, or any 0008 later version accepted by the membership of KDE e.V. (or its 0009 successor approved by the membership of KDE e.V.), Nokia Corporation 0010 (or its successors, if any) and the KDE Free Qt Foundation, which shall 0011 act as a proxy defined in Section 6 of version 3 of the license. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Lesser General Public License for more details. 0017 0018 You should have received a copy of the GNU Lesser General Public 0019 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0020 0021 */ 0022 0023 #include "seekslider.h" 0024 #include "seekslider_p.h" 0025 #include "mediaobject.h" 0026 #include "phonondefs_p.h" 0027 0028 #include <QMouseEvent> 0029 #include <QApplication> 0030 0031 #ifndef QT_NO_PHONON_SEEKSLIDER 0032 0033 namespace Phonon 0034 { 0035 0036 SeekSlider::SeekSlider(QWidget *parent) 0037 : QWidget(parent) 0038 , k_ptr(new SeekSliderPrivate(this)) 0039 { 0040 P_D(SeekSlider); 0041 connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int))); 0042 } 0043 0044 SeekSlider::SeekSlider(MediaObject *mo, QWidget *parent) 0045 : QWidget(parent) 0046 , k_ptr(new SeekSliderPrivate(this)) 0047 { 0048 P_D(SeekSlider); 0049 connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int))); 0050 setMediaObject(mo); 0051 } 0052 0053 /*SeekSlider::SeekSlider(SeekSliderPrivate &_d, QWidget *parent) 0054 : QWidget(parent) 0055 , k_ptr(&_d) 0056 { 0057 } */ 0058 0059 SeekSlider::~SeekSlider() 0060 { 0061 delete k_ptr; 0062 } 0063 0064 void SeekSlider::setMediaObject(MediaObject *media) 0065 { 0066 P_D(SeekSlider); 0067 if (d->media) { 0068 disconnect(d->media, nullptr, this, nullptr); 0069 } 0070 d->media = media; 0071 0072 if (media) { 0073 connect(media, SIGNAL(stateChanged(Phonon::State,Phonon::State)), 0074 SLOT(_k_stateChanged(Phonon::State))); 0075 connect(media, SIGNAL(totalTimeChanged(qint64)), SLOT(_k_length(qint64))); 0076 connect(media, SIGNAL(tick(qint64)), SLOT(_k_tick(qint64))); 0077 connect(media, SIGNAL(seekableChanged(bool)), SLOT(_k_seekableChanged(bool))); 0078 connect(media, SIGNAL(currentSourceChanged(Phonon::MediaSource)), SLOT(_k_currentSourceChanged())); 0079 d->_k_stateChanged(media->state()); 0080 d->_k_seekableChanged(media->isSeekable()); 0081 d->_k_length(media->totalTime()); 0082 } else { 0083 d->_k_stateChanged(Phonon::StoppedState); 0084 d->_k_seekableChanged(false); 0085 } 0086 } 0087 0088 MediaObject *SeekSlider::mediaObject() const 0089 { 0090 P_D(const SeekSlider); 0091 return d->media; 0092 } 0093 0094 void SeekSliderPrivate::_k_seek(int msec) 0095 { 0096 if (!ticking && media) { 0097 media->seek(msec); 0098 } 0099 } 0100 0101 void SeekSliderPrivate::_k_tick(qint64 msec) 0102 { 0103 ticking = true; 0104 slider.setValue(msec); 0105 ticking = false; 0106 } 0107 0108 void SeekSliderPrivate::_k_length(qint64 msec) 0109 { 0110 ticking = true; 0111 slider.setRange(0, msec); 0112 ticking = false; 0113 } 0114 0115 void SeekSliderPrivate::_k_seekableChanged(bool isSeekable) 0116 { 0117 if (!isSeekable || !media) { 0118 setEnabled(false); 0119 } else { 0120 switch (media->state()) { 0121 case Phonon::PlayingState: 0122 if (media->tickInterval() == 0) { 0123 // if the tick signal is not enabled the slider is useless 0124 // set the tickInterval to some common value 0125 media->setTickInterval(350); 0126 } 0127 break; 0128 case Phonon::BufferingState: 0129 case Phonon::PausedState: 0130 setEnabled(true); 0131 break; 0132 case Phonon::StoppedState: 0133 case Phonon::LoadingState: 0134 case Phonon::ErrorState: 0135 setEnabled(false); 0136 ticking = true; 0137 slider.setValue(0); 0138 ticking = false; 0139 break; 0140 } 0141 } 0142 } 0143 0144 void SeekSliderPrivate::_k_currentSourceChanged() 0145 { 0146 //this releases the mouse and makes the seek slider stop seeking if the current source has changed 0147 QMouseEvent event(QEvent::MouseButtonRelease, QPoint(), Qt::LeftButton, {}, {}); 0148 QApplication::sendEvent(&slider, &event); 0149 } 0150 0151 void SeekSliderPrivate::setEnabled(bool x) 0152 { 0153 slider.setEnabled(x); 0154 iconLabel.setPixmap(icon.pixmap(iconSize, x ? QIcon::Normal : QIcon::Disabled)); 0155 } 0156 0157 void SeekSliderPrivate::_k_stateChanged(State newstate) 0158 { 0159 if (!media || !media->isSeekable()) { 0160 setEnabled(false); 0161 return; 0162 } 0163 switch (newstate) { 0164 case Phonon::PlayingState: 0165 if (media->tickInterval() == 0) { 0166 // if the tick signal is not enabled the slider is useless 0167 // set the tickInterval to some common value 0168 media->setTickInterval(350); 0169 } 0170 break; 0171 case Phonon::BufferingState: 0172 case Phonon::PausedState: 0173 setEnabled(true); 0174 break; 0175 case Phonon::StoppedState: 0176 case Phonon::LoadingState: 0177 case Phonon::ErrorState: 0178 setEnabled(false); 0179 ticking = true; 0180 slider.setValue(0); 0181 ticking = false; 0182 break; 0183 } 0184 } 0185 0186 bool SeekSlider::hasTracking() const 0187 { 0188 return k_ptr->slider.hasTracking(); 0189 } 0190 0191 void SeekSlider::setTracking(bool tracking) 0192 { 0193 k_ptr->slider.setTracking(tracking); 0194 } 0195 0196 int SeekSlider::pageStep() const 0197 { 0198 return k_ptr->slider.pageStep(); 0199 } 0200 0201 void SeekSlider::setPageStep(int milliseconds) 0202 { 0203 k_ptr->slider.setPageStep(milliseconds); 0204 } 0205 0206 int SeekSlider::singleStep() const 0207 { 0208 return k_ptr->slider.singleStep(); 0209 } 0210 0211 void SeekSlider::setSingleStep(int milliseconds) 0212 { 0213 k_ptr->slider.setSingleStep(milliseconds); 0214 } 0215 0216 bool SeekSlider::isIconVisible() const 0217 { 0218 P_D(const SeekSlider); 0219 return d->iconLabel.isVisible(); 0220 } 0221 0222 void SeekSlider::setIconVisible(bool vis) 0223 { 0224 P_D(SeekSlider); 0225 d->iconLabel.setVisible(vis); 0226 } 0227 0228 Qt::Orientation SeekSlider::orientation() const 0229 { 0230 return k_ptr->slider.orientation(); 0231 } 0232 0233 void SeekSlider::setOrientation(Qt::Orientation o) 0234 { 0235 P_D(SeekSlider); 0236 Qt::Alignment align = (o == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter); 0237 d->layout.setAlignment(&d->iconLabel, align); 0238 d->layout.setAlignment(&d->slider, align); 0239 d->layout.setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); 0240 d->slider.setOrientation(o); 0241 } 0242 0243 QSize SeekSlider::iconSize() const 0244 { 0245 return k_ptr->iconSize; 0246 } 0247 0248 void SeekSlider::setIconSize(const QSize &iconSize) 0249 { 0250 P_D(SeekSlider); 0251 d->iconSize = iconSize; 0252 d->iconLabel.setPixmap(d->icon.pixmap(d->iconSize, d->slider.isEnabled() ? QIcon::Normal : QIcon::Disabled)); 0253 } 0254 0255 } // namespace Phonon 0256 0257 #endif //QT_NO_PHONON_SEEKSLIDER 0258 0259 #include "moc_seekslider.cpp" 0260 0261 // vim: sw=4 ts=4