QGIS API Documentation  3.20.0-Odense (decaadbb31)
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
6  email : [email protected]
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 
21 #include <memory>
22 
23 #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 
36 class QgsMapCanvas;
37 class QgsMapTool;
39 class QgsMapMouseEvent;
40 
48 class 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  };
65  Q_DECLARE_FLAGS( CadCapacities, CadCapacity )
66  Q_FLAG( CadCapacities )
67 
68 
72  {
73  NoConstraint,
74  Perpendicular,
75  Parallel
76  };
77 
84  {
85  ReturnPressed, FocusOut, TextEdited
86  };
87 
88 
95  class GUI_EXPORT CadConstraint
96  {
97  public:
98 
102  enum LockMode
103  {
106  HardLock
107  };
108 
116  CadConstraint( QLineEdit *lineEdit, QToolButton *lockerButton, QToolButton *relativeButton = nullptr, QToolButton *repeatingLockButton = nullptr )
117  : mLineEdit( lineEdit )
118  , mLockerButton( lockerButton )
119  , mRelativeButton( relativeButton )
120  , mRepeatingLockButton( repeatingLockButton )
121  , mLockMode( NoLock )
122  , mRepeatingLock( false )
123  , mRelative( false )
124  , mValue( 0.0 )
125  {}
126 
131  LockMode lockMode() const { return mLockMode; }
132 
136  bool isLocked() const { return mLockMode != NoLock; }
137 
144  bool isRepeatingLock() const { return mRepeatingLock; }
145 
149  bool relative() const { return mRelative; }
150 
154  double value() const { return mValue; }
155 
159  QLineEdit *lineEdit() const { return mLineEdit; }
160 
164  void setLockMode( LockMode mode );
165 
173  void setRepeatingLock( bool repeating );
174 
178  void setRelative( bool relative );
179 
185  void setValue( double value, bool updateWidget = true );
186 
190  void toggleLocked();
191 
195  void toggleRelative();
196 
197  private:
198  QLineEdit *mLineEdit = nullptr;
199  QToolButton *mLockerButton = nullptr;
200  QToolButton *mRelativeButton = nullptr;
201  QToolButton *mRepeatingLockButton = nullptr;
202  LockMode mLockMode;
203  bool mRepeatingLock;
204  bool mRelative;
205  double mValue;
206  };
207 
213  explicit QgsAdvancedDigitizingDockWidget( QgsMapCanvas *canvas, QWidget *parent = nullptr );
214 
221  bool canvasKeyPressEventFilter( QKeyEvent *e );
222 
227  bool applyConstraints( QgsMapMouseEvent *e );
228 
235 
241  void releaseLocks( bool releaseRepeatingLocks = true );
242 
246  void clear();
247 
248  void keyPressEvent( QKeyEvent *e ) override;
249 
251  bool cadEnabled() const { return mCadEnabled; }
252 
254  bool constructionMode() const { return mConstructionMode; }
255 
260  AdditionalConstraint additionalConstraint() const { return mAdditionalConstraint; }
262  const CadConstraint *constraintAngle() const { return mAngleConstraint.get(); }
264  const CadConstraint *constraintDistance() const { return mDistanceConstraint.get(); }
266  const CadConstraint *constraintX() const { return mXConstraint.get(); }
268  const CadConstraint *constraintY() const { return mYConstraint.get(); }
270  bool commonAngleConstraint() const { return !qgsDoubleNear( mCommonAngleConstraint, 0.0 ); }
271 
276  QgsPointLocator::Match mapPointMatch() const { return mSnapMatch; }
277 
282  void clearPoints();
283 
288  void addPoint( const QgsPointXY &point );
289 
294  void removePreviousPoint();
295 
303  void setPoints( const QList<QgsPointXY> &points );
304 
310  QgsPointXY currentPoint( bool *exists = nullptr ) const;
311 
317  QgsPointXY previousPoint( bool *exists = nullptr ) const;
318 
324  QgsPointXY penultimatePoint( bool *exists = nullptr ) const;
325 
329  inline int pointsCount() const { return mCadPointList.count(); }
330 
334  inline bool snappedToVertex() const { return ( mSnapMatch.isValid() && ( mSnapMatch.hasVertex() || mSnapMatch.hasLineEndpoint() ) ); }
335 
339  QList<QgsPointXY> snappedSegment() const { return mSnappedSegment; }
340 
342  QAction *enableAction() { return mEnableAction; }
343 
350  void enable();
351 
355  void disable();
356 
361  void updateCadPaintItem();
362 
371  void setX( const QString &value, WidgetSetMode mode );
372 
381  void setY( const QString &value, WidgetSetMode mode );
382 
391  void setAngle( const QString &value, WidgetSetMode mode );
392 
401  void setDistance( const QString &value, WidgetSetMode mode );
402 
403 
404 
405  signals:
406 
412  void pushWarning( const QString &message );
413 
417  void popWarning();
418 
425  void pointChanged( const QgsPointXY &point );
426 
428 
436  void cadEnabledChanged( bool enabled );
437 
444  void valueXChanged( const QString &value );
445 
452  void valueYChanged( const QString &value );
453 
460  void valueAngleChanged( const QString &value );
461 
468  void valueDistanceChanged( const QString &value );
469 
476  void lockXChanged( bool locked );
477 
484  void lockYChanged( bool locked );
485 
492  void lockAngleChanged( bool locked );
493 
500  void lockDistanceChanged( bool locked );
501 
510  void relativeXChanged( bool relative );
511 
520  void relativeYChanged( bool relative );
521 
530  void relativeAngleChanged( bool relative );
531 
532  // relativeDistanceChanged doesn't exist as distance is always relative
533 
543  void enabledChangedX( bool enabled );
544 
554  void enabledChangedY( bool enabled );
555 
565  void enabledChangedAngle( bool enabled );
566 
576  void enabledChangedDistance( bool enabled );
577 
585 
593 
601 
609 
610 
611  private slots:
613  void additionalConstraintClicked( bool activated );
614 
616  void lockConstraint( bool activate = true );
617 
622  void constraintTextEdited( const QString &textValue );
623 
628  void constraintFocusOut();
629 
631  void setConstraintRelative( bool activate );
632 
634  void setConstraintRepeatingLock( bool activate );
635 
640  void activateCad( bool enabled );
641 
643  void setConstructionMode( bool enabled );
644 
646  void settingsButtonTriggered( QAction *action );
647 
648  private:
650  void setCadEnabled( bool enabled );
651 
656  void updateCapacity( bool updateUIwithoutChange = false );
657 
659  void lockAdditionalConstraint( AdditionalConstraint constraint );
660 
666  QList<QgsPointXY> snapSegmentToAllLayers( const QgsPointXY &originalMapPoint, bool *snapped = nullptr ) const;
667 
669  void updateCurrentPoint( const QgsPointXY &point );
670 
671 
676  bool filterKeyPress( QKeyEvent *e );
677 
682  bool eventFilter( QObject *obj, QEvent *event ) override SIP_SKIP;
683 
685  void triggerMouseMoveEvent();
686 
688  CadConstraint *objectToConstraint( const QObject *obj ) const;
689 
691  double parseUserInput( const QString &inputValue, bool &ok ) const;
692 
699  void updateConstraintValue( CadConstraint *constraint, const QString &textValue, bool convertExpression = false );
700 
702  void updateUnlockedConstraintValues( const QgsPointXY &point );
703 
704  QgsMapCanvas *mMapCanvas = nullptr;
705  QgsAdvancedDigitizingCanvasItem *mCadPaintItem = nullptr;
707  std::unique_ptr<QgsSnapIndicator> mSnapIndicator;
708 
709  CadCapacities mCapacities = CadCapacities();
710 
711  bool mCurrentMapToolSupportsCad = false;
712 
713  // Pointer to the floater
714  QgsAdvancedDigitizingFloater *mFloater = nullptr;
715 
716  // CAD properties
718  bool mCadEnabled = false;
719  bool mConstructionMode = false;
720 
721  // constraints
722  std::unique_ptr< CadConstraint > mAngleConstraint;
723  std::unique_ptr< CadConstraint > mDistanceConstraint;
724  std::unique_ptr< CadConstraint > mXConstraint;
725  std::unique_ptr< CadConstraint > mYConstraint;
726  AdditionalConstraint mAdditionalConstraint;
727  double mCommonAngleConstraint; // if 0: do not snap to common angles
728 
729  // point list and current snap point / segment
730  QList<QgsPointXY> mCadPointList;
731  QList<QgsPointXY> mSnappedSegment;
732 
733  bool mSessionActive = false;
734 
735  // error message
736  std::unique_ptr<QgsMessageBarItem> mErrorMessage;
737 
738  // UI
739  QMap< QAction *, double > mCommonAngleActions; // map the common angle actions with their angle values
740 
741  // Snap indicator
742 
743  QgsPointLocator::Match mSnapMatch;
744  private:
745 #ifdef SIP_RUN
747  bool eventFilter( QObject *obj, QEvent *event );
748 #endif
749 };
750 
751 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAdvancedDigitizingDockWidget::CadCapacities )
752 
753 #endif // QGSADVANCEDDIGITIZINGDOCK_H
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (.
The CadConstraint is an abstract class for all basic constraints (angle/distance/x/y).
CadConstraint(QLineEdit *lineEdit, QToolButton *lockerButton, QToolButton *relativeButton=nullptr, QToolButton *repeatingLockButton=nullptr)
Constructor for CadConstraint.
QLineEdit * lineEdit() const
The line edit that manages the value of the constraint.
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.
bool relative() const
Is the constraint in relative mode.
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.
const CadConstraint * constraintDistance() const
Returns the CadConstraint on the distance.
AdditionalConstraint
Additional constraints which can be enabled.
void enabledChangedY(bool enabled)
Emitted whenever the Y field is enabled or disabled.
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.
void lockXChanged(bool locked)
Emitted whenever the X 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).
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.
AdditionalConstraint additionalConstraint() const
Returns the additional constraints which are used to place perpendicular/parallel segments to snapped...
void lockAngleChanged(bool locked)
Emitted whenever the angle parameter is locked.
const CadConstraint * constraintX() const
Returns the CadConstraint on the X coordinate.
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.
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 cadEnabledChanged(bool enabled)
Signals for external widgets that need to update according to current values.
void pointChanged(const QgsPointXY &point)
Sometimes a constraint may change the current point out of a mouse event.
void lockYChanged(bool locked)
Emitted whenever the Y parameter is locked.
void valueAngleChanged(const QString &value)
Emitted whenever the angle value changes (either the mouse moved, or the user changed the input).
CadCapacity
The CadCapacity enum defines the possible constraints to be set depending on the number of points in ...
void enabledChangedAngle(bool enabled)
Emitted whenever the angle field is enabled or disabled.
const CadConstraint * constraintAngle() const
Returns the CadConstraint on the angle.
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.
QgsPointLocator::Match mapPointMatch() const
Returns the point locator match.
QAction * enableAction()
Returns the action used to enable/disable the tools.
const CadConstraint * constraintY() const
Returns the CadConstraint on the Y coordinate.
void focusOnDistanceRequested()
Emitted whenever the distance field should get the focus using the shortcuts (D).
void pushWarning(const QString &message)
Push a warning.
void relativeYChanged(bool relative)
Emitted whenever the Y parameter is toggled between absolute and relative.
QList< QgsPointXY > snappedSegment() const
Snapped to a segment.
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:86
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:66
A class to represent a 2D point.
Definition: qgspointxy.h:59
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:598
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_MONKEYPATCH_SCOPEENUM
Definition: qgis_sip.h:256
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.