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 | |
31 | QT_BEGIN_NAMESPACE |
32 | |
33 | #ifndef QT_NO_PHONON_SEEKSLIDER |
34 | |
35 | namespace Phonon |
36 | { |
37 | |
38 | SeekSlider::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 | |
46 | SeekSlider::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 | |
61 | SeekSlider::~SeekSlider() |
62 | { |
63 | delete k_ptr; |
64 | } |
65 | |
66 | void 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 | |
90 | MediaObject *SeekSlider::mediaObject() const |
91 | { |
92 | K_D(const SeekSlider); |
93 | return d->media; |
94 | } |
95 | |
96 | void SeekSliderPrivate::_k_seek(int msec) |
97 | { |
98 | if (!ticking && media) { |
99 | media->seek(msec); |
100 | } |
101 | } |
102 | |
103 | void SeekSliderPrivate::_k_tick(qint64 msec) |
104 | { |
105 | ticking = true; |
106 | slider.setValue(msec); |
107 | ticking = false; |
108 | } |
109 | |
110 | void SeekSliderPrivate::_k_length(qint64 msec) |
111 | { |
112 | ticking = true; |
113 | slider.setRange(0, msec); |
114 | ticking = false; |
115 | } |
116 | |
117 | void 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 | |
145 | void 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 | |
152 | void SeekSliderPrivate::setEnabled(bool x) |
153 | { |
154 | slider.setEnabled(x); |
155 | iconLabel.setPixmap(icon.pixmap(iconSize, x ? QIcon::Normal : QIcon::Disabled)); |
156 | } |
157 | |
158 | void 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 | |
186 | bool SeekSlider::hasTracking() const |
187 | { |
188 | return k_ptr->slider.hasTracking(); |
189 | } |
190 | |
191 | void SeekSlider::setTracking(bool tracking) |
192 | { |
193 | k_ptr->slider.setTracking(tracking); |
194 | } |
195 | |
196 | int SeekSlider::pageStep() const |
197 | { |
198 | return k_ptr->slider.pageStep(); |
199 | } |
200 | |
201 | void SeekSlider::setPageStep(int milliseconds) |
202 | { |
203 | k_ptr->slider.setPageStep(milliseconds); |
204 | } |
205 | |
206 | int SeekSlider::singleStep() const |
207 | { |
208 | return k_ptr->slider.singleStep(); |
209 | } |
210 | |
211 | void SeekSlider::setSingleStep(int milliseconds) |
212 | { |
213 | k_ptr->slider.setSingleStep(milliseconds); |
214 | } |
215 | |
216 | bool SeekSlider::isIconVisible() const |
217 | { |
218 | K_D(const SeekSlider); |
219 | return d->iconLabel.isVisible(); |
220 | } |
221 | |
222 | void SeekSlider::setIconVisible(bool vis) |
223 | { |
224 | K_D(SeekSlider); |
225 | d->iconLabel.setVisible(vis); |
226 | } |
227 | |
228 | Qt::Orientation SeekSlider::orientation() const |
229 | { |
230 | return k_ptr->slider.orientation(); |
231 | } |
232 | |
233 | void 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 | |
243 | QSize SeekSlider::iconSize() const |
244 | { |
245 | return k_ptr->iconSize; |
246 | } |
247 | |
248 | void 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 | |
259 | QT_END_NAMESPACE |
260 | |
261 | #include "moc_seekslider.cpp" |
262 | |
263 | // vim: sw=4 ts=4 |
264 | |