QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgslayoutitemscalebar.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemscalebar.cpp
3  -------------------------
4  begin : November 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 
17 #include "qgslayoutitemscalebar.h"
18 #include "qgslayoutitemregistry.h"
20 #include "qgslayoutitemmap.h"
21 #include "qgslayout.h"
22 #include "qgslayoututils.h"
23 #include "qgsdistancearea.h"
25 #include "qgsscalebarrenderer.h"
26 #include "qgsmapsettings.h"
27 #include "qgsrectangle.h"
28 #include "qgsproject.h"
29 #include "qgssymbollayerutils.h"
30 #include "qgsfontutils.h"
31 #include "qgsunittypes.h"
32 #include "qgssettings.h"
33 #include "qgsstyleentityvisitor.h"
34 #include "qgsnumericformat.h"
36 #include "qgslinesymbollayer.h"
37 #include "qgsfillsymbollayer.h"
38 #include "qgslinesymbol.h"
39 #include "qgsfillsymbol.h"
40 
41 #include <QDomDocument>
42 #include <QDomElement>
43 #include <QFontMetricsF>
44 #include <QPainter>
45 
46 #include <cmath>
47 
49  : QgsLayoutItem( layout )
50 {
53 }
54 
56 {
58 }
59 
61 {
62  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemScaleBar.svg" ) );
63 }
64 
66 {
67  return new QgsLayoutItemScaleBar( layout );
68 }
69 
71 {
73  return QgsLayoutSize( mStyle->calculateBoxSize( context, mSettings, createScaleContext() ), QgsUnitTypes::LayoutMillimeters );
74 }
75 
77 {
78  if ( !mStyle )
79  return;
80 
82  {
83  // compatibility code - ScalebarLineColor and ScalebarLineWidth are deprecated
84  const QgsExpressionContext expContext = createExpressionContext();
85  std::unique_ptr< QgsLineSymbol > sym( mSettings.lineSymbol()->clone() );
88  sym->setWidth( mDataDefinedProperties.valueAsDouble( QgsLayoutObject::ScalebarLineWidth, expContext, mSettings.lineWidth() ) );
90  sym->setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarLineColor, expContext, mSettings.lineColor() ) );
92  mSettings.setLineSymbol( sym.release() );
93  }
95  {
96  // compatibility code - ScalebarLineColor and ScalebarLineWidth are deprecated
97  const QgsExpressionContext expContext = createExpressionContext();
98  std::unique_ptr< QgsFillSymbol > sym( mSettings.fillSymbol()->clone() );
100  sym->setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarFillColor, expContext, mSettings.fillColor() ) );
102  mSettings.setFillSymbol( sym.release() );
103  }
105  {
106  // compatibility code - ScalebarLineColor and ScalebarLineWidth are deprecated
107  const QgsExpressionContext expContext = createExpressionContext();
108  std::unique_ptr< QgsFillSymbol > sym( mSettings.alternateFillSymbol()->clone() );
110  sym->setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarFillColor2, expContext, mSettings.fillColor2() ) );
112  mSettings.setAlternateFillSymbol( sym.release() );
113  }
114 
115  mStyle->draw( context.renderContext(), mSettings, createScaleContext() );
116 }
117 
119 {
120  if ( !mStyle )
121  {
122  mSettings.setNumberOfSegments( nSegments );
123  return;
124  }
125  mSettings.setNumberOfSegments( nSegments );
127 }
128 
130 {
131  if ( !mStyle )
132  {
133  mSettings.setUnitsPerSegment( units );
134  return;
135  }
136  mSettings.setUnitsPerSegment( units );
137  refreshSegmentMillimeters();
139 }
140 
142 {
143  if ( !mStyle )
144  {
145  mSettings.setSegmentSizeMode( mode );
146  return;
147  }
148  mSettings.setSegmentSizeMode( mode );
149  refreshSegmentMillimeters();
151 }
152 
154 {
155  if ( !mStyle )
156  {
157  mSettings.setMinimumBarWidth( minWidth );
158  return;
159  }
160  mSettings.setMinimumBarWidth( minWidth );
161  refreshSegmentMillimeters();
163 }
164 
166 {
167  if ( !mStyle )
168  {
169  mSettings.setMaximumBarWidth( maxWidth );
170  return;
171  }
172  mSettings.setMaximumBarWidth( maxWidth );
173  refreshSegmentMillimeters();
175 }
176 
178 {
179  return mSettings.textFormat();
180 }
181 
183 {
184  mSettings.setTextFormat( format );
185  refreshItemSize();
186  emit changed();
187 }
188 
190 {
191  return mSettings.lineSymbol();
192 }
193 
195 {
196  mSettings.setLineSymbol( symbol );
197 }
198 
200 {
201  return mSettings.divisionLineSymbol();
202 }
203 
205 {
206  mSettings.setDivisionLineSymbol( symbol );
207 }
208 
210 {
211  return mSettings.subdivisionLineSymbol();
212 }
213 
215 {
216  mSettings.setSubdivisionLineSymbol( symbol );
217 }
218 
220 {
221  return mSettings.fillSymbol();
222 }
223 
225 {
226  mSettings.setFillSymbol( symbol );
227 }
228 
230 {
231  return mSettings.alternateFillSymbol();
232 }
233 
235 {
236  mSettings.setAlternateFillSymbol( symbol );
237 }
238 
240 {
241  if ( !mStyle )
242  {
243  mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
244  return;
245  }
246  mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
248 }
249 
251 {
252  if ( !mStyle )
253  {
254  mSettings.setBoxContentSpace( space );
255  return;
256  }
257  mSettings.setBoxContentSpace( space );
258  refreshItemSize();
259 }
260 
262 {
263  disconnectCurrentMap();
264 
265  mMap = map;
266 
267  if ( !map )
268  {
269  return;
270  }
271 
272  connect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateScale );
273  connect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
274 
275  refreshSegmentMillimeters();
276  emit changed();
277 }
278 
279 void QgsLayoutItemScaleBar::disconnectCurrentMap()
280 {
281  if ( !mMap )
282  {
283  return;
284  }
285 
286  disconnect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateScale );
287  disconnect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
288  mMap = nullptr;
289 }
290 
292 {
294 
295  bool forceUpdate = false;
296  //updates data defined properties and redraws item to match
298  {
299  forceUpdate = true;
300  }
302  {
303  forceUpdate = true;
304  }
306  {
307  forceUpdate = true;
308  }
310  {
311  forceUpdate = true;
312  }
313  if ( forceUpdate )
314  {
315  refreshItemSize();
316  update();
317  }
318 
320 }
321 
322 void QgsLayoutItemScaleBar::refreshSegmentMillimeters()
323 {
324  if ( mMap )
325  {
326  //get mm dimension of composer map
327  const QRectF composerItemRect = mMap->rect();
328 
329  switch ( mSettings.segmentSizeMode() )
330  {
332  {
333  //calculate size depending on mNumUnitsPerSegment
334  mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment();
335  break;
336  }
337 
339  {
340  if ( mSettings.maximumBarWidth() < mSettings.minimumBarWidth() )
341  {
342  mSegmentMillimeters = 0;
343  }
344  else
345  {
346  const double nSegments = ( mSettings.numberOfSegmentsLeft() != 0 ) + mSettings.numberOfSegments();
347  // unitsPerSegments which fit minBarWidth resp. maxBarWidth
348  const double minUnitsPerSeg = ( mSettings.minimumBarWidth() * mapWidth() ) / ( nSegments * composerItemRect.width() );
349  const double maxUnitsPerSeg = ( mSettings.maximumBarWidth() * mapWidth() ) / ( nSegments * composerItemRect.width() );
350  mSettings.setUnitsPerSegment( QgsLayoutUtils::calculatePrettySize( minUnitsPerSeg, maxUnitsPerSeg ) );
351  mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment();
352  }
353  break;
354  }
355  }
356  }
357 }
358 
359 double QgsLayoutItemScaleBar::mapWidth() const
360 {
361  if ( !mMap )
362  {
363  return 0.0;
364  }
365 
366  const QgsRectangle mapExtent = mMap->extent();
367  if ( mSettings.units() == QgsUnitTypes::DistanceUnknownUnit )
368  {
369  return mapExtent.width();
370  }
371  else
372  {
373  QgsDistanceArea da;
374  da.setSourceCrs( mMap->crs(), mLayout->project()->transformContext() );
375  da.setEllipsoid( mLayout->project()->ellipsoid() );
376 
378  double measure = da.measureLine( QgsPointXY( mapExtent.xMinimum(), mapExtent.yMinimum() ),
379  QgsPointXY( mapExtent.xMaximum(), mapExtent.yMinimum() ) );
380  measure /= QgsUnitTypes::fromUnitToUnitFactor( mSettings.units(), units );
381  return measure;
382  }
383 }
384 
385 QgsScaleBarRenderer::ScaleBarContext QgsLayoutItemScaleBar::createScaleContext() const
386 {
388  scaleContext.size = rect().size();
389  scaleContext.segmentWidth = mSegmentMillimeters;
390  scaleContext.scale = mMap ? mMap->scale() : 1.0;
391  scaleContext.flags = mStyle->flags();
392  return scaleContext;
393 }
394 
396 {
397  mSettings.setLabelVerticalPlacement( placement );
398  refreshItemSize();
399  emit changed();
400 }
401 
403 {
404  mSettings.setLabelHorizontalPlacement( placement );
405  refreshItemSize();
406  emit changed();
407 }
408 
410 {
411  mSettings.setAlignment( a );
412  refreshItemSize();
413  emit changed();
414 }
415 
417 {
418  mSettings.setUnits( u );
419  refreshSegmentMillimeters();
420  refreshItemSize();
421  emit changed();
422 }
423 
424 Qt::PenJoinStyle QgsLayoutItemScaleBar::lineJoinStyle() const
425 {
427  return mSettings.lineJoinStyle();
429 }
430 
431 void QgsLayoutItemScaleBar::setLineJoinStyle( Qt::PenJoinStyle style )
432 {
434  if ( mSettings.lineJoinStyle() == style )
435  {
436  //no change
437  return;
438  }
439  mSettings.setLineJoinStyle( style );
441  update();
442  emit changed();
443 }
444 
445 Qt::PenCapStyle QgsLayoutItemScaleBar::lineCapStyle() const
446 {
448  return mSettings.lineCapStyle();
450 }
451 
452 void QgsLayoutItemScaleBar::setLineCapStyle( Qt::PenCapStyle style )
453 {
455  if ( mSettings.lineCapStyle() == style )
456  {
457  //no change
458  return;
459  }
460  mSettings.setLineCapStyle( style );
462  update();
463  emit changed();
464 }
465 
467 {
468  //style
469  mStyle = std::make_unique< QgsSingleBoxScaleBarRenderer >();
470 
471  //default to no background
472  setBackgroundEnabled( false );
473 
474  //get default composer font from settings
475  const QgsSettings settings;
476  const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
477  QgsTextFormat format;
478  QFont f;
479  if ( !defaultFontString.isEmpty() )
480  {
481  f.setFamily( defaultFontString );
482  }
483  format.setFont( f );
484  format.setSize( 12.0 );
486 
487  mSettings.setTextFormat( format );
488 
490  refreshItemSize();
491 
492  emit changed();
493 }
494 
496 {
497  return renderer->applyDefaultSettings( mSettings );
498 }
499 
501 {
502  if ( !mMap )
504 
505  const QgsCoordinateReferenceSystem crs = mMap->crs();
506  // start with crs units
509  {
510  // geographic CRS, use metric units
512  }
513 
514  // try to pick reasonable choice between metric / imperial units
515  const double widthInSelectedUnits = mapWidth();
516  const double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
517  switch ( unit )
518  {
520  {
521  if ( initialUnitsPerSegment > 1000.0 )
522  {
524  }
525  break;
526  }
528  {
529  if ( initialUnitsPerSegment > 5419.95 )
530  {
532  }
533  break;
534  }
535  default:
536  break;
537  }
538 
539  return unit;
540 }
541 
543 {
544  mSettings.setUnits( units );
545  if ( mMap )
546  {
547  double upperMagnitudeMultiplier = 1.0;
548  const double widthInSelectedUnits = mapWidth();
549  const double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
550  mSettings.setUnitsPerSegment( initialUnitsPerSegment );
551 
553  upperMagnitudeMultiplier = 1;
554 
555  const double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier;
556  const int segmentMagnitude = std::floor( std::log10( segmentWidth ) );
557  double unitsPerSegment = upperMagnitudeMultiplier * ( std::pow( 10.0, segmentMagnitude ) );
558  const double multiplier = std::floor( ( widthInSelectedUnits / ( unitsPerSegment * 10.0 ) ) / 2.5 ) * 2.5;
559 
560  if ( multiplier > 0 )
561  {
562  unitsPerSegment = unitsPerSegment * multiplier;
563  }
564  mSettings.setUnitsPerSegment( unitsPerSegment );
565  mSettings.setMapUnitsPerScaleBarUnit( upperMagnitudeMultiplier );
566 
567  mSettings.setNumberOfSegments( 2 );
568  mSettings.setNumberOfSegmentsLeft( 0 );
569  }
570 
571  refreshSegmentMillimeters();
573  emit changed();
574 }
575 
577 {
578  if ( !mStyle )
579  return;
580 
582  const double widthMM = mStyle->calculateBoxSize( context, mSettings, createScaleContext() ).width();
583  QgsLayoutSize currentSize = sizeWithUnits();
584  currentSize.setWidth( mLayout->renderContext().measurementConverter().convert( QgsLayoutMeasurement( widthMM, QgsUnitTypes::LayoutMillimeters ), currentSize.units() ).length() );
585  attemptResize( currentSize );
586  update();
587  emit changed();
588 }
589 
591 {
592  //Don't adjust box size for numeric scale bars:
593  if ( mStyle && mStyle->id() != QLatin1String( "Numeric" ) )
594  {
595  refreshItemSize();
596  }
597  QgsLayoutItem::update();
598 }
599 
600 void QgsLayoutItemScaleBar::updateScale()
601 {
602  refreshSegmentMillimeters();
603  //Don't adjust box size for numeric scale bars:
604  if ( mStyle && mStyle->id() != QLatin1String( "Numeric" ) )
605  {
607  }
608  update();
609 }
610 
611 void QgsLayoutItemScaleBar::setStyle( const QString &styleName )
612 {
613  //switch depending on style name
614  std::unique_ptr< QgsScaleBarRenderer> renderer( QgsApplication::scaleBarRendererRegistry()->renderer( styleName ) );
615  if ( renderer )
616  {
617  mStyle = std::move( renderer );
618  }
619  refreshItemSize();
620  emit changed();
621 }
622 
624 {
625  if ( mStyle )
626  {
627  return mStyle->id();
628  }
629  else
630  {
631  return QString();
632  }
633 }
634 
636 {
637  return mSettings.numericFormat();
638 }
639 
641 {
642  mSettings.setNumericFormat( format );
643 }
644 
646 {
647  return mSettings.textFormat().font();
648 }
649 
650 void QgsLayoutItemScaleBar::setFont( const QFont &font )
651 {
653  mSettings.setFont( font );
655  refreshItemSize();
656  emit changed();
657 }
658 
660 {
661  QColor color = mSettings.textFormat().color();
662  color.setAlphaF( mSettings.textFormat().opacity() );
663  return color;
664 }
665 
666 void QgsLayoutItemScaleBar::setFontColor( const QColor &color )
667 {
668  mSettings.textFormat().setColor( color );
669  mSettings.textFormat().setOpacity( color.alphaF() );
670 }
671 
673 {
675  return mSettings.fillColor();
677 }
678 
679 void QgsLayoutItemScaleBar::setFillColor( const QColor &color )
680 {
682  mSettings.setFillColor( color );
684 }
685 
687 {
689  return mSettings.fillColor2();
691 }
692 
693 void QgsLayoutItemScaleBar::setFillColor2( const QColor &color )
694 {
696  mSettings.setFillColor2( color );
698 }
699 
701 {
703  return mSettings.lineColor();
705 }
706 
707 void QgsLayoutItemScaleBar::setLineColor( const QColor &color )
708 {
710  mSettings.setLineColor( color );
712 }
713 
715 {
717  return mSettings.lineWidth();
719 }
720 
722 {
724  mSettings.setLineWidth( width );
726 }
727 
729 {
731  return mSettings.pen();
733 }
734 
736 {
738  return mSettings.brush();
740 }
741 
743 {
745  return mSettings.brush2();
747 }
748 
749 bool QgsLayoutItemScaleBar::writePropertiesToElement( QDomElement &composerScaleBarElem, QDomDocument &doc, const QgsReadWriteContext &rwContext ) const
750 {
751  composerScaleBarElem.setAttribute( QStringLiteral( "height" ), QString::number( mSettings.height() ) );
752  composerScaleBarElem.setAttribute( QStringLiteral( "labelBarSpace" ), QString::number( mSettings.labelBarSpace() ) );
753  composerScaleBarElem.setAttribute( QStringLiteral( "boxContentSpace" ), QString::number( mSettings.boxContentSpace() ) );
754  composerScaleBarElem.setAttribute( QStringLiteral( "numSegments" ), mSettings.numberOfSegments() );
755  composerScaleBarElem.setAttribute( QStringLiteral( "numSegmentsLeft" ), mSettings.numberOfSegmentsLeft() );
756  composerScaleBarElem.setAttribute( QStringLiteral( "numSubdivisions" ), mSettings.numberOfSubdivisions() );
757  composerScaleBarElem.setAttribute( QStringLiteral( "subdivisionsHeight" ), mSettings.subdivisionsHeight() );
758  composerScaleBarElem.setAttribute( QStringLiteral( "numUnitsPerSegment" ), QString::number( mSettings.unitsPerSegment() ) );
759  composerScaleBarElem.setAttribute( QStringLiteral( "segmentSizeMode" ), mSettings.segmentSizeMode() );
760  composerScaleBarElem.setAttribute( QStringLiteral( "minBarWidth" ), mSettings.minimumBarWidth() );
761  composerScaleBarElem.setAttribute( QStringLiteral( "maxBarWidth" ), mSettings.maximumBarWidth() );
762  composerScaleBarElem.setAttribute( QStringLiteral( "segmentMillimeters" ), QString::number( mSegmentMillimeters ) );
763  composerScaleBarElem.setAttribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QString::number( mSettings.mapUnitsPerScaleBarUnit() ) );
764 
765  const QDomElement textElem = mSettings.textFormat().writeXml( doc, rwContext );
766  composerScaleBarElem.appendChild( textElem );
767 
769  // kept just for allowing projects to open in QGIS < 3.14, remove for 4.0
770  composerScaleBarElem.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mSettings.lineWidth() ) );
771  composerScaleBarElem.setAttribute( QStringLiteral( "lineJoinStyle" ), QgsSymbolLayerUtils::encodePenJoinStyle( mSettings.lineJoinStyle() ) );
772  composerScaleBarElem.setAttribute( QStringLiteral( "lineCapStyle" ), QgsSymbolLayerUtils::encodePenCapStyle( mSettings.lineCapStyle() ) );
773  //pen color
774  QDomElement strokeColorElem = doc.createElement( QStringLiteral( "strokeColor" ) );
775  strokeColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.lineColor().red() ) );
776  strokeColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.lineColor().green() ) );
777  strokeColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.lineColor().blue() ) );
778  strokeColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.lineColor().alpha() ) );
779  composerScaleBarElem.appendChild( strokeColorElem );
781 
782  composerScaleBarElem.setAttribute( QStringLiteral( "unitLabel" ), mSettings.unitLabel() );
783  composerScaleBarElem.setAttribute( QStringLiteral( "unitType" ), QgsUnitTypes::encodeUnit( mSettings.units() ) );
784 
785  QDomElement numericFormatElem = doc.createElement( QStringLiteral( "numericFormat" ) );
786  mSettings.numericFormat()->writeXml( numericFormatElem, doc, rwContext );
787  composerScaleBarElem.appendChild( numericFormatElem );
788 
789  //style
790  if ( mStyle )
791  {
792  composerScaleBarElem.setAttribute( QStringLiteral( "style" ), mStyle->id() );
793  }
794 
795  //map id
796  if ( mMap )
797  {
798  composerScaleBarElem.setAttribute( QStringLiteral( "mapUuid" ), mMap->uuid() );
799  }
800 
801  //colors
802 
804  // kept just for allowing projects to open in QGIS < 3.14, remove for 4.0
805 
806  //fill color
807  QDomElement fillColorElem = doc.createElement( QStringLiteral( "fillColor" ) );
808  fillColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.fillColor().red() ) );
809  fillColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.fillColor().green() ) );
810  fillColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.fillColor().blue() ) );
811  fillColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.fillColor().alpha() ) );
812  composerScaleBarElem.appendChild( fillColorElem );
813 
814  //fill color 2
815  QDomElement fillColor2Elem = doc.createElement( QStringLiteral( "fillColor2" ) );
816  fillColor2Elem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.fillColor2().red() ) );
817  fillColor2Elem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.fillColor2().green() ) );
818  fillColor2Elem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.fillColor2().blue() ) );
819  fillColor2Elem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.fillColor2().alpha() ) );
820  composerScaleBarElem.appendChild( fillColor2Elem );
821 
823 
824  //label vertical/horizontal placement
825  composerScaleBarElem.setAttribute( QStringLiteral( "labelVerticalPlacement" ), QString::number( static_cast< int >( mSettings.labelVerticalPlacement() ) ) );
826  composerScaleBarElem.setAttribute( QStringLiteral( "labelHorizontalPlacement" ), QString::number( static_cast< int >( mSettings.labelHorizontalPlacement() ) ) );
827 
828  //alignment
829  composerScaleBarElem.setAttribute( QStringLiteral( "alignment" ), QString::number( static_cast< int >( mSettings.alignment() ) ) );
830 
831  QDomElement lineSymbol = doc.createElement( QStringLiteral( "lineSymbol" ) );
832  const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QString(),
833  mSettings.lineSymbol(),
834  doc,
835  rwContext );
836  lineSymbol.appendChild( symbolElem );
837  composerScaleBarElem.appendChild( lineSymbol );
838 
839  QDomElement divisionSymbol = doc.createElement( QStringLiteral( "divisionLineSymbol" ) );
840  const QDomElement divisionSymbolElem = QgsSymbolLayerUtils::saveSymbol( QString(),
841  mSettings.divisionLineSymbol(),
842  doc,
843  rwContext );
844  divisionSymbol.appendChild( divisionSymbolElem );
845  composerScaleBarElem.appendChild( divisionSymbol );
846 
847  QDomElement subdivisionSymbol = doc.createElement( QStringLiteral( "subdivisionLineSymbol" ) );
848  const QDomElement subdivisionSymbolElem = QgsSymbolLayerUtils::saveSymbol( QString(),
849  mSettings.subdivisionLineSymbol(),
850  doc,
851  rwContext );
852  subdivisionSymbol.appendChild( subdivisionSymbolElem );
853  composerScaleBarElem.appendChild( subdivisionSymbol );
854 
855  QDomElement fillSymbol1Elem = doc.createElement( QStringLiteral( "fillSymbol1" ) );
856  const QDomElement symbol1Elem = QgsSymbolLayerUtils::saveSymbol( QString(),
857  mSettings.fillSymbol(),
858  doc,
859  rwContext );
860  fillSymbol1Elem.appendChild( symbol1Elem );
861  composerScaleBarElem.appendChild( fillSymbol1Elem );
862 
863  QDomElement fillSymbol2Elem = doc.createElement( QStringLiteral( "fillSymbol2" ) );
864  const QDomElement symbol2Elem = QgsSymbolLayerUtils::saveSymbol( QString(),
865  mSettings.alternateFillSymbol(),
866  doc,
867  rwContext );
868  fillSymbol2Elem.appendChild( symbol2Elem );
869  composerScaleBarElem.appendChild( fillSymbol2Elem );
870 
871  return true;
872 }
873 
874 bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context )
875 {
876  mSettings.setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() );
877  mSettings.setLabelBarSpace( itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble() );
878  mSettings.setBoxContentSpace( itemElem.attribute( QStringLiteral( "boxContentSpace" ), QStringLiteral( "1.0" ) ).toDouble() );
879  mSettings.setNumberOfSegments( itemElem.attribute( QStringLiteral( "numSegments" ), QStringLiteral( "2" ) ).toInt() );
880  mSettings.setNumberOfSegmentsLeft( itemElem.attribute( QStringLiteral( "numSegmentsLeft" ), QStringLiteral( "0" ) ).toInt() );
881  mSettings.setNumberOfSubdivisions( itemElem.attribute( QStringLiteral( "numSubdivisions" ), QStringLiteral( "1" ) ).toInt() );
882  mSettings.setSubdivisionsHeight( itemElem.attribute( QStringLiteral( "subdivisionsHeight" ), QStringLiteral( "1.5" ) ).toDouble() );
883  mSettings.setUnitsPerSegment( itemElem.attribute( QStringLiteral( "numUnitsPerSegment" ), QStringLiteral( "1.0" ) ).toDouble() );
884  mSettings.setSegmentSizeMode( static_cast<QgsScaleBarSettings::SegmentSizeMode>( itemElem.attribute( QStringLiteral( "segmentSizeMode" ), QStringLiteral( "0" ) ).toInt() ) );
885  mSettings.setMinimumBarWidth( itemElem.attribute( QStringLiteral( "minBarWidth" ), QStringLiteral( "50" ) ).toDouble() );
886  mSettings.setMaximumBarWidth( itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toDouble() );
887  mSegmentMillimeters = itemElem.attribute( QStringLiteral( "segmentMillimeters" ), QStringLiteral( "0.0" ) ).toDouble();
888  mSettings.setMapUnitsPerScaleBarUnit( itemElem.attribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QStringLiteral( "1.0" ) ).toDouble() );
889 
890  const QDomElement lineSymbolElem = itemElem.firstChildElement( QStringLiteral( "lineSymbol" ) );
891  bool foundLineSymbol = false;
892  if ( !lineSymbolElem.isNull() )
893  {
894  const QDomElement symbolElem = lineSymbolElem.firstChildElement( QStringLiteral( "symbol" ) );
895  std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
896  if ( lineSymbol )
897  {
898  mSettings.setLineSymbol( lineSymbol.release() );
899  foundLineSymbol = true;
900  }
901  }
902  const QDomElement divisionSymbolElem = itemElem.firstChildElement( QStringLiteral( "divisionLineSymbol" ) );
903  if ( !divisionSymbolElem.isNull() )
904  {
905  const QDomElement symbolElem = divisionSymbolElem.firstChildElement( QStringLiteral( "symbol" ) );
906  std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
907  if ( lineSymbol )
908  {
909  mSettings.setDivisionLineSymbol( lineSymbol.release() );
910  }
911  }
912  else if ( foundLineSymbol )
913  {
914  mSettings.setDivisionLineSymbol( mSettings.lineSymbol()->clone() );
915  }
916  const QDomElement subdivisionSymbolElem = itemElem.firstChildElement( QStringLiteral( "subdivisionLineSymbol" ) );
917  if ( !subdivisionSymbolElem.isNull() )
918  {
919  const QDomElement symbolElem = subdivisionSymbolElem.firstChildElement( QStringLiteral( "symbol" ) );
920  std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
921  if ( lineSymbol )
922  {
923  mSettings.setSubdivisionLineSymbol( lineSymbol.release() );
924  }
925  }
926  else if ( foundLineSymbol )
927  {
928  mSettings.setSubdivisionLineSymbol( mSettings.lineSymbol()->clone() );
929  }
930 
931  if ( !foundLineSymbol )
932  {
933  // old project compatibility
934  std::unique_ptr< QgsLineSymbol > lineSymbol = std::make_unique< QgsLineSymbol >();
935  std::unique_ptr< QgsSimpleLineSymbolLayer > lineSymbolLayer = std::make_unique< QgsSimpleLineSymbolLayer >();
936  lineSymbolLayer->setWidth( itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "0.3" ) ).toDouble() );
937  lineSymbolLayer->setWidthUnit( QgsUnitTypes::RenderMillimeters );
938  lineSymbolLayer->setPenJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "lineJoinStyle" ), QStringLiteral( "miter" ) ) ) );
939  lineSymbolLayer->setPenCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( itemElem.attribute( QStringLiteral( "lineCapStyle" ), QStringLiteral( "square" ) ) ) );
940 
941  //stroke color
942  const QDomNodeList strokeColorList = itemElem.elementsByTagName( QStringLiteral( "strokeColor" ) );
943  if ( !strokeColorList.isEmpty() )
944  {
945  const QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
946  bool redOk, greenOk, blueOk, alphaOk;
947  int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
948 
949  strokeRed = strokeColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
950  strokeGreen = strokeColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
951  strokeBlue = strokeColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
952  strokeAlpha = strokeColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
953 
954  if ( redOk && greenOk && blueOk && alphaOk )
955  {
956  lineSymbolLayer->setColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
957  }
958  }
959  else
960  {
961  lineSymbolLayer->setColor( QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ) );
962  }
963 
964  // need to translate the deprecated ScalebarLineWidth and ScalebarLineColor properties to symbol properties,
965  // and then remove them from the scalebar so they don't interfere and apply to other compatibility workarounds
966  lineSymbolLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyStrokeWidth, dataDefinedProperties().property( QgsLayoutObject::ScalebarLineWidth ) );
968  lineSymbolLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyStrokeColor, dataDefinedProperties().property( QgsLayoutObject::ScalebarLineColor ) );
970 
971  lineSymbol->changeSymbolLayer( 0, lineSymbolLayer.release() );
972  mSettings.setLineSymbol( lineSymbol->clone() );
973  mSettings.setDivisionLineSymbol( lineSymbol->clone() );
974  mSettings.setSubdivisionLineSymbol( lineSymbol.release() );
975  }
976 
977  mSettings.setUnitLabel( itemElem.attribute( QStringLiteral( "unitLabel" ) ) );
978 
979  const QDomNodeList textFormatNodeList = itemElem.elementsByTagName( QStringLiteral( "text-style" ) );
980  if ( !textFormatNodeList.isEmpty() )
981  {
982  const QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
983  mSettings.textFormat().readXml( textFormatElem, context );
984  }
985  else
986  {
987  QFont f;
988  if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, QStringLiteral( "scaleBarFont" ) ) )
989  {
990  f.fromString( itemElem.attribute( QStringLiteral( "font" ), QString() ) );
991  }
992  mSettings.textFormat().setFont( f );
993  if ( f.pointSizeF() > 0 )
994  {
995  mSettings.textFormat().setSize( f.pointSizeF() );
997  }
998  else if ( f.pixelSize() > 0 )
999  {
1000  mSettings.textFormat().setSize( f.pixelSize() );
1002  }
1003  }
1004 
1005  const QDomNodeList numericFormatNodeList = itemElem.elementsByTagName( QStringLiteral( "numericFormat" ) );
1006  if ( !numericFormatNodeList.isEmpty() )
1007  {
1008  const QDomElement numericFormatElem = numericFormatNodeList.at( 0 ).toElement();
1009  mSettings.setNumericFormat( QgsApplication::numericFormatRegistry()->createFromXml( numericFormatElem, context ) );
1010  }
1011 
1012  const QDomElement fillSymbol1Elem = itemElem.firstChildElement( QStringLiteral( "fillSymbol1" ) );
1013  bool foundFillSymbol1 = false;
1014  if ( !fillSymbol1Elem.isNull() )
1015  {
1016  const QDomElement symbolElem = fillSymbol1Elem.firstChildElement( QStringLiteral( "symbol" ) );
1017  std::unique_ptr< QgsFillSymbol > fillSymbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context ) );
1018  if ( fillSymbol )
1019  {
1020  mSettings.setFillSymbol( fillSymbol.release() );
1021  foundFillSymbol1 = true;
1022  }
1023  }
1024  if ( !foundFillSymbol1 )
1025  {
1026  // old project compatibility
1027  std::unique_ptr< QgsFillSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1028  std::unique_ptr< QgsSimpleFillSymbolLayer > fillSymbolLayer = std::make_unique< QgsSimpleFillSymbolLayer >();
1029  fillSymbolLayer->setStrokeStyle( Qt::NoPen );
1030 
1031  //fill color
1032  const QDomNodeList fillColorList = itemElem.elementsByTagName( QStringLiteral( "fillColor" ) );
1033  if ( !fillColorList.isEmpty() )
1034  {
1035  const QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
1036  bool redOk, greenOk, blueOk, alphaOk;
1037  int fillRed, fillGreen, fillBlue, fillAlpha;
1038 
1039  fillRed = fillColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1040  fillGreen = fillColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1041  fillBlue = fillColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1042  fillAlpha = fillColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1043 
1044  if ( redOk && greenOk && blueOk && alphaOk )
1045  {
1046  fillSymbolLayer->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1047  }
1048  }
1049  else
1050  {
1051  fillSymbolLayer->setColor( QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ) );
1052  }
1053 
1054  // need to translate the deprecated ScalebarFillColor property to symbol properties,
1055  // and then remove them from the scalebar so they don't interfere and apply to other compatibility workarounds
1056  fillSymbolLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyFillColor, dataDefinedProperties().property( QgsLayoutObject::ScalebarFillColor ) );
1058 
1059  fillSymbol->changeSymbolLayer( 0, fillSymbolLayer.release() );
1060  mSettings.setFillSymbol( fillSymbol.release() );
1061  }
1062 
1063  const QDomElement fillSymbol2Elem = itemElem.firstChildElement( QStringLiteral( "fillSymbol2" ) );
1064  bool foundFillSymbol2 = false;
1065  if ( !fillSymbol2Elem.isNull() )
1066  {
1067  const QDomElement symbolElem = fillSymbol2Elem.firstChildElement( QStringLiteral( "symbol" ) );
1068  std::unique_ptr< QgsFillSymbol > fillSymbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context ) );
1069  if ( fillSymbol )
1070  {
1071  mSettings.setAlternateFillSymbol( fillSymbol.release() );
1072  foundFillSymbol2 = true;
1073  }
1074  }
1075  if ( !foundFillSymbol2 )
1076  {
1077  // old project compatibility
1078  std::unique_ptr< QgsFillSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1079  std::unique_ptr< QgsSimpleFillSymbolLayer > fillSymbolLayer = std::make_unique< QgsSimpleFillSymbolLayer >();
1080  fillSymbolLayer->setStrokeStyle( Qt::NoPen );
1081 
1082  //fill color 2
1083 
1084  const QDomNodeList fillColor2List = itemElem.elementsByTagName( QStringLiteral( "fillColor2" ) );
1085  if ( !fillColor2List.isEmpty() )
1086  {
1087  const QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
1088  bool redOk, greenOk, blueOk, alphaOk;
1089  int fillRed, fillGreen, fillBlue, fillAlpha;
1090 
1091  fillRed = fillColor2Elem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1092  fillGreen = fillColor2Elem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1093  fillBlue = fillColor2Elem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1094  fillAlpha = fillColor2Elem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1095 
1096  if ( redOk && greenOk && blueOk && alphaOk )
1097  {
1098  fillSymbolLayer->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1099  }
1100  }
1101  else
1102  {
1103  fillSymbolLayer->setColor( QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ) );
1104  }
1105 
1106  // need to translate the deprecated ScalebarFillColor2 property to symbol properties,
1107  // and then remove them from the scalebar so they don't interfere and apply to other compatibility workarounds
1108  fillSymbolLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyFillColor, dataDefinedProperties().property( QgsLayoutObject::ScalebarFillColor2 ) );
1110 
1111  fillSymbol->changeSymbolLayer( 0, fillSymbolLayer.release() );
1112  mSettings.setAlternateFillSymbol( fillSymbol.release() );
1113 
1114  }
1115 
1116  //font color
1117  const QDomNodeList textColorList = itemElem.elementsByTagName( QStringLiteral( "textColor" ) );
1118  if ( !textColorList.isEmpty() )
1119  {
1120  const QDomElement textColorElem = textColorList.at( 0 ).toElement();
1121  bool redOk, greenOk, blueOk, alphaOk;
1122  int textRed, textGreen, textBlue, textAlpha;
1123 
1124  textRed = textColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1125  textGreen = textColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1126  textBlue = textColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1127  textAlpha = textColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1128 
1129  if ( redOk && greenOk && blueOk && alphaOk )
1130  {
1131  mSettings.textFormat().setColor( QColor( textRed, textGreen, textBlue, textAlpha ) );
1132  }
1133  }
1134  else if ( itemElem.hasAttribute( QStringLiteral( "fontColor" ) ) )
1135  {
1136  QColor c;
1137  c.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
1138  mSettings.textFormat().setColor( c );
1139  }
1140 
1141  //style
1142  setStyle( itemElem.attribute( QStringLiteral( "style" ), QString() ) );
1143 
1144  //call attemptResize after setStyle to ensure the appropriate size limitations are applied
1145  attemptResize( QgsLayoutSize::decodeSize( itemElem.attribute( QStringLiteral( "size" ) ) ) );
1146 
1147  if ( itemElem.attribute( QStringLiteral( "unitType" ) ).isEmpty() )
1148  {
1150  switch ( itemElem.attribute( QStringLiteral( "units" ) ).toInt() )
1151  {
1152  case 0:
1154  break;
1155  case 1:
1157  break;
1158  case 2:
1160  break;
1161  case 3:
1163  break;
1164  }
1165  mSettings.setUnits( u );
1166  }
1167  else
1168  {
1169  mSettings.setUnits( QgsUnitTypes::decodeDistanceUnit( itemElem.attribute( QStringLiteral( "unitType" ) ) ) );
1170  }
1171 
1172  mSettings.setLabelVerticalPlacement( static_cast< QgsScaleBarSettings::LabelVerticalPlacement >( itemElem.attribute( QStringLiteral( "labelVerticalPlacement" ), QStringLiteral( "0" ) ).toInt() ) );
1173  mSettings.setLabelHorizontalPlacement( static_cast< QgsScaleBarSettings::LabelHorizontalPlacement >( itemElem.attribute( QStringLiteral( "labelHorizontalPlacement" ), QStringLiteral( "0" ) ).toInt() ) );
1174 
1175  mSettings.setAlignment( static_cast< QgsScaleBarSettings::Alignment >( itemElem.attribute( QStringLiteral( "alignment" ), QStringLiteral( "0" ) ).toInt() ) );
1176 
1177  //map
1178  disconnectCurrentMap();
1179  mMap = nullptr;
1180  mMapUuid = itemElem.attribute( QStringLiteral( "mapUuid" ) );
1181  return true;
1182 }
1183 
1184 
1186 {
1187  if ( mLayout && !mMapUuid.isEmpty() )
1188  {
1189  disconnectCurrentMap();
1190  mMap = qobject_cast< QgsLayoutItemMap * >( mLayout->itemByUuid( mMapUuid, true ) );
1191  if ( mMap )
1192  {
1193  connect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateScale );
1194  connect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
1195  }
1196  }
1197 
1198  updateScale();
1199 }
1200 
1202 {
1203  QgsStyleTextFormatEntity entity( mSettings.textFormat() );
1204  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, uuid(), displayName() ) ) )
1205  return false;
1206 
1207  return true;
1208 }
1209 
1211 {
1213 }
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
static QgsScaleBarRendererRegistry * scaleBarRendererRegistry()
Gets the registry of available scalebar renderers.
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This class represents a coordinate reference system (CRS).
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
QgsUnitTypes::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
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
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
double scale() const
Returns the map scale.
QgsRectangle extent() const
Returns the current map extent.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
@ LayoutScaleBar
Scale bar item.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:45
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgslayoutitem.h:72
A layout item subclass for scale bars.
void setNumberOfSegments(int segments)
Sets the number of segments included in the scalebar.
Q_DECL_DEPRECATED QBrush brush() const
Returns the primary brush for the scalebar.
Q_DECL_DEPRECATED QColor fillColor2() const
Returns the secondary color used for fills in the scalebar.
Q_DECL_DEPRECATED double lineWidth() const
Returns the line width in millimeters for lines in the scalebar.
QIcon icon() const override
Returns the item's icon.
Q_DECL_DEPRECATED void setFillColor(const QColor &color)
Sets the color used for fills in the scalebar.
void setLabelHorizontalPlacement(QgsScaleBarSettings::LabelHorizontalPlacement placement)
Sets the horizontal placement of text labels.
QgsLineSymbol * divisionLineSymbol() const
Returns the line symbol used to render the scalebar divisions (only used for some scalebar types).
QgsFillSymbol * alternateFillSymbol() const
Returns the secondary fill symbol used to render the scalebar (only used for some scalebar types).
Q_DECL_DEPRECATED QBrush brush2() const
Returns the secondary brush for the scalebar.
void setMinimumBarWidth(double minWidth)
Sets the minimum width (in millimeters) for scale bar segments.
QgsFillSymbol * fillSymbol() const
Returns the primary fill symbol used to render the scalebar (only used for some scalebar types).
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
Q_DECL_DEPRECATED QColor fontColor() const
Returns the color used for drawing text in the scalebar.
void setMaximumBarWidth(double maxWidth)
Sets the maximum width (in millimeters) for scale bar segments.
Q_DECL_DEPRECATED QColor fillColor() const
Returns the color used for fills in the scalebar.
void setSegmentSizeMode(QgsScaleBarSettings::SegmentSizeMode mode)
Sets the size mode for scale bar segments.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for numbers in the scalebar.
Q_DECL_DEPRECATED void setLineColor(const QColor &color)
Sets the color used for lines in the scalebar.
void setDivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar divisions (only used for some scalebar types).
Q_DECL_DEPRECATED QColor lineColor() const
Returns the color used for lines in the scalebar.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void update()
Adjusts the scale bar box size and updates the item.
void setFillSymbol(QgsFillSymbol *symbol)
Sets the primary fill symbol used to render the scalebar (only used for some scalebar types).
void setLabelVerticalPlacement(QgsScaleBarSettings::LabelVerticalPlacement placement)
Sets the vertical placement of text labels.
double unitsPerSegment() const
Returns the number of scalebar units per segment.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool applyDefaultRendererSettings(QgsScaleBarRenderer *renderer)
Applies any default settings relating to the specified renderer to the item.
void setUnits(QgsUnitTypes::DistanceUnit units)
Sets the distance units used by the scalebar.
QgsLineSymbol * subdivisionLineSymbol() const
Returns the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
QgsUnitTypes::DistanceUnit guessUnits() const
Attempts to guess the most reasonable unit choice for the scalebar, given the current linked map's sc...
Q_DECL_DEPRECATED QFont font() const
Returns the font used for drawing text in the scalebar.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setAlignment(QgsScaleBarSettings::Alignment alignment)
Sets the scalebar alignment.
void setAlternateFillSymbol(QgsFillSymbol *symbol)
Sets the secondary fill symbol used to render the scalebar (only used for some scalebar types).
void applyDefaultSize(QgsUnitTypes::DistanceUnit units=QgsUnitTypes::DistanceMeters)
Applies the default size to the scale bar (scale bar 1/5 of map item width)
int type() const override
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar (only used for some scalebar types).
void setStyle(const QString &name)
Sets the scale bar style by name.
Q_DECL_DEPRECATED void setFillColor2(const QColor &color)
Sets the secondary color used for fills in the scalebar.
void applyDefaultSettings()
Applies the default scalebar settings to the scale bar.
Q_DECL_DEPRECATED Qt::PenCapStyle lineCapStyle() const
Returns the cap style used for drawing lines in the scalebar.
void setNumberOfSegmentsLeft(int segments)
Sets the number of segments included in the left part of the scalebar.
Q_DECL_DEPRECATED Qt::PenJoinStyle lineJoinStyle() const
Returns the join style used for drawing lines in the scalebar.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for drawing text in the scalebar.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map item linked to the scalebar.
QgsLayoutSize minimumSize() const override
Returns the minimum allowed size of the item, if applicable, or an empty size if item can be freely r...
Q_DECL_DEPRECATED void setLineJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the lines in the scalebar.
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render the scalebar (only used for some scalebar types).
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties) override
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
Q_DECL_DEPRECATED void setFontColor(const QColor &color)
Sets the color used for drawing text in the scalebar.
Q_DECL_DEPRECATED void setLineWidth(double width)
Sets the line width in millimeters for lines in the scalebar.
Q_DECL_DEPRECATED QPen pen() const
Returns the pen used for drawing outlines in the scalebar.
void setBoxContentSpace(double space)
Sets the space (margin) between the scalebar box and content in millimeters.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for numbers in the scalebar.
void setUnitLabel(const QString &label)
Sets the label for units.
QString style() const
Returns the scale bar style name.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsTextFormat textFormat() const
Returns the text format used for drawing text in the scalebar.
Q_DECL_DEPRECATED void setLineCapStyle(Qt::PenCapStyle style)
Sets the cap style used when drawing the lines in the scalebar.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
void resizeToMinimumWidth()
Resizes the scale bar to its minimum width, without changing the height.
void setUnitsPerSegment(double units)
Sets the number of scalebar units per segment.
static QgsLayoutItemScaleBar * create(QgsLayout *layout)
Returns a new scale bar item for the specified layout.
Q_DECL_DEPRECATED void setFont(const QFont &font)
Sets the font used for drawing text in the scalebar.
void setSubdivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
QgsUnitTypes::DistanceUnit units() const
Returns the distance units used by the scalebar.
QgsLayoutItemScaleBar(QgsLayout *layout)
Constructor for QgsLayoutItemScaleBar, with the specified parent layout.
Base class for graphical items within a QgsLayout.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
void refreshItemSize()
Refreshes an item's size by rechecking it against any possible item fixed or minimum sizes.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual QString displayName() const
Gets item display name.
virtual void attemptResize(const QgsLayoutSize &size, bool includesFrame=false)
Attempts to resize the item to a specified target size.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual QString uuid() const
Returns the item identification string.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ CanGroupWithItemsOfSameType
Item can only be placed on layers with other items of the same type, but multiple items of this type ...
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
@ ScalebarFillColor2
Scalebar secondary fill color (deprecated, use data defined properties on scalebar fill symbol 2 inst...
@ ScalebarLineWidth
Scalebar line width (deprecated, use data defined properties on scalebar line symbol instead)
@ AllProperties
All properties for item.
@ ScalebarFillColor
Scalebar fill color (deprecated, use data defined properties on scalebar fill symbol 1 instead)
@ ScalebarLineColor
Scalebar line color (deprecated, use data defined properties on scalebar line symbol instead)
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:41
static QgsLayoutSize decodeSize(const QString &string)
Decodes a size from a string.
QgsUnitTypes::LayoutUnit units() const
Returns the units for the size.
void setWidth(const double width)
Sets the width for the size.
Definition: qgslayoutsize.h:83
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
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
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
A numeric formatter allows for formatting a numeric value for display, using a variety of different f...
void writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes the format to an XML element.
A class to represent a 2D point.
Definition: qgspointxy.h:59
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
A store for object properties.
Definition: qgsproperty.h:232
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
Contains information about the context of a rendering operation.
Abstract base class for scale bar renderers.
virtual bool applyDefaultSettings(QgsScaleBarSettings &settings) const
Applies any default settings relating to the scalebar to the passed settings object.
double subdivisionsHeight() const
Returns the scalebar subdivisions height (in millimeters) for segments included in the right part of ...
void setSubdivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
Q_DECL_DEPRECATED QColor fillColor() const
Returns the color used for fills in the scalebar.
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render the scalebar (only used for some scalebar types).
void setAlignment(Alignment alignment)
Sets the scalebar alignment.
QgsLineSymbol * subdivisionLineSymbol() const
Returns the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
Q_DECL_DEPRECATED QColor fillColor2() const
Returns the secondary color used for fills in the scalebar.
void setAlternateFillSymbol(QgsFillSymbol *symbol)
Sets the secondary fill symbol used to render the scalebar (only used for some scalebar types).
SegmentSizeMode segmentSizeMode() const
Returns the size mode for the scale bar segments.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for numbers in the scalebar.
Q_DECL_DEPRECATED void setFillColor(const QColor &color)
Sets the color used for fills in the scalebar.
int numberOfSegments() const
Returns the number of segments included in the scalebar.
Q_DECL_DEPRECATED void setFillColor2(const QColor &color)
Sets the secondary color used for fills in the scalebar.
double maximumBarWidth() const
Returns the maximum width (in millimeters) for scale bar segments.
Q_DECL_DEPRECATED void setLineCapStyle(Qt::PenCapStyle style)
Sets the cap style used when drawing the lines in the scalebar.
QgsUnitTypes::DistanceUnit units() const
Returns the distance units used by the scalebar.
void setFillSymbol(QgsFillSymbol *symbol)
Sets the primary fill symbol used to render the scalebar (only used for some scalebar types).
double unitsPerSegment() const
Returns the number of scalebar units per segment.
Q_DECL_DEPRECATED void setLineJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the lines in the scalebar.
Q_DECL_DEPRECATED QPen pen() const
Returns the pen used for drawing outlines in the scalebar.
void setLabelVerticalPlacement(LabelVerticalPlacement placement)
Sets the vertical placement of text labels.
Q_DECL_DEPRECATED void setLineColor(const QColor &color)
Sets the color used for lines in the scalebar.
void setUnitLabel(const QString &label)
Sets the label for units.
LabelHorizontalPlacement labelHorizontalPlacement() const
Returns the horizontal placement of text labels.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar (only used for some scalebar types).
void setDivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar divisions (only used for some scalebar types).
void setBoxContentSpace(double space)
Sets the space (margin) between the scalebar box and content in millimeters.
Q_DECL_DEPRECATED void setLineWidth(double width)
Sets the line width in millimeters for lines in the scalebar.
Alignment alignment() const
Returns the scalebar alignment.
double boxContentSpace() const
Returns the spacing (margin) between the scalebar box and content in millimeters.
void setHeight(double height)
Sets the scalebar height (in millimeters).
QgsFillSymbol * alternateFillSymbol() const
Returns the secondary fill symbol used to render the scalebar (only used for some scalebar types).
void setUnits(QgsUnitTypes::DistanceUnit units)
Sets the distance units used by the scalebar.
QgsFillSymbol * fillSymbol() const
Returns the primary fill symbol used to render the scalebar (only used for some scalebar types).
Q_DECL_DEPRECATED double lineWidth() const
Returns the line width in millimeters for lines in the scalebar.
Q_DECL_DEPRECATED QBrush brush2() const
Returns the secondary brush for the scalebar.
Alignment
Scalebar alignment.
void setNumberOfSubdivisions(int subdivisions)
Sets the number of subdivisions for segments included in the right part of the scalebar (only used fo...
LabelVerticalPlacement labelVerticalPlacement() const
Returns the vertical placement of text labels.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for numbers in the scalebar.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for drawing text in the scalebar.
double minimumBarWidth() const
Returns the minimum width (in millimeters) for scale bar segments.
QString unitLabel() const
Returns the label for units.
int numberOfSubdivisions() const
Returns the number of subdivisions for segments included in the right part of the scalebar (only used...
Q_DECL_DEPRECATED QColor lineColor() const
Returns the color used for lines in the scalebar.
LabelHorizontalPlacement
Label horizontal placement.
void setLabelBarSpace(double space)
Sets the spacing (in millimeters) between labels and the scalebar.
void setNumberOfSegments(int segments)
Sets the number of segments included in the scalebar.
void setUnitsPerSegment(double units)
Sets the number of scalebar units per segment.
LabelVerticalPlacement
Label vertical placement.
Q_DECL_DEPRECATED Qt::PenCapStyle lineCapStyle() const
Returns the cap style used for drawing lines in the scalebar.
void setLabelHorizontalPlacement(LabelHorizontalPlacement placement)
Sets the horizontal placement of text labels.
void setSubdivisionsHeight(double height)
Sets the scalebar subdivisions height (in millimeters) for segments included in the right part of the...
double labelBarSpace() const
Returns the spacing (in millimeters) between labels and the scalebar.
QgsTextFormat & textFormat()
Returns the text format used for drawing text in the scalebar.
double height() const
Returns the scalebar height (in millimeters).
int numberOfSegmentsLeft() const
Returns the number of segments included in the left part of the scalebar.
Q_DECL_DEPRECATED void setFont(const QFont &font)
Sets the font used for drawing text in the scalebar.
SegmentSizeMode
Modes for setting size for scale bar segments.
@ SegmentSizeFitWidth
Scale bar segment size is calculated to fit a size range.
@ SegmentSizeFixed
Scale bar segment size is fixed to a map unit.
Q_DECL_DEPRECATED Qt::PenJoinStyle lineJoinStyle() const
Returns the join style used for drawing lines in the scalebar.
void setNumberOfSegmentsLeft(int segments)
Sets the number of segments included in the left part of the scalebar.
Q_DECL_DEPRECATED QBrush brush() const
Returns the primary brush used for filling the scalebar.
void setSegmentSizeMode(SegmentSizeMode mode)
Sets the size mode for scale bar segments.
QgsLineSymbol * divisionLineSymbol() const
Returns the line symbol used to render the scalebar divisions (only used for some scalebar types).
void setMapUnitsPerScaleBarUnit(double units)
Sets the number of map units per scale bar unit used by the scalebar.
double mapUnitsPerScaleBarUnit() const
Returns the number of map units per scale bar unit used by the scalebar.
void setMinimumBarWidth(double width)
Sets the minimum width (in millimeters) for scale bar segments.
void setMaximumBarWidth(double width)
Sets the maximum width (in millimeters) for scale bar segments.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A text format entity for QgsStyle databases.
Definition: qgsstyle.h:1282
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
static QString encodePenCapStyle(Qt::PenCapStyle style)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyStrokeColor
Stroke color.
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
Deletes the current layer at the specified index and replaces it with layer.
Definition: qgssymbol.cpp:473
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setOpacity(double opacity)
Sets the text's opacity.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
double opacity() const
Returns the text's opacity.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:75
@ DistanceKilometers
Kilometers.
Definition: qgsunittypes.h:70
@ DistanceMiles
Terrestrial miles.
Definition: qgsunittypes.h:74
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
@ DistanceNauticalMiles
Nautical miles.
Definition: qgsunittypes.h:72
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:183
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static Q_INVOKABLE QString toAbbreviatedString(QgsUnitTypes::DistanceUnit unit)
Returns a translated abbreviation representing a distance unit.
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:1730
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:1729
const QgsCoordinateReferenceSystem & crs
Contains parameters regarding scalebar calculations.
Flags flags
Scalebar renderer flags.
QSizeF size
Destination size for scalebar.
double segmentWidth
The width, in millimeters, of each individual segment drawn.
Contains information relating to the style entity currently being visited.