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 <QtGui/QMouseEvent>
29#include <QtGui/QApplication>
30
31QT_BEGIN_NAMESPACE
32
33#ifndef QT_NO_PHONON_SEEKSLIDER
34
35namespace Phonon
36{
37
38SeekSlider::SeekSlider(QWidget *parent)
39 : QWidget(parent)
40 , k_ptr(new SeekSliderPrivate(this))
41{
42 K_D(SeekSlider);
43 connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int)));
44}
45
46SeekSlider::SeekSlider(MediaObject *mo, QWidget *parent)
47 : QWidget(parent)
48 , k_ptr(new SeekSliderPrivate(this))
49{
50 K_D(SeekSlider);
51 connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_seek(int)));
52 setMediaObject(mo);
53}
54
55/*SeekSlider::SeekSlider(SeekSliderPrivate &_d, QWidget *parent)
56 : QWidget(parent)
57 , k_ptr(&_d)
58{
59} */
60
61SeekSlider::~SeekSlider()
62{
63 delete k_ptr;
64}
65
66void SeekSlider::setMediaObject(MediaObject *media)
67{
68 K_D(SeekSlider);
69 if (d->media) {
70 disconnect(d->media, 0, this, 0);
71 }
72 d->media = media;
73
74 if (media) {
75 connect(media, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
76 SLOT(_k_stateChanged(Phonon::State)));
77 connect(media, SIGNAL(totalTimeChanged(qint64)), SLOT(_k_length(qint64)));
78 connect(media, SIGNAL(tick(qint64)), SLOT(_k_tick(qint64)));
79 connect(media, SIGNAL(seekableChanged(bool)), SLOT(_k_seekableChanged(bool)));
80 connect(media, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)), SLOT(_k_currentSourceChanged()));
81 d->_k_stateChanged(media->state());
82 d->_k_seekableChanged(media->isSeekable());
83 d->_k_length(media->totalTime());
84 } else {
85 d->_k_stateChanged(Phonon::StoppedState);
86 d->_k_seekableChanged(false);
87 }
88}
89
90MediaObject *SeekSlider::mediaObject() const
91{
92 K_D(const SeekSlider);
93 return d->media;
94}
95
96void SeekSliderPrivate::_k_seek(int msec)
97{
98 if (!ticking && media) {
99 media->seek(msec);
100 }
101}
102
103void SeekSliderPrivate::_k_tick(qint64 msec)
104{
105 ticking = true;
106 slider.setValue(msec);
107 ticking = false;
108}
109
110void SeekSliderPrivate::_k_length(qint64 msec)
111{
112 ticking = true;
113 slider.setRange(0, msec);
114 ticking = false;
115}
116
117void SeekSliderPrivate::_k_seekableChanged(bool isSeekable)
118{
119 if (!isSeekable || !media) {
120 setEnabled(false);
121 } else {
122 switch (media->state()) {
123 case Phonon::PlayingState:
124 if (media->tickInterval() == 0) {
125 // if the tick signal is not enabled the slider is useless
126 // set the tickInterval to some common value
127 media->setTickInterval(350);
128 }
129 case Phonon::BufferingState:
130 case Phonon::PausedState:
131 setEnabled(true);
132 break;
133 case Phonon::StoppedState:
134 case Phonon::LoadingState:
135 case Phonon::ErrorState:
136 setEnabled(false);
137 ticking = true;
138 slider.setValue(0);
139 ticking = false;
140 break;
141 }
142 }
143}
144
145void SeekSliderPrivate::_k_currentSourceChanged()
146{
147 //this releases the mouse and makes the seek slider stop seeking if the current source has changed
148 QMouseEvent event(QEvent::MouseButtonRelease, QPoint(), Qt::LeftButton, 0, 0);
149 QApplication::sendEvent(&slider, &event);
150}
151
152void SeekSliderPrivate::setEnabled(bool x)
153{
154 slider.setEnabled(x);
155 iconLabel.setPixmap(icon.pixmap(iconSize, x ? QIcon::Normal : QIcon::Disabled));
156}
157
158void SeekSliderPrivate::_k_stateChanged(State newstate)
159{
160 if (!media || !media->isSeekable()) {
161 setEnabled(false);
162 return;
163 }
164 switch (newstate) {
165 case Phonon::PlayingState:
166 if (media->tickInterval() == 0) {
167 // if the tick signal is not enabled the slider is useless
168 // set the tickInterval to some common value
169 media->setTickInterval(350);
170 }
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 K_D(const SeekSlider);
219 return d->iconLabel.isVisible();
220}
221
222void SeekSlider::setIconVisible(bool vis)
223{
224 K_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 K_D(SeekSlider);
236 Qt::Alignment align = (o == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter);
237 d->layout.setAlignment(&d->iconLabel, align);
238 d->layout.setAlignment(&d->slider, 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 K_D(SeekSlider);
251 d->iconSize = iconSize;
252 d->iconLabel.setPixmap(d->icon.pixmap(d->iconSize, d->slider.isEnabled() ? QIcon::Normal : QIcon::Disabled));
253}
254
255} // namespace Phonon
256
257#endif //QT_NO_PHONON_SEEKSLIDER
258
259QT_END_NAMESPACE
260
261#include "moc_seekslider.cpp"
262
263// vim: sw=4 ts=4
264