QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgslayoutelevationprofilewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutelevationprofilewidget.cpp
3 ----------------------
4 begin : January 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "moc_qgslayoutelevationprofilewidget.cpp"
21#include "qgslayoutitemwidget.h"
23#include "qgsplot.h"
24#include "qgsfillsymbol.h"
25#include "qgslinesymbol.h"
26#include "qgsvectorlayer.h"
28#include "qgslayout.h"
29#include "qgslayertree.h"
33#include "qgscurve.h"
34#include "qgslayoutatlas.h"
36#include "qgsgui.h"
37#include <QMenu>
38
40
42 : QgsLayoutItemBaseWidget( nullptr, profile )
43 , mProfile( profile )
44 , mLayerTree( new QgsLayerTree() )
45 , mLayerTreeBridge( new QgsLayerTreeRegistryBridge( mLayerTree.get(), mProfile->layout() ? mProfile->layout()->project() : QgsProject::instance(), this ) )
46{
47 Q_ASSERT( mProfile );
48
49 setupUi( this );
50 setPanelTitle( tr( "Elevation Profile Properties" ) );
51
52 mCopyFromDockMenu = new QMenu( this );
53 connect( mCopyFromDockMenu, &QMenu::aboutToShow, this, [=] {
54 sBuildCopyMenuFunction( this, mCopyFromDockMenu );
55 } );
56
57 connect( mActionRefresh, &QAction::triggered, this, [=] {
58 if ( !mProfile )
59 {
60 return;
61 }
62 mProfile->invalidateCache();
63 mProfile->refresh();
64 } );
65
66 QToolButton *copyFromDockButton = new QToolButton();
67 copyFromDockButton->setAutoRaise( true );
68 copyFromDockButton->setToolTip( tr( "Copy From Profile" ) );
69 copyFromDockButton->setMenu( mCopyFromDockMenu );
70 copyFromDockButton->setPopupMode( QToolButton::InstantPopup );
71 copyFromDockButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionCopyProfileSettings.svg" ) ) );
72
73 mDockToolbar->addWidget( copyFromDockButton );
74
75 //add widget for general composer item properties
76 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, profile );
77 mainLayout->addWidget( mItemPropertiesWidget );
78
79 connect( mLayerTree.get(), &QgsLayerTree::layerOrderChanged, this, &QgsLayoutElevationProfileWidget::updateItemLayers );
80 connect( mLayerTree.get(), &QgsLayerTreeGroup::visibilityChanged, this, &QgsLayoutElevationProfileWidget::updateItemLayers );
81
82 mSpinTolerance->setClearValue( 0 );
83 connect( mSpinTolerance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
84 if ( !mProfile || mBlockChanges )
85 return;
86
87 mProfile->beginCommand( tr( "Change Profile Tolerance Distance" ), QgsLayoutItem::UndoElevationProfileTolerance );
88 mProfile->setTolerance( value );
89 mProfile->invalidateCache();
90 mProfile->update();
91 mProfile->endCommand();
92 } );
93
94 connect( mCheckControlledByAtlas, &QCheckBox::toggled, this, [=] {
95 if ( !mProfile || mBlockChanges )
96 return;
97
98 mProfile->beginCommand( tr( "Change Profile Atlas Control" ) );
99 mProfile->setAtlasDriven( mCheckControlledByAtlas->isChecked() );
100 mProfile->invalidateCache();
101 mProfile->update();
102 mProfile->endCommand();
103 } );
104
105 mSpinMinDistance->setClearValue( 0 );
106 connect( mSpinMinDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
107 if ( !mProfile || mBlockChanges )
108 return;
109
110 mProfile->beginCommand( tr( "Change Profile Chart Minimum Distance" ), QgsLayoutItem::UndoElevationProfileMinimumDistance );
111 mProfile->plot()->setXMinimum( value );
112 mProfile->invalidateCache();
113 mProfile->update();
114 mProfile->endCommand();
115 } );
116
117 connect( mSpinMaxDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
118 if ( !mProfile || mBlockChanges )
119 return;
120
121 mProfile->beginCommand( tr( "Change Profile Chart Maximum Distance" ), QgsLayoutItem::UndoElevationProfileMaximumDistance );
122 mProfile->plot()->setXMaximum( value );
123 mProfile->invalidateCache();
124 mProfile->update();
125 mProfile->endCommand();
126 } );
127
128 mSpinMinElevation->setClearValue( 0 );
129 connect( mSpinMinElevation, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
130 if ( !mProfile || mBlockChanges )
131 return;
132
133 mProfile->beginCommand( tr( "Change Profile Chart Minimum Elevation" ), QgsLayoutItem::UndoElevationProfileMinimumElevation );
134 mProfile->plot()->setYMinimum( value );
135 mProfile->invalidateCache();
136 mProfile->update();
137 mProfile->endCommand();
138 } );
139
140 connect( mSpinMaxElevation, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
141 if ( !mProfile || mBlockChanges )
142 return;
143
144 mProfile->beginCommand( tr( "Change Profile Chart Maximum Elevation" ), QgsLayoutItem::UndoElevationProfileMaximumElevation );
145 mProfile->plot()->setYMaximum( value );
146 mProfile->invalidateCache();
147 mProfile->update();
148 mProfile->endCommand();
149 } );
150
151 mDistanceAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
152 connect( mDistanceAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [=] {
153 if ( !mProfile || mBlockChanges )
154 return;
155
156 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
157 mProfile->plot()->xAxis().setGridMajorSymbol( mDistanceAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
158 mProfile->invalidateCache();
159 mProfile->update();
160 mProfile->endCommand();
161 } );
162 mDistanceAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
163
164 mDistanceAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
165 connect( mDistanceAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [=] {
166 if ( !mProfile || mBlockChanges )
167 return;
168
169 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
170 mProfile->plot()->xAxis().setGridMinorSymbol( mDistanceAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
171 mProfile->invalidateCache();
172 mProfile->update();
173 mProfile->endCommand();
174 } );
175 mDistanceAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
176
177 connect( mDistanceAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
178 if ( !mProfile || mBlockChanges )
179 return;
180
181 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
182 mProfile->plot()->xAxis().setGridIntervalMajor( value );
183 mProfile->invalidateCache();
184 mProfile->update();
185 mProfile->endCommand();
186 } );
187
188 connect( mDistanceAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
189 if ( !mProfile || mBlockChanges )
190 return;
191
192 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
193 mProfile->plot()->xAxis().setGridIntervalMinor( value );
194 mProfile->invalidateCache();
195 mProfile->update();
196 mProfile->endCommand();
197 } );
198
199 connect( mDistanceAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
200 if ( !mProfile || mBlockChanges )
201 return;
202
203 mProfile->beginCommand( tr( "Change Profile Chart Distance Label" ), QgsLayoutItem::UndoElevationProfileDistanceLabels );
204 mProfile->plot()->xAxis().setLabelInterval( value );
205 mProfile->invalidateCache();
206 mProfile->update();
207 mProfile->endCommand();
208 } );
209
210 mElevationAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
211 connect( mElevationAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [=] {
212 if ( !mProfile || mBlockChanges )
213 return;
214
215 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
216 mProfile->plot()->yAxis().setGridMajorSymbol( mElevationAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
217 mProfile->invalidateCache();
218 mProfile->update();
219 mProfile->endCommand();
220 } );
221 mElevationAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
222
223 mElevationAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
224 connect( mElevationAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [=] {
225 if ( !mProfile || mBlockChanges )
226 return;
227
228 mProfile->beginCommand( tr( "Change Profile Chart Elevation Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
229 mProfile->plot()->yAxis().setGridMinorSymbol( mElevationAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
230 mProfile->invalidateCache();
231 mProfile->update();
232 mProfile->endCommand();
233 } );
234 mElevationAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
235
236 connect( mElevationAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
237 if ( !mProfile || mBlockChanges )
238 return;
239
240 mProfile->beginCommand( tr( "Change Profile Chart Elevation Label" ), QgsLayoutItem::UndoElevationProfileElevationLabels );
241 mProfile->plot()->yAxis().setLabelInterval( value );
242 mProfile->invalidateCache();
243 mProfile->update();
244 mProfile->endCommand();
245 } );
246
247 connect( mElevationAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
248 if ( !mProfile || mBlockChanges )
249 return;
250
251 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
252 mProfile->plot()->yAxis().setGridIntervalMajor( value );
253 mProfile->invalidateCache();
254 mProfile->update();
255 mProfile->endCommand();
256 } );
257
258 connect( mElevationAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
259 if ( !mProfile || mBlockChanges )
260 return;
261
262 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
263 mProfile->plot()->yAxis().setGridIntervalMinor( value );
264 mProfile->invalidateCache();
265 mProfile->update();
266 mProfile->endCommand();
267 } );
268
269 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
270 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [=] {
271 if ( !mProfile || mBlockChanges )
272 return;
273
274 mProfile->beginCommand( tr( "Change Profile Chart Background" ), QgsLayoutItem::UndoElevationProfileChartBackground );
275 mProfile->plot()->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
276 mProfile->invalidateCache();
277 mProfile->update();
278 mProfile->endCommand();
279 } );
280 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
281
282 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
283 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [=] {
284 if ( !mProfile || mBlockChanges )
285 return;
286
287 mProfile->beginCommand( tr( "Change Profile Chart Border" ), QgsLayoutItem::UndoElevationProfileChartBorder );
288 mProfile->plot()->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
289 mProfile->invalidateCache();
290 mProfile->update();
291 mProfile->endCommand();
292 } );
293 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
294
295 connect( mDistanceAxisLabelFormatButton, &QPushButton::clicked, this, [=] {
296 if ( !mProfile || mBlockChanges )
297 return;
298
300 widget->setPanelTitle( tr( "Distance Number Format" ) );
301 widget->setFormat( mProfile->plot()->xAxis().numericFormat() );
302 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [=] {
303 mProfile->beginCommand( tr( "Change Profile Chart Distance Format" ), QgsLayoutItem::UndoElevationProfileDistanceFormat );
304 mProfile->plot()->xAxis().setNumericFormat( widget->format() );
305 mProfile->invalidateCache();
306 mProfile->endCommand();
307 mProfile->update();
308 } );
309 openPanel( widget );
310 } );
311
312 connect( mElevationAxisLabelFormatButton, &QPushButton::clicked, this, [=] {
313 if ( !mProfile || mBlockChanges )
314 return;
315
317 widget->setPanelTitle( tr( "Elevation Number Format" ) );
318 widget->setFormat( mProfile->plot()->yAxis().numericFormat() );
319 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [=] {
320 mProfile->beginCommand( tr( "Change Profile Chart Elevation Format" ), QgsLayoutItem::UndoElevationProfileElevationFormat );
321 mProfile->plot()->yAxis().setNumericFormat( widget->format() );
322 mProfile->invalidateCache();
323 mProfile->endCommand();
324 mProfile->update();
325 } );
326 openPanel( widget );
327 } );
328
329 mDistanceAxisLabelFontButton->setDialogTitle( tr( "Distance Label Font" ) );
330 mElevationAxisLabelFontButton->setDialogTitle( tr( "Elevation Label Font" ) );
331 mDistanceAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
332 mElevationAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
333
334 connect( mDistanceAxisLabelFontButton, &QgsFontButton::changed, this, [=] {
335 if ( !mProfile || mBlockChanges )
336 return;
337
338 mProfile->beginCommand( tr( "Change Profile Chart Distance Font" ), QgsLayoutItem::UndoElevationProfileDistanceFont );
339 mProfile->plot()->xAxis().setTextFormat( mDistanceAxisLabelFontButton->textFormat() );
340 mProfile->invalidateCache();
341 mProfile->endCommand();
342 mProfile->update();
343 } );
344
345 connect( mElevationAxisLabelFontButton, &QgsFontButton::changed, this, [=] {
346 if ( !mProfile || mBlockChanges )
347 return;
348
349 mProfile->beginCommand( tr( "Change Profile Chart Elevation Font" ), QgsLayoutItem::UndoElevationProfileElevationFont );
350 mProfile->plot()->yAxis().setTextFormat( mElevationAxisLabelFontButton->textFormat() );
351 mProfile->invalidateCache();
352 mProfile->endCommand();
353 mProfile->update();
354 } );
355
356 mSpinLeftMargin->setClearValue( 0 );
357 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
358 if ( !mProfile || mBlockChanges )
359 return;
360
361 mProfile->beginCommand( tr( "Change Profile Chart Left Margin" ), QgsLayoutItem::UndoMarginLeft );
362 QgsMargins margins = mProfile->plot()->margins();
363 margins.setLeft( value );
364 mProfile->plot()->setMargins( margins );
365 mProfile->invalidateCache();
366 mProfile->update();
367 mProfile->endCommand();
368 } );
369
370 mSpinRightMargin->setClearValue( 0 );
371 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
372 if ( !mProfile || mBlockChanges )
373 return;
374
375 mProfile->beginCommand( tr( "Change Profile Chart Right Margin" ), QgsLayoutItem::UndoMarginRight );
376 QgsMargins margins = mProfile->plot()->margins();
377 margins.setRight( value );
378 mProfile->plot()->setMargins( margins );
379 mProfile->invalidateCache();
380 mProfile->update();
381 mProfile->endCommand();
382 } );
383
384 mSpinTopMargin->setClearValue( 0 );
385 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
386 if ( !mProfile || mBlockChanges )
387 return;
388
389 mProfile->beginCommand( tr( "Change Profile Chart Top Margin" ), QgsLayoutItem::UndoMarginTop );
390 QgsMargins margins = mProfile->plot()->margins();
391 margins.setTop( value );
392 mProfile->plot()->setMargins( margins );
393 mProfile->invalidateCache();
394 mProfile->update();
395 mProfile->endCommand();
396 } );
397
398 mSpinBottomMargin->setClearValue( 0 );
399 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [=]( double value ) {
400 if ( !mProfile || mBlockChanges )
401 return;
402
403 mProfile->beginCommand( tr( "Change Profile Chart Bottom Margin" ), QgsLayoutItem::UndoMarginBottom );
404 QgsMargins margins = mProfile->plot()->margins();
405 margins.setBottom( value );
406 mProfile->plot()->setMargins( margins );
407 mProfile->invalidateCache();
408 mProfile->update();
409 mProfile->endCommand();
410 } );
411
412 for ( Qgis::DistanceUnit unit :
413 {
424 } )
425 {
426 QString title;
428 {
430 }
431 else
432 {
433 title = QgsUnitTypes::toString( unit );
434 }
435 mDistanceUnitCombo->addItem( title, QVariant::fromValue( unit ) );
436 }
437
438 connect( mDistanceUnitCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [=]( int ) {
439 if ( !mProfile || mBlockChanges )
440 return;
441
442 mProfile->beginCommand( tr( "Change Profile Chart Units" ) );
443 mProfile->setDistanceUnit( mDistanceUnitCombo->currentData().value<Qgis::DistanceUnit>() );
444 mProfile->invalidateCache();
445 mProfile->update();
446 mProfile->endCommand();
447 } );
448
449 mDistanceLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
450 mDistanceLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
451 mDistanceLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
452 mDistanceLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
453 mDistanceLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
454 connect( mDistanceLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [=]( int ) {
455 if ( !mProfile || mBlockChanges )
456 return;
457
458 mProfile->beginCommand( tr( "Change Profile Chart Label Placement" ) );
459 mProfile->plot()->xAxis().setLabelSuffixPlacement( mDistanceLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
460 mProfile->invalidateCache();
461 mProfile->update();
462 mProfile->endCommand();
463 } );
464
465
481
482 mLayerTreeView = new QgsElevationProfileLayerTreeView( mLayerTree.get() );
483
484 QVBoxLayout *vl = new QVBoxLayout();
485 vl->setContentsMargins( 0, 0, 0, 0 );
486 vl->addWidget( mLayerTreeView );
487 mTreeViewContainer->setLayout( vl );
488
489 mBlockChanges++;
490 mLayerTreeView->populateInitialLayers( mProfile->layout() && mProfile->layout()->project() ? mProfile->layout()->project() : QgsProject::instance() );
491 mBlockChanges--;
492
493 setGuiElementValues();
494
495 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
496 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
497 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
498 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
499 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
500 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
501 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
502 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
503
504 mDistanceAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
505 mDistanceAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
506 mElevationAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
507 mElevationAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
508 mDistanceAxisLabelFontButton->setLayer( coverageLayer() );
509 mElevationAxisLabelFontButton->setLayer( coverageLayer() );
510 mChartBackgroundSymbolButton->setLayer( coverageLayer() );
511 mChartBorderSymbolButton->setLayer( coverageLayer() );
512
513 if ( mProfile->layout() )
514 {
515 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, this, [=]( QgsVectorLayer *layer ) {
516 mDistanceAxisMajorLinesSymbolButton->setLayer( layer );
517 mDistanceAxisMinorLinesSymbolButton->setLayer( layer );
518 mElevationAxisMajorLinesSymbolButton->setLayer( layer );
519 mElevationAxisMinorLinesSymbolButton->setLayer( layer );
520 mDistanceAxisLabelFontButton->setLayer( layer );
521 mElevationAxisLabelFontButton->setLayer( layer );
522 mChartBackgroundSymbolButton->setLayer( layer );
523 mChartBorderSymbolButton->setLayer( layer );
524 } );
525
526 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, this, &QgsLayoutElevationProfileWidget::atlasLayerChanged );
527 }
528
529 if ( QgsLayoutAtlas *atlas = layoutAtlas() )
530 {
531 connect( atlas, &QgsLayoutAtlas::toggled, this, &QgsLayoutElevationProfileWidget::layoutAtlasToggled );
532 layoutAtlasToggled( atlas->enabled() );
533 }
534}
535
537
539{
540 if ( mItemPropertiesWidget )
541 mItemPropertiesWidget->setMasterLayout( masterLayout );
542}
543
545{
546 return mProfile->createExpressionContext();
547}
548
554
556{
557 mCheckControlledByAtlas->setText( tr( "Controlled by %1" ).arg( string == tr( "atlas" ) ? tr( "Atlas" ) : tr( "Report" ) ) );
558}
559
561{
562 mBlockChanges++;
563
564 mProfile->setCrs( canvas->crs() );
565
566 mSpinTolerance->setValue( canvas->tolerance() );
567 mProfile->setTolerance( canvas->tolerance() );
568
569 mProfile->setDistanceUnit( canvas->distanceUnit() );
570 mDistanceUnitCombo->setCurrentIndex( mDistanceUnitCombo->findData( QVariant::fromValue( canvas->distanceUnit() ) ) );
571
572 mProfile->plot()->xAxis().setLabelSuffixPlacement( canvas->plot().xAxis().labelSuffixPlacement() );
573 mDistanceLabelsCombo->setCurrentIndex( mDistanceLabelsCombo->findData( QVariant::fromValue( canvas->plot().xAxis().labelSuffixPlacement() ) ) );
574
575 if ( const QgsCurve *curve = canvas->profileCurve() )
576 mProfile->setProfileCurve( curve->clone() );
577
578 mSpinMinDistance->setValue( canvas->plot().xMinimum() );
579 mSpinMinDistance->setClearValue( canvas->plot().xMinimum() );
580 mProfile->plot()->setXMinimum( canvas->plot().xMinimum() );
581
582 mSpinMaxDistance->setValue( canvas->plot().xMaximum() );
583 mSpinMaxDistance->setClearValue( canvas->plot().xMaximum() );
584 mProfile->plot()->setXMaximum( canvas->plot().xMaximum() );
585
586 mDistanceAxisMajorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMajor() );
587 mDistanceAxisMajorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMajor() );
588 mProfile->plot()->xAxis().setGridIntervalMajor( canvas->plot().xAxis().gridIntervalMajor() );
589
590 mDistanceAxisMinorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMinor() );
591 mDistanceAxisMinorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMinor() );
592 mProfile->plot()->xAxis().setGridIntervalMinor( canvas->plot().xAxis().gridIntervalMinor() );
593
594 mDistanceAxisLabelIntervalSpin->setValue( canvas->plot().xAxis().labelInterval() );
595 mDistanceAxisLabelIntervalSpin->setClearValue( canvas->plot().xAxis().labelInterval() );
596 mProfile->plot()->xAxis().setLabelInterval( canvas->plot().xAxis().labelInterval() );
597
598 mSpinMinElevation->setValue( canvas->plot().xMinimum() );
599 mSpinMinElevation->setClearValue( canvas->plot().yMinimum() );
600 mProfile->plot()->setYMinimum( canvas->plot().yMinimum() );
601
602 mSpinMaxElevation->setValue( canvas->plot().yMaximum() );
603 mSpinMaxElevation->setClearValue( canvas->plot().yMaximum() );
604 mProfile->plot()->setYMaximum( canvas->plot().yMaximum() );
605
606 mElevationAxisMajorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMajor() );
607 mElevationAxisMajorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMajor() );
608 mProfile->plot()->yAxis().setGridIntervalMajor( canvas->plot().yAxis().gridIntervalMajor() );
609
610 mElevationAxisMinorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMinor() );
611 mElevationAxisMinorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMinor() );
612 mProfile->plot()->yAxis().setGridIntervalMinor( canvas->plot().yAxis().gridIntervalMinor() );
613
614 mElevationAxisLabelIntervalSpin->setValue( canvas->plot().yAxis().labelInterval() );
615 mElevationAxisLabelIntervalSpin->setClearValue( canvas->plot().yAxis().labelInterval() );
616 mProfile->plot()->yAxis().setLabelInterval( canvas->plot().yAxis().labelInterval() );
617
618 QList<QgsMapLayer *> canvasLayers = canvas->layers();
619 // canvas layers are in opposite direction to what the layout item requires
620 std::reverse( canvasLayers.begin(), canvasLayers.end() );
621 mProfile->setLayers( canvasLayers );
622 const QList<QgsLayerTreeLayer *> layers = mLayerTree->findLayers();
623 for ( QgsLayerTreeLayer *layer : layers )
624 {
625 layer->setItemVisibilityChecked( mProfile->layers().contains( layer->layer() ) );
626 }
627 mLayerTree->reorderGroupLayers( mProfile->layers() );
628
629 mProfile->invalidateCache();
630 mProfile->update();
631 mBlockChanges--;
632}
633
635{
637 return false;
638
639 if ( mProfile )
640 {
641 disconnect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
642 }
643
644 mProfile = qobject_cast<QgsLayoutItemElevationProfile *>( item );
645 mItemPropertiesWidget->setItem( mProfile );
646
647 if ( mProfile )
648 {
649 connect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
650 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
651 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
652 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
653 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
654 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
655 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
656 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
657 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
658 }
659
660 setGuiElementValues();
661
662 return true;
663}
664
665void QgsLayoutElevationProfileWidget::setGuiElementValues()
666{
667 mBlockChanges++;
668
669 mSpinTolerance->setValue( mProfile->tolerance() );
670 mCheckControlledByAtlas->setChecked( mProfile->atlasDriven() );
671
672 mSpinMinDistance->setValue( mProfile->plot()->xMinimum() );
673 mSpinMaxDistance->setValue( mProfile->plot()->xMaximum() );
674 mSpinMinElevation->setValue( mProfile->plot()->yMinimum() );
675 mSpinMaxElevation->setValue( mProfile->plot()->yMaximum() );
676
677 if ( mProfile->plot()->xAxis().gridMajorSymbol() )
678 mDistanceAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMajorSymbol()->clone() );
679 if ( mProfile->plot()->xAxis().gridMinorSymbol() )
680 mDistanceAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMinorSymbol()->clone() );
681 if ( mProfile->plot()->yAxis().gridMajorSymbol() )
682 mElevationAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMajorSymbol()->clone() );
683 if ( mProfile->plot()->yAxis().gridMinorSymbol() )
684 mElevationAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMinorSymbol()->clone() );
685
686 mDistanceAxisLabelFontButton->setTextFormat( mProfile->plot()->xAxis().textFormat() );
687 mElevationAxisLabelFontButton->setTextFormat( mProfile->plot()->yAxis().textFormat() );
688
689 mDistanceUnitCombo->setCurrentIndex( mDistanceUnitCombo->findData( QVariant::fromValue( mProfile->distanceUnit() ) ) );
690 mDistanceLabelsCombo->setCurrentIndex( mDistanceLabelsCombo->findData( QVariant::fromValue( mProfile->plot()->xAxis().labelSuffixPlacement() ) ) );
691
692 mDistanceAxisMajorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMajor() );
693 mDistanceAxisMinorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMinor() );
694 mDistanceAxisLabelIntervalSpin->setValue( mProfile->plot()->xAxis().labelInterval() );
695
696 mElevationAxisMajorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMajor() );
697 mElevationAxisMinorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMinor() );
698 mElevationAxisLabelIntervalSpin->setValue( mProfile->plot()->yAxis().labelInterval() );
699
700 if ( mProfile->plot()->chartBackgroundSymbol() )
701 mChartBackgroundSymbolButton->setSymbol( mProfile->plot()->chartBackgroundSymbol()->clone() );
702 if ( mProfile->plot()->chartBorderSymbol() )
703 mChartBorderSymbolButton->setSymbol( mProfile->plot()->chartBorderSymbol()->clone() );
704
705 mSpinLeftMargin->setValue( mProfile->plot()->margins().left() );
706 mSpinRightMargin->setValue( mProfile->plot()->margins().right() );
707 mSpinTopMargin->setValue( mProfile->plot()->margins().top() );
708 mSpinBottomMargin->setValue( mProfile->plot()->margins().bottom() );
709
710 const QList<QgsLayerTreeLayer *> layers = mLayerTree->findLayers();
711 for ( QgsLayerTreeLayer *layer : layers )
712 {
713 layer->setItemVisibilityChecked( mProfile->layers().contains( layer->layer() ) );
714 }
715 mLayerTree->reorderGroupLayers( mProfile->layers() );
716
717 updateDataDefinedButton( mDDBtnTolerance );
718 updateDataDefinedButton( mDDBtnMinDistance );
719 updateDataDefinedButton( mDDBtnMaxDistance );
720 updateDataDefinedButton( mDDBtnMinElevation );
721 updateDataDefinedButton( mDDBtnMaxElevation );
722 updateDataDefinedButton( mDDBtnDistanceMajorInterval );
723 updateDataDefinedButton( mDDBtnDistanceMinorInterval );
724 updateDataDefinedButton( mDDBtnDistanceLabelInterval );
725 updateDataDefinedButton( mDDBtnElevationMajorInterval );
726 updateDataDefinedButton( mDDBtnElevationMinorInterval );
727 updateDataDefinedButton( mDDBtnElevationLabelInterval );
728 updateDataDefinedButton( mDDBtnLeftMargin );
729 updateDataDefinedButton( mDDBtnRightMargin );
730 updateDataDefinedButton( mDDBtnTopMargin );
731 updateDataDefinedButton( mDDBtnBottomMargin );
732
733 mBlockChanges--;
734}
735
736void QgsLayoutElevationProfileWidget::updateItemLayers()
737{
738 if ( mBlockChanges )
739 return;
740
741 QList<QgsMapLayer *> layers;
742 const QList<QgsMapLayer *> layerOrder = mLayerTree->layerOrder();
743 layers.reserve( layerOrder.size() );
744 for ( QgsMapLayer *layer : layerOrder )
745 {
746 if ( mLayerTree->findLayer( layer )->isVisible() )
747 layers << layer;
748 }
749
750 mProfile->setLayers( layers );
751 mProfile->update();
752}
753
754void QgsLayoutElevationProfileWidget::layoutAtlasToggled( bool atlasEnabled )
755{
756 if ( atlasEnabled && mProfile && mProfile->layout() && mProfile->layout()->reportContext().layer()
757 && mProfile->layout()->reportContext().layer()->geometryType() == Qgis::GeometryType::Line )
758 {
759 mCheckControlledByAtlas->setEnabled( true );
760 }
761 else
762 {
763 mCheckControlledByAtlas->setEnabled( false );
764 mCheckControlledByAtlas->setChecked( false );
765 }
766}
767
768void QgsLayoutElevationProfileWidget::atlasLayerChanged( QgsVectorLayer *layer )
769{
770 if ( !layer || layer->geometryType() != Qgis::GeometryType::Line )
771 {
772 //non-line layer, disable atlas control
773 mCheckControlledByAtlas->setChecked( false );
774 mCheckControlledByAtlas->setEnabled( false );
775 return;
776 }
777 else
778 {
779 mCheckControlledByAtlas->setEnabled( true );
780 }
781}
PlotAxisSuffixPlacement
Placement options for suffixes in the labels for axis of plots.
Definition qgis.h:3140
@ FirstAndLastLabels
Place suffix after the first and last label values only.
@ EveryLabel
Place suffix after every value label.
@ FirstLabel
Place suffix after the first label value only.
@ LastLabel
Place suffix after the last label value only.
@ NoLabels
Do not place suffixes.
DistanceUnit
Units of distance.
Definition qgis.h:4722
@ Feet
Imperial feet.
@ Centimeters
Centimeters.
@ Millimeters
Millimeters.
@ Miles
Terrestrial miles.
@ Yards
Imperial yards.
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ NauticalMiles
Nautical miles.
@ Kilometers
Kilometers.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
@ Line
Line symbol.
@ Fill
Fill symbol.
double yMaximum() const
Returns the maximum value of the y axis.
Definition qgsplot.h:383
QgsPlotAxis & xAxis()
Returns a reference to the plot's x axis.
Definition qgsplot.h:397
double xMaximum() const
Returns the maximum value of the x axis.
Definition qgsplot.h:369
double xMinimum() const
Returns the minimum value of the x axis.
Definition qgsplot.h:341
QgsPlotAxis & yAxis()
Returns a reference to the plot's y axis.
Definition qgsplot.h:411
double yMinimum() const
Returns the minimum value of the y axis.
Definition qgsplot.h:355
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Abstract base class for curved geometry type.
Definition qgscurve.h:35
A canvas for elevation profiles.
QgsCurve * profileCurve() const
Returns the profile curve.
QgsCoordinateReferenceSystem crs() const override
Returns the coordinate reference system (CRS) for map coordinates used by the canvas.
QList< QgsMapLayer * > layers() const
Returns the list of layers included in the profile.
const Qgs2DPlot & plot() const
Returns a reference to the 2D plot used by the widget.
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit used by the canvas.
double tolerance() const
Returns the tolerance of the profile (in crs() units).
A layer tree view for elevation profiles.
void populateInitialLayers(QgsProject *project)
Initially populates the tree view using layers from a project.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
void changed()
Emitted when the widget's text format settings are changed.
@ HigDialogTitleIsTitleCase
Dialog titles should be title case.
Definition qgsgui.h:270
static QgsGui::HigFlags higFlags()
Returns the platform's HIG flags.
Definition qgsgui.cpp:234
Layer tree node points to a map layer.
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
Listens to the updates in map layer registry and does changes in layer tree.
Namespace with helper functions for layer tree operations.
void layerOrderChanged()
Emitted when the layer order has changed.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool enabled)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
A widget for layout elevation profile item settings.
void setReportTypeString(const QString &string) override
Sets the string to use to describe the current report type (e.g.
void copySettingsFromProfileCanvas(QgsElevationProfileCanvas *canvas)
Copies selected settings from a elevation profile canvas.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
static std::function< void(QgsLayoutElevationProfileWidget *, QMenu *)> sBuildCopyMenuFunction
QgsLayoutElevationProfileWidget(QgsLayoutItemElevationProfile *profile)
constructor
void setDesignerInterface(QgsLayoutDesignerInterface *iface) override
Sets the the layout designer interface in which the widget is being shown.
A base class for property widgets for layout items.
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Updates a previously registered data defined button to reflect the item's current properties.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsLayoutObject::DataDefinedProperty property)
Registers a data defined button, setting up its initial value, connections and description.
virtual void setDesignerInterface(QgsLayoutDesignerInterface *iface)
Sets the the layout designer interface in which the widget is being shown.
QgsLayoutAtlas * layoutAtlas() const
Returns the atlas for the layout (if available)
A layout item subclass for elevation profile plots.
A widget for controlling the common properties of layout items (e.g.
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout associated with the item.
void setItem(QgsLayoutItem *item)
Sets the layout item.
@ LayoutElevationProfile
Elevation profile item.
Base class for graphical items within a QgsLayout.
@ UndoElevationProfileElevationMajorGridlines
Change elevation profile elevation axis major gridlines.
@ UndoElevationProfileMaximumDistance
Change elevation profile maximum distance.
@ UndoElevationProfileChartBackground
Change elevation profile chart background.
@ UndoElevationProfileDistanceMinorGridlines
Change elevation profile distance axis minor gridlines.
@ UndoMarginTop
Top margin.
@ UndoElevationProfileChartBorder
Change elevation profile chart border.
@ UndoElevationProfileMaximumElevation
Change elevation profile maximum elevation.
@ UndoMarginLeft
Left margin.
@ UndoMarginRight
Right margin.
@ UndoElevationProfileTolerance
Change elevation profile distance tolerance.
@ UndoElevationProfileElevationFormat
Change elevation profile elevation axis number format.
@ UndoElevationProfileMinimumElevation
Change elevation profile minimum elevation.
@ UndoElevationProfileDistanceLabels
Change elevation profile distance axis label interval.
@ UndoMarginBottom
Bottom margin.
@ UndoElevationProfileElevationFont
Change elevation profile elevation axis number font.
@ UndoElevationProfileDistanceFormat
Change elevation profile distance axis number format.
@ UndoElevationProfileElevationMinorGridlines
Change elevation profile elevation axis minor gridlines.
@ UndoElevationProfileDistanceFont
Change elevation profile distance axis number font.
@ UndoElevationProfileElevationLabels
Change elevation profile elevation axis label interval.
@ UndoElevationProfileDistanceMajorGridlines
Change elevation profile distance axis major gridlines.
@ UndoElevationProfileMinimumDistance
Change elevation profile minimum distance.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
@ ElevationProfileMaximumDistance
Maximum distance value for elevation profile.
@ ElevationProfileElevationMinorInterval
Minor grid line interval for elevation profile elevation axis.
@ ElevationProfileDistanceMinorInterval
Minor grid line interval for elevation profile distance axis.
@ ElevationProfileMinimumDistance
Minimum distance value for elevation profile.
@ ElevationProfileMaximumElevation
Maximum elevation value for elevation profile.
@ ElevationProfileDistanceLabelInterval
Label interval for elevation profile distance axis.
@ ElevationProfileTolerance
Tolerance distance for elevation profiles.
@ ElevationProfileMinimumElevation
Minimum elevation value for elevation profile.
@ ElevationProfileElevationLabelInterval
Label interval for elevation profile elevation axis.
@ ElevationProfileDistanceMajorInterval
Major grid line interval for elevation profile distance axis.
@ ElevationProfileElevationMajorInterval
Major grid line interval for elevation profile elevation axis.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
A line symbol type, for rendering LineString and MultiLineString geometries.
Base class for all map layer types.
Definition qgsmaplayer.h:76
The QgsMargins class defines the four margins of a rectangle.
Definition qgsmargins.h:37
void setBottom(double bottom)
Sets the bottom margin to bottom.
Definition qgsmargins.h:113
void setLeft(double left)
Sets the left margin to left.
Definition qgsmargins.h:95
void setRight(double right)
Sets the right margin to right.
Definition qgsmargins.h:107
void setTop(double top)
Sets the top margin to top.
Definition qgsmargins.h:101
Interface for master layout type objects, such as print layouts and reports.
A widget which allows choice of numeric formats and the properties of them.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
void changed()
Emitted whenever the format configured55 in the widget is changed.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
double gridIntervalMinor() const
Returns the interval of minor grid lines for the axis.
Definition qgsplot.h:99
double gridIntervalMajor() const
Returns the interval of major grid lines for the axis.
Definition qgsplot.h:113
double labelInterval() const
Returns the interval of labels for the axis.
Definition qgsplot.h:127
Qgis::PlotAxisSuffixPlacement labelSuffixPlacement() const
Returns the placement for the axis label suffixes.
Definition qgsplot.cpp:124
static QgsFillSymbol * chartBorderSymbol()
Returns the default fill symbol to use for the chart area border.
Definition qgsplot.cpp:805
static QgsLineSymbol * axisGridMinorSymbol()
Returns the default line symbol to use for axis minor grid lines.
Definition qgsplot.cpp:792
static QgsFillSymbol * chartBackgroundSymbol()
Returns the default fill symbol to use for the chart area background fill.
Definition qgsplot.cpp:799
static QgsLineSymbol * axisGridMajorSymbol()
Returns the default line symbol to use for axis major grid lines.
Definition qgsplot.cpp:785
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:107
static QgsProject * instance()
Returns the QgsProject singleton instance.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
void changed()
Emitted when the symbol's settings are changed.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.