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