QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 : denis.rouzaud@gmail.com
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() ); }
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 
584  void focusOnXRequested();
585 
592  void focusOnYRequested();
593 
600  void focusOnAngleRequested();
601 
608  void focusOnDistanceRequested();
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 = nullptr;
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
746  bool eventFilter( QObject *obj, QEvent *event );
748 #endif
749 };
750 
751 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAdvancedDigitizingDockWidget::CadCapacities )
752 
753 #endif // QGSADVANCEDDIGITIZINGDOCK_H
int pointsCount() const
The number of points in the CAD point helper list.
bool constructionMode() const
construction mode is used to draw intermediate points. These points won&#39;t be given any further (i...
bool cadEnabled() const
determines if CAD tools are enabled or if map tools behaves "nomally"
The CadConstraint is an abstract class for all basic constraints (angle/distance/x/y).
const CadConstraint * constraintY() const
Returns the CadConstraint on the Y coordinate.
QgsPointLocator::Match mapPointMatch() const
Returns the point locator match.
CadCapacity
The CadCapacity enum defines the possible constraints to be set depending on the number of points in ...
QAction * enableAction()
Returns the action used to enable/disable the tools.
const CadConstraint * constraintAngle() const
Returns the CadConstraint on the angle.
A class to represent a 2D point.
Definition: qgspointxy.h:43
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:265
CadConstraint(QLineEdit *lineEdit, QToolButton *lockerButton, QToolButton *relativeButton=nullptr, QToolButton *repeatingLockButton=nullptr)
Constructor for CadConstraint.
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
#define SIP_MONKEYPATCH_SCOPEENUM
Definition: qgis_sip.h:244
The QgsMapToolAdvancedDigitizing class is a QgsMapTool which gives event directly in map coordinates ...
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:73
LockMode lockMode() const
The current lock mode of this constraint.
QList< QgsPointXY > snappedSegment() const
Snapped to a segment.
double value() const
The value of the constraint.
#define SIP_SKIP
Definition: qgis_sip.h:119
QgsDockWidget subclass with more fine-grained control over how the widget is closed or opened...
Definition: qgsdockwidget.h:31
bool isLocked() const
Is any kind of lock mode enabled.
const CadConstraint * constraintX() const
Returns the CadConstraint on the X coordinate.
AdditionalConstraint additionalConstraint() const
Returns the additional constraints which are used to place perpendicular/parallel segments to snapped...
Abstract base class for all map tools.
Definition: qgsmaptool.h:62
The QgsAdvancedDigitizingFloater class is widget that floats next to the mouse pointer, and allow interaction with the AdvancedDigitizing feature.
const CadConstraint * constraintDistance() const
Returns the CadConstraint on the distance.
bool relative() const
Is the constraint in relative mode.
QLineEdit * lineEdit() const
The line edit that manages the value of the constraint.
AdditionalConstraint
Additional constraints which can be enabled.
bool commonAngleConstraint() const
Returns true if a constraint on a common angle is active.
bool isRepeatingLock() const
Returns true if a repeating lock is set for the constraint.
bool snappedToVertex() const
Is it snapped to a vertex.
WidgetSetMode
Type of interaction to simulate when editing values from external widget.
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (...