QGIS API Documentation 3.39.0-Master (47f7b3a4989)
Loading...
Searching...
No Matches
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
312 bool constructionMode() const { return mConstructionMode; }
313
318 QgsVectorLayer *constructionGuidesLayer() const { return mConstructionGuidesLayer.get(); }
319
324 bool showConstructionGuides() const;
325
330 bool snapToConstructionGuides() const;
331
336 bool recordConstructionGuides() const;
337
342 Qgis::BetweenLineConstraint betweenLineConstraint() const { return mBetweenLineConstraint; }
344 const CadConstraint *constraintAngle() const { return mAngleConstraint.get(); }
346 const CadConstraint *constraintDistance() const { return mDistanceConstraint.get(); }
348 const CadConstraint *constraintX() const { return mXConstraint.get(); }
350 const CadConstraint *constraintY() const { return mYConstraint.get(); }
351
356 const CadConstraint *constraintZ() const { return mZConstraint.get(); }
357
362 const CadConstraint *constraintM() const { return mMConstraint.get(); }
364 bool commonAngleConstraint() const { return !qgsDoubleNear( mCommonAngleConstraint, 0.0 ); }
365
367 const CadConstraint *constraintLineExtension() const { return mLineExtensionConstraint.get(); }
368
370 Qgis::LineExtensionSide lineExtensionSide() const { return mSoftLockLineExtension; }
371
373 const CadConstraint *constraintXyVertex() const { return mXyVertexConstraint.get(); }
374
376 double softLockX() const { return mSoftLockX; }
377
379 double softLockY() const { return mSoftLockY; }
380
385 QgsPointLocator::Match mapPointMatch() const { return mSnapMatch; }
386
391 QList< QgsPointLocator::Match > lockedSnapVertices() const { return mLockedSnapVertices; }
392
398 void clearLockedSnapVertices( bool force = true );
399
403 void clearPoints();
404
408 void addPoint( const QgsPointXY &point );
409
414 void removePreviousPoint();
415
420 void updateCurrentPoint( const QgsPoint &point );
421
428 void setPoints( const QList<QgsPointXY> &points );
429
437 QgsPoint currentPointV2( bool *exists = nullptr ) const;
438
444 QgsPoint currentPointLayerCoordinates( QgsMapLayer *layer ) const;
445
452 Q_DECL_DEPRECATED QgsPointXY currentPoint( bool *exists = nullptr ) const SIP_DEPRECATED { return currentPointV2( exists ); };
453
459 QgsPoint previousPointV2( bool *exists = nullptr ) const;
460
467 Q_DECL_DEPRECATED QgsPointXY previousPoint( bool *exists = nullptr ) const SIP_DEPRECATED { return previousPointV2( exists ); };
468
474 QgsPoint penultimatePointV2( bool *exists = nullptr ) const;
475
482 Q_DECL_DEPRECATED QgsPointXY penultimatePoint( bool *exists = nullptr ) const SIP_DEPRECATED { return penultimatePointV2( exists ); };
483
487 inline int pointsCount() const { return mCadPointList.count(); }
488
492 inline bool snappedToVertex() const { return ( mSnapMatch.isValid() && ( mSnapMatch.hasVertex() || mSnapMatch.hasLineEndpoint() ) ); }
493
497 QList<QgsPointXY> snappedSegment() const { return mSnappedSegment; }
498
500 QAction *enableAction() { return mEnableAction; }
501
508 void enable();
509
513 void disable();
514
518 void updateCadPaintItem();
519
528 void setX( const QString &value, WidgetSetMode mode );
529
538 void setY( const QString &value, WidgetSetMode mode );
539
548 void setZ( const QString &value, WidgetSetMode mode );
549
558 void setM( const QString &value, WidgetSetMode mode );
559
568 void setAngle( const QString &value, WidgetSetMode mode );
569
578 void setDistance( const QString &value, WidgetSetMode mode );
579
584 double getLineZ( ) const;
585
590 double getLineM( ) const;
591
596 CadCapacities capacities() const { return mCapacities; };
597
602 QString formatCommonAngleSnapping( double angle );
603
604 signals:
605
611 void pushWarning( const QString &message );
612
617
625 void pointChangedV2( const QgsPoint &point );
626
634 Q_DECL_DEPRECATED void pointChanged( const QgsPointXY &point ) SIP_DEPRECATED;
635
637
645 void cadEnabledChanged( bool enabled );
646
653 void valueXChanged( const QString &value );
654
661 void valueYChanged( const QString &value );
662
669 void valueZChanged( const QString &value );
670
677 void valueMChanged( const QString &value );
678
685 void valueAngleChanged( const QString &value );
686
693 void valueDistanceChanged( const QString &value );
694
701 void valueBearingChanged( const QString &value );
702
709 void lockXChanged( bool locked );
710
717 void lockYChanged( bool locked );
718
725 void lockZChanged( bool locked );
726
733 void lockMChanged( bool locked );
734
741 void lockAngleChanged( bool locked );
742
749 void lockDistanceChanged( bool locked );
750
759 void relativeXChanged( bool relative );
760
769 void relativeYChanged( bool relative );
770
779 void relativeZChanged( bool relative );
780
789 void relativeMChanged( bool relative );
790
799 void relativeAngleChanged( bool relative );
800
807 void softLockLineExtensionChanged( bool locked );
808
815 void softLockXyChanged( bool locked );
816
817 // relativeDistanceChanged doesn't exist as distance is always relative
818
828 void enabledChangedX( bool enabled );
829
839 void enabledChangedY( bool enabled );
840
850 void enabledChangedZ( bool enabled );
851
861 void enabledChangedM( bool enabled );
862
872 void enabledChangedAngle( bool enabled );
873
883 void enabledChangedDistance( bool enabled );
884
892
900
908
916
924
932
938
944
945 private slots:
947 void betweenLineConstraintClicked( bool activated );
948
950 void lockConstraint( bool activate = true );
951
953 void lockParameterlessConstraint( bool activate = true );
954
959 void constraintTextEdited( const QString &textValue );
960
965 void constraintFocusOut();
966
968 void setConstraintRelative( bool activate );
969
971 void setConstraintRepeatingLock( bool activate );
972
977 void activateCad( bool enabled );
978
980 void setConstructionMode( bool enabled );
981
983 void settingsButtonTriggered( QAction *action );
984
985 private:
986
990 QgsMapLayer *targetLayer() const;
991
993 void setCadEnabled( bool enabled );
994
999 void updateCapacity( bool updateUIwithoutChange = false );
1000
1002 void lockBetweenLineConstraint( Qgis::BetweenLineConstraint constraint );
1003
1009 QList<QgsPointXY> snapSegmentToAllLayers( const QgsPointXY &originalMapPoint, bool *snapped = nullptr ) const;
1010
1015 bool filterKeyPress( QKeyEvent *e );
1016
1021 bool eventFilter( QObject *obj, QEvent *event ) override SIP_SKIP;
1022
1024 void triggerMouseMoveEvent();
1025
1027 CadConstraint *objectToConstraint( const QObject *obj ) const;
1028
1030 double parseUserInput( const QString &inputValue, const Qgis::CadConstraintType type, bool &ok ) const;
1031
1038 void updateConstraintValue( CadConstraint *constraint, const QString &textValue, bool convertExpression = false );
1039
1041 void updateUnlockedConstraintValues( const QgsPoint &point );
1042
1048 void toggleLockedSnapVertex( const QgsPointLocator::Match &snapMatch, QgsPointLocator::Match previouslySnap );
1049
1053 void resetConstructionGuides();
1054
1059 void updateConstructionGuidesCrs();
1060
1061 QgsMapCanvas *mMapCanvas = nullptr;
1062 QgsAdvancedDigitizingCanvasItem *mCadPaintItem = nullptr;
1064 std::unique_ptr<QgsSnapIndicator> mSnapIndicator;
1065
1066 CadCapacities mCapacities = CadCapacities();
1067
1068 bool mCurrentMapToolSupportsCad = false;
1069
1070 // Pointer to the floater
1071 QgsAdvancedDigitizingFloater *mFloater = nullptr;
1072
1073 // CAD properties
1075 bool mCadEnabled = false;
1076 bool mConstructionMode = false;
1077
1078 // constraints
1079 std::unique_ptr< CadConstraint > mAngleConstraint;
1080 std::unique_ptr< CadConstraint > mDistanceConstraint;
1081 std::unique_ptr< CadConstraint > mXConstraint;
1082 std::unique_ptr< CadConstraint > mYConstraint;
1083 std::unique_ptr< CadConstraint > mZConstraint;
1084 std::unique_ptr< CadConstraint > mMConstraint;
1085 std::unique_ptr< CadConstraint > mLineExtensionConstraint;
1086 std::unique_ptr< CadConstraint > mXyVertexConstraint;
1087 Qgis::BetweenLineConstraint mBetweenLineConstraint;
1088 double mCommonAngleConstraint; // if 0: do not snap to common angles
1089
1091 bool mSnappingPrioritizeFeatures = false;
1092
1093 // Point list and current snap point / segment
1094 QList<QgsPoint> mCadPointList;
1095 QList<QgsPointXY> mSnappedSegment;
1096
1097 bool mSessionActive = false;
1098
1099 // Construction path history
1100 std::unique_ptr<QgsVectorLayer> mConstructionGuidesLayer;
1101 QgsFeatureId mConstructionGuideId;
1102 QgsLineString mConstructionGuideLine;
1103 bool mDeferredUpdateConstructionGuidesCrs = false;
1104
1105 // Error message
1106 std::unique_ptr<QgsMessageBarItem> mErrorMessage;
1107
1108 // UI
1109 QMap< double, QAction *> mCommonAngleActions; // map the common angle actions with their angle values
1110 QAction *mLineExtensionAction = nullptr;
1111 QAction *mXyVertexAction = nullptr;
1112 QAction *mRecordConstructionGuides = nullptr;
1113 QAction *mShowConstructionGuides = nullptr;
1114 QAction *mSnapToConstructionGuides = nullptr;
1115 QAction *mClearConstructionGuides = nullptr;
1116
1117 // Snap indicator
1118 QgsPointLocator::Match mSnapMatch;
1119 QgsPointLocator::Match mLastSnapMatch;
1120
1121 // Extra constraint context
1122 Qgis::LineExtensionSide mSoftLockLineExtension;
1123 double mSoftLockX;
1124 double mSoftLockY;
1125 QQueue< QgsPointLocator::Match > mLockedSnapVertices;
1126
1127#ifdef SIP_RUN
1129 bool eventFilter( QObject *obj, QEvent *event );
1130#endif
1132 QgsPoint pointXYToPoint( const QgsPointXY &point ) const;
1133
1134 QMenu *mCommonAngleActionsMenu = nullptr;
1135 QMenu *mFloaterActionsMenu = nullptr;
1136
1137 static const QgsSettingsEntryBool *settingsCadSnappingPriorityPrioritizeFeature;
1138 static const QgsSettingsEntryBool *settingsCadRecordConstructionGuides;
1139 static const QgsSettingsEntryBool *settingsCadShowConstructionGuides;
1140 static const QgsSettingsEntryBool *settingsCadSnapToConstructionGuides;
1141
1142 friend class TestQgsAdvancedDigitizing;
1143 friend class TestQgsAdvancedDigitizingDockWidget;
1144};
1145
1147
1148#endif // QGSADVANCEDDIGITIZINGDOCK_H
CadConstraintType
Advanced digitizing constraint type.
Definition qgis.h:3500
@ Generic
Generic value.
BetweenLineConstraint
Between line constraints which can be enabled.
Definition qgis.h:3474
LineExtensionSide
Designates whether the line extension constraint is currently soft locked with the previous or next v...
Definition qgis.h:3487
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.
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
Returns whether the construction mode is activated.
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).
QgsVectorLayer * constructionGuidesLayer() const
Returns the vector layer within which construction guides are stored.
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.
Line string geometry type, with support for z-dimension and m-values.
Map canvas is a class for displaying all GIS data types on a canvas.
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.
Represents a vector layer which manages a vector based data sets.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:5465
#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
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsTextRendererUtils::CurvedTextFlags)
int precision