2009-02-08 22:20:41 +01:00
/*
2009-02-12 14:58:10 +01:00
* Copyright 2009 Marco Martin < notmart @ gmail . com >
2009-02-08 22:20:41 +01:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation ; either version 2 , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program ; if not , write to the
* Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
# include "videowidget.h"
2009-02-12 14:58:10 +01:00
# include <QUrl>
2009-02-12 19:19:32 +01:00
# include <QTimer>
2009-02-12 14:58:10 +01:00
# include <QGraphicsLinearLayout>
# include <QGraphicsSceneResizeEvent>
# include <kicon.h>
# include <kfiledialog.h>
2009-02-11 22:34:07 +01:00
2009-02-08 22:20:41 +01:00
# include <phonon/videowidget.h>
# include <phonon/mediaobject.h>
# include <phonon/mediasource.h>
# include <phonon/audiooutput.h>
2009-02-12 14:58:10 +01:00
# include <plasma/widgets/iconwidget.h>
# include <plasma/widgets/slider.h>
2009-02-15 12:52:16 +01:00
# include <plasma/widgets/frame.h>
2009-02-08 22:20:41 +01:00
namespace Plasma
{
class VideoWidgetPrivate
{
public :
2009-02-12 19:19:32 +01:00
VideoWidgetPrivate ( VideoWidget * video )
: q ( video ) ,
ticking ( false ) ,
2009-02-12 21:51:49 +01:00
forceControlsVisible ( false ) ,
2009-02-12 19:19:32 +01:00
animId ( 0 ) ,
hideTimer ( 0 ) ,
2009-02-12 14:58:10 +01:00
shownControls ( VideoWidget : : NoControls ) ,
2009-02-12 17:47:30 +01:00
controlsWidget ( 0 ) ,
playButton ( 0 ) ,
pauseButton ( 0 ) ,
stopButton ( 0 ) ,
playPauseButton ( 0 ) ,
progress ( 0 ) ,
volume ( 0 ) ,
openFileButton ( 0 )
2009-02-08 22:20:41 +01:00
{
}
~ VideoWidgetPrivate ( )
{
}
2009-02-12 14:58:10 +01:00
void playPause ( ) ;
void ticked ( qint64 progress ) ;
void totalTimeChanged ( qint64 time ) ;
void setPosition ( int newProgress ) ;
void setVolume ( int value ) ;
void volumeChanged ( qreal value ) ;
void showOpenFileDialog ( ) ;
void openFile ( const QString & path ) ;
void stateChanged ( Phonon : : State newState , Phonon : : State oldState ) ;
2009-02-12 19:19:32 +01:00
void animateControlWidget ( bool show ) ;
void hideControlWidget ( ) ;
void slidingCompleted ( QGraphicsItem * item ) ;
2009-02-12 21:51:49 +01:00
bool spaceForControlsAvailable ( ) ;
2009-02-12 14:58:10 +01:00
2009-02-12 19:19:32 +01:00
VideoWidget * q ;
2009-02-08 22:20:41 +01:00
Phonon : : VideoWidget * videoWidget ;
Phonon : : AudioOutput * audioOutput ;
Phonon : : MediaObject * media ;
2009-02-12 14:58:10 +01:00
bool ticking ;
2009-02-12 21:51:49 +01:00
bool forceControlsVisible ;
2009-02-12 14:58:10 +01:00
//control widgets
2009-02-12 19:19:32 +01:00
int animId ;
QTimer * hideTimer ;
2009-02-12 14:58:10 +01:00
VideoWidget : : Controls shownControls ;
2009-02-15 12:52:16 +01:00
Plasma : : Frame * controlsWidget ;
2009-02-12 17:47:30 +01:00
IconWidget * playButton ;
IconWidget * pauseButton ;
IconWidget * stopButton ;
2009-02-12 14:58:10 +01:00
IconWidget * playPauseButton ;
Slider * progress ;
Slider * volume ;
IconWidget * openFileButton ;
2009-02-08 22:20:41 +01:00
} ;
2009-02-12 14:58:10 +01:00
void VideoWidgetPrivate : : playPause ( )
{
if ( media - > state ( ) = = Phonon : : PlayingState ) {
media - > pause ( ) ;
} else {
media - > play ( ) ;
}
}
void VideoWidgetPrivate : : ticked ( qint64 newProgress )
{
ticking = true ;
progress - > setValue ( newProgress ) ;
ticking = false ;
}
void VideoWidgetPrivate : : totalTimeChanged ( qint64 time )
{
ticking = true ;
//FIXME: this will break for veeery long stuff, butPhonon::SeekSlider seems to have the same problem
progress - > setRange ( 0 , time ) ;
ticking = false ;
}
void VideoWidgetPrivate : : setPosition ( int progress )
{
if ( ! ticking ) {
media - > seek ( progress ) ;
}
}
void VideoWidgetPrivate : : setVolume ( int value )
{
audioOutput - > setVolume ( qreal ( value ) / 100.0 ) ;
}
void VideoWidgetPrivate : : volumeChanged ( qreal value )
{
volume - > setValue ( value * 100 ) ;
}
void VideoWidgetPrivate : : showOpenFileDialog ( )
{
openFile ( KFileDialog : : getOpenFileName ( ) ) ;
}
void VideoWidgetPrivate : : openFile ( const QString & path )
{
media - > setCurrentSource ( Phonon : : MediaSource ( path ) ) ;
media - > play ( ) ;
}
void VideoWidgetPrivate : : stateChanged ( Phonon : : State newState , Phonon : : State oldState )
{
Q_UNUSED ( oldState )
if ( newState = = Phonon : : PlayingState ) {
playPauseButton - > setIcon ( " media-playback-pause " ) ;
} else {
playPauseButton - > setIcon ( " media-playback-start " ) ;
}
}
2009-02-12 19:19:32 +01:00
void VideoWidgetPrivate : : animateControlWidget ( bool show )
{
if ( ! controlsWidget | | controlsWidget - > isVisible ( ) = = show ) {
return ;
}
QPoint oldPos ( 0 , 0 ) ;
QPoint newPos ( 0 , 0 ) ;
if ( show ) {
oldPos = QPoint ( 0 , - controlsWidget - > size ( ) . height ( ) ) ;
} else {
newPos = QPoint ( 0 , - controlsWidget - > size ( ) . height ( ) ) ;
}
controlsWidget - > setPos ( oldPos ) ;
controlsWidget - > show ( ) ;
animId = Animator : : self ( ) - > moveItem (
controlsWidget , Plasma : : Animator : : SlideOutMovement ,
newPos ) ;
}
void VideoWidgetPrivate : : hideControlWidget ( )
{
animateControlWidget ( false ) ;
}
void VideoWidgetPrivate : : slidingCompleted ( QGraphicsItem * item )
{
Q_UNUSED ( item )
animId = 0 ;
if ( ! controlsWidget ) {
return ;
}
if ( controlsWidget - > pos ( ) . y ( ) < 0 ) {
controlsWidget - > hide ( ) ;
2009-02-12 21:51:49 +01:00
} else if ( ! forceControlsVisible ) {
2009-02-12 19:19:32 +01:00
hideTimer - > start ( 3000 ) ;
}
}
2009-02-12 21:51:49 +01:00
bool VideoWidgetPrivate : : spaceForControlsAvailable ( )
{
if ( controlsWidget ) {
QSize hint = controlsWidget - > effectiveSizeHint ( Qt : : MinimumSize ) . toSize ( ) ;
return ( q - > size ( ) . width ( ) > = hint . width ( ) ) & &
( q - > size ( ) . height ( ) > = hint . height ( ) ) ;
} else {
return true ;
}
}
2009-02-12 14:58:10 +01:00
2009-02-08 22:20:41 +01:00
VideoWidget : : VideoWidget ( QGraphicsWidget * parent )
: QGraphicsProxyWidget ( parent ) ,
2009-02-12 19:19:32 +01:00
d ( new VideoWidgetPrivate ( this ) )
2009-02-08 22:20:41 +01:00
{
d - > videoWidget = new Phonon : : VideoWidget ;
d - > audioOutput = new Phonon : : AudioOutput ( this ) ;
d - > media = new Phonon : : MediaObject ( this ) ;
//it appears that the path has to be created BEFORE setting the proxy
Phonon : : createPath ( d - > media , d - > videoWidget ) ;
Phonon : : createPath ( d - > media , d - > audioOutput ) ;
setWidget ( d - > videoWidget ) ;
2009-02-12 19:19:32 +01:00
setAcceptHoverEvents ( true ) ;
//FIXME: would be desiderable to have clipping on just when animating, seems that changing it on the fly messes up with visibility of children, indagate if is a qt bug
setFlags ( flags ( ) | QGraphicsItem : : ItemClipsChildrenToShape ) ;
2009-02-08 22:20:41 +01:00
connect ( d - > media , SIGNAL ( tick ( qint64 ) ) , this , SIGNAL ( tick ( qint64 ) ) ) ;
connect ( d - > media , SIGNAL ( aboutToFinish ( ) ) , this , SIGNAL ( aboutToFinish ( ) ) ) ;
2009-02-12 19:19:32 +01:00
connect ( Plasma : : Animator : : self ( ) , SIGNAL ( movementFinished ( QGraphicsItem * ) ) ,
this , SLOT ( slidingCompleted ( QGraphicsItem * ) ) ) ;
2009-02-08 22:20:41 +01:00
}
VideoWidget : : ~ VideoWidget ( )
{
delete d ;
}
Phonon : : MediaObject * VideoWidget : : mediaObject ( ) const
{
return d - > media ;
}
Phonon : : AudioOutput * VideoWidget : : audioOutput ( ) const
{
return d - > audioOutput ;
}
2009-02-11 22:34:07 +01:00
void VideoWidget : : setUrl ( const QString & url )
2009-02-08 22:20:41 +01:00
{
2009-02-11 22:34:07 +01:00
d - > media - > setCurrentSource ( Phonon : : MediaSource ( url ) ) ;
2009-02-08 22:20:41 +01:00
}
2009-02-11 22:34:07 +01:00
QString VideoWidget : : url ( ) const
2009-02-08 22:20:41 +01:00
{
2009-02-11 22:34:07 +01:00
return d - > media - > currentSource ( ) . url ( ) . toString ( ) ;
2009-02-08 22:20:41 +01:00
}
2009-02-14 14:55:09 +01:00
void VideoWidget : : setUsedControls ( const Controls controls )
2009-02-12 14:58:10 +01:00
{
d - > shownControls = controls ;
2009-02-14 14:55:09 +01:00
//kDebug()<<"Setting used controls"<<controls;
2009-02-12 14:58:10 +01:00
QGraphicsLinearLayout * controlsLayout ;
if ( controls ! = NoControls & & d - > controlsWidget = = 0 ) {
2009-02-15 12:52:16 +01:00
d - > controlsWidget = new Plasma : : Frame ( this ) ;
d - > controlsWidget - > setFrameShadow ( Plasma : : Frame : : Raised ) ;
2009-02-12 14:58:10 +01:00
controlsLayout = new QGraphicsLinearLayout ( Qt : : Horizontal , d - > controlsWidget ) ;
2009-02-12 19:19:32 +01:00
d - > hideTimer = new QTimer ( this ) ;
connect ( d - > hideTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( hideControlWidget ( ) ) ) ;
2009-02-12 14:58:10 +01:00
//controls == NoControls
} else if ( d - > controlsWidget ! = 0 ) {
d - > controlsWidget - > deleteLater ( ) ;
2009-02-12 19:19:32 +01:00
d - > hideTimer - > deleteLater ( ) ;
2009-02-12 14:58:10 +01:00
d - > controlsWidget = 0 ;
//disconnect all the stuff that wasn't automatically disconnected 'cause widget deaths
disconnect ( d - > media , SIGNAL ( stateChanged ( Phonon : : State , Phonon : : State ) ) , this , SLOT ( stateChanged ( Phonon : : State , Phonon : : State ) ) ) ;
disconnect ( d - > media , SIGNAL ( tick ( qint64 ) ) , this , SLOT ( ticked ( qint64 ) ) ) ;
disconnect ( d - > media , SIGNAL ( totalTimeChanged ( qint64 ) ) , this , SLOT ( totalTimeChanged ( qint64 ) ) ) ;
disconnect ( d - > audioOutput , SIGNAL ( volumeChanged ( qreal ) ) , this , SLOT ( volumeChanged ( qreal ) ) ) ;
return ;
}
2009-02-12 17:47:30 +01:00
//empty the layout
while ( controlsLayout - > count ( ) > 0 ) {
controlsLayout - > removeAt ( 0 ) ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & Play ) {
if ( ! d - > playButton ) {
d - > playButton = new IconWidget ( d - > controlsWidget ) ;
d - > playButton - > setIcon ( " media-playback-start " ) ;
connect ( d - > playButton , SIGNAL ( clicked ( ) ) , this , SLOT ( play ( ) ) ) ;
}
controlsLayout - > addItem ( d - > playButton ) ;
} else {
d - > playButton - > deleteLater ( ) ;
d - > playButton = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & Pause ) {
if ( ! d - > pauseButton ) {
d - > pauseButton = new IconWidget ( d - > controlsWidget ) ;
d - > pauseButton - > setIcon ( " media-playback-pause " ) ;
connect ( d - > pauseButton , SIGNAL ( clicked ( ) ) , this , SLOT ( pause ( ) ) ) ;
}
controlsLayout - > addItem ( d - > pauseButton ) ;
} else {
d - > pauseButton - > deleteLater ( ) ;
d - > pauseButton = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & Stop ) {
if ( ! d - > stopButton ) {
d - > stopButton = new IconWidget ( d - > controlsWidget ) ;
d - > stopButton - > setIcon ( " media-playback-stop " ) ;
connect ( d - > stopButton , SIGNAL ( clicked ( ) ) , this , SLOT ( stop ( ) ) ) ;
}
controlsLayout - > addItem ( d - > stopButton ) ;
} else {
d - > stopButton - > deleteLater ( ) ;
d - > stopButton = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & PlayPause ) {
if ( ! d - > playPauseButton ) {
d - > playPauseButton = new IconWidget ( d - > controlsWidget ) ;
d - > playPauseButton - > setIcon ( " media-playback-start " ) ;
connect ( d - > playPauseButton , SIGNAL ( clicked ( ) ) , this , SLOT ( playPause ( ) ) ) ;
}
controlsLayout - > addItem ( d - > playPauseButton ) ;
} else {
d - > playPauseButton - > deleteLater ( ) ;
d - > playPauseButton = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
connect ( d - > media , SIGNAL ( stateChanged ( Phonon : : State , Phonon : : State ) ) , this , SLOT ( stateChanged ( Phonon : : State , Phonon : : State ) ) ) ;
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & Progress ) {
if ( ! d - > progress ) {
d - > progress = new Slider ( d - > controlsWidget ) ;
d - > progress - > setMinimum ( 0 ) ;
d - > progress - > setMaximum ( 100 ) ;
d - > progress - > setOrientation ( Qt : : Horizontal ) ;
controlsLayout - > setStretchFactor ( d - > progress , 4 ) ;
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
connect ( d - > media , SIGNAL ( tick ( qint64 ) ) , this , SLOT ( ticked ( qint64 ) ) ) ;
connect ( d - > media , SIGNAL ( totalTimeChanged ( qint64 ) ) , SLOT ( totalTimeChanged ( qint64 ) ) ) ;
connect ( d - > progress , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( setPosition ( int ) ) ) ;
}
controlsLayout - > addItem ( d - > progress ) ;
} else {
d - > progress - > deleteLater ( ) ;
d - > progress = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
if ( controls & Volume ) {
if ( ! d - > volume ) {
d - > volume = new Slider ( d - > controlsWidget ) ;
d - > volume - > setMinimum ( 0 ) ;
d - > volume - > setMaximum ( 100 ) ;
d - > volume - > setValue ( 100 ) ;
d - > volume - > setOrientation ( Qt : : Horizontal ) ;
2009-02-12 14:58:10 +01:00
2009-02-12 17:47:30 +01:00
connect ( d - > volume , SIGNAL ( valueChanged ( int ) ) , SLOT ( setVolume ( int ) ) ) ;
connect ( d - > audioOutput , SIGNAL ( volumeChanged ( qreal ) ) , SLOT ( volumeChanged ( qreal ) ) ) ;
}
2009-02-12 19:19:32 +01:00
controlsLayout - > addItem ( d - > volume ) ;
2009-02-12 17:47:30 +01:00
} else {
d - > volume - > deleteLater ( ) ;
d - > volume = 0 ;
}
if ( controls & OpenFile ) {
if ( ! d - > openFileButton ) {
d - > openFileButton = new IconWidget ( d - > controlsWidget ) ;
d - > openFileButton - > setIcon ( KIcon ( " document-open " ) ) ;
connect ( d - > openFileButton , SIGNAL ( clicked ( ) ) , this , SLOT ( showOpenFileDialog ( ) ) ) ;
}
controlsLayout - > addItem ( d - > openFileButton ) ;
} else {
d - > openFileButton - > deleteLater ( ) ;
d - > openFileButton = 0 ;
}
2009-02-12 14:58:10 +01:00
2009-02-12 19:19:32 +01:00
controlsLayout - > activate ( ) ;
d - > controlsWidget - > setPos ( 0 , - d - > controlsWidget - > size ( ) . height ( ) ) ;
d - > controlsWidget - > resize ( size ( ) . width ( ) , d - > controlsWidget - > size ( ) . height ( ) ) ;
d - > controlsWidget - > hide ( ) ;
2009-02-12 14:58:10 +01:00
}
2009-02-12 21:51:49 +01:00
VideoWidget : : Controls VideoWidget : : usedControls ( ) const
2009-02-12 14:58:10 +01:00
{
return d - > shownControls ;
}
2009-02-08 22:20:41 +01:00
void VideoWidget : : play ( )
{
d - > media - > play ( ) ;
}
void VideoWidget : : pause ( )
{
d - > media - > pause ( ) ;
}
void VideoWidget : : stop ( )
{
d - > media - > stop ( ) ;
}
void VideoWidget : : seek ( qint64 time )
{
d - > media - > seek ( time ) ;
}
qint64 VideoWidget : : currentTime ( ) const
{
return d - > media - > currentTime ( ) ;
}
qint64 VideoWidget : : totalTime ( ) const
{
return d - > media - > totalTime ( ) ;
}
qint64 VideoWidget : : remainingTime ( ) const
{
return d - > media - > remainingTime ( ) ;
}
2009-02-12 21:51:49 +01:00
void VideoWidget : : setControlsVisible ( bool visible )
{
if ( d - > controlsWidget ) {
d - > forceControlsVisible = visible ;
d - > animateControlWidget ( visible ) ;
}
}
bool VideoWidget : : controlsVisible ( ) const
{
return d - > controlsWidget ! = 0 & & d - > controlsWidget - > isVisible ( ) ;
}
2009-02-08 22:20:41 +01:00
void VideoWidget : : setStyleSheet ( const QString & stylesheet )
{
d - > videoWidget - > setStyleSheet ( stylesheet ) ;
}
QString VideoWidget : : styleSheet ( )
{
return d - > videoWidget - > styleSheet ( ) ;
}
Phonon : : VideoWidget * VideoWidget : : nativeWidget ( ) const
{
return d - > videoWidget ;
}
2009-02-12 14:58:10 +01:00
void VideoWidget : : resizeEvent ( QGraphicsSceneResizeEvent * event )
{
QGraphicsProxyWidget : : resizeEvent ( event ) ;
if ( d - > controlsWidget ) {
d - > controlsWidget - > resize ( event - > newSize ( ) . width ( ) , d - > controlsWidget - > size ( ) . height ( ) ) ;
2009-02-12 21:51:49 +01:00
if ( d - > spaceForControlsAvailable ( ) ) {
d - > animateControlWidget ( false ) ;
}
2009-02-12 14:58:10 +01:00
}
}
2009-02-12 19:19:32 +01:00
void VideoWidget : : hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
{
Q_UNUSED ( event )
2009-02-12 21:51:49 +01:00
if ( d - > controlsWidget & &
! d - > forceControlsVisible & &
d - > spaceForControlsAvailable ( ) ) {
2009-02-12 19:19:32 +01:00
d - > animateControlWidget ( true ) ;
}
}
void VideoWidget : : hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
{
Q_UNUSED ( event )
2009-02-12 21:51:49 +01:00
if ( d - > controlsWidget & & ! d - > forceControlsVisible ) {
2009-02-12 19:19:32 +01:00
d - > hideTimer - > start ( 1000 ) ;
}
}
void VideoWidget : : hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
{
Q_UNUSED ( event )
2009-02-12 22:08:31 +01:00
if ( d - > forceControlsVisible | | ! d - > controlsWidget ) {
2009-02-12 21:51:49 +01:00
return ;
}
2009-02-12 19:19:32 +01:00
d - > hideTimer - > start ( 3000 ) ;
2009-02-12 22:08:31 +01:00
if ( ! d - > controlsWidget - > isVisible ( ) & &
2009-02-12 21:51:49 +01:00
d - > spaceForControlsAvailable ( ) ) {
2009-02-12 19:19:32 +01:00
d - > animateControlWidget ( true ) ;
}
}
2009-02-08 22:20:41 +01:00
} // namespace Plasma
# include <videowidget.moc>