QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsadvanceddigitizingdockwidget.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsadvanceddigitizingdockwidget.h - dock for CAD tools
3 ----------------------
4 begin : October 2014
5 copyright : (C) Denis Rouzaud
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#ifndef QGSADVANCEDDIGITIZINGDOCK
17#define QGSADVANCEDDIGITIZINGDOCK
18
19#include <QList>
20#include <QQueue>
21
22#include <memory>
23
24#include "ui_qgsadvanceddigitizingdockwidgetbase.h"
25#include "qgis_gui.h"
26#include "qgis_sip.h"
27#include "qgsdockwidget.h"
28#include "qgsmessagebaritem.h"
29#include "qgspointxy.h"
30#include "qgspointlocator.h"
31#include "qgssnapindicator.h"
32
33
36class QgsMapCanvas;
37class QgsMapTool;
40
48class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private Ui::QgsAdvancedDigitizingDockWidgetBase
49{
50 Q_OBJECT
51
52 public:
53
60 {
61 AbsoluteAngle = 1,
62 RelativeAngle = 2,
63 RelativeCoordinates = 4,
64 Distance = 8,
65 };
66 Q_DECLARE_FLAGS( CadCapacities, CadCapacity )
67 Q_FLAG( CadCapacities )
68
69
75 {
76 ReturnPressed, FocusOut, TextEdited
77 };
78
79
86 class GUI_EXPORT CadConstraint
87 {
88 public:
89
94 {
97 HardLock
98 };
99
107 CadConstraint( QLineEdit *lineEdit, QToolButton *lockerButton, QToolButton *relativeButton = nullptr, QToolButton *repeatingLockButton = nullptr )
108 : mLineEdit( lineEdit )
109 , mLockerButton( lockerButton )
110 , mRelativeButton( relativeButton )
111 , mRepeatingLockButton( repeatingLockButton )
112 , mLockMode( NoLock )
113 , mRepeatingLock( false )
114 , mRelative( false )
115 , mValue( 0.0 )
116 {}
117
122 LockMode lockMode() const { return mLockMode; }
123
127 bool isLocked() const { return mLockMode != NoLock; }
128
134 bool isRepeatingLock() const { return mRepeatingLock; }
135
139 bool relative() const { return mRelative; }
140
144 double value() const { return mValue; }
145
149 QLineEdit *lineEdit() const { return mLineEdit; }
150
154 void setLockMode( LockMode mode );
155
162 void setRepeatingLock( bool repeating );
163
167 void setRelative( bool relative );
168
174 void setValue( double value, bool updateWidget = true );
175
180 QString displayValue() const;
181
185 void toggleLocked();
186
190 void toggleRelative();
191
198 int precision() const { return mPrecision; }
199
206 void setPrecision( int precision );
207
212 Qgis::CadConstraintType cadConstraintType() const;
213
218 void setCadConstraintType( Qgis::CadConstraintType constraintType );
219
224 void setMapCanvas( QgsMapCanvas *mapCanvas );
225
230 static QString removeSuffix( const QString &text, Qgis::CadConstraintType constraintType );
231
232
233 private:
234 QLineEdit *mLineEdit = nullptr;
235 QToolButton *mLockerButton = nullptr;
236 QToolButton *mRelativeButton = nullptr;
237 QToolButton *mRepeatingLockButton = nullptr;
238 LockMode mLockMode;
239 bool mRepeatingLock;
240 bool mRelative;
241 double mValue;
242 int mPrecision = 6;
244 QgsMapCanvas *mMapCanvas = nullptr;
245 };
246
252 explicit QgsAdvancedDigitizingDockWidget( QgsMapCanvas *canvas, QWidget *parent = nullptr );
253
260 bool canvasKeyPressEventFilter( QKeyEvent *e );
261
266 bool applyConstraints( QgsMapMouseEvent *e );
267
273
278 void releaseLocks( bool releaseRepeatingLocks = true );
279
283 void clear();
284
285 void keyPressEvent( QKeyEvent *e ) override;
286
288 bool cadEnabled() const { return mCadEnabled; }
289
294 void switchZM( );
295
300 void setEnabledZ( bool enable );
301
306 void setEnabledM( bool enable );
307
309 bool constructionMode() const { return mConstructionMode; }
310
315 Qgis::BetweenLineConstraint betweenLineConstraint() const { return mBetweenLineConstraint; }
317 const CadConstraint *constraintAngle() const { return mAngleConstraint.get(); }
319 const CadConstraint *constraintDistance() const { return mDistanceConstraint.get(); }
321 const CadConstraint *constraintX() const { return mXConstraint.get(); }
323 const CadConstraint *constraintY() const { return mYConstraint.get(); }
324
329 const CadConstraint *constraintZ() const { return mZConstraint.get(); }
330
335 const CadConstraint *constraintM() const { return mMConstraint.get(); }
337 bool commonAngleConstraint() const { return !qgsDoubleNear( mCommonAngleConstraint, 0.0 ); }
338
340 const CadConstraint *constraintLineExtension() const { return mLineExtensionConstraint.get(); }
341
343 Qgis::LineExtensionSide lineExtensionSide() const { return mSoftLockLineExtension; }
344
346 const CadConstraint *constraintXyVertex() const { return mXyVertexConstraint.get(); }
347
349 double softLockX() const { return mSoftLockX; }
350
352 double softLockY() const { return mSoftLockY; }
353
358 QgsPointLocator::Match mapPointMatch() const { return mSnapMatch; }
359
364 QList< QgsPointLocator::Match > lockedSnapVertices() const { return mLockedSnapVertices; }
365
371 void clearLockedSnapVertices( bool force = true );
372
376 void clearPoints();
377
381 void addPoint( const QgsPointXY &point );
382
387 void removePreviousPoint();
388
393 void updateCurrentPoint( const QgsPoint &point );
394
401 void setPoints( const QList<QgsPointXY> &points );
402
410 QgsPoint currentPointV2( bool *exists = nullptr ) const;
411
417 QgsPoint currentPointLayerCoordinates( QgsMapLayer *layer ) const;
418
425 Q_DECL_DEPRECATED QgsPointXY currentPoint( bool *exists = nullptr ) const SIP_DEPRECATED { return currentPointV2( exists ); };
426
432 QgsPoint previousPointV2( bool *exists = nullptr ) const;
433
440 Q_DECL_DEPRECATED QgsPointXY previousPoint( bool *exists = nullptr ) const SIP_DEPRECATED { return previousPointV2( exists ); };
441
447 QgsPoint penultimatePointV2( bool *exists = nullptr ) const;
448
455 Q_DECL_DEPRECATED QgsPointXY penultimatePoint( bool *exists = nullptr ) const SIP_DEPRECATED { return penultimatePointV2( exists ); };
456
460 inline int pointsCount() const { return mCadPointList.count(); }
461
465 inline bool snappedToVertex() const { return ( mSnapMatch.isValid() && ( mSnapMatch.hasVertex() || mSnapMatch.hasLineEndpoint() ) ); }
466
470 QList<QgsPointXY> snappedSegment() const { return mSnappedSegment; }
471
473 QAction *enableAction() { return mEnableAction; }
474
481 void enable();
482
486 void disable();
487
491 void updateCadPaintItem();
492
501 void setX( const QString &value, WidgetSetMode mode );
502
511 void setY( const QString &value, WidgetSetMode mode );
512
521 void setZ( const QString &value, WidgetSetMode mode );
522
531 void setM( const QString &value, WidgetSetMode mode );
532
541 void setAngle( const QString &value, WidgetSetMode mode );
542
551 void setDistance( const QString &value, WidgetSetMode mode );
552
557 double getLineZ( ) const;
558
563 double getLineM( ) const;
564
569 CadCapacities capacities() const { return mCapacities; };
570
575 QString formatCommonAngleSnapping( double angle );
576
577 signals:
578
584 void pushWarning( const QString &message );
585
590
598 void pointChangedV2( const QgsPoint &point );
599
607 Q_DECL_DEPRECATED void pointChanged( const QgsPointXY &point ) SIP_DEPRECATED;
608
610
618 void cadEnabledChanged( bool enabled );
619
626 void valueXChanged( const QString &value );
627
634 void valueYChanged( const QString &value );
635
642 void valueZChanged( const QString &value );
643
650 void valueMChanged( const QString &value );
651
658 void valueAngleChanged( const QString &value );
659
666 void valueDistanceChanged( const QString &value );
667
674 void valueBearingChanged( const QString &value );
675
682 void lockXChanged( bool locked );
683
690 void lockYChanged( bool locked );
691
698 void lockZChanged( bool locked );
699
706 void lockMChanged( bool locked );
707
714 void lockAngleChanged( bool locked );
715
722 void lockDistanceChanged( bool locked );
723
732 void relativeXChanged( bool relative );
733
742 void relativeYChanged( bool relative );
743
752 void relativeZChanged( bool relative );
753
762 void relativeMChanged( bool relative );
763
772 void relativeAngleChanged( bool relative );
773
780 void softLockLineExtensionChanged( bool locked );
781
788 void softLockXyChanged( bool locked );
789
790 // relativeDistanceChanged doesn't exist as distance is always relative
791
801 void enabledChangedX( bool enabled );
802
812 void enabledChangedY( bool enabled );
813
823 void enabledChangedZ( bool enabled );
824
834 void enabledChangedM( bool enabled );
835
845 void enabledChangedAngle( bool enabled );
846
856 void enabledChangedDistance( bool enabled );
857
865
873
881
889
897
905
911
917
918 private slots:
920 void betweenLineConstraintClicked( bool activated );
921
923 void lockConstraint( bool activate = true );
924
926 void lockParameterlessConstraint( bool activate = true );
927
932 void constraintTextEdited( const QString &textValue );
933
938 void constraintFocusOut();
939
941 void setConstraintRelative( bool activate );
942
944 void setConstraintRepeatingLock( bool activate );
945
950 void activateCad( bool enabled );
951
953 void setConstructionMode( bool enabled );
954
956 void settingsButtonTriggered( QAction *action );
957
958 private:
959
963 QgsMapLayer *targetLayer() const;
964
966 void setCadEnabled( bool enabled );
967
972 void updateCapacity( bool updateUIwithoutChange = false );
973
975 void lockBetweenLineConstraint( Qgis::BetweenLineConstraint constraint );
976
982 QList<QgsPointXY> snapSegmentToAllLayers( const QgsPointXY &originalMapPoint, bool *snapped = nullptr ) const;
983
988 bool filterKeyPress( QKeyEvent *e );
989
994 bool eventFilter( QObject *obj, QEvent *event ) override SIP_SKIP;
995
997 void triggerMouseMoveEvent();
998
1000 CadConstraint *objectToConstraint( const QObject *obj ) const;
1001
1003 double parseUserInput( const QString &inputValue, const Qgis::CadConstraintType type, bool &ok ) const;
1004
1011 void updateConstraintValue( CadConstraint *constraint, const QString &textValue, bool convertExpression = false );
1012
1014 void updateUnlockedConstraintValues( const QgsPoint &point );
1015
1016
1022 void toggleLockedSnapVertex( const QgsPointLocator::Match &snapMatch, QgsPointLocator::Match previouslySnap );
1023
1024 QgsMapCanvas *mMapCanvas = nullptr;
1025 QgsAdvancedDigitizingCanvasItem *mCadPaintItem = nullptr;
1027 std::unique_ptr<QgsSnapIndicator> mSnapIndicator;
1028
1029 CadCapacities mCapacities = CadCapacities();
1030
1031 bool mCurrentMapToolSupportsCad = false;
1032
1033 // Pointer to the floater
1034 QgsAdvancedDigitizingFloater *mFloater = nullptr;
1035
1036 // CAD properties
1038 bool mCadEnabled = false;
1039 bool mConstructionMode = false;
1040
1041 // constraints
1042 std::unique_ptr< CadConstraint > mAngleConstraint;
1043 std::unique_ptr< CadConstraint > mDistanceConstraint;
1044 std::unique_ptr< CadConstraint > mXConstraint;
1045 std::unique_ptr< CadConstraint > mYConstraint;
1046 std::unique_ptr< CadConstraint > mZConstraint;
1047 std::unique_ptr< CadConstraint > mMConstraint;
1048 std::unique_ptr< CadConstraint > mLineExtensionConstraint;
1049 std::unique_ptr< CadConstraint > mXyVertexConstraint;
1050 Qgis::BetweenLineConstraint mBetweenLineConstraint;
1051 double mCommonAngleConstraint; // if 0: do not snap to common angles
1052
1054 bool mSnappingPrioritizeFeatures = false;
1055
1056 // point list and current snap point / segment
1057 QList<QgsPoint> mCadPointList;
1058 QList<QgsPointXY> mSnappedSegment;
1059
1060 bool mSessionActive = false;
1061
1062 // error message
1063 std::unique_ptr<QgsMessageBarItem> mErrorMessage;
1064
1065 // UI
1066 QMap< double, QAction *> mCommonAngleActions; // map the common angle actions with their angle values
1067 QAction *mLineExtensionAction;
1068 QAction *mXyVertexAction;
1069
1070 // Snap indicator
1071 QgsPointLocator::Match mSnapMatch;
1072 QgsPointLocator::Match mLastSnapMatch;
1073
1074 // Extra constraint context
1075 Qgis::LineExtensionSide mSoftLockLineExtension;
1076 double mSoftLockX;
1077 double mSoftLockY;
1078 QQueue< QgsPointLocator::Match > mLockedSnapVertices;
1079
1080#ifdef SIP_RUN
1082 bool eventFilter( QObject *obj, QEvent *event );
1083#endif
1085 QgsPoint pointXYToPoint( const QgsPointXY &point ) const;
1086
1087 QMenu *mCommonAngleActionsMenu = nullptr;
1088 QMenu *mFloaterActionsMenu = nullptr;
1089
1090 static const QgsSettingsEntryBool *settingsCadSnappingPriorityPrioritizeFeature;
1091
1092 friend class TestQgsAdvancedDigitizing;
1093 friend class TestQgsAdvancedDigitizingDockWidget;
1094};
1095
1097
1098#endif // QGSADVANCEDDIGITIZINGDOCK_H
CadConstraintType
Advanced digitizing constraint type.
Definition: qgis.h:3329
@ Generic
Generic value.
BetweenLineConstraint
Between line constraints which can be enabled.
Definition: qgis.h:3303
LineExtensionSide
Designates whether the line extension constraint is currently soft locked with the previous or next v...
Definition: qgis.h:3316
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (.
The CadConstraint is a class for all basic constraints (angle/distance/x/y).
CadConstraint(QLineEdit *lineEdit, QToolButton *lockerButton, QToolButton *relativeButton=nullptr, QToolButton *repeatingLockButton=nullptr)
Constructor for CadConstraint.
bool isLocked() const
Is any kind of lock mode enabled.
double value() const
The value of the constraint.
bool isRepeatingLock() const
Returns true if a repeating lock is set for the constraint.
LockMode lockMode() const
The current lock mode of this constraint.
int precision() const
Returns the numeric precision (decimal places) to show in the associated widget.
bool relative() const
Is the constraint in relative mode.
QLineEdit * lineEdit() const
The line edit that manages the value of the constraint.
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
void valueDistanceChanged(const QString &value)
Emitted whenever the distance value changes (either the mouse moved, or the user changed the input).
bool commonAngleConstraint() const
Returns true if a constraint on a common angle is active.
Q_DECL_DEPRECATED QgsPointXY currentPoint(bool *exists=nullptr) const
The last point.
void lockZChanged(bool locked)
Emitted whenever the Z parameter is locked.
double softLockY() const
Returns the Y value of the Y soft lock. The value is NaN is the constraint isn't magnetized to a line...
const CadConstraint * constraintM() const
Returns the CadConstraint on the M coordinate.
void enabledChangedY(bool enabled)
Emitted whenever the Y field is enabled or disabled.
QAction * enableAction()
Returns the action used to enable/disable the tools.
bool cadEnabled() const
determines if CAD tools are enabled or if map tools behaves "nomally"
int pointsCount() const
The number of points in the CAD point helper list.
QList< QgsPointXY > snappedSegment() const
Snapped to a segment.
void relativeMChanged(bool relative)
Emitted whenever the M parameter is toggled between absolute and relative.
void lockXChanged(bool locked)
Emitted whenever the X parameter is locked.
void softLockLineExtensionChanged(bool locked)
Emitted whenever the soft line extension parameter is locked.
void focusOnXRequested()
Emitted whenever the X field should get the focus using the shortcuts (X).
bool constructionMode() const
construction mode is used to draw intermediate points. These points won't be given any further (i....
void enabledChangedX(bool enabled)
Emitted whenever the X field is enabled or disabled.
void valueYChanged(const QString &value)
Emitted whenever the Y value changes (either the mouse moved, or the user changed the input).
Q_DECL_DEPRECATED QgsPointXY penultimatePoint(bool *exists=nullptr) const
The penultimate point.
const CadConstraint * constraintLineExtension() const
Returns the CadConstraint.
void focusOnYRequested()
Emitted whenever the Y field should get the focus using the shortcuts (Y).
void enabledChangedDistance(bool enabled)
Emitted whenever the distance field is enabled or disabled.
bool snappedToVertex() const
Is it snapped to a vertex.
void valueZChanged(const QString &value)
Emitted whenever the Z value changes (either the mouse moved, or the user changed the input).
QList< QgsPointLocator::Match > lockedSnapVertices() const
Returns the snap matches whose vertices have been locked.
void lockAngleChanged(bool locked)
Emitted whenever the angle parameter is locked.
void pointChangedV2(const QgsPoint &point)
Sometimes a constraint may change the current point out of a mouse event.
void commonAngleSnappingShowInFloaterChanged(bool enabled)
Emitted whenever the option to show common angle snapping in the floater changes.
void relativeXChanged(bool relative)
Emitted whenever the X parameter is toggled between absolute and relative.
void focusOnAngleRequested()
Emitted whenever the angle field should get the focus using the shortcuts (A).
WidgetSetMode
Type of interaction to simulate when editing values from external widget.
const CadConstraint * constraintXyVertex() const
Returns the CadConstraint.
void focusOnZRequested()
Emitted whenever the Z field should get the focus using the shortcuts (Z).
void focusOnMRequested()
Emitted whenever the M field should get the focus using the shortcuts (M).
void popWarning()
Remove any previously emitted warnings (if any)
void valueXChanged(const QString &value)
Emitted whenever the X value changes (either the mouse moved, or the user changed the input).
void lockMChanged(bool locked)
Emitted whenever the M parameter is locked.
void cadEnabledChanged(bool enabled)
Signals for external widgets that need to update according to current values.
void lockYChanged(bool locked)
Emitted whenever the Y parameter is locked.
const CadConstraint * constraintY() const
Returns the CadConstraint on the Y coordinate.
void valueAngleChanged(const QString &value)
Emitted whenever the angle value changes (either the mouse moved, or the user changed the input).
void valueMChanged(const QString &value)
Emitted whenever the M value changes (either the mouse moved, or the user changed the input).
void relativeZChanged(bool relative)
Emitted whenever the Z parameter is toggled between absolute and relative.
double softLockX() const
Returns the X value of the X soft lock. The value is NaN is the constraint isn't magnetized to a line...
Q_DECL_DEPRECATED void pointChanged(const QgsPointXY &point)
Sometimes a constraint may change the current point out of a mouse event.
CadCapacity
The CadCapacity enum defines the possible constraints to be set depending on the number of points in ...
Qgis::BetweenLineConstraint betweenLineConstraint() const
Returns the between line constraints which are used to place perpendicular/parallel segments to snapp...
void enabledChangedAngle(bool enabled)
Emitted whenever the angle field is enabled or disabled.
Q_DECL_DEPRECATED QgsPointXY previousPoint(bool *exists=nullptr) const
The previous point.
void enabledChangedZ(bool enabled)
Emitted whenever the Z field is enabled or disabled.
void lockDistanceChanged(bool locked)
Emitted whenever the distance parameter is locked.
void relativeAngleChanged(bool relative)
Emitted whenever the angleX parameter is toggled between absolute and relative.
const CadConstraint * constraintX() const
Returns the CadConstraint on the X coordinate.
CadCapacities capacities() const
Returns the capacities.
void softLockXyChanged(bool locked)
Emitted whenever the soft x/y extension parameter is locked.
const CadConstraint * constraintZ() const
Returns the CadConstraint on the Z coordinate.
void valueBearingChanged(const QString &value)
Emitted whenever the bearing value changes.
void enabledChangedM(bool enabled)
Emitted whenever the M field is enabled or disabled.
QgsPointLocator::Match mapPointMatch() const
Returns the point locator match.
void focusOnDistanceRequested()
Emitted whenever the distance field should get the focus using the shortcuts (D).
const CadConstraint * constraintAngle() const
Returns the CadConstraint on the angle.
void valueCommonAngleSnappingChanged(double angle)
Emitted whenever the snapping to common angle option changes, angle = 0 means that the functionality ...
void pushWarning(const QString &message)
Push a warning.
Qgis::LineExtensionSide lineExtensionSide() const
Returns on which side of the constraint line extension point, the line was created.
const CadConstraint * constraintDistance() const
Returns the CadConstraint on the distance.
void relativeYChanged(bool relative)
Emitted whenever the Y parameter is toggled between absolute and relative.
The QgsAdvancedDigitizingFloater class is widget that floats next to the mouse pointer,...
QgsDockWidget subclass with more fine-grained control over how the widget is closed or opened.
Definition: qgsdockwidget.h:31
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
Base class for all map layer types.
Definition: qgsmaplayer.h:75
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
The QgsMapToolAdvancedDigitizing class is a QgsMapTool which gives event directly in map coordinates ...
Abstract base class for all map tools.
Definition: qgsmaptool.h:71
A class to represent a 2D point.
Definition: qgspointxy.h:60
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
A boolean settings entry.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:716
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5207
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_ENUM_BASETYPE(type)
Definition: qgis_sip.h:278
#define SIP_SKIP
Definition: qgis_sip.h:126
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsTextRendererUtils::CurvedTextFlags)
int precision