QGIS API Documentation 4.1.0-Master (376402f9aeb)
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"
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}
382
383void QgsAdvancedDigitizingFloater::changeY( const QString &text )
384{
385 mYLineEdit->setText( text );
386}
387
388void QgsAdvancedDigitizingFloater::changeZ( const QString &text )
389{
390 mZLineEdit->setText( text );
391}
392
393void QgsAdvancedDigitizingFloater::changeM( const QString &text )
394{
395 mMLineEdit->setText( text );
396}
397
398void QgsAdvancedDigitizingFloater::changeCommonAngleSnapping( double angle )
399{
400 mCommonAngleSnappingLineEdit->setText( qgsDoubleNear( angle, 0.0 ) ? tr( "disabled" ) : QLocale().toString( angle ).append( tr( " °" ) ) );
401}
402
403void QgsAdvancedDigitizingFloater::changeDistance( const QString &text )
404{
405 mDistanceLineEdit->setText( text );
406}
407
408void QgsAdvancedDigitizingFloater::changeAngle( const QString &text )
409{
410 mAngleLineEdit->setText( text );
411}
412
413void QgsAdvancedDigitizingFloater::changeBearing( const QString &text )
414{
415 mBearingLineEdit->setText( text );
416}
417
418void QgsAdvancedDigitizingFloater::changeArea( const QString &text )
419{
420 mTotalAreaLineEdit->setText( text );
421}
422
423void QgsAdvancedDigitizingFloater::changeTotalLength( const QString &text )
424{
425 mTotalLengthLineEdit->setText( text );
426}
427
428void QgsAdvancedDigitizingFloater::changeLockX( bool locked )
429{
430 if ( !locked )
431 {
432 mXLineEdit->setStyleSheet( QString() );
433 mXLabel->setStyleSheet( QString() );
434 }
435 else
436 {
437 mXLineEdit->setStyleSheet( u"font-weight: bold"_s );
438 mXLabel->setStyleSheet( u"font-weight: bold"_s );
439 }
440}
441
442void QgsAdvancedDigitizingFloater::changeLockY( bool locked )
443{
444 if ( !locked )
445 {
446 mYLineEdit->setStyleSheet( QString() );
447 mYLabel->setStyleSheet( QString() );
448 }
449 else
450 {
451 mYLineEdit->setStyleSheet( u"font-weight: bold"_s );
452 mYLabel->setStyleSheet( u"font-weight: bold"_s );
453 }
454}
455
456void QgsAdvancedDigitizingFloater::changeLockZ( bool locked )
457{
458 if ( !locked )
459 {
460 mZLineEdit->setStyleSheet( QString() );
461 mZLabel->setStyleSheet( QString() );
462 }
463 else
464 {
465 mZLineEdit->setStyleSheet( u"font-weight: bold"_s );
466 mZLabel->setStyleSheet( u"font-weight: bold"_s );
467 }
468}
469
470void QgsAdvancedDigitizingFloater::changeLockM( bool locked )
471{
472 if ( !locked )
473 {
474 mMLineEdit->setStyleSheet( QString() );
475 mMLabel->setStyleSheet( QString() );
476 }
477 else
478 {
479 mMLineEdit->setStyleSheet( u"font-weight: bold"_s );
480 mMLabel->setStyleSheet( u"font-weight: bold"_s );
481 }
482}
483
484void QgsAdvancedDigitizingFloater::changeLockDistance( bool locked )
485{
486 if ( !locked )
487 {
488 mDistanceLineEdit->setStyleSheet( QString() );
489 mDistanceLabel->setStyleSheet( QString() );
490 }
491 else
492 {
493 mDistanceLineEdit->setStyleSheet( u"font-weight: bold"_s );
494 mDistanceLabel->setStyleSheet( u"font-weight: bold"_s );
495 }
496}
497
498void QgsAdvancedDigitizingFloater::changeLockAngle( bool locked )
499{
500 if ( !locked )
501 {
502 mAngleLineEdit->setStyleSheet( QString() );
503 mAngleLabel->setStyleSheet( QString() );
504 }
505 else
506 {
507 mAngleLineEdit->setStyleSheet( u"font-weight: bold"_s );
508 mAngleLabel->setStyleSheet( u"font-weight: bold"_s );
509 }
510}
511
512
513void QgsAdvancedDigitizingFloater::changeRelativeX( bool relative )
514{
515 if ( !relative )
516 {
517 mXLabel->setText( "x" );
518 }
519 else
520 {
521 mXLabel->setText( "Δx" );
522 }
523 adjustSize();
524}
525
526void QgsAdvancedDigitizingFloater::changeRelativeY( bool relative )
527{
528 if ( !relative )
529 {
530 mYLabel->setText( "y" );
531 }
532 else
533 {
534 mYLabel->setText( "Δy" );
535 }
536 adjustSize();
537}
538
539void QgsAdvancedDigitizingFloater::changeRelativeZ( bool relative )
540{
541 if ( !relative )
542 {
543 mZLabel->setText( "z" );
544 }
545 else
546 {
547 mZLabel->setText( "Δz" );
548 }
549 adjustSize();
550}
551
552void QgsAdvancedDigitizingFloater::changeRelativeM( bool relative )
553{
554 if ( !relative )
555 {
556 mMLabel->setText( "m" );
557 }
558 else
559 {
560 mMLabel->setText( "Δm" );
561 }
562 adjustSize();
563}
564
565// distance is always relative
566
567void QgsAdvancedDigitizingFloater::changeRelativeAngle( bool relative )
568{
569 if ( !relative )
570 {
571 mAngleLabel->setText( "a" );
572 }
573 else
574 {
575 mAngleLabel->setText( "Δa" );
576 }
577 adjustSize();
578}
579
580void QgsAdvancedDigitizingFloater::focusOnX()
581{
582 if ( mActive )
583 {
584 mXLineEdit->setFocus();
585 mXLineEdit->selectAll();
586 }
587}
588
589void QgsAdvancedDigitizingFloater::focusOnY()
590{
591 if ( mActive )
592 {
593 mYLineEdit->setFocus();
594 mYLineEdit->selectAll();
595 }
596}
597
598void QgsAdvancedDigitizingFloater::focusOnZ()
599{
600 if ( mActive )
601 {
602 mZLineEdit->setFocus();
603 mZLineEdit->selectAll();
604 }
605}
606
607void QgsAdvancedDigitizingFloater::focusOnM()
608{
609 if ( mActive )
610 {
611 mMLineEdit->setFocus();
612 mMLineEdit->selectAll();
613 }
614}
615
616void QgsAdvancedDigitizingFloater::focusOnDistance()
617{
618 if ( mActive )
619 {
620 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mDistanceLineEdit->text(), Qgis::CadConstraintType::Distance ) };
621 mDistanceLineEdit->setText( cleanedInputValue );
622 mDistanceLineEdit->setFocus();
623 mDistanceLineEdit->selectAll();
624 }
625}
626
627void QgsAdvancedDigitizingFloater::focusOnAngle()
628{
629 if ( mActive )
630 {
631 const QString cleanedInputValue { QgsAdvancedDigitizingDockWidget::CadConstraint::removeSuffix( mAngleLineEdit->text(), Qgis::CadConstraintType::Angle ) };
632 mAngleLineEdit->setText( cleanedInputValue );
633 mAngleLineEdit->setFocus();
634 mAngleLineEdit->selectAll();
635 }
636}
637
639{
640 if ( mActive )
641 {
642 mWeightLineEdit->setFocus();
643 mWeightLineEdit->selectAll();
644 }
645}
646
647
648void QgsAdvancedDigitizingFloater::enabledChangedX( bool enabled )
649{
650 mXLineEdit->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
651 mXLabel->setVisible( enabled && itemVisibility( FloaterItem::XCoordinate ) );
652 adjustSize();
653}
654
655void QgsAdvancedDigitizingFloater::enabledChangedY( bool enabled )
656{
657 mYLineEdit->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
658 mYLabel->setVisible( enabled && itemVisibility( FloaterItem::YCoordinate ) );
659 adjustSize();
660}
661
662void QgsAdvancedDigitizingFloater::enabledChangedZ( bool enabled )
663{
664 mZLineEdit->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
665 mZLabel->setVisible( enabled && itemVisibility( FloaterItem::ZCoordinate ) );
666 adjustSize();
667}
668
669void QgsAdvancedDigitizingFloater::enabledChangedM( bool enabled )
670{
671 mMLineEdit->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
672 mMLabel->setVisible( enabled && itemVisibility( FloaterItem::MCoordinate ) );
673 adjustSize();
674}
675
676void QgsAdvancedDigitizingFloater::enabledChangedDistance( bool enabled )
677{
678 mDistanceLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
679 mDistanceLabel->setVisible( enabled && itemVisibility( FloaterItem::Distance ) );
680 adjustSize();
681}
682
683void QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping( bool enabled )
684{
685 mCommonAngleSnappingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
686 mCommonAngleSnappingLabel->setVisible( enabled && itemVisibility( FloaterItem::CommonAngleSnapping ) );
687 adjustSize();
688}
689
690void QgsAdvancedDigitizingFloater::enabledChangedAngle( bool enabled )
691{
692 mAngleLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
693 mAngleLabel->setVisible( enabled && itemVisibility( FloaterItem::Angle ) );
694 adjustSize();
695}
696
697void QgsAdvancedDigitizingFloater::enabledChangedBearing( bool enabled )
698{
699 mBearingLineEdit->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
700 mBearingLabel->setVisible( enabled && itemVisibility( FloaterItem::Bearing ) );
701 adjustSize();
702}
703
705{
706 mWeightLineEdit->setText( text );
707}
708
710{
711 // Always show weight when enabled, regardless of user preference
712 // This is because weight editing is a temporary mode (activated with W key)
713 mWeightLineEdit->setVisible( enabled );
714 mWeightLabel->setVisible( enabled );
715 adjustSize();
716}
@ Distance
Distance value.
Definition qgis.h:4261
@ Angle
Angle value.
Definition qgis.h:4260
CadMeasurementDisplayType
Advanced digitizing measurement display types.
Definition qgis.h:4274
@ Hidden
Hide measurement.
Definition qgis.h:4275
@ Cartesian
Use Cartesian measurements.
Definition qgis.h:4276
@ Ellipsoidal
Use Ellipsoidal measurements.
Definition qgis.h:4277
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:7714
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7134
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:7039