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
2018-08-17 18:05:01 +00:00
# include <qloggingcategory.h>
2018-08-31 09:23:45 +00:00
# include <QDBusConnection>
# include <QDBusMessage>
# include <QDBusReply>
2008-08-30 17:31:59 +00:00
2006-03-24 19:35:20 +00:00
# include <qevent.h>
2006-06-29 18:12:12 +00:00
# include <qfontmetrics.h>
2014-10-06 06:31:17 +00:00
# include <QIcon>
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>
2009-03-14 16:03:06 +00:00
# include <qlayout.h>
2004-12-17 17:14:46 +00:00
# include <qpainter.h>
2008-01-13 23:27:31 +00:00
# include <qstyle.h>
# include <qstyleoption.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>
2017-03-19 23:22:24 +00:00
# include <QGestureEvent>
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>
2014-10-14 05:37:01 +00:00
# include <qaction.h>
2006-06-25 16:34:11 +00:00
# include <kactioncollection.h>
2008-01-12 19:06:46 +00:00
# include <klineedit.h>
2014-10-14 05:37:01 +00:00
# include <KLocalizedString>
2004-12-17 17:14:46 +00:00
# include <kiconloader.h>
2005-06-13 16:55:57 +00:00
# include <kmessagebox.h>
2008-04-09 15:05:08 +00:00
# include <kselectaction.h>
2016-07-17 00:28:57 +00:00
# include <QDialog>
2004-12-17 17:14:46 +00:00
2016-07-24 21:36:03 +00:00
# ifdef Q_OS_LINUX
# include <QDBusUnixFileDescriptor>
# include <unistd.h> // For ::close() for sleep inhibition
# endif
2012-01-18 00:04:06 +00:00
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"
2014-09-11 19:12:27 +00:00
# include "debug_ui.h"
2015-08-22 20:15:32 +00:00
# include "drawingtoolactions.h"
2012-09-27 12:15:58 +00:00
# include "guiutils.h"
2005-01-27 17:31:07 +00:00
# include "pagepainter.h"
2007-03-17 22:58:41 +00:00
# include "presentationsearchbar.h"
2013-02-24 21:58:53 +00:00
# include "priorities.h"
2008-08-25 01:41:41 +00:00
# include "videowidget.h"
2007-04-20 11:26:05 +00:00
# include "core/action.h"
2008-08-25 01:41:41 +00:00
# include "core/annotations.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"
2008-08-25 01:41:41 +00:00
# include "core/movie.h"
2005-01-02 14:37:49 +00:00
# include "core/page.h"
2006-03-28 22:22:10 +00:00
# include "settings.h"
2012-10-15 22:27:42 +00:00
# include "settings_core.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
{
2019-01-09 23:28:49 +00:00
PresentationFrame ( ) = default ;
2008-08-25 01:41:41 +00:00
~ PresentationFrame ( )
{
qDeleteAll ( videoWidgets ) ;
}
2019-01-09 23:28:49 +00:00
PresentationFrame ( const PresentationFrame & ) = delete ;
PresentationFrame & operator = ( const PresentationFrame & ) = delete ;
2008-04-09 14:04:39 +00:00
void recalcGeometry ( int width , int height , float screenRatio )
{
// calculate frame geometry keeping constant aspect ratio
float pageRatio = page - > ratio ( ) ;
int pageWidth = width ,
pageHeight = height ;
if ( pageRatio > screenRatio )
pageWidth = ( int ) ( ( float ) pageHeight / pageRatio ) ;
else
pageHeight = ( int ) ( ( float ) pageWidth * pageRatio ) ;
geometry . setRect ( ( width - pageWidth ) / 2 ,
( height - pageHeight ) / 2 ,
pageWidth , pageHeight ) ;
2017-10-14 12:47:20 +00:00
2008-08-25 01:41:41 +00:00
Q_FOREACH ( VideoWidget * vw , videoWidgets )
{
const Okular : : NormalizedRect r = vw - > normGeometry ( ) ;
2008-08-25 18:27:19 +00:00
QRect vwgeom = r . geometry ( geometry . width ( ) , geometry . height ( ) ) ;
2008-08-25 01:41:41 +00:00
vw - > resize ( vwgeom . size ( ) ) ;
vw - > move ( geometry . topLeft ( ) + vwgeom . topLeft ( ) ) ;
}
2008-04-09 14:04:39 +00:00
}
2006-09-21 08:45:36 +00:00
const Okular : : Page * page ;
2004-12-17 17:14:46 +00:00
QRect geometry ;
2008-08-25 01:41:41 +00:00
QHash < Okular : : Movie * , VideoWidget * > videoWidgets ;
2012-09-08 17:29:28 +00:00
QLinkedList < SmoothPath > drawings ;
2004-12-17 17:14:46 +00:00
} ;
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
{
2016-10-29 14:32:24 +00:00
Q_OBJECT
2006-11-05 17:25:46 +00:00
public :
2015-08-18 13:12:07 +00:00
PresentationToolBar ( QWidget * parent = Q_NULLPTR )
2006-11-05 17:25:46 +00:00
: QToolBar ( parent )
{ }
protected :
2016-10-29 14:38:19 +00:00
void mousePressEvent ( QMouseEvent * e ) override
2006-11-05 17:25:46 +00:00
{
QToolBar : : mousePressEvent ( e ) ;
e - > accept ( ) ;
}
2016-10-29 14:38:19 +00:00
void mouseReleaseEvent ( QMouseEvent * e ) override
2006-11-05 17:25:46 +00:00
{
QToolBar : : mouseReleaseEvent ( e ) ;
e - > accept ( ) ;
}
} ;
2015-08-22 20:15:32 +00:00
PresentationWidget : : PresentationWidget ( QWidget * parent , Okular : : Document * doc , DrawingToolActions * drawingToolActions , KActionCollection * collection )
2017-09-05 21:27:18 +00:00
: QWidget ( nullptr /* must be null, to have an independent widget */ , Qt : : FramelessWindowHint ) ,
m_pressedLink ( nullptr ) , m_handCursor ( false ) , m_drawingEngine ( nullptr ) ,
2018-09-18 19:30:25 +00:00
m_screenInhibitCookie ( 0 ) , m_sleepInhibitFd ( - 1 ) ,
2009-11-10 19:07:23 +00:00
m_parentWidget ( parent ) ,
2017-09-05 21:27:18 +00:00
m_document ( doc ) , m_frameIndex ( - 1 ) , m_topBar ( nullptr ) , m_pagesEdit ( nullptr ) , m_searchBar ( nullptr ) ,
m_ac ( collection ) , m_screenSelect ( nullptr ) , m_isSetup ( false ) , m_blockNotifications ( false ) , m_inBlackScreenMode ( false ) ,
2014-02-24 22:08:39 +00:00
m_showSummaryView ( Okular : : Settings : : slidesShowSummary ( ) ) ,
2017-03-19 23:35:05 +00:00
m_advanceSlides ( Okular : : SettingsCore : : slidesAdvance ( ) ) ,
2019-01-08 12:50:20 +00:00
m_goToPreviousPageOnRelease ( false ) ,
2017-03-19 23:35:05 +00:00
m_goToNextPageOnRelease ( false )
2004-12-17 17:14:46 +00:00
{
2008-06-06 17:22:19 +00:00
Q_UNUSED ( parent )
2006-04-03 22:23:39 +00:00
setAttribute ( Qt : : WA_DeleteOnClose ) ;
setAttribute ( Qt : : WA_OpaquePaintEvent ) ;
2015-10-29 12:37:11 +00:00
setObjectName ( QStringLiteral ( " presentationWidget " ) ) ;
QString caption = doc - > metaData ( QStringLiteral ( " DocumentTitle " ) ) . toString ( ) ;
2006-10-21 23:21:11 +00:00
if ( caption . trimmed ( ) . isEmpty ( ) )
caption = doc - > currentDocument ( ) . fileName ( ) ;
2009-07-25 14:23:30 +00:00
caption = i18nc ( " [document title/filename] – Presentation " , " %1 – Presentation " , caption ) ;
2016-07-17 00:28:57 +00:00
setWindowTitle ( caption ) ;
2005-03-05 15:59:15 +00:00
m_width = - 1 ;
2008-04-07 18:16:39 +00:00
m_screen = - 2 ;
// create top toolbar
m_topBar = new PresentationToolBar ( this ) ;
2015-10-29 12:37:11 +00:00
m_topBar - > setObjectName ( QStringLiteral ( " presentationBar " ) ) ;
2008-04-07 18:16:39 +00:00
m_topBar - > setMovable ( false ) ;
2019-02-27 06:50:47 +00:00
m_topBar - > layout ( ) - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2016-07-11 20:05:18 +00:00
m_topBar - > addAction ( QIcon : : fromTheme ( layoutDirection ( ) = = Qt : : RightToLeft ? QStringLiteral ( " go-next " ) : QStringLiteral ( " go-previous " ) ) , i18n ( " Previous Page " ) , this , SLOT ( slotPrevPage ( ) ) ) ;
2008-04-07 18:16:39 +00:00
m_pagesEdit = new KLineEdit ( m_topBar ) ;
QSizePolicy sp = m_pagesEdit - > sizePolicy ( ) ;
sp . setHorizontalPolicy ( QSizePolicy : : Minimum ) ;
m_pagesEdit - > setSizePolicy ( sp ) ;
QFontMetrics fm ( m_pagesEdit - > font ( ) ) ;
QStyleOptionFrame option ;
option . initFrom ( m_pagesEdit ) ;
2019-07-03 22:30:47 +00:00
m_pagesEdit - > setMaximumWidth ( fm . width ( QString : : number ( m_document - > pages ( ) ) ) + 2 * style ( ) - > pixelMetric ( QStyle : : PM_DefaultFrameWidth , & option , m_pagesEdit ) + 4 ) ; // the 4 comes from 2*horizontalMargin, horizontalMargin being a define in qlineedit.cpp
2008-04-07 18:16:39 +00:00
QIntValidator * validator = new QIntValidator ( 1 , m_document - > pages ( ) , m_pagesEdit ) ;
m_pagesEdit - > setValidator ( validator ) ;
m_topBar - > addWidget ( m_pagesEdit ) ;
QLabel * pagesLabel = new QLabel ( m_topBar ) ;
pagesLabel - > setText ( QLatin1String ( " / " ) + QString : : number ( m_document - > pages ( ) ) + QLatin1String ( " " ) ) ;
m_topBar - > addWidget ( pagesLabel ) ;
2014-10-01 17:40:48 +00:00
connect ( m_pagesEdit , & QLineEdit : : returnPressed , this , & PresentationWidget : : slotPageChanged ) ;
2016-07-11 20:05:18 +00:00
m_topBar - > addAction ( QIcon : : fromTheme ( layoutDirection ( ) = = Qt : : RightToLeft ? QStringLiteral ( " go-previous " ) : QStringLiteral ( " go-next " ) ) , i18n ( " Next Page " ) , this , SLOT ( slotNextPage ( ) ) ) ;
2008-04-07 18:16:39 +00:00
m_topBar - > addSeparator ( ) ;
2015-10-29 12:37:11 +00:00
QAction * playPauseAct = collection - > action ( QStringLiteral ( " presentation_play_pause " ) ) ;
2014-02-24 22:08:39 +00:00
playPauseAct - > setEnabled ( true ) ;
2014-10-01 17:40:48 +00:00
connect ( playPauseAct , & QAction : : triggered , this , & PresentationWidget : : slotTogglePlayPause ) ;
2014-02-24 22:08:39 +00:00
m_topBar - > addAction ( playPauseAct ) ;
setPlayPauseIcon ( ) ;
addAction ( playPauseAct ) ;
m_topBar - > addSeparator ( ) ;
2015-08-22 14:00:04 +00:00
2015-08-22 20:15:32 +00:00
foreach ( QAction * action , drawingToolActions - > actions ( ) )
{
action - > setEnabled ( true ) ;
m_topBar - > addAction ( action ) ;
addAction ( action ) ;
}
connect ( drawingToolActions , & DrawingToolActions : : changeEngine , this , & PresentationWidget : : slotChangeDrawingToolEngine ) ;
connect ( drawingToolActions , & DrawingToolActions : : actionsRecreated , this , & PresentationWidget : : slotAddDrawingToolActions ) ;
2015-08-22 14:00:04 +00:00
2018-12-21 11:40:49 +00:00
QAction * eraseDrawingAct = collection - > action ( QStringLiteral ( " presentation_erase_drawings " ) ) ;
eraseDrawingAct - > setEnabled ( true ) ;
connect ( eraseDrawingAct , & QAction : : triggered , this , & PresentationWidget : : clearDrawings ) ;
m_topBar - > addAction ( eraseDrawingAct ) ;
addAction ( eraseDrawingAct ) ;
2008-04-09 15:05:08 +00:00
QDesktopWidget * desktop = QApplication : : desktop ( ) ;
if ( desktop - > numScreens ( ) > 1 )
{
m_topBar - > addSeparator ( ) ;
2015-10-29 12:37:11 +00:00
m_screenSelect = new KSelectAction ( QIcon : : fromTheme ( QStringLiteral ( " video-display " ) ) , i18n ( " Switch Screen " ) , m_topBar ) ;
2008-04-09 15:05:08 +00:00
m_screenSelect - > setToolBarMode ( KSelectAction : : MenuMode ) ;
m_screenSelect - > setToolButtonPopupMode ( QToolButton : : InstantPopup ) ;
m_topBar - > addAction ( m_screenSelect ) ;
const int screenCount = desktop - > numScreens ( ) ;
for ( int i = 0 ; i < screenCount ; + + i )
{
QAction * act = m_screenSelect - > addAction ( i18nc ( " %1 is the screen number (0, 1, ...) " , " Screen %1 " , i ) ) ;
act - > setData ( qVariantFromValue ( i ) ) ;
}
}
2008-04-07 18:16:39 +00:00
QWidget * spacer = new QWidget ( m_topBar ) ;
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : MinimumExpanding ) ;
m_topBar - > addWidget ( spacer ) ;
2015-10-29 12:37:11 +00:00
m_topBar - > addAction ( QIcon : : fromTheme ( QStringLiteral ( " application-exit " ) ) , i18n ( " Exit Presentation Mode " ) , this , SLOT ( close ( ) ) ) ;
2008-04-07 18:16:39 +00:00
m_topBar - > setAutoFillBackground ( true ) ;
2010-03-30 04:03:00 +00:00
showTopBar ( false ) ;
2008-04-07 18:16:39 +00:00
// change topbar background color
QPalette p = m_topBar - > palette ( ) ;
p . setColor ( QPalette : : Active , QPalette : : Button , Qt : : gray ) ;
2019-02-27 06:50:47 +00:00
p . setColor ( QPalette : : Active , QPalette : : Window , Qt : : darkGray ) ;
2008-04-07 18:16:39 +00:00
m_topBar - > setPalette ( p ) ;
2004-12-17 17:14:46 +00:00
2017-03-19 23:22:24 +00:00
// Grab swipe gestures to change pages
grabGesture ( Qt : : SwipeGesture ) ;
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 ) ;
2014-10-01 17:40:48 +00:00
connect ( m_transitionTimer , & QTimer : : timeout , this , & PresentationWidget : : slotTransitionStep ) ;
2004-12-17 17:14:46 +00:00
m_overlayHideTimer = new QTimer ( this ) ;
2006-05-27 17:30:53 +00:00
m_overlayHideTimer - > setSingleShot ( true ) ;
2014-10-01 17:40:48 +00:00
connect ( m_overlayHideTimer , & QTimer : : timeout , this , & PresentationWidget : : slotHideOverlay ) ;
2016-07-17 00:28:57 +00:00
m_nextPageTimer = new QTimer ( this ) ;
2007-04-21 00:02:12 +00:00
m_nextPageTimer - > setSingleShot ( true ) ;
2014-10-01 17:40:48 +00:00
connect ( m_nextPageTimer , & QTimer : : timeout , this , & PresentationWidget : : slotNextPage ) ;
2009-11-10 19:07:23 +00:00
2014-10-01 17:40:48 +00:00
connect ( m_document , & Okular : : Document : : processMovieAction , this , & PresentationWidget : : slotProcessMovieAction ) ;
connect ( m_document , & Okular : : Document : : processRenditionAction , this , & PresentationWidget : : slotProcessRenditionAction ) ;
2012-04-03 12:18:10 +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
2014-02-24 22:08:39 +00:00
setupActions ( ) ;
2008-11-29 13:50:37 +00:00
2012-01-18 20:34:12 +00:00
// inhibit power management
inhibitPowerManagement ( ) ;
2008-08-30 17:31:59 +00:00
2009-03-07 22:13:06 +00:00
show ( ) ;
2015-10-29 12:37:11 +00:00
QTimer : : singleShot ( 0 , this , & PresentationWidget : : slotDelayedEvents ) ;
2010-03-28 12:25:35 +00:00
// setFocus() so KCursor::setAutoHideCursor() goes into effect if it's enabled
setFocus ( Qt : : OtherFocusReason ) ;
2004-12-17 17:14:46 +00:00
}
PresentationWidget : : ~ PresentationWidget ( )
{
2012-01-18 20:34:12 +00:00
// allow power management saver again
allowPowerManagement ( ) ;
2008-08-30 17:31:59 +00:00
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 ) ;
2015-08-22 20:15:32 +00:00
foreach ( QAction * action , m_topBar - > actions ( ) )
{
action - > setChecked ( false ) ;
action - > setEnabled ( false ) ;
}
2014-02-24 22:08:39 +00:00
2006-11-01 15:34:27 +00:00
delete m_drawingEngine ;
2009-11-10 19:07:23 +00:00
2004-12-17 17:14:46 +00:00
// delete frames
2019-03-26 22:37:30 +00:00
qDeleteAll ( m_frames ) ;
2004-12-17 17:14:46 +00:00
}
2007-09-09 10:50:36 +00:00
void PresentationWidget : : notifySetup ( const QVector < Okular : : Page * > & pageSet , int setupFlags )
2004-12-17 17:14:46 +00:00
{
2007-08-23 21:36:41 +00:00
// same document, nothing to change - here we assume the document sets up
// us with the whole document set as first notifySetup()
2007-09-09 10:50:36 +00:00
if ( ! ( setupFlags & Okular : : DocumentObserver : : DocumentChanged ) )
2007-08-23 21:36:41 +00:00
return ;
2004-12-17 17:14:46 +00:00
// delete previous frames (if any (shouldn't be))
2019-03-26 22:37:30 +00:00
qDeleteAll ( m_frames ) ;
2004-12-17 17:14:46 +00:00
if ( ! m_frames . isEmpty ( ) )
2014-09-11 19:12:27 +00:00
qCWarning ( OkularUiDebug ) < < " Frames setup changed while a Presentation is in progress. " ;
2004-12-17 17:14:46 +00:00
m_frames . clear ( ) ;
// create the new frames
float screenRatio = ( float ) m_height / ( float ) m_width ;
2019-03-26 22:37:30 +00:00
for ( const Okular : : Page * page : pageSet )
2004-12-17 17:14:46 +00:00
{
PresentationFrame * frame = new PresentationFrame ( ) ;
2019-03-26 22:37:30 +00:00
frame - > page = page ;
const QLinkedList < Okular : : Annotation * > annotations = page - > annotations ( ) ;
for ( Okular : : Annotation * a : annotations )
2008-08-25 01:41:41 +00:00
{
if ( a - > subType ( ) = = Okular : : Annotation : : AMovie )
{
Okular : : MovieAnnotation * movieAnn = static_cast < Okular : : MovieAnnotation * > ( a ) ;
2012-09-27 11:02:14 +00:00
VideoWidget * vw = new VideoWidget ( movieAnn , movieAnn - > movie ( ) , m_document , this ) ;
2008-08-25 01:41:41 +00:00
frame - > videoWidgets . insert ( movieAnn - > movie ( ) , vw ) ;
2012-09-21 09:20:53 +00:00
vw - > pageInitialized ( ) ;
2008-08-25 01:41:41 +00:00
}
2015-08-04 09:11:29 +00:00
else if ( a - > subType ( ) = = Okular : : Annotation : : ARichMedia )
{
Okular : : RichMediaAnnotation * richMediaAnn = static_cast < Okular : : RichMediaAnnotation * > ( a ) ;
if ( richMediaAnn - > movie ( ) ) {
VideoWidget * vw = new VideoWidget ( richMediaAnn , richMediaAnn - > movie ( ) , m_document , this ) ;
frame - > videoWidgets . insert ( richMediaAnn - > movie ( ) , vw ) ;
vw - > pageInitialized ( ) ;
}
}
2012-09-27 12:15:58 +00:00
else if ( a - > subType ( ) = = Okular : : Annotation : : AScreen )
{
const Okular : : ScreenAnnotation * screenAnn = static_cast < Okular : : ScreenAnnotation * > ( a ) ;
Okular : : Movie * movie = GuiUtils : : renditionMovieFromScreenAnnotation ( screenAnn ) ;
if ( movie )
{
VideoWidget * vw = new VideoWidget ( screenAnn , movie , m_document , this ) ;
frame - > videoWidgets . insert ( movie , vw ) ;
vw - > pageInitialized ( ) ;
}
}
2008-08-25 01:41:41 +00:00
}
2008-04-09 14:04:39 +00:00
frame - > recalcGeometry ( m_width , m_height , screenRatio ) ;
2004-12-17 17:14:46 +00:00
// add the frame to the vector
m_frames . push_back ( frame ) ;
}
2009-11-10 19:07:23 +00:00
2004-12-17 17:14:46 +00:00
// get metadata from the document
m_metaStrings . clear ( ) ;
2014-05-11 09:17:49 +00:00
const Okular : : DocumentInfo info = m_document - > documentInfo ( QSet < Okular : : DocumentInfo : : Key > ( ) < < Okular : : DocumentInfo : : Title < < Okular : : DocumentInfo : : Author ) ;
if ( ! info . get ( Okular : : DocumentInfo : : Title ) . isNull ( ) )
m_metaStrings + = i18n ( " Title: %1 " , info . get ( Okular : : DocumentInfo : : Title ) ) ;
if ( ! info . get ( Okular : : DocumentInfo : : Author ) . isNull ( ) )
m_metaStrings + = i18n ( " Author: %1 " , info . get ( Okular : : DocumentInfo : : Author ) ) ;
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 " ) ;
2009-03-07 22:13:06 +00:00
m_isSetup = true ;
2004-12-17 17:14:46 +00:00
}
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
// 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
{
2008-04-11 19:53:59 +00:00
// if we are blocking the notifications, do nothing
if ( m_blockNotifications )
return ;
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 )
2007-08-23 21:36:41 +00:00
generatePage ( changedFlags & ( DocumentObserver : : Annotations | DocumentObserver : : Highlights ) ) ;
2004-12-22 18:21:36 +00:00
}
2012-08-16 15:37:39 +00:00
void PresentationWidget : : notifyCurrentPageChanged ( int previousPage , int currentPage )
{
if ( previousPage ! = - 1 )
{
// stop video playback
Q_FOREACH ( VideoWidget * vw , m_frames [ previousPage ] - > videoWidgets )
{
vw - > stop ( ) ;
vw - > pageLeft ( ) ;
}
// stop audio playback, if any
Okular : : AudioPlayer : : instance ( ) - > stopPlaybacks ( ) ;
// perform the page closing action, if any
if ( m_document - > page ( previousPage ) - > pageAction ( Okular : : Page : : Closing ) )
m_document - > processAction ( m_document - > page ( previousPage ) - > pageAction ( Okular : : Page : : Closing ) ) ;
2012-08-16 09:53:58 +00:00
// perform the additional actions of the page's annotations, if any
2012-09-25 09:58:48 +00:00
Q_FOREACH ( const Okular : : Annotation * annotation , m_document - > page ( previousPage ) - > annotations ( ) )
2012-08-16 09:53:58 +00:00
{
2017-09-05 21:27:18 +00:00
Okular : : Action * action = nullptr ;
2012-08-16 09:53:58 +00:00
if ( annotation - > subType ( ) = = Okular : : Annotation : : AScreen )
action = static_cast < const Okular : : ScreenAnnotation * > ( annotation ) - > additionalAction ( Okular : : Annotation : : PageClosing ) ;
else if ( annotation - > subType ( ) = = Okular : : Annotation : : AWidget )
action = static_cast < const Okular : : WidgetAnnotation * > ( annotation ) - > additionalAction ( Okular : : Annotation : : PageClosing ) ;
if ( action )
m_document - > processAction ( action ) ;
}
2012-08-16 15:37:39 +00:00
}
if ( currentPage ! = - 1 )
{
m_frameIndex = currentPage ;
// check if pixmap exists or else request it
PresentationFrame * frame = m_frames [ m_frameIndex ] ;
int pixW = frame - > geometry . width ( ) ;
int pixH = frame - > geometry . height ( ) ;
bool signalsBlocked = m_pagesEdit - > signalsBlocked ( ) ;
m_pagesEdit - > blockSignals ( true ) ;
m_pagesEdit - > setText ( QString : : number ( m_frameIndex + 1 ) ) ;
m_pagesEdit - > blockSignals ( signalsBlocked ) ;
// if pixmap not inside the Okular::Page we request it and wait for
// notifyPixmapChanged call or else we can proceed to pixmap generation
2017-10-14 12:47:20 +00:00
if ( ! frame - > page - > hasPixmap ( this , ceil ( pixW * qApp - > devicePixelRatio ( ) ) , ceil ( pixH * qApp - > devicePixelRatio ( ) ) ) )
2012-08-16 15:37:39 +00:00
{
requestPixmaps ( ) ;
}
else
{
// make the background pixmap
generatePage ( ) ;
}
// perform the page opening action, if any
if ( m_document - > page ( m_frameIndex ) - > pageAction ( Okular : : Page : : Opening ) )
m_document - > processAction ( m_document - > page ( m_frameIndex ) - > pageAction ( Okular : : Page : : Opening ) ) ;
2012-08-16 09:53:58 +00:00
// perform the additional actions of the page's annotations, if any
Q_FOREACH ( const Okular : : Annotation * annotation , m_document - > page ( m_frameIndex ) - > annotations ( ) )
{
2017-09-05 21:27:18 +00:00
Okular : : Action * action = nullptr ;
2012-08-16 09:53:58 +00:00
if ( annotation - > subType ( ) = = Okular : : Annotation : : AScreen )
action = static_cast < const Okular : : ScreenAnnotation * > ( annotation ) - > additionalAction ( Okular : : Annotation : : PageOpening ) ;
else if ( annotation - > subType ( ) = = Okular : : Annotation : : AWidget )
action = static_cast < const Okular : : WidgetAnnotation * > ( annotation ) - > additionalAction ( Okular : : Annotation : : PageOpening ) ;
if ( action )
m_document - > processAction ( action ) ;
}
2012-08-16 15:37:39 +00:00
// start autoplay video playback
Q_FOREACH ( VideoWidget * vw , m_frames [ m_frameIndex ] - > videoWidgets )
vw - > pageEntered ( ) ;
}
}
2006-11-20 20:10:42 +00:00
bool PresentationWidget : : canUnloadPixmap ( int pageNumber ) const
2004-12-17 17:14:46 +00:00
{
2012-10-15 22:27:42 +00:00
if ( Okular : : SettingsCore : : memoryLevel ( ) = = Okular : : SettingsCore : : EnumMemoryLevel : : Low | |
Okular : : SettingsCore : : memoryLevel ( ) = = Okular : : SettingsCore : : EnumMemoryLevel : : Normal )
2008-05-03 12:34:49 +00:00
{
// can unload all pixmaps except for the currently visible one
return pageNumber ! = m_frameIndex ;
}
else
{
// can unload all pixmaps except for the currently visible one, previous and next
return qAbs ( pageNumber - m_frameIndex ) < = 1 ;
}
2004-12-17 17:14:46 +00:00
}
2014-02-24 22:08:39 +00:00
void PresentationWidget : : setupActions ( )
2006-06-25 16:34:11 +00:00
{
2015-10-29 12:37:11 +00:00
addAction ( m_ac - > action ( QStringLiteral ( " first_page " ) ) ) ;
addAction ( m_ac - > action ( QStringLiteral ( " last_page " ) ) ) ;
2016-07-11 20:05:18 +00:00
addAction ( m_ac - > action ( QString : : fromLocal8Bit ( KStandardAction : : name ( KStandardAction : : Prior ) ) ) ) ;
addAction ( m_ac - > action ( QString : : fromLocal8Bit ( KStandardAction : : name ( KStandardAction : : Next ) ) ) ) ;
addAction ( m_ac - > action ( QString : : fromLocal8Bit ( KStandardAction : : name ( KStandardAction : : DocumentBack ) ) ) ) ;
addAction ( m_ac - > action ( QString : : fromLocal8Bit ( KStandardAction : : name ( KStandardAction : : DocumentForward ) ) ) ) ;
2008-09-11 08:40:00 +00:00
2015-10-29 12:37:11 +00:00
QAction * action = m_ac - > action ( QStringLiteral ( " switch_blackscreen_mode " ) ) ;
2014-10-01 17:40:48 +00:00
connect ( action , & QAction : : toggled , this , & PresentationWidget : : toggleBlackScreenMode ) ;
2012-06-07 14:35:13 +00:00
action - > setEnabled ( true ) ;
2008-09-11 08:40:00 +00:00
addAction ( action ) ;
2006-06-25 16:34:11 +00:00
}
2014-02-24 22:08:39 +00:00
void PresentationWidget : : setPlayPauseIcon ( )
{
2015-10-29 12:37:11 +00:00
QAction * playPauseAction = m_ac - > action ( QStringLiteral ( " presentation_play_pause " ) ) ;
2014-02-24 22:08:39 +00:00
if ( m_advanceSlides )
{
2015-10-29 12:37:11 +00:00
playPauseAction - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " media-playback-pause " ) ) ) ;
2014-02-24 22:08:39 +00:00
playPauseAction - > setToolTip ( i18nc ( " For Presentation " , " Pause " ) ) ;
}
else
{
2015-10-29 12:37:11 +00:00
playPauseAction - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " media-playback-start " ) ) ) ;
2014-02-24 22:08:39 +00:00
playPauseAction - > setToolTip ( i18nc ( " For Presentation " , " Play " ) ) ;
}
}
2004-12-17 17:14:46 +00:00
// <widget events>
2006-06-16 17:04:21 +00:00
bool PresentationWidget : : event ( QEvent * e )
{
2017-03-19 23:22:24 +00:00
if ( e - > type ( ) = = QEvent : : Gesture )
return gestureEvent ( static_cast < QGestureEvent * > ( e ) ) ;
2006-06-16 17:04:21 +00:00
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
2008-06-06 17:22:19 +00:00
return QWidget : : event ( e ) ;
2006-06-16 17:04:21 +00:00
}
2017-03-19 23:22:24 +00:00
bool PresentationWidget : : gestureEvent ( QGestureEvent * event )
{
// Swiping left or right on a touch screen will go to the previous or next slide, respectively.
// The precise gesture is the standard Qt swipe: with three(!) fingers.
if ( QGesture * swipe = event - > gesture ( Qt : : SwipeGesture ) )
{
QSwipeGesture * swipeEvent = static_cast < QSwipeGesture * > ( swipe ) ;
if ( swipeEvent - > state ( ) = = Qt : : GestureFinished )
{
if ( swipeEvent - > horizontalDirection ( ) = = QSwipeGesture : : Left )
{
slotPrevPage ( ) ;
event - > accept ( ) ;
return true ;
}
if ( swipeEvent - > horizontalDirection ( ) = = QSwipeGesture : : Right )
{
slotNextPage ( ) ;
event - > accept ( ) ;
return true ;
}
}
}
return false ;
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : keyPressEvent ( QKeyEvent * e )
{
2009-03-07 22:13:06 +00:00
if ( ! m_isSetup )
return ;
2005-06-13 16:47:01 +00:00
2009-03-01 14:32:24 +00:00
switch ( e - > key ( ) )
2004-12-17 17:14:46 +00:00
{
2009-03-01 14:32:24 +00:00
case Qt : : Key_Left :
case Qt : : Key_Backspace :
case Qt : : Key_PageUp :
2009-03-01 14:37:00 +00:00
case Qt : : Key_Up :
2009-03-01 14:32:24 +00:00
slotPrevPage ( ) ;
break ;
case Qt : : Key_Right :
case Qt : : Key_Space :
case Qt : : Key_PageDown :
2009-03-01 14:37:00 +00:00
case Qt : : Key_Down :
2009-03-01 14:32:24 +00:00
slotNextPage ( ) ;
break ;
case Qt : : Key_Home :
slotFirstPage ( ) ;
break ;
case Qt : : Key_End :
slotLastPage ( ) ;
break ;
case Qt : : Key_Escape :
if ( ! m_topBar - > isHidden ( ) )
2010-03-30 04:03:00 +00:00
showTopBar ( false ) ;
2009-03-01 14:32:24 +00:00
else
close ( ) ;
break ;
2004-12-17 17:14:46 +00:00
}
}
void PresentationWidget : : wheelEvent ( QWheelEvent * e )
{
2009-03-07 22:13:06 +00:00
if ( ! m_isSetup )
return ;
2009-01-12 00:01:07 +00:00
2004-12-17 17:14:46 +00:00
// performance note: don't remove the clipping
int div = e - > delta ( ) / 120 ;
if ( div > 0 )
{
if ( div > 3 )
div = 3 ;
while ( div - - )
2008-01-29 19:13:08 +00:00
slotPrevPage ( ) ;
2004-12-17 17:14:46 +00:00
}
else if ( div < 0 )
{
if ( div < - 3 )
div = - 3 ;
while ( div + + )
2008-01-29 19:13:08 +00:00
slotNextPage ( ) ;
2004-12-17 17:14:46 +00:00
}
}
void PresentationWidget : : mousePressEvent ( QMouseEvent * e )
{
2009-03-07 22:13:06 +00:00
if ( ! m_isSetup )
return ;
2009-01-12 00:01:07 +00:00
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 ;
2012-03-12 16:05:43 +00:00
const Okular : : Annotation * annotation = getAnnotation ( e - > x ( ) , e - > y ( ) ) ;
2012-09-27 12:15:58 +00:00
if ( annotation )
2012-03-12 16:05:43 +00:00
{
2012-09-27 12:15:58 +00:00
if ( annotation - > subType ( ) = = Okular : : Annotation : : AMovie )
{
const Okular : : MovieAnnotation * movieAnnotation = static_cast < const Okular : : MovieAnnotation * > ( annotation ) ;
2012-03-12 16:05:43 +00:00
2012-09-27 12:15:58 +00:00
VideoWidget * vw = m_frames [ m_frameIndex ] - > videoWidgets . value ( movieAnnotation - > movie ( ) ) ;
vw - > show ( ) ;
vw - > play ( ) ;
return ;
}
2015-08-04 09:11:29 +00:00
else if ( annotation - > subType ( ) = = Okular : : Annotation : : ARichMedia )
{
const Okular : : RichMediaAnnotation * richMediaAnnotation = static_cast < const Okular : : RichMediaAnnotation * > ( annotation ) ;
VideoWidget * vw = m_frames [ m_frameIndex ] - > videoWidgets . value ( richMediaAnnotation - > movie ( ) ) ;
vw - > show ( ) ;
vw - > play ( ) ;
return ;
}
2012-09-27 12:15:58 +00:00
else if ( annotation - > subType ( ) = = Okular : : Annotation : : AScreen )
{
m_document - > processAction ( static_cast < const Okular : : ScreenAnnotation * > ( annotation ) - > action ( ) ) ;
return ;
}
2012-03-12 16:05:43 +00:00
}
2005-07-18 17:51:27 +00:00
// handle clicking on top-right overlay
2010-04-02 19:20:54 +00:00
if ( ! ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : Hidden ) & &
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 ;
}
2017-03-19 23:35:05 +00:00
2019-01-08 12:50:20 +00:00
// Actual mouse press events always lead to the next page page
if ( e - > source ( ) = = Qt : : MouseEventNotSynthesized )
{
m_goToNextPageOnRelease = true ;
}
// Touch events may lead to the previous or next page
else if ( Okular : : Settings : : slidesTapNavigation ( ) ! = Okular : : Settings : : EnumSlidesTapNavigation : : Disabled )
{
switch ( Okular : : Settings : : slidesTapNavigation ( ) )
{
case Okular : : Settings : : EnumSlidesTapNavigation : : ForwardBackward :
{
if ( e - > x ( ) < ( geometry ( ) . width ( ) / 2 ) )
{
m_goToPreviousPageOnRelease = true ;
}
else
{
m_goToNextPageOnRelease = true ;
}
break ;
}
case Okular : : Settings : : EnumSlidesTapNavigation : : Forward :
{
m_goToNextPageOnRelease = true ;
break ;
}
case Okular : : Settings : : EnumSlidesTapNavigation : : Disabled :
{
// Do Nothing
}
}
}
2005-01-03 15:51:05 +00:00
}
2019-03-26 20:45:44 +00:00
// pressing forward button
2017-07-08 10:24:36 +00:00
else if ( e - > button ( ) = = Qt : : ForwardButton ) {
2019-03-26 20:45:44 +00:00
m_goToNextPageOnRelease = true ;
2017-07-08 10:24:36 +00:00
}
// pressing right or backward button
else if ( e - > button ( ) = = Qt : : RightButton | | e - > button ( ) = = Qt : : BackButton )
2019-03-26 20:45:44 +00:00
m_goToPreviousPageOnRelease = true ;
2004-12-17 17:14:46 +00:00
}
2005-07-18 17:51:27 +00:00
void PresentationWidget : : mouseReleaseEvent ( QMouseEvent * e )
{
2006-11-01 15:34:27 +00:00
if ( m_drawingEngine )
{
2015-10-17 21:57:07 +00:00
routeMouseDrawingEvent ( e ) ;
2006-11-01 15:34:27 +00:00
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 ) ;
2017-09-05 21:27:18 +00:00
m_pressedLink = nullptr ;
2005-07-18 17:51:27 +00:00
}
2017-03-19 23:22:24 +00:00
2019-01-08 12:50:20 +00:00
if ( m_goToPreviousPageOnRelease ) {
slotPrevPage ( ) ;
m_goToPreviousPageOnRelease = false ;
}
2017-03-19 23:35:05 +00:00
if ( m_goToNextPageOnRelease ) {
slotNextPage ( ) ;
m_goToNextPageOnRelease = false ;
}
2005-07-18 17:51:27 +00:00
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : mouseMoveEvent ( QMouseEvent * e )
{
2005-07-18 17:51:27 +00:00
// safety check
2009-03-07 22:13:06 +00:00
if ( ! m_isSetup )
2005-07-18 17:51:27 +00:00
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
{
2010-03-30 04:03:00 +00:00
showTopBar ( false ) ;
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 ) ;
2012-05-31 18:22:14 +00:00
if ( r . isValid ( ) )
2006-11-01 15:34:27 +00:00
{
m_drawingRect | = r . translated ( m_frames [ m_frameIndex ] - > geometry . topLeft ( ) ) ;
update ( m_drawingRect ) ;
}
}
else
{
// show the bar if reaching top 2 pixels
2008-04-07 18:16:39 +00:00
if ( e - > y ( ) < = 1 )
2010-03-30 04:03:00 +00:00
showTopBar ( true ) ;
2006-11-01 15:34:27 +00:00
// 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 )
{
2017-10-14 12:47:20 +00:00
qreal dpr = devicePixelRatioF ( ) ;
2008-09-11 08:40:00 +00:00
if ( m_inBlackScreenMode )
{
QPainter painter ( this ) ;
painter . fillRect ( pe - > rect ( ) , Qt : : black ) ;
return ;
}
2009-03-07 22:13:06 +00:00
if ( ! m_isSetup )
2005-03-05 15:59:15 +00:00
{
2008-04-07 18:16:39 +00:00
m_width = width ( ) ;
m_height = height ( ) ;
2005-03-05 15:59:15 +00:00
2014-10-01 17:40:48 +00:00
connect ( m_document , & Okular : : Document : : linkFind , this , & PresentationWidget : : slotFind ) ;
2007-03-17 22:58:41 +00:00
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 ( ) ;
}
2019-01-11 07:09:34 +00:00
// check painting rect consistency
2016-07-24 21:46:53 +00:00
QRect r = pe - > rect ( ) . intersected ( QRect ( QPoint ( 0 , 0 ) , geometry ( ) . size ( ) ) ) ;
2008-04-16 11:12:21 +00:00
if ( r . isNull ( ) )
2004-12-17 17:14:46 +00:00
return ;
2008-04-16 11:12:21 +00:00
if ( m_lastRenderedPixmap . isNull ( ) )
{
QPainter painter ( this ) ;
painter . fillRect ( pe - > rect ( ) , Okular : : Settings : : slidesBackgroundColor ( ) ) ;
return ;
}
2004-12-17 17:14:46 +00:00
// 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
2017-10-14 12:47:20 +00:00
const QRect dR ( QRectF ( r . x ( ) * dpr , r . y ( ) * dpr , r . width ( ) * dpr , r . height ( ) * dpr ) . toAlignedRect ( ) ) ;
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
2017-10-14 12:47:20 +00:00
QPixmap backPixmap ( dR . size ( ) ) ;
backPixmap . setDevicePixelRatio ( dpr ) ;
2004-12-17 17:14:46 +00:00
QPainter pixPainter ( & backPixmap ) ;
// first draw the background on the backbuffer
2017-10-14 12:47:20 +00:00
pixPainter . drawPixmap ( QPoint ( 0 , 0 ) , m_lastRenderedPixmap , dR ) ;
2004-12-17 17:14:46 +00:00
// then blend the overlay (a piece of) over the background
2016-07-24 21:46:53 +00:00
QRect ovr = m_overlayGeometry . intersected ( r ) ;
2017-10-14 12:47:20 +00:00
pixPainter . drawPixmap ( ( ovr . left ( ) - r . left ( ) ) , ( ovr . top ( ) - r . top ( ) ) ,
m_lastRenderedOverlay , ( ovr . left ( ) - m_overlayGeometry . left ( ) ) * dpr ,
( ovr . top ( ) - m_overlayGeometry . top ( ) ) * dpr , ovr . width ( ) * dpr , ovr . height ( ) * dpr ) ;
2004-12-17 17:14:46 +00:00
// finally blit the pixmap to the screen
pixPainter . end ( ) ;
2017-10-14 12:47:20 +00:00
const QRect backPixmapRect = backPixmap . rect ( ) ;
const QRect dBackPixmapRect ( QRectF ( backPixmapRect . x ( ) * dpr , backPixmapRect . y ( ) * dpr , backPixmapRect . width ( ) * dpr , backPixmapRect . height ( ) * dpr ) . toAlignedRect ( ) ) ;
painter . drawPixmap ( r . topLeft ( ) , backPixmap , dBackPixmapRect ) ;
2004-12-17 17:14:46 +00:00
} else
# endif
// copy the rendered pixmap to the screen
2017-10-14 12:47:20 +00:00
painter . drawPixmap ( r . topLeft ( ) , m_lastRenderedPixmap , dR ) ;
2004-12-17 17:14:46 +00:00
}
2012-06-07 13:48:53 +00:00
// paint drawings
if ( m_frameIndex ! = - 1 )
2006-11-01 15:34:27 +00:00
{
painter . save ( ) ;
2012-06-07 13:48:53 +00:00
2015-08-10 11:05:12 +00:00
const QRect & geom = m_frames [ m_frameIndex ] - > geometry ;
2019-06-15 21:24:30 +00:00
const QSize pmSize ( geom . width ( ) * dpr , geom . height ( ) * dpr ) ;
QPixmap pm ( pmSize ) ;
2015-08-10 11:05:12 +00:00
pm . fill ( Qt : : transparent ) ;
QPainter pmPainter ( & pm ) ;
2019-06-15 21:24:30 +00:00
pm . setDevicePixelRatio ( dpr ) ;
2015-08-10 11:05:12 +00:00
pmPainter . setRenderHints ( QPainter : : Antialiasing ) ;
2019-06-15 21:24:30 +00:00
// Paint old paths
2012-09-08 17:29:28 +00:00
foreach ( const SmoothPath & drawing , m_frames [ m_frameIndex ] - > drawings )
2019-06-15 21:24:30 +00:00
drawing . paint ( & pmPainter , pmSize . width ( ) , pmSize . height ( ) ) ;
2012-06-07 13:48:53 +00:00
2019-06-15 21:24:30 +00:00
// Paint the path that is currently being drawn by the user
2012-06-07 13:48:53 +00:00
if ( m_drawingEngine & & m_drawingRect . intersects ( pe - > rect ( ) ) )
2019-06-15 21:24:30 +00:00
m_drawingEngine - > paint ( & pmPainter , pmSize . width ( ) , pmSize . height ( ) , m_drawingRect . intersected ( pe - > rect ( ) ) ) ;
2015-08-10 11:05:12 +00:00
painter . setRenderHints ( QPainter : : Antialiasing ) ;
painter . drawPixmap ( geom . topLeft ( ) , pm ) ;
2012-06-07 13:48:53 +00:00
2006-11-01 15:34:27 +00:00
painter . restore ( ) ;
}
2006-06-30 18:36:41 +00:00
painter . end ( ) ;
2004-12-17 17:14:46 +00:00
}
2008-11-29 17:45:25 +00:00
void PresentationWidget : : resizeEvent ( QResizeEvent * re )
{
2014-09-11 17:36:01 +00:00
// qCDebug(OkularUiDebug) << re->oldSize() << "=>" << re->size();
2008-11-29 17:45:25 +00:00
if ( re - > oldSize ( ) = = QSize ( - 1 , - 1 ) )
return ;
m_screen = QApplication : : desktop ( ) - > screenNumber ( this ) ;
applyNewScreenSize ( re - > oldSize ( ) ) ;
}
2009-10-07 22:28:06 +00:00
2010-03-30 19:59:59 +00:00
void PresentationWidget : : leaveEvent ( QEvent * e )
{
Q_UNUSED ( e )
if ( ! m_topBar - > isHidden ( ) )
{
showTopBar ( false ) ;
}
}
2010-03-30 19:45:48 +00:00
// </widget events>
2004-12-17 17:14:46 +00:00
2012-03-12 16:05:43 +00:00
const void * PresentationWidget : : getObjectRect ( Okular : : ObjectRect : : ObjectType type , 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 ( ) )
2017-09-05 21:27:18 +00:00
return nullptr ;
2005-07-18 17:51:27 +00:00
// 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 )
2017-09-05 21:27:18 +00:00
return nullptr ;
2005-07-18 17:51:27 +00:00
// check if 1) there is an object and 2) it's a link
2008-04-07 18:16:39 +00:00
const QRect d = QApplication : : desktop ( ) - > screenGeometry ( m_screen ) ;
2012-03-12 16:05:43 +00:00
const Okular : : ObjectRect * object = page - > objectRect ( type , nx , ny , d . width ( ) , d . height ( ) ) ;
2005-07-18 17:51:27 +00:00
if ( ! object )
2017-09-05 21:27:18 +00:00
return nullptr ;
2005-07-18 17:51:27 +00:00
// 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
2012-03-12 16:05:43 +00:00
return object - > object ( ) ;
}
const Okular : : Action * PresentationWidget : : getLink ( int x , int y , QRect * geometry ) const
{
return reinterpret_cast < const Okular : : Action * > ( getObjectRect ( Okular : : ObjectRect : : Action , x , y , geometry ) ) ;
}
const Okular : : Annotation * PresentationWidget : : getAnnotation ( int x , int y , QRect * geometry ) const
{
return reinterpret_cast < const Okular : : Annotation * > ( getObjectRect ( Okular : : ObjectRect : : OAnnotation , x , y , geometry ) ) ;
2005-07-18 17:51:27 +00:00
}
void PresentationWidget : : testCursorOnLink ( int x , int y )
{
2017-09-05 21:27:18 +00:00
const Okular : : Action * link = getLink ( x , y , nullptr ) ;
const Okular : : Annotation * annotation = getAnnotation ( x , y , nullptr ) ;
2012-03-12 16:05:43 +00:00
2017-09-05 21:27:18 +00:00
const bool needsHandCursor = ( ( link ! = nullptr ) | |
( ( annotation ! = nullptr ) & & ( annotation - > subType ( ) = = Okular : : Annotation : : AMovie ) ) | |
( ( annotation ! = nullptr ) & & ( annotation - > subType ( ) = = Okular : : Annotation : : ARichMedia ) ) | |
( ( annotation ! = nullptr ) & & ( annotation - > subType ( ) = = Okular : : Annotation : : AScreen ) & & ( GuiUtils : : renditionMovieFromScreenAnnotation ( static_cast < const Okular : : ScreenAnnotation * > ( annotation ) ) ! = nullptr ) ) ) ;
2005-07-18 17:51:27 +00:00
// only react on changes (in/out from a link)
2012-03-12 16:05:43 +00:00
if ( ( needsHandCursor & & ! m_handCursor ) | | ( ! needsHandCursor & & m_handCursor ) )
2005-07-18 17:51:27 +00:00
{
// change cursor shape
2012-03-12 16:05:43 +00:00
m_handCursor = needsHandCursor ;
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 )
{
2012-08-16 15:37:39 +00:00
if ( m_showSummaryView ) {
m_showSummaryView = false ;
m_frameIndex = - 1 ;
2005-01-03 15:51:05 +00:00
return ;
2012-06-06 20:07:16 +00:00
}
2012-08-16 15:37:39 +00:00
if ( m_frameIndex = = newPage )
return ;
2006-09-09 17:31:36 +00:00
2012-08-16 15:37:39 +00:00
// switch to newPage
2013-02-24 21:58:53 +00:00
m_document - > setViewportPage ( newPage , this ) ;
2007-02-05 00:49:40 +00:00
2012-08-16 15:37:39 +00:00
if ( ( Okular : : Settings : : slidesShowSummary ( ) & & ! m_showSummaryView ) | | m_frameIndex = = - 1 )
notifyCurrentPageChanged ( - 1 , newPage ) ;
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 ( ) )
2015-07-16 23:02:07 +00:00
{
2017-10-14 12:47:20 +00:00
qreal dpr = qApp - > devicePixelRatio ( ) ;
m_lastRenderedPixmap = QPixmap ( m_width * dpr , m_height * dpr ) ;
m_lastRenderedPixmap . setDevicePixelRatio ( dpr ) ;
2015-07-16 23:02:07 +00:00
m_previousPagePixmap = QPixmap ( ) ;
}
else
{
m_previousPagePixmap = m_lastRenderedPixmap ;
}
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
2008-03-13 13:00:37 +00:00
if ( ! disableTransition & & Okular : : Settings : : slidesTransitionsEnabled ( ) )
2006-11-01 15:34:27 +00:00
{
const Okular : : PageTransition * transition = m_frameIndex ! = - 1 ?
2017-09-05 21:27:18 +00:00
m_frames [ m_frameIndex ] - > page - > transition ( ) : nullptr ;
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
2010-03-30 05:14:21 +00:00
if ( ! m_drawingEngine & & 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 )
{
2017-10-14 12:47:20 +00:00
qreal dpr = qApp - > devicePixelRatio ( ) ;
2004-12-17 17:14:46 +00:00
// 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
2017-10-14 12:47:20 +00:00
QPixmap logo = DesktopIcon ( QStringLiteral ( " okular " ) , 64 * dpr ) ;
logo . setDevicePixelRatio ( dpr ) ;
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 ;
2017-10-14 12:47:20 +00:00
2013-02-24 21:58:53 +00:00
PagePainter : : paintPageOnPainter ( & p , frame - > page , this , flags ,
2005-04-01 16:24:11 +00:00
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 ) ) ;
2016-07-24 21:46:53 +00:00
QVector < QRect > rects = unpainted . subtracted ( frame - > geometry ) . rects ( ) ;
2006-03-24 19:35:20 +00:00
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
2017-10-14 12:47:20 +00:00
qreal dpr = qApp - > devicePixelRatio ( ) ;
2004-12-17 17:14:46 +00:00
// 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 ;
2017-10-14 12:47:20 +00:00
QPixmap doublePixmap ( side * dpr , side * dpr ) ;
doublePixmap . setDevicePixelRatio ( dpr ) ;
2004-12-17 17:14:46 +00:00
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 ( ) ;
2017-10-14 12:47:20 +00:00
QImage image ( doublePixmap . toImage ( ) . scaled ( ( side / 2 ) * dpr , ( side / 2 ) * dpr , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ) ;
image . setDevicePixelRatio ( dpr ) ;
2006-06-25 15:50:35 +00:00
image = image . convertToFormat ( QImage : : Format_ARGB32 ) ;
2017-10-14 12:47:20 +00:00
image . setDevicePixelRatio ( dpr ) ;
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 ( ) ;
2017-10-14 12:47:20 +00:00
QImage shadow ( doublePixmap . toImage ( ) . scaled ( ( side / 2 ) * dpr , ( side / 2 ) * dpr , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ) ;
shadow . setDevicePixelRatio ( dpr ) ;
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 ) ;
2017-10-14 12:47:20 +00:00
m_lastRenderedOverlay . setDevicePixelRatio ( dpr ) ;
2004-12-17 17:14:46 +00:00
// start the autohide timer
2008-04-07 18:34:33 +00:00
//repaint( m_overlayGeometry ); // toggle with next line
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 )
{
2012-05-31 18:22:14 +00:00
if ( m_frameIndex = = - 1 ) // Can't draw on the summary page
return QRect ( ) ;
2006-11-01 15:34:27 +00:00
const QRect & geom = m_frames [ m_frameIndex ] - > geometry ;
const Okular : : Page * page = m_frames [ m_frameIndex ] - > page ;
2010-08-18 19:14:54 +00:00
AnnotatorEngine : : EventType eventType ;
AnnotatorEngine : : Button button ;
// figure out the event type and button
AnnotatorEngine : : decodeEvent ( e , & eventType , & button ) ;
2006-11-01 15:34:27 +00:00
static bool hasclicked = false ;
if ( eventType = = AnnotatorEngine : : Press )
hasclicked = true ;
2019-06-15 21:24:30 +00:00
QPointF mousePos = e - > localPos ( ) ;
double nX = ( mousePos . x ( ) - ( double ) geom . left ( ) ) / ( double ) geom . width ( ) ;
double nY = ( mousePos . y ( ) - ( double ) geom . top ( ) ) / ( double ) geom . height ( ) ;
2006-11-01 15:34:27 +00:00
QRect ret ;
2015-10-17 21:57:07 +00:00
bool isInside = nX > = 0 & & nX < 1 & & nY > = 0 & & nY < 1 ;
if ( hasclicked & & ! isInside ) {
// Fake a move to the last border pos
nX = qBound ( 0. , nX , 1. ) ;
nY = qBound ( 0. , nY , 1. ) ;
m_drawingEngine - > event ( AnnotatorEngine : : Move , button , nX , nY , geom . width ( ) , geom . height ( ) , page ) ;
// Fake a release in the following lines
eventType = AnnotatorEngine : : Release ;
isInside = true ;
} else if ( ! hasclicked & & isInside )
{
// we're coming from the outside, pretend we started clicking at the closest border
if ( nX < ( 1 - nX ) & & nX < nY & & nX < ( 1 - nY ) )
nX = 0 ;
else if ( nY < ( 1 - nY ) & & nY < nX & & nY < ( 1 - nX ) )
nY = 0 ;
else if ( ( 1 - nX ) < nX & & ( 1 - nX ) < nY & & ( 1 - nX ) < ( 1 - nY ) )
nX = 1 ;
else
nY = 1 ;
hasclicked = true ;
eventType = AnnotatorEngine : : Press ;
}
if ( hasclicked & & isInside )
{
2006-11-01 15:34:27 +00:00
ret = m_drawingEngine - > event ( eventType , button , nX , nY , geom . width ( ) , geom . height ( ) , page ) ;
2015-10-17 21:57:07 +00:00
}
2006-11-01 15:34:27 +00:00
if ( eventType = = AnnotatorEngine : : Release )
2015-10-17 21:57:07 +00:00
{
2006-11-01 15:34:27 +00:00
hasclicked = false ;
2015-10-17 21:57:07 +00:00
}
if ( m_drawingEngine - > creationCompleted ( ) )
{
// add drawing to current page
m_frames [ m_frameIndex ] - > drawings < < m_drawingEngine - > endSmoothPath ( ) ;
// 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
2015-10-18 20:29:00 +00:00
slotChangeDrawingToolEngine ( QDomElement ( ) ) ;
slotChangeDrawingToolEngine ( m_currentDrawingToolElement ) ;
2015-10-17 21:57:07 +00:00
// schedule repaint
update ( ) ;
}
2006-11-01 15:34:27 +00:00
return ret ;
}
2006-12-31 10:48:49 +00:00
void PresentationWidget : : startAutoChangeTimer ( )
{
2009-11-10 19:07:23 +00:00
double pageDuration = m_frameIndex > = 0 & & m_frameIndex < ( int ) m_frames . count ( ) ? m_frames [ m_frameIndex ] - > page - > duration ( ) : - 1 ;
2014-02-24 21:39:08 +00:00
if ( m_advanceSlides | | pageDuration > = 0.0 )
2006-12-31 10:48:49 +00:00
{
2014-10-30 23:06:12 +00:00
double secs ;
if ( pageDuration < 0.0 )
secs = Okular : : SettingsCore : : slidesAdvanceTime ( ) ;
else if ( m_advanceSlides )
secs = qMin < double > ( pageDuration , Okular : : SettingsCore : : slidesAdvanceTime ( ) ) ;
else
secs = pageDuration ;
2009-11-10 19:07:23 +00:00
m_nextPageTimer - > start ( ( int ) ( secs * 1000 ) ) ;
2006-12-31 10:48:49 +00:00
}
}
2008-04-07 18:16:39 +00:00
void PresentationWidget : : recalcGeometry ( )
{
QDesktopWidget * desktop = QApplication : : desktop ( ) ;
const int preferenceScreen = Okular : : Settings : : slidesScreen ( ) ;
2008-04-11 18:25:15 +00:00
int screen = 0 ;
if ( preferenceScreen = = - 2 )
{
2009-02-20 11:17:54 +00:00
screen = desktop - > screenNumber ( m_parentWidget ) ;
2008-04-11 18:25:15 +00:00
}
else if ( preferenceScreen = = - 1 )
{
screen = desktop - > primaryScreen ( ) ;
}
else if ( preferenceScreen > = 0 & & preferenceScreen < desktop - > numScreens ( ) )
2008-04-07 18:16:39 +00:00
{
screen = preferenceScreen ;
}
else
{
2009-02-20 11:17:54 +00:00
screen = desktop - > screenNumber ( m_parentWidget ) ;
2008-04-11 18:25:15 +00:00
Okular : : Settings : : setSlidesScreen ( - 2 ) ;
2008-04-07 18:16:39 +00:00
}
const QRect screenGeom = desktop - > screenGeometry ( screen ) ;
2014-09-11 17:36:01 +00:00
// qCDebug(OkularUiDebug) << screen << "=>" << screenGeom;
2008-04-07 18:16:39 +00:00
m_screen = screen ;
setGeometry ( screenGeom ) ;
}
void PresentationWidget : : repositionContent ( )
{
const QRect ourGeom = geometry ( ) ;
2016-02-22 10:56:17 +00:00
// tool bar height in pixels, make it large enough to hold the text fields with the page numbers
const int toolBarHeight = m_pagesEdit - > height ( ) * 1.5 ;
m_topBar - > setGeometry ( 0 , 0 , ourGeom . width ( ) , toolBarHeight ) ;
m_topBar - > setIconSize ( QSize ( toolBarHeight * 0.75 , toolBarHeight * 0.75 ) ) ;
2008-04-07 18:16:39 +00:00
}
2006-11-01 15:34:27 +00:00
2008-04-09 14:04:39 +00:00
void PresentationWidget : : requestPixmaps ( )
{
PresentationFrame * frame = m_frames [ m_frameIndex ] ;
int pixW = frame - > geometry . width ( ) ;
int pixH = frame - > geometry . height ( ) ;
// operation will take long: set busy cursor
QApplication : : setOverrideCursor ( QCursor ( Qt : : BusyCursor ) ) ;
// request the pixmap
QLinkedList < Okular : : PixmapRequest * > requests ;
2013-02-24 21:58:53 +00:00
requests . push_back ( new Okular : : PixmapRequest ( this , m_frameIndex , pixW , pixH , PRESENTATION_PRIO , Okular : : PixmapRequest : : NoFeature ) ) ;
2008-04-09 14:04:39 +00:00
// restore cursor
QApplication : : restoreOverrideCursor ( ) ;
// ask for next and previous page if not in low memory usage setting
2012-10-15 22:27:42 +00:00
if ( Okular : : SettingsCore : : memoryLevel ( ) ! = Okular : : SettingsCore : : EnumMemoryLevel : : Low )
2008-04-09 14:04:39 +00:00
{
2012-07-02 18:57:33 +00:00
int pagesToPreload = 1 ;
2012-03-08 23:12:20 +00:00
// If greedy, preload everything
2012-10-15 22:27:42 +00:00
if ( Okular : : SettingsCore : : memoryLevel ( ) = = Okular : : SettingsCore : : EnumMemoryLevel : : Greedy )
2012-07-02 18:57:33 +00:00
pagesToPreload = ( int ) m_document - > pages ( ) ;
2013-02-24 21:58:53 +00:00
Okular : : PixmapRequest : : PixmapRequestFeatures requestFeatures = Okular : : PixmapRequest : : Preload ;
requestFeatures | = Okular : : PixmapRequest : : Asynchronous ;
2012-07-02 18:57:33 +00:00
for ( int j = 1 ; j < = pagesToPreload ; j + + )
2012-03-08 23:12:20 +00:00
{
2012-07-02 18:57:33 +00:00
int tailRequest = m_frameIndex + j ;
if ( tailRequest < ( int ) m_document - > pages ( ) )
2012-03-08 23:12:20 +00:00
{
2012-07-02 18:57:33 +00:00
PresentationFrame * nextFrame = m_frames [ tailRequest ] ;
pixW = nextFrame - > geometry . width ( ) ;
pixH = nextFrame - > geometry . height ( ) ;
2013-02-24 21:58:53 +00:00
if ( ! nextFrame - > page - > hasPixmap ( this , pixW , pixH ) )
requests . push_back ( new Okular : : PixmapRequest ( this , tailRequest , pixW , pixH , PRESENTATION_PRELOAD_PRIO , requestFeatures ) ) ;
2012-03-08 23:12:20 +00:00
}
2012-07-02 18:57:33 +00:00
int headRequest = m_frameIndex - j ;
if ( headRequest > = 0 )
{
PresentationFrame * prevFrame = m_frames [ headRequest ] ;
pixW = prevFrame - > geometry . width ( ) ;
pixH = prevFrame - > geometry . height ( ) ;
2013-02-24 21:58:53 +00:00
if ( ! prevFrame - > page - > hasPixmap ( this , pixW , pixH ) )
requests . push_back ( new Okular : : PixmapRequest ( this , headRequest , pixW , pixH , PRESENTATION_PRELOAD_PRIO , requestFeatures ) ) ;
2012-07-02 18:57:33 +00:00
}
// stop if we've already reached both ends of the document
if ( headRequest < 0 & & tailRequest > = ( int ) m_document - > pages ( ) )
break ;
2012-03-08 23:12:20 +00:00
}
2008-04-09 14:04:39 +00:00
}
m_document - > requestPixmaps ( requests ) ;
}
2004-12-17 17:14:46 +00:00
void PresentationWidget : : slotNextPage ( )
{
2012-06-06 20:07:16 +00:00
int nextIndex = m_frameIndex + 1 ;
2005-01-03 23:31:40 +00:00
// loop when configured
2012-06-06 20:07:16 +00:00
if ( nextIndex = = m_frames . count ( ) & & Okular : : Settings : : slidesLoop ( ) )
nextIndex = 0 ;
2005-01-03 23:31:40 +00:00
2012-06-06 20:07:16 +00:00
if ( nextIndex < m_frames . count ( ) )
2004-12-17 17:14:46 +00:00
{
// go to next page
2012-06-06 20:07:16 +00:00
changePage ( nextIndex ) ;
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 ( ) ;
2015-07-16 23:02:07 +00:00
m_lastRenderedPixmap = m_currentPagePixmap ;
2005-11-04 11:59:51 +00:00
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 ( ) ;
2015-07-16 23:02:07 +00:00
m_lastRenderedPixmap = m_currentPagePixmap ;
2005-11-04 11:59:51 +00:00
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 ( )
{
2015-07-16 23:02:07 +00:00
switch ( m_currentTransition . type ( ) )
2005-01-08 00:12:08 +00:00
{
2015-07-16 23:02:07 +00:00
case Okular : : PageTransition : : Fade :
{
QPainter pixmapPainter ;
2015-10-14 22:10:39 +00:00
m_currentPixmapOpacity + = 1.0 / m_transitionSteps ;
2015-07-16 23:02:07 +00:00
m_lastRenderedPixmap = QPixmap ( m_lastRenderedPixmap . size ( ) ) ;
2017-10-14 12:47:20 +00:00
m_lastRenderedPixmap . setDevicePixelRatio ( qApp - > devicePixelRatio ( ) ) ;
2015-07-16 23:02:07 +00:00
m_lastRenderedPixmap . fill ( Qt : : transparent ) ;
pixmapPainter . begin ( & m_lastRenderedPixmap ) ;
pixmapPainter . setCompositionMode ( QPainter : : CompositionMode_Source ) ;
pixmapPainter . setOpacity ( 1 - m_currentPixmapOpacity ) ;
pixmapPainter . drawPixmap ( 0 , 0 , m_previousPagePixmap ) ;
pixmapPainter . setOpacity ( m_currentPixmapOpacity ) ;
pixmapPainter . drawPixmap ( 0 , 0 , m_currentPagePixmap ) ;
update ( ) ;
if ( m_currentPixmapOpacity > = 1 )
return ;
} break ;
default :
{
if ( m_transitionRects . empty ( ) )
{
// it's better to fix the transition to cover the whole screen than
// enabling the following line that wastes cpu for nothing
//update();
return ;
}
2004-12-17 17:14:46 +00:00
2015-07-16 23:02:07 +00:00
for ( int i = 0 ; i < m_transitionMul & & ! m_transitionRects . empty ( ) ; i + + )
{
update ( m_transitionRects . first ( ) ) ;
m_transitionRects . pop_front ( ) ;
}
} break ;
2004-12-17 17:14:46 +00:00
}
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 ( )
{
2008-04-07 18:16:39 +00:00
recalcGeometry ( ) ;
repositionContent ( ) ;
2008-04-09 15:05:08 +00:00
if ( m_screenSelect )
{
2008-04-11 18:25:15 +00:00
m_screenSelect - > setCurrentItem ( m_screen ) ;
2015-03-17 08:08:04 +00:00
connect ( m_screenSelect - > selectableActionGroup ( ) , & QActionGroup : : triggered ,
this , & PresentationWidget : : chooseScreen ) ;
2008-04-09 15:05:08 +00:00
}
2008-04-07 18:16:39 +00:00
// show widget and take control
show ( ) ;
setWindowState ( windowState ( ) | Qt : : WindowFullScreen ) ;
2015-10-29 12:37:11 +00:00
connect ( QApplication : : desktop ( ) , & QDesktopWidget : : resized , this , & PresentationWidget : : screenResized ) ;
2008-04-07 18:16:39 +00:00
2006-05-13 16:50:53 +00:00
// inform user on how to exit from presentation mode
2015-10-29 12:37:11 +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 ( ) , QStringLiteral ( " 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 ) ;
}
2015-08-22 14:00:04 +00:00
void PresentationWidget : : slotChangeDrawingToolEngine ( const QDomElement & element )
2006-11-01 15:34:27 +00:00
{
2015-08-22 14:00:04 +00:00
if ( element . isNull ( ) )
2006-11-01 15:34:27 +00:00
{
delete m_drawingEngine ;
2017-09-05 21:27:18 +00:00
m_drawingEngine = nullptr ;
2006-11-01 15:34:27 +00:00
m_drawingRect = QRect ( ) ;
2007-08-14 23:23:16 +00:00
setCursor ( Qt : : ArrowCursor ) ;
2006-11-01 15:34:27 +00:00
}
2015-08-22 14:00:04 +00:00
else
{
m_drawingEngine = new SmoothPathEngine ( element ) ;
setCursor ( QCursor ( QPixmap ( QStringLiteral ( " pencil " ) ) , Qt : : ArrowCursor ) ) ;
m_currentDrawingToolElement = element ;
}
2006-11-01 15:34:27 +00:00
}
2015-08-22 20:15:32 +00:00
void PresentationWidget : : slotAddDrawingToolActions ( )
{
DrawingToolActions * drawingToolActions = qobject_cast < DrawingToolActions * > ( sender ( ) ) ;
foreach ( QAction * action , drawingToolActions - > actions ( ) ) {
action - > setEnabled ( true ) ;
m_topBar - > addAction ( action ) ;
addAction ( action ) ;
}
}
2015-08-22 14:00:04 +00:00
2006-11-01 15:34:27 +00:00
void PresentationWidget : : clearDrawings ( )
{
2012-09-08 17:29:28 +00:00
if ( m_frameIndex ! = - 1 )
m_frames [ m_frameIndex ] - > drawings . clear ( ) ;
2012-06-07 13:48:53 +00:00
update ( ) ;
2006-11-01 15:34:27 +00:00
}
2008-04-07 18:16:39 +00:00
void PresentationWidget : : screenResized ( int screen )
{
// we can ignore if a screen was resized in the case the screen is not
// where we are on
2008-04-11 18:25:15 +00:00
if ( screen ! = m_screen )
2008-04-07 18:16:39 +00:00
return ;
2008-04-11 20:41:22 +00:00
setScreen ( screen ) ;
2008-04-07 18:16:39 +00:00
}
2008-04-09 15:05:08 +00:00
void PresentationWidget : : chooseScreen ( QAction * act )
{
if ( ! act | | act - > data ( ) . type ( ) ! = QVariant : : Int )
return ;
const int newScreen = act - > data ( ) . toInt ( ) ;
2008-04-11 20:41:22 +00:00
setScreen ( newScreen ) ;
}
2008-09-11 08:40:00 +00:00
void PresentationWidget : : toggleBlackScreenMode ( bool )
{
m_inBlackScreenMode = ! m_inBlackScreenMode ;
update ( ) ;
}
2008-04-11 20:41:22 +00:00
void PresentationWidget : : setScreen ( int newScreen )
{
2008-04-09 15:05:08 +00:00
const QRect screenGeom = QApplication : : desktop ( ) - > screenGeometry ( newScreen ) ;
const QSize oldSize = size ( ) ;
2014-09-11 17:36:01 +00:00
// qCDebug(OkularUiDebug) << newScreen << "=>" << screenGeom;
2008-04-09 15:05:08 +00:00
m_screen = newScreen ;
setGeometry ( screenGeom ) ;
2008-11-29 17:45:25 +00:00
applyNewScreenSize ( oldSize ) ;
}
void PresentationWidget : : applyNewScreenSize ( const QSize & oldSize )
{
2008-04-09 15:05:08 +00:00
repositionContent ( ) ;
// if by chance the new screen has the same resolution of the previous,
// do not invalidate pixmaps and such..
if ( size ( ) = = oldSize )
return ;
m_width = width ( ) ;
m_height = height ( ) ;
// update the frames
const float screenRatio = ( float ) m_height / ( float ) m_width ;
2019-03-26 22:37:30 +00:00
for ( PresentationFrame * frame : qAsConst ( m_frames ) )
2008-04-09 15:05:08 +00:00
{
2019-03-26 22:37:30 +00:00
frame - > recalcGeometry ( m_width , m_height , screenRatio ) ;
2008-04-09 15:05:08 +00:00
}
2008-11-29 17:45:25 +00:00
if ( m_frameIndex ! = - 1 )
{
2008-10-24 07:10:18 +00:00
// ugliness alarm!
2013-02-24 21:58:53 +00:00
const_cast < Okular : : Page * > ( m_frames [ m_frameIndex ] - > page ) - > deletePixmap ( this ) ;
2008-04-11 19:53:59 +00:00
// force the regeneration of the pixmap
m_lastRenderedPixmap = QPixmap ( ) ;
m_blockNotifications = true ;
2008-04-09 15:05:08 +00:00
requestPixmaps ( ) ;
2008-04-11 19:53:59 +00:00
m_blockNotifications = false ;
2008-11-29 17:45:25 +00:00
}
2015-07-16 23:02:07 +00:00
if ( m_transitionTimer - > isActive ( ) )
{
m_transitionTimer - > stop ( ) ;
}
2008-04-09 15:05:08 +00:00
generatePage ( true /* no transitions */ ) ;
}
2012-01-18 20:34:12 +00:00
void PresentationWidget : : inhibitPowerManagement ( )
2008-08-30 17:31:59 +00:00
{
2016-07-24 21:36:03 +00:00
# ifdef Q_OS_LINUX
2012-01-18 00:04:06 +00:00
QString reason = i18nc ( " Reason for inhibiting the screensaver activation, when the presentation mode is active " , " Giving a presentation " ) ;
2016-07-24 21:36:03 +00:00
if ( ! m_screenInhibitCookie ) {
2019-04-25 21:10:48 +00:00
QDBusMessage message = QDBusMessage : : createMethodCall ( QStringLiteral ( " org.freedesktop.ScreenSaver " ) , QStringLiteral ( " /ScreenSaver " ) ,
QStringLiteral ( " org.freedesktop.ScreenSaver " ) , QStringLiteral ( " Inhibit " ) ) ;
2016-07-24 21:36:03 +00:00
message < < QCoreApplication : : applicationName ( ) ;
message < < reason ;
QDBusPendingReply < uint > reply = QDBusConnection : : sessionBus ( ) . asyncCall ( message ) ;
reply . waitForFinished ( ) ;
if ( reply . isValid ( ) ) {
m_screenInhibitCookie = reply . value ( ) ;
2017-01-14 18:15:26 +00:00
qCDebug ( OkularUiDebug ) < < " Screen inhibition cookie " < < m_screenInhibitCookie ;
2016-07-24 21:36:03 +00:00
} else {
2017-01-14 18:15:26 +00:00
qCWarning ( OkularUiDebug ) < < " Unable to inhibit screensaver " < < reply . error ( ) ;
2016-07-24 21:36:03 +00:00
}
}
2018-09-18 19:30:25 +00:00
if ( m_sleepInhibitFd ! = - 1 ) {
2016-07-24 21:36:03 +00:00
QDBusMessage message = QDBusMessage : : createMethodCall ( QStringLiteral ( " org.freedesktop.login1 " ) ,
QStringLiteral ( " /org/freedesktop/login1 " ) ,
QStringLiteral ( " org.freedesktop.login1.Manager " ) ,
QStringLiteral ( " Inhibit " )
) ;
message < < QStringLiteral ( " sleep " ) ;
message < < QCoreApplication : : applicationName ( ) ;
message < < reason ;
message < < QStringLiteral ( " block " ) ;
QDBusPendingReply < QDBusUnixFileDescriptor > reply = QDBusConnection : : systemBus ( ) . asyncCall ( message ) ;
reply . waitForFinished ( ) ;
if ( reply . isValid ( ) ) {
2018-09-18 19:30:25 +00:00
m_sleepInhibitFd = dup ( reply . value ( ) . fileDescriptor ( ) ) ;
2016-07-24 21:36:03 +00:00
} else {
2017-01-14 18:15:26 +00:00
qCWarning ( OkularUiDebug ) < < " Unable to inhibit sleep " < < reply . error ( ) ;
2016-07-24 21:36:03 +00:00
}
}
# endif
2008-08-30 17:31:59 +00:00
}
2012-01-18 20:34:12 +00:00
void PresentationWidget : : allowPowerManagement ( )
2008-08-30 17:31:59 +00:00
{
2016-07-24 21:36:03 +00:00
# ifdef Q_OS_LINUX
2018-09-18 19:30:25 +00:00
if ( m_sleepInhibitFd ! = - 1 ) {
: : close ( m_sleepInhibitFd ) ;
m_sleepInhibitFd = - 1 ;
2016-07-24 21:36:03 +00:00
}
if ( m_screenInhibitCookie ) {
2019-04-25 21:10:48 +00:00
QDBusMessage message = QDBusMessage : : createMethodCall ( QStringLiteral ( " org.freedesktop.ScreenSaver " ) , QStringLiteral ( " /ScreenSaver " ) ,
QStringLiteral ( " org.freedesktop.ScreenSaver " ) , QStringLiteral ( " UnInhibit " ) ) ;
2016-07-24 21:36:03 +00:00
message < < m_screenInhibitCookie ;
QDBusPendingReply < uint > reply = QDBusConnection : : sessionBus ( ) . asyncCall ( message ) ;
reply . waitForFinished ( ) ;
m_screenInhibitCookie = 0 ;
}
# endif
2008-08-30 17:31:59 +00:00
}
2008-04-09 15:05:08 +00:00
2010-03-30 04:03:00 +00:00
void PresentationWidget : : showTopBar ( bool show )
{
if ( show )
{
2010-03-30 04:47:29 +00:00
m_topBar - > show ( ) ;
// Don't autohide the mouse cursor if it's over the toolbar
2010-03-30 04:03:00 +00:00
if ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : HiddenDelay )
{
KCursor : : setAutoHideCursor ( this , false ) ;
}
2010-03-30 04:47:29 +00:00
// Always show a cursor when topBar is visible
if ( ! m_drawingEngine )
{
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
}
2010-03-30 04:03:00 +00:00
}
else
{
m_topBar - > hide ( ) ;
2010-03-30 04:47:29 +00:00
// Reenable autohide if need be when leaving the toolbar
2010-03-30 04:03:00 +00:00
if ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : HiddenDelay )
{
KCursor : : setAutoHideCursor ( this , true ) ;
}
2010-03-30 04:47:29 +00:00
// Or hide the cursor again if hidden cursor is enabled
else if ( Okular : : Settings : : slidesCursor ( ) = = Okular : : Settings : : EnumSlidesCursor : : Hidden )
{
2010-04-02 18:49:13 +00:00
// Don't hide the cursor if drawing mode is on
2010-03-30 04:47:29 +00:00
if ( ! m_drawingEngine )
{
setCursor ( QCursor ( Qt : : BlankCursor ) ) ;
}
}
2010-03-30 04:03:00 +00:00
}
// Make sure mouse tracking isn't off after the KCursor::setAutoHideCursor() calls
setMouseTracking ( true ) ;
}
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 ;
}
2015-07-16 23:02:07 +00:00
case Okular : : Settings : : EnumSlidesTransition : : Fade :
{
return Okular : : PageTransition ( Okular : : PageTransition : : Fade ) ;
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 ( ) ;
2015-07-16 23:02:07 +00:00
m_currentTransition = * transition ;
m_currentPagePixmap = m_lastRenderedPixmap ;
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 + + )
{
2018-11-14 19:12:15 +00:00
// compute shrunk box coords
2005-01-08 00:12:08 +00:00
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 + + )
{
2018-11-14 19:12:15 +00:00
// compute shrunk box coords
2005-01-08 00:12:08 +00:00
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 + + )
{
2016-08-31 14:34:15 +00:00
# ifndef Q_OS_WIN
2004-12-17 17:14:46 +00:00
int n1 = ( int ) ( steps * drand48 ( ) ) ;
int n2 = ( int ) ( steps * drand48 ( ) ) ;
2016-08-31 14:34:15 +00:00
# else
int n1 = ( int ) ( steps * ( std : : rand ( ) / RAND_MAX ) ) ;
int n2 = ( int ) ( steps * ( std : : rand ( ) / RAND_MAX ) ) ;
# endif
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 + + )
{
2016-08-31 14:34:15 +00:00
# ifndef Q_OS_WIN
2005-01-08 00:12:08 +00:00
int n1 = ( int ) ( steps * drand48 ( ) ) ;
int n2 = ( int ) ( steps * drand48 ( ) ) ;
2016-08-31 14:34:15 +00:00
# else
int n1 = ( int ) ( steps * ( std : : rand ( ) / RAND_MAX ) ) ;
int n2 = ( int ) ( steps * ( std : : rand ( ) / RAND_MAX ) ) ;
# endif
2005-01-08 00:12:08 +00:00
// 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 ;
2015-07-16 23:02:07 +00:00
case Okular : : PageTransition : : Fade :
{
2015-10-14 22:10:39 +00:00
enum { FADE_TRANSITION_FPS = 20 } ;
const int steps = totalTime * FADE_TRANSITION_FPS ;
m_transitionSteps = steps ;
2015-07-16 23:02:07 +00:00
QPainter pixmapPainter ;
m_currentPixmapOpacity = ( double ) 1 / steps ;
m_transitionDelay = ( int ) ( totalTime * 1000 ) / steps ;
m_lastRenderedPixmap = QPixmap ( m_lastRenderedPixmap . size ( ) ) ;
m_lastRenderedPixmap . fill ( Qt : : transparent ) ;
pixmapPainter . begin ( & m_lastRenderedPixmap ) ;
pixmapPainter . setCompositionMode ( QPainter : : CompositionMode_Source ) ;
pixmapPainter . setOpacity ( 1 - m_currentPixmapOpacity ) ;
pixmapPainter . drawPixmap ( 0 , 0 , m_previousPagePixmap ) ;
pixmapPainter . setOpacity ( m_currentPixmapOpacity ) ;
pixmapPainter . drawPixmap ( 0 , 0 , m_currentPagePixmap ) ;
pixmapPainter . end ( ) ;
update ( ) ;
} 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
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
}
2012-04-03 12:18:10 +00:00
void PresentationWidget : : slotProcessMovieAction ( const Okular : : MovieAction * action )
{
const Okular : : MovieAnnotation * movieAnnotation = action - > annotation ( ) ;
if ( ! movieAnnotation )
return ;
Okular : : Movie * movie = movieAnnotation - > movie ( ) ;
if ( ! movie )
return ;
VideoWidget * vw = m_frames [ m_frameIndex ] - > videoWidgets . value ( movieAnnotation - > movie ( ) ) ;
if ( ! vw )
return ;
vw - > show ( ) ;
switch ( action - > operation ( ) )
{
case Okular : : MovieAction : : Play :
vw - > stop ( ) ;
vw - > play ( ) ;
break ;
case Okular : : MovieAction : : Stop :
vw - > stop ( ) ;
break ;
case Okular : : MovieAction : : Pause :
vw - > pause ( ) ;
break ;
case Okular : : MovieAction : : Resume :
vw - > play ( ) ;
break ;
} ;
}
2004-12-17 17:14:46 +00:00
2012-09-27 12:15:58 +00:00
void PresentationWidget : : slotProcessRenditionAction ( const Okular : : RenditionAction * action )
{
Okular : : Movie * movie = action - > movie ( ) ;
if ( ! movie )
return ;
VideoWidget * vw = m_frames [ m_frameIndex ] - > videoWidgets . value ( movie ) ;
if ( ! vw )
return ;
if ( action - > operation ( ) = = Okular : : RenditionAction : : None )
return ;
vw - > show ( ) ;
switch ( action - > operation ( ) )
{
case Okular : : RenditionAction : : Play :
vw - > stop ( ) ;
vw - > play ( ) ;
break ;
case Okular : : RenditionAction : : Stop :
vw - > stop ( ) ;
break ;
case Okular : : RenditionAction : : Pause :
vw - > pause ( ) ;
break ;
case Okular : : RenditionAction : : Resume :
vw - > play ( ) ;
break ;
2016-07-24 20:39:45 +00:00
default :
return ;
2012-09-27 12:15:58 +00:00
} ;
}
2014-02-24 22:08:39 +00:00
void PresentationWidget : : slotTogglePlayPause ( )
2014-02-24 21:39:08 +00:00
{
2014-02-24 22:08:39 +00:00
m_advanceSlides = ! m_advanceSlides ;
setPlayPauseIcon ( ) ;
if ( m_advanceSlides )
2014-02-24 21:39:08 +00:00
{
2014-02-24 22:08:39 +00:00
startAutoChangeTimer ( ) ;
2014-02-24 21:39:08 +00:00
}
else
{
2014-02-24 22:08:39 +00:00
m_nextPageTimer - > stop ( ) ;
2014-02-24 21:39:08 +00:00
}
}
2016-10-29 14:40:03 +00:00
# include "presentationwidget.moc"