QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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
20#include "qgslayoutitemwidget.h"
22#include "qgsplot.h"
23#include "qgsfillsymbol.h"
24#include "qgslinesymbol.h"
25#include "qgsvectorlayer.h"
27#include "qgslayout.h"
28#include "qgslayertree.h"
32#include "qgscurve.h"
33#include "qgslayoutatlas.h"
35#include <QMenu>
36
38
40 : QgsLayoutItemBaseWidget( nullptr, profile )
41 , mProfile( profile )
42 , mLayerTree( new QgsLayerTree() )
43 , mLayerTreeBridge( new QgsLayerTreeRegistryBridge( mLayerTree.get(), mProfile->layout() ? mProfile->layout()->project() : QgsProject::instance(), this ) )
44{
45 Q_ASSERT( mProfile );
46
47 setupUi( this );
48 setPanelTitle( tr( "Elevation Profile Properties" ) );
49
50 mCopyFromDockMenu = new QMenu( this );
51 connect( mCopyFromDockMenu, &QMenu::aboutToShow, this, [ = ]
52 {
53 sBuildCopyMenuFunction( this, mCopyFromDockMenu );
54 } );
55
56 connect( mActionRefresh, &QAction::triggered, this, [ = ]
57 {
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 {
85 if ( !mProfile || mBlockChanges )
86 return;
87
88 mProfile->beginCommand( tr( "Change Profile Tolerance Distance" ), QgsLayoutItem::UndoElevationProfileTolerance );
89 mProfile->setTolerance( value );
90 mProfile->invalidateCache();
91 mProfile->update();
92 mProfile->endCommand();
93 } );
94
95 connect( mCheckControlledByAtlas, &QCheckBox::toggled, this, [ = ]
96 {
97 if ( !mProfile || mBlockChanges )
98 return;
99
100 mProfile->beginCommand( tr( "Change Profile Atlas Control" ) );
101 mProfile->setAtlasDriven( mCheckControlledByAtlas->isChecked() );
102 mProfile->invalidateCache();
103 mProfile->update();
104 mProfile->endCommand();
105 } );
106
107 mSpinMinDistance->setClearValue( 0 );
108 connect( mSpinMinDistance, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
109 {
110 if ( !mProfile || mBlockChanges )
111 return;
112
113 mProfile->beginCommand( tr( "Change Profile Chart Minimum Distance" ), QgsLayoutItem::UndoElevationProfileMinimumDistance );
114 mProfile->plot()->setXMinimum( value );
115 mProfile->invalidateCache();
116 mProfile->update();
117 mProfile->endCommand();
118 } );
119
120 connect( mSpinMaxDistance, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
121 {
122 if ( !mProfile || mBlockChanges )
123 return;
124
125 mProfile->beginCommand( tr( "Change Profile Chart Maximum Distance" ), QgsLayoutItem::UndoElevationProfileMaximumDistance );
126 mProfile->plot()->setXMaximum( value );
127 mProfile->invalidateCache();
128 mProfile->update();
129 mProfile->endCommand();
130 } );
131
132 mSpinMinElevation->setClearValue( 0 );
133 connect( mSpinMinElevation, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
134 {
135 if ( !mProfile || mBlockChanges )
136 return;
137
138 mProfile->beginCommand( tr( "Change Profile Chart Minimum Elevation" ), QgsLayoutItem::UndoElevationProfileMinimumElevation );
139 mProfile->plot()->setYMinimum( value );
140 mProfile->invalidateCache();
141 mProfile->update();
142 mProfile->endCommand();
143 } );
144
145 connect( mSpinMaxElevation, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
146 {
147 if ( !mProfile || mBlockChanges )
148 return;
149
150 mProfile->beginCommand( tr( "Change Profile Chart Maximum Elevation" ), QgsLayoutItem::UndoElevationProfileMaximumElevation );
151 mProfile->plot()->setYMaximum( value );
152 mProfile->invalidateCache();
153 mProfile->update();
154 mProfile->endCommand();
155 } );
156
157 mDistanceAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
158 connect( mDistanceAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [ = ]
159 {
160 if ( !mProfile || mBlockChanges )
161 return;
162
163 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
164 mProfile->plot()->xAxis().setGridMajorSymbol( mDistanceAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
165 mProfile->invalidateCache();
166 mProfile->update();
167 mProfile->endCommand();
168 } );
169 mDistanceAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
170
171 mDistanceAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
172 connect( mDistanceAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [ = ]
173 {
174 if ( !mProfile || mBlockChanges )
175 return;
176
177 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
178 mProfile->plot()->xAxis().setGridMinorSymbol( mDistanceAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
179 mProfile->invalidateCache();
180 mProfile->update();
181 mProfile->endCommand();
182 } );
183 mDistanceAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
184
185 connect( mDistanceAxisMajorIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
186 {
187 if ( !mProfile || mBlockChanges )
188 return;
189
190 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
191 mProfile->plot()->xAxis().setGridIntervalMajor( value );
192 mProfile->invalidateCache();
193 mProfile->update();
194 mProfile->endCommand();
195 } );
196
197 connect( mDistanceAxisMinorIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
198 {
199 if ( !mProfile || mBlockChanges )
200 return;
201
202 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
203 mProfile->plot()->xAxis().setGridIntervalMinor( value );
204 mProfile->invalidateCache();
205 mProfile->update();
206 mProfile->endCommand();
207 } );
208
209 connect( mDistanceAxisLabelIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
210 {
211 if ( !mProfile || mBlockChanges )
212 return;
213
214 mProfile->beginCommand( tr( "Change Profile Chart Distance Label" ), QgsLayoutItem::UndoElevationProfileDistanceLabels );
215 mProfile->plot()->xAxis().setLabelInterval( value );
216 mProfile->invalidateCache();
217 mProfile->update();
218 mProfile->endCommand();
219 } );
220
221 mElevationAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
222 connect( mElevationAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [ = ]
223 {
224 if ( !mProfile || mBlockChanges )
225 return;
226
227 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
228 mProfile->plot()->yAxis().setGridMajorSymbol( mElevationAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
229 mProfile->invalidateCache();
230 mProfile->update();
231 mProfile->endCommand();
232 } );
233 mElevationAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
234
235 mElevationAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
236 connect( mElevationAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [ = ]
237 {
238 if ( !mProfile || mBlockChanges )
239 return;
240
241 mProfile->beginCommand( tr( "Change Profile Chart Elevation Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
242 mProfile->plot()->yAxis().setGridMinorSymbol( mElevationAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
243 mProfile->invalidateCache();
244 mProfile->update();
245 mProfile->endCommand();
246 } );
247 mElevationAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
248
249 connect( mElevationAxisLabelIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
250 {
251 if ( !mProfile || mBlockChanges )
252 return;
253
254 mProfile->beginCommand( tr( "Change Profile Chart Elevation Label" ), QgsLayoutItem::UndoElevationProfileElevationLabels );
255 mProfile->plot()->yAxis().setLabelInterval( value );
256 mProfile->invalidateCache();
257 mProfile->update();
258 mProfile->endCommand();
259 } );
260
261 connect( mElevationAxisMajorIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
262 {
263 if ( !mProfile || mBlockChanges )
264 return;
265
266 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
267 mProfile->plot()->yAxis().setGridIntervalMajor( value );
268 mProfile->invalidateCache();
269 mProfile->update();
270 mProfile->endCommand();
271 } );
272
273 connect( mElevationAxisMinorIntervalSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
274 {
275 if ( !mProfile || mBlockChanges )
276 return;
277
278 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
279 mProfile->plot()->yAxis().setGridIntervalMinor( value );
280 mProfile->invalidateCache();
281 mProfile->update();
282 mProfile->endCommand();
283 } );
284
285 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
286 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [ = ]
287 {
288 if ( !mProfile || mBlockChanges )
289 return;
290
291 mProfile->beginCommand( tr( "Change Profile Chart Background" ), QgsLayoutItem::UndoElevationProfileChartBackground );
292 mProfile->plot()->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
293 mProfile->invalidateCache();
294 mProfile->update();
295 mProfile->endCommand();
296 } );
297 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
298
299 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
300 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [ = ]
301 {
302 if ( !mProfile || mBlockChanges )
303 return;
304
305 mProfile->beginCommand( tr( "Change Profile Chart Border" ), QgsLayoutItem::UndoElevationProfileChartBorder );
306 mProfile->plot()->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
307 mProfile->invalidateCache();
308 mProfile->update();
309 mProfile->endCommand();
310 } );
311 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
312
313 connect( mDistanceAxisLabelFormatButton, &QPushButton::clicked, this, [ = ]
314 {
315 if ( !mProfile || mBlockChanges )
316 return;
317
319 widget->setPanelTitle( tr( "Distance Number Format" ) );
320 widget->setFormat( mProfile->plot()->xAxis().numericFormat() );
321 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [ = ]
322 {
323 mProfile->beginCommand( tr( "Change Profile Chart Distance Format" ), QgsLayoutItem::UndoElevationProfileDistanceFormat );
324 mProfile->plot()->xAxis().setNumericFormat( widget->format() );
325 mProfile->invalidateCache();
326 mProfile->endCommand();
327 mProfile->update();
328 } );
329 openPanel( widget );
330 } );
331
332 connect( mElevationAxisLabelFormatButton, &QPushButton::clicked, this, [ = ]
333 {
334 if ( !mProfile || mBlockChanges )
335 return;
336
338 widget->setPanelTitle( tr( "Elevation Number Format" ) );
339 widget->setFormat( mProfile->plot()->yAxis().numericFormat() );
340 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [ = ]
341 {
342 mProfile->beginCommand( tr( "Change Profile Chart Elevation Format" ), QgsLayoutItem::UndoElevationProfileElevationFormat );
343 mProfile->plot()->yAxis().setNumericFormat( widget->format() );
344 mProfile->invalidateCache();
345 mProfile->endCommand();
346 mProfile->update();
347 } );
348 openPanel( widget );
349 } );
350
351 mDistanceAxisLabelFontButton->setDialogTitle( tr( "Distance Label Font" ) );
352 mElevationAxisLabelFontButton->setDialogTitle( tr( "Elevation Label Font" ) );
353 mDistanceAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
354 mElevationAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
355
356 connect( mDistanceAxisLabelFontButton, &QgsFontButton::changed, this, [ = ]
357 {
358 if ( !mProfile || mBlockChanges )
359 return;
360
361 mProfile->beginCommand( tr( "Change Profile Chart Distance Font" ), QgsLayoutItem::UndoElevationProfileDistanceFont );
362 mProfile->plot()->xAxis().setTextFormat( mDistanceAxisLabelFontButton->textFormat() );
363 mProfile->invalidateCache();
364 mProfile->endCommand();
365 mProfile->update();
366 } );
367
368 connect( mElevationAxisLabelFontButton, &QgsFontButton::changed, this, [ = ]
369 {
370 if ( !mProfile || mBlockChanges )
371 return;
372
373 mProfile->beginCommand( tr( "Change Profile Chart Elevation Font" ), QgsLayoutItem::UndoElevationProfileElevationFont );
374 mProfile->plot()->yAxis().setTextFormat( mElevationAxisLabelFontButton->textFormat() );
375 mProfile->invalidateCache();
376 mProfile->endCommand();
377 mProfile->update();
378 } );
379
380 mSpinLeftMargin->setClearValue( 0 );
381 connect( mSpinLeftMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
382 {
383 if ( !mProfile || mBlockChanges )
384 return;
385
386 mProfile->beginCommand( tr( "Change Profile Chart Left Margin" ), QgsLayoutItem::UndoMarginLeft );
387 QgsMargins margins = mProfile->plot()->margins();
388 margins.setLeft( value );
389 mProfile->plot()->setMargins( margins );
390 mProfile->invalidateCache();
391 mProfile->update();
392 mProfile->endCommand();
393 } );
394
395 mSpinRightMargin->setClearValue( 0 );
396 connect( mSpinRightMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
397 {
398 if ( !mProfile || mBlockChanges )
399 return;
400
401 mProfile->beginCommand( tr( "Change Profile Chart Right Margin" ), QgsLayoutItem::UndoMarginRight );
402 QgsMargins margins = mProfile->plot()->margins();
403 margins.setRight( value );
404 mProfile->plot()->setMargins( margins );
405 mProfile->invalidateCache();
406 mProfile->update();
407 mProfile->endCommand();
408 } );
409
410 mSpinTopMargin->setClearValue( 0 );
411 connect( mSpinTopMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
412 {
413 if ( !mProfile || mBlockChanges )
414 return;
415
416 mProfile->beginCommand( tr( "Change Profile Chart Top Margin" ), QgsLayoutItem::UndoMarginTop );
417 QgsMargins margins = mProfile->plot()->margins();
418 margins.setTop( value );
419 mProfile->plot()->setMargins( margins );
420 mProfile->invalidateCache();
421 mProfile->update();
422 mProfile->endCommand();
423 } );
424
425 mSpinBottomMargin->setClearValue( 0 );
426 connect( mSpinBottomMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
427 {
428 if ( !mProfile || mBlockChanges )
429 return;
430
431 mProfile->beginCommand( tr( "Change Profile Chart Bottom Margin" ), QgsLayoutItem::UndoMarginBottom );
432 QgsMargins margins = mProfile->plot()->margins();
433 margins.setBottom( value );
434 mProfile->plot()->setMargins( margins );
435 mProfile->invalidateCache();
436 mProfile->update();
437 mProfile->endCommand();
438 } );
439
455
456 mLayerTreeView = new QgsElevationProfileLayerTreeView( mLayerTree.get() );
457
458 QVBoxLayout *vl = new QVBoxLayout();
459 vl->setContentsMargins( 0, 0, 0, 0 );
460 vl->addWidget( mLayerTreeView );
461 mTreeViewContainer->setLayout( vl );
462
463 mBlockChanges++;
464 mLayerTreeView->populateInitialLayers( mProfile->layout() && mProfile->layout()->project() ? mProfile->layout()->project() : QgsProject::instance() );
465 mBlockChanges--;
466
467 setGuiElementValues();
468
469 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
470 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
471 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
472 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
473 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
474 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
475 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
476 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
477
478 mDistanceAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
479 mDistanceAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
480 mElevationAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
481 mElevationAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
482 mDistanceAxisLabelFontButton->setLayer( coverageLayer() );
483 mElevationAxisLabelFontButton->setLayer( coverageLayer() );
484 mChartBackgroundSymbolButton->setLayer( coverageLayer() );
485 mChartBorderSymbolButton->setLayer( coverageLayer() );
486
487 if ( mProfile->layout() )
488 {
489 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, this, [ = ]( QgsVectorLayer * layer )
490 {
491 mDistanceAxisMajorLinesSymbolButton->setLayer( layer );
492 mDistanceAxisMinorLinesSymbolButton->setLayer( layer );
493 mElevationAxisMajorLinesSymbolButton->setLayer( layer );
494 mElevationAxisMinorLinesSymbolButton->setLayer( layer );
495 mDistanceAxisLabelFontButton->setLayer( layer );
496 mElevationAxisLabelFontButton->setLayer( layer );
497 mChartBackgroundSymbolButton->setLayer( layer );
498 mChartBorderSymbolButton->setLayer( layer );
499 } );
500
501 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged,
502 this, &QgsLayoutElevationProfileWidget::atlasLayerChanged );
503 }
504
505 if ( QgsLayoutAtlas *atlas = layoutAtlas() )
506 {
507 connect( atlas, &QgsLayoutAtlas::toggled, this, &QgsLayoutElevationProfileWidget::layoutAtlasToggled );
508 layoutAtlasToggled( atlas->enabled() );
509 }
510}
511
513
515{
516 if ( mItemPropertiesWidget )
517 mItemPropertiesWidget->setMasterLayout( masterLayout );
518}
519
521{
522 return mProfile->createExpressionContext();
523}
524
526{
527 mInterface = iface;
529}
530
532{
533 mCheckControlledByAtlas->setText( tr( "Controlled by %1" ).arg( string == tr( "atlas" ) ? tr( "Atlas" ) : tr( "Report" ) ) );
534}
535
537{
538 mBlockChanges++;
539
540 mProfile->setCrs( canvas->crs() );
541
542 mSpinTolerance->setValue( canvas->tolerance() );
543 mProfile->setTolerance( canvas->tolerance() );
544
545 if ( const QgsCurve *curve = canvas->profileCurve() )
546 mProfile->setProfileCurve( curve->clone() );
547
548 mSpinMinDistance->setValue( canvas->plot().xMinimum() );
549 mSpinMinDistance->setClearValue( canvas->plot().xMinimum() );
550 mProfile->plot()->setXMinimum( canvas->plot().xMinimum() );
551
552 mSpinMaxDistance->setValue( canvas->plot().xMaximum() );
553 mSpinMaxDistance->setClearValue( canvas->plot().xMaximum() );
554 mProfile->plot()->setXMaximum( canvas->plot().xMaximum() );
555
556 mDistanceAxisMajorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMajor() );
557 mDistanceAxisMajorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMajor() );
558 mProfile->plot()->xAxis().setGridIntervalMajor( canvas->plot().xAxis().gridIntervalMajor() );
559
560 mDistanceAxisMinorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMinor() );
561 mDistanceAxisMinorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMinor() );
562 mProfile->plot()->xAxis().setGridIntervalMinor( canvas->plot().xAxis().gridIntervalMinor() );
563
564 mDistanceAxisLabelIntervalSpin->setValue( canvas->plot().xAxis().labelInterval() );
565 mDistanceAxisLabelIntervalSpin->setClearValue( canvas->plot().xAxis().labelInterval() );
566 mProfile->plot()->xAxis().setLabelInterval( canvas->plot().xAxis().labelInterval() );
567
568 mSpinMinElevation->setValue( canvas->plot().xMinimum() );
569 mSpinMinElevation->setClearValue( canvas->plot().yMinimum() );
570 mProfile->plot()->setYMinimum( canvas->plot().yMinimum() );
571
572 mSpinMaxElevation->setValue( canvas->plot().yMaximum() );
573 mSpinMaxElevation->setClearValue( canvas->plot().yMaximum() );
574 mProfile->plot()->setYMaximum( canvas->plot().yMaximum() );
575
576 mElevationAxisMajorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMajor() );
577 mElevationAxisMajorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMajor() );
578 mProfile->plot()->yAxis().setGridIntervalMajor( canvas->plot().yAxis().gridIntervalMajor() );
579
580 mElevationAxisMinorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMinor() );
581 mElevationAxisMinorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMinor() );
582 mProfile->plot()->yAxis().setGridIntervalMinor( canvas->plot().yAxis().gridIntervalMinor() );
583
584 mElevationAxisLabelIntervalSpin->setValue( canvas->plot().yAxis().labelInterval() );
585 mElevationAxisLabelIntervalSpin->setClearValue( canvas->plot().yAxis().labelInterval() );
586 mProfile->plot()->yAxis().setLabelInterval( canvas->plot().yAxis().labelInterval() );
587
588 QList<QgsMapLayer *> canvasLayers = canvas->layers();
589 // canvas layers are in opposite direction to what the layout item requires
590 std::reverse( canvasLayers.begin(), canvasLayers.end() );
591 mProfile->setLayers( canvasLayers );
592 const QList<QgsLayerTreeLayer *> layers = mLayerTree->findLayers();
593 for ( QgsLayerTreeLayer *layer : layers )
594 {
595 layer->setItemVisibilityChecked( mProfile->layers().contains( layer->layer() ) );
596 }
597 mLayerTree->reorderGroupLayers( mProfile->layers() );
598
599 mProfile->invalidateCache();
600 mProfile->update();
601 mBlockChanges--;
602}
603
605{
607 return false;
608
609 if ( mProfile )
610 {
611 disconnect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
612 }
613
614 mProfile = qobject_cast< QgsLayoutItemElevationProfile * >( item );
615 mItemPropertiesWidget->setItem( mProfile );
616
617 if ( mProfile )
618 {
619 connect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
620 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
621 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
622 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
623 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
624 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
625 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
626 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
627 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
628 }
629
630 setGuiElementValues();
631
632 return true;
633}
634
635void QgsLayoutElevationProfileWidget::setGuiElementValues()
636{
637 mBlockChanges++;
638
639 mSpinTolerance->setValue( mProfile->tolerance() );
640 mCheckControlledByAtlas->setChecked( mProfile->atlasDriven() );
641
642 mSpinMinDistance->setValue( mProfile->plot()->xMinimum() );
643 mSpinMaxDistance->setValue( mProfile->plot()->xMaximum() );
644 mSpinMinElevation->setValue( mProfile->plot()->yMinimum() );
645 mSpinMaxElevation->setValue( mProfile->plot()->yMaximum() );
646
647 if ( mProfile->plot()->xAxis().gridMajorSymbol() )
648 mDistanceAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMajorSymbol()->clone() );
649 if ( mProfile->plot()->xAxis().gridMinorSymbol() )
650 mDistanceAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMinorSymbol()->clone() );
651 if ( mProfile->plot()->yAxis().gridMajorSymbol() )
652 mElevationAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMajorSymbol()->clone() );
653 if ( mProfile->plot()->yAxis().gridMajorSymbol() )
654 mElevationAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMinorSymbol()->clone() );
655
656 mDistanceAxisLabelFontButton->setTextFormat( mProfile->plot()->xAxis().textFormat() );
657 mElevationAxisLabelFontButton->setTextFormat( mProfile->plot()->yAxis().textFormat() );
658
659 mDistanceAxisMajorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMajor() );
660 mDistanceAxisMinorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMinor() );
661 mDistanceAxisLabelIntervalSpin->setValue( mProfile->plot()->xAxis().labelInterval() );
662
663 mElevationAxisMajorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMajor() );
664 mElevationAxisMinorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMinor() );
665 mElevationAxisLabelIntervalSpin->setValue( mProfile->plot()->yAxis().labelInterval() );
666
667 if ( mProfile->plot()->chartBackgroundSymbol() )
668 mChartBackgroundSymbolButton->setSymbol( mProfile->plot()->chartBackgroundSymbol()->clone() );
669 if ( mProfile->plot()->chartBorderSymbol() )
670 mChartBorderSymbolButton->setSymbol( mProfile->plot()->chartBorderSymbol()->clone() );
671
672 mSpinLeftMargin->setValue( mProfile->plot()->margins().left() );
673 mSpinRightMargin->setValue( mProfile->plot()->margins().right() );
674 mSpinTopMargin->setValue( mProfile->plot()->margins().top() );
675 mSpinBottomMargin->setValue( mProfile->plot()->margins().bottom() );
676
677 const QList<QgsLayerTreeLayer *> layers = mLayerTree->findLayers();
678 for ( QgsLayerTreeLayer *layer : layers )
679 {
680 layer->setItemVisibilityChecked( mProfile->layers().contains( layer->layer() ) );
681 }
682 mLayerTree->reorderGroupLayers( mProfile->layers() );
683
684 updateDataDefinedButton( mDDBtnTolerance );
685 updateDataDefinedButton( mDDBtnMinDistance );
686 updateDataDefinedButton( mDDBtnMaxDistance );
687 updateDataDefinedButton( mDDBtnMinElevation );
688 updateDataDefinedButton( mDDBtnMaxElevation );
689 updateDataDefinedButton( mDDBtnDistanceMajorInterval );
690 updateDataDefinedButton( mDDBtnDistanceMinorInterval );
691 updateDataDefinedButton( mDDBtnDistanceLabelInterval );
692 updateDataDefinedButton( mDDBtnElevationMajorInterval );
693 updateDataDefinedButton( mDDBtnElevationMinorInterval );
694 updateDataDefinedButton( mDDBtnElevationLabelInterval );
695 updateDataDefinedButton( mDDBtnLeftMargin );
696 updateDataDefinedButton( mDDBtnRightMargin );
697 updateDataDefinedButton( mDDBtnTopMargin );
698 updateDataDefinedButton( mDDBtnBottomMargin );
699
700 mBlockChanges--;
701}
702
703void QgsLayoutElevationProfileWidget::updateItemLayers()
704{
705 if ( mBlockChanges )
706 return;
707
708 QList<QgsMapLayer *> layers;
709 const QList< QgsMapLayer * > layerOrder = mLayerTree->layerOrder();
710 layers.reserve( layerOrder.size() );
711 for ( QgsMapLayer *layer : layerOrder )
712 {
713 if ( mLayerTree->findLayer( layer )->isVisible() )
714 layers << layer;
715 }
716
717 mProfile->setLayers( layers );
718 mProfile->update();
719}
720
721void QgsLayoutElevationProfileWidget::layoutAtlasToggled( bool atlasEnabled )
722{
723 if ( atlasEnabled &&
724 mProfile && mProfile->layout() && mProfile->layout()->reportContext().layer()
725 && mProfile->layout()->reportContext().layer()->geometryType() == Qgis::GeometryType::Line )
726 {
727 mCheckControlledByAtlas->setEnabled( true );
728 }
729 else
730 {
731 mCheckControlledByAtlas->setEnabled( false );
732 mCheckControlledByAtlas->setChecked( false );
733 }
734}
735
736void QgsLayoutElevationProfileWidget::atlasLayerChanged( QgsVectorLayer *layer )
737{
738 if ( !layer || layer->geometryType() != Qgis::GeometryType::Line )
739 {
740 //non-line layer, disable atlas control
741 mCheckControlledByAtlas->setChecked( false );
742 mCheckControlledByAtlas->setEnabled( false );
743 return;
744 }
745 else
746 {
747 mCheckControlledByAtlas->setEnabled( true );
748 }
749}
@ Line
Line symbol.
@ Fill
Fill symbol.
double yMaximum() const
Returns the maximum value of the y axis.
Definition: qgsplot.h:347
QgsPlotAxis & xAxis()
Returns a reference to the plot's x axis.
Definition: qgsplot.h:361
double xMaximum() const
Returns the maximum value of the x axis.
Definition: qgsplot.h:333
double xMinimum() const
Returns the minimum value of the x axis.
Definition: qgsplot.h:305
QgsPlotAxis & yAxis()
Returns a reference to the plot's y axis.
Definition: qgsplot.h:375
double yMinimum() const
Returns the minimum value of the y axis.
Definition: qgsplot.h:319
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:36
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.
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.
Definition: qgsfillsymbol.h:30
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
Definition: qgsfontbutton.h:62
void changed()
Emitted when the widget's text format settings are changed.
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.
Definition: qgslayertree.h:33
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)
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.
static std::function< void(QgsLayoutElevationProfileWidget *, QMenu *) > sBuildCopyMenuFunction
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.
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 (since QGIS 3.30)
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 (since QGIS 3.30)
@ UndoElevationProfileChartBorder
Change elevation profile chart border.
@ UndoElevationProfileMaximumElevation
Change elevation profile maximum elevation.
@ UndoMarginLeft
Left margin (since QGIS 3.30)
@ UndoMarginRight
Right margin (since QGIS 3.30)
@ 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 (since QGIS 3.30)
@ 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.
@ ElevationProfileTolerance
Tolerance distance for elevation profiles (since QGIS 3.30)
@ ElevationProfileElevationLabelInterval
Label interval for elevation profile elevation axis (since QGIS 3.30)
@ ElevationProfileDistanceMajorInterval
Major grid line interval for elevation profile distance axis (since QGIS 3.30)
@ MarginTop
Top margin (since QGIS 3.30)
@ ElevationProfileDistanceLabelInterval
Label interval for elevation profile distance axis (since QGIS 3.30)
@ ElevationProfileElevationMinorInterval
Minor grid line interval for elevation profile elevation axis (since QGIS 3.30)
@ MarginLeft
Left margin (since QGIS 3.30)
@ ElevationProfileMaximumDistance
Maximum distance value for elevation profile (since QGIS 3.30)
@ MarginRight
Right margin (since QGIS 3.30)
@ ElevationProfileMinimumElevation
Minimum elevation value for elevation profile (since QGIS 3.30)
@ ElevationProfileElevationMajorInterval
Major grid line interval for elevation profile elevation axis (since QGIS 3.30)
@ ElevationProfileMinimumDistance
Minimum distance value for elevation profile (since QGIS 3.30)
@ MarginBottom
Bottom margin (since QGIS 3.30)
@ ElevationProfileDistanceMinorInterval
Minor grid line interval for elevation profile distance axis (since QGIS 3.30)
@ ElevationProfileMaximumElevation
Maximum elevation value for elevation profile (since QGIS 3.30)
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
Base class for all map layer types.
Definition: qgsmaplayer.h:73
The QgsMargins class defines the four margins of a rectangle.
Definition: qgsmargins.h:38
void setBottom(double bottom)
Sets the bottom margin to bottom.
Definition: qgsmargins.h:114
void setLeft(double left)
Sets the left margin to left.
Definition: qgsmargins.h:96
void setRight(double right)
Sets the right margin to right.
Definition: qgsmargins.h:108
void setTop(double top)
Sets the top margin to top.
Definition: qgsmargins.h:102
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:104
double gridIntervalMajor() const
Returns the interval of major grid lines for the axis.
Definition: qgsplot.h:118
double labelInterval() const
Returns the interval of labels for the axis.
Definition: qgsplot.h:132
static QgsFillSymbol * chartBorderSymbol()
Returns the default fill symbol to use for the chart area border.
Definition: qgsplot.cpp:609
static QgsLineSymbol * axisGridMinorSymbol()
Returns the default line symbol to use for axis minor grid lines.
Definition: qgsplot.cpp:596
static QgsFillSymbol * chartBackgroundSymbol()
Returns the default fill symbol to use for the chart area background fill.
Definition: qgsplot.cpp:603
static QgsLineSymbol * axisGridMajorSymbol()
Returns the default line symbol to use for axis major grid lines.
Definition: qgsplot.cpp:589
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:105
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:477
void changed()
Emitted when the symbol's settings are changed.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.