1 /* This file is part of the KDE project
2 Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "mediaobjectitem.h"
21 #include <QtCore/QTime>
22 #include <QtCore/QUrl>
23 #include <QtGui/QHBoxLayout>
24 #include <QtGui/QPushButton>
25 #include <QtGui/QVBoxLayout>
28 #include <kurlcompletion.h>
29 #include <kmessagebox.h>
31 #include <klineedit.h>
33 MediaObjectItem::MediaObjectItem()
40 QVBoxLayout
*topLayout
= new QVBoxLayout(this);
41 topLayout
->setMargin(0);
43 // as wide as possible:
44 KLineEdit
*file
= new KLineEdit(this);
45 file
->setCompletionObject(new KUrlCompletion(KUrlCompletion::FileCompletion
));
46 connect(file
, SIGNAL(returnPressed(const QString
&)), SLOT(loadUrl(const QString
&)));
47 topLayout
->addWidget(file
);
49 m_seekslider
= new SeekSlider(this);
50 topLayout
->addWidget(m_seekslider
);
52 // not much need for horizontal space:
53 QHBoxLayout
*subLayout
= new QHBoxLayout();
54 subLayout
->setMargin(0);
55 subLayout
->setSpacing(4);
56 topLayout
->addLayout(subLayout
);
58 QVBoxLayout
*mediaLayout
= new QVBoxLayout();
59 mediaLayout
->setMargin(0);
60 mediaLayout
->setSpacing(4);
61 subLayout
->addLayout(mediaLayout
);
63 QToolButton
*audiocdButton
= new QToolButton(this);
64 audiocdButton
->setIconSize(QSize(32, 32));
65 audiocdButton
->setToolTip("CD");
66 audiocdButton
->setIcon(KIcon("media-optical-audio"));
67 mediaLayout
->addWidget(audiocdButton
);
68 connect(audiocdButton
, SIGNAL(clicked()), SLOT(openCD()));
70 QToolButton
*dvdButton
= new QToolButton(this);
71 dvdButton
->setIconSize(QSize(32, 32));
72 dvdButton
->setToolTip("DVD");
73 dvdButton
->setIcon(KIcon("media-optical-dvd"));
74 mediaLayout
->addWidget(dvdButton
);
75 connect(dvdButton
, SIGNAL(clicked()), SLOT(openDVD()));
77 mediaLayout
->addStretch();
79 QVBoxLayout
*buttonLayout
= new QVBoxLayout();
80 buttonLayout
->setMargin(0);
81 buttonLayout
->setSpacing(4);
82 subLayout
->addLayout(buttonLayout
);
84 QHBoxLayout
*mediaControlsLayout
= new QHBoxLayout();
85 mediaControlsLayout
->setMargin(0);
86 mediaControlsLayout
->setSpacing(2);
87 buttonLayout
->addLayout(mediaControlsLayout
);
90 m_play
= new QToolButton(this);
91 m_play
->setIconSize(QSize(32, 32));
92 m_play
->setFixedSize(36, 36);
93 m_play
->setToolTip("play");
94 m_play
->setIcon(KIcon("media-playback-start"));
95 mediaControlsLayout
->addWidget(m_play
);
97 m_pause
= new QToolButton(this);
98 m_pause
->setIconSize(QSize(32, 32));
99 m_pause
->setFixedSize(36, 36);
100 m_pause
->setToolTip("pause");
101 m_pause
->setIcon(KIcon("media-playback-pause"));
102 mediaControlsLayout
->addWidget(m_pause
);
104 m_stop
= new QToolButton(this);
105 m_stop
->setIconSize(QSize(32, 32));
106 m_stop
->setFixedSize(36, 36);
107 m_stop
->setToolTip("stop");
108 m_stop
->setIcon(KIcon("media-playback-stop"));
109 mediaControlsLayout
->addWidget(m_stop
);
111 m_titleButton
= new QPushButton(this);
112 m_titleButton
->setText("Title");
113 m_titleButton
->setCheckable(true);
114 buttonLayout
->addWidget(m_titleButton
);
115 m_chapterButton
= new QPushButton(this);
116 m_chapterButton
->setText("Chapter");
117 m_chapterButton
->setCheckable(true);
118 buttonLayout
->addWidget(m_chapterButton
);
119 m_angleButton
= new QPushButton(this);
120 m_angleButton
->setText("Angle");
121 m_angleButton
->setCheckable(true);
122 buttonLayout
->addWidget(m_angleButton
);
123 m_navigationButton
= new QPushButton(this);
124 m_navigationButton
->setText("Navigation");
125 m_navigationButton
->setCheckable(true);
126 buttonLayout
->addWidget(m_navigationButton
);
127 connect(m_titleButton
, SIGNAL(toggled(bool)), SLOT(showTitleWidget(bool)));
128 connect(m_chapterButton
, SIGNAL(toggled(bool)), SLOT(showChapterWidget(bool)));
129 connect(m_angleButton
, SIGNAL(toggled(bool)), SLOT(showAngleWidget(bool)));
130 connect(m_navigationButton
, SIGNAL(toggled(bool)), SLOT(showNavigationWidget(bool)));
132 QVBoxLayout
*infoLayout
= new QVBoxLayout();
133 infoLayout
->setMargin(0);
134 infoLayout
->setSpacing(4);
135 subLayout
->addLayout(infoLayout
);
138 m_statelabel
= new QLabel(this);
139 infoLayout
->addWidget(m_statelabel
);
141 // buffer progressbar
142 m_bufferProgress
= new QProgressBar(this);
143 m_bufferProgress
->setMaximumSize(100, 16);
144 m_bufferProgress
->setTextVisible(false);
145 infoLayout
->addWidget(m_bufferProgress
);
148 m_totaltime
= new QLabel(this);
149 infoLayout
->addWidget(m_totaltime
);
151 m_currenttime
= new QLabel(this);
152 infoLayout
->addWidget(m_currenttime
);
154 m_remainingtime
= new QLabel(this);
155 infoLayout
->addWidget(m_remainingtime
);
156 infoLayout
->addStretch();
159 m_metaDataLabel
= new QLabel(this);
160 m_metaDataLabel
->setAlignment(Qt::AlignLeft
| Qt::AlignTop
);
161 m_metaDataLabel
->setWordWrap(true);
163 QFont f
= m_metaDataLabel
->font();
164 f
.setPointSizeF(f
.pointSizeF() * 0.85);
165 m_metaDataLabel
->setFont(f
);
167 subLayout
->addWidget(m_metaDataLabel
);
169 connect(&m_media
, SIGNAL(metaDataChanged()), SLOT(updateMetaData()));
170 m_seekslider
->setMediaObject(&m_media
);
171 m_media
.setTickInterval(100);
172 m_media
.setPrefinishMark(2000);
174 stateChanged(m_media
.state(), Phonon::LoadingState
);
175 length(m_media
.totalTime());
177 connect(m_pause
, SIGNAL(clicked()), &m_media
, SLOT(pause()));
178 connect(m_play
, SIGNAL(clicked()), &m_media
, SLOT(play()));
179 connect(m_stop
, SIGNAL(clicked()), &m_media
, SLOT(stop()));
181 connect(&m_media
, SIGNAL(stateChanged(Phonon::State
, Phonon::State
)),
182 SLOT(stateChanged(Phonon::State
, Phonon::State
)));
183 connect(&m_media
, SIGNAL(tick(qint64
)), SLOT(tick(qint64
)));
184 connect(&m_media
, SIGNAL(totalTimeChanged(qint64
)), SLOT(length(qint64
)));
185 connect(&m_media
, SIGNAL(finished()), SLOT(slotFinished()));
186 connect(&m_media
, SIGNAL(prefinishMarkReached(qint32
)), SLOT(slotPrefinishMarkReached(qint32
)));
187 connect(&m_media
, SIGNAL(bufferStatus(int)), m_bufferProgress
, SLOT(setValue(int)));
190 void MediaObjectItem::loadUrl(const QString
&url
)
192 m_media
.setCurrentSource(KUrl(url
));
195 void MediaObjectItem::updateMetaData()
198 const QMultiMap
<QString
, QString
> map
= m_media
.metaData();
199 const QStringList keys
= map
.keys();
200 foreach (const QString
&key
, keys
) {
201 metaData
+= key
+ QLatin1String(": ") + QStringList(map
.values(key
)).join(QLatin1String("\n")) + "\n";
203 m_metaDataLabel
->setText(metaData
.left(metaData
.length() - 1));
206 void MediaObjectItem::slotFinished()
208 kDebug() << "finished signal from MediaObject with URL " << m_media
.currentSource().url();
211 void MediaObjectItem::slotPrefinishMarkReached(qint32 remaining
)
213 kDebug() << "prefinishMarkReached(" << remaining
<< ") signal from MediaObject with URL " << m_media
.currentSource().url();
216 void MediaObjectItem::tick(qint64 t
)
220 m_currenttime
->setText(x
.toString("m:ss.zzz"));
221 x
.setHMS(0, 0, 0, 0);
222 qint64 r
= m_media
.remainingTime();
226 m_remainingtime
->setText(x
.toString("m:ss.zzz"));
229 void MediaObjectItem::stateChanged(Phonon::State newstate
, Phonon::State oldstate
)
234 case Phonon::ErrorState
:
235 m_statelabel
->setText("Error");
237 QString text
= m_media
.errorString();
238 if (text
.isEmpty()) {
239 KMessageBox::error(this, "reached error state but the backend did not report an errorString");
241 KMessageBox::error(this, text
);
245 case Phonon::LoadingState
:
246 m_statelabel
->setText("Loading");
248 case Phonon::StoppedState
:
249 m_statelabel
->setText("Stopped");
251 case Phonon::PausedState
:
252 m_statelabel
->setText("Paused");
254 case Phonon::BufferingState
:
255 m_statelabel
->setText("Buffering");
256 m_bufferProgress
->reset();
257 m_bufferProgress
->show();
259 case Phonon::PlayingState
:
260 m_statelabel
->setText("Playing");
265 void MediaObjectItem::length(qint64 ms
)
269 x
= x
.addMSecs(m_length
);
270 m_totaltime
->setText(x
.toString("m:ss.zzz"));
271 tick(m_media
.currentTime());
274 void MediaObjectItem::openCD()
276 m_media
.setCurrentSource(Phonon::Cd
);
279 void MediaObjectItem::openDVD()
281 m_media
.setCurrentSource(Phonon::Dvd
);
284 void MediaObjectItem::showTitleWidget(bool b
)
287 if (!m_titleWidget
) {
288 m_titleWidget
= new TitleWidget
;
289 connect(m_titleWidget
, SIGNAL(destroyed()), SLOT(updateIfaceButtons()));
291 if (!m_mediaController
) {
292 m_mediaController
= new MediaController(&m_media
);
294 if (m_mediaController
) {
295 m_titleWidget
->setInterface(m_mediaController
);
297 m_titleWidget
->show();
300 m_titleWidget
->hide();
305 void MediaObjectItem::showChapterWidget(bool b
)
308 if (!m_chapterWidget
) {
309 m_chapterWidget
= new ChapterWidget
;
310 connect(m_chapterWidget
, SIGNAL(destroyed()), SLOT(updateIfaceButtons()));
312 if (!m_mediaController
) {
313 m_mediaController
= new MediaController(&m_media
);
315 if (m_mediaController
) {
316 m_chapterWidget
->setInterface(m_mediaController
);
318 m_chapterWidget
->show();
320 if (m_chapterWidget
) {
321 m_chapterWidget
->hide();
326 void MediaObjectItem::showAngleWidget(bool b
)
329 if (!m_angleWidget
) {
330 m_angleWidget
= new AngleWidget
;
331 connect(m_angleWidget
, SIGNAL(destroyed()), SLOT(updateIfaceButtons()));
333 if (!m_mediaController
) {
334 m_mediaController
= new MediaController(&m_media
);
336 if (m_mediaController
) {
337 m_angleWidget
->setInterface(m_mediaController
);
339 m_angleWidget
->show();
342 m_angleWidget
->hide();
347 void MediaObjectItem::showNavigationWidget(bool b
)
350 if (!m_navigationWidget
) {
351 m_navigationWidget
= new NavigationWidget
;
352 connect(m_navigationWidget
, SIGNAL(destroyed()), SLOT(updateIfaceButtons()));
354 if (!m_mediaController
) {
355 m_mediaController
= new MediaController(&m_media
);
357 if (m_mediaController
) {
358 m_navigationWidget
->setInterface(m_mediaController
);
360 m_navigationWidget
->show();
362 if (m_navigationWidget
) {
363 m_navigationWidget
->hide();