1 /* 2 SPDX-FileCopyrightText: 2004 Enrico Ros <eros.kde@email.it> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #ifndef _OKULAR_PRESENTATIONWIDGET_H_ 8 #define _OKULAR_PRESENTATIONWIDGET_H_ 9 10 #include "core/area.h" 11 #include "core/observer.h" 12 #include "core/pagetransition.h" 13 #include <QDomElement> 14 #include <QList> 15 #include <QPixmap> 16 #include <QStringList> 17 #include <qwidget.h> 18 19 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) // TODO Qt6: These are needed for oldQt_screenOf(). 20 #include <QApplication> 21 #include <QScreen> 22 #include <QWindow> 23 #endif 24 25 class QLineEdit; 26 class QToolBar; 27 class QTimer; 28 class QGestureEvent; 29 class KActionCollection; 30 class KSelectAction; 31 class SmoothPathEngine; 32 struct PresentationFrame; 33 class PresentationSearchBar; 34 class DrawingToolActions; 35 36 namespace Okular 37 { 38 class Action; 39 class Annotation; 40 class Document; 41 class MovieAction; 42 class Page; 43 class RenditionAction; 44 } 45 46 /** 47 * @short A widget that shows pages as fullscreen slides (with transitions fx). 48 * 49 * This is a fullscreen widget that displays 50 */ 51 class PresentationWidget : public QWidget, public Okular::DocumentObserver 52 { 53 Q_OBJECT 54 public: 55 PresentationWidget(QWidget *parent, Okular::Document *doc, DrawingToolActions *drawingToolActions, KActionCollection *collection); 56 ~PresentationWidget() override; 57 58 // inherited from DocumentObserver 59 void notifySetup(const QVector<Okular::Page *> &pages, int setupFlags) override; 60 void notifyViewportChanged(bool smoothMove) override; 61 void notifyPageChanged(int pageNumber, int changedFlags) override; 62 bool canUnloadPixmap(int pageNumber) const override; 63 void notifyCurrentPageChanged(int previous, int current) override; 64 65 public Q_SLOTS: 66 void slotFind(); 67 68 protected: 69 // widget events 70 bool event(QEvent *e) override; 71 void keyPressEvent(QKeyEvent *e) override; 72 void wheelEvent(QWheelEvent *e) override; 73 void mousePressEvent(QMouseEvent *e) override; 74 void mouseReleaseEvent(QMouseEvent *e) override; 75 void mouseMoveEvent(QMouseEvent *e) override; 76 void paintEvent(QPaintEvent *e) override; 77 void resizeEvent(QResizeEvent *e) override; 78 void enterEvent(QEvent *e) override; 79 void leaveEvent(QEvent *e) override; 80 bool gestureEvent(QGestureEvent *e); 81 82 // Catch TabletEnterProximity and TabletLeaveProximity events from the QApplication 83 bool eventFilter(QObject *o, QEvent *ev) override; 84 85 private: 86 const void *getObjectRect(Okular::ObjectRect::ObjectType type, int x, int y, QRect *geometry = nullptr) const; 87 const Okular::Action *getLink(int x, int y, QRect *geometry = nullptr) const; 88 const Okular::Annotation *getAnnotation(int x, int y, QRect *geometry = nullptr) const; 89 void testCursorOnLink(int x, int y); 90 void overlayClick(const QPoint position); 91 void changePage(int newPage); 92 void generatePage(bool disableTransition = false); 93 void generateIntroPage(QPainter &p); 94 void generateContentsPage(int page, QPainter &p); 95 void generateOverlay(); 96 void initTransition(const Okular::PageTransition *transition); 97 const Okular::PageTransition defaultTransition() const; 98 const Okular::PageTransition defaultTransition(int) const; 99 QRect routeMouseDrawingEvent(QMouseEvent *); 100 void startAutoChangeTimer(); 101 /** @returns Configure -> Presentation -> Preferred screen */ 102 QScreen *defaultScreen() const; 103 void requestPixmaps(); 104 /** @param newScreen must be valid. */ 105 void setScreen(const QScreen *newScreen); 106 void inhibitPowerManagement(); 107 void allowPowerManagement(); 108 void showTopBar(bool); 109 // create actions that interact with this widget 110 void setupActions(); 111 void setPlayPauseIcon(); 112 113 // cache stuff 114 int m_width; 115 int m_height; 116 QPixmap m_lastRenderedPixmap; 117 QPixmap m_lastRenderedOverlay; 118 QRect m_overlayGeometry; 119 const Okular::Action *m_pressedLink; 120 bool m_handCursor; 121 SmoothPathEngine *m_drawingEngine; 122 QRect m_drawingRect; 123 uint m_screenInhibitCookie; 124 int m_sleepInhibitFd; 125 126 // transition related 127 QTimer *m_transitionTimer; 128 QTimer *m_overlayHideTimer; 129 QTimer *m_nextPageTimer; 130 int m_transitionDelay; 131 int m_transitionMul; 132 int m_transitionSteps; 133 QList<QRect> m_transitionRects; 134 Okular::PageTransition m_currentTransition; 135 QPixmap m_currentPagePixmap; 136 QPixmap m_previousPagePixmap; 137 double m_currentPixmapOpacity; 138 139 // misc stuff 140 QWidget *m_parentWidget; 141 Okular::Document *m_document; 142 QVector<PresentationFrame *> m_frames; 143 int m_frameIndex; 144 QStringList m_metaStrings; 145 QToolBar *m_topBar; 146 QLineEdit *m_pagesEdit; 147 PresentationSearchBar *m_searchBar; 148 KActionCollection *m_ac; 149 KSelectAction *m_screenSelect; 150 QDomElement m_currentDrawingToolElement; 151 bool m_isSetup; 152 bool m_blockNotifications; 153 bool m_inBlackScreenMode; 154 bool m_showSummaryView; 155 bool m_advanceSlides; 156 bool m_goToPreviousPageOnRelease; 157 bool m_goToNextPageOnRelease; 158 159 /** TODO Qt6: Just use QWidget::screen() instead of this. */ oldQt_screenOf(const QWidget * widget)160 static inline QScreen *oldQt_screenOf(const QWidget *widget) 161 { 162 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 163 return widget->screen(); 164 #else 165 if (widget->window() && widget->window()->windowHandle() && widget->window()->windowHandle()->screen()) { 166 return widget->window()->windowHandle()->screen(); 167 } else { 168 return QApplication::primaryScreen(); 169 } 170 #endif 171 } 172 173 private Q_SLOTS: 174 void slotNextPage(); 175 void slotPrevPage(); 176 void slotFirstPage(); 177 void slotLastPage(); 178 void slotHideOverlay(); 179 void slotTransitionStep(); 180 void slotDelayedEvents(); 181 void slotPageChanged(); 182 void clearDrawings(); 183 void chooseScreen(QAction *); 184 void toggleBlackScreenMode(bool); 185 void slotProcessMovieAction(const Okular::MovieAction *action); 186 void slotProcessRenditionAction(const Okular::RenditionAction *action); 187 void slotTogglePlayPause(); 188 void slotChangeDrawingToolEngine(const QDomElement &element); 189 void slotAddDrawingToolActions(); 190 }; 191 192 #endif 193