QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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]() {
133 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited );
134 } );
135 connect( mDistanceLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() {
136 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited );
137 } );
138
139 QgsFocusWatcher *xWatcher = new QgsFocusWatcher( mXLineEdit );
140 connect( xWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
141 QgsFocusWatcher *yWatcher = new QgsFocusWatcher( mYLineEdit );
142 connect( yWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
143 QgsFocusWatcher *zWatcher = new QgsFocusWatcher( mZLineEdit );
144 connect( zWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
145 QgsFocusWatcher *mWatcher = new QgsFocusWatcher( mYLineEdit );
146 connect( mWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
147 QgsFocusWatcher *angleWatcher = new QgsFocusWatcher( mAngleLineEdit );
148 connect( angleWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
149 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
150 whileBlocking( mAngleLineEdit )->setText( mCadDockWidget->constraintAngle()->displayValue() );
151 } );
152 connect( angleWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
153 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
154 whileBlocking( mAngleLineEdit )->setText( cleanedInputValue );
155 } );
156 QgsFocusWatcher *distanceWatcher = new QgsFocusWatcher( mDistanceLineEdit );
157 connect( distanceWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
158 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
159 whileBlocking( mDistanceLineEdit )->setText( mCadDockWidget->constraintDistance()->displayValue() );
160 } );
161 connect( distanceWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
162 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
163 whileBlocking( mDistanceLineEdit )->setText( cleanedInputValue );
164 } );
165 changeCommonAngleSnapping( mCadDockWidget->commonAngleConstraint() );
166}
167
168bool QgsAdvancedDigitizingFloater::eventFilter( QObject *obj, QEvent *event )
169{
170 if ( mCadDockWidget && mCadDockWidget->cadEnabled() && mActive )
171 {
172 if ( event->type() == QEvent::MouseMove )
173 {
174 // We update the position when mouse moves
175 QMouseEvent *mouseEvent = qgis::down_cast<QMouseEvent *>( event );
176 updatePos( mouseEvent->pos() );
177 }
178 else if ( event->type() == QEvent::Enter )
179 {
180 // We show the widget when mouse enters
181 QEnterEvent *enterEvent = qgis::down_cast<QEnterEvent *>( event );
182 updatePos( enterEvent->pos() );
183 setVisible( true );
184 }
185 else if ( event->type() == QEvent::Leave )
186 {
187 // We hide the widget when mouse leaves
188 setVisible( false );
189 }
190 }
191 return QWidget::eventFilter( obj, event );
192}
193
195{
196 return mActive;
197}
198
200{
201 return mItemsVisibility.testFlag( item );
202}
203
205{
206 if ( !itemSupportsMeasurementType( item ) )
207 {
209 }
210
211 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
212 return QgsSettings().enumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), Qgis::CadMeasurementDisplayType::Hidden );
213}
214
216{
217 QgsSettings().setValue( u"/Cad/Floater"_s, active );
218
219 mActive = active;
220
221 hideIfDisabled();
222}
223
225{
226 if ( itemSupportsMeasurementType( item ) )
227 {
228 // use setItemMeasurementType instead
229 return;
230 }
231
232 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
233 QgsSettings().setValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), visible );
234 mItemsVisibility.setFlag( item, visible );
235 switch ( item )
236 {
238 enabledChangedX( visible );
239 break;
241 enabledChangedY( visible );
242 break;
244 enabledChangedM( visible );
245 break;
247 enabledChangedZ( visible );
248 break;
250 enabledChangedAngle( visible );
251 break;
253 enabledChangedDistance( visible );
254 break;
256 enabledCommonAngleSnapping( visible );
257 break;
259 enabledChangedBearing( visible );
260 break;
262 enabledChangedWeight( visible );
263 break;
266 break;
267 }
268}
269
271{
272 if ( !itemSupportsMeasurementType( item ) )
273 {
274 // use setItemVisibility instead
275 return;
276 }
277
278 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
279 QgsSettings().setEnumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), type );
280 switch ( type )
281 {
283 mItemsVisibility.setFlag( item, false );
284 break;
285
288 mItemsVisibility.setFlag( item, true );
289 break;
290 }
291
292 QPixmap pixmap;
293 const QColor iconColor = palette().color( QPalette::ColorRole::WindowText );
294 switch ( type )
295 {
297 break;
298
300 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterCartesian.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
301 break;
303 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterEllipsoid.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
304 break;
305 }
306
307 switch ( item )
308 {
318 break;
319
321 {
322 const bool show = itemVisibility( FloaterItem::Area );
323 mTotalAreaLineEdit->setVisible( show );
324 mAreaLabel->setVisible( show );
325 mAreaMeasurementTypeLabel->setVisible( show );
326 mAreaMeasurementTypeLabel->setPixmap( pixmap );
327 adjustSize();
328 break;
329 }
331 const bool show = itemVisibility( FloaterItem::TotalLength );
332 mTotalLengthLineEdit->setVisible( show );
333 mTotalLengthLabel->setVisible( show );
334 mLengthMeasurementTypeLabel->setVisible( show );
335 mLengthMeasurementTypeLabel->setPixmap( pixmap );
336 adjustSize();
337 break;
338 }
339}
340
362
363void QgsAdvancedDigitizingFloater::updatePos( const QPoint &pos )
364{
365 // We hardcode a small delta between the mouse position and the widget's position
366 move( pos + QPoint( 15, 5 ) );
367}
368
369void QgsAdvancedDigitizingFloater::hideIfDisabled()
370{
371 if ( !mCadDockWidget || !mCadDockWidget->cadEnabled() || !mActive )
372 {
373 setVisible( false );
374 }
375}
376
377void QgsAdvancedDigitizingFloater::changeX( const QString &text )
378{
379 mXLineEdit->setText( text );
380}
381
382void QgsAdvancedDigitizingFloater::changeY( const QString &text )
383{
384 mYLineEdit->setText( text );
385}
386
387void QgsAdvancedDigitizingFloater::changeZ( const QString &text )
388{
389 mZLineEdit->setText( text );
390}
391
392void QgsAdvancedDigitizingFloater::changeM( const QString &text )
393{
394 mMLineEdit->setText( text );
395}
396
397void QgsAdvancedDigitizingFloater::changeCommonAngleSnapping( double angle )
398{
399 mCommonAngleSnappingLineEdit->setText( qgsDoubleNear( angle, 0.0 ) ? tr( "disabled" ) : QLocale().toString( angle ).append( tr( " °" ) ) );
400}
401
402void QgsAdvancedDigitizingFloater::changeDistance( const QString &text )
403{
404 mDistanceLineEdit->setText( text );
405}
406
407void QgsAdvancedDigitizingFloater::changeAngle( const QString &text )
408{
409 mAngleLineEdit->setText( text );
410}
411
412void QgsAdvancedDigitizingFloater::changeBearing( const QString &text )
413{
414 mBearingLineEdit->setText( text );
415}
416
417void QgsAdvancedDigitizingFloater::changeArea( const QString &text )
418{
419 mTotalAreaLineEdit->setText( text );
420}
421
422void QgsAdvancedDigitizingFloater::changeTotalLength( const QString &text )
423{
424 mTotalLengthLineEdit->setText( text );
425}
426
427void QgsAdvancedDigitizingFloater::changeLockX( bool locked )
428{
429 if ( !locked )
430 {
431 mXLineEdit->setStyleSheet( QString() );
432 mXLabel->setStyleSheet( QString() );
433 }
434 else
435 {
436 mXLineEdit->setStyleSheet( u"font-weight: bold"_s );
437 mXLabel->setStyleSheet( u"font-weight: bold"_s );
438 }
439}
440
441void QgsAdvancedDigitizingFloater::changeLockY( bool locked )
442{
443 if ( !locked )
444 {
445 mYLineEdit->setStyleSheet( QString() );
446 mYLabel->setStyleSheet( QString() );
447 }
448 else
449 {
450 mYLineEdit->setStyleSheet( u"font-weight: bold"_s );
451 mYLabel->setStyleSheet( u"font-weight: bold"_s );
452 }
453}
454
455void QgsAdvancedDigitizingFloater::changeLockZ( bool locked )
456{
457 if ( !locked )
458 {
459 mZLineEdit->setStyleSheet( QString() );
460 mZLabel->setStyleSheet( QString() );
461 }
462 else
463 {
464 mZLineEdit->setStyleSheet( u"font-weight: bold"_s );
465 mZLabel->setStyleSheet( u"font-weight: bold"_s );
466 }
467}
468
469void QgsAdvancedDigitizingFloater::changeLockM( bool locked )
470{
471 if ( !locked )
472 {
473 mMLineEdit->setStyleSheet( QString() );
474 mMLabel->setStyleSheet( QString() );
475 }
476 else
477 {
478 mMLineEdit->setStyleSheet( u"font-weight: bold"_s );
479 mMLabel->setStyleSheet( u"font-weight: bold"_s );
480 }
481}
482
483void QgsAdvancedDigitizingFloater::changeLockDistance( bool locked )
484{
485 if ( !locked )
486 {
487 mDistanceLineEdit->setStyleSheet( QString() );
488 mDistanceLabel->setStyleSheet( QString() );
489 }
490 else
491 {
492 mDistanceLineEdit->setStyleSheet( u"font-weight: bold"_s );
493 mDistanceLabel->setStyleSheet( u"font-weight: bold"_s );
494 }
495}
496
497void QgsAdvancedDigitizingFloater::changeLockAngle( bool locked )
498{
499 if ( !locked )
500 {
501 mAngleLineEdit->setStyleSheet( QString() );
502 mAngleLabel->setStyleSheet( QString() );
503 }
504 else
505 {
506 mAngleLineEdit->setStyleSheet( u"font-weight: bold"_s );
507 mAngleLabel->setStyleSheet( u"font-weight: bold"_s );
508 }
509}
510
511
512void QgsAdvancedDigitizingFloater::changeRelativeX( bool relative )
513{
514 if ( !relative )
515 {
516 mXLabel->setText( "x" );
517 }
518 else
519 {
520 mXLabel->setText( "Δx" );
521 }
522 adjustSize();
523}
524
525void QgsAdvancedDigitizingFloater::changeRelativeY( bool relative )
526{
527 if ( !relative )
528 {
529 mYLabel->setText( "y" );
530 }
531 else
532 {
533 mYLabel->setText( "Δy" );
534 }
535 adjustSize();
536}
537
538void QgsAdvancedDigitizingFloater::changeRelativeZ( bool relative )
539{
540 if ( !relative )
541 {
542 mZLabel->setText( "z" );
543 }
544 else
545 {
546 mZLabel->setText( "Δz" );
547 }
548 adjustSize();
549}
550
551void QgsAdvancedDigitizingFloater::changeRelativeM( bool relative )
552{
553 if ( !relative )
554 {
555 mMLabel->setText( "m" );
556 }
557 else
558 {
559 mMLabel->setText( "Δm" );
560 }
561 adjustSize();
562}
563
564// distance is always relative
565
566void QgsAdvancedDigitizingFloater::changeRelativeAngle( bool relative )
567{
568 if ( !relative )
569 {
570 mAngleLabel->setText( "a" );
571 }
572 else
573 {
574 mAngleLabel->setText( "Δa" );
575 }
576 adjustSize();
577}
578
579void QgsAdvancedDigitizingFloater::focusOnX()
580{
581 if ( mActive )
582 {
583 mXLineEdit->setFocus();
584 mXLineEdit->selectAll();
585 }
586}
587
588void QgsAdvancedDigitizingFloater::focusOnY()
589{
590 if ( mActive )
591 {
592 mYLineEdit->setFocus();
593 mYLineEdit->selectAll();
594 }
595}
596
597void QgsAdvancedDigitizingFloater::focusOnZ()
598{
599 if ( mActive )
600 {
601 mZLineEdit->setFocus();
602 mZLineEdit->selectAll();
603 }
604}
605
606void QgsAdvancedDigitizingFloater::focusOnM()
607{
608 if ( mActive )
609 {
610 mMLineEdit->setFocus();
611 mMLineEdit->selectAll();
612 }
613}
614
615void QgsAdvancedDigitizingFloater::focusOnDistance()
616{
617 if ( mActive )
618 {
619 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
620 mDistanceLineEdit->setText( cleanedInputValue );
621 mDistanceLineEdit->setFocus();
622 mDistanceLineEdit->selectAll();
623 }
624}
625
626void QgsAdvancedDigitizingFloater::focusOnAngle()
627{
628 if ( mActive )
629 {
630 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
631 mAngleLineEdit->setText( cleanedInputValue );
632 mAngleLineEdit->setFocus();
633 mAngleLineEdit->selectAll();
634 }
635}
636
638{
639 if ( mActive )
640 {
641 mWeightLineEdit->setFocus();
642 mWeightLineEdit->selectAll();
643 }
644}
645
646
647void QgsAdvancedDigitizingFloater::enabledChangedX( bool enabled )
648{
649 mXLineEdit->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
650 mXLabel->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
651 adjustSize();
652}
653
654void QgsAdvancedDigitizingFloater::enabledChangedY( bool enabled )
655{
656 mYLineEdit->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
657 mYLabel->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
658 adjustSize();
659}
660
661void QgsAdvancedDigitizingFloater::enabledChangedZ( bool enabled )
662{
663 mZLineEdit->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
664 mZLabel->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
665 adjustSize();
666}
667
668void QgsAdvancedDigitizingFloater::enabledChangedM( bool enabled )
669{
670 mMLineEdit->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
671 mMLabel->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
672 adjustSize();
673}
674
675void QgsAdvancedDigitizingFloater::enabledChangedDistance( bool enabled )
676{
677 mDistanceLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
678 mDistanceLabel->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
679 adjustSize();
680}
681
682void QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping( bool enabled )
683{
684 mCommonAngleSnappingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
685 mCommonAngleSnappingLabel->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
686 adjustSize();
687}
688
689void QgsAdvancedDigitizingFloater::enabledChangedAngle( bool enabled )
690{
691 mAngleLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
692 mAngleLabel->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
693 adjustSize();
694}
695
696void QgsAdvancedDigitizingFloater::enabledChangedBearing( bool enabled )
697{
698 mBearingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
699 mBearingLabel->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
700 adjustSize();
701}
702
704{
705 mWeightLineEdit->setText( text );
706}
707
709{
710 // Always show weight when enabled, regardless of user preference
711 // This is because weight editing is a temporary mode (activated with W key)
712 mWeightLineEdit->setVisible( enabled );
713 mWeightLabel->setVisible( enabled );
714 adjustSize();
715}
@ Distance
Distance value.
Definition qgis.h:4194
@ Angle
Angle value.
Definition qgis.h:4193
CadMeasurementDisplayType
Advanced digitizing measurement display types.
Definition qgis.h:4207
@ Hidden
Hide measurement.
Definition qgis.h:4208
@ Cartesian
Use Cartesian measurements.
Definition qgis.h:4209
@ Ellipsoidal
Use Ellipsoidal measurements.
Definition qgis.h:4210
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:7540
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6975
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6880