QGIS API Documentation 3.31.0-Master (9f23a2c1dc)
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
135 bool isRepeatingLock() const { return mRepeatingLock; }
136
140 bool relative() const { return mRelative; }
141
145 double value() const { return mValue; }
146
150 QLineEdit *lineEdit() const { return mLineEdit; }
151
155 void setLockMode( LockMode mode );
156
164 void setRepeatingLock( bool repeating );
165
169 void setRelative( bool relative );
170
176 void setValue( double value, bool updateWidget = true );
177
182 QString displayValue() const;
183
187 void toggleLocked();
188
192 void toggleRelative();
193
200 int precision() const { return mPrecision; }
201
208 void setPrecision( int precision );
209
214 Qgis::CadConstraintType cadConstraintType() const;
215
220 void setCadConstraintType( Qgis::CadConstraintType constraintType );
221
226 void setMapCanvas( QgsMapCanvas *mapCanvas );
227
228 private:
229 QLineEdit *mLineEdit = nullptr;
230 QToolButton *mLockerButton = nullptr;
231 QToolButton *mRelativeButton = nullptr;
232 QToolButton *mRepeatingLockButton = nullptr;
233 LockMode mLockMode;
234 bool mRepeatingLock;
235 bool mRelative;
236 double mValue;
237 int mPrecision = 6;
239 QgsMapCanvas *mMapCanvas = nullptr;
240 };
241
247 explicit QgsAdvancedDigitizingDockWidget( QgsMapCanvas *canvas, QWidget *parent = nullptr );
248
255 bool canvasKeyPressEventFilter( QKeyEvent *e );
256
261 bool applyConstraints( QgsMapMouseEvent *e );
262
269
275 void releaseLocks( bool releaseRepeatingLocks = true );
276
280 void clear();
281
282 void keyPressEvent( QKeyEvent *e ) override;
283
285 bool cadEnabled() const { return mCadEnabled; }
286
291 void switchZM( );
292
297 void setEnabledZ( bool enable );
298
303 void setEnabledM( bool enable );
304
306 bool constructionMode() const { return mConstructionMode; }
307
312 Qgis::BetweenLineConstraint betweenLineConstraint() const { return mBetweenLineConstraint; }
314 const CadConstraint *constraintAngle() const { return mAngleConstraint.get(); }
316 const CadConstraint *constraintDistance() const { return mDistanceConstraint.get(); }
318 const CadConstraint *constraintX() const { return mXConstraint.get(); }
320 const CadConstraint *constraintY() const { return mYConstraint.get(); }
321
326 const CadConstraint *constraintZ() const { return mZConstraint.get(); }
327
332 const CadConstraint *constraintM() const { return mMConstraint.get(); }
334 bool commonAngleConstraint() const { return !qgsDoubleNear( mCommonAngleConstraint, 0.0 ); }
335
337 const CadConstraint *constraintLineExtension() const { return mLineExtensionConstraint.get(); }
338
340 Qgis::LineExtensionSide lineExtensionSide() const { return mSoftLockLineExtension; }
341
343 const CadConstraint *constraintXyVertex() const { return mXyVertexConstraint.get(); }
344
346 double softLockX() const { return mSoftLockX; }
347
349 double softLockY() const { return mSoftLockY; }
350
355 QgsPointLocator::Match mapPointMatch() const { return mSnapMatch; }
356
361 QList< QgsPointLocator::Match > lockedSnapVertices() const { return mLockedSnapVertices; }
362
368 void clearLockedSnapVertices( bool force = true );
369
374 void clearPoints();
375
380 void addPoint( const QgsPointXY &point );
381
386 void removePreviousPoint();
387
392 void updateCurrentPoint( const QgsPoint &point );
393
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
492 void updateCadPaintItem();
493
502 void setX( const QString &value, WidgetSetMode mode );
503
512 void setY( const QString &value, WidgetSetMode mode );
513
522 void setZ( const QString &value, WidgetSetMode mode );
523
532 void setM( const QString &value, WidgetSetMode mode );
533
542 void setAngle( const QString &value, WidgetSetMode mode );
543
552 void setDistance( const QString &value, WidgetSetMode mode );
553
558 double getLineZ( ) const;
559
564 double getLineM( ) const;
565
570 CadCapacities capacities() const { return mCapacities; };
571
576 QString formatCommonAngleSnapping( double angle );
577
578 signals:
579
585 void pushWarning( const QString &message );
586
591
599 void pointChangedV2( const QgsPoint &point );
600
608 Q_DECL_DEPRECATED void pointChanged( const QgsPointXY &point ) SIP_DEPRECATED;
609
611
619 void cadEnabledChanged( bool enabled );
620
627 void valueXChanged( const QString &value );
628
635 void valueYChanged( const QString &value );
636
643 void valueZChanged( const QString &value );
644
651 void valueMChanged( const QString &value );
652
659 void valueAngleChanged( const QString &value );
660
667 void valueDistanceChanged( const QString &value );
668
675 void valueBearingChanged( const QString &value );
676
683 void lockXChanged( bool locked );
684
691 void lockYChanged( bool locked );
692
699 void lockZChanged( bool locked );
700
707 void lockMChanged( bool locked );
708
715 void lockAngleChanged( bool locked );
716
723 void lockDistanceChanged( bool locked );
724
733 void relativeXChanged( bool relative );
734
743 void relativeYChanged( bool relative );
744
753 void relativeZChanged( bool relative );
754
763 void relativeMChanged( bool relative );
764
773 void relativeAngleChanged( bool relative );
774
781 void softLockLineExtensionChanged( bool locked );
782
789 void softLockXyChanged( bool locked );
790
791 // relativeDistanceChanged doesn't exist as distance is always relative
792
802 void enabledChangedX( bool enabled );
803
813 void enabledChangedY( bool enabled );
814
824 void enabledChangedZ( bool enabled );
825
835 void enabledChangedM( bool enabled );
836
846 void enabledChangedAngle( bool enabled );
847
857 void enabledChangedDistance( bool enabled );
858
866
874
882
890
898
906
912
918
919 private slots:
921 void betweenLineConstraintClicked( bool activated );
922
924 void lockConstraint( bool activate = true );
925
927 void lockParameterlessConstraint( bool activate = true );
928
933 void constraintTextEdited( const QString &textValue );
934
939 void constraintFocusOut();
940
942 void setConstraintRelative( bool activate );
943
945 void setConstraintRepeatingLock( bool activate );
946
951 void activateCad( bool enabled );
952
954 void setConstructionMode( bool enabled );
955
957 void settingsButtonTriggered( QAction *action );
958
959 private:
960
964 QgsMapLayer *targetLayer() const;
965
967 void setCadEnabled( bool enabled );
968
973 void updateCapacity( bool updateUIwithoutChange = false );
974
976 void lockBetweenLineConstraint( Qgis::BetweenLineConstraint constraint );
977
983 QList<QgsPointXY> snapSegmentToAllLayers( const QgsPointXY &originalMapPoint, bool *snapped = nullptr ) const;
984
989 bool filterKeyPress( QKeyEvent *e );
990
995 bool eventFilter( QObject *obj, QEvent *event ) override SIP_SKIP;
996
998 void triggerMouseMoveEvent();
999
1001 CadConstraint *objectToConstraint( const QObject *obj ) const;
1002
1004 double parseUserInput( const QString &inputValue, const Qgis::CadConstraintType type, bool &ok ) const;
1005
1012 void updateConstraintValue( CadConstraint *constraint, const QString &textValue, bool convertExpression = false );
1013
1015 void updateUnlockedConstraintValues( const QgsPoint &point );
1016
1017
1023 void toggleLockedSnapVertex( const QgsPointLocator::Match &snapMatch, QgsPointLocator::Match previouslySnap );
1024
1025 QgsMapCanvas *mMapCanvas = nullptr;
1026 QgsAdvancedDigitizingCanvasItem *mCadPaintItem = nullptr;
1028 std::unique_ptr<QgsSnapIndicator> mSnapIndicator;
1029
1030 CadCapacities mCapacities = CadCapacities();
1031
1032 bool mCurrentMapToolSupportsCad = false;
1033
1034 // Pointer to the floater
1035 QgsAdvancedDigitizingFloater *mFloater = nullptr;
1036
1037 // CAD properties
1039 bool mCadEnabled = false;
1040 bool mConstructionMode = false;
1041
1042 // constraints
1043 std::unique_ptr< CadConstraint > mAngleConstraint;
1044 std::unique_ptr< CadConstraint > mDistanceConstraint;
1045 std::unique_ptr< CadConstraint > mXConstraint;
1046 std::unique_ptr< CadConstraint > mYConstraint;
1047 std::unique_ptr< CadConstraint > mZConstraint;
1048 std::unique_ptr< CadConstraint > mMConstraint;
1049 std::unique_ptr< CadConstraint > mLineExtensionConstraint;
1050 std::unique_ptr< CadConstraint > mXyVertexConstraint;
1051 Qgis::BetweenLineConstraint mBetweenLineConstraint;
1052 double mCommonAngleConstraint; // if 0: do not snap to common angles
1053
1055 bool mSnappingPrioritizeFeatures = false;
1056
1057 // point list and current snap point / segment
1058 QList<QgsPoint> mCadPointList;
1059 QList<QgsPointXY> mSnappedSegment;
1060
1061 bool mSessionActive = false;
1062
1063 // error message
1064 std::unique_ptr<QgsMessageBarItem> mErrorMessage;
1065
1066 // UI
1067 QMap< QAction *, double > mCommonAngleActions; // map the common angle actions with their angle values
1068 QAction *mLineExtensionAction;
1069 QAction *mXyVertexAction;
1070
1071 // Snap indicator
1072 QgsPointLocator::Match mSnapMatch;
1073 QgsPointLocator::Match mLastSnapMatch;
1074
1075 // Extra constraint context
1076 Qgis::LineExtensionSide mSoftLockLineExtension;
1077 double mSoftLockX;
1078 double mSoftLockY;
1079 QQueue< QgsPointLocator::Match > mLockedSnapVertices;
1080
1081#ifdef SIP_RUN
1083 bool eventFilter( QObject *obj, QEvent *event );
1084#endif
1086 QgsPoint pointXYToPoint( const QgsPointXY &point ) const;
1087
1088 QMenu *mCommonAngleActionsMenu = nullptr;
1089 QMenu *mFloaterActionsMenu = nullptr;
1090
1091 static const QgsSettingsEntryBool *settingsCadSnappingPriorityPrioritizeFeature;
1092
1093 friend class TestQgsAdvancedDigitizing;
1094 friend class TestQgsAdvancedDigitizingDockWidget;
1095};
1096
1097Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAdvancedDigitizingDockWidget::CadCapacities )
1098
1099#endif // QGSADVANCEDDIGITIZINGDOCK_H
CadConstraintType
Advanced digitizing constraint type.
Definition: qgis.h:2495
@ Generic
Generic value.
BetweenLineConstraint
Between line constraints which can be enabled.
Definition: qgis.h:2469
LineExtensionSide
Designates whether the line extension constraint is currently soft locked with the previous or next v...
Definition: qgis.h:2482
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:32
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
Base class for all map layer types.
Definition: qgsmaplayer.h:73
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:59
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:786
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:3903
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_SKIP
Definition: qgis_sip.h:126
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
int precision