File indexing completed on 2024-04-21 04:43:19

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