22#include "config-plasma.h"
26#include <QGraphicsLinearLayout>
27#include <QGraphicsSceneResizeEvent>
30#include <kiconloader.h>
33#include <kfiledialog.h>
38#include <phonon/videowidget.h>
39#include <phonon/mediaobject.h>
40#include <phonon/mediasource.h>
41#include <phonon/audiooutput.h>
51class 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;
118void VideoWidgetPrivate::playPause()
120 if (media->state() == Phonon::PlayingState) {
127void VideoWidgetPrivate::ticked(qint64 newProgress)
130 progress->setValue(newProgress);
134void VideoWidgetPrivate::totalTimeChanged(qint64 time)
138 progress->setRange(0, time);
142void VideoWidgetPrivate::setPosition(
int progress)
145 media->seek(progress);
149void VideoWidgetPrivate::setVolume(
int value)
151 audioOutput->setVolume(qreal(value)/100.0);
154void VideoWidgetPrivate::volumeChanged(qreal value)
156 volume->setValue(value*100);
159void VideoWidgetPrivate::showOpenFileDialog()
162 openFile(KFileDialog::getOpenFileName());
164 openFile(QFileDialog::getOpenFileName());
168void VideoWidgetPrivate::openFile(
const QString &path)
170 media->setCurrentSource(Phonon::MediaSource(path));
174void 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");
187void 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);
205 animation->setProperty(
"movementDirection", Animation::MoveDown);
206 q->connect(animation, SIGNAL(finished()), q, SLOT(slidingCompleted()));
209 animation->setProperty(
"distance", distance);
210 animation->setProperty(
"direction", show? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
214void VideoWidgetPrivate::hideControlWidget()
216 animateControlWidget(
false);
219void 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);
235bool 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)));
268VideoWidget::~VideoWidget()
273Phonon::MediaObject *VideoWidget::mediaObject()
const
278Phonon::AudioOutput *VideoWidget::audioOutput()
const
280 return d->audioOutput;
283void VideoWidget::setUrl(
const QString &url)
286 if (
url.startsWith(
'/')) {
287 fileUrl =
"file://" %
url;
292 if (fileUrl == d->media->currentSource().url().toString()) {
296 d->media->setCurrentSource(Phonon::MediaSource(fileUrl));
299QString VideoWidget::url()
const
301 return d->media->currentSource().url().toString();
304void VideoWidget::setUsedControls(
const Controls controls)
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);
424 d->progress->setOrientation(Qt::Horizontal);
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);
445 d->volume->setOrientation(Qt::Horizontal);
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();
476VideoWidget::Controls VideoWidget::usedControls()
const
478 return d->shownControls;
481void VideoWidget::play()
483 if (d->media->state() == Phonon::PlayingState) {
490void VideoWidget::pause()
492 if (d->media->state() == Phonon::PausedState) {
499void VideoWidget::stop()
501 if (d->media->state() == Phonon::StoppedState) {
508void VideoWidget::seek(qint64 time)
510 if (d->media->currentTime() == time) {
514 d->media->seek(time);
517qint64 VideoWidget::currentTime()
const
519 return d->media->currentTime();
522qint64 VideoWidget::totalTime()
const
524 return d->media->totalTime();
527qint64 VideoWidget::remainingTime()
const
529 return d->media->remainingTime();
532void VideoWidget::setControlsVisible(
bool visible)
534 if (d->controlsWidget) {
535 d->forceControlsVisible = visible;
536 d->animateControlWidget(visible);
540bool VideoWidget::controlsVisible()
const
542 return d->controlsWidget != 0 && d->controlsWidget->isVisible();
545void VideoWidget::setTickInterval(qint64 interval)
547 d->media->setTickInterval(interval);
550qint64 VideoWidget::tickInterval()
const
552 return d->media->tickInterval();
555void VideoWidget::setStyleSheet(
const QString &stylesheet)
557 d->videoWidget->setStyleSheet(stylesheet);
560QString VideoWidget::styleSheet()
562 return d->videoWidget->styleSheet();
565Phonon::VideoWidget *VideoWidget::nativeWidget()
const
567 return d->videoWidget;
571void VideoWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
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);
600void VideoWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
604 if (d->controlsWidget &&
605 !d->forceControlsVisible &&
606 d->spaceForControlsAvailable()) {
607 d->animateControlWidget(
true);
611void VideoWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
615 if (d->controlsWidget && !d->forceControlsVisible) {
616 d->hideTimer->start(1000);
620void VideoWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
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.
static Plasma::Animation * create(Animator::Animation type, QObject *parent=0)
Factory to build new animation objects.
A widget that provides a simple frame.
Provides a plasma-themed QSlider.
QScriptValue animation(const QString &anim)
Namespace for everything in libplasma.