22 #include "config-plasma.h"
26 #include <QGraphicsLinearLayout>
27 #include <QGraphicsSceneResizeEvent>
30 #include <kiconloader.h>
33 #include <kfiledialog.h>
35 #include <QFileDialog>
38 #include <phonon/videowidget.h>
39 #include <phonon/mediaobject.h>
40 #include <phonon/mediasource.h>
41 #include <phonon/audiooutput.h>
51 class VideoWidgetPrivate
54 VideoWidgetPrivate(VideoWidget *video)
57 forceControlsVisible(false),
60 shownControls(VideoWidget::NoControls),
79 void ticked(qint64 progress);
80 void totalTimeChanged(qint64 time);
81 void setPosition(
int newProgress);
82 void setVolume(
int value);
83 void volumeChanged(qreal value);
84 void showOpenFileDialog();
85 void openFile(
const QString &path);
86 void stateChanged(Phonon::State newState, Phonon::State oldState);
87 void animateControlWidget(
bool show);
88 void hideControlWidget();
89 void slidingCompleted();
90 bool spaceForControlsAvailable();
95 Phonon::VideoWidget *videoWidget;
96 Phonon::AudioOutput *audioOutput;
97 Phonon::MediaObject *media;
100 bool forceControlsVisible;
105 VideoWidget::Controls shownControls;
118 void VideoWidgetPrivate::playPause()
120 if (media->state() == Phonon::PlayingState) {
127 void VideoWidgetPrivate::ticked(qint64 newProgress)
130 progress->setValue(newProgress);
134 void VideoWidgetPrivate::totalTimeChanged(qint64 time)
138 progress->setRange(0, time);
142 void VideoWidgetPrivate::setPosition(
int progress)
145 media->seek(progress);
149 void VideoWidgetPrivate::setVolume(
int value)
151 audioOutput->setVolume(qreal(value)/100.0);
154 void VideoWidgetPrivate::volumeChanged(qreal value)
156 volume->setValue(value*100);
159 void VideoWidgetPrivate::showOpenFileDialog()
161 #ifndef PLASMA_NO_KIO
162 openFile(KFileDialog::getOpenFileName());
164 openFile(QFileDialog::getOpenFileName());
168 void VideoWidgetPrivate::openFile(
const QString &path)
170 media->setCurrentSource(Phonon::MediaSource(path));
174 void VideoWidgetPrivate::stateChanged(Phonon::State newState, Phonon::State oldState)
178 if (playPauseButton) {
179 if (newState == Phonon::PlayingState) {
180 playPauseButton->setIcon(
"media-playback-pause");
182 playPauseButton->setIcon(
"media-playback-start");
187 void VideoWidgetPrivate::animateControlWidget(
bool show)
189 if (!controlsWidget || controlsWidget->isVisible() == show) {
193 const int distance = controlsWidget->size().height();
194 if (!controlsWidget->isVisible()) {
195 controlsWidget->setPos(0, -distance);
196 controlsWidget->show();
200 q->setFlags(q->flags()|QGraphicsItem::ItemClipsChildrenToShape);
204 animation->setTargetWidget(controlsWidget);
206 q->connect(
animation, SIGNAL(finished()), q, SLOT(slidingCompleted()));
209 animation->setProperty(
"distance", distance);
210 animation->setProperty(
"direction", show? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
214 void VideoWidgetPrivate::hideControlWidget()
216 animateControlWidget(
false);
219 void VideoWidgetPrivate::slidingCompleted()
221 if (!controlsWidget) {
226 q->setFlags(q->flags()^QGraphicsItem::ItemClipsChildrenToShape);
228 if (controlsWidget->pos().y() < 0) {
229 controlsWidget->hide();
230 }
else if (!forceControlsVisible) {
231 hideTimer->start(3000);
235 bool VideoWidgetPrivate::spaceForControlsAvailable()
237 if (controlsWidget) {
238 QSize hint = controlsWidget->effectiveSizeHint(Qt::MinimumSize).toSize();
239 return (q->size().width() >= hint.width()) &&
240 (q->size().height() >= hint.height());
250 d(new VideoWidgetPrivate(this))
252 d->videoWidget =
new Phonon::VideoWidget;
253 d->audioOutput =
new Phonon::AudioOutput(
this);
254 d->media =
new Phonon::MediaObject(
this);
256 Phonon::createPath(d->media, d->videoWidget);
257 Phonon::createPath(d->media, d->audioOutput);
260 setWidget(d->videoWidget);
261 d->videoWidget->setWindowIcon(QIcon());
262 setAcceptHoverEvents(
true);
264 connect(d->media, SIGNAL(
tick(qint64)),
this, SIGNAL(
tick(qint64)));
280 return d->audioOutput;
286 if (url.startsWith(
'/')) {
287 fileUrl =
"file://" %
url;
292 if (fileUrl == d->media->currentSource().url().toString()) {
296 d->media->setCurrentSource(Phonon::MediaSource(fileUrl));
301 return d->media->currentSource().url().toString();
306 if (controls == d->shownControls) {
310 d->shownControls = controls;
314 QGraphicsLinearLayout *controlsLayout = 0;
315 if (controls !=
NoControls && d->controlsWidget == 0) {
318 controlsLayout =
new QGraphicsLinearLayout(
Qt::Horizontal, d->controlsWidget);
319 d->hideTimer =
new QTimer(
this);
320 connect(d->hideTimer, SIGNAL(timeout()),
this, SLOT(hideControlWidget()));
322 }
else if (d->controlsWidget != 0) {
323 d->controlsWidget->deleteLater();
324 d->hideTimer->deleteLater();
325 d->controlsWidget = 0;
328 disconnect(d->media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this, SLOT(stateChanged(Phonon::State,Phonon::State)));
329 disconnect(d->media, SIGNAL(
tick(qint64)),
this, SLOT(ticked(qint64)));
330 disconnect(d->media, SIGNAL(totalTimeChanged(qint64)),
this, SLOT(totalTimeChanged(qint64)));
331 disconnect(d->audioOutput, SIGNAL(volumeChanged(qreal)),
this, SLOT(volumeChanged(qreal)));
335 Q_ASSERT(controlsLayout);
338 while (controlsLayout->count() > 0) {
339 controlsLayout->removeAt(0);
343 if (!d->previousButton) {
344 d->previousButton =
new IconWidget(d->controlsWidget);
345 d->previousButton->setIcon(
"media-playback-start");
346 connect(d->playButton, SIGNAL(clicked()),
this, SLOT(PreviousRequested()));
348 controlsLayout->addItem(d->previousButton);
350 d->previousButton->deleteLater();
351 d->previousButton = 0;
355 if (!d->playButton) {
356 d->playButton =
new IconWidget(d->controlsWidget);
357 d->playButton->setIcon(
"media-playback-start");
358 connect(d->playButton, SIGNAL(clicked()),
this, SLOT(
play()));
360 controlsLayout->addItem(d->playButton);
362 d->playButton->deleteLater();
366 if (controls&
Pause) {
367 if (!d->pauseButton) {
368 d->pauseButton =
new IconWidget(d->controlsWidget);
369 d->pauseButton->setIcon(
"media-playback-pause");
370 connect(d->pauseButton, SIGNAL(clicked()),
this, SLOT(
pause()));
372 controlsLayout->addItem(d->pauseButton);
374 d->pauseButton->deleteLater();
379 if (!d->stopButton) {
380 d->stopButton =
new IconWidget(d->controlsWidget);
381 d->stopButton->setIcon(
"media-playback-stop");
382 connect(d->stopButton, SIGNAL(clicked()),
this, SLOT(
stop()));
384 controlsLayout->addItem(d->stopButton);
386 d->stopButton->deleteLater();
391 if (!d->playPauseButton) {
392 d->playPauseButton =
new IconWidget(d->controlsWidget);
393 d->playPauseButton->setIcon(
"media-playback-start");
394 connect(d->playPauseButton, SIGNAL(clicked()),
this, SLOT(playPause()));
396 controlsLayout->addItem(d->playPauseButton);
398 d->playPauseButton->deleteLater();
399 d->playPauseButton = 0;
403 if (!d->nextButton) {
404 d->nextButton =
new IconWidget(d->nextButton);
405 d->nextButton->setIcon(
"media-playback-start");
406 connect(d->nextButton, SIGNAL(clicked()),
this, SIGNAL(
nextRequested()));
408 controlsLayout->addItem(d->nextButton);
410 d->nextButton->deleteLater();
414 connect(d->media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this, SLOT(stateChanged(Phonon::State,Phonon::State)));
421 d->progress =
new Slider(d->controlsWidget);
422 d->progress->setMinimum(0);
423 d->progress->setMaximum(100);
425 controlsLayout->setStretchFactor(d->progress, 4);
426 d->progress->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
428 connect(d->media, SIGNAL(
tick(qint64)),
this, SLOT(ticked(qint64)));
429 connect(d->media, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64)));
430 connect(d->progress, SIGNAL(valueChanged(
int)),
this, SLOT(setPosition(
int)));
432 controlsLayout->addItem(d->progress);
434 d->progress->deleteLater();
441 d->volume =
new Slider(d->controlsWidget);
442 d->volume->setMinimum(0);
443 d->volume->setMaximum(100);
444 d->volume->setValue(100);
446 d->volume->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
448 connect(d->volume, SIGNAL(valueChanged(
int)), SLOT(setVolume(
int)));
449 connect(d->audioOutput, SIGNAL(volumeChanged(qreal)), SLOT(volumeChanged(qreal)));
451 controlsLayout->addItem(d->volume);
453 d->volume->deleteLater();
459 if (!d->openFileButton) {
460 d->openFileButton =
new IconWidget(d->controlsWidget);
461 d->openFileButton->setIcon(KIcon(
"document-open"));
462 connect(d->openFileButton, SIGNAL(clicked()),
this, SLOT(showOpenFileDialog()));
464 controlsLayout->addItem(d->openFileButton);
466 d->openFileButton->deleteLater();
467 d->openFileButton = 0;
470 controlsLayout->activate();
471 d->controlsWidget->setPos(0,-d->controlsWidget->size().height());
472 d->controlsWidget->resize(size().width(), d->controlsWidget->size().height());
473 d->controlsWidget->hide();
478 return d->shownControls;
483 if (d->media->state() == Phonon::PlayingState) {
492 if (d->media->state() == Phonon::PausedState) {
501 if (d->media->state() == Phonon::StoppedState) {
510 if (d->media->currentTime() == time) {
514 d->media->seek(time);
519 return d->media->currentTime();
524 return d->media->totalTime();
529 return d->media->remainingTime();
534 if (d->controlsWidget) {
535 d->forceControlsVisible = visible;
536 d->animateControlWidget(visible);
542 return d->controlsWidget != 0 && d->controlsWidget->isVisible();
547 d->media->setTickInterval(interval);
552 return d->media->tickInterval();
557 d->videoWidget->setStyleSheet(stylesheet);
562 return d->videoWidget->styleSheet();
567 return d->videoWidget;
573 QGraphicsProxyWidget::resizeEvent(event);
575 if (d->controlsWidget) {
576 QSize newControlsSize(event->newSize().width(), d->controlsWidget->size().height());
577 int newHeight =
event->newSize().height();
578 qreal leftMargin, topMargin, rightMargin, bottomMargin;
579 d->controlsWidget->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
581 if (newHeight/5 >= KIconLoader::SizeEnormous) {
582 newControlsSize.setHeight(KIconLoader::SizeEnormous+topMargin+bottomMargin);
583 }
else if (newHeight/5 >= KIconLoader::SizeHuge) {
584 newControlsSize.setHeight(KIconLoader::SizeHuge+topMargin+bottomMargin);
585 }
else if (newHeight/5 >= KIconLoader::SizeLarge) {
586 newControlsSize.setHeight(KIconLoader::SizeLarge+topMargin+bottomMargin);
587 }
else if (newHeight/5 >= KIconLoader::SizeMedium) {
588 newControlsSize.setHeight(KIconLoader::SizeMedium+topMargin+bottomMargin);
590 newControlsSize.setHeight(KIconLoader::SizeSmallMedium+topMargin+bottomMargin);
592 d->controlsWidget->resize(newControlsSize);
594 if (d->spaceForControlsAvailable()) {
595 d->animateControlWidget(
false);
604 if (d->controlsWidget &&
605 !d->forceControlsVisible &&
606 d->spaceForControlsAvailable()) {
607 d->animateControlWidget(
true);
615 if (d->controlsWidget && !d->forceControlsVisible) {
616 d->hideTimer->start(1000);
624 if (d->forceControlsVisible || !d->controlsWidget) {
628 d->hideTimer->start(3000);
630 if (!d->controlsWidget->isVisible() &&
631 d->spaceForControlsAvailable()) {
632 d->animateControlWidget(
true);
638 #include <videowidget.moc>
Abstract representation of a single animation.
The applet is constrained vertically, but can expand horizontally.
QScriptValue animation(const QString &anim)
Provides a plasma-themed QSlider.
static Plasma::Animation * create(Animator::Animation type, QObject *parent=0)
Factory to build new animation objects.
A widget that provides a simple frame.