1 /***************************************************************************
2 * Copyright (C) 2008 by Pino Toscano <pino@kde.org> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 ***************************************************************************/
10 #include "videowidget.h"
19 #include <qtoolbutton.h>
20 #include <qwidgetaction.h>
25 #include <phonon/seekslider.h>
26 #include <phonon/videoplayer.h>
28 #include "core/area.h"
29 #include "core/annotations.h"
30 #include "core/document.h"
31 #include "core/movie.h"
33 static QAction
* createToolBarButtonWithWidgetPopup( QToolBar
* toolBar
, QWidget
*widget
, const QIcon
&icon
)
35 QToolButton
*button
= new QToolButton( toolBar
);
36 QAction
*action
= toolBar
->addWidget( button
);
37 button
->setAutoRaise( true );
38 button
->setIcon( icon
);
39 button
->setPopupMode( QToolButton::InstantPopup
);
40 QMenu
*menu
= new QMenu( button
);
41 button
->setMenu( menu
);
42 QWidgetAction
*widgetAction
= new QWidgetAction( menu
);
43 QWidget
*dummy
= new QWidget( menu
);
44 widgetAction
->setDefaultWidget( dummy
);
45 QVBoxLayout
*dummyLayout
= new QVBoxLayout( dummy
);
46 dummyLayout
->setMargin( 5 );
47 dummyLayout
->addWidget( widget
);
48 menu
->addAction( widgetAction
);
52 /* Private storage. */
53 class VideoWidget::Private
56 Private( Okular::MovieAnnotation
*ma
, Okular::Document
*doc
, VideoWidget
*qq
)
57 : q( qq
), anno( ma
), document( doc
), loaded( false )
61 enum PlayPauseMode
{ PlayMode
, PauseMode
};
64 void setupPlayPauseAction( PlayPauseMode mode
);
71 Okular::MovieAnnotation
*anno
;
72 Okular::Document
*document
;
73 Okular::NormalizedRect geom
;
74 Phonon::VideoPlayer
*player
;
75 Phonon::SeekSlider
*seekSlider
;
77 QAction
*playPauseAction
;
79 QAction
*seekSliderAction
;
80 QAction
*seekSliderMenuAction
;
84 void VideoWidget::Private::load()
91 QString url
= anno
->movie()->url();
93 if ( QDir::isRelativePath( url
) )
95 newurl
= document
->currentDocument();
96 newurl
.setFileName( url
);
102 if ( newurl
.isLocalFile() )
103 player
->load( newurl
.toLocalFile() );
105 player
->load( newurl
);
107 seekSlider
->setEnabled( true );
110 void VideoWidget::Private::setupPlayPauseAction( PlayPauseMode mode
)
112 if ( mode
== PlayMode
)
114 playPauseAction
->setIcon( KIcon( "media-playback-start" ) );
115 playPauseAction
->setText( i18nc( "start the movie playback", "Play" ) );
117 else if ( mode
== PauseMode
)
119 playPauseAction
->setIcon( KIcon( "media-playback-pause" ) );
120 playPauseAction
->setText( i18nc( "pause the movie playback", "Pause" ) );
124 void VideoWidget::Private::finished()
126 switch ( anno
->movie()->playMode() )
128 case Okular::Movie::PlayOnce
:
129 case Okular::Movie::PlayOpen
:
130 // playback has ended, nothing to do
131 stopAction
->setEnabled( false );
132 setupPlayPauseAction( PlayMode
);
133 if ( anno
->movie()->playMode() == Okular::Movie::PlayOnce
)
134 controlBar
->setVisible( false );
136 case Okular::Movie::PlayRepeat
:
137 // repeat the playback
140 case Okular::Movie::PlayPalindrome
:
141 // FIXME we should play backward, but we cannot
147 void VideoWidget::Private::playOrPause()
149 if ( player
->isPlaying() )
152 setupPlayPauseAction( PlayMode
);
160 VideoWidget::VideoWidget( Okular::MovieAnnotation
*movieann
, Okular::Document
*document
, QWidget
*parent
)
161 : QWidget( parent
), d( new Private( movieann
, document
, this ) )
163 // do not propagate the mouse events to the parent widget;
164 // they should be tied to this widget, not spread around...
165 setAttribute( Qt::WA_NoMousePropagation
);
167 QVBoxLayout
*mainlay
= new QVBoxLayout( this );
168 mainlay
->setMargin( 0 );
169 mainlay
->setSpacing( 0 );
171 d
->player
= new Phonon::VideoPlayer( Phonon::NoCategory
, this );
172 d
->player
->installEventFilter( this );
173 mainlay
->addWidget( d
->player
);
175 d
->controlBar
= new QToolBar( this );
176 d
->controlBar
->setIconSize( QSize( 16, 16 ) );
177 d
->controlBar
->setAutoFillBackground( true );
178 mainlay
->addWidget( d
->controlBar
);
180 d
->playPauseAction
= new QAction( d
->controlBar
);
181 d
->controlBar
->addAction( d
->playPauseAction
);
182 d
->setupPlayPauseAction( Private::PlayMode
);
183 d
->stopAction
= d
->controlBar
->addAction(
184 KIcon( "media-playback-stop" ),
185 i18nc( "stop the movie playback", "Stop" ),
186 this, SLOT( stop() ) );
187 d
->stopAction
->setEnabled( false );
188 d
->controlBar
->addSeparator();
189 d
->seekSlider
= new Phonon::SeekSlider( d
->player
->mediaObject(), d
->controlBar
);
190 d
->seekSliderAction
= d
->controlBar
->addWidget( d
->seekSlider
);
191 d
->seekSlider
->setEnabled( false );
193 Phonon::SeekSlider
*verticalSeekSlider
= new Phonon::SeekSlider( d
->player
->mediaObject(), 0 );
194 verticalSeekSlider
->setMaximumHeight( 100 );
195 d
->seekSliderMenuAction
= createToolBarButtonWithWidgetPopup(
196 d
->controlBar
, verticalSeekSlider
, KIcon( "player-time" ) );
197 d
->seekSliderMenuAction
->setVisible( false );
199 d
->controlBar
->setVisible( movieann
->movie()->showControls() );
201 connect( d
->player
, SIGNAL( finished() ), this, SLOT( finished() ) );
202 connect( d
->playPauseAction
, SIGNAL( triggered() ), this, SLOT( playOrPause() ) );
204 d
->geom
= movieann
->transformedBoundingRectangle();
207 VideoWidget::~VideoWidget()
212 void VideoWidget::setNormGeometry( const Okular::NormalizedRect
&rect
)
217 Okular::NormalizedRect
VideoWidget::normGeometry() const
222 void VideoWidget::play()
226 d
->stopAction
->setEnabled( true );
227 d
->setupPlayPauseAction( Private::PauseMode
);
230 void VideoWidget::stop()
233 d
->stopAction
->setEnabled( false );
234 d
->setupPlayPauseAction( Private::PlayMode
);
237 void VideoWidget::pause()
240 d
->setupPlayPauseAction( Private::PlayMode
);
243 bool VideoWidget::eventFilter( QObject
* object
, QEvent
* event
)
245 if ( object
== d
->player
)
247 switch ( event
->type() )
249 case QEvent::MouseButtonPress
:
251 QMouseEvent
* me
= static_cast< QMouseEvent
* >( event
);
252 if ( me
->button() == Qt::LeftButton
)
254 if ( !d
->player
->isPlaying() )
268 bool VideoWidget::event( QEvent
* event
)
270 switch ( event
->type() )
272 case QEvent::ToolTip
:
273 // "eat" the help events (= tooltips), avoid parent widgets receiving them
280 return QWidget::event( event
);
283 void VideoWidget::resizeEvent( QResizeEvent
* event
)
285 const QSize
&s
= event
->size();
286 int usedSpace
= d
->seekSlider
->geometry().left() + d
->seekSlider
->iconSize().width();
287 // try to give the slider at least 30px of space
288 if ( s
.width() < ( usedSpace
+ 30 ) )
290 d
->seekSliderAction
->setVisible( false );
291 d
->seekSliderMenuAction
->setVisible( true );
295 d
->seekSliderAction
->setVisible( true );
296 d
->seekSliderMenuAction
->setVisible( false );
300 #include "videowidget.moc"