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 );
697 updateCurrentPoint( point );
699 updateUnlockedConstraintValues( point );
707 emit
pushWarning( tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
714 void QgsAdvancedDigitizingDockWidget::updateUnlockedConstraintValues(
const QgsPointXY &point )
716 bool previousPointExist, penulPointExist;
721 if ( !mAngleConstraint->isLocked() && previousPointExist )
724 if ( penulPointExist && mAngleConstraint->relative() )
727 angle = std::atan2( previousPt.
y() - penultimatePt.
y(),
728 previousPt.
x() - penultimatePt.
x() );
730 angle = ( std::atan2( point.
y() - previousPt.
y(),
731 point.
x() - previousPt.
x()
732 ) - angle ) * 180 / M_PI;
734 angle = std::fmod( angle, 360.0 );
735 mAngleConstraint->setValue( angle );
738 if ( !mDistanceConstraint->isLocked() && previousPointExist )
740 mDistanceConstraint->setValue( std::sqrt( previousPt.
sqrDist( point ) ) );
743 if ( !mXConstraint->isLocked() )
745 if ( previousPointExist && mXConstraint->relative() )
747 mXConstraint->setValue( point.
x() - previousPt.
x() );
751 mXConstraint->setValue( point.
x() );
755 if ( !mYConstraint->isLocked() )
757 if ( previousPointExist && mYConstraint->relative() )
759 mYConstraint->setValue( point.
y() - previousPt.
y() );
763 mYConstraint->setValue( point.
y() );
769 QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers(
const QgsPointXY &originalMapPoint,
bool *snapped )
const 771 QList<QgsPointXY> segment;
784 match = snappingUtils->
snapToMap( originalMapPoint );
786 snappingUtils->
setConfig( canvasConfig );
791 segment << pt1 << pt2;
796 *snapped = segment.count() == 2;
809 bool previousPointExist, penulPointExist, snappedSegmentExist;
812 mSnappedSegment = snapSegmentToAllLayers( e->
originalMapPoint(), &snappedSegmentExist );
814 if ( !previousPointExist || !snappedSegmentExist )
819 double angle = std::atan2( mSnappedSegment[0].y() - mSnappedSegment[1].y(), mSnappedSegment[0].x() - mSnappedSegment[1].x() );
821 if ( mAngleConstraint->relative() && penulPointExist )
823 angle -= std::atan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
833 mAngleConstraint->setValue( angle );
834 mAngleConstraint->setLockMode( lockMode );
852 case Qt::Key_Backspace:
889 case Qt::Key_Backspace:
912 const auto constPoints = points;
919 bool QgsAdvancedDigitizingDockWidget::eventFilter( QObject *obj, QEvent *event )
923 return QgsDockWidget::eventFilter( obj, event );
931 if ( event->type() == QEvent::ShortcutOverride ||
event->type() == QEvent::KeyPress )
933 if ( QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>( event ) )
935 return filterKeyPress( keyEvent );
938 return QgsDockWidget::eventFilter( obj, event );
941 bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
947 QEvent::Type type = e->type();
953 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
955 mXConstraint->toggleLocked();
960 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
964 mXConstraint->toggleRelative();
971 else if ( type == QEvent::KeyPress )
973 mXLineEdit->setFocus();
974 mXLineEdit->selectAll();
983 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
985 mYConstraint->toggleLocked();
990 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
994 mYConstraint->toggleRelative();
1001 else if ( type == QEvent::KeyPress )
1003 mYLineEdit->setFocus();
1004 mYLineEdit->selectAll();
1013 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
1017 mAngleConstraint->toggleLocked();
1023 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
1027 mAngleConstraint->toggleRelative();
1034 else if ( type == QEvent::KeyPress )
1036 mAngleLineEdit->setFocus();
1037 mAngleLineEdit->selectAll();
1046 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
1050 mDistanceConstraint->toggleLocked();
1057 else if ( type == QEvent::KeyPress )
1059 mDistanceLineEdit->setFocus();
1060 mDistanceLineEdit->selectAll();
1068 if ( type == QEvent::KeyPress )
1070 setConstructionMode( !mConstructionMode );
1077 if ( type == QEvent::KeyPress )
1079 bool parallel = mParallelAction->isChecked();
1080 bool perpendicular = mPerpendicularAction->isChecked();
1082 if ( !parallel && !perpendicular )
1086 else if ( perpendicular )
1103 return e->isAccepted();
1111 mErrorLabel->setText( tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
1112 mErrorLabel->show();
1113 mEnableAction->setEnabled(
false );
1114 setCadEnabled(
false );
1118 mEnableAction->setEnabled(
true );
1119 mErrorLabel->hide();
1122 mCurrentMapToolSupportsCad =
true;
1124 if ( mSessionActive && !isVisible() )
1128 setCadEnabled( mSessionActive );
1136 mEnableAction->setEnabled(
false );
1137 mErrorLabel->setText( tr(
"CAD tools are not enabled for the current map tool" ) );
1138 mErrorLabel->show();
1141 mCurrentMapToolSupportsCad =
false;
1143 setCadEnabled(
false );
1148 mCadPaintItem->update();
1155 mCadPointList << point;
1159 mCadPointList.insert( 0, point );
1172 mCadPointList.removeAt( i );
1179 mCadPointList.clear();
1180 mSnappedSegment.clear();
1186 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPointXY &point )
1190 mCadPointList << point;
1195 mCadPointList[0] = point;
1204 mLockerButton->setChecked( mode == HardLock );
1205 if ( mRepeatingLockButton )
1207 if ( mode == HardLock )
1209 mRepeatingLockButton->setEnabled(
true );
1213 mRepeatingLockButton->setChecked(
false );
1214 mRepeatingLockButton->setEnabled(
false );
1218 if ( mode == NoLock )
1227 mRepeatingLock = repeating;
1228 if ( mRepeatingLockButton )
1229 mRepeatingLockButton->setChecked( repeating );
1234 mRelative = relative;
1235 if ( mRelativeButton )
1237 mRelativeButton->setChecked( relative );
1245 mLineEdit->setText( QLocale().toString( value,
'f', 6 ) );
1250 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1255 setRelative( !mRelative );
1263 return mCadPointList.value( 0 );
1273 return mCadPointList.value( 1 );
1283 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.
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.
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.
QgsPointLocator::Match snapToMap(QPoint point, QgsPointLocator::MatchFilter *filter=nullptr)
Snap to map according to the current configuration. Optional filter allows discarding unwanted matche...
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.