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