Commit 0957abc3 authored by Tobias Deiminger's avatar Tobias Deiminger Committed by Albert Astals Cid

Add annotation resize functionality

Usage:
If you left-click an annotation, it gets selected. Resize handles appear on the selection rectangle. When cursor is moved over one of the 8 resize handles on the corners/edges, the cursor shape changes to indicate resize mode. Everywhere else on the annotation means "move", just as it was before resize feature was added. Pressing ESC or clicking an area outside the annotation cancels a selection. Pressing Del deletes a selected annotation.

Feature is only applicable for annotation types AText, AStamp and AGeom.

Implementation:
It works by eventually changing AnnotationPrivate::m_boundary and notifying generator (i.e. poppler) about that change. Annotation state handling is shifted out of PageView into a new class MouseAnnotation (ui/pageviewmouseannotation.cpp). Some functionality not related to resizing but to annotation interaction in general is also shifted to class MouseAnnotation, to build a single place of responsiblity.

Other changes:
Add method Document::adjustPageAnnotation, backed by a QUndoCommand.
class Okular::AdjustAnnotationCommand.
Add Annotation::adjust and Annotation::canBeResized methods.
Draw resize handles in PagePainter::paintCroppedPageOnPainter.

Resize and move work
-for types AText, AStamp and AGeom
-on all pages of document
-when viewport position changes
-when zoom level changes
-for all page rotations (0°, 90°, 180°, 270°)

Selection is canceled
-when currently selected annotation is deleted
-on mouse click outside of currently selected annotation
-ESC is pressed

Viewport is shifted when mouse cursor during move/resize comes close to viewport border.
Resize to negative is prevented.
Tiny annotations are still selectable.
If mouse is moved over an annotation type that we can focus, and the annotation is not yet focused, mouse cursor shape changes to arrow.
If mouse cursor rests over an annotation A, while annotation B is focused, a tooltip for annotation A is shown.
Selected Annotation is deleted when Del is pressed.

Test for regressions:
-Annotation interaction (focus, move, resize, start playback, ...) are only done in mode EnumMouseMode::Browse.
-If mouse is moved over an annotation type where we can start an action, mouse cursor shape changes to pointing hand.
-If mouse is moved over an annotation type that we can't interact with, mouse cursor shape stays a open hand.
-If mouse cursor rests over an annotation of any type, a tooltip for that annotation is shown.
-Grab/move scroll area (on left click + mouse move) is prevented, if mouse is over focused annotation, or over AMovie/AScreen/AFileAttachment annotation.
-A double click on a annotation starts the "annotator".

REVIEW: 127366
BUG: 177778
BUG: 314843
BUG: 358060
parent 3859fba0
......@@ -272,6 +272,7 @@ set(okularpart_SRCS
ui/pagepainter.cpp
ui/pagesizelabel.cpp
ui/pageviewannotator.cpp
ui/pageviewmouseannotation.cpp
ui/pageview.cpp
ui/magnifierview.cpp
ui/pageviewutils.cpp
......
......@@ -630,6 +630,17 @@ void Annotation::translate( const NormalizedPoint &coord )
}
}
void Annotation::adjust( const NormalizedPoint & deltaCoord1, const NormalizedPoint & deltaCoord2 )
{
Q_D( Annotation );
d->adjust( deltaCoord1, deltaCoord2 );
d->resetTransformation();
if ( d->m_page )
{
d->transform( d->m_page->rotationMatrix() );
}
}
bool Annotation::openDialogAfterCreation() const
{
Q_D( const Annotation );
......@@ -705,6 +716,17 @@ bool Annotation::canBeMoved() const
return true;
}
bool Annotation::canBeResized() const
{
Q_D( const Annotation );
// Don't resize annotations if they cannot be modified
if ( !d->m_page || !d->m_page->m_doc->m_parent->canModifyPageAnnotation(this) )
return false;
return d->canBeResized();
}
void Annotation::store( QDomNode & annNode, QDomDocument & document ) const
{
Q_D( const Annotation );
......@@ -726,7 +748,7 @@ void Annotation::store( QDomNode & annNode, QDomDocument & document ) const
// store -other- attributes
if ( d->m_flags ) // Strip internal flags
e.setAttribute( QStringLiteral("flags"), d->m_flags & ~(External | ExternallyDrawn | BeingMoved) );
e.setAttribute( QStringLiteral("flags"), d->m_flags & ~(External | ExternallyDrawn | BeingMoved | BeingResized ) );
if ( d->m_style.color().isValid() )
e.setAttribute( QStringLiteral("color"), d->m_style.color().name() );
if ( d->m_style.opacity() != 1.0 )
......@@ -812,7 +834,7 @@ void Annotation::setAnnotationProperties( const QDomNode& node )
// Save off internal properties that aren't contained in node
Okular::PagePrivate *p = d_ptr->m_page;
QVariant nativeID = d_ptr->m_nativeId;
int internalFlags = d_ptr->m_flags & (External | ExternallyDrawn | BeingMoved);
const int internalFlags = d_ptr->m_flags & (External | ExternallyDrawn | BeingMoved | BeingResized );
Annotation::DisposeDataFunction disposeFunc = d_ptr->m_disposeFunc;
// Replace AnnotationPrivate object with a fresh copy
......@@ -867,6 +889,14 @@ void AnnotationPrivate::translate( const NormalizedPoint &coord )
m_boundary.bottom = m_boundary.bottom + coord.y;
}
void AnnotationPrivate::adjust( const NormalizedPoint &deltaCoord1, const NormalizedPoint &deltaCoord2 )
{
m_boundary.left = m_boundary.left + qBound( -m_boundary.left, deltaCoord1.x, m_boundary.right - m_boundary.left );
m_boundary.top = m_boundary.top + qBound( -m_boundary.top, deltaCoord1.y, m_boundary.bottom - m_boundary.top );;
m_boundary.right = m_boundary.right + qBound( m_boundary.left - m_boundary.right, deltaCoord2.x, 1. - m_boundary.right );
m_boundary.bottom = m_boundary.bottom + qBound( m_boundary.top - m_boundary.bottom, deltaCoord2.y, 1. - m_boundary.bottom );
}
bool AnnotationPrivate::openDialogAfterCreation() const
{
return false;
......@@ -966,6 +996,11 @@ void AnnotationPrivate::setAnnotationProperties( const QDomNode& node )
m_transformedBoundary = m_boundary;
}
bool AnnotationPrivate::canBeResized() const
{
return false;
}
//END Annotation implementation
......@@ -987,6 +1022,7 @@ class Okular::TextAnnotationPrivate : public Okular::AnnotationPrivate
void translate( const NormalizedPoint &coord ) override;
bool openDialogAfterCreation() const override;
void setAnnotationProperties( const QDomNode& node ) override;
bool canBeResized() const override;
AnnotationPrivate* getNewAnnotationPrivate() override;
TextAnnotation::TextType m_textType;
......@@ -1245,6 +1281,14 @@ void TextAnnotationPrivate::setAnnotationProperties( const QDomNode& node )
m_transformedInplaceCallout[i] = m_inplaceCallout[i];
}
bool TextAnnotationPrivate::canBeResized() const
{
if ( m_textType != TextAnnotation::Linked ) {
return true;
}
return false;
}
AnnotationPrivate* TextAnnotationPrivate::getNewAnnotationPrivate()
{
return new TextAnnotationPrivate();
......@@ -1589,6 +1633,7 @@ class Okular::GeomAnnotationPrivate : public Okular::AnnotationPrivate
{
}
void setAnnotationProperties( const QDomNode& node ) override;
bool canBeResized() const override;
AnnotationPrivate* getNewAnnotationPrivate() override;
double distanceSqr( double x, double y, double xScale, double yScale ) override;
......@@ -1682,6 +1727,11 @@ void GeomAnnotationPrivate::setAnnotationProperties( const QDomNode& node )
}
}
bool GeomAnnotationPrivate::canBeResized() const
{
return true;
}
AnnotationPrivate* GeomAnnotationPrivate::getNewAnnotationPrivate()
{
return new GeomAnnotationPrivate();
......@@ -2061,6 +2111,7 @@ class Okular::StampAnnotationPrivate : public Okular::AnnotationPrivate
{
}
void setAnnotationProperties( const QDomNode& node ) override;
bool canBeResized() const override;
AnnotationPrivate* getNewAnnotationPrivate() override;
QString m_stampIconName;
......@@ -2134,6 +2185,11 @@ void StampAnnotationPrivate::setAnnotationProperties( const QDomNode& node )
}
}
bool StampAnnotationPrivate::canBeResized() const
{
return true;
}
AnnotationPrivate* StampAnnotationPrivate::getNewAnnotationPrivate()
{
return new StampAnnotationPrivate();
......
......@@ -135,7 +135,8 @@ class OKULARCORE_EXPORT Annotation
ToggleHidingOnMouse = 64, ///< Can be hidden/shown by mouse click
External = 128, ///< Is stored external
ExternallyDrawn = 256, ///< Is drawn externally (by the generator which provided it) @since 0.10 (KDE 4.4)
BeingMoved = 512 ///< Is being moved (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 0.15 (KDE 4.9)
BeingMoved = 512, ///< Is being moved (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 0.15 (KDE 4.9)
BeingResized = 1024 ///< Is being resized (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 1.1.0
};
/**
......@@ -300,6 +301,15 @@ class OKULARCORE_EXPORT Annotation
*/
void translate( const NormalizedPoint &coord );
/**
* Adjust the annotation by the specified coordinates.
* Adds coordinates of @p deltaCoord1 to annotations top left corner,
* and @p deltaCoord2 to the bottom right.
*
* @see canBeResized()
*/
void adjust( const NormalizedPoint & deltaCoord1, const NormalizedPoint & deltaCoord2 );
/**
* The Style class contains all information about style of the
* annotation.
......@@ -634,6 +644,11 @@ class OKULARCORE_EXPORT Annotation
*/
bool canBeMoved() const;
/**
* Returns whether the annotation can be resized.
*/
bool canBeResized() const;
/**
* Returns whether the annotation dialog should be open after creation of the annotation or not
*
......
......@@ -42,8 +42,10 @@ class AnnotationPrivate
virtual void baseTransform( const QTransform &matrix );
virtual void resetTransformation();
virtual void translate( const NormalizedPoint &coord );
virtual void adjust( const NormalizedPoint & deltaCoord1, const NormalizedPoint & deltaCoord2 );
virtual bool openDialogAfterCreation() const;
virtual void setAnnotationProperties( const QDomNode& node );
virtual bool canBeResized() const;
virtual AnnotationPrivate* getNewAnnotationPrivate() = 0;
/**
......
......@@ -1061,16 +1061,16 @@ void DocumentPrivate::performModifyPageAnnotation( int page, Annotation * annota
{
/* When an annotation is being moved, the generator will not render it.
* Therefore there's no need to refresh pixmaps after the first time */
if ( annotation->flags() & Annotation::BeingMoved )
if ( annotation->flags() & (Annotation::BeingMoved | Annotation::BeingResized) )
{
if ( m_annotationBeingMoved )
if ( m_annotationBeingModified )
return;
else // First time: take note
m_annotationBeingMoved = true;
m_annotationBeingModified = true;
}
else
{
m_annotationBeingMoved = false;
m_annotationBeingModified = false;
}
// Redraw everything, including ExternallyDrawn annotations
......@@ -1078,8 +1078,8 @@ void DocumentPrivate::performModifyPageAnnotation( int page, Annotation * annota
refreshPixmaps( page );
}
// If the user is moving the annotation, don't steal the focus
if ( (annotation->flags() & Annotation::BeingMoved) == 0 )
// If the user is moving or resizing the annotation, don't steal the focus
if ( (annotation->flags() & (Annotation::BeingMoved | Annotation::BeingResized) ) == 0 )
warnLimitedAnnotSupport();
}
......@@ -3291,6 +3291,13 @@ void Document::translatePageAnnotation(int page, Annotation* annotation, const N
d->m_undoStack->push(uc);
}
void Document::adjustPageAnnotation( int page, Annotation *annotation, const Okular::NormalizedPoint & delta1, const Okular::NormalizedPoint & delta2 )
{
const bool complete = (annotation->flags() & Okular::Annotation::BeingResized) == 0;
QUndoCommand *uc = new Okular::AdjustAnnotationCommand( d, annotation, page, delta1, delta2, complete );
d->m_undoStack->push(uc);
}
void Document::editPageAnnotationContents( int page, Annotation* annotation,
const QString & newContents,
int newCursorPos,
......
......@@ -522,12 +522,25 @@ class OKULARCORE_EXPORT Document : public QObject
* Translates the position of the given @p annotation on the given @p page by a distance @p delta in normalized coordinates.
*
* Consecutive translations applied to the same @p annotation are merged together on the undo stack if the
* BeingMoved flag is set on the @P annotation
* BeingMoved flag is set on the @P annotation.
*
* @since 0.17 (KDE 4.11)
*/
void translatePageAnnotation( int page, Annotation *annotation, const Okular::NormalizedPoint & delta );
/**
* Adjusts the position of the top-left and bottom-right corners of given @p annotation on the given @p page.
*
* Can be used to implement resize functionality.
* @p delta1 in normalized coordinates is added to top-left.
* @p delta2 in normalized coordinates is added to bottom-right.
*
* Consecutive adjustments applied to the same @p annotation are merged together on the undo stack if the
* BeingResized flag is set on the @P annotation.
*
* @since 1.1.0
*/
void adjustPageAnnotation( int page, Annotation * annotation, const Okular::NormalizedPoint & delta1, const Okular::NormalizedPoint & delta2 );
/**
* Edits the plain text contents of the given @p annotation on the given @p page.
......
......@@ -98,7 +98,7 @@ class DocumentPrivate
m_archiveData( 0 ),
m_fontsCached( false ),
m_annotationEditingEnabled ( true ),
m_annotationBeingMoved( false ),
m_annotationBeingModified( false ),
m_synctex_scanner( 0 )
{
calculateMaxTextPages();
......@@ -274,7 +274,7 @@ class DocumentPrivate
bool m_annotationEditingEnabled;
bool m_annotationsNeedSaveAs;
bool m_annotationBeingMoved; // is an annotation currently being moved?
bool m_annotationBeingModified; // is an annotation currently being moved or resized?
bool m_showWarningLimitedAnnotSupport;
QUndoStack *m_undoStack;
......
......@@ -212,6 +212,71 @@ Okular::NormalizedRect TranslateAnnotationCommand::translateBoundingRectangle( c
return boundingRect;
}
AdjustAnnotationCommand::AdjustAnnotationCommand(Okular::DocumentPrivate * docPriv,
Okular::Annotation * annotation,
int pageNumber,
const Okular::NormalizedPoint & delta1,
const Okular::NormalizedPoint & delta2,
bool completeDrag )
: m_docPriv( docPriv ),
m_annotation( annotation ),
m_pageNumber( pageNumber ),
m_delta1( delta1 ),
m_delta2( delta2 ),
m_completeDrag( completeDrag )
{
setText( i18nc( "Change an annotation's size", "adjust annotation" ) );
}
void AdjustAnnotationCommand::undo()
{
const NormalizedPoint minusDelta1 = Okular::NormalizedPoint( -m_delta1.x, -m_delta1.y );
const NormalizedPoint minusDelta2 = Okular::NormalizedPoint( -m_delta2.x, -m_delta2.y );
moveViewportIfBoundingRectNotFullyVisible( adjustBoundingRectangle( minusDelta1, minusDelta2 ), m_docPriv, m_pageNumber );
m_annotation->adjust( minusDelta1, minusDelta2 );
m_docPriv->performModifyPageAnnotation( m_pageNumber, m_annotation, true );
}
void AdjustAnnotationCommand::redo()
{
moveViewportIfBoundingRectNotFullyVisible( adjustBoundingRectangle( m_delta1, m_delta2 ), m_docPriv, m_pageNumber );
m_annotation->adjust( m_delta1, m_delta2 );
m_docPriv->performModifyPageAnnotation( m_pageNumber, m_annotation, true );
}
int AdjustAnnotationCommand::id() const
{
return 5;
}
bool AdjustAnnotationCommand::mergeWith( const QUndoCommand * uc )
{
AdjustAnnotationCommand *tuc = (AdjustAnnotationCommand *)uc;
if ( tuc->m_annotation != m_annotation )
return false;
if ( m_completeDrag )
{
return false;
}
m_delta1 = Okular::NormalizedPoint( tuc->m_delta1.x + m_delta1.x, tuc->m_delta1.y + m_delta1.y );
m_delta2 = Okular::NormalizedPoint( tuc->m_delta2.x + m_delta2.x, tuc->m_delta2.y + m_delta2.y );
m_completeDrag = tuc->m_completeDrag;
return true;
}
Okular::NormalizedRect AdjustAnnotationCommand::adjustBoundingRectangle(
const Okular::NormalizedPoint & delta1, const Okular::NormalizedPoint & delta2 )
{
const Okular::NormalizedRect annotBoundingRect = m_annotation->boundingRectangle();
const double left = qMin<double>( annotBoundingRect.left, annotBoundingRect.left + delta1.x );
const double right = qMax<double>( annotBoundingRect.right, annotBoundingRect.right + delta2.x );
const double top = qMin<double>( annotBoundingRect.top, annotBoundingRect.top + delta1.y );
const double bottom = qMax<double>( annotBoundingRect.bottom, annotBoundingRect.bottom + delta2.y );
return Okular::NormalizedRect( left, top, right, bottom );
}
EditTextCommand::EditTextCommand( const QString & newContents,
int newCursorPos,
const QString & prevContents,
......
......@@ -100,6 +100,32 @@ class TranslateAnnotationCommand : public QUndoCommand
bool m_completeDrag;
};
class AdjustAnnotationCommand : public QUndoCommand
{
public:
AdjustAnnotationCommand(Okular::DocumentPrivate * docPriv,
Okular::Annotation * annotation,
int pageNumber,
const Okular::NormalizedPoint & delta1,
const Okular::NormalizedPoint & delta2,
bool completeDrag
);
void undo() override;
void redo() override;
int id() const override;
bool mergeWith(const QUndoCommand * uc) override;
Okular::NormalizedRect adjustBoundingRectangle(
const Okular::NormalizedPoint & delta1, const Okular::NormalizedPoint & delta2 );
private:
Okular::DocumentPrivate * m_docPriv;
Okular::Annotation* m_annotation;
int m_pageNumber;
Okular::NormalizedPoint m_delta1;
Okular::NormalizedPoint m_delta2;
bool m_completeDrag;
};
class EditTextCommand : public QUndoCommand
{
public:
......
......@@ -144,7 +144,7 @@ void PopplerAnnotationProxy::notifyModification( const Okular::Annotation *okl_a
QMutexLocker ml(mutex);
if ( okl_ann->flags() & Okular::Annotation::BeingMoved )
if ( okl_ann->flags() & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized) )
{
// Okular ui already renders the annotation on its own
ppl_ann->setFlags( Poppler::Annotation::Hidden );
......
......@@ -123,6 +123,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
bool canDrawAnnotations = (flags & Annotations) && !page->m_annotations.isEmpty();
bool enhanceLinks = (flags & EnhanceLinks) && Okular::Settings::highlightLinks();
bool enhanceImages = (flags & EnhanceImages) && Okular::Settings::highlightImages();
// vectors containing objects to draw
// make this a qcolor, rect map, since we don't need
// to know s_id here! we are only drawing this right?
......@@ -190,9 +191,11 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
if ( flags & Okular::Annotation::ExternallyDrawn )
{
// ExternallyDrawn annots are never rendered by PagePainter.
// Just paint the boundingRect if the annot is BeingMoved
if ( flags & Okular::Annotation::BeingMoved )
// Just paint the boundingRect if the annot is moved or resized.
if ( flags & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized) )
{
boundingRectOnlyAnn = ann;
}
continue;
}
......
This diff is collapsed.
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2017 by Tobias Deiminger <haxtibal@t-online.de> *
* Copyright (C) 2004-2005 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2004-2006 by Albert Astals Cid <aacid@kde.org> *
* *
* With portions of code from kpdf/kpdf_pagewidget.cc by: *
* Copyright (C) 2002 by Wilco Greven <greven@kde.org> *
* Copyright (C) 2003 by Christophe Devriese *
* <Christophe.Devriese@student.kuleuven.ac.be> *
* Copyright (C) 2003 by Laurent Montel <montel@kde.org> *
* Copyright (C) 2003 by Dirk Mueller <mueller@kde.org> *
* Copyright (C) 2004 by James Ots <kde@jamesots.com> *
* Copyright (C) 2011 by Jiri Baum - NICTA <jiri@baum.com.au> *
* *
* 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. *
***************************************************************************/
#ifndef _OKULAR_PAGEVIEWMOUSEANNOTATION_H_
#define _OKULAR_PAGEVIEWMOUSEANNOTATION_H_
#include <qobject.h>
#include "pageviewutils.h"
#include "core/annotations.h"
class QHelpEvent;
class QPainter;
class QPoint;
class PageView;
class PageViewItem;
class AnnotationDescription;
namespace Okular
{
class Document;
}
/* This class shall help to keep data for one annotation consistent. */
class AnnotationDescription
{
public:
AnnotationDescription()
: annotation( 0 ), pageViewItem( 0 ), pageNumber( 0 ) {}
AnnotationDescription( PageViewItem * newPageViewItem, const QPoint& eventPos );
bool isValid() const;
void invalidate();
bool operator==( const AnnotationDescription & rhs ) const
{
return ( annotation == rhs.annotation );
}
Okular::Annotation * annotation;
PageViewItem * pageViewItem;
int pageNumber;
};
/**
* @short Handle UI for annotation interactions, like moving, resizing and triggering actions.
*
* An object of this class tracks which annotation is currently under the mouse cursor.
* Some annotation types can be focused in order to move or resize them.
* State is determined from mouse and keyboard events, which are forwarded from the parent PageView object.
* Move and resize actions are dispatched to the Document object.
*/
class MouseAnnotation : public QObject
{
Q_OBJECT
public:
MouseAnnotation( PageView * parent, Okular::Document * document );
~MouseAnnotation();
/* Process a mouse press event. eventPos: Mouse position in content area coordinates. */
void routeMousePressEvent( PageViewItem * pageViewItem, const QPoint & eventPos );
/* Process a mouse release event. */
void routeMouseReleaseEvent();
/* Process a mouse move event. eventPos: Mouse position in content area coordinates. */
void routeMouseMoveEvent( PageViewItem * pageViewItem, const QPoint & eventPos, bool leftButtonPressed );
/* Process a key event. */
void routeKeyPressEvent( const QKeyEvent * e );
/* Process a tooltip event. eventPos: Mouse position in content area coordinates. */
void routeTooltipEvent( const QHelpEvent * helpEvent );
/* Process a paint event. */
void routePaint( QPainter * painter, const QRect & paintRect );
/* Cancel the current selection or action, if any. */
void cancel();
Okular::Annotation * annotation() const;
/* Return true, if MouseAnnotation demands control for a mouse click on the current cursor position. */
bool isMouseOver() const;
bool isActive() const;
bool isFocused() const;
bool isMoved() const;
bool isResized() const;
bool isModified() const;
Qt::CursorShape cursor() const;
enum MouseAnnotationState {
StateInactive,
StateFocused,
StateMoving,
StateResizing
};
enum ResizeHandleFlag {
RH_None = 0,
RH_Top = 1,
RH_Right = 2,
RH_Bottom = 4,
RH_Left = 8,
RH_TopLeft = RH_Top | RH_Left,
RH_BottomLeft = RH_Bottom | RH_Left,
RH_TopRight = RH_Top | RH_Right,
RH_BottomRight = RH_Bottom | RH_Right,
RH_Content = 16,
RH_AllHandles = RH_Top | RH_Right | RH_Bottom | RH_Left
};
Q_DECLARE_FLAGS( ResizeHandle, ResizeHandleFlag )
private:
void setState( MouseAnnotationState state, const AnnotationDescription & ad );
QRect getFullBoundingRect( const AnnotationDescription & ad ) const;
void performCommand( const QPoint & newPos );
void finishCommand();
void updateViewport( const AnnotationDescription & ad ) const;
ResizeHandle getHandleAt( const QPoint & eventPos, const AnnotationDescription & ad ) const;
QRect getHandleRect( ResizeHandle handle, const AnnotationDescription & ad ) const;
static void handleToAdjust( const QPointF & dIn, QPointF & dOut1, QPointF & dOut2, MouseAnnotation::ResizeHandle handle, Okular::Rotation rotation );
static QPointF rotateInRect( const QPointF & rotated, Okular::Rotation rotation );
static ResizeHandle rotateHandle( ResizeHandle handle, Okular::Rotation rotation );
void processAction( const AnnotationDescription& ad );
/* We often have to delegate to the document model and our parent widget. */
Okular::Document * m_document;
PageView * m_pageView;
/* Remember which annotation is currently focused/modified. */
MouseAnnotationState m_state;
MouseAnnotation::ResizeHandle m_handle;
AnnotationDescription m_focusedAnnotation;
/* Mouse tracking, always kept up to date with the latest mouse position and annotation under mouse cursor. */
AnnotationDescription m_mouseOverAnnotation;
QPoint m_mousePosition; // in page view item coordinates
QList<ResizeHandle> m_resizeHandleList;
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment