1/* This file is part of the KDE project
2 Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), Nokia Corporation
10 (or its successors, if any) and the KDE Free Qt Foundation, which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library. If not, see <http://www.gnu.org/licenses/>.
20
21*/
22
23#include "seekslider.h"
24#include "seekslider_p.h"
25#include "mediaobject.h"
26#include "phonondefs_p.h"
27
28#include <QMouseEvent>
29#include <QApplication>
30
31#ifndef QT_NO_PHONON_SEEKSLIDER
32
33namespace Phonon
34{
35
36SeekSlider::SeekSlider(QWidget *parent)
37 : QWidget(parent)
38 , k_ptr(new SeekSliderPrivate(this))
39{
40 P_D(SeekSlider);
41 connect(asender: &d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int)));
42}
43
44SeekSlider::SeekSlider(MediaObject *mo, QWidget *parent)
45 : QWidget(parent)
46 , k_ptr(new SeekSliderPrivate(this))
47{
48 P_D(SeekSlider);
49 connect(asender: &d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int)));
50 setMediaObject(mo);
51}
52
53/*SeekSlider::SeekSlider(SeekSliderPrivate &_d, QWidget *parent)
54 : QWidget(parent)
55 , k_ptr(&_d)
56{
57} */
58
59SeekSlider::~SeekSlider()
60{
61 delete k_ptr;
62}
63
64void SeekSlider::setMediaObject(MediaObject *media)
65{
66 P_D(SeekSlider);
67 if (d->media) {
68 disconnect(sender: d->media, signal: nullptr, receiver: this, member: nullptr);
69 }
70 d->media = media;
71
72 if (media) {
73 connect(asender: media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
74 SLOT(_k_stateChanged(Phonon::State)));
75 connect(asender: media, SIGNAL(totalTimeChanged(qint64)), SLOT(_k_length(qint64)));
76 connect(asender: media, SIGNAL(tick(qint64)), SLOT(_k_tick(qint64)));
77 connect(asender: media, SIGNAL(seekableChanged(bool)), SLOT(_k_seekableChanged(bool)));
78 connect(asender: media, SIGNAL(currentSourceChanged(Phonon::MediaSource)), SLOT(_k_currentSourceChanged()));
79 d->_k_stateChanged(media->state());
80 d->_k_seekableChanged(media->isSeekable());
81 d->_k_length(media->totalTime());
82 } else {
83 d->_k_stateChanged(Phonon::StoppedState);
84 d->_k_seekableChanged(false);
85 }
86}
87
88MediaObject *SeekSlider::mediaObject() const
89{
90 P_D(const SeekSlider);
91 return d->media;
92}
93
94void SeekSliderPrivate::_k_seek(int msec)
95{
96 if (!ticking && media) {
97 media->seek(time: msec);
98 }
99}
100
101void SeekSliderPrivate::_k_tick(qint64 msec)
102{
103 ticking = true;
104 slider.setValue(msec);
105 ticking = false;
106}
107
108void SeekSliderPrivate::_k_length(qint64 msec)
109{
110 ticking = true;
111 slider.setRange(min: 0, max: msec);
112 ticking = false;
113}
114
115void SeekSliderPrivate::_k_seekableChanged(bool isSeekable)
116{
117 if (!isSeekable || !media) {
118 setEnabled(false);
119 } else {
120 switch (media->state()) {
121 case Phonon::PlayingState:
122 if (media->tickInterval() == 0) {
123 // if the tick signal is not enabled the slider is useless
124 // set the tickInterval to some common value
125 media->setTickInterval(350);
126 }
127 break;
128 case Phonon::BufferingState:
129 case Phonon::PausedState:
130 setEnabled(true);
131 break;
132 case Phonon::StoppedState:
133 case Phonon::LoadingState:
134 case Phonon::ErrorState:
135 setEnabled(false);
136 ticking = true;
137 slider.setValue(0);
138 ticking = false;
139 break;
140 }
141 }
142}
143
144void SeekSliderPrivate::_k_currentSourceChanged()
145{
146 //this releases the mouse and makes the seek slider stop seeking if the current source has changed
147 QMouseEvent event(QEvent::MouseButtonRelease, QPoint(), Qt::LeftButton, {}, {});
148 QApplication::sendEvent(receiver: &slider, event: &event);
149}
150
151void SeekSliderPrivate::setEnabled(bool x)
152{
153 slider.setEnabled(x);
154 iconLabel.setPixmap(icon.pixmap(size: iconSize, mode: x ? QIcon::Normal : QIcon::Disabled));
155}
156
157void SeekSliderPrivate::_k_stateChanged(State newstate)
158{
159 if (!media || !media->isSeekable()) {
160 setEnabled(false);
161 return;
162 }
163 switch (newstate) {
164 case Phonon::PlayingState:
165 if (media->tickInterval() == 0) {
166 // if the tick signal is not enabled the slider is useless
167 // set the tickInterval to some common value
168 media->setTickInterval(350);
169 }
170 break;
171 case Phonon::BufferingState:
172 case Phonon::PausedState:
173 setEnabled(true);
174 break;
175 case Phonon::StoppedState:
176 case Phonon::LoadingState:
177 case Phonon::ErrorState:
178 setEnabled(false);
179 ticking = true;
180 slider.setValue(0);
181 ticking = false;
182 break;
183 }
184}
185
186bool SeekSlider::hasTracking() const
187{
188 return k_ptr->slider.hasTracking();
189}
190
191void SeekSlider::setTracking(bool tracking)
192{
193 k_ptr->slider.setTracking(tracking);
194}
195
196int SeekSlider::pageStep() const
197{
198 return k_ptr->slider.pageStep();
199}
200
201void SeekSlider::setPageStep(int milliseconds)
202{
203 k_ptr->slider.setPageStep(milliseconds);
204}
205
206int SeekSlider::singleStep() const
207{
208 return k_ptr->slider.singleStep();
209}
210
211void SeekSlider::setSingleStep(int milliseconds)
212{
213 k_ptr->slider.setSingleStep(milliseconds);
214}
215
216bool SeekSlider::isIconVisible() const
217{
218 P_D(const SeekSlider);
219 return d->iconLabel.isVisible();
220}
221
222void SeekSlider::setIconVisible(bool vis)
223{
224 P_D(SeekSlider);
225 d->iconLabel.setVisible(vis);
226}
227
228Qt::Orientation SeekSlider::orientation() const
229{
230 return k_ptr->slider.orientation();
231}
232
233void SeekSlider::setOrientation(Qt::Orientation o)
234{
235 P_D(SeekSlider);
236 Qt::Alignment align = (o == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter);
237 d->layout.setAlignment(w: &d->iconLabel, alignment: align);
238 d->layout.setAlignment(w: &d->slider, alignment: align);
239 d->layout.setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
240 d->slider.setOrientation(o);
241}
242
243QSize SeekSlider::iconSize() const
244{
245 return k_ptr->iconSize;
246}
247
248void SeekSlider::setIconSize(const QSize &iconSize)
249{
250 P_D(SeekSlider);
251 d->iconSize = iconSize;
252 d->iconLabel.setPixmap(d->icon.pixmap(size: d->iconSize, mode: d->slider.isEnabled() ? QIcon::Normal : QIcon::Disabled));
253}
254
255} // namespace Phonon
256
257#endif //QT_NO_PHONON_SEEKSLIDER
258
259#include "moc_seekslider.cpp"
260
261// vim: sw=4 ts=4
262

source code of phonon/phonon/seekslider.cpp