QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgslayoutscalebarwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutscalebarwidget.cpp
3  -----------------------------
4  begin : 11 June 2008
5  copyright : (C) 2008 by Marco Hugentobler
6  email : marco dot hugentobler at karto dot baug dot ethz dot ch
7  ***************************************************************************/
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
18 #include "qgslayoutitemmap.h"
19 #include "qgslayoutitemscalebar.h"
21 #include "qgslayout.h"
22 #include "qgsguiutils.h"
23 #include "qgsvectorlayer.h"
25 #include "qgslayoutundostack.h"
26 #include "qgsfillsymbol.h"
27 #include "qgslinesymbol.h"
28 
29 #include <QColorDialog>
30 #include <QFontDialog>
31 #include <QWidget>
32 
34  : QgsLayoutItemBaseWidget( nullptr, scaleBar )
35  , mScalebar( scaleBar )
36 {
37  setupUi( this );
38 
39  mNumberOfSubdivisionsSpinBox->setClearValue( 1 );
40 
41  connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mHeightSpinBox_valueChanged );
42  connect( mSegmentSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mSegmentSizeSpinBox_valueChanged );
43  connect( mSegmentsLeftSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mSegmentsLeftSpinBox_valueChanged );
44  connect( mNumberOfSegmentsSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mNumberOfSegmentsSpinBox_valueChanged );
45  connect( mNumberOfSubdivisionsSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mNumberOfSubdivisionsSpinBox_valueChanged );
46  connect( mSubdivisionsHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mSubdivisionsHeightSpinBox_valueChanged );
47  connect( mUnitLabelLineEdit, &QLineEdit::textChanged, this, &QgsLayoutScaleBarWidget::mUnitLabelLineEdit_textChanged );
48  connect( mMapUnitsPerBarUnitSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMapUnitsPerBarUnitSpinBox_valueChanged );
49  connect( mStyleComboBox, &QComboBox::currentTextChanged, this, &QgsLayoutScaleBarWidget::mStyleComboBox_currentIndexChanged );
50  connect( mLabelBarSpaceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mLabelBarSpaceSpinBox_valueChanged );
51  connect( mBoxSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mBoxSizeSpinBox_valueChanged );
52  connect( mAlignmentComboBox, &QgsAlignmentComboBox::changed, this, &QgsLayoutScaleBarWidget::alignmentChanged );
53  connect( mLabelVerticalPlacementComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mLabelVerticalPlacementComboBox_currentIndexChanged );
54  connect( mLabelHorizontalPlacementComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mLabelHorizontalPlacementComboBox_currentIndexChanged );
55  connect( mUnitsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mUnitsComboBox_currentIndexChanged );
56  connect( mMinWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMinWidthSpinBox_valueChanged );
57  connect( mMaxWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMaxWidthSpinBox_valueChanged );
58  connect( mNumberFormatPushButton, &QPushButton::clicked, this, &QgsLayoutScaleBarWidget::changeNumberFormat );
59  setPanelTitle( tr( "Scalebar Properties" ) );
60 
61  mFontButton->registerExpressionContextGenerator( this );
62 
63  connectUpdateSignal();
64 
65  //add widget for general composer item properties
66  mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, scaleBar );
67  mainLayout->addWidget( mItemPropertiesWidget );
68 
69  mSegmentSizeRadioGroup.addButton( mFixedSizeRadio );
70  mSegmentSizeRadioGroup.addButton( mFitWidthRadio );
71  connect( &mSegmentSizeRadioGroup, static_cast < void ( QButtonGroup::* )( QAbstractButton * ) > ( &QButtonGroup::buttonClicked ), this, &QgsLayoutScaleBarWidget::segmentSizeRadioChanged );
72 
73  blockMemberSignals( true );
74 
75  //style combo box
76  const QStringList renderers = QgsApplication::scaleBarRendererRegistry()->sortedRendererList();
77  for ( const QString &renderer : renderers )
78  {
79  mStyleComboBox->addItem( QgsApplication::scaleBarRendererRegistry()->visibleName( renderer ), renderer );
80  }
81 
82  //label vertical/horizontal placement combo box
83  mLabelVerticalPlacementComboBox->addItem( tr( "Above Segments" ), static_cast< int >( QgsScaleBarSettings::LabelAboveSegment ) );
84  mLabelVerticalPlacementComboBox->addItem( tr( "Below Segments" ), static_cast< int >( QgsScaleBarSettings::LabelBelowSegment ) );
85  mLabelHorizontalPlacementComboBox->addItem( tr( "Centered at Segment Edge" ), static_cast< int >( QgsScaleBarSettings::LabelCenteredEdge ) );
86  mLabelHorizontalPlacementComboBox->addItem( tr( "Centered at Center of Segment" ), static_cast< int >( QgsScaleBarSettings::LabelCenteredSegment ) );
87 
88  //alignment combo box
89  mAlignmentComboBox->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
90 
91  //units combo box
92  mUnitsComboBox->addItem( tr( "Map units" ), QgsUnitTypes::DistanceUnknownUnit );
93  mUnitsComboBox->addItem( tr( "Meters" ), QgsUnitTypes::DistanceMeters );
94  mUnitsComboBox->addItem( tr( "Kilometers" ), QgsUnitTypes::DistanceKilometers );
95  mUnitsComboBox->addItem( tr( "Feet" ), QgsUnitTypes::DistanceFeet );
96  mUnitsComboBox->addItem( tr( "Yards" ), QgsUnitTypes::DistanceYards );
97  mUnitsComboBox->addItem( tr( "Miles" ), QgsUnitTypes::DistanceMiles );
98  mUnitsComboBox->addItem( tr( "Nautical Miles" ), QgsUnitTypes::DistanceNauticalMiles );
99  mUnitsComboBox->addItem( tr( "Centimeters" ), QgsUnitTypes::DistanceCentimeters );
100  mUnitsComboBox->addItem( tr( "Millimeters" ), QgsUnitTypes::DistanceMillimeters );
101 
102  mLineStyleButton->setSymbolType( Qgis::SymbolType::Line );
103  connect( mLineStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutScaleBarWidget::lineSymbolChanged );
104 
105  mDivisionStyleButton->setSymbolType( Qgis::SymbolType::Line );
106  connect( mDivisionStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutScaleBarWidget::divisionSymbolChanged );
107 
108  mSubdivisionStyleButton->setSymbolType( Qgis::SymbolType::Line );
109  connect( mSubdivisionStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutScaleBarWidget::subdivisionSymbolChanged );
110 
111  mFillSymbol1Button->setSymbolType( Qgis::SymbolType::Fill );
112  connect( mFillSymbol1Button, &QgsSymbolButton::changed, this, &QgsLayoutScaleBarWidget::fillSymbol1Changed );
113 
114  mFillSymbol2Button->setSymbolType( Qgis::SymbolType::Fill );
115  connect( mFillSymbol2Button, &QgsSymbolButton::changed, this, &QgsLayoutScaleBarWidget::fillSymbol2Changed );
116 
117  mFontButton->setDialogTitle( tr( "Scalebar Font" ) );
118  mFontButton->setMode( QgsFontButton::ModeTextRenderer );
119 
120  if ( mScalebar )
121  {
122  QgsLayout *scaleBarLayout = mScalebar->layout();
123  if ( scaleBarLayout )
124  {
125  mMapItemComboBox->setCurrentLayout( scaleBarLayout );
126  mMapItemComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
127  }
128  }
129 
130  connect( mMapItemComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutScaleBarWidget::mapChanged );
131 
132  blockMemberSignals( false );
133  setGuiElements(); //set the GUI elements to the state of scaleBar
134 
135  mLineStyleButton->registerExpressionContextGenerator( mScalebar );
136  mLineStyleButton->setLayer( coverageLayer() );
137  mDivisionStyleButton->registerExpressionContextGenerator( mScalebar );
138  mDivisionStyleButton->setLayer( coverageLayer() );
139  mSubdivisionStyleButton->registerExpressionContextGenerator( mScalebar );
140  mSubdivisionStyleButton->setLayer( coverageLayer() );
141  mFillSymbol1Button->registerExpressionContextGenerator( mScalebar );
142  mFillSymbol1Button->setLayer( coverageLayer() );
143  mFillSymbol2Button->registerExpressionContextGenerator( mScalebar );
144  mFillSymbol2Button->setLayer( coverageLayer() );
145 
146  connect( mFontButton, &QgsFontButton::changed, this, &QgsLayoutScaleBarWidget::textFormatChanged );
147  mFontButton->setLayer( coverageLayer() );
148  if ( mScalebar->layout() )
149  {
150  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mFontButton, &QgsFontButton::setLayer );
151  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mLineStyleButton, &QgsSymbolButton::setLayer );
152  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mDivisionStyleButton, &QgsSymbolButton::setLayer );
153  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mSubdivisionStyleButton, &QgsSymbolButton::setLayer );
154  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mFillSymbol1Button, &QgsSymbolButton::setLayer );
155  connect( &mScalebar->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mFillSymbol2Button, &QgsSymbolButton::setLayer );
156  }
157 }
158 
160 {
161  if ( mItemPropertiesWidget )
162  mItemPropertiesWidget->setMasterLayout( masterLayout );
163 }
164 
166 {
167  QgsExpressionContext context = mScalebar->createExpressionContext();
168  QgsExpressionContextScope *scaleScope = new QgsExpressionContextScope( QStringLiteral( "scalebar_text" ) );
169  scaleScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "scale_value" ), 0, true, false ) );
170  context.appendScope( scaleScope );
171  context.setHighlightedVariables( QStringList() << QStringLiteral( "scale_value" ) );
172  return context;
173 }
174 
176 {
178  return false;
179 
180  disconnectUpdateSignal();
181 
182  mScalebar = qobject_cast< QgsLayoutItemScaleBar * >( item );
183  mItemPropertiesWidget->setItem( mScalebar );
184 
185  if ( mScalebar )
186  {
187  connectUpdateSignal();
188  mFillSymbol1Button->registerExpressionContextGenerator( mScalebar );
189  mFillSymbol2Button->registerExpressionContextGenerator( mScalebar );
190  mLineStyleButton->registerExpressionContextGenerator( mScalebar );
191  mDivisionStyleButton->registerExpressionContextGenerator( mScalebar );
192  mSubdivisionStyleButton->registerExpressionContextGenerator( mScalebar );
193  }
194 
195  setGuiElements();
196 
197  return true;
198 }
199 
200 void QgsLayoutScaleBarWidget::lineSymbolChanged()
201 {
202  if ( !mScalebar )
203  return;
204 
205  mScalebar->layout()->undoStack()->beginCommand( mScalebar, tr( "Change Scalebar Line Style" ), QgsLayoutItem::UndoShapeStyle );
206  mScalebar->setLineSymbol( mLineStyleButton->clonedSymbol<QgsLineSymbol>() );
207  mScalebar->update();
208  mScalebar->layout()->undoStack()->endCommand();
209 }
210 
211 void QgsLayoutScaleBarWidget::divisionSymbolChanged()
212 {
213  if ( !mScalebar )
214  return;
215 
216  mScalebar->layout()->undoStack()->beginCommand( mScalebar, tr( "Change Scalebar Division Style" ), QgsLayoutItem::UndoShapeStyle );
217  mScalebar->setDivisionLineSymbol( mDivisionStyleButton->clonedSymbol<QgsLineSymbol>() );
218  mScalebar->update();
219  mScalebar->layout()->undoStack()->endCommand();
220 }
221 
222 void QgsLayoutScaleBarWidget::subdivisionSymbolChanged()
223 {
224  if ( !mScalebar )
225  return;
226 
227  mScalebar->layout()->undoStack()->beginCommand( mScalebar, tr( "Change Scalebar Subdivision Style" ), QgsLayoutItem::UndoShapeStyle );
228  mScalebar->setSubdivisionLineSymbol( mSubdivisionStyleButton->clonedSymbol<QgsLineSymbol>() );
229  mScalebar->update();
230  mScalebar->layout()->undoStack()->endCommand();
231 }
232 
233 void QgsLayoutScaleBarWidget::fillSymbol1Changed()
234 {
235  if ( !mScalebar )
236  return;
237 
238  mScalebar->layout()->undoStack()->beginCommand( mScalebar, tr( "Change Scalebar Fill Style" ), QgsLayoutItem::UndoShapeStyle );
239  mScalebar->setFillSymbol( mFillSymbol1Button->clonedSymbol<QgsFillSymbol>() );
240  mScalebar->update();
241  mScalebar->layout()->undoStack()->endCommand();
242 }
243 
244 void QgsLayoutScaleBarWidget::fillSymbol2Changed()
245 {
246  if ( !mScalebar )
247  return;
248 
249  mScalebar->layout()->undoStack()->beginCommand( mScalebar, tr( "Change Scalebar Fill Style" ), QgsLayoutItem::UndoShapeStyle );
250  mScalebar->setAlternateFillSymbol( mFillSymbol2Button->clonedSymbol<QgsFillSymbol>() );
251  mScalebar->update();
252  mScalebar->layout()->undoStack()->endCommand();
253 }
254 
255 void QgsLayoutScaleBarWidget::setGuiElements()
256 {
257  if ( !mScalebar )
258  {
259  return;
260  }
261 
262  blockMemberSignals( true );
263  mNumberOfSegmentsSpinBox->setValue( mScalebar->numberOfSegments() );
264  mSegmentsLeftSpinBox->setValue( mScalebar->numberOfSegmentsLeft() );
265  mSegmentSizeSpinBox->setValue( mScalebar->unitsPerSegment() );
266  mHeightSpinBox->setValue( mScalebar->height() );
267  mNumberOfSubdivisionsSpinBox->setValue( mScalebar->numberOfSubdivisions() );
268  mSubdivisionsHeightSpinBox->setValue( mScalebar->subdivisionsHeight() );
269  mMapUnitsPerBarUnitSpinBox->setValue( mScalebar->mapUnitsPerScaleBarUnit() );
270  mLabelBarSpaceSpinBox->setValue( mScalebar->labelBarSpace() );
271  mBoxSizeSpinBox->setValue( mScalebar->boxContentSpace() );
272  mUnitLabelLineEdit->setText( mScalebar->unitLabel() );
273  mFontButton->setTextFormat( mScalebar->textFormat() );
274 
275  whileBlocking( mLineStyleButton )->setSymbol( mScalebar->lineSymbol()->clone() );
276  whileBlocking( mDivisionStyleButton )->setSymbol( mScalebar->divisionLineSymbol()->clone() );
277  whileBlocking( mSubdivisionStyleButton )->setSymbol( mScalebar->subdivisionLineSymbol()->clone() );
278  whileBlocking( mFillSymbol1Button )->setSymbol( mScalebar->fillSymbol()->clone() );
279  whileBlocking( mFillSymbol2Button )->setSymbol( mScalebar->alternateFillSymbol()->clone() );
280 
281  //map combo box
282  mMapItemComboBox->setItem( mScalebar->linkedMap() );
283 
284  //style...
285  const QString style = mScalebar->style();
286  mStyleComboBox->setCurrentIndex( mStyleComboBox->findData( style ) );
287  toggleStyleSpecificControls( style );
288 
289  //label vertical/horizontal placement
290  mLabelVerticalPlacementComboBox->setCurrentIndex( mLabelVerticalPlacementComboBox->findData( static_cast< int >( mScalebar->labelVerticalPlacement() ) ) );
291  mLabelHorizontalPlacementComboBox->setCurrentIndex( mLabelHorizontalPlacementComboBox->findData( static_cast< int >( mScalebar->labelHorizontalPlacement() ) ) );
292 
293  //alignment
294 
295  Qt::Alignment a = Qt::AlignLeft;
296  switch ( mScalebar->alignment() )
297  {
299  a = Qt::AlignLeft;
300  break;
302  a = Qt::AlignRight;
303  break;
305  a = Qt::AlignHCenter;
306  break;
307  }
308  mAlignmentComboBox->setCurrentAlignment( a );
309 
310  //units
311  mUnitsComboBox->setCurrentIndex( mUnitsComboBox->findData( static_cast< int >( mScalebar->units() ) ) );
312 
313  if ( mScalebar->segmentSizeMode() == QgsScaleBarSettings::SegmentSizeFixed )
314  {
315  mFixedSizeRadio->setChecked( true );
316  mSegmentSizeSpinBox->setEnabled( true );
317  mMinWidthSpinBox->setEnabled( false );
318  mMaxWidthSpinBox->setEnabled( false );
319  }
320  else /*if(mComposerScaleBar->segmentSizeMode() == QgsComposerScaleBar::SegmentSizeFitWidth)*/
321  {
322  mFitWidthRadio->setChecked( true );
323  mSegmentSizeSpinBox->setEnabled( false );
324  mMinWidthSpinBox->setEnabled( true );
325  mMaxWidthSpinBox->setEnabled( true );
326  }
327  mMinWidthSpinBox->setValue( mScalebar->minimumBarWidth() );
328  mMaxWidthSpinBox->setValue( mScalebar->maximumBarWidth() );
329  blockMemberSignals( false );
330 }
331 
332 //slots
333 
334 void QgsLayoutScaleBarWidget::mSegmentSizeSpinBox_valueChanged( double d )
335 {
336  if ( !mScalebar )
337  {
338  return;
339  }
340 
341  mScalebar->beginCommand( tr( "Set Scalebar Segment Size" ), QgsLayoutItem::UndoScaleBarSegmentSize );
342  disconnectUpdateSignal();
343  mScalebar->setUnitsPerSegment( d );
344  mScalebar->update();
345  connectUpdateSignal();
346  mScalebar->endCommand();
347 }
348 
349 void QgsLayoutScaleBarWidget::mSegmentsLeftSpinBox_valueChanged( int i )
350 {
351  if ( !mScalebar )
352  {
353  return;
354  }
355 
356  mScalebar->beginCommand( tr( "Set Scalebar Segments" ), QgsLayoutItem::UndoScaleBarSegmentsLeft );
357  disconnectUpdateSignal();
358  mScalebar->setNumberOfSegmentsLeft( i );
359  mScalebar->update();
360  connectUpdateSignal();
361  mScalebar->endCommand();
362 }
363 
364 void QgsLayoutScaleBarWidget::mNumberOfSegmentsSpinBox_valueChanged( int i )
365 {
366  if ( !mScalebar )
367  {
368  return;
369  }
370 
371  mScalebar->beginCommand( tr( "Set Scalebar Segments" ), QgsLayoutItem::UndoScaleBarSegments );
372  disconnectUpdateSignal();
373  mScalebar->setNumberOfSegments( i );
374  mScalebar->update();
375  connectUpdateSignal();
376  mScalebar->endCommand();
377 }
378 
379 void QgsLayoutScaleBarWidget::mHeightSpinBox_valueChanged( double d )
380 {
381  if ( !mScalebar )
382  {
383  return;
384  }
385  mScalebar->beginCommand( tr( "Set Scalebar Height" ), QgsLayoutItem::UndoScaleBarHeight );
386  disconnectUpdateSignal();
387  mScalebar->setHeight( d );
388  mScalebar->update();
389  connectUpdateSignal();
390  mScalebar->endCommand();
391 }
392 
393 void QgsLayoutScaleBarWidget::mNumberOfSubdivisionsSpinBox_valueChanged( int i )
394 {
395  if ( !mScalebar )
396  {
397  return;
398  }
399 
400  mScalebar->beginCommand( tr( "Set Scalebar Subdivisions" ), QgsLayoutItem::UndoScaleBarSubdivisions );
401  disconnectUpdateSignal();
402  mScalebar->setNumberOfSubdivisions( i );
403  mScalebar->update();
404  connectUpdateSignal();
405  mScalebar->endCommand();
406 }
407 
408 void QgsLayoutScaleBarWidget::mSubdivisionsHeightSpinBox_valueChanged( double d )
409 {
410  if ( !mScalebar )
411  {
412  return;
413  }
414  mScalebar->beginCommand( tr( "Set Subdivisions Height" ), QgsLayoutItem::UndoScaleBarSubdivisionsHeight );
415  disconnectUpdateSignal();
416  mScalebar->setSubdivisionsHeight( d );
417  mScalebar->update();
418  connectUpdateSignal();
419  mScalebar->endCommand();
420 }
421 
422 void QgsLayoutScaleBarWidget::textFormatChanged()
423 {
424  if ( !mScalebar )
425  {
426  return;
427  }
428 
429  mScalebar->beginCommand( tr( "Set Scalebar Font" ) );
430  disconnectUpdateSignal();
431  mScalebar->setTextFormat( mFontButton->textFormat() );
432  connectUpdateSignal();
433  mScalebar->endCommand();
434  mScalebar->update();
435 }
436 
437 void QgsLayoutScaleBarWidget::changeNumberFormat()
438 {
439  if ( !mScalebar )
440  {
441  return;
442  }
443 
445  widget->setPanelTitle( tr( "Number Format" ) );
446  widget->setFormat( mScalebar->numericFormat() );
447  connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [ = ]
448  {
449  mScalebar->beginCommand( tr( "Set Scalebar Number Format" ) );
450  disconnectUpdateSignal();
451  mScalebar->setNumericFormat( widget->format() );
452  connectUpdateSignal();
453  mScalebar->endCommand();
454  mScalebar->update();
455  } );
456  openPanel( widget );
457  return;
458 }
459 
460 void QgsLayoutScaleBarWidget::mUnitLabelLineEdit_textChanged( const QString &text )
461 {
462  if ( !mScalebar )
463  {
464  return;
465  }
466 
467  mScalebar->beginCommand( tr( "Set Scalebar Unit Text" ), QgsLayoutItem::UndoScaleBarUnitText );
468  disconnectUpdateSignal();
469  mScalebar->setUnitLabel( text );
470  mScalebar->update();
471  connectUpdateSignal();
472  mScalebar->endCommand();
473 }
474 
475 void QgsLayoutScaleBarWidget::mMapUnitsPerBarUnitSpinBox_valueChanged( double d )
476 {
477  if ( !mScalebar )
478  {
479  return;
480  }
481 
482  mScalebar->beginCommand( tr( "Set Scalebar Map Units per Segment" ), QgsLayoutItem::UndoScaleBarMapUnitsSegment );
483  disconnectUpdateSignal();
484  mScalebar->setMapUnitsPerScaleBarUnit( d );
485  mScalebar->update();
486  connectUpdateSignal();
487  mScalebar->endCommand();
488 }
489 
490 void QgsLayoutScaleBarWidget::mStyleComboBox_currentIndexChanged( const QString & )
491 {
492  if ( !mScalebar )
493  {
494  return;
495  }
496 
497  const QString rendererId = mStyleComboBox->currentData().toString();
498  if ( rendererId == mScalebar->style() )
499  return;
500 
501  mScalebar->beginCommand( tr( "Set Scalebar Style" ) );
502  disconnectUpdateSignal();
503 
504  bool defaultsApplied = false;
505  const std::unique_ptr< QgsScaleBarRenderer > renderer( QgsApplication::scaleBarRendererRegistry()->renderer( rendererId ) );
506  if ( renderer )
507  defaultsApplied = mScalebar->applyDefaultRendererSettings( renderer.get() );
508 
509  //disable or enable controls which apply to specific scale bar styles
510  toggleStyleSpecificControls( rendererId );
511 
512  mScalebar->setStyle( rendererId );
513  mScalebar->update();
514  connectUpdateSignal();
515  mScalebar->endCommand();
516 
517  if ( defaultsApplied )
518  setGuiElements();
519 }
520 
521 void QgsLayoutScaleBarWidget::toggleStyleSpecificControls( const QString &style )
522 {
523  std::unique_ptr< QgsScaleBarRenderer > renderer( QgsApplication::scaleBarRendererRegistry()->renderer( style ) );
524 
525  //Selectively enable controls which apply to the scale bar style
526  mUnitsComboBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagRespectsUnits : true );
527  mUnitsLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagRespectsUnits : true );
528  mMapUnitsPerBarUnitSpinBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagRespectsMapUnitsPerScaleBarUnit : true );
529  mMapUnitsPerBarUnitLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagRespectsMapUnitsPerScaleBarUnit : true );
530  mUnitLabelLineEdit->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesUnitLabel : true );
531  mUnitLabelLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesUnitLabel : true );
532  mSubdivisionsLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisions : true );
533  mNumberOfSubdivisionsSpinBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisions : true );
534  mSubdivisionsHeightLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisionsHeight : true );
535  mSubdivisionsHeightSpinBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisionsHeight : true );
536  mGroupBoxSegments->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSegments : true );
537  if ( !mGroupBoxUnits->isEnabled() )
538  mGroupBoxSegments->setCollapsed( true );
539  mLabelBarSpaceSpinBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelBarSpace : true );
540  mLabelBarSpaceLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelBarSpace : true );
541  mLabelVerticalPlacementComboBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelVerticalPlacement : true );
542  mLabelVerticalPlacementLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelVerticalPlacement : true );
543  mLabelHorizontalPlacementComboBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelHorizontalPlacement : true );
544  mLabelHorizontalPlacementLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLabelHorizontalPlacement : true );
545  mAlignmentComboBox->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesAlignment : true );
546  mAlignmentLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesAlignment : true );
547  mFillSymbol1Button->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesFillSymbol : true );
548  mFillSymbol1Label->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesFillSymbol : true );
549  mFillSymbol2Button->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesAlternateFillSymbol : true );
550  mFillSymbol2Label->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesAlternateFillSymbol : true );
551  mLineStyleButton->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLineSymbol : true );
552  mLineStyleLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesLineSymbol : true );
553  mDivisionStyleButton->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesDivisionSymbol : true );
554  mDivisionStyleLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesDivisionSymbol : true );
555  mSubdivisionStyleButton->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisionSymbol : true );
556  mSubdivisionStyleLabel->setEnabled( renderer ? renderer->flags() & QgsScaleBarRenderer::Flag::FlagUsesSubdivisionSymbol : true );
557 }
558 
559 void QgsLayoutScaleBarWidget::mLabelBarSpaceSpinBox_valueChanged( double d )
560 {
561  if ( !mScalebar )
562  {
563  return;
564  }
565 
566  mScalebar->beginCommand( tr( "Set Scalebar Label Space" ), QgsLayoutItem::UndoScaleBarLabelBarSize );
567  disconnectUpdateSignal();
568  mScalebar->setLabelBarSpace( d );
569  mScalebar->update();
570  connectUpdateSignal();
571  mScalebar->endCommand();
572 }
573 
574 void QgsLayoutScaleBarWidget::mBoxSizeSpinBox_valueChanged( double d )
575 {
576  if ( !mScalebar )
577  {
578  return;
579  }
580 
581  mScalebar->beginCommand( tr( "Set Scalebar Box Space" ), QgsLayoutItem::UndoScaleBarBoxContentSpace );
582  disconnectUpdateSignal();
583  mScalebar->setBoxContentSpace( d );
584  mScalebar->update();
585  connectUpdateSignal();
586  mScalebar->endCommand();
587 }
588 
589 void QgsLayoutScaleBarWidget::mLabelVerticalPlacementComboBox_currentIndexChanged( int index )
590 {
591  if ( !mScalebar )
592  {
593  return;
594  }
595 
596  mScalebar->beginCommand( tr( "Set Scalebar Label Vertical Placement" ) );
597  disconnectUpdateSignal();
598  mScalebar->setLabelVerticalPlacement( static_cast<QgsScaleBarSettings::LabelVerticalPlacement>( mLabelVerticalPlacementComboBox->itemData( index ).toInt() ) );
599  mScalebar->update();
600  connectUpdateSignal();
601  mScalebar->endCommand();
602 }
603 
604 void QgsLayoutScaleBarWidget::mLabelHorizontalPlacementComboBox_currentIndexChanged( int index )
605 {
606  if ( !mScalebar )
607  {
608  return;
609  }
610 
611  mScalebar->beginCommand( tr( "Set Scalebar Label Horizontal Placement" ) );
612  disconnectUpdateSignal();
613  mScalebar->setLabelHorizontalPlacement( static_cast<QgsScaleBarSettings::LabelHorizontalPlacement>( mLabelHorizontalPlacementComboBox->itemData( index ).toInt() ) );
614  mScalebar->update();
615  connectUpdateSignal();
616  mScalebar->endCommand();
617 }
618 
619 void QgsLayoutScaleBarWidget::alignmentChanged()
620 {
621  if ( !mScalebar )
622  {
623  return;
624  }
625 
626  mScalebar->beginCommand( tr( "Set Scalebar Alignment" ) );
627  disconnectUpdateSignal();
628 
629  const QgsScaleBarSettings::Alignment a = mAlignmentComboBox->currentAlignment() & Qt::AlignLeft ? QgsScaleBarSettings::AlignLeft
630  : mAlignmentComboBox->currentAlignment() & Qt::AlignRight ? QgsScaleBarSettings::AlignRight : QgsScaleBarSettings::AlignMiddle;
631  mScalebar->setAlignment( a );
632  mScalebar->update();
633  connectUpdateSignal();
634  mScalebar->endCommand();
635 }
636 
637 void QgsLayoutScaleBarWidget::mUnitsComboBox_currentIndexChanged( int index )
638 {
639  if ( !mScalebar )
640  {
641  return;
642  }
643 
644  const QVariant unitData = mUnitsComboBox->itemData( index );
645  if ( unitData.type() == QVariant::Invalid )
646  {
647  return;
648  }
649 
650  disconnectUpdateSignal();
651  mScalebar->beginCommand( tr( "Set Scalebar Units" ) );
652  mScalebar->applyDefaultSize( static_cast< QgsUnitTypes::DistanceUnit >( unitData.toInt() ) );
653  mScalebar->update();
654 
655  mNumberOfSegmentsSpinBox->setValue( mScalebar->numberOfSegments() );
656  mSegmentsLeftSpinBox->setValue( mScalebar->numberOfSegmentsLeft() );
657  mUnitLabelLineEdit->setText( mScalebar->unitLabel() );
658  mSegmentSizeSpinBox->setValue( mScalebar->unitsPerSegment() );
659  mMapUnitsPerBarUnitSpinBox->setValue( mScalebar->mapUnitsPerScaleBarUnit() );
660 
661  connectUpdateSignal();
662  mScalebar->endCommand();
663 }
664 
665 void QgsLayoutScaleBarWidget::blockMemberSignals( bool block )
666 {
667  mSegmentSizeSpinBox->blockSignals( block );
668  mNumberOfSegmentsSpinBox->blockSignals( block );
669  mSegmentsLeftSpinBox->blockSignals( block );
670  mNumberOfSubdivisionsSpinBox->blockSignals( block );
671  mSubdivisionsHeightSpinBox->blockSignals( block );
672  mStyleComboBox->blockSignals( block );
673  mUnitLabelLineEdit->blockSignals( block );
674  mMapUnitsPerBarUnitSpinBox->blockSignals( block );
675  mHeightSpinBox->blockSignals( block );
676  mLineStyleButton->blockSignals( block );
677  mDivisionStyleButton->blockSignals( block );
678  mSubdivisionStyleButton->blockSignals( block );
679  mLabelBarSpaceSpinBox->blockSignals( block );
680  mBoxSizeSpinBox->blockSignals( block );
681  mLabelVerticalPlacementComboBox->blockSignals( block );
682  mLabelHorizontalPlacementComboBox->blockSignals( block );
683  mAlignmentComboBox->blockSignals( block );
684  mUnitsComboBox->blockSignals( block );
685  mFillSymbol1Button->blockSignals( block );
686  mFillSymbol2Button->blockSignals( block );
687  mSegmentSizeRadioGroup.blockSignals( block );
688  mMapItemComboBox->blockSignals( block );
689  mFontButton->blockSignals( block );
690  mMinWidthSpinBox->blockSignals( block );
691  mMaxWidthSpinBox->blockSignals( block );
692 }
693 
694 void QgsLayoutScaleBarWidget::connectUpdateSignal()
695 {
696  if ( mScalebar )
697  {
698  connect( mScalebar, &QgsLayoutObject::changed, this, &QgsLayoutScaleBarWidget::setGuiElements );
699  }
700 }
701 
702 void QgsLayoutScaleBarWidget::disconnectUpdateSignal()
703 {
704  if ( mScalebar )
705  {
706  disconnect( mScalebar, &QgsLayoutObject::changed, this, &QgsLayoutScaleBarWidget::setGuiElements );
707  }
708 }
709 
710 void QgsLayoutScaleBarWidget::segmentSizeRadioChanged( QAbstractButton *radio )
711 {
712  const bool fixedSizeMode = radio == mFixedSizeRadio;
713  mMinWidthSpinBox->setEnabled( !fixedSizeMode );
714  mMaxWidthSpinBox->setEnabled( !fixedSizeMode );
715  mSegmentSizeSpinBox->setEnabled( fixedSizeMode );
716 
717  if ( !mScalebar )
718  {
719  return;
720  }
721 
722  mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize );
723  disconnectUpdateSignal();
724  if ( mFixedSizeRadio->isChecked() )
725  {
726  mScalebar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFixed );
727  mScalebar->setUnitsPerSegment( mSegmentSizeSpinBox->value() );
728  }
729  else /*if(mFitWidthRadio->isChecked())*/
730  {
731  mScalebar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFitWidth );
732  }
733  mScalebar->update();
734  connectUpdateSignal();
735  mScalebar->endCommand();
736 }
737 
738 void QgsLayoutScaleBarWidget::mapChanged( QgsLayoutItem *item )
739 {
740  QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( item );
741  if ( !map )
742  {
743  return;
744  }
745 
746  //set it to scale bar
747  mScalebar->beginCommand( tr( "Set Scalebar Map" ) );
748  disconnectUpdateSignal();
749  mScalebar->setLinkedMap( map );
750  mScalebar->update();
751  connectUpdateSignal();
752  mScalebar->endCommand();
753 }
754 
755 void QgsLayoutScaleBarWidget::mMinWidthSpinBox_valueChanged( double )
756 {
757  if ( !mScalebar )
758  {
759  return;
760  }
761 
762  mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize );
763  disconnectUpdateSignal();
764  mScalebar->setMinimumBarWidth( mMinWidthSpinBox->value() );
765  mScalebar->update();
766  connectUpdateSignal();
767  mScalebar->endCommand();
768 }
769 
770 void QgsLayoutScaleBarWidget::mMaxWidthSpinBox_valueChanged( double )
771 {
772  if ( !mScalebar )
773  {
774  return;
775  }
776 
777  mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize );
778  disconnectUpdateSignal();
779  mScalebar->setMaximumBarWidth( mMaxWidthSpinBox->value() );
780  mScalebar->update();
781  connectUpdateSignal();
782  mScalebar->endCommand();
783 }
@ Line
Line symbol.
@ Fill
Fill symbol.
void changed()
Emitted when the alignment is changed.
static QgsScaleBarRendererRegistry * scaleBarRendererRegistry()
Gets the registry of available scalebar renderers.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
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:61
void setLayer(QgsVectorLayer *layer)
Sets a layer to associate with the widget.
void changed()
Emitted when the widget's text format settings are changed.
A base class for property widgets for layout items.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
Layout graphical items for displaying a map.
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.
@ LayoutScaleBar
Scale bar item.
A layout item subclass for scale bars.
Base class for graphical items within a QgsLayout.
@ UndoScaleBarSubdivisionsHeight
Scalebar subdivisions height.
@ UndoScaleBarLabelBarSize
Scalebar label bar size.
@ UndoScaleBarMapUnitsSegment
Scalebar map units per segment.
@ UndoScaleBarBoxContentSpace
Scalebar box context space.
@ UndoScaleBarSegmentSize
Scalebar segment size.
@ UndoScaleBarHeight
Scalebar height.
@ UndoScaleBarSegments
Scalebar number of segments.
@ UndoScaleBarSubdivisions
Scalebar number of subdivisions.
@ UndoShapeStyle
Shape symbol style.
@ UndoScaleBarSegmentsLeft
Scalebar segments left.
@ UndoScaleBarUnitText
Scalebar unit text.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
QgsLayoutScaleBarWidget(QgsLayoutItemScaleBar *scaleBar)
constructor
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.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
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.
QStringList sortedRendererList() const
Returns a list of the renderer ids currently contained in the registry, sorted in an order respecting...
@ FlagUsesLabelVerticalPlacement
Renderer uses the QgsScaleBarSettings::labelVerticalPlacement() setting.
@ FlagUsesLabelHorizontalPlacement
Renderer uses the QgsScaleBarSettings::labelHorizontalPlacement() setting.
@ FlagUsesLineSymbol
Renderer utilizes the scalebar line symbol (see QgsScaleBarSettings::lineSymbol() )
@ FlagUsesUnitLabel
Renderer uses the QgsScaleBarSettings::unitLabel() setting.
@ FlagUsesSubdivisionsHeight
Renderer uses the scalebar subdivisions height (see QgsScaleBarSettings::subdivisionsHeight() )
@ FlagUsesSubdivisionSymbol
Renderer utilizes the scalebar subdivision symbol (see QgsScaleBarSettings::subdivisionLineSymbol() )
@ FlagUsesSegments
Renderer uses the scalebar segments.
@ FlagUsesLabelBarSpace
Renderer uses the QgsScaleBarSettings::labelBarSpace() setting.
@ FlagUsesAlignment
Renderer uses the QgsScaleBarSettings::alignment() setting.
@ FlagUsesFillSymbol
Renderer utilizes the scalebar fill symbol (see QgsScaleBarSettings::fillSymbol() )
@ FlagRespectsMapUnitsPerScaleBarUnit
Renderer respects the QgsScaleBarSettings::mapUnitsPerScaleBarUnit() setting.
@ FlagRespectsUnits
Renderer respects the QgsScaleBarSettings::units() setting.
@ FlagUsesAlternateFillSymbol
Renderer utilizes the alternate scalebar fill symbol (see QgsScaleBarSettings::alternateFillSymbol() ...
@ FlagUsesSubdivisions
Renderer uses the scalebar subdivisions (see QgsScaleBarSettings::numberOfSubdivisions() )
@ FlagUsesDivisionSymbol
Renderer utilizes the scalebar division symbol (see QgsScaleBarSettings::divisionLineSymbol() )
Alignment
Scalebar alignment.
@ AlignLeft
Left aligned.
@ AlignMiddle
Center aligned.
@ AlignRight
Right aligned.
LabelHorizontalPlacement
Label horizontal placement.
@ LabelCenteredSegment
Labels are drawn centered relative to segment.
@ LabelCenteredEdge
Labels are drawn centered relative to segment's edge.
LabelVerticalPlacement
Label vertical placement.
@ LabelAboveSegment
Labels are drawn above the scalebar.
@ LabelBelowSegment
Labels are drawn below the scalebar.
@ SegmentSizeFitWidth
Scale bar segment size is calculated to fit a size range.
@ SegmentSizeFixed
Scale bar segment size is fixed to a map unit.
void setLayer(QgsVectorLayer *layer)
Sets a layer to associate with the widget.
void changed()
Emitted when the symbol's settings are changed.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
@ DistanceKilometers
Kilometers.
Definition: qgsunittypes.h:70
@ DistanceMiles
Terrestrial miles.
Definition: qgsunittypes.h:74
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
@ DistanceMillimeters
Millimeters.
Definition: qgsunittypes.h:77
@ DistanceYards
Imperial yards.
Definition: qgsunittypes.h:73
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
@ DistanceNauticalMiles
Nautical miles.
Definition: qgsunittypes.h:72
@ DistanceCentimeters
Centimeters.
Definition: qgsunittypes.h:76
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:1517
Single variable definition for use within a QgsExpressionContextScope.