QGIS API Documentation 3.99.0-Master (09f76ad7019)
Loading...
Searching...
No Matches
qgsadvanceddigitizingfloater.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsadvanceddigitizingfloater.cpp - floater for CAD tools
3 ----------------------
4 begin : May 2019
5 copyright : (C) Olivier Dalang
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
17
18#include "qgsapplication.h"
19#include "qgsfocuswatcher.h"
20#include "qgsmapcanvas.h"
21#include "qgssettings.h"
22#include "qgsunittypes.h"
23
24#include <QEnterEvent>
25#include <QLocale>
26#include <QMouseEvent>
27#include <QString>
28
29#include "moc_qgsadvanceddigitizingfloater.cpp"
30
31using namespace Qt::StringLiterals;
32
34 : QWidget( canvas->viewport() )
35 , mMapCanvas( canvas )
36 , mCadDockWidget( cadDockWidget )
37{
38 setupUi( this );
39
40 setAttribute( Qt::WA_TransparentForMouseEvents );
41 adjustSize();
42
43 setActive( QgsSettings().value( u"/Cad/Floater"_s, false ).toBool() );
44
45 hideIfDisabled();
46
47 enabledCommonAngleSnapping( cadDockWidget->commonAngleConstraint() );
48
49 // This is required to be able to track mouse move events
50 mMapCanvas->viewport()->installEventFilter( this );
51 mMapCanvas->viewport()->setMouseTracking( true );
52
53 // We reuse cadDockWidget's eventFilter for the CAD specific shortcuts
54 mAngleLineEdit->installEventFilter( cadDockWidget );
55 mDistanceLineEdit->installEventFilter( cadDockWidget );
56 mXLineEdit->installEventFilter( cadDockWidget );
57 mYLineEdit->installEventFilter( cadDockWidget );
58 mZLineEdit->installEventFilter( cadDockWidget );
59 mMLineEdit->installEventFilter( cadDockWidget );
60 mWeightLineEdit->installEventFilter( cadDockWidget );
61
62 // Connect all cadDockWidget's signals to update the widget's display
63 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::cadEnabledChanged, this, &QgsAdvancedDigitizingFloater::hideIfDisabled );
64
65 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueXChanged, this, &QgsAdvancedDigitizingFloater::changeX );
66 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueYChanged, this, &QgsAdvancedDigitizingFloater::changeY );
67 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueZChanged, this, &QgsAdvancedDigitizingFloater::changeZ );
68 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueMChanged, this, &QgsAdvancedDigitizingFloater::changeM );
69 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueAngleChanged, this, &QgsAdvancedDigitizingFloater::changeAngle );
70 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueBearingChanged, this, &QgsAdvancedDigitizingFloater::changeBearing );
71 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueAreaChanged, this, &QgsAdvancedDigitizingFloater::changeArea );
72 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueTotalLengthChanged, this, &QgsAdvancedDigitizingFloater::changeTotalLength );
73 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueCommonAngleSnappingChanged, this, &QgsAdvancedDigitizingFloater::changeCommonAngleSnapping );
74 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::commonAngleSnappingShowInFloaterChanged, this, &QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping );
75 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueDistanceChanged, this, &QgsAdvancedDigitizingFloater::changeDistance );
78
79 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockXChanged, this, &QgsAdvancedDigitizingFloater::changeLockX );
80 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockYChanged, this, &QgsAdvancedDigitizingFloater::changeLockY );
81 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockZChanged, this, &QgsAdvancedDigitizingFloater::changeLockZ );
82 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockMChanged, this, &QgsAdvancedDigitizingFloater::changeLockM );
83 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockAngleChanged, this, &QgsAdvancedDigitizingFloater::changeLockAngle );
84 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockDistanceChanged, this, &QgsAdvancedDigitizingFloater::changeLockDistance );
85
86 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeXChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeX );
87 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeYChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeY );
88 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeZChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeZ );
89 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeMChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeM );
90 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeAngleChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeAngle );
91 // distance is always relative
92
93 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnXRequested, this, &QgsAdvancedDigitizingFloater::focusOnX );
94 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnYRequested, this, &QgsAdvancedDigitizingFloater::focusOnY );
95 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnZRequested, this, &QgsAdvancedDigitizingFloater::focusOnZ );
96 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnMRequested, this, &QgsAdvancedDigitizingFloater::focusOnM );
97 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnAngleRequested, this, &QgsAdvancedDigitizingFloater::focusOnAngle );
98 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnDistanceRequested, this, &QgsAdvancedDigitizingFloater::focusOnDistance );
100
101 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedX, this, &QgsAdvancedDigitizingFloater::enabledChangedX );
102 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedY, this, &QgsAdvancedDigitizingFloater::enabledChangedY );
103 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedZ, this, &QgsAdvancedDigitizingFloater::enabledChangedZ );
104 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedM, this, &QgsAdvancedDigitizingFloater::enabledChangedM );
105 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledChangedAngle );
106 // Bearing capability is the same an angle, connect to the same signal:
107 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledChangedBearing );
108 // Common angle snapping capbility is also linked to angle, connect to the same signal:
109 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping );
110 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedDistance, this, &QgsAdvancedDigitizingFloater::enabledChangedDistance );
111
112 // Connect our line edits signals to update cadDockWidget's state (implementation copied from QgsAdvancedDigitizingDockWidget)
113 connect( mXLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
114 connect( mYLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
115 connect( mZLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
116 connect( mMLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
117 connect( mAngleLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() {
118 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed );
119 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
120 whileBlocking( mAngleLineEdit )->setText( cleanedInputValue );
121 } );
122 connect( mDistanceLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() {
123 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed );
124 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
125 whileBlocking( mDistanceLineEdit )->setText( cleanedInputValue );
126 } );
127
128 connect( mXLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
129 connect( mYLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
130 connect( mZLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
131 connect( mMLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
132 connect( mAngleLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
133 connect( mDistanceLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
134
135 QgsFocusWatcher *xWatcher = new QgsFocusWatcher( mXLineEdit );
136 connect( xWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
137 QgsFocusWatcher *yWatcher = new QgsFocusWatcher( mYLineEdit );
138 connect( yWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
139 QgsFocusWatcher *zWatcher = new QgsFocusWatcher( mZLineEdit );
140 connect( zWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
141 QgsFocusWatcher *mWatcher = new QgsFocusWatcher( mYLineEdit );
142 connect( mWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
143 QgsFocusWatcher *angleWatcher = new QgsFocusWatcher( mAngleLineEdit );
144 connect( angleWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
145 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
146 whileBlocking( mAngleLineEdit )->setText( mCadDockWidget->constraintAngle()->displayValue() );
147 } );
148 connect( angleWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
149 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
150 whileBlocking( mAngleLineEdit )->setText( cleanedInputValue );
151 } );
152 QgsFocusWatcher *distanceWatcher = new QgsFocusWatcher( mDistanceLineEdit );
153 connect( distanceWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
154 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
155 whileBlocking( mDistanceLineEdit )->setText( mCadDockWidget->constraintDistance()->displayValue() );
156 } );
157 connect( distanceWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
158 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
159 whileBlocking( mDistanceLineEdit )->setText( cleanedInputValue );
160 } );
161 changeCommonAngleSnapping( mCadDockWidget->commonAngleConstraint() );
162}
163
164bool QgsAdvancedDigitizingFloater::eventFilter( QObject *obj, QEvent *event )
165{
166 if ( mCadDockWidget && mCadDockWidget->cadEnabled() && mActive )
167 {
168 if ( event->type() == QEvent::MouseMove )
169 {
170 // We update the position when mouse moves
171 QMouseEvent *mouseEvent = qgis::down_cast<QMouseEvent *>( event );
172 updatePos( mouseEvent->pos() );
173 }
174 else if ( event->type() == QEvent::Enter )
175 {
176 // We show the widget when mouse enters
177 QEnterEvent *enterEvent = qgis::down_cast<QEnterEvent *>( event );
178 updatePos( enterEvent->pos() );
179 setVisible( true );
180 }
181 else if ( event->type() == QEvent::Leave )
182 {
183 // We hide the widget when mouse leaves
184 setVisible( false );
185 }
186 }
187 return QWidget::eventFilter( obj, event );
188}
189
191{
192 return mActive;
193}
194
196{
197 return mItemsVisibility.testFlag( item );
198}
199
201{
202 if ( !itemSupportsMeasurementType( item ) )
203 {
205 }
206
207 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
208 return QgsSettings().enumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), Qgis::CadMeasurementDisplayType::Hidden );
209}
210
212{
213 QgsSettings().setValue( u"/Cad/Floater"_s, active );
214
215 mActive = active;
216
217 hideIfDisabled();
218}
219
221{
222 if ( itemSupportsMeasurementType( item ) )
223 {
224 // use setItemMeasurementType instead
225 return;
226 }
227
228 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
229 QgsSettings().setValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), visible );
230 mItemsVisibility.setFlag( item, visible );
231 switch ( item )
232 {
234 enabledChangedX( visible );
235 break;
237 enabledChangedY( visible );
238 break;
240 enabledChangedM( visible );
241 break;
243 enabledChangedZ( visible );
244 break;
246 enabledChangedAngle( visible );
247 break;
249 enabledChangedDistance( visible );
250 break;
252 enabledCommonAngleSnapping( visible );
253 break;
255 enabledChangedBearing( visible );
256 break;
258 enabledChangedWeight( visible );
259 break;
262 break;
263 }
264}
265
267{
268 if ( !itemSupportsMeasurementType( item ) )
269 {
270 // use setItemVisibility instead
271 return;
272 }
273
274 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
275 QgsSettings().setEnumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), type );
276 switch ( type )
277 {
279 mItemsVisibility.setFlag( item, false );
280 break;
281
284 mItemsVisibility.setFlag( item, true );
285 break;
286 }
287
288 QPixmap pixmap;
289 const QColor iconColor = palette().color( QPalette::ColorRole::WindowText );
290 switch ( type )
291 {
293 break;
294
296 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterCartesian.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
297 break;
299 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterEllipsoid.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
300 break;
301 }
302
303 switch ( item )
304 {
314 break;
315
317 {
318 const bool show = itemVisibility( FloaterItem::Area );
319 mTotalAreaLineEdit->setVisible( show );
320 mAreaLabel->setVisible( show );
321 mAreaMeasurementTypeLabel->setVisible( show );
322 mAreaMeasurementTypeLabel->setPixmap( pixmap );
323 adjustSize();
324 break;
325 }
327 const bool show = itemVisibility( FloaterItem::TotalLength );
328 mTotalLengthLineEdit->setVisible( show );
329 mTotalLengthLabel->setVisible( show );
330 mLengthMeasurementTypeLabel->setVisible( show );
331 mLengthMeasurementTypeLabel->setPixmap( pixmap );
332 adjustSize();
333 break;
334 }
335}
336
358
359void QgsAdvancedDigitizingFloater::updatePos( const QPoint &pos )
360{
361 // We hardcode a small delta between the mouse position and the widget's position
362 move( pos + QPoint( 15, 5 ) );
363}
364
365void QgsAdvancedDigitizingFloater::hideIfDisabled()
366{
367 if ( !mCadDockWidget || !mCadDockWidget->cadEnabled() || !mActive )
368 {
369 setVisible( false );
370 }
371}
372
373void QgsAdvancedDigitizingFloater::changeX( const QString &text )
374{
375 mXLineEdit->setText( text );
376}
377
378void QgsAdvancedDigitizingFloater::changeY( const QString &text )
379{
380 mYLineEdit->setText( text );
381}
382
383void QgsAdvancedDigitizingFloater::changeZ( const QString &text )
384{
385 mZLineEdit->setText( text );
386}
387
388void QgsAdvancedDigitizingFloater::changeM( const QString &text )
389{
390 mMLineEdit->setText( text );
391}
392
393void QgsAdvancedDigitizingFloater::changeCommonAngleSnapping( double angle )
394{
395 mCommonAngleSnappingLineEdit->setText( qgsDoubleNear( angle, 0.0 ) ? tr( "disabled" ) : QLocale().toString( angle ).append( tr( " °" ) ) );
396}
397
398void QgsAdvancedDigitizingFloater::changeDistance( const QString &text )
399{
400 mDistanceLineEdit->setText( text );
401}
402
403void QgsAdvancedDigitizingFloater::changeAngle( const QString &text )
404{
405 mAngleLineEdit->setText( text );
406}
407
408void QgsAdvancedDigitizingFloater::changeBearing( const QString &text )
409{
410 mBearingLineEdit->setText( text );
411}
412
413void QgsAdvancedDigitizingFloater::changeArea( const QString &text )
414{
415 mTotalAreaLineEdit->setText( text );
416}
417
418void QgsAdvancedDigitizingFloater::changeTotalLength( const QString &text )
419{
420 mTotalLengthLineEdit->setText( text );
421}
422
423void QgsAdvancedDigitizingFloater::changeLockX( bool locked )
424{
425 if ( !locked )
426 {
427 mXLineEdit->setStyleSheet( QString() );
428 mXLabel->setStyleSheet( QString() );
429 }
430 else
431 {
432 mXLineEdit->setStyleSheet( u"font-weight: bold"_s );
433 mXLabel->setStyleSheet( u"font-weight: bold"_s );
434 }
435}
436
437void QgsAdvancedDigitizingFloater::changeLockY( bool locked )
438{
439 if ( !locked )
440 {
441 mYLineEdit->setStyleSheet( QString() );
442 mYLabel->setStyleSheet( QString() );
443 }
444 else
445 {
446 mYLineEdit->setStyleSheet( u"font-weight: bold"_s );
447 mYLabel->setStyleSheet( u"font-weight: bold"_s );
448 }
449}
450
451void QgsAdvancedDigitizingFloater::changeLockZ( bool locked )
452{
453 if ( !locked )
454 {
455 mZLineEdit->setStyleSheet( QString() );
456 mZLabel->setStyleSheet( QString() );
457 }
458 else
459 {
460 mZLineEdit->setStyleSheet( u"font-weight: bold"_s );
461 mZLabel->setStyleSheet( u"font-weight: bold"_s );
462 }
463}
464
465void QgsAdvancedDigitizingFloater::changeLockM( bool locked )
466{
467 if ( !locked )
468 {
469 mMLineEdit->setStyleSheet( QString() );
470 mMLabel->setStyleSheet( QString() );
471 }
472 else
473 {
474 mMLineEdit->setStyleSheet( u"font-weight: bold"_s );
475 mMLabel->setStyleSheet( u"font-weight: bold"_s );
476 }
477}
478
479void QgsAdvancedDigitizingFloater::changeLockDistance( bool locked )
480{
481 if ( !locked )
482 {
483 mDistanceLineEdit->setStyleSheet( QString() );
484 mDistanceLabel->setStyleSheet( QString() );
485 }
486 else
487 {
488 mDistanceLineEdit->setStyleSheet( u"font-weight: bold"_s );
489 mDistanceLabel->setStyleSheet( u"font-weight: bold"_s );
490 }
491}
492
493void QgsAdvancedDigitizingFloater::changeLockAngle( bool locked )
494{
495 if ( !locked )
496 {
497 mAngleLineEdit->setStyleSheet( QString() );
498 mAngleLabel->setStyleSheet( QString() );
499 }
500 else
501 {
502 mAngleLineEdit->setStyleSheet( u"font-weight: bold"_s );
503 mAngleLabel->setStyleSheet( u"font-weight: bold"_s );
504 }
505}
506
507
508void QgsAdvancedDigitizingFloater::changeRelativeX( bool relative )
509{
510 if ( !relative )
511 {
512 mXLabel->setText( "x" );
513 }
514 else
515 {
516 mXLabel->setText( "Δx" );
517 }
518 adjustSize();
519}
520
521void QgsAdvancedDigitizingFloater::changeRelativeY( bool relative )
522{
523 if ( !relative )
524 {
525 mYLabel->setText( "y" );
526 }
527 else
528 {
529 mYLabel->setText( "Δy" );
530 }
531 adjustSize();
532}
533
534void QgsAdvancedDigitizingFloater::changeRelativeZ( bool relative )
535{
536 if ( !relative )
537 {
538 mZLabel->setText( "z" );
539 }
540 else
541 {
542 mZLabel->setText( "Δz" );
543 }
544 adjustSize();
545}
546
547void QgsAdvancedDigitizingFloater::changeRelativeM( bool relative )
548{
549 if ( !relative )
550 {
551 mMLabel->setText( "m" );
552 }
553 else
554 {
555 mMLabel->setText( "Δm" );
556 }
557 adjustSize();
558}
559
560// distance is always relative
561
562void QgsAdvancedDigitizingFloater::changeRelativeAngle( bool relative )
563{
564 if ( !relative )
565 {
566 mAngleLabel->setText( "a" );
567 }
568 else
569 {
570 mAngleLabel->setText( "Δa" );
571 }
572 adjustSize();
573}
574
575void QgsAdvancedDigitizingFloater::focusOnX()
576{
577 if ( mActive )
578 {
579 mXLineEdit->setFocus();
580 mXLineEdit->selectAll();
581 }
582}
583
584void QgsAdvancedDigitizingFloater::focusOnY()
585{
586 if ( mActive )
587 {
588 mYLineEdit->setFocus();
589 mYLineEdit->selectAll();
590 }
591}
592
593void QgsAdvancedDigitizingFloater::focusOnZ()
594{
595 if ( mActive )
596 {
597 mZLineEdit->setFocus();
598 mZLineEdit->selectAll();
599 }
600}
601
602void QgsAdvancedDigitizingFloater::focusOnM()
603{
604 if ( mActive )
605 {
606 mMLineEdit->setFocus();
607 mMLineEdit->selectAll();
608 }
609}
610
611void QgsAdvancedDigitizingFloater::focusOnDistance()
612{
613 if ( mActive )
614 {
615 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
616 mDistanceLineEdit->setText( cleanedInputValue );
617 mDistanceLineEdit->setFocus();
618 mDistanceLineEdit->selectAll();
619 }
620}
621
622void QgsAdvancedDigitizingFloater::focusOnAngle()
623{
624 if ( mActive )
625 {
626 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
627 mAngleLineEdit->setText( cleanedInputValue );
628 mAngleLineEdit->setFocus();
629 mAngleLineEdit->selectAll();
630 }
631}
632
634{
635 if ( mActive )
636 {
637 mWeightLineEdit->setFocus();
638 mWeightLineEdit->selectAll();
639 }
640}
641
642
643void QgsAdvancedDigitizingFloater::enabledChangedX( bool enabled )
644{
645 mXLineEdit->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
646 mXLabel->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
647 adjustSize();
648}
649
650void QgsAdvancedDigitizingFloater::enabledChangedY( bool enabled )
651{
652 mYLineEdit->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
653 mYLabel->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
654 adjustSize();
655}
656
657void QgsAdvancedDigitizingFloater::enabledChangedZ( bool enabled )
658{
659 mZLineEdit->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
660 mZLabel->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
661 adjustSize();
662}
663
664void QgsAdvancedDigitizingFloater::enabledChangedM( bool enabled )
665{
666 mMLineEdit->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
667 mMLabel->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
668 adjustSize();
669}
670
671void QgsAdvancedDigitizingFloater::enabledChangedDistance( bool enabled )
672{
673 mDistanceLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
674 mDistanceLabel->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
675 adjustSize();
676}
677
678void QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping( bool enabled )
679{
680 mCommonAngleSnappingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
681 mCommonAngleSnappingLabel->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
682 adjustSize();
683}
684
685void QgsAdvancedDigitizingFloater::enabledChangedAngle( bool enabled )
686{
687 mAngleLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
688 mAngleLabel->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
689 adjustSize();
690}
691
692void QgsAdvancedDigitizingFloater::enabledChangedBearing( bool enabled )
693{
694 mBearingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
695 mBearingLabel->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
696 adjustSize();
697}
698
700{
701 mWeightLineEdit->setText( text );
702}
703
705{
706 // Always show weight when enabled, regardless of user preference
707 // This is because weight editing is a temporary mode (activated with W key)
708 mWeightLineEdit->setVisible( enabled );
709 mWeightLabel->setVisible( enabled );
710 adjustSize();
711}
@ Distance
Distance value.
Definition qgis.h:4148
@ Angle
Angle value.
Definition qgis.h:4147
CadMeasurementDisplayType
Advanced digitizing measurement display types.
Definition qgis.h:4161
@ Hidden
Hide measurement.
Definition qgis.h:4162
@ Cartesian
Use Cartesian measurements.
Definition qgis.h:4163
@ Ellipsoidal
Use Ellipsoidal measurements.
Definition qgis.h:4164
static QString removeSuffix(const QString &text, Qgis::CadConstraintType constraintType)
Removes unit suffix from the constraint text.
A dockable widget used to handle the CAD tools on top of a selection of map tools.
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.
void lockZChanged(bool locked)
Emitted whenever the Z parameter is locked.
void setZ(const QString &value, WidgetSetMode mode)
Set the Z value on the widget.
void setY(const QString &value, WidgetSetMode mode)
Set the Y value on the widget.
void enabledChangedY(bool enabled)
Emitted whenever the Y field is enabled or disabled.
void valueWeightChanged(const QString &value)
Emitted whenever the weight value changes for NURBS curves.
void enabledChangedWeight(bool enabled)
Emitted whenever the weight field is enabled or disabled for NURBS curves.
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 focusOnXRequested()
Emitted whenever the X field should get the focus using the shortcuts (X).
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 valueTotalLengthChanged(const QString &value)
Emitted whenever the total length (or perimeter) value changes.
void focusOnWeightRequested()
Emitted whenever the weight field should get the focus using the shortcuts (W).
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.
void valueZChanged(const QString &value)
Emitted whenever the Z value changes (either the mouse moved, or the user changed the input).
void lockAngleChanged(bool locked)
Emitted whenever the angle parameter is locked.
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).
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 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.
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).
void relativeZChanged(bool relative)
Emitted whenever the Z parameter is toggled between absolute and relative.
void setAngle(const QString &value, WidgetSetMode mode)
Set the angle value on the widget.
void enabledChangedAngle(bool enabled)
Emitted whenever the angle field is enabled or disabled.
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.
void valueBearingChanged(const QString &value)
Emitted whenever the bearing value changes.
void enabledChangedM(bool enabled)
Emitted whenever the M field is enabled or disabled.
void setDistance(const QString &value, WidgetSetMode mode)
Set the distance value on the widget.
void setX(const QString &value, WidgetSetMode mode)
Set the X value on the widget.
void focusOnDistanceRequested()
Emitted whenever the distance field should get the focus using the shortcuts (D).
void valueAreaChanged(const QString &value)
Emitted whenever the total summed area value changes.
void valueCommonAngleSnappingChanged(double angle)
Emitted whenever the snapping to common angle option changes, angle = 0 means that the functionality ...
void setM(const QString &value, WidgetSetMode mode)
Set the M value on the widget.
void relativeYChanged(bool relative)
Emitted whenever the Y parameter is toggled between absolute and relative.
bool itemVisibility(QgsAdvancedDigitizingFloater::FloaterItem item) const
Returns true if the floater item visibility setting is enabled.
void setItemVisibility(QgsAdvancedDigitizingFloater::FloaterItem item, bool visible)
Set whether the floater item should be visible or not.
QgsAdvancedDigitizingFloater(QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget)
Create an advanced digitizing floater widget.
void setActive(bool active)
Set whether the floater should be active or not.
void setItemMeasurementType(QgsAdvancedDigitizingFloater::FloaterItem item, Qgis::CadMeasurementDisplayType type)
Set whether the measurement display type for a floater item.
void enabledChangedWeight(bool enabled)
Shows or hides the weight widget in the floater for NURBSCurve.
void focusOnWeight()
Requests focus on the weight input field for NURBSCurve.
void changeWeight(const QString &text)
Updates the weight value displayed in the floater for NURBSCurve.
static bool itemSupportsMeasurementType(QgsAdvancedDigitizingFloater::FloaterItem item)
Returns true if a floater item supports display in different Qgis::CadMeasurementDisplayType values.
bool active()
Whether the floater is active or not.
Qgis::CadMeasurementDisplayType itemMeasurementDisplayType(QgsAdvancedDigitizingFloater::FloaterItem item) const
Returns the measurement display type for a floater item.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
An event filter for watching for focus events on a parent object.
void focusIn()
Emitted when parent object gains focus.
void focusOut()
Emitted when parent object loses focus.
Map canvas is a class for displaying all GIS data types on a canvas.
Stores settings for use within QGIS.
Definition qgssettings.h:68
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
#define BUILTIN_UNREACHABLE
Definition qgis.h:7524
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6935
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6839