File indexing completed on 2024-04-28 15:51:51
0001 /* 0002 SPDX-FileCopyrightText: 2017 Tobias Deiminger <haxtibal@t-online.de> 0003 SPDX-FileCopyrightText: 2004-2005 Enrico Ros <eros.kde@email.it> 0004 SPDX-FileCopyrightText: 2004-2006 Albert Astals Cid <aacid@kde.org> 0005 0006 Work sponsored by the LiMux project of the city of Munich: 0007 SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com> 0008 0009 With portions of code from kpdf/kpdf_pagewidget.cc by: 0010 SPDX-FileCopyrightText: 2002 Wilco Greven <greven@kde.org> 0011 SPDX-FileCopyrightText: 2003 Christophe Devriese <Christophe.Devriese@student.kuleuven.ac.be> 0012 SPDX-FileCopyrightText: 2003 Laurent Montel <montel@kde.org> 0013 SPDX-FileCopyrightText: 2003 Dirk Mueller <mueller@kde.org> 0014 SPDX-FileCopyrightText: 2004 James Ots <kde@jamesots.com> 0015 SPDX-FileCopyrightText: 2011 Jiri Baum - NICTA <jiri@baum.com.au> 0016 0017 SPDX-License-Identifier: GPL-2.0-or-later 0018 */ 0019 0020 #ifndef _OKULAR_PAGEVIEWMOUSEANNOTATION_H_ 0021 #define _OKULAR_PAGEVIEWMOUSEANNOTATION_H_ 0022 0023 #include <QObject> 0024 0025 #include "core/annotations.h" 0026 #include "pageviewutils.h" 0027 0028 class QHelpEvent; 0029 class QPainter; 0030 class QPoint; 0031 class PageView; 0032 class PageViewItem; 0033 class AnnotationDescription; 0034 0035 namespace Okular 0036 { 0037 class Document; 0038 } 0039 0040 /* This class shall help to keep data for one annotation consistent. */ 0041 class AnnotationDescription 0042 { 0043 public: 0044 AnnotationDescription() 0045 : annotation(nullptr) 0046 , pageViewItem(nullptr) 0047 , pageNumber(-1) 0048 { 0049 } 0050 AnnotationDescription(PageViewItem *newPageViewItem, const QPoint eventPos); 0051 bool isValid() const; 0052 bool isContainedInPage(const Okular::Document *document, int pageNumber) const; 0053 void invalidate(); 0054 bool operator==(const AnnotationDescription &rhs) const 0055 { 0056 return (annotation == rhs.annotation); 0057 } 0058 Okular::Annotation *annotation; 0059 PageViewItem *pageViewItem; 0060 int pageNumber; 0061 }; 0062 0063 /** 0064 * @short Handle UI for annotation interactions, like moving, resizing and triggering actions. 0065 * 0066 * An object of this class tracks which annotation is currently under the mouse cursor. 0067 * Some annotation types can be focused in order to move or resize them. 0068 * State is determined from mouse and keyboard events, which are forwarded from the parent PageView object. 0069 * Move and resize actions are dispatched to the Document object. 0070 */ 0071 class MouseAnnotation : public QObject 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 MouseAnnotation(PageView *parent, Okular::Document *document); 0077 ~MouseAnnotation() override; 0078 0079 /* Process a mouse press event. eventPos: Mouse position in content area coordinates. */ 0080 void routeMousePressEvent(PageViewItem *pageViewItem, const QPoint eventPos); 0081 0082 /* Process a mouse release event. */ 0083 void routeMouseReleaseEvent(); 0084 0085 /* Process a mouse move event. eventPos: Mouse position in content area coordinates. */ 0086 void routeMouseMoveEvent(PageViewItem *pageViewItem, const QPoint eventPos, bool leftButtonPressed); 0087 0088 /* Process a key event. */ 0089 void routeKeyPressEvent(const QKeyEvent *e); 0090 0091 /* Process a tooltip event. eventPos: Mouse position in content area coordinates. */ 0092 void routeTooltipEvent(const QHelpEvent *helpEvent); 0093 0094 /* Process a paint event. */ 0095 void routePaint(QPainter *painter, const QRect paintRect); 0096 0097 /* Cancel the current selection or action, if any. */ 0098 void cancel(); 0099 0100 /* Reset to initial state. Cancel current action and relinquish references to PageViewItem widgets. */ 0101 void reset(); 0102 0103 Okular::Annotation *annotation() const; 0104 0105 /* Return true, if MouseAnnotation demands control for a mouse click on the current cursor position. */ 0106 bool isMouseOver() const; 0107 0108 bool isActive() const; 0109 0110 bool isFocused() const; 0111 0112 bool isMoved() const; 0113 0114 bool isResized() const; 0115 0116 bool isModified() const; 0117 0118 Qt::CursorShape cursor() const; 0119 0120 /* Forward DocumentObserver::notifyPageChanged to this method. */ 0121 void notifyAnnotationChanged(int pageNumber); 0122 0123 /* Forward DocumentObserver::notifySetup to this method. */ 0124 void updateAnnotationPointers(); 0125 0126 enum MouseAnnotationState { StateInactive, StateFocused, StateMoving, StateResizing }; 0127 0128 enum ResizeHandleFlag { 0129 RH_None = 0, 0130 RH_Top = 1, 0131 RH_Right = 2, 0132 RH_Bottom = 4, 0133 RH_Left = 8, 0134 RH_TopLeft = RH_Top | RH_Left, 0135 RH_BottomLeft = RH_Bottom | RH_Left, 0136 RH_TopRight = RH_Top | RH_Right, 0137 RH_BottomRight = RH_Bottom | RH_Right, 0138 RH_Content = 16, 0139 RH_AllHandles = RH_Top | RH_Right | RH_Bottom | RH_Left 0140 }; 0141 Q_DECLARE_FLAGS(ResizeHandle, ResizeHandleFlag) 0142 0143 private: 0144 void setState(MouseAnnotationState state, const AnnotationDescription &ad); 0145 QRect getFullBoundingRect(const AnnotationDescription &ad) const; 0146 void performCommand(const QPoint newPos); 0147 void finishCommand(); 0148 void updateViewport(const AnnotationDescription &ad) const; 0149 ResizeHandle getHandleAt(const QPoint eventPos, const AnnotationDescription &ad) const; 0150 QRect getHandleRect(ResizeHandle handle, const AnnotationDescription &ad) const; 0151 static void handleToAdjust(const QPointF dIn, QPointF &dOut1, QPointF &dOut2, MouseAnnotation::ResizeHandle handle, Okular::Rotation rotation); 0152 static QPointF rotateInRect(const QPointF rotated, Okular::Rotation rotation); 0153 static ResizeHandle rotateHandle(ResizeHandle handle, Okular::Rotation rotation); 0154 void processAction(const AnnotationDescription &ad); 0155 0156 /* We often have to delegate to the document model and our parent widget. */ 0157 Okular::Document *m_document; 0158 PageView *m_pageView; 0159 0160 /* Remember which annotation is currently focused/modified. */ 0161 MouseAnnotationState m_state; 0162 MouseAnnotation::ResizeHandle m_handle; 0163 AnnotationDescription m_focusedAnnotation; 0164 0165 /* Mouse tracking, always kept up to date with the latest mouse position and annotation under mouse cursor. */ 0166 AnnotationDescription m_mouseOverAnnotation; 0167 QPoint m_mousePosition; // in page view item coordinates 0168 0169 QList<ResizeHandle> m_resizeHandleList; 0170 }; 0171 0172 #endif