• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

videowidget.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2009 Marco Martin <notmart@gmail.com>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU Library General Public License as
00006  *   published by the Free Software Foundation; either version 2, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details
00013  *
00014  *   You should have received a copy of the GNU Library General Public
00015  *   License along with this program; if not, write to the
00016  *   Free Software Foundation, Inc.,
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 
00020 #include "videowidget.h"
00021 
00022 #include <QUrl>
00023 #include <QTimer>
00024 #include <QGraphicsLinearLayout>
00025 #include <QGraphicsSceneResizeEvent>
00026 
00027 #include <kicon.h>
00028 #include <kfiledialog.h>
00029 
00030 #include <phonon/videowidget.h>
00031 #include <phonon/mediaobject.h>
00032 #include <phonon/mediasource.h>
00033 #include <phonon/audiooutput.h>
00034 
00035 #include <plasma/widgets/iconwidget.h>
00036 #include <plasma/widgets/slider.h>
00037 #include <plasma/widgets/frame.h>
00038 
00039 namespace Plasma
00040 {
00041 
00042 class VideoWidgetPrivate
00043 {
00044 public:
00045     VideoWidgetPrivate(VideoWidget *video)
00046          : q(video),
00047            ticking(false),
00048            forceControlsVisible(false),
00049            animId(0),
00050            hideTimer(0),
00051            shownControls(VideoWidget::NoControls),
00052            controlsWidget(0),
00053            previousButton(0),
00054            playButton(0),
00055            pauseButton(0),
00056            stopButton(0),
00057            playPauseButton(0),
00058            nextButton(0),
00059            progress(0),
00060            volume(0),
00061            openFileButton(0)
00062     {
00063     }
00064 
00065     ~VideoWidgetPrivate()
00066     {
00067     }
00068 
00069     void playPause();
00070     void ticked(qint64 progress);
00071     void totalTimeChanged(qint64 time);
00072     void setPosition(int newProgress);
00073     void setVolume(int value);
00074     void volumeChanged(qreal value);
00075     void showOpenFileDialog();
00076     void openFile(const QString &path);
00077     void stateChanged(Phonon::State newState, Phonon::State oldState);
00078     void animateControlWidget(bool show);
00079     void hideControlWidget();
00080     void slidingCompleted(QGraphicsItem *item);
00081     bool spaceForControlsAvailable();
00082 
00083 
00084     VideoWidget *q;
00085 
00086     Phonon::VideoWidget *videoWidget;
00087     Phonon::AudioOutput *audioOutput;
00088     Phonon::MediaObject *media;
00089 
00090     bool ticking;
00091     bool forceControlsVisible;
00092 
00093     //control widgets
00094     int animId;
00095     QTimer *hideTimer;
00096     VideoWidget::Controls shownControls;
00097     Plasma::Frame *controlsWidget;
00098     IconWidget *previousButton;
00099     IconWidget *playButton;
00100     IconWidget *pauseButton;
00101     IconWidget *stopButton;
00102     IconWidget *playPauseButton;
00103     IconWidget *nextButton;
00104     Slider *progress;
00105     Slider *volume;
00106     IconWidget *openFileButton;
00107 };
00108 
00109 void VideoWidgetPrivate::playPause()
00110 {
00111     if (media->state() == Phonon::PlayingState) {
00112         media->pause();
00113     } else {
00114         media->play();
00115     }
00116 }
00117 
00118 void VideoWidgetPrivate::ticked(qint64 newProgress)
00119 {
00120     ticking = true;
00121     progress->setValue(newProgress);
00122     ticking = false;
00123 }
00124 
00125 void VideoWidgetPrivate::totalTimeChanged(qint64 time)
00126 {
00127     ticking = true;
00128     //FIXME: this will break for veeery long stuff, butPhonon::SeekSlider seems to have the same problem
00129     progress->setRange(0, time);
00130     ticking = false;
00131 }
00132 
00133 void VideoWidgetPrivate::setPosition(int progress)
00134 {
00135     if (!ticking) {
00136         media->seek(progress);
00137     }
00138 }
00139 
00140 void VideoWidgetPrivate::setVolume(int value)
00141 {
00142      audioOutput->setVolume(qreal(value)/100.0);
00143 }
00144 
00145 void VideoWidgetPrivate::volumeChanged(qreal value)
00146 {
00147      volume->setValue(value*100);
00148 }
00149 
00150 void VideoWidgetPrivate::showOpenFileDialog()
00151 {
00152     openFile(KFileDialog::getOpenFileName());
00153 }
00154 
00155 void VideoWidgetPrivate::openFile(const QString &path)
00156 {
00157     media->setCurrentSource(Phonon::MediaSource(path));
00158     media->play();
00159 }
00160 
00161 void VideoWidgetPrivate::stateChanged(Phonon::State newState, Phonon::State oldState)
00162 {
00163     Q_UNUSED(oldState)
00164 
00165     if (playPauseButton) {
00166         if (newState == Phonon::PlayingState) {
00167             playPauseButton->setIcon("media-playback-pause");
00168         } else {
00169             playPauseButton->setIcon("media-playback-start");
00170         }
00171     }
00172 }
00173 
00174 void VideoWidgetPrivate::animateControlWidget(bool show)
00175 {
00176     if (!controlsWidget || controlsWidget->isVisible() == show) {
00177         return;
00178     }
00179 
00180     QPoint oldPos(0,0);
00181     QPoint newPos(0,0);
00182 
00183     if (show) {
00184         oldPos = QPoint(0, -controlsWidget->size().height());
00185     } else {
00186         newPos = QPoint(0, -controlsWidget->size().height());
00187     }
00188 
00189     //clip only when animating
00190     q->setFlags(q->flags()|QGraphicsItem::ItemClipsChildrenToShape);
00191 
00192     controlsWidget->setPos(oldPos);
00193     controlsWidget->show();
00194 
00195     animId = Animator::self()->moveItem(
00196               controlsWidget, Plasma::Animator::SlideOutMovement,
00197               newPos);
00198 }
00199 
00200 void VideoWidgetPrivate::hideControlWidget()
00201 {
00202     animateControlWidget(false);
00203 }
00204 
00205 void VideoWidgetPrivate::slidingCompleted(QGraphicsItem *item)
00206 {
00207     Q_UNUSED(item)
00208 
00209     animId = 0;
00210 
00211     if (!controlsWidget) {
00212         return;
00213     }
00214 
00215     //usually don't clip
00216     q->setFlags(q->flags()^QGraphicsItem::ItemClipsChildrenToShape);
00217 
00218     if (controlsWidget->pos().y() < 0) {
00219         controlsWidget->hide();
00220     } else if (!forceControlsVisible) {
00221         hideTimer->start(3000);
00222     }
00223 }
00224 
00225 bool VideoWidgetPrivate::spaceForControlsAvailable()
00226 {
00227     if (controlsWidget) {
00228         QSize hint = controlsWidget->effectiveSizeHint(Qt::MinimumSize).toSize();
00229         return (q->size().width() >= hint.width()) &&
00230                (q->size().height() >= hint.height());
00231     } else {
00232         return true;
00233     }
00234 }
00235 
00236 
00237 
00238 VideoWidget::VideoWidget(QGraphicsWidget *parent)
00239     : QGraphicsProxyWidget(parent),
00240       d(new VideoWidgetPrivate(this))
00241 {
00242     d->videoWidget = new Phonon::VideoWidget;
00243     d->audioOutput = new Phonon::AudioOutput(this);
00244     d->media = new Phonon::MediaObject(this);
00245     //it appears that the path has to be created BEFORE setting the proxy
00246     Phonon::createPath(d->media, d->videoWidget);
00247     Phonon::createPath(d->media, d->audioOutput);
00248 
00249 
00250     setWidget(d->videoWidget);
00251     setAcceptHoverEvents(true);
00252 
00253     connect(d->media, SIGNAL(tick(qint64)), this, SIGNAL(tick(qint64)));
00254     connect(d->media, SIGNAL(aboutToFinish()), this, SIGNAL(aboutToFinish()));
00255     connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)),
00256            this, SLOT(slidingCompleted(QGraphicsItem*)));
00257 }
00258 
00259 VideoWidget::~VideoWidget()
00260 {
00261     delete d;
00262 }
00263 
00264 Phonon::MediaObject *VideoWidget::mediaObject() const
00265 {
00266     return d->media;
00267 }
00268 
00269 Phonon::AudioOutput *VideoWidget::audioOutput() const
00270 {
00271     return d->audioOutput;
00272 }
00273 
00274 void VideoWidget::setUrl(const QString &url)
00275 {
00276     d->media->setCurrentSource(Phonon::MediaSource(url));
00277 }
00278 
00279 QString VideoWidget::url() const
00280 {
00281     return d->media->currentSource().url().toString();
00282 }
00283 
00284 void VideoWidget::setUsedControls(const Controls controls)
00285 {
00286     d->shownControls = controls;
00287 
00288     //kDebug()<<"Setting used controls"<<controls;
00289 
00290     QGraphicsLinearLayout *controlsLayout = 0;
00291     if (controls != NoControls && d->controlsWidget == 0) {
00292         d->controlsWidget = new Plasma::Frame(this);
00293         d->controlsWidget->setFrameShadow(Plasma::Frame::Raised);
00294         controlsLayout = new QGraphicsLinearLayout(Qt::Horizontal, d->controlsWidget);
00295         d->hideTimer = new QTimer(this);
00296         connect(d->hideTimer, SIGNAL(timeout()), this, SLOT(hideControlWidget()));
00297     //controls == NoControls
00298     } else if (d->controlsWidget != 0) {
00299         d->controlsWidget->deleteLater();
00300         d->hideTimer->deleteLater();
00301         d->controlsWidget = 0;
00302 
00303         //disconnect all the stuff that wasn't automatically disconnected 'cause widget deaths
00304         disconnect(d->media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State)));
00305         disconnect(d->media, SIGNAL(tick(qint64)), this, SLOT(ticked(qint64)));
00306         disconnect(d->media, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
00307         disconnect(d->audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
00308         return;
00309     }
00310 
00311     Q_ASSERT(controlsLayout);
00312 
00313     //empty the layout
00314     while (controlsLayout->count() > 0) {
00315         controlsLayout->removeAt(0);
00316     }
00317 
00318     if (controls&Previous) {
00319         if (!d->previousButton) {
00320             d->previousButton = new IconWidget(d->controlsWidget);
00321             d->previousButton->setIcon("media-playback-start");
00322             connect(d->playButton, SIGNAL(clicked()), this, SLOT(PreviousRequested()));
00323         }
00324         controlsLayout->addItem(d->previousButton);
00325     } else {
00326         d->previousButton->deleteLater();
00327         d->previousButton = 0;
00328     }
00329 
00330     if (controls&Play) {
00331         if (!d->playButton) {
00332             d->playButton = new IconWidget(d->controlsWidget);
00333             d->playButton->setIcon("media-playback-start");
00334             connect(d->playButton, SIGNAL(clicked()), this, SLOT(play()));
00335         }
00336         controlsLayout->addItem(d->playButton);
00337     } else {
00338         d->playButton->deleteLater();
00339         d->playButton = 0;
00340     }
00341 
00342     if (controls&Pause) {
00343         if (!d->pauseButton) {
00344             d->pauseButton = new IconWidget(d->controlsWidget);
00345             d->pauseButton->setIcon("media-playback-pause");
00346             connect(d->pauseButton, SIGNAL(clicked()), this, SLOT(pause()));
00347         }
00348         controlsLayout->addItem(d->pauseButton);
00349     } else {
00350         d->pauseButton->deleteLater();
00351         d->pauseButton = 0;
00352     }
00353 
00354     if (controls&Stop) {
00355         if (!d->stopButton) {
00356             d->stopButton = new IconWidget(d->controlsWidget);
00357             d->stopButton->setIcon("media-playback-stop");
00358             connect(d->stopButton, SIGNAL(clicked()), this, SLOT(stop()));
00359         }
00360         controlsLayout->addItem(d->stopButton);
00361     } else {
00362         d->stopButton->deleteLater();
00363         d->stopButton = 0;
00364     }
00365 
00366     if (controls&PlayPause) {
00367         if (!d->playPauseButton) {
00368             d->playPauseButton = new IconWidget(d->controlsWidget);
00369             d->playPauseButton->setIcon("media-playback-start");
00370             connect(d->playPauseButton, SIGNAL(clicked()), this, SLOT(playPause()));
00371         }
00372         controlsLayout->addItem(d->playPauseButton);
00373     } else {
00374         d->playPauseButton->deleteLater();
00375         d->playPauseButton = 0;
00376     }
00377 
00378     if (controls&Next) {
00379         if (!d->nextButton) {
00380             d->nextButton = new IconWidget(d->nextButton);
00381             d->nextButton->setIcon("media-playback-start");
00382             connect(d->nextButton, SIGNAL(clicked()), this, SIGNAL(nextRequested()));
00383         }
00384         controlsLayout->addItem(d->nextButton);
00385     } else {
00386         d->nextButton->deleteLater();
00387         d->nextButton = 0;
00388     }
00389 
00390     connect(d->media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State)));
00391 
00392 
00393 
00394 
00395     if (controls&Progress) {
00396         if (!d->progress) {
00397             d->progress = new Slider(d->controlsWidget);
00398             d->progress->setMinimum(0);
00399             d->progress->setMaximum(100);
00400             d->progress->setOrientation(Qt::Horizontal);
00401             controlsLayout->setStretchFactor(d->progress, 4);
00402             d->progress->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
00403 
00404             connect(d->media, SIGNAL(tick(qint64)), this, SLOT(ticked(qint64)));
00405             connect(d->media, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64)));
00406             connect(d->progress, SIGNAL(valueChanged(int)), this, SLOT(setPosition(int)));
00407         }
00408         controlsLayout->addItem(d->progress);
00409     } else {
00410         d->progress->deleteLater();
00411         d->progress = 0;
00412     }
00413 
00414 
00415     if (controls&Volume) {
00416         if (!d->volume) {
00417             d->volume = new Slider(d->controlsWidget);
00418             d->volume->setMinimum(0);
00419             d->volume->setMaximum(100);
00420             d->volume->setValue(100);
00421             d->volume->setOrientation(Qt::Horizontal);
00422             d->volume->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
00423 
00424             connect(d->volume, SIGNAL(valueChanged(int)), SLOT(setVolume(int)));
00425             connect(d->audioOutput, SIGNAL(volumeChanged(qreal)), SLOT(volumeChanged(qreal)));
00426         }
00427         controlsLayout->addItem(d->volume);
00428     } else {
00429         d->volume->deleteLater();
00430         d->volume = 0;
00431     }
00432 
00433 
00434     if (controls&OpenFile) {
00435         if (!d->openFileButton) {
00436             d->openFileButton = new IconWidget(d->controlsWidget);
00437             d->openFileButton->setIcon(KIcon("document-open"));
00438             connect(d->openFileButton, SIGNAL(clicked()), this, SLOT(showOpenFileDialog()));
00439         }
00440         controlsLayout->addItem(d->openFileButton);
00441     } else {
00442         d->openFileButton->deleteLater();
00443         d->openFileButton = 0;
00444     }
00445 
00446     controlsLayout->activate();
00447     d->controlsWidget->setPos(0,-d->controlsWidget->size().height());
00448     d->controlsWidget->resize(size().width(), d->controlsWidget->size().height());
00449     d->controlsWidget->hide();
00450 }
00451 
00452 VideoWidget::Controls VideoWidget::usedControls() const
00453 {
00454     return d->shownControls;
00455 }
00456 
00457 void VideoWidget::play()
00458 {
00459     d->media->play();
00460 }
00461 
00462 void VideoWidget::pause()
00463 {
00464     d->media->pause();
00465 }
00466 
00467 void VideoWidget::stop()
00468 {
00469     d->media->stop();
00470 }
00471 
00472 void VideoWidget::seek(qint64 time)
00473 {
00474     d->media->seek(time);
00475 }
00476 
00477 qint64 VideoWidget::currentTime() const
00478 {
00479     return d->media->currentTime();
00480 }
00481 
00482 qint64 VideoWidget::totalTime() const
00483 {
00484     return d->media->totalTime();
00485 }
00486 
00487 qint64 VideoWidget::remainingTime() const
00488 {
00489     return d->media->remainingTime();
00490 }
00491 
00492 void VideoWidget::setControlsVisible(bool visible)
00493 {
00494     if (d->controlsWidget) {
00495         d->forceControlsVisible = visible;
00496         d->animateControlWidget(visible);
00497     }
00498 }
00499 
00500 bool VideoWidget::controlsVisible() const
00501 {
00502     return d->controlsWidget != 0 && d->controlsWidget->isVisible();
00503 }
00504 
00505 void VideoWidget::setStyleSheet(const QString &stylesheet)
00506 {
00507     d->videoWidget->setStyleSheet(stylesheet);
00508 }
00509 
00510 QString VideoWidget::styleSheet()
00511 {
00512     return d->videoWidget->styleSheet();
00513 }
00514 
00515 Phonon::VideoWidget *VideoWidget::nativeWidget() const
00516 {
00517     return d->videoWidget;
00518 }
00519 
00520 
00521 void VideoWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
00522 {
00523     QGraphicsProxyWidget::resizeEvent(event);
00524 
00525     if (d->controlsWidget) {
00526         QSize newControlsSize(event->newSize().width(), d->controlsWidget->size().height());
00527         int newHeight = event->newSize().height();
00528         qreal leftMargin, topMargin, rightMargin, bottomMargin;
00529         d->controlsWidget->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
00530 
00531         if (newHeight/5 >= KIconLoader::SizeEnormous) {
00532             newControlsSize.setHeight(KIconLoader::SizeEnormous+topMargin+bottomMargin);
00533         } else if (newHeight/5 >= KIconLoader::SizeHuge) {
00534             newControlsSize.setHeight(KIconLoader::SizeHuge+topMargin+bottomMargin);
00535         } else if (newHeight/5 >= KIconLoader::SizeLarge) {
00536             newControlsSize.setHeight(KIconLoader::SizeLarge+topMargin+bottomMargin);
00537         } else if (newHeight/5 >= KIconLoader::SizeMedium) {
00538             newControlsSize.setHeight(KIconLoader::SizeMedium+topMargin+bottomMargin);
00539         } else {
00540             newControlsSize.setHeight(KIconLoader::SizeSmallMedium+topMargin+bottomMargin);
00541         }
00542         d->controlsWidget->resize(newControlsSize);
00543 
00544         if (d->spaceForControlsAvailable()) {
00545             d->animateControlWidget(false);
00546         }
00547     }
00548 }
00549 
00550 void VideoWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00551 {
00552     Q_UNUSED(event)
00553 
00554     if (d->controlsWidget &&
00555         !d->forceControlsVisible &&
00556         d->spaceForControlsAvailable()) {
00557         d->animateControlWidget(true);
00558     }
00559 }
00560 
00561 void VideoWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00562 {
00563     Q_UNUSED(event)
00564 
00565     if (d->controlsWidget && !d->forceControlsVisible) {
00566         d->hideTimer->start(1000);
00567     }
00568 }
00569 
00570 void VideoWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
00571 {
00572     Q_UNUSED(event)
00573 
00574     if (d->forceControlsVisible || !d->controlsWidget) {
00575         return;
00576     }
00577 
00578     d->hideTimer->start(3000);
00579 
00580     if (!d->controlsWidget->isVisible() &&
00581         d->spaceForControlsAvailable()) {
00582         d->animateControlWidget(true);
00583     }
00584 }
00585 
00586 } // namespace Plasma
00587 
00588 #include <videowidget.moc>
00589 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal