18 #include <QCoreApplication> 44 , mMapCanvas( canvas )
46 , mCommonAngleConstraint(
QgsSettings().value( QStringLiteral(
"/Cad/CommonAngle" ), 90 ).toDouble() )
52 mAngleConstraint.reset(
new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton, mRepeatingLockAngleButton ) );
53 mDistanceConstraint.reset(
new CadConstraint( mDistanceLineEdit, mLockDistanceButton,
nullptr, mRepeatingLockDistanceButton ) );
54 mXConstraint.reset(
new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton ) );
55 mYConstraint.reset(
new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) );
58 mMapCanvas->installEventFilter(
this );
59 mAngleLineEdit->installEventFilter(
this );
60 mDistanceLineEdit->installEventFilter(
this );
61 mXLineEdit->installEventFilter(
this );
62 mYLineEdit->installEventFilter(
this );
65 connect( mEnableAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::activateCad );
66 connect( mConstructionModeAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::setConstructionMode );
67 connect( mParallelAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
68 connect( mPerpendicularAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
69 connect( mLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
70 connect( mLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
71 connect( mLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
72 connect( mLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
73 connect( mRelativeAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
74 connect( mRelativeXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
75 connect( mRelativeYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
76 connect( mRepeatingLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
77 connect( mRepeatingLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
78 connect( mRepeatingLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
79 connect( mRepeatingLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
80 connect( mAngleLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
81 connect( mDistanceLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
82 connect( mXLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
83 connect( mYLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
84 connect( mAngleLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
85 connect( mDistanceLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
86 connect( mXLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
87 connect( mYLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
99 QMenu *menu =
new QMenu(
this );
101 QActionGroup *angleButtonGroup =
new QActionGroup( menu );
102 mCommonAngleActions = QMap<QAction *, double>();
103 QList< QPair< double, QString > > commonAngles;
105 QList<double> anglesDouble( { 0.0, 5.0, 10.0, 15.0, 18.0, 22.5, 30.0, 45.0, 90.0} );
106 for ( QList<double>::const_iterator it = anglesDouble.constBegin(); it != anglesDouble.constEnd(); ++it )
109 menuText = tr(
"Do Not Snap to Common Angles" );
111 menuText = QString( tr(
"%1, %2, %3, %4°…" ) ).arg( *it, 0,
'f', 1 ).arg( *it * 2, 0,
'f', 1 ).arg( *it * 3, 0,
'f', 1 ).arg( *it * 4, 0,
'f', 1 );
112 commonAngles << QPair<double, QString>( *it, menuText );
114 for ( QList< QPair<double, QString > >::const_iterator it = commonAngles.constBegin(); it != commonAngles.constEnd(); ++it )
116 QAction *action =
new QAction( it->second, menu );
117 action->setCheckable(
true );
118 action->setChecked( it->first == mCommonAngleConstraint );
119 menu->addAction( action );
120 angleButtonGroup->addAction( action );
121 mCommonAngleActions.insert( action, it->first );
124 qobject_cast< QToolButton *>( mToolbar->widgetForAction( mSettingsAction ) )->setPopupMode( QToolButton::InstantPopup );
125 mSettingsAction->setMenu( menu );
126 connect( menu, &QMenu::triggered,
this, &QgsAdvancedDigitizingDockWidget::settingsButtonTriggered );
129 mConstructionModeAction->setToolTip(
"<b>" + tr(
"Construction mode" ) +
"</b><br>(" + tr(
"press c to toggle on/off" ) +
")" );
130 mDistanceLineEdit->setToolTip(
"<b>" + tr(
"Distance" ) +
"</b><br>(" + tr(
"press d for quick access" ) +
")" );
131 mLockDistanceButton->setToolTip(
"<b>" + tr(
"Lock distance" ) +
"</b><br>(" + tr(
"press Ctrl + d for quick access" ) +
")" );
132 mRepeatingLockDistanceButton->setToolTip(
"<b>" + tr(
"Continuously lock distance" ) +
"</b>" );
134 mRelativeAngleButton->setToolTip(
"<b>" + tr(
"Toggles relative angle to previous segment" ) +
"</b><br>(" + tr(
"press Shift + a for quick access" ) +
")" );
135 mAngleLineEdit->setToolTip(
"<b>" + tr(
"Angle" ) +
"</b><br>(" + tr(
"press a for quick access" ) +
")" );
136 mLockAngleButton->setToolTip(
"<b>" + tr(
"Lock angle" ) +
"</b><br>(" + tr(
"press Ctrl + a for quick access" ) +
")" );
137 mRepeatingLockAngleButton->setToolTip(
"<b>" + tr(
"Continuously lock angle" ) +
"</b>" );
139 mRelativeXButton->setToolTip(
"<b>" + tr(
"Toggles relative x to previous node" ) +
"</b><br>(" + tr(
"press Shift + x for quick access" ) +
")" );
140 mXLineEdit->setToolTip(
"<b>" + tr(
"X coordinate" ) +
"</b><br>(" + tr(
"press x for quick access" ) +
")" );
141 mLockXButton->setToolTip(
"<b>" + tr(
"Lock x coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + x for quick access" ) +
")" );
142 mRepeatingLockXButton->setToolTip(
"<b>" + tr(
"Continuously lock x coordinate" ) +
"</b>" );
144 mRelativeYButton->setToolTip(
"<b>" + tr(
"Toggles relative y to previous node" ) +
"</b><br>(" + tr(
"press Shift + y for quick access" ) +
")" );
145 mYLineEdit->setToolTip(
"<b>" + tr(
"Y coordinate" ) +
"</b><br>(" + tr(
"press y for quick access" ) +
")" );
146 mLockYButton->setToolTip(
"<b>" + tr(
"Lock y coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + y for quick access" ) +
")" );
147 mRepeatingLockYButton->setToolTip(
"<b>" + tr(
"Continuously lock y coordinate" ) +
"</b>" );
158 mToggleFloaterAction->setChecked( mFloater->
active() );
160 updateCapacity(
true );
168 mXLineEdit->setText( value );
169 if ( mode == WidgetSetMode::ReturnPressed )
171 mXLineEdit->returnPressed();
173 else if ( mode == WidgetSetMode::FocusOut )
175 QEvent *e =
new QEvent( QEvent::FocusOut );
176 QCoreApplication::postEvent( mXLineEdit, e );
178 else if ( mode == WidgetSetMode::TextEdited )
180 mXLineEdit->textEdited( value );
185 mYLineEdit->setText( value );
186 if ( mode == WidgetSetMode::ReturnPressed )
188 mYLineEdit->returnPressed();
190 else if ( mode == WidgetSetMode::FocusOut )
192 QEvent *e =
new QEvent( QEvent::FocusOut );
193 QCoreApplication::postEvent( mYLineEdit, e );
195 else if ( mode == WidgetSetMode::TextEdited )
197 mYLineEdit->textEdited( value );
202 mAngleLineEdit->setText( value );
203 if ( mode == WidgetSetMode::ReturnPressed )
205 mAngleLineEdit->returnPressed();
207 else if ( mode == WidgetSetMode::FocusOut )
209 QEvent *e =
new QEvent( QEvent::FocusOut );
210 QCoreApplication::postEvent( mAngleLineEdit, e );
212 else if ( mode == WidgetSetMode::TextEdited )
214 mAngleLineEdit->textEdited( value );
219 mDistanceLineEdit->setText( value );
220 if ( mode == WidgetSetMode::ReturnPressed )
222 mDistanceLineEdit->returnPressed();
224 else if ( mode == WidgetSetMode::FocusOut )
226 QEvent *e =
new QEvent( QEvent::FocusOut );
227 QCoreApplication::postEvent( mDistanceLineEdit, e );
229 else if ( mode == WidgetSetMode::TextEdited )
231 mDistanceLineEdit->textEdited( value );
236 void QgsAdvancedDigitizingDockWidget::setCadEnabled(
bool enabled )
238 mCadEnabled = enabled;
239 mEnableAction->setChecked( enabled );
240 mConstructionModeAction->setEnabled( enabled );
241 mParallelAction->setEnabled( enabled );
242 mPerpendicularAction->setEnabled( enabled );
243 mSettingsAction->setEnabled( enabled );
244 mInputWidgets->setEnabled( enabled );
245 mToggleFloaterAction->setEnabled( enabled );
248 setConstructionMode(
false );
253 void QgsAdvancedDigitizingDockWidget::activateCad(
bool enabled )
255 enabled &= mCurrentMapToolSupportsCad;
257 mSessionActive = enabled;
259 if ( enabled && !isVisible() )
264 setCadEnabled( enabled );
267 void QgsAdvancedDigitizingDockWidget::additionalConstraintClicked(
bool activated )
273 if ( sender() == mParallelAction )
277 else if ( sender() == mPerpendicularAction )
283 void QgsAdvancedDigitizingDockWidget::setConstraintRelative(
bool activate )
285 if ( sender() == mRelativeAngleButton )
287 mAngleConstraint->setRelative( activate );
290 else if ( sender() == mRelativeXButton )
292 mXConstraint->setRelative( activate );
295 else if ( sender() == mRelativeYButton )
297 mYConstraint->setRelative( activate );
302 void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock(
bool activate )
304 if ( sender() == mRepeatingLockDistanceButton )
306 mDistanceConstraint->setRepeatingLock( activate );
308 else if ( sender() == mRepeatingLockAngleButton )
310 mAngleConstraint->setRepeatingLock( activate );
312 else if ( sender() == mRepeatingLockXButton )
314 mXConstraint->setRepeatingLock( activate );
316 else if ( sender() == mRepeatingLockYButton )
318 mYConstraint->setRepeatingLock( activate );
322 void QgsAdvancedDigitizingDockWidget::setConstructionMode(
bool enabled )
324 mConstructionMode = enabled;
325 mConstructionModeAction->setChecked( enabled );
328 void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction *action )
331 QMap<QAction *, double>::const_iterator ica = mCommonAngleActions.constFind( action );
332 if ( ica != mCommonAngleActions.constEnd() )
334 ica.key()->setChecked(
true );
335 mCommonAngleConstraint = ica.value();
347 if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
352 if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
357 if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
362 if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
370 void QgsAdvancedDigitizingDockWidget::emit
pointChanged()
373 QPoint globalPos = mMapCanvas->cursor().pos();
374 QPoint pos = mMapCanvas->mapFromGlobal( globalPos );
375 QMouseEvent *e =
new QMouseEvent( QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier );
376 mCurrentMapTool->canvasMoveEvent( e );
383 if ( obj == mAngleLineEdit || obj == mLockAngleButton )
385 constraint = mAngleConstraint.get();
387 else if ( obj == mDistanceLineEdit || obj == mLockDistanceButton )
389 constraint = mDistanceConstraint.get();
391 else if ( obj == mXLineEdit || obj == mLockXButton )
393 constraint = mXConstraint.get();
395 else if ( obj == mYLineEdit || obj == mLockYButton )
397 constraint = mYConstraint.get();
402 double QgsAdvancedDigitizingDockWidget::parseUserInput(
const QString &inputValue,
bool &ok )
const 418 value = result.toDouble( &ok );
423 void QgsAdvancedDigitizingDockWidget::updateConstraintValue(
CadConstraint *constraint,
const QString &textValue,
bool convertExpression )
425 if ( !constraint || textValue.isEmpty() )
434 double value = parseUserInput( textValue, ok );
438 constraint->
setValue( value, convertExpression );
443 void QgsAdvancedDigitizingDockWidget::lockConstraint(
bool activate )
453 QString textValue = constraint->
lineEdit()->text();
454 if ( !textValue.isEmpty() )
457 double value = parseUserInput( textValue, ok );
474 if ( constraint == mXConstraint.get() )
478 else if ( constraint == mYConstraint.get() )
482 else if ( constraint == mDistanceConstraint.get() )
486 else if ( constraint == mAngleConstraint.get() )
494 if ( constraint == mAngleConstraint.get() )
504 void QgsAdvancedDigitizingDockWidget::constraintTextEdited(
const QString &textValue )
512 updateConstraintValue( constraint, textValue,
false );
515 void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
517 QLineEdit *lineEdit = qobject_cast< QLineEdit * >( sender()->parent() );
527 updateConstraintValue( constraint, lineEdit->text(), true );
530 void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint(
AdditionalConstraint constraint )
532 mAdditionalConstraint = constraint;
537 void QgsAdvancedDigitizingDockWidget::updateCapacity(
bool updateUIwithoutChange )
539 CadCapacities newCapacities =
nullptr;
541 if ( mCadPointList.count() > 1 )
545 if ( mCadPointList.count() > 2 )
549 if ( !updateUIwithoutChange && newCapacities == mCapacities )
559 bool relativeAngle = mCadEnabled && newCapacities.testFlag(
RelativeAngle );
560 bool absoluteAngle = mCadEnabled && newCapacities.testFlag(
AbsoluteAngle );
563 mPerpendicularAction->setEnabled( absoluteAngle && snappingEnabled );
564 mParallelAction->setEnabled( absoluteAngle && snappingEnabled );
567 if ( !snappingEnabled )
569 mPerpendicularAction->setToolTip( tr(
"Snapping must be enabled to utilize perpendicular mode" ) );
570 mParallelAction->setToolTip( tr(
"Snapping must be enabled to utilize parallel mode" ) );
574 mPerpendicularAction->setToolTip(
"<b>" + tr(
"Perpendicular" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
575 mParallelAction->setToolTip(
"<b>" + tr(
"Parallel" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
579 if ( !absoluteAngle )
585 mLockAngleButton->setEnabled( absoluteAngle );
586 mRelativeAngleButton->setEnabled( relativeAngle );
587 mAngleLineEdit->setEnabled( absoluteAngle );
589 if ( !absoluteAngle )
593 if ( !relativeAngle )
595 mAngleConstraint->setRelative(
false );
598 else if ( relativeAngle && !mCapacities.testFlag(
RelativeAngle ) )
601 mAngleConstraint->setRelative(
true );
606 mLockDistanceButton->setEnabled( relativeCoordinates );
607 mDistanceLineEdit->setEnabled( relativeCoordinates );
609 if ( !relativeCoordinates )
614 mRelativeXButton->setEnabled( relativeCoordinates );
615 mRelativeYButton->setEnabled( relativeCoordinates );
618 mCapacities = newCapacities;
636 context.
xConstraint = _constraint( mXConstraint.get() );
637 context.
yConstraint = _constraint( mYConstraint.get() );
648 bool res = output.
valid;
650 mSnappedSegment.clear();
655 mSnappedSegment << edgePt0 << edgePt1;
677 mSnapIndicator->setMatch( mSnapMatch );
678 mSnapIndicator->setVisible(
true );
682 mSnapIndicator->setVisible(
false );
698 updateCurrentPoint( point );
700 updateUnlockedConstraintValues( point );
708 emit
pushWarning( tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
715 void QgsAdvancedDigitizingDockWidget::updateUnlockedConstraintValues(
const QgsPointXY &point )
717 bool previousPointExist, penulPointExist;
722 if ( !mAngleConstraint->isLocked() && previousPointExist )
725 if ( penulPointExist && mAngleConstraint->relative() )
728 angle = std::atan2( previousPt.
y() - penultimatePt.
y(),
729 previousPt.
x() - penultimatePt.
x() );
731 angle = ( std::atan2( point.
y() - previousPt.
y(),
732 point.
x() - previousPt.
x()
733 ) - angle ) * 180 / M_PI;
735 angle = std::fmod( angle, 360.0 );
736 mAngleConstraint->setValue( angle );
739 if ( !mDistanceConstraint->isLocked() && previousPointExist )
741 mDistanceConstraint->setValue( std::sqrt( previousPt.
sqrDist( point ) ) );
744 if ( !mXConstraint->isLocked() )
746 if ( previousPointExist && mXConstraint->relative() )
748 mXConstraint->setValue( point.
x() - previousPt.
x() );
752 mXConstraint->setValue( point.
x() );
756 if ( !mYConstraint->isLocked() )
758 if ( previousPointExist && mYConstraint->relative() )
760 mYConstraint->setValue( point.
y() - previousPt.
y() );
764 mYConstraint->setValue( point.
y() );
770 QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers(
const QgsPointXY &originalMapPoint,
bool *snapped )
const 772 QList<QgsPointXY> segment;
785 match = snappingUtils->
snapToMap( originalMapPoint,
nullptr,
true );
787 snappingUtils->
setConfig( canvasConfig );
792 segment << pt1 << pt2;
797 *snapped = segment.count() == 2;
810 bool previousPointExist, penulPointExist, snappedSegmentExist;
813 mSnappedSegment = snapSegmentToAllLayers( e->
originalMapPoint(), &snappedSegmentExist );
815 if ( !previousPointExist || !snappedSegmentExist )
820 double angle = std::atan2( mSnappedSegment[0].y() - mSnappedSegment[1].y(), mSnappedSegment[0].x() - mSnappedSegment[1].x() );
822 if ( mAngleConstraint->relative() && penulPointExist )
824 angle -= std::atan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
834 mAngleConstraint->setValue( angle );
835 mAngleConstraint->setLockMode( lockMode );
853 case Qt::Key_Backspace:
890 case Qt::Key_Backspace:
913 const auto constPoints = points;
920 bool QgsAdvancedDigitizingDockWidget::eventFilter( QObject *obj, QEvent *event )
924 return QgsDockWidget::eventFilter( obj, event );
932 if ( event->type() == QEvent::ShortcutOverride ||
event->type() == QEvent::KeyPress )
934 if ( QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>( event ) )
936 return filterKeyPress( keyEvent );
939 return QgsDockWidget::eventFilter( obj, event );
942 bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
948 QEvent::Type type = e->type();
954 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
956 mXConstraint->toggleLocked();
961 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
965 mXConstraint->toggleRelative();
972 else if ( type == QEvent::KeyPress )
974 mXLineEdit->setFocus();
975 mXLineEdit->selectAll();
984 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
986 mYConstraint->toggleLocked();
991 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
995 mYConstraint->toggleRelative();
1002 else if ( type == QEvent::KeyPress )
1004 mYLineEdit->setFocus();
1005 mYLineEdit->selectAll();
1014 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
1018 mAngleConstraint->toggleLocked();
1024 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
1028 mAngleConstraint->toggleRelative();
1035 else if ( type == QEvent::KeyPress )
1037 mAngleLineEdit->setFocus();
1038 mAngleLineEdit->selectAll();
1047 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
1051 mDistanceConstraint->toggleLocked();
1058 else if ( type == QEvent::KeyPress )
1060 mDistanceLineEdit->setFocus();
1061 mDistanceLineEdit->selectAll();
1069 if ( type == QEvent::KeyPress )
1071 setConstructionMode( !mConstructionMode );
1078 if ( type == QEvent::KeyPress )
1080 bool parallel = mParallelAction->isChecked();
1081 bool perpendicular = mPerpendicularAction->isChecked();
1083 if ( !parallel && !perpendicular )
1087 else if ( perpendicular )
1104 return e->isAccepted();
1112 mErrorLabel->setText( tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
1113 mErrorLabel->show();
1114 mEnableAction->setEnabled(
false );
1115 setCadEnabled(
false );
1119 mEnableAction->setEnabled(
true );
1120 mErrorLabel->hide();
1123 mCurrentMapToolSupportsCad =
true;
1125 if ( mSessionActive && !isVisible() )
1129 setCadEnabled( mSessionActive );
1137 mEnableAction->setEnabled(
false );
1138 mErrorLabel->setText( tr(
"CAD tools are not enabled for the current map tool" ) );
1139 mErrorLabel->show();
1142 mCurrentMapToolSupportsCad =
false;
1144 setCadEnabled(
false );
1149 mCadPaintItem->update();
1156 mCadPointList << point;
1160 mCadPointList.insert( 0, point );
1173 mCadPointList.removeAt( i );
1180 mCadPointList.clear();
1181 mSnappedSegment.clear();
1187 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPointXY &point )
1191 mCadPointList << point;
1196 mCadPointList[0] = point;
1205 mLockerButton->setChecked( mode == HardLock );
1206 if ( mRepeatingLockButton )
1208 if ( mode == HardLock )
1210 mRepeatingLockButton->setEnabled(
true );
1214 mRepeatingLockButton->setChecked(
false );
1215 mRepeatingLockButton->setEnabled(
false );
1219 if ( mode == NoLock )
1228 mRepeatingLock = repeating;
1229 if ( mRepeatingLockButton )
1230 mRepeatingLockButton->setChecked( repeating );
1235 mRelative = relative;
1236 if ( mRelativeButton )
1238 mRelativeButton->setChecked( relative );
1246 mLineEdit->setText( QLocale().toString( value,
'f', 6 ) );
1251 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1256 setRelative( !mRelative );
1264 return mCadPointList.value( 0 );
1274 return mCadPointList.value( 1 );
1284 return mCadPointList.value( 2 );
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsCadUtils::AlignMapPointConstraint yConstraint
Constraint for Y coordinate.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
void focusOut()
Emitted when parent object loses focus.
A event filter for watching for focus events on a parent object.
This class is a composition of two QSettings instances:
bool enabled() const
Returns if snapping is enabled.
Structure with details of one constraint.
A class to represent a 2D point.
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
QVariant evaluate()
Evaluate the feature and return the result.
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
void setMapPoint(const QgsPointXY &point)
Set the (snapped) point this event points to in map coordinates.
Map canvas is a class for displaying all GIS data types on a canvas.
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)
bool active()
Whether the floater is active or not.
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
QgsPointLocator::Match edgeMatch
Snapped segment - only valid if actually used for something.
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
bool locked
Whether the constraint is active, i.e. should be considered.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
QgsCadUtils::AlignMapPointConstraint distanceConstraint
Constraint for distance.
QgsPointLocator::Match snapToMap(QPoint point, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Snap to map according to the current configuration.
Structure defining all constraints for alignMapPoint() method.
void edgePoints(QgsPointXY &pt1, QgsPointXY &pt2) const
Only for a valid edge match - obtain endpoints of the edge.
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint
Constraint for soft lock to a common angle.
void destinationCrsChanged()
Emitted when map CRS has changed.
QgsPointXY finalMapPoint
map point aligned according to the constraints
double value
Numeric value of the constraint (coordinate/distance in map units or angle in degrees) ...
double softLockCommonAngle
Angle (in degrees) to which we have soft-locked ourselves (if not set it is -1)
Structure returned from alignMapPoint() method.
double mapUnitsPerPixel
Map units/pixel ratio from map canvas. Needed for.
bool topologicalEditing() const
Convenience function to query topological editing status.
void setMode(SnappingMode mode)
define the mode of snapping
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsPointXY originalMapPoint() const
Returns the original, unmodified map point of the mouse cursor.
The QgsAdvancedDigitizingFloater class is widget that floats next to the mouse pointer, and allow interaction with the AdvancedDigitizing feature.
void setActive(bool active)
Set whether the floater should be active or not.
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords...
QgsCadUtils::AlignMapPointConstraint xConstraint
Constraint for X coordinate.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QgsCadUtils::AlignMapPointConstraint angleConstraint
Constraint for angle.
bool valid
Whether the combination of constraints is actually valid.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setType(SnappingType type)
define the type of snapping
This class has all the configuration of snapping and can return answers to snapping queries...
Class that shows snapping marker on map canvas for the current snapping match.
QgsSnappingUtils * snappingUtils
Snapping utils that will be used to snap point to map. Must not be nullptr.
This is a container for configuration of the snapping of the project.
static QgsCadUtils::AlignMapPointOutput alignMapPoint(const QgsPointXY &originalMapPoint, const QgsCadUtils::AlignMapPointContext &ctx)
Applies X/Y/angle/distance constraints from the given context to a map point.
QgsSnappingUtils * snappingUtils() const
Returns snapping utility class that is associated with map canvas.
QgsPointXY snapPoint()
snapPoint will snap the points using the map canvas snapping utils configuration
bool relative
Whether the value is relative to previous value.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QgsSnappingConfig snappingConfig
void setConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration controls the behavior of this object.
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (...
QList< QgsPointXY > cadPointList
List of recent CAD points in map coordinates.