diff --git a/doc/index.docbook b/doc/index.docbook
index 3f044804f..70996f35c 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -1171,13 +1171,10 @@ Context menu actions like Rename Bookmarks etc.)
- The contents of the annotating toolbar can be configured using the Annotations page of &okular; configuration dialog. This page can be opened with &RMB; clicking on the annotating toolbar then choosing Configure Annotations... from the context menu.
-
-
- With a single &LMB; click on an annotation tool button you can use a tool once.
- If you ⪚ want to highlight all important parts of a text, activate that tool
- permanently by double clicking on the tool button.
- Press the Esc key or click the tool button again to leave the permanent mode.
+ By pressing Shift you can constrain the angle of line and polygon annotations to 15° steps, and the ratio of shape annotations (⪚ Rectangle, Ellipse) to 1:1. You can also get a toolbar button from Configure Toolbars....
+
+
+ The contents of the Quick Annotations menu can be configured using the Annotations page of &okular; configuration dialog. This page can be opened by clicking Quick Annotations button, then choosing Configure Annotations... from the pop-up menu.
diff --git a/ui/annotationactionhandler.cpp b/ui/annotationactionhandler.cpp
index b49bed971..43569e717 100644
--- a/ui/annotationactionhandler.cpp
+++ b/ui/annotationactionhandler.cpp
@@ -52,6 +52,7 @@ public:
, aStamp(nullptr)
, aAddToQuickTools(nullptr)
, aContinuousMode(nullptr)
+ , aConstrainRatioAndAngle(nullptr)
, aWidth(nullptr)
, aColor(nullptr)
, aInnerColor(nullptr)
@@ -107,6 +108,7 @@ public:
ToggleActionMenu *aStamp;
QAction *aAddToQuickTools;
KToggleAction *aContinuousMode;
+ KToggleAction *aConstrainRatioAndAngle;
KSelectAction *aWidth;
KSelectAction *aColor;
KSelectAction *aInnerColor;
@@ -252,8 +254,10 @@ void AnnotationActionHandlerPrivate::updateConfigActions(const QString &annotTyp
const bool isTypewriter = annotType == QStringLiteral("typewriter");
const bool isInlineNote = annotType == QStringLiteral("note-inline");
const bool isText = isInlineNote || isTypewriter;
- const bool isShape = annotType == QStringLiteral("rectangle") || annotType == QStringLiteral("ellipse") || annotType == QStringLiteral("polygon");
- const bool isLine = annotType == QStringLiteral("ink") || annotType == QStringLiteral("straight-line");
+ const bool isPolygon = annotType == QStringLiteral("polygon");
+ const bool isShape = annotType == QStringLiteral("rectangle") || annotType == QStringLiteral("ellipse") || isPolygon;
+ const bool isStraightLine = annotType == QStringLiteral("straight-line");
+ const bool isLine = annotType == QStringLiteral("ink") || isStraightLine;
const bool isStamp = annotType == QStringLiteral("stamp");
if (isTypewriter) {
@@ -269,6 +273,7 @@ void AnnotationActionHandlerPrivate::updateConfigActions(const QString &annotTyp
aInnerColor->setEnabled(isShape);
aOpacity->setEnabled(isAnnotationSelected);
aFont->setEnabled(isText);
+ aConstrainRatioAndAngle->setEnabled(isStraightLine || isShape);
aAdvancedSettings->setEnabled(isAnnotationSelected);
// set tooltips
@@ -279,6 +284,7 @@ void AnnotationActionHandlerPrivate::updateConfigActions(const QString &annotTyp
aOpacity->setToolTip(i18nc("@info:tooltip", "Annotation opacity (No annotation selected)"));
aFont->setToolTip(i18nc("@info:tooltip", "Annotation font (No annotation selected)"));
aAddToQuickTools->setToolTip(i18nc("@info:tooltip", "Add the current annotation to the quick annotations menu (No annotation selected)"));
+ aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation selected)"));
aAdvancedSettings->setToolTip(i18nc("@info:tooltip", "Advanced settings for the current annotation tool (No annotation selected)"));
return;
}
@@ -309,6 +315,14 @@ void AnnotationActionHandlerPrivate::updateConfigActions(const QString &annotTyp
aFont->setToolTip(i18nc("@info:tooltip", "Annotation font (Current annotation has no font)"));
}
+ if (isStraightLine || isPolygon) {
+ aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain line angle to 15° steps"));
+ } else if (isShape) {
+ aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1"));
+ } else {
+ aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by current annotation)"));
+ }
+
aOpacity->setToolTip(i18nc("@info:tooltip", "Annotation opacity"));
aAddToQuickTools->setToolTip(i18nc("@info:tooltip", "Add the current annotation to the quick annotations menu"));
aAdvancedSettings->setToolTip(i18nc("@info:tooltip", "Advanced settings for the current annotation tool"));
@@ -612,6 +626,11 @@ AnnotationActionHandler::AnnotationActionHandler(PageViewAnnotator *parent, KAct
d->aContinuousMode->setToolTip(i18nc("@info:tooltip", "Keep the annotation tool active after use"));
d->aContinuousMode->setChecked(d->annotator->continuousMode());
+ // Constrain angle action
+ d->aConstrainRatioAndAngle =
+ new KToggleAction(QIcon::fromTheme(QStringLiteral("snap-angle")), i18nc("@action When checked, line annotations are constrained to 15° steps, shape annotations to 1:1 ratio", "Constrain Ratio and Angle of Annotation Tools"), this);
+ d->aConstrainRatioAndAngle->setChecked(d->annotator->constrainRatioAndAngleActive());
+
// Annotation settings actions
d->aColor = d->colorPickerAction(AnnotationActionHandlerPrivate::AnnotationColor::Color);
d->aInnerColor = d->colorPickerAction(AnnotationActionHandlerPrivate::AnnotationColor::InnerColor);
@@ -638,6 +657,7 @@ AnnotationActionHandler::AnnotationActionHandler(PageViewAnnotator *parent, KAct
connect(d->aAddToQuickTools, &QAction::triggered, d->annotator, &PageViewAnnotator::addToQuickAnnotations);
connect(d->aContinuousMode, &QAction::toggled, d->annotator, &PageViewAnnotator::setContinuousMode);
+ connect(d->aConstrainRatioAndAngle, &QAction::toggled, d->annotator, &PageViewAnnotator::setConstrainRatioAndAngle);
connect(d->aAdvancedSettings, &QAction::triggered, d->annotator, &PageViewAnnotator::slotAdvancedSettings);
connect(d->aFont, &QAction::triggered, std::bind(&AnnotationActionHandlerPrivate::slotSelectAnnotationFont, d));
@@ -675,6 +695,7 @@ AnnotationActionHandler::AnnotationActionHandler(PageViewAnnotator *parent, KAct
ac->addAction(QStringLiteral("annotation_favorites"), d->aQuickTools);
ac->addAction(QStringLiteral("annotation_bookmark"), d->aAddToQuickTools);
ac->addAction(QStringLiteral("annotation_settings_pin"), d->aContinuousMode);
+ ac->addAction(QStringLiteral("annotation_constrain_ratio_angle"), d->aConstrainRatioAndAngle);
ac->addAction(QStringLiteral("annotation_settings_width"), d->aWidth);
ac->addAction(QStringLiteral("annotation_settings_color"), d->aColor);
ac->addAction(QStringLiteral("annotation_settings_inner_color"), d->aInnerColor);
diff --git a/ui/annotationtools.cpp b/ui/annotationtools.cpp
index b32f5b31e..b4c5cf519 100644
--- a/ui/annotationtools.cpp
+++ b/ui/annotationtools.cpp
@@ -34,7 +34,7 @@ AnnotatorEngine::AnnotatorEngine(const QDomElement &engineElement)
m_annotElement = annElement;
}
-void AnnotatorEngine::decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button, Modifiers *modifiers)
+void AnnotatorEngine::decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button)
{
*eventType = AnnotatorEngine::Press;
if (mouseEvent->type() == QEvent::MouseMove)
@@ -48,11 +48,9 @@ void AnnotatorEngine::decodeEvent(const QMouseEvent *mouseEvent, EventType *even
*button = AnnotatorEngine::Left;
else if (buttonState == Qt::RightButton)
*button = AnnotatorEngine::Right;
-
- modifiers->shift = mouseEvent->modifiers() & Qt::ShiftModifier;
}
-void AnnotatorEngine::decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button, Modifiers *modifiers)
+void AnnotatorEngine::decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button)
{
switch (tabletEvent->type()) {
case QEvent::TabletPress:
@@ -75,8 +73,6 @@ void AnnotatorEngine::decodeEvent(const QTabletEvent *tabletEvent, EventType *ev
Q_ASSERT(false);
break;
}
-
- modifiers->shift = tabletEvent->modifiers() & Qt::ShiftModifier;
}
AnnotatorEngine::~AnnotatorEngine()
diff --git a/ui/annotationtools.h b/ui/annotationtools.h
index 869e94bd6..54e0c3bbb 100644
--- a/ui/annotationtools.h
+++ b/ui/annotationtools.h
@@ -42,8 +42,9 @@ public:
// enum definitions
enum EventType { Press, Move, Release };
enum Button { None, Left, Right };
+ /** To tell the annotator engine about modifier keys and other special wishes */
struct Modifiers {
- bool shift;
+ bool constrainRatioAndAngle; ///< Whether the engine shall snap to certain angles, if supported.
};
// perform operations
@@ -63,8 +64,8 @@ public:
m_item = item;
}
- static void decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button, Modifiers *modifiers);
- static void decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button, Modifiers *modifiers);
+ static void decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button);
+ static void decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button);
virtual QCursor cursor() const;
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 89ba44a9f..005fc7433 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -99,8 +99,8 @@ public:
} else
return QRect();
- // shift button: enforce 1:1 form factor (e.g. circle or square)
- if (modifiers.shift) {
+ // Constrain to 1:1 form factor (e.g. circle or square)
+ if (modifiers.constrainRatioAndAngle) {
double side = qMin(qAbs(nX - startpoint.x) * xScale, qAbs(nY - startpoint.y) * yScale);
nX = qBound(startpoint.x - side / xScale, nX, startpoint.x + side / xScale);
nY = qBound(startpoint.y - side / yScale, nY, startpoint.y + side / yScale);
@@ -350,8 +350,8 @@ public:
// if ( button != Left )
// return rect;
- // shift button: constrain to 15° steps
- if (modifiers.shift && !points.isEmpty()) {
+ // Constrain to 15° steps, except first point of course.
+ if (modifiers.constrainRatioAndAngle && !points.isEmpty()) {
const Okular::NormalizedPoint constrainedPoint = constrainAngle(points.constLast(), nX, nY, xScale, yScale, M_PI / 12.);
nX = constrainedPoint.x;
nY = constrainedPoint.y;
@@ -707,6 +707,7 @@ PageViewAnnotator::PageViewAnnotator(PageView *parent, Okular::Document *storage
, m_toolsDefinition(nullptr)
, m_quickToolsDefinition(nullptr)
, m_continuousMode(true)
+ , m_constrainRatioAndAngle(false)
, m_lastToolID(-1)
, m_lockedItem(nullptr)
{
@@ -840,7 +841,10 @@ QRect PageViewAnnotator::routeMouseEvent(QMouseEvent *e, PageViewItem *item)
AnnotatorEngine::Modifiers modifiers;
// figure out the event type and button
- AnnotatorEngine::decodeEvent(e, &eventType, &button, &modifiers);
+ AnnotatorEngine::decodeEvent(e, &eventType, &button);
+
+ // Constrain angle if action checked XOR shift button pressed.
+ modifiers.constrainRatioAndAngle = (bool(constrainRatioAndAngleActive()) != bool(e->modifiers() & Qt::ShiftModifier));
return performRouteMouseOrTabletEvent(eventType, button, modifiers, e->localPos(), item);
}
@@ -859,7 +863,10 @@ QRect PageViewAnnotator::routeTabletEvent(QTabletEvent *e, PageViewItem *item, c
AnnotatorEngine::Modifiers modifiers;
// figure out the event type and button
- AnnotatorEngine::decodeEvent(e, &eventType, &button, &modifiers);
+ AnnotatorEngine::decodeEvent(e, &eventType, &button);
+
+ // Constrain angle if action checked XOR shift button pressed.
+ modifiers.constrainRatioAndAngle = (bool(constrainRatioAndAngleActive()) != bool(e->modifiers() & Qt::ShiftModifier));
const QPointF globalPosF = e->globalPosF();
const QPointF localPosF = globalPosF - localOriginInGlobal;
@@ -1222,6 +1229,16 @@ void PageViewAnnotator::setContinuousMode(bool enabled)
Okular::Settings::self()->save();
}
+bool PageViewAnnotator::constrainRatioAndAngleActive()
+{
+ return m_constrainRatioAndAngle;
+}
+
+void PageViewAnnotator::setConstrainRatioAndAngle(bool enabled)
+{
+ m_constrainRatioAndAngle = enabled;
+}
+
void PageViewAnnotator::setToolsEnabled(bool enabled)
{
if (m_actionHandler)
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index 7177d0f7d..3c1ebdda5 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -92,6 +92,11 @@ public:
void setupActionsPostGUIActivated();
// @return Is continuous mode active (pin annotation)?
bool continuousMode();
+ /**
+ * State of constrain ratio and angle action.
+ * While annotating, this value is XOR-ed with the Shift modifier.
+ */
+ bool constrainRatioAndAngleActive();
// enable/disable the annotation actions
void setToolsEnabled(bool enabled);
// enable/disable the text-selection annotation actions
@@ -120,6 +125,11 @@ public:
public Q_SLOTS:
void setContinuousMode(bool enabled);
+ /**
+ * State of constrain ratio and angle action.
+ * While annotating, this value is XOR-ed with the Shift modifier.
+ */
+ void setConstrainRatioAndAngle(bool enabled);
void addToQuickAnnotations();
void slotAdvancedSettings();
@@ -142,6 +152,7 @@ private:
AnnotationTools *m_toolsDefinition;
AnnotationTools *m_quickToolsDefinition;
bool m_continuousMode;
+ bool m_constrainRatioAndAngle;
// creation related variables
int m_lastToolID;
diff --git a/ui/presentationwidget.cpp b/ui/presentationwidget.cpp
index 3f574031f..25ed5fdf2 100644
--- a/ui/presentationwidget.cpp
+++ b/ui/presentationwidget.cpp
@@ -1237,7 +1237,7 @@ QRect PresentationWidget::routeMouseDrawingEvent(QMouseEvent *e)
AnnotatorEngine::Modifiers modifiers;
// figure out the event type and button
- AnnotatorEngine::decodeEvent(e, &eventType, &button, &modifiers);
+ AnnotatorEngine::decodeEvent(e, &eventType, &button);
static bool hasclicked = false;
if (eventType == AnnotatorEngine::Press)