2004-12-17 17:14:46 +00:00
/***************************************************************************
* Copyright ( C ) 2004 by Enrico Ros < eros . kde @ email . it > *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-19 18:30:20 +00:00
# include "presentationwidget.h"
2004-12-17 17:14:46 +00:00
// qt/kde includes
2006-03-24 19:35:20 +00:00
# include <qevent.h>
2006-06-29 18:12:12 +00:00
# include <qfontmetrics.h>
2006-04-05 20:52:41 +00:00
# include <kicon.h>
2004-12-17 17:14:46 +00:00
# include <qtimer.h>
# include <qimage.h>
2007-04-15 11:10:21 +00:00
# include <qlabel.h>
2006-06-29 18:12:12 +00:00
# include <qlineedit.h>
2004-12-17 17:14:46 +00:00
# include <qpainter.h>
2005-07-18 17:51:27 +00:00
# include <qtooltip.h>
2006-06-29 18:12:12 +00:00
# include <qvalidator.h>
2004-12-17 17:14:46 +00:00
# include <qapplication.h>
# include <qdesktopwidget.h>
2004-12-31 15:34:08 +00:00
# include <kcursor.h>
2006-03-24 19:35:20 +00:00
# include <krandom.h>
2006-04-01 22:54:26 +00:00
# include <qtoolbar.h>
2006-06-25 16:34:11 +00:00
# include <kaction.h>
# include <kactioncollection.h>
2007-01-03 00:17:31 +00:00
# include <kglobalsettings.h>
2004-12-17 17:14:46 +00:00
# include <klocale.h>
# include <kiconloader.h>
2005-06-13 16:55:57 +00:00
# include <kmessagebox.h>
2006-06-25 16:34:11 +00:00
# include <kshortcut.h>
2006-12-12 10:15:18 +00:00
# include <kdialog.h>
2004-12-17 17:14:46 +00:00
// system includes
# include <stdlib.h>
2005-01-03 15:51:05 +00:00
# include <math.h>
2004-12-17 17:14:46 +00:00
// local includes
2006-11-01 15:34:27 +00:00
# include "annotationtools.h"
2005-01-27 17:31:07 +00:00
# include "pagepainter.h"
2007-03-17 22:58:41 +00:00
# include "presentationsearchbar.h"
2007-04-20 11:26:05 +00:00
# include "core/action.h"
2007-02-05 15:27:11 +00:00
# include "core/audioplayer.h"
2007-01-03 14:30:48 +00:00
# include "core/document.h"
2005-01-02 14:37:49 +00:00
# include "core/generator.h"
# include "core/page.h"
2006-03-28 22:22:10 +00:00
# include "settings.h"
2004-12-17 17:14:46 +00:00
// comment this to disable the top-right progress indicator
# define ENABLE_PROGRESS_OVERLAY
// a frame contains a pointer to the page object, its geometry and the
// transition effect to the next frame
struct PresentationFrame
{
2006-09-21 08:45:36 +00:00
const Okular : : Page * page ;
2004-12-17 17:14:46 +00:00
QRect geometry ;
} ;
2006-11-05 17:25:46 +00:00
// a custom QToolBar that basically does not propagate the event if the widget
// background is not automatically filled
class PresentationToolBar : public QToolBar
{
public :
PresentationToolBar ( QWidget * parent = 0 )
: QToolBar ( parent )
{ }
protected :
void mousePressEvent ( QMouseEvent * e )
{
QToolBar : : mousePressEvent ( e ) ;
e - > accept ( ) ;
}
void mouseReleaseEvent ( QMouseEvent * e )
{
QToolBar : : mouseReleaseEvent ( e ) ;
e - > accept ( ) ;
}
} ;
2006-09-21 08:45:36 +00:00
PresentationWidget : : PresentationWidget ( QWidget * parent , Okular : : Document * doc )
2006-04-03 22:23:39 +00:00
: QDialog ( parent , Qt : : FramelessWindowHint ) ,
2006-11-01 15:34:27 +00:00
m_pressedLink ( 0 ) , m_handCursor ( false ) , m_drawingEngine ( 0 ) , m_document ( doc ) ,
2007-03-17 22:58:41 +00:00
m_frameIndex ( - 1 ) , m_topBar ( 0 ) , m_pagesEdit ( 0 ) , m_searchBar ( 0 )
2004-12-17 17:14:46 +00:00
{
2006-04-03 22:23:39 +00:00
setModal ( true ) ;
setAttribute ( Qt : : WA_DeleteOnClose ) ;
setAttribute ( Qt : : WA_OpaquePaintEvent ) ;
setObjectName ( " presentationWidget " ) ;
2007-01-02 22:37:55 +00:00
QString caption = doc - > metaData ( " DocumentTitle " ) . toString ( ) ;
2006-10-21 23:21:11 +00:00
if ( caption . trimmed ( ) . isEmpty ( ) )
caption = doc - > currentDocument ( ) . fileName ( ) ;
2006-12-12 10:15:18 +00:00
setWindowTitle ( KDialog : : makeStandardCaption ( caption ) ) ;
2005-03-05 15:59:15 +00:00
m_width = - 1 ;
// show widget and take control
showFullScreen ( ) ;
2004-12-17 17:14:46 +00:00
// misc stuff
setMouseTracking ( true ) ;
2006-11-01 15:37:57 +00:00
setContextMenuPolicy ( Qt : : PreventContextMenu ) ;
2004-12-17 17:14:46 +00:00
m_transitionTimer = new QTimer ( this ) ;
2006-05-27 17:30:53 +00:00
m_transitionTimer - > setSingleShot ( true ) ;
2004-12-17 17:14:46 +00:00
connect ( m_transitionTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotTransitionStep ( ) ) ) ;
m_overlayHideTimer = new QTimer ( this ) ;
2006-05-27 17:30:53 +00:00
m_overlayHideTimer - > setSingleShot ( true ) ;
2004-12-17 17:14:46 +00:00
connect ( m_overlayHideTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotHideOverlay ( ) ) ) ;
2006-11-27 20:17:11 +00:00
m_nextPageTimer = new QTimer ( this ) ;
2007-04-21 00:02:12 +00:00
m_nextPageTimer - > setSingleShot ( true ) ;
2006-11-27 20:17:11 +00:00
connect ( m_nextPageTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotNextPage ( ) ) ) ;
2004-12-17 17:14:46 +00:00
2005-02-12 17:42:54 +00:00
// handle cursor appearance as specified in configuration
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : HiddenDelay )
2005-01-03 23:31:40 +00:00
{
KCursor : : setAutoHideCursor ( this , true ) ;
KCursor : : setHideCursorDelay ( 3000 ) ;
}
2006-09-21 08:45:36 +00:00
else if ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : Hidden )
2005-01-03 23:31:40 +00:00
{
2007-04-02 21:12:19 +00:00
setCursor ( QCursor ( Qt : : BlankCursor ) ) ;
2005-01-03 23:31:40 +00:00
}
2006-05-13 16:50:53 +00:00
QTimer : : singleShot ( 0 , this , SLOT ( slotDelayedEvents ( ) ) ) ;
2004-12-17 17:14:46 +00:00
}
PresentationWidget : : ~ PresentationWidget ( )
{
2007-02-05 15:27:11 +00:00
// stop the audio playbacks
Okular : : AudioPlayer : : instance ( ) - > stopPlaybacks ( ) ;
2007-03-17 22:58:41 +00:00
// remove our highlights
if ( m_searchBar )
{
m_document - > resetSearch ( PRESENTATION_SEARCH_ID ) ;
}
2004-12-17 17:14:46 +00:00
// remove this widget from document observer
m_document - > removeObserver ( this ) ;
2006-11-01 15:34:27 +00:00
m_document - > removePageAnnotations ( m_document - > viewport ( ) . pageNumber , m_currentPageDrawings ) ;
delete m_drawingEngine ;
2004-12-17 17:14:46 +00:00
// delete frames
2006-03-24 19:35:20 +00:00
QVector < PresentationFrame * > : : iterator fIt = m_frames . begin ( ) , fEnd = m_frames . end ( ) ;
2004-12-17 17:14:46 +00:00
for ( ; fIt ! = fEnd ; + + fIt )
delete * fIt ;
}
2006-09-21 08:45:36 +00:00
void PresentationWidget : : notifySetup ( const QVector < Okular : : Page * > & pageSet , bool /*documentChanged*/ )
2004-12-17 17:14:46 +00:00
{
// delete previous frames (if any (shouldn't be))
2006-03-24 19:35:20 +00:00
QVector < PresentationFrame * > : : iterator fIt = m_frames . begin ( ) , fEnd = m_frames . end ( ) ;
2004-12-17 17:14:46 +00:00
for ( ; fIt ! = fEnd ; + + fIt )
delete * fIt ;
if ( ! m_frames . isEmpty ( ) )
2006-03-29 13:52:17 +00:00
kWarning ( ) < < " Frames setup changed while a Presentation is in progress. " < < endl ;
2004-12-17 17:14:46 +00:00
m_frames . clear ( ) ;
// create the new frames
2006-09-21 08:45:36 +00:00
QVector < Okular : : Page * > : : const_iterator setIt = pageSet . begin ( ) , setEnd = pageSet . end ( ) ;
2004-12-17 17:14:46 +00:00
float screenRatio = ( float ) m_height / ( float ) m_width ;
for ( ; setIt ! = setEnd ; + + setIt )
{
PresentationFrame * frame = new PresentationFrame ( ) ;
frame - > page = * setIt ;
// calculate frame geometry keeping constant aspect ratio
float pageRatio = frame - > page - > ratio ( ) ;
int pageWidth = m_width ,
pageHeight = m_height ;
if ( pageRatio > screenRatio )
pageWidth = ( int ) ( ( float ) pageHeight / pageRatio ) ;
else
pageHeight = ( int ) ( ( float ) pageWidth * pageRatio ) ;
frame - > geometry . setRect ( ( m_width - pageWidth ) / 2 ,
( m_height - pageHeight ) / 2 ,
pageWidth , pageHeight ) ;
// add the frame to the vector
m_frames . push_back ( frame ) ;
}
// get metadata from the document
m_metaStrings . clear ( ) ;
2006-09-21 08:45:36 +00:00
const Okular : : DocumentInfo * info = m_document - > documentInfo ( ) ;
2004-12-17 17:14:46 +00:00
if ( info )
{
2005-01-02 22:37:52 +00:00
if ( ! info - > get ( " title " ) . isNull ( ) )
2006-04-10 19:50:00 +00:00
m_metaStrings + = i18n ( " Title: %1 " , info - > get ( " title " ) ) ;
2005-01-02 22:37:52 +00:00
if ( ! info - > get ( " author " ) . isNull ( ) )
2006-04-10 19:50:00 +00:00
m_metaStrings + = i18n ( " Author: %1 " , info - > get ( " author " ) ) ;
2004-12-17 17:14:46 +00:00
}
2006-04-10 19:50:00 +00:00
m_metaStrings + = i18n ( " Pages: %1 " , m_document - > pages ( ) ) ;
2004-12-17 17:14:46 +00:00
m_metaStrings + = i18n ( " Click to begin " ) ;
}
2005-02-01 18:23:55 +00:00
void PresentationWidget : : notifyViewportChanged ( bool /*smoothMove*/ )
2005-01-28 11:28:18 +00:00
{
2005-02-12 17:42:54 +00:00
// discard notifications if displaying the summary
2006-09-21 08:45:36 +00:00
if ( m_frameIndex = = - 1 & & Okular : : Settings : : slidesShowSummary ( ) )
2005-02-12 17:42:54 +00:00
return ;
// display the current page
changePage ( m_document - > viewport ( ) . pageNumber ) ;
// auto advance to the next page if set
2006-12-31 10:48:49 +00:00
startAutoChangeTimer ( ) ;
2005-01-28 11:28:18 +00:00
}
2005-01-09 23:37:07 +00:00
void PresentationWidget : : notifyPageChanged ( int pageNumber , int changedFlags )
2004-12-22 18:21:36 +00:00
{
2005-01-09 23:37:07 +00:00
// check if it's the last requested pixmap. if so update the widget.
2007-03-17 23:28:05 +00:00
if ( ( changedFlags & ( DocumentObserver : : Pixmap | DocumentObserver : : Annotations | DocumentObserver : : Highlights ) ) & & pageNumber = = m_frameIndex )
2006-11-01 15:34:27 +00:00
generatePage ( changedFlags & DocumentObserver : : Annotations ) ;
2004-12-22 18:21:36 +00:00
}
2006-11-20 20:10:42 +00:00
bool PresentationWidget : : canUnloadPixmap ( int pageNumber ) const
2004-12-17 17:14:46 +00:00
{
2005-01-09 23:37:07 +00:00
// can unload all pixmaps except for the currently visible one
return pageNumber ! = m_frameIndex ;
2004-12-17 17:14:46 +00:00
}
2006-06-25 16:34:11 +00:00
void PresentationWidget : : setupActions ( KActionCollection * collection )
{
m_ac = collection ;
}
2004-12-17 17:14:46 +00:00
// <widget events>
2006-06-16 17:04:21 +00:00
bool PresentationWidget : : event ( QEvent * e )
{
if ( e - > type ( ) = = QEvent : : ToolTip )
{
QHelpEvent * he = ( QHelpEvent * ) e ;
2006-09-27 10:28:03 +00:00
QRect r ;
2007-04-20 12:37:12 +00:00
const Okular : : Action * link = getLink ( he - > x ( ) , he - > y ( ) , & r ) ;
2006-06-16 17:04:21 +00:00
if ( link )
{
2007-04-20 12:37:12 +00:00
QString tip = link - > actionTip ( ) ;
2006-06-16 17:04:21 +00:00
if ( ! tip . isEmpty ( ) )
2006-09-27 10:28:03 +00:00
QToolTip : : showText ( he - > globalPos ( ) , tip , this , r ) ;
2006-06-16 17:04:21 +00:00
}
e - > accept ( ) ;
return true ;
}
else
// do not stop the event
return QDialog : : event ( e ) ;
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : keyPressEvent ( QKeyEvent * e )
{
2005-03-05 15:59:15 +00:00
if ( m_width = = - 1 ) return ;
2005-06-13 16:47:01 +00:00
2007-01-06 01:08:05 +00:00
# ifdef __GNUC__
2006-12-05 20:29:20 +00:00
# warning FIX the usage of KActionCollection actions
# endif
if ( /*e->key() == m_ac->action( "previous_page" )->shortcut().keyQt() || */ e - > key ( ) = = Qt : : Key_Left | | e - > key ( ) = = Qt : : Key_Backspace | | e - > key ( ) = = Qt : : Key_PageUp )
2004-12-17 17:14:46 +00:00
slotPrevPage ( ) ;
2006-12-05 20:29:20 +00:00
else if ( /*e->key() == m_ac->action( "next_page" )->shortcut().keyQt() || */ e - > key ( ) = = Qt : : Key_Right | | e - > key ( ) = = Qt : : Key_Space | | e - > key ( ) = = Qt : : Key_PageDown )
2004-12-17 17:14:46 +00:00
slotNextPage ( ) ;
2006-12-05 20:29:20 +00:00
else if ( /*e->key() == m_ac->action( "first_page" )->shortcut().keyQt() || */ e - > key ( ) = = Qt : : Key_Home )
2005-06-13 16:47:01 +00:00
slotFirstPage ( ) ;
2006-12-05 20:29:20 +00:00
else if ( /*e->key() == m_ac->action( "last_page" )->shortcut().keyQt() || */ e - > key ( ) = = Qt : : Key_End )
2005-06-13 16:47:01 +00:00
slotLastPage ( ) ;
2006-03-24 19:35:20 +00:00
else if ( e - > key ( ) = = Qt : : Key_Escape )
2004-12-17 17:14:46 +00:00
{
2006-05-19 12:11:25 +00:00
if ( ! m_topBar - > isHidden ( ) )
2004-12-17 17:14:46 +00:00
m_topBar - > hide ( ) ;
else
close ( ) ;
}
}
void PresentationWidget : : wheelEvent ( QWheelEvent * e )
{
// performance note: don't remove the clipping
int div = e - > delta ( ) / 120 ;
if ( div > 0 )
{
if ( div > 3 )
div = 3 ;
while ( div - - )
2006-11-05 17:29:07 +00:00
slotNextPage ( ) ;
2004-12-17 17:14:46 +00:00
}
else if ( div < 0 )
{
if ( div < - 3 )
div = - 3 ;
while ( div + + )
2006-11-05 17:29:07 +00:00
slotPrevPage ( ) ;
2004-12-17 17:14:46 +00:00
}
}
void PresentationWidget : : mousePressEvent ( QMouseEvent * e )
{
2006-11-01 15:34:27 +00:00
if ( m_drawingEngine )
{
QRect r = routeMouseDrawingEvent ( e ) ;
if ( r . isValid ( ) )
{
m_drawingRect | = r . translated ( m_frames [ m_frameIndex ] - > geometry . topLeft ( ) ) ;
update ( m_drawingRect ) ;
}
return ;
}
2005-01-03 15:51:05 +00:00
// pressing left button
2004-12-17 17:14:46 +00:00
if ( e - > button ( ) = = Qt : : LeftButton )
2005-01-03 15:51:05 +00:00
{
2005-07-18 17:51:27 +00:00
// if pressing on a link, skip other checks
if ( ( m_pressedLink = getLink ( e - > x ( ) , e - > y ( ) ) ) )
return ;
// handle clicking on top-right overlay
2005-01-03 15:51:05 +00:00
if ( m_overlayGeometry . contains ( e - > pos ( ) ) )
2005-07-18 17:51:27 +00:00
{
2005-01-03 15:51:05 +00:00
overlayClick ( e - > pos ( ) ) ;
2005-07-18 17:51:27 +00:00
return ;
}
// if no other actions, go to next page
slotNextPage ( ) ;
2005-01-03 15:51:05 +00:00
}
// pressing right button
2004-12-17 17:14:46 +00:00
else if ( e - > button ( ) = = Qt : : RightButton )
slotPrevPage ( ) ;
}
2005-07-18 17:51:27 +00:00
void PresentationWidget : : mouseReleaseEvent ( QMouseEvent * e )
{
2006-11-01 15:34:27 +00:00
if ( m_drawingEngine )
{
QRect r = routeMouseDrawingEvent ( e ) ;
( void ) r ;
if ( m_drawingEngine - > creationCompleted ( ) )
{
QList < Okular : : Annotation * > annots = m_drawingEngine - > end ( ) ;
// manually disable and re-enable the pencil mode, so we can do
// cleaning of the actual drawer and create a new one just after
// that - that gives continuous drawing
togglePencilMode ( false ) ;
togglePencilMode ( true ) ;
foreach ( Okular : : Annotation * ann , annots )
m_document - > addPageAnnotation ( m_frameIndex , ann ) ;
m_currentPageDrawings < < annots ;
}
return ;
}
2005-07-18 17:51:27 +00:00
// if releasing on the same link we pressed over, execute it
if ( m_pressedLink & & e - > button ( ) = = Qt : : LeftButton )
{
2007-04-20 12:37:12 +00:00
const Okular : : Action * link = getLink ( e - > x ( ) , e - > y ( ) ) ;
2005-07-18 17:51:27 +00:00
if ( link = = m_pressedLink )
2007-04-20 12:49:17 +00:00
m_document - > processAction ( link ) ;
2005-07-18 17:51:27 +00:00
m_pressedLink = 0 ;
}
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : mouseMoveEvent ( QMouseEvent * e )
{
2005-07-18 17:51:27 +00:00
// safety check
if ( m_width = = - 1 )
return ;
// update cursor and tooltip if hovering a link
2006-11-01 15:34:27 +00:00
if ( ! m_drawingEngine & & Okular : : Settings : : slidesCursor ( ) ! = Okular : : Settings : : EnumSlidesCursor : : Hidden )
2005-07-18 17:51:27 +00:00
testCursorOnLink ( e - > x ( ) , e - > y ( ) ) ;
2006-05-19 12:11:25 +00:00
if ( ! m_topBar - > isHidden ( ) )
2004-12-17 17:14:46 +00:00
{
2005-07-18 17:51:27 +00:00
// hide a shown bar when exiting the area
2004-12-17 17:14:46 +00:00
if ( e - > y ( ) > ( m_topBar - > height ( ) + 1 ) )
2006-06-29 18:12:12 +00:00
{
2004-12-17 17:14:46 +00:00
m_topBar - > hide ( ) ;
2006-06-29 18:12:12 +00:00
setFocus ( Qt : : OtherFocusReason ) ;
}
2004-12-17 17:14:46 +00:00
}
2005-07-18 17:51:27 +00:00
else
{
2006-11-01 15:34:27 +00:00
if ( m_drawingEngine & & e - > buttons ( ) ! = Qt : : NoButton )
{
QRect r = routeMouseDrawingEvent ( e ) ;
{
m_drawingRect | = r . translated ( m_frames [ m_frameIndex ] - > geometry . topLeft ( ) ) ;
update ( m_drawingRect ) ;
}
}
else
{
// show the bar if reaching top 2 pixels
if ( e - > y ( ) < = ( geometry ( ) . top ( ) + 1 ) )
m_topBar - > show ( ) ;
// handle "dragging the wheel" if clicking on its geometry
else if ( ( QApplication : : mouseButtons ( ) & Qt : : LeftButton ) & & m_overlayGeometry . contains ( e - > pos ( ) ) )
overlayClick ( e - > pos ( ) ) ;
}
2005-07-18 17:51:27 +00:00
}
2004-12-17 17:14:46 +00:00
}
void PresentationWidget : : paintEvent ( QPaintEvent * pe )
{
2005-03-05 15:59:15 +00:00
if ( m_width = = - 1 )
{
QRect d = KGlobalSettings : : desktopGeometry ( this ) ;
m_width = d . width ( ) ;
m_height = d . height ( ) ;
// create top toolbar
2006-11-05 17:25:46 +00:00
m_topBar = new PresentationToolBar ( this ) ;
2006-04-01 22:54:26 +00:00
m_topBar - > setObjectName ( " presentationBar " ) ;
m_topBar - > setIconSize ( QSize ( 32 , 32 ) ) ;
2007-03-17 14:58:19 +00:00
m_topBar - > setMovable ( false ) ;
2007-03-08 21:41:46 +00:00
m_topBar - > addAction ( KIcon ( layoutDirection ( ) = = Qt : : RightToLeft ? " arrow-right " : " arrow-left " ) , i18n ( " Previous Page " ) , this , SLOT ( slotPrevPage ( ) ) ) ;
2006-06-29 18:12:12 +00:00
m_pagesEdit = new QLineEdit ( m_topBar ) ;
QSizePolicy sp = m_pagesEdit - > sizePolicy ( ) ;
sp . setHorizontalPolicy ( QSizePolicy : : Minimum ) ;
m_pagesEdit - > setSizePolicy ( sp ) ;
QFontMetrics fm ( m_pagesEdit - > font ( ) ) ;
2006-11-02 21:57:59 +00:00
m_pagesEdit - > setMaximumWidth ( fm . width ( QString : : number ( m_document - > pages ( ) ) ) * 2 ) ;
2006-06-29 18:12:12 +00:00
QIntValidator * validator = new QIntValidator ( 1 , m_document - > pages ( ) , m_pagesEdit ) ;
m_pagesEdit - > setValidator ( validator ) ;
m_topBar - > addWidget ( m_pagesEdit ) ;
2007-04-15 11:10:21 +00:00
QLabel * pagesLabel = new QLabel ( m_topBar ) ;
pagesLabel - > setText ( QLatin1String ( " / " ) + QString : : number ( m_document - > pages ( ) ) + QLatin1String ( " " ) ) ;
m_topBar - > addWidget ( pagesLabel ) ;
2006-06-29 18:12:12 +00:00
connect ( m_pagesEdit , SIGNAL ( returnPressed ( ) ) , this , SLOT ( slotPageChanged ( ) ) ) ;
2007-03-08 21:41:46 +00:00
m_topBar - > addAction ( KIcon ( layoutDirection ( ) = = Qt : : RightToLeft ? " arrow-left " : " arrow-right " ) , i18n ( " Next Page " ) , this , SLOT ( slotNextPage ( ) ) ) ;
2006-11-01 15:34:27 +00:00
m_topBar - > addSeparator ( ) ;
QAction * drawingAct = m_topBar - > addAction ( KIcon ( " pencil " ) , i18n ( " Toggle Drawing Mode " ) ) ;
drawingAct - > setCheckable ( true ) ;
connect ( drawingAct , SIGNAL ( toggled ( bool ) ) , this , SLOT ( togglePencilMode ( bool ) ) ) ;
QAction * eraseDrawingAct = m_topBar - > addAction ( KIcon ( " eraser " ) , i18n ( " Erase Drawings " ) ) ;
connect ( eraseDrawingAct , SIGNAL ( triggered ( ) ) , this , SLOT ( clearDrawings ( ) ) ) ;
2006-03-24 19:35:20 +00:00
QWidget * spacer = new QWidget ( m_topBar ) ;
2006-06-29 18:12:12 +00:00
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : MinimumExpanding ) ;
2006-03-24 19:35:20 +00:00
m_topBar - > addWidget ( spacer ) ;
2007-03-08 21:41:46 +00:00
m_topBar - > addAction ( KIcon ( " application-exit " ) , i18n ( " Exit Presentation Mode " ) , this , SLOT ( close ( ) ) ) ;
2005-03-05 15:59:15 +00:00
m_topBar - > setGeometry ( 0 , 0 , m_width , 32 + 10 ) ;
2007-03-27 20:36:24 +00:00
m_topBar - > setAutoFillBackground ( true ) ;
2005-03-05 15:59:15 +00:00
m_topBar - > hide ( ) ;
// change topbar background color
QPalette p = m_topBar - > palette ( ) ;
2006-06-03 13:01:15 +00:00
p . setColor ( QPalette : : Active , QPalette : : Button , Qt : : gray ) ;
p . setColor ( QPalette : : Active , QPalette : : Background , Qt : : darkGray ) ;
2005-03-05 15:59:15 +00:00
m_topBar - > setPalette ( p ) ;
2007-03-17 22:58:41 +00:00
connect ( m_document , SIGNAL ( linkFind ( ) ) , this , SLOT ( slotFind ( ) ) ) ;
2005-03-05 15:59:15 +00:00
// register this observer in document. events will come immediately
m_document - > addObserver ( this ) ;
// show summary if requested
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesShowSummary ( ) )
2005-03-05 15:59:15 +00:00
generatePage ( ) ;
}
2004-12-17 17:14:46 +00:00
// check painting rect consistancy
QRect r = pe - > rect ( ) . intersect ( geometry ( ) ) ;
if ( r . isNull ( ) | | m_lastRenderedPixmap . isNull ( ) )
return ;
// blit the pixmap to the screen
2006-03-24 19:35:20 +00:00
QVector < QRect > allRects = pe - > region ( ) . rects ( ) ;
2004-12-17 17:14:46 +00:00
uint numRects = allRects . count ( ) ;
2006-06-30 18:36:41 +00:00
QPainter painter ( this ) ;
2004-12-17 17:14:46 +00:00
for ( uint i = 0 ; i < numRects ; i + + )
{
const QRect & r = allRects [ i ] ;
2005-01-08 00:12:08 +00:00
if ( ! r . isValid ( ) )
continue ;
2004-12-17 17:14:46 +00:00
# ifdef ENABLE_PROGRESS_OVERLAY
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesShowProgress ( ) & & r . intersects ( m_overlayGeometry ) )
2004-12-17 17:14:46 +00:00
{
// backbuffer the overlay operation
QPixmap backPixmap ( r . size ( ) ) ;
QPainter pixPainter ( & backPixmap ) ;
// first draw the background on the backbuffer
pixPainter . drawPixmap ( QPoint ( 0 , 0 ) , m_lastRenderedPixmap , r ) ;
// then blend the overlay (a piece of) over the background
QRect ovr = m_overlayGeometry . intersect ( r ) ;
pixPainter . drawPixmap ( ovr . left ( ) - r . left ( ) , ovr . top ( ) - r . top ( ) ,
m_lastRenderedOverlay , ovr . left ( ) - m_overlayGeometry . left ( ) ,
ovr . top ( ) - m_overlayGeometry . top ( ) , ovr . width ( ) , ovr . height ( ) ) ;
// finally blit the pixmap to the screen
pixPainter . end ( ) ;
2006-06-30 18:36:41 +00:00
painter . drawPixmap ( r . topLeft ( ) , backPixmap , backPixmap . rect ( ) ) ;
2004-12-17 17:14:46 +00:00
} else
# endif
// copy the rendered pixmap to the screen
2006-06-30 18:36:41 +00:00
painter . drawPixmap ( r . topLeft ( ) , m_lastRenderedPixmap , r ) ;
2004-12-17 17:14:46 +00:00
}
2006-11-01 15:34:27 +00:00
if ( m_drawingEngine & & m_drawingRect . intersects ( pe - > rect ( ) ) )
{
const QRect & geom = m_frames [ m_frameIndex ] - > geometry ;
painter . save ( ) ;
painter . translate ( geom . topLeft ( ) ) ;
m_drawingEngine - > paint ( & painter , geom . width ( ) , geom . height ( ) , m_drawingRect . intersect ( pe - > rect ( ) ) ) ;
painter . restore ( ) ;
}
2006-06-30 18:36:41 +00:00
painter . end ( ) ;
2004-12-17 17:14:46 +00:00
}
// </widget events>
2007-04-20 12:37:12 +00:00
const Okular : : Action * PresentationWidget : : getLink ( int x , int y , QRect * geometry ) const
2005-07-18 17:51:27 +00:00
{
// no links on invalid pages
if ( geometry & & ! geometry - > isNull ( ) )
2006-06-16 17:04:21 +00:00
geometry - > setRect ( 0 , 0 , 0 , 0 ) ;
2005-07-18 17:51:27 +00:00
if ( m_frameIndex < 0 | | m_frameIndex > = ( int ) m_frames . size ( ) )
return 0 ;
// get frame, page and geometry
const PresentationFrame * frame = m_frames [ m_frameIndex ] ;
2006-09-21 08:45:36 +00:00
const Okular : : Page * page = frame - > page ;
2005-07-18 17:51:27 +00:00
const QRect & frameGeometry = frame - > geometry ;
// compute normalized x and y
double nx = ( double ) ( x - frameGeometry . left ( ) ) / ( double ) frameGeometry . width ( ) ;
double ny = ( double ) ( y - frameGeometry . top ( ) ) / ( double ) frameGeometry . height ( ) ;
// no links outside the pages
if ( nx < 0 | | nx > 1 | | ny < 0 | | ny > 1 )
return 0 ;
// check if 1) there is an object and 2) it's a link
2006-09-19 17:17:29 +00:00
QRect d = KGlobalSettings : : desktopGeometry ( const_cast < PresentationWidget * > ( this ) ) ;
2007-04-20 12:37:12 +00:00
const Okular : : ObjectRect * object = page - > objectRect ( Okular : : ObjectRect : : Action , nx , ny , d . width ( ) , d . height ( ) ) ;
2005-07-18 17:51:27 +00:00
if ( ! object )
return 0 ;
// compute link geometry if destination rect present
if ( geometry )
{
2006-07-13 15:03:18 +00:00
* geometry = object - > boundingRect ( frameGeometry . width ( ) , frameGeometry . height ( ) ) ;
2006-03-29 17:16:46 +00:00
geometry - > translate ( frameGeometry . left ( ) , frameGeometry . top ( ) ) ;
2005-07-18 17:51:27 +00:00
}
// return the link pointer
2007-04-20 12:37:12 +00:00
return ( Okular : : Action * ) object - > object ( ) ;
2005-07-18 17:51:27 +00:00
}
void PresentationWidget : : testCursorOnLink ( int x , int y )
{
2007-04-20 12:37:12 +00:00
const Okular : : Action * link = getLink ( x , y , 0 ) ;
2005-07-18 17:51:27 +00:00
// only react on changes (in/out from a link)
if ( ( link & & ! m_handCursor ) | | ( ! link & & m_handCursor ) )
{
// change cursor shape
m_handCursor = link ! = 0 ;
2007-04-02 21:12:19 +00:00
setCursor ( QCursor ( m_handCursor ? Qt : : PointingHandCursor : Qt : : ArrowCursor ) ) ;
2005-07-18 17:51:27 +00:00
}
}
2005-01-03 15:51:05 +00:00
void PresentationWidget : : overlayClick ( const QPoint & position )
{
// clicking the progress indicator
int xPos = position . x ( ) - m_overlayGeometry . x ( ) - m_overlayGeometry . width ( ) / 2 ,
yPos = m_overlayGeometry . height ( ) / 2 - position . y ( ) ;
if ( ! xPos & & ! yPos )
return ;
// compute angle relative to indicator (note coord transformation)
2007-03-18 17:14:36 +00:00
float angle = 0.5 + 0.5 * atan2 ( ( double ) - xPos , ( double ) - yPos ) / M_PI ;
2005-01-10 16:17:00 +00:00
int pageIndex = ( int ) ( angle * ( m_frames . count ( ) - 1 ) + 0.5 ) ;
2005-01-03 15:51:05 +00:00
// go to selected page
changePage ( pageIndex ) ;
}
void PresentationWidget : : changePage ( int newPage )
{
if ( m_frameIndex = = newPage )
return ;
// check if pixmap exists or else request it
m_frameIndex = newPage ;
PresentationFrame * frame = m_frames [ m_frameIndex ] ;
int pixW = frame - > geometry . width ( ) ;
int pixH = frame - > geometry . height ( ) ;
2006-06-29 18:12:12 +00:00
bool signalsBlocked = m_pagesEdit - > signalsBlocked ( ) ;
m_pagesEdit - > blockSignals ( true ) ;
m_pagesEdit - > setText ( QString : : number ( m_frameIndex + 1 ) ) ;
m_pagesEdit - > blockSignals ( signalsBlocked ) ;
2006-09-21 08:45:36 +00:00
// if pixmap not inside the Okular::Page we request it and wait for
2005-01-03 15:51:05 +00:00
// notifyPixmapChanged call or else we can proceed to pixmap generation
2006-11-20 07:53:32 +00:00
if ( ! frame - > page - > hasPixmap ( PRESENTATION_ID , pixW , pixH ) )
2005-01-03 15:51:05 +00:00
{
2005-07-18 17:51:27 +00:00
// operation will take long: set busy cursor
2007-04-02 21:12:19 +00:00
QApplication : : setOverrideCursor ( QCursor ( Qt : : BusyCursor ) ) ;
2005-07-18 17:51:27 +00:00
// request the pixmap
2007-01-04 00:02:48 +00:00
QLinkedList < Okular : : PixmapRequest * > requests ;
requests . push_back ( new Okular : : PixmapRequest ( PRESENTATION_ID , m_frameIndex , pixW , pixH , PRESENTATION_PRIO , false ) ) ;
2005-07-18 17:51:27 +00:00
// restore cursor
QApplication : : restoreOverrideCursor ( ) ;
2006-11-29 22:00:13 +00:00
// ask for next and previous page if not in low memory usage setting
if ( Okular : : Settings : : memoryLevel ( ) ! = Okular : : Settings : : EnumMemoryLevel : : Low & & Okular : : Settings : : enableThreading ( ) ) {
2007-01-04 00:02:48 +00:00
if ( newPage + 1 < ( int ) m_document - > pages ( ) )
{
PresentationFrame * nextFrame = m_frames [ newPage + 1 ] ;
pixW = nextFrame - > geometry . width ( ) ;
pixH = nextFrame - > geometry . height ( ) ;
if ( ! nextFrame - > page - > hasPixmap ( PRESENTATION_ID , pixW , pixH ) )
requests . push_back ( new Okular : : PixmapRequest ( PRESENTATION_ID , newPage + 1 , pixW , pixH , PRESENTATION_PRELOAD_PRIO , true ) ) ;
2006-11-29 22:00:13 +00:00
}
2007-01-04 14:28:54 +00:00
if ( newPage - 1 > = 0 )
{
PresentationFrame * prevFrame = m_frames [ newPage - 1 ] ;
pixW = prevFrame - > geometry . width ( ) ;
pixH = prevFrame - > geometry . height ( ) ;
if ( ! prevFrame - > page - > hasPixmap ( PRESENTATION_ID , pixW , pixH ) )
requests . push_back ( new Okular : : PixmapRequest ( PRESENTATION_ID , newPage - 1 , pixW , pixH , PRESENTATION_PRELOAD_PRIO , true ) ) ;
}
2006-11-29 22:00:13 +00:00
}
2007-01-04 00:02:48 +00:00
m_document - > requestPixmaps ( requests ) ;
2005-01-03 15:51:05 +00:00
}
else
2005-07-18 17:51:27 +00:00
{
// make the background pixmap
2005-01-03 15:51:05 +00:00
generatePage ( ) ;
2005-07-18 17:51:27 +00:00
}
2006-09-09 17:31:36 +00:00
// set a new viewport in document if page number differs
if ( m_frameIndex ! = - 1 & & m_frameIndex ! = m_document - > viewport ( ) . pageNumber )
2006-11-01 15:34:27 +00:00
{
2007-02-05 15:27:11 +00:00
// stop the audio playback, if any
Okular : : AudioPlayer : : instance ( ) - > stopPlaybacks ( ) ;
// perform the page closing action, if any
2007-02-05 00:49:40 +00:00
if ( m_document - > page ( m_document - > viewport ( ) . pageNumber ) - > pageAction ( Okular : : Page : : Closing ) )
2007-04-20 12:49:17 +00:00
m_document - > processAction ( m_document - > page ( m_document - > viewport ( ) . pageNumber ) - > pageAction ( Okular : : Page : : Closing ) ) ;
2007-02-05 00:49:40 +00:00
2006-11-01 15:34:27 +00:00
// remove the drawing on the old page before switching
clearDrawings ( ) ;
2006-09-09 17:31:36 +00:00
m_document - > setViewportPage ( m_frameIndex , PRESENTATION_ID ) ;
2007-02-05 00:49:40 +00:00
2007-02-05 15:27:11 +00:00
// perform the page opening action, if any
2007-02-05 00:49:40 +00:00
if ( m_document - > page ( m_frameIndex ) - > pageAction ( Okular : : Page : : Opening ) )
2007-04-20 12:49:17 +00:00
m_document - > processAction ( m_document - > page ( m_frameIndex ) - > pageAction ( Okular : : Page : : Opening ) ) ;
2007-02-05 00:49:40 +00:00
2006-11-01 15:34:27 +00:00
}
2005-01-03 15:51:05 +00:00
}
2006-11-01 15:34:27 +00:00
void PresentationWidget : : generatePage ( bool disableTransition )
2004-12-17 17:14:46 +00:00
{
if ( m_lastRenderedPixmap . isNull ( ) )
2006-06-28 11:49:01 +00:00
m_lastRenderedPixmap = QPixmap ( m_width , m_height ) ;
2004-12-17 17:14:46 +00:00
// opens the painter over the pixmap
QPainter pixmapPainter ;
pixmapPainter . begin ( & m_lastRenderedPixmap ) ;
// generate welcome page
if ( m_frameIndex = = - 1 )
generateIntroPage ( pixmapPainter ) ;
// generate a normal pixmap with extended margin filling
if ( m_frameIndex > = 0 & & m_frameIndex < ( int ) m_document - > pages ( ) )
generateContentsPage ( m_frameIndex , pixmapPainter ) ;
pixmapPainter . end ( ) ;
// generate the top-right corner overlay
# ifdef ENABLE_PROGRESS_OVERLAY
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesShowProgress ( ) & & m_frameIndex ! = - 1 )
2004-12-17 17:14:46 +00:00
generateOverlay ( ) ;
# endif
2005-01-02 22:25:49 +00:00
// start transition on pages that have one
2006-11-01 15:34:27 +00:00
if ( ! disableTransition )
{
const Okular : : PageTransition * transition = m_frameIndex ! = - 1 ?
2006-11-23 17:11:04 +00:00
m_frames [ m_frameIndex ] - > page - > transition ( ) : 0 ;
2006-11-01 15:34:27 +00:00
if ( transition )
initTransition ( transition ) ;
else {
Okular : : PageTransition trans = defaultTransition ( ) ;
initTransition ( & trans ) ;
}
}
else
{
Okular : : PageTransition trans = defaultTransition ( Okular : : Settings : : EnumSlidesTransition : : Replace ) ;
2005-01-03 23:31:40 +00:00
initTransition ( & trans ) ;
}
2005-07-18 17:51:27 +00:00
// update cursor + tooltip
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesCursor ( ) ! = Okular : : Settings : : EnumSlidesCursor : : Hidden )
2005-07-18 17:51:27 +00:00
{
QPoint p = mapFromGlobal ( QCursor : : pos ( ) ) ;
testCursorOnLink ( p . x ( ) , p . y ( ) ) ;
}
2004-12-17 17:14:46 +00:00
}
void PresentationWidget : : generateIntroPage ( QPainter & p )
{
// use a vertical gray gradient background
int blend1 = m_height / 10 ,
blend2 = 9 * m_height / 10 ;
2006-03-24 19:35:20 +00:00
int baseTint = QColor ( Qt : : gray ) . red ( ) ;
2004-12-17 17:14:46 +00:00
for ( int i = 0 ; i < m_height ; i + + )
{
int k = baseTint ;
if ( i < blend1 )
k - = ( int ) ( baseTint * ( i - blend1 ) * ( i - blend1 ) / ( float ) ( blend1 * blend1 ) ) ;
if ( i > blend2 )
k + = ( int ) ( ( 255 - baseTint ) * ( i - blend2 ) * ( i - blend2 ) / ( float ) ( blend1 * blend1 ) ) ;
p . fillRect ( 0 , i , m_width , 1 , QColor ( k , k , k ) ) ;
}
2006-06-12 18:25:18 +00:00
// draw okular logo in the four corners
QPixmap logo = DesktopIcon ( " okular " , 64 ) ;
2004-12-17 17:14:46 +00:00
if ( ! logo . isNull ( ) )
{
p . drawPixmap ( 5 , 5 , logo ) ;
p . drawPixmap ( m_width - 5 - logo . width ( ) , 5 , logo ) ;
p . drawPixmap ( m_width - 5 - logo . width ( ) , m_height - 5 - logo . height ( ) , logo ) ;
p . drawPixmap ( 5 , m_height - 5 - logo . height ( ) , logo ) ;
}
// draw metadata text (the last line is 'click to begin')
int strNum = m_metaStrings . count ( ) ,
strHeight = m_height / ( strNum + 4 ) ,
fontHeight = 2 * strHeight / 3 ;
QFont font ( p . font ( ) ) ;
font . setPixelSize ( fontHeight ) ;
QFontMetrics metrics ( font ) ;
for ( int i = 0 ; i < strNum ; i + + )
{
// set a font to fit text width
float wScale = ( float ) metrics . boundingRect ( m_metaStrings [ i ] ) . width ( ) / ( float ) m_width ;
QFont f ( font ) ;
if ( wScale > 1.0 )
f . setPixelSize ( ( int ) ( ( float ) fontHeight / ( float ) wScale ) ) ;
p . setFont ( f ) ;
// text shadow
p . setPen ( Qt : : darkGray ) ;
p . drawText ( 2 , m_height / 4 + strHeight * i + 2 , m_width , strHeight ,
2006-03-24 19:35:20 +00:00
Qt : : AlignHCenter | Qt : : AlignVCenter , m_metaStrings [ i ] ) ;
2004-12-17 17:14:46 +00:00
// text body
p . setPen ( 128 + ( 127 * i ) / strNum ) ;
p . drawText ( 0 , m_height / 4 + strHeight * i , m_width , strHeight ,
2006-03-24 19:35:20 +00:00
Qt : : AlignHCenter | Qt : : AlignVCenter , m_metaStrings [ i ] ) ;
2004-12-17 17:14:46 +00:00
}
}
void PresentationWidget : : generateContentsPage ( int pageNum , QPainter & p )
{
PresentationFrame * frame = m_frames [ pageNum ] ;
// translate painter and contents rect
QRect geom ( frame - > geometry ) ;
p . translate ( geom . left ( ) , geom . top ( ) ) ;
2006-03-29 17:16:46 +00:00
geom . translate ( - geom . left ( ) , - geom . top ( ) ) ;
2004-12-17 17:14:46 +00:00
// draw the page using the shared PagePainter class
2007-03-17 23:28:05 +00:00
int flags = PagePainter : : Accessibility | PagePainter : : Highlights | PagePainter : : Annotations ;
2005-04-01 16:24:11 +00:00
PagePainter : : paintPageOnPainter ( & p , frame - > page , PRESENTATION_ID , flags ,
geom . width ( ) , geom . height ( ) , geom ) ;
2004-12-17 17:14:46 +00:00
// restore painter
p . translate ( - frame - > geometry . left ( ) , - frame - > geometry . top ( ) ) ;
// fill unpainted areas with background color
QRegion unpainted ( QRect ( 0 , 0 , m_width , m_height ) ) ;
2006-03-24 19:35:20 +00:00
QVector < QRect > rects = unpainted . subtract ( frame - > geometry ) . rects ( ) ;
for ( int i = 0 ; i < rects . count ( ) ; i + + )
2004-12-17 17:14:46 +00:00
{
const QRect & r = rects [ i ] ;
2006-09-21 08:45:36 +00:00
p . fillRect ( r , Okular : : Settings : : slidesBackgroundColor ( ) ) ;
2004-12-17 17:14:46 +00:00
}
}
2005-07-18 17:51:27 +00:00
// from Arthur - Qt4 - (is defined elsewhere as 'qt_div_255' to not break final compilation)
inline int qt_div255 ( int x ) { return ( x + ( x > > 8 ) + 0x80 ) > > 8 ; }
2004-12-17 17:14:46 +00:00
void PresentationWidget : : generateOverlay ( )
{
# ifdef ENABLE_PROGRESS_OVERLAY
// calculate overlay geometry and resize pixmap if needed
int side = m_width / 16 ;
2005-07-18 17:51:27 +00:00
m_overlayGeometry . setRect ( m_width - side - 4 , 4 , side , side ) ;
2004-12-17 17:14:46 +00:00
// note: to get a sort of antialiasing, we render the pixmap double sized
// and the resulting image is smoothly scaled down. So here we open a
// painter on the double sized pixmap.
side * = 2 ;
QPixmap doublePixmap ( side , side ) ;
doublePixmap . fill ( Qt : : black ) ;
QPainter pixmapPainter ( & doublePixmap ) ;
2007-03-18 10:21:21 +00:00
pixmapPainter . setRenderHints ( QPainter : : Antialiasing ) ;
2004-12-17 17:14:46 +00:00
// draw PIE SLICES in blue levels (the levels will then be the alpha component)
int pages = m_document - > pages ( ) ;
2005-07-18 17:51:27 +00:00
if ( pages > 28 )
2005-03-05 15:59:15 +00:00
{ // draw continuous slices
2004-12-17 17:14:46 +00:00
int degrees = ( int ) ( 360 * ( float ) ( m_frameIndex + 1 ) / ( float ) pages ) ;
2005-07-18 17:51:27 +00:00
pixmapPainter . setPen ( 0x05 ) ;
2006-05-13 16:50:53 +00:00
pixmapPainter . setBrush ( QColor ( 0x40 ) ) ;
2004-12-17 17:14:46 +00:00
pixmapPainter . drawPie ( 2 , 2 , side - 4 , side - 4 , 90 * 16 , ( 360 - degrees ) * 16 ) ;
2005-07-18 17:51:27 +00:00
pixmapPainter . setPen ( 0x40 ) ;
2006-05-13 16:50:53 +00:00
pixmapPainter . setBrush ( QColor ( 0xF0 ) ) ;
2004-12-17 17:14:46 +00:00
pixmapPainter . drawPie ( 2 , 2 , side - 4 , side - 4 , 90 * 16 , - degrees * 16 ) ;
}
else
{ // draw discrete slices
float oldCoord = - 90 ;
for ( int i = 0 ; i < pages ; i + + )
{
float newCoord = - 90 + 360 * ( float ) ( i + 1 ) / ( float ) pages ;
pixmapPainter . setPen ( i < = m_frameIndex ? 0x40 : 0x05 ) ;
2006-05-13 16:50:53 +00:00
pixmapPainter . setBrush ( QColor ( i < = m_frameIndex ? 0xF0 : 0x40 ) ) ;
2004-12-17 17:14:46 +00:00
pixmapPainter . drawPie ( 2 , 2 , side - 4 , side - 4 ,
( int ) ( - 16 * ( oldCoord + 1 ) ) , ( int ) ( - 16 * ( newCoord - ( oldCoord + 2 ) ) ) ) ;
oldCoord = newCoord ;
}
}
int circleOut = side / 4 ;
pixmapPainter . setPen ( Qt : : black ) ;
pixmapPainter . setBrush ( Qt : : black ) ;
pixmapPainter . drawEllipse ( circleOut , circleOut , side - 2 * circleOut , side - 2 * circleOut ) ;
// draw TEXT using maximum opacity
QFont f ( pixmapPainter . font ( ) ) ;
f . setPixelSize ( side / 4 ) ;
pixmapPainter . setFont ( f ) ;
pixmapPainter . setPen ( 0xFF ) ;
// use a little offset to prettify output
pixmapPainter . drawText ( 2 , 2 , side , side , Qt : : AlignCenter , QString : : number ( m_frameIndex + 1 ) ) ;
// end drawing pixmap and halve image
pixmapPainter . end ( ) ;
2006-04-05 17:49:44 +00:00
QImage image ( doublePixmap . toImage ( ) . scaled ( side / 2 , side / 2 , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ) ;
2006-06-25 15:50:35 +00:00
image = image . convertToFormat ( QImage : : Format_ARGB32 ) ;
2004-12-17 17:14:46 +00:00
2005-07-18 17:51:27 +00:00
// draw circular shadow using the same technique
doublePixmap . fill ( Qt : : black ) ;
pixmapPainter . begin ( & doublePixmap ) ;
pixmapPainter . setPen ( 0x40 ) ;
2006-05-13 16:50:53 +00:00
pixmapPainter . setBrush ( QColor ( 0x80 ) ) ;
2005-07-18 17:51:27 +00:00
pixmapPainter . drawEllipse ( 0 , 0 , side , side ) ;
pixmapPainter . end ( ) ;
2006-04-05 17:49:44 +00:00
QImage shadow ( doublePixmap . toImage ( ) . scaled ( side / 2 , side / 2 , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ) ;
2005-07-18 17:51:27 +00:00
// generate a 2 colors pixmap using mixing shadow (made with highlight color)
// and image (made with highlightedText color)
2006-05-27 17:30:53 +00:00
QPalette pal = palette ( ) ;
QColor color = pal . color ( QPalette : : Active , QPalette : : HighlightedText ) ;
2005-07-18 17:51:27 +00:00
int red = color . red ( ) , green = color . green ( ) , blue = color . blue ( ) ;
2006-05-27 17:30:53 +00:00
color = pal . color ( QPalette : : Active , QPalette : : Highlight ) ;
2005-07-18 17:51:27 +00:00
int sRed = color . red ( ) , sGreen = color . green ( ) , sBlue = color . blue ( ) ;
// pointers
unsigned int * data = ( unsigned int * ) image . bits ( ) ,
* shadowData = ( unsigned int * ) shadow . bits ( ) ,
pixels = image . width ( ) * image . height ( ) ;
// cache data (reduce computation time to 26%!)
int c1 = - 1 , c2 = - 1 , cR = 0 , cG = 0 , cB = 0 , cA = 0 ;
// foreach pixel
for ( unsigned int i = 0 ; i < pixels ; + + i )
{
// alpha for shadow and image
int shadowAlpha = shadowData [ i ] & 0xFF ,
srcAlpha = data [ i ] & 0xFF ;
// cache values
if ( srcAlpha ! = c1 | | shadowAlpha ! = c2 )
{
c1 = srcAlpha ;
c2 = shadowAlpha ;
// fuse color components and alpha value of image over shadow
data [ i ] = qRgba (
cR = qt_div255 ( srcAlpha * red + ( 255 - srcAlpha ) * sRed ) ,
cG = qt_div255 ( srcAlpha * green + ( 255 - srcAlpha ) * sGreen ) ,
cB = qt_div255 ( srcAlpha * blue + ( 255 - srcAlpha ) * sBlue ) ,
cA = qt_div255 ( srcAlpha * srcAlpha + ( 255 - srcAlpha ) * shadowAlpha )
) ;
}
else
data [ i ] = qRgba ( cR , cG , cB , cA ) ;
}
2006-04-13 14:51:05 +00:00
m_lastRenderedOverlay = QPixmap : : fromImage ( image ) ;
2004-12-17 17:14:46 +00:00
// start the autohide timer
2006-04-13 14:51:05 +00:00
repaint ( m_overlayGeometry ) ; // toggle with next line
2004-12-17 17:14:46 +00:00
//update( m_overlayGeometry );
2006-05-27 17:30:53 +00:00
m_overlayHideTimer - > start ( 2500 ) ;
2004-12-17 17:14:46 +00:00
# endif
}
2006-11-01 15:34:27 +00:00
QRect PresentationWidget : : routeMouseDrawingEvent ( QMouseEvent * e )
{
const QRect & geom = m_frames [ m_frameIndex ] - > geometry ;
const Okular : : Page * page = m_frames [ m_frameIndex ] - > page ;
AnnotatorEngine : : EventType eventType = AnnotatorEngine : : Press ;
if ( e - > type ( ) = = QEvent : : MouseMove )
eventType = AnnotatorEngine : : Move ;
else if ( e - > type ( ) = = QEvent : : MouseButtonRelease )
eventType = AnnotatorEngine : : Release ;
// find out the pressed button
AnnotatorEngine : : Button button = AnnotatorEngine : : None ;
Qt : : MouseButtons buttonState = ( eventType = = AnnotatorEngine : : Move ) ? e - > buttons ( ) : e - > button ( ) ;
if ( buttonState = = Qt : : LeftButton )
button = AnnotatorEngine : : Left ;
else if ( buttonState = = Qt : : RightButton )
button = AnnotatorEngine : : Right ;
static bool hasclicked = false ;
if ( eventType = = AnnotatorEngine : : Press )
hasclicked = true ;
double nX = ( ( double ) e - > x ( ) - ( double ) geom . left ( ) ) / ( double ) geom . width ( ) ;
double nY = ( ( double ) e - > y ( ) - ( double ) geom . top ( ) ) / ( double ) geom . height ( ) ;
QRect ret ;
if ( hasclicked & & nX > = 0 & & nX < 1 & & nY > = 0 & & nY < 1 )
ret = m_drawingEngine - > event ( eventType , button , nX , nY , geom . width ( ) , geom . height ( ) , page ) ;
if ( eventType = = AnnotatorEngine : : Release )
hasclicked = false ;
return ret ;
}
2006-12-31 10:48:49 +00:00
void PresentationWidget : : startAutoChangeTimer ( )
{
2006-12-31 14:41:34 +00:00
double pageDuration = m_frameIndex > = 0 & & m_frameIndex < ( int ) m_frames . count ( ) ? m_frames [ m_frameIndex ] - > page - > duration ( ) : - 1 ;
2007-04-21 00:02:12 +00:00
if ( Okular : : Settings : : slidesAdvance ( ) | | pageDuration > = 0.0 )
2006-12-31 10:48:49 +00:00
{
2007-04-21 00:02:12 +00:00
double secs = pageDuration < 0.0
2006-12-31 10:48:49 +00:00
? Okular : : Settings : : slidesAdvanceTime ( )
2006-12-31 14:41:34 +00:00
: qMin < double > ( pageDuration , Okular : : Settings : : slidesAdvanceTime ( ) ) ;
m_nextPageTimer - > start ( ( int ) ( secs * 1000 ) ) ;
2006-12-31 10:48:49 +00:00
}
}
2006-11-01 15:34:27 +00:00
2004-12-17 17:14:46 +00:00
void PresentationWidget : : slotNextPage ( )
{
2005-01-03 23:31:40 +00:00
// loop when configured
2006-09-21 08:45:36 +00:00
if ( m_frameIndex = = ( int ) m_frames . count ( ) - 1 & & Okular : : Settings : : slidesLoop ( ) )
2005-01-03 23:31:40 +00:00
m_frameIndex = - 1 ;
2004-12-17 17:14:46 +00:00
if ( m_frameIndex < ( int ) m_frames . count ( ) - 1 )
{
// go to next page
2005-01-03 15:51:05 +00:00
changePage ( m_frameIndex + 1 ) ;
2005-11-04 11:59:51 +00:00
// auto advance to the next page if set
2006-12-31 10:48:49 +00:00
startAutoChangeTimer ( ) ;
2004-12-17 17:14:46 +00:00
}
2005-11-04 11:59:51 +00:00
else
2004-12-17 17:14:46 +00:00
{
2005-11-04 11:59:51 +00:00
# ifdef ENABLE_PROGRESS_OVERLAY
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesShowProgress ( ) )
2005-11-04 11:59:51 +00:00
generateOverlay ( ) ;
# endif
if ( m_transitionTimer - > isActive ( ) )
{
m_transitionTimer - > stop ( ) ;
update ( ) ;
}
2004-12-17 17:14:46 +00:00
}
2005-01-03 23:31:40 +00:00
// we need the setFocus() call here to let KCursor::autoHide() work correctly
2004-12-31 15:34:08 +00:00
setFocus ( ) ;
2004-12-17 17:14:46 +00:00
}
void PresentationWidget : : slotPrevPage ( )
{
if ( m_frameIndex > 0 )
{
// go to previous page
2005-01-03 15:51:05 +00:00
changePage ( m_frameIndex - 1 ) ;
2005-11-04 11:59:51 +00:00
// auto advance to the next page if set
2006-12-31 10:48:49 +00:00
startAutoChangeTimer ( ) ;
2004-12-17 17:14:46 +00:00
}
2005-11-04 11:59:51 +00:00
else
2004-12-17 17:14:46 +00:00
{
2005-11-04 11:59:51 +00:00
# ifdef ENABLE_PROGRESS_OVERLAY
2006-09-21 08:45:36 +00:00
if ( Okular : : Settings : : slidesShowProgress ( ) )
2005-11-04 11:59:51 +00:00
generateOverlay ( ) ;
# endif
if ( m_transitionTimer - > isActive ( ) )
{
m_transitionTimer - > stop ( ) ;
update ( ) ;
}
2004-12-17 17:14:46 +00:00
}
}
2005-06-13 16:47:01 +00:00
void PresentationWidget : : slotFirstPage ( )
{
changePage ( 0 ) ;
}
void PresentationWidget : : slotLastPage ( )
{
changePage ( ( int ) m_frames . count ( ) - 1 ) ;
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : slotHideOverlay ( )
{
QRect geom ( m_overlayGeometry ) ;
m_overlayGeometry . setCoords ( 0 , 0 , - 1 , - 1 ) ;
update ( geom ) ;
}
void PresentationWidget : : slotTransitionStep ( )
{
if ( m_transitionRects . empty ( ) )
2005-01-08 00:12:08 +00:00
{
// it's better to fix the transition to cover the whole screen than
// enabling the following line that wastes cpu for nothing
//update();
2004-12-17 17:14:46 +00:00
return ;
2005-01-08 00:12:08 +00:00
}
2004-12-17 17:14:46 +00:00
for ( int i = 0 ; i < m_transitionMul & & ! m_transitionRects . empty ( ) ; i + + )
{
update ( m_transitionRects . first ( ) ) ;
m_transitionRects . pop_front ( ) ;
}
2006-05-27 17:30:53 +00:00
m_transitionTimer - > start ( m_transitionDelay ) ;
2004-12-17 17:14:46 +00:00
}
2006-05-13 16:50:53 +00:00
void PresentationWidget : : slotDelayedEvents ( )
{
// inform user on how to exit from presentation mode
2007-04-15 19:11:10 +00:00
KMessageBox : : information ( this , i18n ( " There are two ways of exiting presentation mode, you can press either ESC key or click with the quit button that appears when placing the mouse in the top-right corner. Of course you can cycle windows (Alt+TAB by default) " ) , QString ( ) , " presentationInfo " ) ;
2006-05-13 16:50:53 +00:00
}
2006-06-29 18:12:12 +00:00
void PresentationWidget : : slotPageChanged ( )
{
bool ok = true ;
int p = m_pagesEdit - > text ( ) . toInt ( & ok ) ;
if ( ! ok )
return ;
changePage ( p - 1 ) ;
}
2006-11-01 15:34:27 +00:00
void PresentationWidget : : togglePencilMode ( bool on )
{
if ( on )
{
2006-11-01 23:03:48 +00:00
QString colorstring = Okular : : Settings : : slidesPencilColor ( ) . name ( ) ;
2006-11-01 15:34:27 +00:00
// FIXME this should not be recreated every time
QDomDocument doc ( " engine " ) ;
QDomElement root = doc . createElement ( " engine " ) ;
2006-11-01 23:03:48 +00:00
root . setAttribute ( " color " , colorstring ) ;
2006-11-01 15:34:27 +00:00
doc . appendChild ( root ) ;
QDomElement annElem = doc . createElement ( " annotation " ) ;
root . appendChild ( annElem ) ;
annElem . setAttribute ( " type " , " Ink " ) ;
2006-11-01 23:03:48 +00:00
annElem . setAttribute ( " color " , colorstring ) ;
2006-11-01 15:34:27 +00:00
annElem . setAttribute ( " width " , " 2 " ) ;
m_drawingEngine = new SmoothPathEngine ( root ) ;
}
else
{
delete m_drawingEngine ;
m_drawingEngine = 0 ;
m_drawingRect = QRect ( ) ;
}
}
void PresentationWidget : : clearDrawings ( )
{
m_document - > removePageAnnotations ( m_document - > viewport ( ) . pageNumber , m_currentPageDrawings ) ;
m_currentPageDrawings . clear ( ) ;
}
2007-03-17 22:58:41 +00:00
void PresentationWidget : : slotFind ( )
{
if ( ! m_searchBar )
{
m_searchBar = new PresentationSearchBar ( m_document , this , this ) ;
m_searchBar - > forceSnap ( ) ;
}
2007-04-20 19:45:33 +00:00
m_searchBar - > focusOnSearchEdit ( ) ;
2007-03-17 22:58:41 +00:00
m_searchBar - > show ( ) ;
}
2006-11-01 15:34:27 +00:00
2006-09-21 08:45:36 +00:00
const Okular : : PageTransition PresentationWidget : : defaultTransition ( ) const
2005-01-03 23:31:40 +00:00
{
2006-09-21 08:45:36 +00:00
return defaultTransition ( Okular : : Settings : : slidesTransition ( ) ) ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
const Okular : : PageTransition PresentationWidget : : defaultTransition ( int type ) const
2005-01-09 23:23:37 +00:00
{
switch ( type )
2005-01-03 23:31:40 +00:00
{
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : BlindsHorizontal :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Blinds ) ;
transition . setAlignment ( Okular : : PageTransition : : Horizontal ) ;
2005-01-09 23:23:37 +00:00
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : BlindsVertical :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Blinds ) ;
transition . setAlignment ( Okular : : PageTransition : : Vertical ) ;
2005-01-09 23:23:37 +00:00
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : BoxIn :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Box ) ;
transition . setDirection ( Okular : : PageTransition : : Inward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : BoxOut :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Box ) ;
transition . setDirection ( Okular : : PageTransition : : Outward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : Dissolve :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
return Okular : : PageTransition ( Okular : : PageTransition : : Dissolve ) ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : GlitterDown :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Glitter ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 270 ) ;
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : GlitterRight :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Glitter ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 0 ) ;
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : GlitterRightDown :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Glitter ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 315 ) ;
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : Random :
2005-01-09 23:23:37 +00:00
{
2006-03-24 19:35:20 +00:00
return defaultTransition ( KRandom : : random ( ) % 18 ) ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : SplitHorizontalIn :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Split ) ;
transition . setAlignment ( Okular : : PageTransition : : Horizontal ) ;
transition . setDirection ( Okular : : PageTransition : : Inward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : SplitHorizontalOut :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Split ) ;
transition . setAlignment ( Okular : : PageTransition : : Horizontal ) ;
transition . setDirection ( Okular : : PageTransition : : Outward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : SplitVerticalIn :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Split ) ;
transition . setAlignment ( Okular : : PageTransition : : Vertical ) ;
transition . setDirection ( Okular : : PageTransition : : Inward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : SplitVerticalOut :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Split ) ;
transition . setAlignment ( Okular : : PageTransition : : Vertical ) ;
transition . setDirection ( Okular : : PageTransition : : Outward ) ;
2005-01-09 23:23:37 +00:00
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : WipeDown :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Wipe ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 270 ) ;
return transition ;
2005-01-03 23:31:40 +00:00
break ;
2005-01-09 23:23:37 +00:00
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : WipeRight :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Wipe ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 0 ) ;
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : WipeLeft :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Wipe ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 180 ) ;
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : WipeUp :
2005-01-09 23:23:37 +00:00
{
2006-09-21 08:45:36 +00:00
Okular : : PageTransition transition ( Okular : : PageTransition : : Wipe ) ;
2005-01-09 23:23:37 +00:00
transition . setAngle ( 90 ) ;
return transition ;
break ;
}
2006-09-21 08:45:36 +00:00
case Okular : : Settings : : EnumSlidesTransition : : Replace :
2005-01-03 23:31:40 +00:00
default :
2006-09-21 08:45:36 +00:00
return Okular : : PageTransition ( Okular : : PageTransition : : Replace ) ;
2005-01-03 23:31:40 +00:00
break ;
}
2006-06-28 11:49:01 +00:00
// should not happen, just make gcc happy
2006-09-21 08:45:36 +00:00
return Okular : : PageTransition ( ) ;
2005-01-03 23:31:40 +00:00
}
2004-12-17 17:14:46 +00:00
/** ONLY the TRANSITIONS GENERATION function from here on **/
2006-09-21 08:45:36 +00:00
void PresentationWidget : : initTransition ( const Okular : : PageTransition * transition )
2004-12-17 17:14:46 +00:00
{
2005-01-08 00:12:08 +00:00
// if it's just a 'replace' transition, repaint the screen
2006-09-21 08:45:36 +00:00
if ( transition - > type ( ) = = Okular : : PageTransition : : Replace )
2005-01-08 00:12:08 +00:00
{
update ( ) ;
return ;
}
2006-09-21 08:45:36 +00:00
const bool isInward = transition - > direction ( ) = = Okular : : PageTransition : : Inward ;
const bool isHorizontal = transition - > alignment ( ) = = Okular : : PageTransition : : Horizontal ;
2005-01-08 00:12:08 +00:00
const float totalTime = transition - > duration ( ) ;
2004-12-17 17:14:46 +00:00
m_transitionRects . clear ( ) ;
2005-01-08 00:12:08 +00:00
2005-01-02 20:32:58 +00:00
switch ( transition - > type ( ) )
2004-12-17 17:14:46 +00:00
{
2005-01-08 00:12:08 +00:00
// split: horizontal / vertical and inward / outward
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Split :
2005-01-08 00:12:08 +00:00
{
const int steps = isHorizontal ? 100 : 75 ;
if ( isHorizontal )
{
if ( isInward )
{
int xPosition = 0 ;
for ( int i = 0 ; i < steps ; i + + )
{
int xNext = ( ( i + 1 ) * m_width ) / ( 2 * steps ) ;
m_transitionRects . push_back ( QRect ( xPosition , 0 , xNext - xPosition , m_height ) ) ;
m_transitionRects . push_back ( QRect ( m_width - xNext , 0 , xNext - xPosition , m_height ) ) ;
xPosition = xNext ;
}
}
else
{
int xPosition = m_width / 2 ;
for ( int i = 0 ; i < steps ; i + + )
{
int xNext = ( ( steps - ( i + 1 ) ) * m_width ) / ( 2 * steps ) ;
m_transitionRects . push_back ( QRect ( xNext , 0 , xPosition - xNext , m_height ) ) ;
m_transitionRects . push_back ( QRect ( m_width - xPosition , 0 , xPosition - xNext , m_height ) ) ;
xPosition = xNext ;
}
}
}
else
{
if ( isInward )
{
int yPosition = 0 ;
for ( int i = 0 ; i < steps ; i + + )
{
int yNext = ( ( i + 1 ) * m_height ) / ( 2 * steps ) ;
m_transitionRects . push_back ( QRect ( 0 , yPosition , m_width , yNext - yPosition ) ) ;
m_transitionRects . push_back ( QRect ( 0 , m_height - yNext , m_width , yNext - yPosition ) ) ;
yPosition = yNext ;
}
}
else
{
int yPosition = m_height / 2 ;
for ( int i = 0 ; i < steps ; i + + )
{
int yNext = ( ( steps - ( i + 1 ) ) * m_height ) / ( 2 * steps ) ;
m_transitionRects . push_back ( QRect ( 0 , yNext , m_width , yPosition - yNext ) ) ;
m_transitionRects . push_back ( QRect ( 0 , m_height - yPosition , m_width , yPosition - yNext ) ) ;
yPosition = yNext ;
}
}
}
m_transitionMul = 2 ;
m_transitionDelay = ( int ) ( ( totalTime * 1000 ) / steps ) ;
} break ;
// blinds: horizontal(l-to-r) / vertical(t-to-b)
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Blinds :
2005-01-08 00:12:08 +00:00
{
const int blinds = isHorizontal ? 8 : 6 ;
const int steps = m_width / ( 4 * blinds ) ;
if ( isHorizontal )
{
2005-01-11 12:42:06 +00:00
int xPosition [ 8 ] ;
2005-01-08 00:12:08 +00:00
for ( int b = 0 ; b < blinds ; b + + )
xPosition [ b ] = ( b * m_width ) / blinds ;
for ( int i = 0 ; i < steps ; i + + )
{
int stepOffset = ( int ) ( ( ( float ) i * ( float ) m_width ) / ( ( float ) blinds * ( float ) steps ) ) ;
for ( int b = 0 ; b < blinds ; b + + )
{
m_transitionRects . push_back ( QRect ( xPosition [ b ] , 0 , stepOffset , m_height ) ) ;
xPosition [ b ] = stepOffset + ( b * m_width ) / blinds ;
}
}
}
else
{
2005-01-11 12:42:06 +00:00
int yPosition [ 6 ] ;
2005-01-08 00:12:08 +00:00
for ( int b = 0 ; b < blinds ; b + + )
yPosition [ b ] = ( b * m_height ) / blinds ;
for ( int i = 0 ; i < steps ; i + + )
{
int stepOffset = ( int ) ( ( ( float ) i * ( float ) m_height ) / ( ( float ) blinds * ( float ) steps ) ) ;
for ( int b = 0 ; b < blinds ; b + + )
{
m_transitionRects . push_back ( QRect ( 0 , yPosition [ b ] , m_width , stepOffset ) ) ;
yPosition [ b ] = stepOffset + ( b * m_height ) / blinds ;
}
}
}
m_transitionMul = blinds ;
m_transitionDelay = ( int ) ( ( totalTime * 1000 ) / steps ) ;
} break ;
// box: inward / outward
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Box :
2005-01-08 00:12:08 +00:00
{
const int steps = m_width / 10 ;
if ( isInward )
{
int L = 0 , T = 0 , R = m_width , B = m_height ;
for ( int i = 0 ; i < steps ; i + + )
{
// compure shrinked box coords
int newL = ( ( i + 1 ) * m_width ) / ( 2 * steps ) ;
int newT = ( ( i + 1 ) * m_height ) / ( 2 * steps ) ;
int newR = m_width - newL ;
int newB = m_height - newT ;
// add left, right, topcenter, bottomcenter rects
m_transitionRects . push_back ( QRect ( L , T , newL - L , B - T ) ) ;
m_transitionRects . push_back ( QRect ( newR , T , R - newR , B - T ) ) ;
m_transitionRects . push_back ( QRect ( newL , T , newR - newL , newT - T ) ) ;
m_transitionRects . push_back ( QRect ( newL , newB , newR - newL , B - newB ) ) ;
L = newL ; T = newT ; R = newR , B = newB ;
}
}
else
{
int L = m_width / 2 , T = m_height / 2 , R = L , B = T ;
for ( int i = 0 ; i < steps ; i + + )
{
// compure shrinked box coords
int newL = ( ( steps - ( i + 1 ) ) * m_width ) / ( 2 * steps ) ;
int newT = ( ( steps - ( i + 1 ) ) * m_height ) / ( 2 * steps ) ;
int newR = m_width - newL ;
int newB = m_height - newT ;
// add left, right, topcenter, bottomcenter rects
m_transitionRects . push_back ( QRect ( newL , newT , L - newL , newB - newT ) ) ;
m_transitionRects . push_back ( QRect ( R , newT , newR - R , newB - newT ) ) ;
m_transitionRects . push_back ( QRect ( L , newT , R - L , T - newT ) ) ;
m_transitionRects . push_back ( QRect ( L , B , R - L , newB - B ) ) ;
L = newL ; T = newT ; R = newR , B = newB ;
}
}
m_transitionMul = 4 ;
m_transitionDelay = ( int ) ( ( totalTime * 1000 ) / steps ) ;
} break ;
// wipe: implemented for 4 canonical angles
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Wipe :
2005-01-08 00:12:08 +00:00
{
const int angle = transition - > angle ( ) ;
const int steps = ( angle = = 0 ) | | ( angle = = 180 ) ? m_width / 8 : m_height / 8 ;
if ( angle = = 0 )
{
int xPosition = 0 ;
for ( int i = 0 ; i < steps ; i + + )
{
int xNext = ( ( i + 1 ) * m_width ) / steps ;
m_transitionRects . push_back ( QRect ( xPosition , 0 , xNext - xPosition , m_height ) ) ;
xPosition = xNext ;
}
}
else if ( angle = = 90 )
{
int yPosition = m_height ;
for ( int i = 0 ; i < steps ; i + + )
{
int yNext = ( ( steps - ( i + 1 ) ) * m_height ) / steps ;
m_transitionRects . push_back ( QRect ( 0 , yNext , m_width , yPosition - yNext ) ) ;
yPosition = yNext ;
}
}
else if ( angle = = 180 )
{
int xPosition = m_width ;
for ( int i = 0 ; i < steps ; i + + )
{
int xNext = ( ( steps - ( i + 1 ) ) * m_width ) / steps ;
m_transitionRects . push_back ( QRect ( xNext , 0 , xPosition - xNext , m_height ) ) ;
xPosition = xNext ;
}
}
else if ( angle = = 270 )
{
int yPosition = 0 ;
for ( int i = 0 ; i < steps ; i + + )
{
int yNext = ( ( i + 1 ) * m_height ) / steps ;
m_transitionRects . push_back ( QRect ( 0 , yPosition , m_width , yNext - yPosition ) ) ;
yPosition = yNext ;
}
}
else
{
update ( ) ;
return ;
}
m_transitionMul = 1 ;
m_transitionDelay = ( int ) ( ( totalTime * 1000 ) / steps ) ;
} break ;
// dissolve: replace 'random' rects
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Dissolve :
2005-01-08 00:12:08 +00:00
{
const int gridXsteps = 50 ;
const int gridYsteps = 38 ;
const int steps = gridXsteps * gridYsteps ;
int oldX = 0 ;
int oldY = 0 ;
2004-12-17 17:14:46 +00:00
// create a grid of gridXstep by gridYstep QRects
2005-01-08 00:12:08 +00:00
for ( int y = 0 ; y < gridYsteps ; y + + )
2004-12-17 17:14:46 +00:00
{
2005-01-08 00:12:08 +00:00
int newY = ( int ) ( m_height * ( ( float ) ( y + 1 ) / ( float ) gridYsteps ) ) ;
for ( int x = 0 ; x < gridXsteps ; x + + )
2004-12-17 17:14:46 +00:00
{
2005-01-08 00:12:08 +00:00
int newX = ( int ) ( m_width * ( ( float ) ( x + 1 ) / ( float ) gridXsteps ) ) ;
2004-12-17 17:14:46 +00:00
m_transitionRects . push_back ( QRect ( oldX , oldY , newX - oldX , newY - oldY ) ) ;
oldX = newX ;
}
oldX = 0 ;
oldY = newY ;
}
// randomize the grid
for ( int i = 0 ; i < steps ; i + + )
{
int n1 = ( int ) ( steps * drand48 ( ) ) ;
int n2 = ( int ) ( steps * drand48 ( ) ) ;
2005-01-08 00:12:08 +00:00
// swap items if index differs
2004-12-17 17:14:46 +00:00
if ( n1 ! = n2 )
{
QRect r = m_transitionRects [ n2 ] ;
m_transitionRects [ n2 ] = m_transitionRects [ n1 ] ;
m_transitionRects [ n1 ] = r ;
}
}
// set global transition parameters
m_transitionMul = 40 ;
2005-01-08 00:12:08 +00:00
m_transitionDelay = ( int ) ( ( m_transitionMul * 1000 * totalTime ) / steps ) ;
} break ;
// glitter: similar to dissolve but has a direction
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Glitter :
2005-01-08 00:12:08 +00:00
{
const int gridXsteps = 50 ;
const int gridYsteps = 38 ;
const int steps = gridXsteps * gridYsteps ;
const int angle = transition - > angle ( ) ;
// generate boxes using a given direction
if ( angle = = 90 )
{
int yPosition = m_height ;
for ( int i = 0 ; i < gridYsteps ; i + + )
{
int yNext = ( ( gridYsteps - ( i + 1 ) ) * m_height ) / gridYsteps ;
int xPosition = 0 ;
for ( int j = 0 ; j < gridXsteps ; j + + )
{
int xNext = ( ( j + 1 ) * m_width ) / gridXsteps ;
m_transitionRects . push_back ( QRect ( xPosition , yNext , xNext - xPosition , yPosition - yNext ) ) ;
xPosition = xNext ;
}
yPosition = yNext ;
}
}
else if ( angle = = 180 )
{
int xPosition = m_width ;
for ( int i = 0 ; i < gridXsteps ; i + + )
{
int xNext = ( ( gridXsteps - ( i + 1 ) ) * m_width ) / gridXsteps ;
int yPosition = 0 ;
for ( int j = 0 ; j < gridYsteps ; j + + )
{
int yNext = ( ( j + 1 ) * m_height ) / gridYsteps ;
m_transitionRects . push_back ( QRect ( xNext , yPosition , xPosition - xNext , yNext - yPosition ) ) ;
yPosition = yNext ;
}
xPosition = xNext ;
}
}
else if ( angle = = 270 )
{
int yPosition = 0 ;
for ( int i = 0 ; i < gridYsteps ; i + + )
{
int yNext = ( ( i + 1 ) * m_height ) / gridYsteps ;
int xPosition = 0 ;
for ( int j = 0 ; j < gridXsteps ; j + + )
{
int xNext = ( ( j + 1 ) * m_width ) / gridXsteps ;
m_transitionRects . push_back ( QRect ( xPosition , yPosition , xNext - xPosition , yNext - yPosition ) ) ;
xPosition = xNext ;
}
yPosition = yNext ;
}
}
else // if angle is 0 or 315
{
int xPosition = 0 ;
for ( int i = 0 ; i < gridXsteps ; i + + )
{
int xNext = ( ( i + 1 ) * m_width ) / gridXsteps ;
int yPosition = 0 ;
for ( int j = 0 ; j < gridYsteps ; j + + )
{
int yNext = ( ( j + 1 ) * m_height ) / gridYsteps ;
m_transitionRects . push_back ( QRect ( xPosition , yPosition , xNext - xPosition , yNext - yPosition ) ) ;
yPosition = yNext ;
}
xPosition = xNext ;
}
}
// add a 'glitter' (1 over 10 pieces is randomized)
int randomSteps = steps / 20 ;
for ( int i = 0 ; i < randomSteps ; i + + )
{
int n1 = ( int ) ( steps * drand48 ( ) ) ;
int n2 = ( int ) ( steps * drand48 ( ) ) ;
// swap items if index differs
if ( n1 ! = n2 )
{
QRect r = m_transitionRects [ n2 ] ;
m_transitionRects [ n2 ] = m_transitionRects [ n1 ] ;
m_transitionRects [ n1 ] = r ;
}
}
// set global transition parameters
m_transitionMul = ( angle = = 90 ) | | ( angle = = 270 ) ? gridYsteps : gridXsteps ;
m_transitionMul / = 2 ;
m_transitionDelay = ( int ) ( ( m_transitionMul * 1000 * totalTime ) / steps ) ;
} break ;
2005-01-27 17:31:07 +00:00
// implement missing transitions (a binary raster engine needed here)
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Fly :
2005-01-08 00:12:08 +00:00
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Push :
2005-01-08 00:12:08 +00:00
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Cover :
2005-01-08 00:12:08 +00:00
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Uncover :
2005-01-08 00:12:08 +00:00
2006-09-21 08:45:36 +00:00
case Okular : : PageTransition : : Fade :
2005-01-08 00:12:08 +00:00
default :
2004-12-17 17:14:46 +00:00
update ( ) ;
return ;
}
// send the first start to the timer
2006-05-27 17:30:53 +00:00
m_transitionTimer - > start ( 0 ) ;
2004-12-17 17:14:46 +00:00
}
# include "presentationwidget.moc"