QGIS API Documentation 4.3.0-Master (bf28115e945)
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
6 email : olivier.dalang@gmail.com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsapplication.h"
19#include "qgsfocuswatcher.h"
20#include "qgsmapcanvas.h"
21#include "qgssettings.h"
23#include "qgsunittypes.h"
24
25#include <QEnterEvent>
26#include <QLocale>
27#include <QMouseEvent>
28#include <QString>
29
30#include "moc_qgsadvanceddigitizingfloater.cpp"
31
32using namespace Qt::StringLiterals;
33
35 : QWidget( canvas->viewport() )
36 , mMapCanvas( canvas )
37 , mCadDockWidget( cadDockWidget )
38{
39 setupUi( this );
40
41 setAttribute( Qt::WA_TransparentForMouseEvents );
42 adjustSize();
43
45
46 hideIfDisabled();
47
48 enabledCommonAngleSnapping( cadDockWidget->commonAngleConstraint() );
49
50 // This is required to be able to track mouse move events
51 mMapCanvas->viewport()->installEventFilter( this );
52 mMapCanvas->viewport()->setMouseTracking( true );
53
54 // We reuse cadDockWidget's eventFilter for the CAD specific shortcuts
55 mAngleLineEdit->installEventFilter( cadDockWidget );
56 mDistanceLineEdit->installEventFilter( cadDockWidget );
57 mXLineEdit->installEventFilter( cadDockWidget );
58 mYLineEdit->installEventFilter( cadDockWidget );
59 mZLineEdit->installEventFilter( cadDockWidget );
60 mMLineEdit->installEventFilter( cadDockWidget );
61 mWeightLineEdit->installEventFilter( cadDockWidget );
62
63 // Connect all cadDockWidget's signals to update the widget's display
64 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::cadEnabledChanged, this, &QgsAdvancedDigitizingFloater::hideIfDisabled );
65
66 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueXChanged, this, &QgsAdvancedDigitizingFloater::changeX );
67 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueYChanged, this, &QgsAdvancedDigitizingFloater::changeY );
68 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueZChanged, this, &QgsAdvancedDigitizingFloater::changeZ );
69 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueMChanged, this, &QgsAdvancedDigitizingFloater::changeM );
70 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueAngleChanged, this, &QgsAdvancedDigitizingFloater::changeAngle );
71 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueBearingChanged, this, &QgsAdvancedDigitizingFloater::changeBearing );
72 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueAreaChanged, this, &QgsAdvancedDigitizingFloater::changeArea );
73 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueTotalLengthChanged, this, &QgsAdvancedDigitizingFloater::changeTotalLength );
74 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueCommonAngleSnappingChanged, this, &QgsAdvancedDigitizingFloater::changeCommonAngleSnapping );
75 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::commonAngleSnappingShowInFloaterChanged, this, &QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping );
76 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueDistanceChanged, this, &QgsAdvancedDigitizingFloater::changeDistance );
79
80 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockXChanged, this, &QgsAdvancedDigitizingFloater::changeLockX );
81 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockYChanged, this, &QgsAdvancedDigitizingFloater::changeLockY );
82 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockZChanged, this, &QgsAdvancedDigitizingFloater::changeLockZ );
83 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockMChanged, this, &QgsAdvancedDigitizingFloater::changeLockM );
84 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockAngleChanged, this, &QgsAdvancedDigitizingFloater::changeLockAngle );
85 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockDistanceChanged, this, &QgsAdvancedDigitizingFloater::changeLockDistance );
86
87 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeXChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeX );
88 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeYChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeY );
89 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeZChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeZ );
90 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeMChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeM );
91 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::relativeAngleChanged, this, &QgsAdvancedDigitizingFloater::changeRelativeAngle );
92 // distance is always relative
93
94 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnXRequested, this, &QgsAdvancedDigitizingFloater::focusOnX );
95 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnYRequested, this, &QgsAdvancedDigitizingFloater::focusOnY );
96 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnZRequested, this, &QgsAdvancedDigitizingFloater::focusOnZ );
97 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnMRequested, this, &QgsAdvancedDigitizingFloater::focusOnM );
98 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnAngleRequested, this, &QgsAdvancedDigitizingFloater::focusOnAngle );
99 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::focusOnDistanceRequested, this, &QgsAdvancedDigitizingFloater::focusOnDistance );
101
102 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedX, this, &QgsAdvancedDigitizingFloater::enabledChangedX );
103 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedY, this, &QgsAdvancedDigitizingFloater::enabledChangedY );
104 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedZ, this, &QgsAdvancedDigitizingFloater::enabledChangedZ );
105 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedM, this, &QgsAdvancedDigitizingFloater::enabledChangedM );
106 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledChangedAngle );
107 // Bearing capability is the same an angle, connect to the same signal:
108 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledChangedBearing );
109 // Common angle snapping capbility is also linked to angle, connect to the same signal:
110 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedAngle, this, &QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping );
111 connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::enabledChangedDistance, this, &QgsAdvancedDigitizingFloater::enabledChangedDistance );
112
113 // Connect our line edits signals to update cadDockWidget's state (implementation copied from QgsAdvancedDigitizingDockWidget)
114 connect( mXLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
115 connect( mYLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
116 connect( mZLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
117 connect( mMLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed ); } );
118 connect( mAngleLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() {
119 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed );
120 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
121 whileBlocking( mAngleLineEdit )->setText( cleanedInputValue );
122 } );
123 connect( mDistanceLineEdit, &QLineEdit::returnPressed, cadDockWidget, [this, cadDockWidget]() {
124 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::ReturnPressed );
125 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
126 whileBlocking( mDistanceLineEdit )->setText( cleanedInputValue );
127 } );
128
129 connect( mXLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
130 connect( mYLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
131 connect( mZLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
132 connect( mMLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited ); } );
133 connect( mAngleLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() {
134 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited );
135 } );
136 connect( mDistanceLineEdit, &QLineEdit::textEdited, cadDockWidget, [this, cadDockWidget]() {
137 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited );
138 } );
139
140 QgsFocusWatcher *xWatcher = new QgsFocusWatcher( mXLineEdit );
141 connect( xWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setX( mXLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
142 QgsFocusWatcher *yWatcher = new QgsFocusWatcher( mYLineEdit );
143 connect( yWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setY( mYLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
144 QgsFocusWatcher *zWatcher = new QgsFocusWatcher( mZLineEdit );
145 connect( zWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setZ( mZLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
146 QgsFocusWatcher *mWatcher = new QgsFocusWatcher( mYLineEdit );
147 connect( mWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() { cadDockWidget->setM( mMLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
148 QgsFocusWatcher *angleWatcher = new QgsFocusWatcher( mAngleLineEdit );
149 connect( angleWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
150 cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
151 whileBlocking( mAngleLineEdit )->setText( mCadDockWidget->constraintAngle()->displayValue() );
152 } );
153 connect( angleWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
154 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
155 whileBlocking( mAngleLineEdit )->setText( cleanedInputValue );
156 } );
157 QgsFocusWatcher *distanceWatcher = new QgsFocusWatcher( mDistanceLineEdit );
158 connect( distanceWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [this, cadDockWidget]() {
159 cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut );
160 whileBlocking( mDistanceLineEdit )->setText( mCadDockWidget->constraintDistance()->displayValue() );
161 } );
162 connect( distanceWatcher, &QgsFocusWatcher::focusIn, this, [this]() {
163 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
164 whileBlocking( mDistanceLineEdit )->setText( cleanedInputValue );
165 } );
166 changeCommonAngleSnapping( mCadDockWidget->commonAngleConstraint() );
167}
168
169bool QgsAdvancedDigitizingFloater::eventFilter( QObject *obj, QEvent *event )
170{
171 if ( mCadDockWidget && mCadDockWidget->cadEnabled() && mActive )
172 {
173 if ( event->type() == QEvent::MouseMove )
174 {
175 // We update the position when mouse moves
176 QMouseEvent *mouseEvent = qgis::down_cast<QMouseEvent *>( event );
177 updatePos( mouseEvent->pos() );
178 }
179 else if ( event->type() == QEvent::Enter )
180 {
181 // We show the widget when mouse enters
182 QEnterEvent *enterEvent = qgis::down_cast<QEnterEvent *>( event );
183 updatePos( enterEvent->pos() );
184 setVisible( true );
185 }
186 else if ( event->type() == QEvent::Leave )
187 {
188 // We hide the widget when mouse leaves
189 setVisible( false );
190 }
191 }
192 return QWidget::eventFilter( obj, event );
193}
194
196{
197 return mActive;
198}
199
201{
202 return mItemsVisibility.testFlag( item );
203}
204
206{
207 if ( !itemSupportsMeasurementType( item ) )
208 {
210 }
211
212 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
213 return QgsSettings().enumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), Qgis::CadMeasurementDisplayType::Hidden );
214}
215
217{
219
220 mActive = active;
221
222 hideIfDisabled();
223}
224
226{
227 if ( itemSupportsMeasurementType( item ) )
228 {
229 // use setItemMeasurementType instead
230 return;
231 }
232
233 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
234 QgsSettings().setValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), visible );
235 mItemsVisibility.setFlag( item, visible );
236 switch ( item )
237 {
239 enabledChangedX( visible );
240 break;
242 enabledChangedY( visible );
243 break;
245 enabledChangedM( visible );
246 break;
248 enabledChangedZ( visible );
249 break;
251 enabledChangedAngle( visible );
252 break;
254 enabledChangedDistance( visible );
255 break;
257 enabledCommonAngleSnapping( visible );
258 break;
260 enabledChangedBearing( visible );
261 break;
263 enabledChangedWeight( visible );
264 break;
267 break;
268 }
269}
270
272{
273 if ( !itemSupportsMeasurementType( item ) )
274 {
275 // use setItemVisibility instead
276 return;
277 }
278
279 const QMetaEnum enumData { QMetaEnum::fromType<QgsAdvancedDigitizingFloater::FloaterItem>() };
280 QgsSettings().setEnumValue( u"/Cad/%1ShowInFloater"_s.arg( enumData.valueToKey( static_cast<int>( item ) ) ), type );
281 switch ( type )
282 {
284 mItemsVisibility.setFlag( item, false );
285 break;
286
289 mItemsVisibility.setFlag( item, true );
290 break;
291 }
292
293 QPixmap pixmap;
294 const QColor iconColor = palette().color( QPalette::ColorRole::WindowText );
295 switch ( type )
296 {
298 break;
299
301 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterCartesian.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
302 break;
304 pixmap = QgsApplication::getThemeIcon( u"mIconFloaterEllipsoid.svg"_s, iconColor, iconColor ).pixmap( QSize( 10, 10 ) );
305 break;
306 }
307
308 switch ( item )
309 {
319 break;
320
322 {
323 const bool show = itemVisibility( FloaterItem::Area );
324 mTotalAreaLineEdit->setVisible( show );
325 mAreaLabel->setVisible( show );
326 mAreaMeasurementTypeLabel->setVisible( show );
327 mAreaMeasurementTypeLabel->setPixmap( pixmap );
328 adjustSize();
329 break;
330 }
332 const bool show = itemVisibility( FloaterItem::TotalLength );
333 mTotalLengthLineEdit->setVisible( show );
334 mTotalLengthLabel->setVisible( show );
335 mLengthMeasurementTypeLabel->setVisible( show );
336 mLengthMeasurementTypeLabel->setPixmap( pixmap );
337 adjustSize();
338 break;
339 }
340}
341
363
364void QgsAdvancedDigitizingFloater::updatePos( const QPoint &pos )
365{
366 // We hardcode a small delta between the mouse position and the widget's position
367 move( pos + QPoint( 15, 5 ) );
368}
369
370void QgsAdvancedDigitizingFloater::hideIfDisabled()
371{
372 if ( !mCadDockWidget || !mCadDockWidget->cadEnabled() || !mActive )
373 {
374 setVisible( false );
375 }
376}
377
378void QgsAdvancedDigitizingFloater::changeX( const QString &text )
379{
380 mXLineEdit->setText( text );
381 mXLineEdit->setCursorPosition( 0 );
382}
383
384void QgsAdvancedDigitizingFloater::changeY( const QString &text )
385{
386 mYLineEdit->setText( text );
387 mYLineEdit->setCursorPosition( 0 );
388}
389
390void QgsAdvancedDigitizingFloater::changeZ( const QString &text )
391{
392 mZLineEdit->setText( text );
393 mZLineEdit->setCursorPosition( 0 );
394}
395
396void QgsAdvancedDigitizingFloater::changeM( const QString &text )
397{
398 mMLineEdit->setText( text );
399 mMLineEdit->setCursorPosition( 0 );
400}
401
402void QgsAdvancedDigitizingFloater::changeCommonAngleSnapping( double angle )
403{
404 mCommonAngleSnappingLineEdit->setText( qgsDoubleNear( angle, 0.0 ) ? tr( "disabled" ) : QLocale().toString( angle ).append( tr( " °" ) ) );
405}
406
407void QgsAdvancedDigitizingFloater::changeDistance( const QString &text )
408{
409 mDistanceLineEdit->setText( text );
410 mDistanceLineEdit->setCursorPosition( 0 );
411}
412
413void QgsAdvancedDigitizingFloater::changeAngle( const QString &text )
414{
415 mAngleLineEdit->setText( text );
416 mAngleLineEdit->setCursorPosition( 0 );
417}
418
419void QgsAdvancedDigitizingFloater::changeBearing( const QString &text )
420{
421 mBearingLineEdit->setText( text );
422 mBearingLineEdit->setCursorPosition( 0 );
423}
424
425void QgsAdvancedDigitizingFloater::changeArea( const QString &text )
426{
427 mTotalAreaLineEdit->setText( text );
428 mTotalAreaLineEdit->setCursorPosition( 0 );
429}
430
431void QgsAdvancedDigitizingFloater::changeTotalLength( const QString &text )
432{
433 mTotalLengthLineEdit->setText( text );
434 mTotalLengthLineEdit->setCursorPosition( 0 );
435}
436
437void QgsAdvancedDigitizingFloater::changeLockX( bool locked )
438{
439 if ( !locked )
440 {
441 mXLineEdit->setStyleSheet( QString() );
442 mXLabel->setStyleSheet( QString() );
443 }
444 else
445 {
446 mXLineEdit->setStyleSheet( u"font-weight: bold"_s );
447 mXLabel->setStyleSheet( u"font-weight: bold"_s );
448 }
449}
450
451void QgsAdvancedDigitizingFloater::changeLockY( bool locked )
452{
453 if ( !locked )
454 {
455 mYLineEdit->setStyleSheet( QString() );
456 mYLabel->setStyleSheet( QString() );
457 }
458 else
459 {
460 mYLineEdit->setStyleSheet( u"font-weight: bold"_s );
461 mYLabel->setStyleSheet( u"font-weight: bold"_s );
462 }
463}
464
465void QgsAdvancedDigitizingFloater::changeLockZ( bool locked )
466{
467 if ( !locked )
468 {
469 mZLineEdit->setStyleSheet( QString() );
470 mZLabel->setStyleSheet( QString() );
471 }
472 else
473 {
474 mZLineEdit->setStyleSheet( u"font-weight: bold"_s );
475 mZLabel->setStyleSheet( u"font-weight: bold"_s );
476 }
477}
478
479void QgsAdvancedDigitizingFloater::changeLockM( bool locked )
480{
481 if ( !locked )
482 {
483 mMLineEdit->setStyleSheet( QString() );
484 mMLabel->setStyleSheet( QString() );
485 }
486 else
487 {
488 mMLineEdit->setStyleSheet( u"font-weight: bold"_s );
489 mMLabel->setStyleSheet( u"font-weight: bold"_s );
490 }
491}
492
493void QgsAdvancedDigitizingFloater::changeLockDistance( bool locked )
494{
495 if ( !locked )
496 {
497 mDistanceLineEdit->setStyleSheet( QString() );
498 mDistanceLabel->setStyleSheet( QString() );
499 }
500 else
501 {
502 mDistanceLineEdit->setStyleSheet( u"font-weight: bold"_s );
503 mDistanceLabel->setStyleSheet( u"font-weight: bold"_s );
504 }
505}
506
507void QgsAdvancedDigitizingFloater::changeLockAngle( bool locked )
508{
509 if ( !locked )
510 {
511 mAngleLineEdit->setStyleSheet( QString() );
512 mAngleLabel->setStyleSheet( QString() );
513 }
514 else
515 {
516 mAngleLineEdit->setStyleSheet( u"font-weight: bold"_s );
517 mAngleLabel->setStyleSheet( u"font-weight: bold"_s );
518 }
519}
520
521
522void QgsAdvancedDigitizingFloater::changeRelativeX( bool relative )
523{
524 if ( !relative )
525 {
526 mXLabel->setText( "x" );
527 }
528 else
529 {
530 mXLabel->setText( "Δx" );
531 }
532 adjustSize();
533}
534
535void QgsAdvancedDigitizingFloater::changeRelativeY( bool relative )
536{
537 if ( !relative )
538 {
539 mYLabel->setText( "y" );
540 }
541 else
542 {
543 mYLabel->setText( "Δy" );
544 }
545 adjustSize();
546}
547
548void QgsAdvancedDigitizingFloater::changeRelativeZ( bool relative )
549{
550 if ( !relative )
551 {
552 mZLabel->setText( "z" );
553 }
554 else
555 {
556 mZLabel->setText( "Δz" );
557 }
558 adjustSize();
559}
560
561void QgsAdvancedDigitizingFloater::changeRelativeM( bool relative )
562{
563 if ( !relative )
564 {
565 mMLabel->setText( "m" );
566 }
567 else
568 {
569 mMLabel->setText( "Δm" );
570 }
571 adjustSize();
572}
573
574// distance is always relative
575
576void QgsAdvancedDigitizingFloater::changeRelativeAngle( bool relative )
577{
578 if ( !relative )
579 {
580 mAngleLabel->setText( "a" );
581 }
582 else
583 {
584 mAngleLabel->setText( "Δa" );
585 }
586 adjustSize();
587}
588
589void QgsAdvancedDigitizingFloater::focusOnX()
590{
591 if ( mActive )
592 {
593 mXLineEdit->setFocus();
594 mXLineEdit->selectAll();
595 }
596}
597
598void QgsAdvancedDigitizingFloater::focusOnY()
599{
600 if ( mActive )
601 {
602 mYLineEdit->setFocus();
603 mYLineEdit->selectAll();
604 }
605}
606
607void QgsAdvancedDigitizingFloater::focusOnZ()
608{
609 if ( mActive )
610 {
611 mZLineEdit->setFocus();
612 mZLineEdit->selectAll();
613 }
614}
615
616void QgsAdvancedDigitizingFloater::focusOnM()
617{
618 if ( mActive )
619 {
620 mMLineEdit->setFocus();
621 mMLineEdit->selectAll();
622 }
623}
624
625void QgsAdvancedDigitizingFloater::focusOnDistance()
626{
627 if ( mActive )
628 {
629 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
630 mDistanceLineEdit->setText( cleanedInputValue );
631 mDistanceLineEdit->setFocus();
632 mDistanceLineEdit->selectAll();
633 }
634}
635
636void QgsAdvancedDigitizingFloater::focusOnAngle()
637{
638 if ( mActive )
639 {
640 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
641 mAngleLineEdit->setText( cleanedInputValue );
642 mAngleLineEdit->setFocus();
643 mAngleLineEdit->selectAll();
644 }
645}
646
648{
649 if ( mActive )
650 {
651 mWeightLineEdit->setFocus();
652 mWeightLineEdit->selectAll();
653 }
654}
655
656
657void QgsAdvancedDigitizingFloater::enabledChangedX( bool enabled )
658{
659 mXLineEdit->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
660 mXLabel->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
661 adjustSize();
662}
663
664void QgsAdvancedDigitizingFloater::enabledChangedY( bool enabled )
665{
666 mYLineEdit->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
667 mYLabel->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
668 adjustSize();
669}
670
671void QgsAdvancedDigitizingFloater::enabledChangedZ( bool enabled )
672{
673 mZLineEdit->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
674 mZLabel->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
675 adjustSize();
676}
677
678void QgsAdvancedDigitizingFloater::enabledChangedM( bool enabled )
679{
680 mMLineEdit->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
681 mMLabel->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
682 adjustSize();
683}
684
685void QgsAdvancedDigitizingFloater::enabledChangedDistance( bool enabled )
686{
687 mDistanceLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
688 mDistanceLabel->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
689 adjustSize();
690}
691
692void QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping( bool enabled )
693{
694 mCommonAngleSnappingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
695 mCommonAngleSnappingLabel->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
696 adjustSize();
697}
698
699void QgsAdvancedDigitizingFloater::enabledChangedAngle( bool enabled )
700{
701 mAngleLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
702 mAngleLabel->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
703 adjustSize();
704}
705
706void QgsAdvancedDigitizingFloater::enabledChangedBearing( bool enabled )
707{
708 mBearingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
709 mBearingLabel->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
710 adjustSize();
711}
712
714{
715 mWeightLineEdit->setText( text );
716}
717
719{
720 // Always show weight when enabled, regardless of user preference
721 // This is because weight editing is a temporary mode (activated with W key)
722 mWeightLineEdit->setVisible( enabled );
723 mWeightLabel->setVisible( enabled );
724 adjustSize();
725}
@ Distance
Distance value.
Definition qgis.h:4275
@ Angle
Angle value.
Definition qgis.h:4274
CadMeasurementDisplayType
Advanced digitizing measurement display types.
Definition qgis.h:4288
@ Hidden
Hide measurement.
Definition qgis.h:4289
@ Cartesian
Use Cartesian measurements.
Definition qgis.h:4290
@ Ellipsoidal
Use Ellipsoidal measurements.
Definition qgis.h:4291
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.
static const QgsSettingsEntryBool * settingsCadFloaterActive
Settings entry CAD floater active state.
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:8015
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7381
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:7275