From b40bc0c1f7dd92c011e9e47a7dfcd5b564a9e54a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 21 Apr 2017 15:47:25 +1000 Subject: [PATCH 1/4] Refactor scale bar rendering Move all scalebar rendering code out of composer and ensure that all scalebar rendering is done independant of QgsComposerScaleBar This allows scalebar rendering code to be reused by plugins and by non-composer code. Also rename QgsScaleBarStyle -> QgsScaleBarRenderer, (and all subclasses too). This name better reflects what these classes do. --- doc/CMakeLists.txt | 1 + doc/api_break.dox | 13 + python/CMakeLists.txt | 1 + python/core/composer/qgscomposerscalebar.sip | 59 +-- .../composer/qgsdoubleboxscalebarstyle.sip | 13 - .../core/composer/qgsnumericscalebarstyle.sip | 16 - python/core/composer/qgsscalebarstyle.sip | 21 - .../composer/qgssingleboxscalebarstyle.sip | 17 - .../core/composer/qgsticksscalebarstyle.sip | 26 - python/core/core.sip | 13 +- .../scalebar/qgsdoubleboxscalebarrenderer.sip | 39 ++ .../scalebar/qgsnumericscalebarrenderer.sip | 42 ++ python/core/scalebar/qgsscalebarrenderer.sip | 114 +++++ python/core/scalebar/qgsscalebarsettings.sip | 399 +++++++++++++++ .../scalebar/qgssingleboxscalebarrenderer.sip | 41 ++ .../scalebar/qgsticksscalebarrenderer.sip | 61 +++ src/app/CMakeLists.txt | 1 + .../composer/qgscomposerscalebarwidget.cpp | 26 +- src/core/CMakeLists.txt | 24 +- src/core/composer/qgscomposerscalebar.cpp | 435 ++++++++--------- src/core/composer/qgscomposerscalebar.h | 171 ++----- .../composer/qgsdoubleboxscalebarstyle.cpp | 93 ---- src/core/composer/qgsnumericscalebarstyle.cpp | 123 ----- src/core/composer/qgsscalebarstyle.cpp | 132 ----- src/core/composer/qgsscalebarstyle.h | 58 --- .../composer/qgssingleboxscalebarstyle.cpp | 83 ---- src/core/composer/qgsticksscalebarstyle.cpp | 99 ---- src/core/composer/qgsticksscalebarstyle.h | 54 --- .../scalebar/qgsdoubleboxscalebarrenderer.cpp | 81 ++++ .../qgsdoubleboxscalebarrenderer.h} | 34 +- .../scalebar/qgsnumericscalebarrenderer.cpp | 75 +++ .../qgsnumericscalebarrenderer.h} | 42 +- src/core/scalebar/qgsscalebarrenderer.cpp | 172 +++++++ src/core/scalebar/qgsscalebarrenderer.h | 113 +++++ src/core/scalebar/qgsscalebarsettings.h | 456 ++++++++++++++++++ .../scalebar/qgssingleboxscalebarrenderer.cpp | 67 +++ .../qgssingleboxscalebarrenderer.h} | 36 +- .../scalebar/qgsticksscalebarrenderer.cpp | 92 ++++ src/core/scalebar/qgsticksscalebarrenderer.h | 66 +++ src/gui/CMakeLists.txt | 1 + src/gui/qgscomposerview.cpp | 2 +- tests/src/core/CMakeLists.txt | 1 + tests/src/core/testqgscomposerscalebar.cpp | 2 +- 43 files changed, 2189 insertions(+), 1226 deletions(-) mode change 100644 => 100755 doc/CMakeLists.txt mode change 100644 => 100755 python/CMakeLists.txt delete mode 100644 python/core/composer/qgsdoubleboxscalebarstyle.sip delete mode 100644 python/core/composer/qgsnumericscalebarstyle.sip delete mode 100644 python/core/composer/qgsscalebarstyle.sip delete mode 100644 python/core/composer/qgssingleboxscalebarstyle.sip delete mode 100644 python/core/composer/qgsticksscalebarstyle.sip create mode 100644 python/core/scalebar/qgsdoubleboxscalebarrenderer.sip create mode 100644 python/core/scalebar/qgsnumericscalebarrenderer.sip create mode 100644 python/core/scalebar/qgsscalebarrenderer.sip create mode 100644 python/core/scalebar/qgsscalebarsettings.sip create mode 100644 python/core/scalebar/qgssingleboxscalebarrenderer.sip create mode 100644 python/core/scalebar/qgsticksscalebarrenderer.sip delete mode 100644 src/core/composer/qgsdoubleboxscalebarstyle.cpp delete mode 100644 src/core/composer/qgsnumericscalebarstyle.cpp delete mode 100644 src/core/composer/qgsscalebarstyle.cpp delete mode 100644 src/core/composer/qgsscalebarstyle.h delete mode 100644 src/core/composer/qgssingleboxscalebarstyle.cpp delete mode 100644 src/core/composer/qgsticksscalebarstyle.cpp delete mode 100644 src/core/composer/qgsticksscalebarstyle.h create mode 100644 src/core/scalebar/qgsdoubleboxscalebarrenderer.cpp rename src/core/{composer/qgsdoubleboxscalebarstyle.h => scalebar/qgsdoubleboxscalebarrenderer.h} (55%) create mode 100644 src/core/scalebar/qgsnumericscalebarrenderer.cpp rename src/core/{composer/qgsnumericscalebarstyle.h => scalebar/qgsnumericscalebarrenderer.h} (51%) create mode 100644 src/core/scalebar/qgsscalebarrenderer.cpp create mode 100644 src/core/scalebar/qgsscalebarrenderer.h create mode 100644 src/core/scalebar/qgsscalebarsettings.h create mode 100644 src/core/scalebar/qgssingleboxscalebarrenderer.cpp rename src/core/{composer/qgssingleboxscalebarstyle.h => scalebar/qgssingleboxscalebarrenderer.h} (58%) create mode 100644 src/core/scalebar/qgsticksscalebarrenderer.cpp create mode 100644 src/core/scalebar/qgsticksscalebarrenderer.h mode change 100644 => 100755 tests/src/core/CMakeLists.txt diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt old mode 100644 new mode 100755 index 7fbac6694a5..44f660a1a5d --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -66,6 +66,7 @@ IF(WITH_APIDOC) ${CMAKE_SOURCE_DIR}/src/core/pal ${CMAKE_SOURCE_DIR}/src/core/processing ${CMAKE_SOURCE_DIR}/src/core/raster + ${CMAKE_SOURCE_DIR}/src/core/scalebar ${CMAKE_SOURCE_DIR}/src/core/symbology-ng ${CMAKE_SOURCE_DIR}/src/gui ${CMAKE_SOURCE_DIR}/src/gui/auth diff --git a/doc/api_break.dox b/doc/api_break.dox index 31bc97562b8..91a6eb149ba 100644 --- a/doc/api_break.dox +++ b/doc/api_break.dox @@ -85,6 +85,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes} QgsCurveV2QgsCurve QgsDbFilterProxyModelQgsDatabaseFilterProxyModel QgsDiagramRendererV2QgsDiagramRenderer +QgsDoubleBoxBarStyleQgsDoubleBoxScaleBarRenderer QgsEditorWidgetV2QgsEditorWidget QgsEllipseSymbolLayerV2QgsEllipseSymbolLayer QgsEllipseSymbolLayerV2WidgetQgsEllipseSymbolLayerWidget @@ -115,6 +116,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes} QgsMultiCurveV2QgsMultiCurve QgsMultiLineStringV2QgsMultiLineString QgsMultiSurfaceV2QgsMultiSurface +QgsNumericScaleBarStyleQgsNumericScaleBarRenderer QgsPointSequenceV2QgsPointSequence QgsPropertyQgsProjectProperty QgsPropertyKeyQgsProjectPropertyKey @@ -140,6 +142,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes} QgsRuleBasedRendererV2CountQgsRuleBasedRendererCount QgsRuleBasedRendererV2ModelQgsRuleBasedRendererModel QgsRuleBasedRendererV2WidgetQgsRuleBasedRendererWidget +QgsScaleBarStyleQgsScaleBarRenderer QgsShapeburstFillSymbolLayerV2QgsShapeburstFillSymbolLayer QgsShapeburstFillSymbolLayerV2WidgetQgsShapeburstFillSymbolLayerWidget QgsSimpleFillSymbolLayerV2QgsSimpleFillSymbolLayer @@ -148,6 +151,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes} QgsSimpleLineSymbolLayerV2WidgetQgsSimpleLineSymbolLayerWidget QgsSimpleMarkerSymbolLayerV2QgsSimpleMarkerSymbolLayer QgsSimpleMarkerSymbolLayerV2WidgetQgsSimpleMarkerSymbolLayerWidget +QgsSingleBoxScaleBarStyleQgsSingleBoxScaleBarRenderer QgsSingleSymbolRendererV2QgsSingleSymbolRenderer QgsSingleSymbolRendererV2WidgetQgsSingleSymbolRendererWidget QgsStyleV2QgsStyle @@ -171,6 +175,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes} QgsSymbolV2RenderContextQgsSymbolRenderContext QgsSymbolV2SelectorDialogQgsSymbolSelectorDialog QgsSymbolV2SelectorWidgetQgsSymbolSelectorWidget +QgsTicksScaleBarStyleQgsTicksScaleBarRenderer QgsVectorColorBrewerColorRampV2QgsColorBrewerColorRamp QgsVectorColorBrewerColorRampV2DialogQgsColorBrewerColorRampDialog QgsVectorColorBrewerColorRampV2DialogBaseQgsColorBrewerColorRampDialogBase @@ -684,9 +689,12 @@ QgsComposerObject::setDataDefinedProperty() instead. QgsComposerScaleBar {#qgis_api_break_3_0_QgsComposerScaleBar} ------------------- +- The Alignment and SegmentSizeMode enums were moved to QgsScaleBarSettings +- The ScaleBarUnits enum was removed. Use QgsUnitTypes::DistanceUnit instead. - setBrush() was removed. Use setFillColor() instead. - setBrush2() was removed. Use setFillColor2() instead. - setPen() was removed. Use setLineColor() and setLineWidth() instead. +- segmentMillimeters() and firstLabelString() were removed. QgsComposerTable {#qgis_api_break_3_0_QgsComposerTable} @@ -1837,6 +1845,11 @@ QgsRuntimeProfiler {#qgis_api_break_3_0_QgsRuntimeProfiler} - This class is no longer a singleton and instance() has been removed. Instead use QgsApplication::profiler() to access an application-wide profiler. +QgsScaleBarStyle {#qgis_api_break_3_0_QgsScaleBarStyle} +---------------- + +- The interface for QgsScaleBarStyle has been completely rewritten - any code using QgsScaleBarStyle or subclasses will need to update +to the new draw() and calculateBoxSize() methods. QgsServer {#qgis_api_break_3_0_QgsServer} ---------- diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt old mode 100644 new mode 100755 index 6f5da3bd70c..e3d8049a755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -107,6 +107,7 @@ INCLUDE_DIRECTORIES( ../src/core/layertree ../src/core/processing ../src/core/raster + ../src/core/scalebar ../src/core/symbology-ng ../src/gui/raster diff --git a/python/core/composer/qgscomposerscalebar.sip b/python/core/composer/qgscomposerscalebar.sip index 92e53e09107..f51574759f6 100644 --- a/python/core/composer/qgscomposerscalebar.sip +++ b/python/core/composer/qgscomposerscalebar.sip @@ -10,29 +10,6 @@ class QgsComposerScaleBar: QgsComposerItem public: - enum Alignment - { - Left, - Middle, - Right - }; - - enum ScaleBarUnits - { - MapUnits, - Meters, - Feet, - NauticalMiles - }; - - /** Modes for setting size for scale bar segments - */ - enum SegmentSizeMode - { - SegmentSizeFixed, /*!< Scale bar segment size is fixed to a map unit*/ - SegmentSizeFitWidth /*!< Scale bar segment size is calculated to fit a size range*/ - }; - QgsComposerScaleBar( QgsComposition* composition /TransferThis/ ); ~QgsComposerScaleBar(); @@ -58,7 +35,7 @@ class QgsComposerScaleBar: QgsComposerItem * @see maxBarWidth * @note added in QGIS 2.9 */ - SegmentSizeMode segmentSizeMode() const; + QgsScaleBarSettings::SegmentSizeMode segmentSizeMode() const; /** Sets the size mode for scale bar segments. * @param mode size mode @@ -67,7 +44,7 @@ class QgsComposerScaleBar: QgsComposerItem * @see setMaxBarWidth * @note added in QGIS 2.9 */ - void setSegmentSizeMode( SegmentSizeMode mode ); + void setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode mode ); /** Returns the minimum size (in millimeters) for scale bar segments. This * property is only effective if the @link segmentSizeMode @endlink is set @@ -212,8 +189,8 @@ class QgsComposerScaleBar: QgsComposerItem double height() const; void setHeight( double h ); - void setComposerMap( const QgsComposerMap* map ); - const QgsComposerMap* composerMap(); + void setComposerMap( QgsComposerMap* map ); + QgsComposerMap* composerMap(); double labelBarSpace() const; void setLabelBarSpace( double space ); @@ -221,16 +198,14 @@ class QgsComposerScaleBar: QgsComposerItem double boxContentSpace() const; void setBoxContentSpace( double space ); - double segmentMillimeters() const; - /** Left / Middle/ Right */ - Alignment alignment() const; + QgsScaleBarSettings::Alignment alignment() const; - void setAlignment( Alignment a ); + void setAlignment( QgsScaleBarSettings::Alignment a ); - ScaleBarUnits units() const; + QgsUnitTypes::DistanceUnit units() const; - void setUnits( ScaleBarUnits u ); + void setUnits( QgsUnitTypes::DistanceUnit u ); /** Returns the join style used for drawing lines in the scalebar * @returns Join style for lines @@ -263,7 +238,7 @@ class QgsComposerScaleBar: QgsComposerItem /** Apply default settings*/ void applyDefaultSettings(); /** Apply default size (scale bar 1/5 of map item width) */ - void applyDefaultSize( ScaleBarUnits u = Meters ); + void applyDefaultSize( QgsUnitTypes::DistanceUnit u = QgsUnitTypes::DistanceMeters ); /** Sets style by name @param styleName (untranslated) style name. Possibilities are: 'Single Box', 'Double Box', 'Line Ticks Middle', 'Line Ticks Down', 'Line Ticks Up', 'Numeric'*/ @@ -272,21 +247,12 @@ class QgsComposerScaleBar: QgsComposerItem /** Returns style name*/ QString style() const; - /** Returns the x - positions of the segment borders (in item coordinates) and the width - * of the segment - * @note not available in Python bindings - */ - // void segmentPositions( QList >& posWidthList ) const; - /** Sets box size suitable to content*/ void adjustBoxSize(); /** Adjusts box size and calls QgsComposerItem::update()*/ void update(); - /** Returns string of first label (important for drawing, labeling, size calculation*/ - QString firstLabelString() const; - /** Stores state in Dom element * @param elem is Dom element corresponding to 'Composer' tag * @param doc Dom document @@ -311,11 +277,4 @@ class QgsComposerScaleBar: QgsComposerItem void invalidateCurrentMap(); virtual void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext* context = nullptr ); - protected: - /** Calculates with of a segment in mm and stores it in mSegmentMillimeters*/ - void refreshSegmentMillimeters(); - - /** Returns diagonal of composer map in selected units (map units / meters / feet / nautical miles)*/ - double mapWidth() const; - }; diff --git a/python/core/composer/qgsdoubleboxscalebarstyle.sip b/python/core/composer/qgsdoubleboxscalebarstyle.sip deleted file mode 100644 index 70f263ac1af..00000000000 --- a/python/core/composer/qgsdoubleboxscalebarstyle.sip +++ /dev/null @@ -1,13 +0,0 @@ -class QgsDoubleBoxScaleBarStyle: QgsScaleBarStyle -{ -%TypeHeaderCode -#include -%End - public: - QgsDoubleBoxScaleBarStyle( const QgsComposerScaleBar* bar ); - ~QgsDoubleBoxScaleBarStyle(); - - QString name() const; - - void draw( QPainter* p, double xOffset = 0 ) const; -}; diff --git a/python/core/composer/qgsnumericscalebarstyle.sip b/python/core/composer/qgsnumericscalebarstyle.sip deleted file mode 100644 index 92d3b0db527..00000000000 --- a/python/core/composer/qgsnumericscalebarstyle.sip +++ /dev/null @@ -1,16 +0,0 @@ -class QgsNumericScaleBarStyle : QgsScaleBarStyle -{ -%TypeHeaderCode -#include -%End - public: - QgsNumericScaleBarStyle( QgsComposerScaleBar* bar ); - ~QgsNumericScaleBarStyle(); - - QString name() const; - - void draw( QPainter* p, double xOffset = 0 ) const; - - //calculation of box size is different compared to segment based scale bars - QRectF calculateBoxSize() const; -}; diff --git a/python/core/composer/qgsscalebarstyle.sip b/python/core/composer/qgsscalebarstyle.sip deleted file mode 100644 index 7bccbb6f9c3..00000000000 --- a/python/core/composer/qgsscalebarstyle.sip +++ /dev/null @@ -1,21 +0,0 @@ -/** \ingroup core - * Abstraction of composer scale bar style. Subclasses draw themselves, have the -possibility to implement custom labeling and calculate corresponding box size. -*/ -class QgsScaleBarStyle -{ -%TypeHeaderCode -#include "qgsscalebarstyle.h" -%End - public: - QgsScaleBarStyle( const QgsComposerScaleBar* bar ); - virtual ~QgsScaleBarStyle(); - - /** Draws the style - @param p painter object - @param xOffset offset to account for centered labeling*/ - virtual void draw( QPainter* p, double xOffset = 0 ) const = 0; //to do by every subclass - virtual void drawLabels( QPainter* p ) const; //default implementation provided - virtual QRectF calculateBoxSize() const; //default implementation provided - virtual QString name() const = 0; //return name of the style -}; diff --git a/python/core/composer/qgssingleboxscalebarstyle.sip b/python/core/composer/qgssingleboxscalebarstyle.sip deleted file mode 100644 index f3798e72ee3..00000000000 --- a/python/core/composer/qgssingleboxscalebarstyle.sip +++ /dev/null @@ -1,17 +0,0 @@ -class QgsSingleBoxScaleBarStyle : QgsScaleBarStyle -{ -%TypeHeaderCode -#include -%End - public: - QgsSingleBoxScaleBarStyle( const QgsComposerScaleBar* bar ); - ~QgsSingleBoxScaleBarStyle(); - - QString name() const; - - /** Draw method - @param p painter object - @param xOffset x offset - */ - void draw( QPainter* p, double xOffset = 0 ) const; -}; diff --git a/python/core/composer/qgsticksscalebarstyle.sip b/python/core/composer/qgsticksscalebarstyle.sip deleted file mode 100644 index 0f8f2014c64..00000000000 --- a/python/core/composer/qgsticksscalebarstyle.sip +++ /dev/null @@ -1,26 +0,0 @@ -class QgsTicksScaleBarStyle: QgsScaleBarStyle -{ -%TypeHeaderCode -#include -%End - public: - enum TickPosition - { - TicksUp, - TicksDown, - TicksMiddle - }; - - QgsTicksScaleBarStyle( const QgsComposerScaleBar* bar ); - ~QgsTicksScaleBarStyle(); - - QString name() const; - - /** Draw method - @param p painter object - @param xOffset offset - */ - void draw( QPainter* p, double xOffset = 0 ) const; - - void setTickPosition( TickPosition p ); -}; diff --git a/python/core/core.sip b/python/core/core.sip index bb76439d074..7e5857cbcfb 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -230,13 +230,9 @@ %Include composer/qgscomposertexttable.sip %Include composer/qgscomposerutils.sip %Include composer/qgscomposition.sip -%Include composer/qgsdoubleboxscalebarstyle.sip %Include composer/qgslayoutmanager.sip -%Include composer/qgsnumericscalebarstyle.sip %Include composer/qgspaperitem.sip -%Include composer/qgsscalebarstyle.sip -%Include composer/qgssingleboxscalebarstyle.sip -%Include composer/qgsticksscalebarstyle.sip + %Include diagram/qgsdiagram.sip %Include diagram/qgshistogramdiagram.sip @@ -327,6 +323,13 @@ %Include raster/qgssinglebandpseudocolorrenderer.sip %Include raster/qgshillshaderenderer.sip +%Include scalebar/qgsdoubleboxscalebarrenderer.sip +%Include scalebar/qgsnumericscalebarrenderer.sip +%Include scalebar/qgsscalebarrenderer.sip +%Include scalebar/qgsscalebarsettings.sip +%Include scalebar/qgssingleboxscalebarrenderer.sip +%Include scalebar/qgsticksscalebarrenderer.sip + %Include symbology-ng/qgscolorbrewerpalette.sip %Include symbology-ng/qgscptcityarchive.sip %Include symbology-ng/qgsstyle.sip diff --git a/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip new file mode 100644 index 00000000000..88fee9494b9 --- /dev/null +++ b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip @@ -0,0 +1,39 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsdoubleboxscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + +class QgsDoubleBoxScaleBarRenderer: QgsScaleBarRenderer +{ +%Docstring + Double box with alternating colors. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsdoubleboxscalebarrenderer.h" +%End + public: + QgsDoubleBoxScaleBarRenderer(); + + virtual QString name() const; + + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsdoubleboxscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/python/core/scalebar/qgsnumericscalebarrenderer.sip b/python/core/scalebar/qgsnumericscalebarrenderer.sip new file mode 100644 index 00000000000..e8b12daf1de --- /dev/null +++ b/python/core/scalebar/qgsnumericscalebarrenderer.sip @@ -0,0 +1,42 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsnumericscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + +class QgsNumericScaleBarRenderer: QgsScaleBarRenderer +{ +%Docstring + A scale bar style that draws text in the form of '1:XXXXX'. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsnumericscalebarrenderer.h" +%End + public: + QgsNumericScaleBarRenderer(); + + virtual QString name() const; + + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + + virtual QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsnumericscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/python/core/scalebar/qgsscalebarrenderer.sip b/python/core/scalebar/qgsscalebarrenderer.sip new file mode 100644 index 00000000000..2bbc6c7da24 --- /dev/null +++ b/python/core/scalebar/qgsscalebarrenderer.sip @@ -0,0 +1,114 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsScaleBarRenderer +{ +%Docstring + Abstract base class for scale bar renderers. + + Scalebar renderer subclasses implement custom drawing logic, with the possibility to implement + custom labeling. + +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsscalebarrenderer.h" +%End + public: + + struct ScaleBarContext + { + double segmentWidth; +%Docstring +Width of each individual segment (in millimeters) +%End + + QSizeF size; +%Docstring + Destination size for scalebar. This is used for scalebars which + alter their appearance or alignment based on the desired scalebar + size (e.g. correctly aligning text in a numeric scale bar). +%End + + double scale; +%Docstring +Scale denominator +%End + + }; + + QgsScaleBarRenderer(); + virtual ~QgsScaleBarRenderer(); + + virtual QString name() const = 0; +%Docstring + Returns the unique name for this style. + :rtype: str +%End + + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const = 0; +%Docstring + Draws the scalebar using the specified ``settings`` and ``scaleContext`` to a destination render ``context``. +%End + + virtual QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; +%Docstring + Calculates the required box size (in millimeters) for a scalebar using the specified ``settings`` and ``scaleContext``. + :rtype: QSizeF +%End + + protected: + + void drawDefaultLabels( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; +%Docstring + Draws default scalebar labels using the specified ``settings`` and ``scaleContext`` to a destination render ``context``. +%End + + QString firstLabelString( const QgsScaleBarSettings &settings ) const; +%Docstring + Returns the text used for the first label in the scalebar. + :rtype: str +%End + + double firstLabelXOffset( const QgsScaleBarSettings &settings ) const; +%Docstring + Returns the x-offset (in millimeters) used for the first label in the scalebar. + :rtype: float +%End + + QList segmentPositions( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const; +%Docstring + Returns a list of positions for each segment within the scalebar. + :rtype: list of float +%End + + QList segmentWidths( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const; +%Docstring + Returns a list of widths of each segment of the scalebar. + :rtype: list of float +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/python/core/scalebar/qgsscalebarsettings.sip b/python/core/scalebar/qgsscalebarsettings.sip new file mode 100644 index 00000000000..48023b5f493 --- /dev/null +++ b/python/core/scalebar/qgsscalebarsettings.sip @@ -0,0 +1,399 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsscalebarsettings.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsScaleBarSettings +{ +%Docstring + The QgsScaleBarSettings class stores the appearance and layout settings + for scalebar drawing with QgsScaleBarRenderer. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsscalebarsettings.h" +%End + public: + + enum Alignment + { + AlignLeft, + AlignMiddle, + AlignRight, + }; + + enum SegmentSizeMode + { + SegmentSizeFixed, + SegmentSizeFitWidth + }; + + QgsScaleBarSettings(); +%Docstring + Constructor for QgsScaleBarSettings. +%End + int numberOfSegments() const; +%Docstring + Returns the number of segments included in the scalebar. + \see setNumberOfSegments() + \see numberOfSegmentsLeft() + :rtype: int +%End + + void setNumberOfSegments( int segments ); +%Docstring + Sets the number of ``segments`` included in the scalebar. + \see numberOfSegments() + \see setNumberOfSegmentsLeft() +%End + + int numberOfSegmentsLeft() const; +%Docstring + Returns the number of segments included in the left part of the scalebar. + \see setNumberOfSegmentsLeft() + \see numberOfSegments() + :rtype: int +%End + + void setNumberOfSegmentsLeft( int segments ); +%Docstring + Sets the number of ``segments`` included in the left part of the scalebar. + \see numberOfSegmentsLeft() + \see setNumberOfSegments() +%End + + double unitsPerSegment() const; +%Docstring + Returns the number of scalebar units per segment. + \see setUnitsPerSegment() + :rtype: float +%End + + void setUnitsPerSegment( double units ); +%Docstring + Sets the number of scalebar ``units`` per segment. + \see unitsPerSegment() +%End + + SegmentSizeMode segmentSizeMode() const; +%Docstring + Returns the size mode for the scale bar segments. + \see setSegmentSizeMode() + \see minBarWidth() + \see maxBarWidth() + :rtype: SegmentSizeMode +%End + + void setSegmentSizeMode( SegmentSizeMode mode ); +%Docstring + Sets the size ``mode`` for scale bar segments. + \see segmentSizeMode() + \see setMinimumBarWidth() + \see setMaximumBarWidth() +%End + + double minimumBarWidth() const; +%Docstring + Returns the minimum width (in millimeters) for scale bar segments. This + property is only effective if the segmentSizeMode() is set + to SegmentSizeFitWidth. + \see segmentSizeMode() + \see setMinimumBarWidth() + \see maximumBarWidth() + :rtype: float +%End + + void setMinimumBarWidth( double width ); +%Docstring + Sets the minimum ``width`` (in millimeters) for scale bar segments. This + property is only effective if the segmentSizeMode() is set + to SegmentSizeFitWidth. + \see minimumBarWidth() + \see setMaximumBarWidth() + \see setSegmentSizeMode() +%End + + double maximumBarWidth() const; +%Docstring + Returns the maximum width (in millimeters) for scale bar segments. This + property is only effective if the segmentSizeMode() is set + to SegmentSizeFitWidth. + \see segmentSizeMode() + \see setMaximumBarWidth() + \see minimumBarWidth() + :rtype: float +%End + + void setMaximumBarWidth( double width ); +%Docstring + Sets the maximum ``width`` (in millimeters) for scale bar segments. This + property is only effective if the segmentSizeMode() is set + to SegmentSizeFitWidth. + \see minimumBarWidth() + \see setMinimumBarWidth() + \see setSegmentSizeMode() +%End + + QgsUnitTypes::DistanceUnit units() const; +%Docstring + Returns the distance units used by the scalebar. + \see setUnits() + :rtype: QgsUnitTypes.DistanceUnit +%End + + void setUnits( QgsUnitTypes::DistanceUnit units ); +%Docstring + Sets the distance ``units`` used by the scalebar. + \see units() +%End + + double mapUnitsPerScaleBarUnit() const; +%Docstring + Returns the number of map units per scale bar unit used by the scalebar. + \see setMapUnitsPerScaleBarUnit() + :rtype: float +%End + + void setMapUnitsPerScaleBarUnit( double units ); +%Docstring + Sets the number of map ``units`` per scale bar unit used by the scalebar. + \see mapUnitsPerScaleBarUnit() +%End + + QString unitLabel() const; +%Docstring + Returns the label for units. + \see setUnitLabel() + :rtype: str +%End + + void setUnitLabel( const QString &label ); +%Docstring + Sets the ``label`` for units. + \see unitLabel() +%End + + QFont font() const; +%Docstring + Returns the font used for drawing text in the scalebar. + \see setFont() + :rtype: QFont +%End + + void setFont( const QFont &font ); +%Docstring + Sets the ``font`` used for drawing text in the scalebar. + \see setFont() +%End + + QColor fontColor() const; +%Docstring + Returns the color used for drawing text in the scalebar. + \see setFontColor() + \see font() + :rtype: QColor +%End + + void setFontColor( const QColor &color ); +%Docstring + Sets the ``color`` used for drawing text in the scalebar. + \see fontColor() + \see setFont() +%End + + QColor fillColor() const; +%Docstring + Returns the color used for fills in the scalebar. + \see setFillColor() + \see fillColor2() + :rtype: QColor +%End + + void setFillColor( const QColor &color ); +%Docstring + Sets the ``color`` used for fills in the scalebar. + \see fillColor() + \see setFillColor2() +%End + + QColor fillColor2() const; +%Docstring + Returns the secondary color used for fills in the scalebar. + \see setFillColor2() + \see fillColor() + :rtype: QColor +%End + + void setFillColor2( const QColor &color ); +%Docstring + Sets the secondary ``color`` used for fills in the scalebar. + \see fillColor2() + \see setFillColor2() +%End + + QColor lineColor() const; +%Docstring + Returns the color used for lines in the scalebar. + \see setLineColor() + :rtype: QColor +%End + + void setLineColor( const QColor &color ); +%Docstring + Sets the ``color`` used for lines in the scalebar. + \see lineColor() +%End + + double lineWidth() const; +%Docstring + Returns the line width in millimeters for lines in the scalebar. + \see setLineWidth() + :rtype: float +%End + + void setLineWidth( double width ); +%Docstring + Sets the line ``width`` in millimeters for lines in the scalebar. + \see lineWidth() +%End + + QPen pen() const; +%Docstring + Returns the pen used for drawing outlines in the scalebar. + \see setPen() + \see brush() + :rtype: QPen +%End + + void setPen( const QPen &pen ); +%Docstring + Sets the pen used for drawing outlines in the scalebar. + \see pen() +%End + + QBrush brush() const; +%Docstring + Returns the primary brush used for filling the scalebar. + \see setBrush() + \see brush2() + \see pen() + :rtype: QBrush +%End + + void setBrush( const QBrush &brush ); +%Docstring + Sets the primary brush used for filling the scalebar. + \see brush() +%End + + QBrush brush2() const; +%Docstring + Returns the secondary brush for the scalebar. This is used for alternating color style scalebars, such + as single and double box styles. + \see setBrush2() + \see brush() + :rtype: QBrush +%End + + void setBrush2( const QBrush &brush ); +%Docstring + Sets the secondary brush used for filling the scalebar. + \see brush() +%End + + double height() const; +%Docstring + Returns the scalebar height (in millimeters). + \see setHeight() + :rtype: float +%End + + void setHeight( double height ); +%Docstring + Sets the scalebar ``height`` (in millimeters). + \see height() +%End + + double labelBarSpace() const; +%Docstring + Returns the spacing (in millimeters) between labels and the scalebar. + \see setLabelBarSpace() + :rtype: float +%End + + void setLabelBarSpace( double space ); +%Docstring + Sets the spacing (in millimeters) between labels and the scalebar. + \see labelBarSpace() +%End + + double boxContentSpace() const; +%Docstring + Returns the spacing (margin) between the scalebar box and content in millimeters. + \see setBoxContentSpace() + :rtype: float +%End + + void setBoxContentSpace( double space ); +%Docstring + Sets the ``space`` (margin) between the scalebar box and content in millimeters. + \see boxContentSpace() +%End + + Alignment alignment() const; +%Docstring + Returns the scalebar alignment. + \see setAlignment() + :rtype: Alignment +%End + + void setAlignment( Alignment alignment ); +%Docstring + Sets the scalebar ``alignment``. + \see alignment() +%End + + Qt::PenJoinStyle lineJoinStyle() const; +%Docstring + Returns the join style used for drawing lines in the scalebar. + \see setLineJoinStyle() + :rtype: Qt.PenJoinStyle +%End + + void setLineJoinStyle( Qt::PenJoinStyle style ); +%Docstring + Sets the join ``style`` used when drawing the lines in the scalebar + \see lineJoinStyle() +%End + + Qt::PenCapStyle lineCapStyle() const; +%Docstring + Returns the cap style used for drawing lines in the scalebar. + \see setLineCapStyle() + :rtype: Qt.PenCapStyle +%End + + void setLineCapStyle( Qt::PenCapStyle style ); +%Docstring + Sets the cap ``style`` used when drawing the lines in the scalebar. + \see lineCapStyle() +%End + +}; + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsscalebarsettings.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/python/core/scalebar/qgssingleboxscalebarrenderer.sip b/python/core/scalebar/qgssingleboxscalebarrenderer.sip new file mode 100644 index 00000000000..e9855a9b110 --- /dev/null +++ b/python/core/scalebar/qgssingleboxscalebarrenderer.sip @@ -0,0 +1,41 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgssingleboxscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + +class QgsSingleBoxScaleBarRenderer: QgsScaleBarRenderer +{ +%Docstring + Scalebar style that draws a single box with alternating + color for the segments. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgssingleboxscalebarrenderer.h" +%End + public: + + QgsSingleBoxScaleBarRenderer(); + + virtual QString name() const; + + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgssingleboxscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/python/core/scalebar/qgsticksscalebarrenderer.sip b/python/core/scalebar/qgsticksscalebarrenderer.sip new file mode 100644 index 00000000000..18768445cef --- /dev/null +++ b/python/core/scalebar/qgsticksscalebarrenderer.sip @@ -0,0 +1,61 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsticksscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + +class QgsTicksScaleBarRenderer: QgsScaleBarRenderer +{ +%Docstring + A scale bar that draws segments using short ticks. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsticksscalebarrenderer.h" +%End + public: + + enum TickPosition + { + TicksUp, + TicksDown, + TicksMiddle, + }; + + QgsTicksScaleBarRenderer(); + + virtual QString name() const; + + + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + + void setTickPosition( TickPosition position ); +%Docstring + Sets the ``position`` for tick marks in the scalebar. + \see tickPosition() +%End + + TickPosition tickPosition() const; +%Docstring + Returns the position for tick marks in the scalebar. + \see setTickPosition() + :rtype: TickPosition +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/scalebar/qgsticksscalebarrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 76e13325b62..fe5b8fb6b2e 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -560,6 +560,7 @@ INCLUDE_DIRECTORIES( ../core/geometry ../core/layertree ../core/raster + ../core/scalebar ../core/symbology-ng ../gui ../gui/symbology-ng diff --git a/src/app/composer/qgscomposerscalebarwidget.cpp b/src/app/composer/qgscomposerscalebarwidget.cpp index 0201c60972b..32a3ad18c27 100644 --- a/src/app/composer/qgscomposerscalebarwidget.cpp +++ b/src/app/composer/qgscomposerscalebarwidget.cpp @@ -55,10 +55,10 @@ QgsComposerScaleBarWidget::QgsComposerScaleBarWidget( QgsComposerScaleBar *scale mAlignmentComboBox->insertItem( 2, tr( "Right" ) ); //units combo box - mUnitsComboBox->insertItem( 0, tr( "Map units" ), 0 ); - mUnitsComboBox->insertItem( 1, tr( "Meters" ), 1 ); - mUnitsComboBox->insertItem( 2, tr( "Feet" ), 2 ); - mUnitsComboBox->insertItem( 3, tr( "Nautical Miles" ), 3 ); + mUnitsComboBox->insertItem( 0, tr( "Map units" ), QgsUnitTypes::DistanceUnknownUnit ); + mUnitsComboBox->insertItem( 1, tr( "Meters" ), QgsUnitTypes::DistanceMeters ); + mUnitsComboBox->insertItem( 2, tr( "Feet" ), QgsUnitTypes::DistanceFeet ); + mUnitsComboBox->insertItem( 3, tr( "Nautical Miles" ), QgsUnitTypes::DistanceNauticalMiles ); mFillColorButton->setColorDialogTitle( tr( "Select fill color" ) ); mFillColorButton->setAllowAlpha( true ); @@ -143,7 +143,7 @@ void QgsComposerScaleBarWidget::setGuiElements() //units mUnitsComboBox->setCurrentIndex( mUnitsComboBox->findData( ( int )mComposerScaleBar->units() ) ); - if ( mComposerScaleBar->segmentSizeMode() == QgsComposerScaleBar::SegmentSizeFixed ) + if ( mComposerScaleBar->segmentSizeMode() == QgsScaleBarSettings::SegmentSizeFixed ) { mFixedSizeRadio->setChecked( true ); mSegmentSizeSpinBox->setEnabled( true ); @@ -480,7 +480,7 @@ void QgsComposerScaleBarWidget::on_mAlignmentComboBox_currentIndexChanged( int i mComposerScaleBar->beginCommand( tr( "Scalebar alignment" ) ); disconnectUpdateSignal(); - mComposerScaleBar->setAlignment( ( QgsComposerScaleBar::Alignment ) index ); + mComposerScaleBar->setAlignment( ( QgsScaleBarSettings::Alignment ) index ); connectUpdateSignal(); mComposerScaleBar->endCommand(); } @@ -499,32 +499,32 @@ void QgsComposerScaleBarWidget::on_mUnitsComboBox_currentIndexChanged( int index } disconnectUpdateSignal(); - mComposerScaleBar->setUnits( ( QgsComposerScaleBar::ScaleBarUnits )unitData.toInt() ); + mComposerScaleBar->setUnits( ( QgsUnitTypes::DistanceUnit )unitData.toInt() ); switch ( mUnitsComboBox->currentIndex() ) { case 0: { mComposerScaleBar->beginCommand( tr( "Scalebar changed to map units" ) ); - mComposerScaleBar->applyDefaultSize( QgsComposerScaleBar::MapUnits ); + mComposerScaleBar->applyDefaultSize( QgsUnitTypes::DistanceUnknownUnit ); break; } case 2: { mComposerScaleBar->beginCommand( tr( "Scalebar changed to feet" ) ); - mComposerScaleBar->applyDefaultSize( QgsComposerScaleBar::Feet ); + mComposerScaleBar->applyDefaultSize( QgsUnitTypes::DistanceFeet ); break; } case 3: { mComposerScaleBar->beginCommand( tr( "Scalebar changed to nautical miles" ) ); - mComposerScaleBar->applyDefaultSize( QgsComposerScaleBar::NauticalMiles ); + mComposerScaleBar->applyDefaultSize( QgsUnitTypes::DistanceNauticalMiles ); break; } case 1: default: { mComposerScaleBar->beginCommand( tr( "Scalebar changed to meters" ) ); - mComposerScaleBar->applyDefaultSize( QgsComposerScaleBar::Meters ); + mComposerScaleBar->applyDefaultSize( QgsUnitTypes::DistanceMeters ); break; } } @@ -621,12 +621,12 @@ void QgsComposerScaleBarWidget::segmentSizeRadioChanged( QAbstractButton *radio disconnectUpdateSignal(); if ( mFixedSizeRadio->isChecked() ) { - mComposerScaleBar->setSegmentSizeMode( QgsComposerScaleBar::SegmentSizeFixed ); + mComposerScaleBar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFixed ); mComposerScaleBar->setNumUnitsPerSegment( mSegmentSizeSpinBox->value() ); } else /*if(mFitWidthRadio->isChecked())*/ { - mComposerScaleBar->setSegmentSizeMode( QgsComposerScaleBar::SegmentSizeFitWidth ); + mComposerScaleBar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFitWidth ); } mComposerScaleBar->update(); connectUpdateSignal(); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b50510b94f7..d2b2440463d 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -89,6 +89,12 @@ SET(QGIS_CORE_SRCS processing/qgsprocessingregistry.cpp processing/qgsprocessingutils.cpp + scalebar/qgsdoubleboxscalebarrenderer.cpp + scalebar/qgsnumericscalebarrenderer.cpp + scalebar/qgsscalebarrenderer.cpp + scalebar/qgssingleboxscalebarrenderer.cpp + scalebar/qgsticksscalebarrenderer.cpp + qgis.cpp qgsapplication.cpp qgsaction.cpp @@ -304,14 +310,9 @@ SET(QGIS_CORE_SRCS composer/qgscomposertexttable.cpp composer/qgscomposerutils.cpp composer/qgscomposition.cpp - composer/qgsdoubleboxscalebarstyle.cpp composer/qgsgroupungroupitemscommand.cpp composer/qgslayoutmanager.cpp - composer/qgsnumericscalebarstyle.cpp composer/qgspaperitem.cpp - composer/qgsscalebarstyle.cpp - composer/qgssingleboxscalebarstyle.cpp - composer/qgsticksscalebarstyle.cpp dxf/qgsdxfexport.cpp dxf/qgsdxfpaintdevice.cpp @@ -846,12 +847,7 @@ SET(QGIS_CORE_HDRS composer/qgscomposeritemcommand.h composer/qgscomposermultiframecommand.h composer/qgscomposertexttable.h - composer/qgsdoubleboxscalebarstyle.h - composer/qgsnumericscalebarstyle.h composer/qgspaperitem.h - composer/qgsscalebarstyle.h - composer/qgssingleboxscalebarstyle.h - composer/qgsticksscalebarstyle.h processing/qgsprocessingalgorithm.h processing/qgsprocessingutils.h @@ -896,6 +892,13 @@ SET(QGIS_CORE_HDRS raster/qgssinglebandpseudocolorrenderer.h raster/qgshillshaderenderer.h + scalebar/qgsdoubleboxscalebarrenderer.h + scalebar/qgsnumericscalebarrenderer.h + scalebar/qgsscalebarsettings.h + scalebar/qgsscalebarrenderer.h + scalebar/qgssingleboxscalebarrenderer.h + scalebar/qgsticksscalebarrenderer.h + symbology-ng/qgs25drenderer.h symbology-ng/qgscategorizedsymbolrenderer.h symbology-ng/qgscolorbrewerpalette.h @@ -983,6 +986,7 @@ INCLUDE_DIRECTORIES( processing raster renderer + scalebar symbology-ng gps/qextserialport ) diff --git a/src/core/composer/qgscomposerscalebar.cpp b/src/core/composer/qgscomposerscalebar.cpp index a574567ff77..e8af9bad8fd 100644 --- a/src/core/composer/qgscomposerscalebar.cpp +++ b/src/core/composer/qgscomposerscalebar.cpp @@ -19,12 +19,12 @@ #include "qgscomposition.h" #include "qgscomposerutils.h" #include "qgsdistancearea.h" -#include "qgsscalebarstyle.h" -#include "qgsdoubleboxscalebarstyle.h" +#include "qgsscalebarrenderer.h" +#include "qgsdoubleboxscalebarrenderer.h" #include "qgsmapsettings.h" -#include "qgsnumericscalebarstyle.h" -#include "qgssingleboxscalebarstyle.h" -#include "qgsticksscalebarstyle.h" +#include "qgsnumericscalebarrenderer.h" +#include "qgssingleboxscalebarrenderer.h" +#include "qgsticksscalebarrenderer.h" #include "qgsrectangle.h" #include "qgsproject.h" #include "qgssymbollayerutils.h" @@ -42,17 +42,8 @@ QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition *composition ) : QgsComposerItem( composition ) , mComposerMap( nullptr ) - , mNumUnitsPerSegment( 0 ) - , mSegmentSizeMode( SegmentSizeFixed ) - , mMinBarWidth( 50 ) - , mMaxBarWidth( 150 ) - , mFontColor( QColor( 0, 0, 0 ) ) , mStyle( nullptr ) , mSegmentMillimeters( 0.0 ) - , mAlignment( Left ) - , mUnits( MapUnits ) - , mLineJoinStyle( Qt::MiterJoin ) - , mLineCapStyle( Qt::SquareCap ) { applyDefaultSettings(); applyDefaultSize(); @@ -78,11 +69,9 @@ void QgsComposerScaleBar::paint( QPainter *painter, const QStyleOptionGraphicsIt drawBackground( painter ); - //x-offset is half of first label width because labels are drawn centered - QString firstLabel = firstLabelString(); - double firstLabelWidth = QgsComposerUtils::textWidthMM( mFont, firstLabel ); + QgsRenderContext c = QgsComposerUtils::createRenderContextForMap( mComposerMap, painter ); - mStyle->draw( painter, firstLabelWidth / 2 ); + mStyle->draw( c, mSettings, createScaleContext() ); //draw frame and selection boxes if necessary drawFrame( painter ); @@ -96,12 +85,12 @@ void QgsComposerScaleBar::setNumSegments( int nSegments ) { if ( !mStyle ) { - mNumSegments = nSegments; + mSettings.setNumberOfSegments( nSegments ); return; } - double width = mStyle->calculateBoxSize().width(); - mNumSegments = nSegments; - double widthAfter = mStyle->calculateBoxSize().width(); + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setNumberOfSegments( nSegments ); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } @@ -110,28 +99,28 @@ void QgsComposerScaleBar::setNumUnitsPerSegment( double units ) { if ( !mStyle ) { - mNumUnitsPerSegment = units; + mSettings.setUnitsPerSegment( units ); return; } - double width = mStyle->calculateBoxSize().width(); - mNumUnitsPerSegment = units; + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setUnitsPerSegment( units ); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize().width(); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } -void QgsComposerScaleBar::setSegmentSizeMode( SegmentSizeMode mode ) +void QgsComposerScaleBar::setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode mode ) { if ( !mStyle ) { - mSegmentSizeMode = mode; + mSettings.setSegmentSizeMode( mode ); return; } - double width = mStyle->calculateBoxSize().width(); - mSegmentSizeMode = mode; + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setSegmentSizeMode( mode ); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize().width(); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } @@ -140,13 +129,13 @@ void QgsComposerScaleBar::setMinBarWidth( double minWidth ) { if ( !mStyle ) { - mMinBarWidth = minWidth; + mSettings.setMinimumBarWidth( minWidth ); return; } - double width = mStyle->calculateBoxSize().width(); - mMinBarWidth = minWidth; + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setMinimumBarWidth( minWidth ); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize().width(); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } @@ -155,13 +144,13 @@ void QgsComposerScaleBar::setMaxBarWidth( double maxWidth ) { if ( !mStyle ) { - mMaxBarWidth = maxWidth; + mSettings.setMaximumBarWidth( maxWidth ); return; } - double width = mStyle->calculateBoxSize().width(); - mMaxBarWidth = maxWidth; + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setMaximumBarWidth( maxWidth ); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize().width(); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } @@ -170,12 +159,12 @@ void QgsComposerScaleBar::setNumSegmentsLeft( int nSegmentsLeft ) { if ( !mStyle ) { - mNumSegmentsLeft = nSegmentsLeft; + mSettings.setNumberOfSegmentsLeft( nSegmentsLeft ); return; } - double width = mStyle->calculateBoxSize().width(); - mNumSegmentsLeft = nSegmentsLeft; - double widthAfter = mStyle->calculateBoxSize().width(); + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setNumberOfSegmentsLeft( nSegmentsLeft ); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } @@ -184,17 +173,17 @@ void QgsComposerScaleBar::setBoxContentSpace( double space ) { if ( !mStyle ) { - mBoxContentSpace = space; + mSettings.setBoxContentSpace( space ); return; } - double width = mStyle->calculateBoxSize().width(); - mBoxContentSpace = space; - double widthAfter = mStyle->calculateBoxSize().width(); + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + mSettings.setBoxContentSpace( space ); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); emit itemChanged(); } -void QgsComposerScaleBar::setComposerMap( const QgsComposerMap *map ) +void QgsComposerScaleBar::setComposerMap( QgsComposerMap *map ) { if ( mComposerMap ) { @@ -236,22 +225,30 @@ void QgsComposerScaleBar::refreshDataDefinedProperty( const QgsComposerObject::D //updates data defined properties and redraws item to match if ( property == QgsComposerObject::ScalebarFillColor || property == QgsComposerObject::AllProperties ) { - mBrush.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarFillColor, *evalContext, mFillColor ) ); + QBrush b = mSettings.brush(); + b.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarFillColor, *evalContext, mSettings.fillColor() ) ); + mSettings.setBrush( b ); forceUpdate = true; } if ( property == QgsComposerObject::ScalebarFillColor2 || property == QgsComposerObject::AllProperties ) { - mBrush2.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarFillColor2, *evalContext, mFillColor2 ) ); + QBrush b = mSettings.brush2(); + b.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarFillColor2, *evalContext, mSettings.fillColor2() ) ); + mSettings.setBrush2( b ); forceUpdate = true; } if ( property == QgsComposerObject::ScalebarLineColor || property == QgsComposerObject::AllProperties ) { - mPen.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarLineColor, *evalContext, mLineColor ) ); + QPen p = mSettings.pen(); + p.setColor( mDataDefinedProperties.valueAsColor( QgsComposerObject::ScalebarLineColor, *evalContext, mSettings.lineColor() ) ); + mSettings.setPen( p ); forceUpdate = true; } if ( property == QgsComposerObject::ScalebarLineWidth || property == QgsComposerObject::AllProperties ) { - mPen.setWidthF( mDataDefinedProperties.valueAsDouble( QgsComposerObject::ScalebarLineWidth, *evalContext, mLineWidth ) ); + QPen p = mSettings.pen(); + p.setWidthF( mDataDefinedProperties.valueAsDouble( QgsComposerObject::ScalebarLineWidth, *evalContext, mSettings.lineWidth() ) ); + mSettings.setPen( p ); forceUpdate = true; } if ( forceUpdate ) @@ -283,23 +280,23 @@ void QgsComposerScaleBar::refreshSegmentMillimeters() //get mm dimension of composer map QRectF composerItemRect = mComposerMap->rect(); - if ( mSegmentSizeMode == SegmentSizeFixed ) + if ( mSettings.segmentSizeMode() == QgsScaleBarSettings::SegmentSizeFixed ) { //calculate size depending on mNumUnitsPerSegment - mSegmentMillimeters = composerItemRect.width() / mapWidth() * mNumUnitsPerSegment; + mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment(); } else /*if(mSegmentSizeMode == SegmentSizeFitWidth)*/ { - if ( mMaxBarWidth < mMinBarWidth ) + if ( mSettings.maximumBarWidth() < mSettings.minimumBarWidth() ) { mSegmentMillimeters = 0; } else { - double nSegments = ( mNumSegmentsLeft != 0 ) + mNumSegments; + double nSegments = ( mSettings.numberOfSegmentsLeft() != 0 ) + mSettings.numberOfSegments(); // unitsPerSegments which fit minBarWidth resp. maxBarWidth - double minUnitsPerSeg = ( mMinBarWidth * mapWidth() ) / ( nSegments * composerItemRect.width() ); - double maxUnitsPerSeg = ( mMaxBarWidth * mapWidth() ) / ( nSegments * composerItemRect.width() ); + double minUnitsPerSeg = ( mSettings.minimumBarWidth() * mapWidth() ) / ( nSegments * composerItemRect.width() ); + double maxUnitsPerSeg = ( mSettings.maximumBarWidth() * mapWidth() ) / ( nSegments * composerItemRect.width() ); // Start with coarsest "nice" number closest to minUnitsPerSeg resp // maxUnitsPerSeg, then proceed to finer numbers as long as neither @@ -317,8 +314,8 @@ void QgsComposerScaleBar::refreshSegmentMillimeters() } // Pick mNumUnitsPerSegment from {lowerNiceUnitsPerSeg, upperNiceUnitsPerSeg}, use the larger if possible - mNumUnitsPerSegment = upperNiceUnitsPerSeg < minUnitsPerSeg ? lowerNiceUnitsPerSeg : upperNiceUnitsPerSeg; - mSegmentMillimeters = composerItemRect.width() / mapWidth() * mNumUnitsPerSegment; + mSettings.setUnitsPerSegment( upperNiceUnitsPerSeg < minUnitsPerSeg ? lowerNiceUnitsPerSeg : upperNiceUnitsPerSeg ); + mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment(); } } } @@ -332,7 +329,7 @@ double QgsComposerScaleBar::mapWidth() const } QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() ); - if ( mUnits == MapUnits ) + if ( mSettings.units() == QgsUnitTypes::DistanceUnknownUnit ) { return composerMapRect.width(); } @@ -345,108 +342,84 @@ double QgsComposerScaleBar::mapWidth() const QgsUnitTypes::DistanceUnit units = da.lengthUnits(); double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) ); - switch ( mUnits ) - { - case QgsComposerScaleBar::Feet: - measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, units ); - break; - case QgsComposerScaleBar::NauticalMiles: - measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceNauticalMiles, units ); - break; - case QgsComposerScaleBar::Meters: - measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, units ); - break; - case QgsComposerScaleBar::MapUnits: - //avoid warning - break; - } + measure /= QgsUnitTypes::fromUnitToUnitFactor( mSettings.units(), units ); return measure; } } -void QgsComposerScaleBar::setAlignment( Alignment a ) +QgsScaleBarRenderer::ScaleBarContext QgsComposerScaleBar::createScaleContext() const { - mAlignment = a; + QgsScaleBarRenderer::ScaleBarContext scaleContext; + scaleContext.size = rect().size(); + scaleContext.segmentWidth = mSegmentMillimeters; + scaleContext.scale = mComposerMap ? mComposerMap->scale() : 1.0; + return scaleContext; +} + +void QgsComposerScaleBar::setAlignment( QgsScaleBarSettings::Alignment a ) +{ + mSettings.setAlignment( a ); update(); emit itemChanged(); } -void QgsComposerScaleBar::setUnits( ScaleBarUnits u ) +void QgsComposerScaleBar::setUnits( QgsUnitTypes::DistanceUnit u ) { - mUnits = u; + mSettings.setUnits( u ); refreshSegmentMillimeters(); emit itemChanged(); } void QgsComposerScaleBar::setLineJoinStyle( Qt::PenJoinStyle style ) { - if ( mLineJoinStyle == style ) + if ( mSettings.lineJoinStyle() == style ) { //no change return; } - mLineJoinStyle = style; - mPen.setJoinStyle( mLineJoinStyle ); + mSettings.setLineJoinStyle( style ); update(); emit itemChanged(); } void QgsComposerScaleBar::setLineCapStyle( Qt::PenCapStyle style ) { - if ( mLineCapStyle == style ) + if ( mSettings.lineCapStyle() == style ) { //no change return; } - mLineCapStyle = style; - mPen.setCapStyle( mLineCapStyle ); + mSettings.setLineCapStyle( style ); update(); emit itemChanged(); } void QgsComposerScaleBar::applyDefaultSettings() { - mNumSegments = 2; - mNumSegmentsLeft = 0; - - mNumMapUnitsPerScaleBarUnit = 1.0; - //style delete mStyle; - mStyle = new QgsSingleBoxScaleBarStyle( this ); - - mHeight = 3; + mStyle = new QgsSingleBoxScaleBarRenderer(); //default to no background setBackgroundEnabled( false ); - mPen = QPen( mLineColor ); - mPen.setJoinStyle( mLineJoinStyle ); - mPen.setCapStyle( mLineCapStyle ); - mPen.setWidthF( mLineWidth ); - - mBrush.setColor( mFillColor ); - mBrush.setStyle( Qt::SolidPattern ); - - mBrush2.setColor( mFillColor2 ); - mBrush2.setStyle( Qt::SolidPattern ); - //get default composer font from settings QgsSettings settings; QString defaultFontString = settings.value( QStringLiteral( "Composer/defaultFont" ) ).toString(); + QFont f; if ( !defaultFontString.isEmpty() ) { - mFont.setFamily( defaultFontString ); + f.setFamily( defaultFontString ); } - mFont.setPointSizeF( 12.0 ); - mFontColor = QColor( 0, 0, 0 ); + f.setPointSizeF( 12.0 ); + mSettings.setFont( f ); + + mSettings.setUnits( QgsUnitTypes::DistanceUnknownUnit ); - mLabelBarSpace = 3.0; - mBoxContentSpace = 1.0; emit itemChanged(); } -void QgsComposerScaleBar::applyDefaultSize( QgsComposerScaleBar::ScaleBarUnits u ) +void QgsComposerScaleBar::applyDefaultSize( QgsUnitTypes::DistanceUnit u ) { if ( mComposerMap ) { @@ -456,15 +429,15 @@ void QgsComposerScaleBar::applyDefaultSize( QgsComposerScaleBar::ScaleBarUnits u double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width setNumUnitsPerSegment( initialUnitsPerSegment ); - switch ( mUnits ) + switch ( u ) { - case MapUnits: + case QgsUnitTypes::DistanceUnknownUnit: { upperMagnitudeMultiplier = 1.0; setUnitLabeling( tr( "units" ) ); break; } - case Meters: + case QgsUnitTypes::DistanceMeters: { if ( initialUnitsPerSegment > 1000.0 ) { @@ -478,7 +451,7 @@ void QgsComposerScaleBar::applyDefaultSize( QgsComposerScaleBar::ScaleBarUnits u } break; } - case Feet: + case QgsUnitTypes::DistanceFeet: { if ( initialUnitsPerSegment > 5419.95 ) { @@ -492,12 +465,11 @@ void QgsComposerScaleBar::applyDefaultSize( QgsComposerScaleBar::ScaleBarUnits u } break; } - case NauticalMiles: - { + + default: + setUnitLabeling( QgsUnitTypes::toAbbreviatedString( u ) ); upperMagnitudeMultiplier = 1; - setUnitLabeling( tr( "Nm" ) ); break; - } } double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier; @@ -528,7 +500,7 @@ void QgsComposerScaleBar::adjustBoxSize() return; } - QRectF box = mStyle->calculateBoxSize(); + QRectF box = QRectF( pos(), mStyle->calculateBoxSize( mSettings, createScaleContext() ) ); if ( rect().height() > box.height() ) { //keep user specified item height if higher than minimum scale bar height @@ -553,7 +525,7 @@ void QgsComposerScaleBar::adjustBoxSize() void QgsComposerScaleBar::setSceneRect( const QRectF &rectangle ) { - QRectF box = mStyle->calculateBoxSize(); + QRectF box = QRectF( pos(), mStyle->calculateBoxSize( mSettings, createScaleContext() ) ); if ( rectangle.height() > box.height() ) { //keep user specified item height if higher than minimum scale bar height @@ -593,35 +565,14 @@ void QgsComposerScaleBar::updateSegmentSize() { return; } - double width = mStyle->calculateBoxSize().width(); + double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize().width(); + double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); update(); emit itemChanged(); } -void QgsComposerScaleBar::segmentPositions( QList > &posWidthList ) const -{ - posWidthList.clear(); - double mCurrentXCoord = mPen.widthF() + mBoxContentSpace; - - //left segments - double leftSegmentSize = mSegmentMillimeters / mNumSegmentsLeft; - for ( int i = 0; i < mNumSegmentsLeft; ++i ) - { - posWidthList.push_back( qMakePair( mCurrentXCoord, leftSegmentSize ) ); - mCurrentXCoord += leftSegmentSize; - } - - //right segments - for ( int i = 0; i < mNumSegments; ++i ) - { - posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters ) ); - mCurrentXCoord += mSegmentMillimeters; - } -} - void QgsComposerScaleBar::setStyle( const QString &styleName ) { delete mStyle; @@ -630,32 +581,32 @@ void QgsComposerScaleBar::setStyle( const QString &styleName ) //switch depending on style name if ( styleName == QLatin1String( "Single Box" ) ) { - mStyle = new QgsSingleBoxScaleBarStyle( this ); + mStyle = new QgsSingleBoxScaleBarRenderer(); } else if ( styleName == QLatin1String( "Double Box" ) ) { - mStyle = new QgsDoubleBoxScaleBarStyle( this ); + mStyle = new QgsDoubleBoxScaleBarRenderer(); } else if ( styleName == QLatin1String( "Line Ticks Middle" ) || styleName == QLatin1String( "Line Ticks Down" ) || styleName == QLatin1String( "Line Ticks Up" ) ) { - QgsTicksScaleBarStyle *tickStyle = new QgsTicksScaleBarStyle( this ); + QgsTicksScaleBarRenderer *tickStyle = new QgsTicksScaleBarRenderer(); if ( styleName == QLatin1String( "Line Ticks Middle" ) ) { - tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksMiddle ); + tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksMiddle ); } else if ( styleName == QLatin1String( "Line Ticks Down" ) ) { - tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksDown ); + tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksDown ); } else if ( styleName == QLatin1String( "Line Ticks Up" ) ) { - tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksUp ); + tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksUp ); } mStyle = tickStyle; } else if ( styleName == QLatin1String( "Numeric" ) ) { - mStyle = new QgsNumericScaleBarStyle( this ); + mStyle = new QgsNumericScaleBarRenderer(); } emit itemChanged(); } @@ -672,26 +623,14 @@ QString QgsComposerScaleBar::style() const } } -QString QgsComposerScaleBar::firstLabelString() const -{ - if ( mNumSegmentsLeft > 0 ) - { - return QString::number( mNumUnitsPerSegment / mNumMapUnitsPerScaleBarUnit ); - } - else - { - return QStringLiteral( "0" ); - } -} - QFont QgsComposerScaleBar::font() const { - return mFont; + return mSettings.font(); } void QgsComposerScaleBar::setFont( const QFont &font ) { - mFont = font; + mSettings.setFont( font ); update(); emit itemChanged(); } @@ -704,23 +643,23 @@ bool QgsComposerScaleBar::writeXml( QDomElement &elem, QDomDocument &doc ) const } QDomElement composerScaleBarElem = doc.createElement( QStringLiteral( "ComposerScaleBar" ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "height" ), QString::number( mHeight ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "labelBarSpace" ), QString::number( mLabelBarSpace ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "boxContentSpace" ), QString::number( mBoxContentSpace ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "numSegments" ), mNumSegments ); - composerScaleBarElem.setAttribute( QStringLiteral( "numSegmentsLeft" ), mNumSegmentsLeft ); - composerScaleBarElem.setAttribute( QStringLiteral( "numUnitsPerSegment" ), QString::number( mNumUnitsPerSegment ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "segmentSizeMode" ), mSegmentSizeMode ); - composerScaleBarElem.setAttribute( QStringLiteral( "minBarWidth" ), mMinBarWidth ); - composerScaleBarElem.setAttribute( QStringLiteral( "maxBarWidth" ), mMaxBarWidth ); + composerScaleBarElem.setAttribute( QStringLiteral( "height" ), QString::number( mSettings.height() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "labelBarSpace" ), QString::number( mSettings.labelBarSpace() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "boxContentSpace" ), QString::number( mSettings.boxContentSpace() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "numSegments" ), mSettings.numberOfSegments() ); + composerScaleBarElem.setAttribute( QStringLiteral( "numSegmentsLeft" ), mSettings.numberOfSegmentsLeft() ); + composerScaleBarElem.setAttribute( QStringLiteral( "numUnitsPerSegment" ), QString::number( mSettings.unitsPerSegment() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "segmentSizeMode" ), mSettings.segmentSizeMode() ); + composerScaleBarElem.setAttribute( QStringLiteral( "minBarWidth" ), mSettings.minimumBarWidth() ); + composerScaleBarElem.setAttribute( QStringLiteral( "maxBarWidth" ), mSettings.maximumBarWidth() ); composerScaleBarElem.setAttribute( QStringLiteral( "segmentMillimeters" ), QString::number( mSegmentMillimeters ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QString::number( mNumMapUnitsPerScaleBarUnit ) ); - composerScaleBarElem.appendChild( QgsFontUtils::toXmlElement( mFont, doc, QStringLiteral( "scaleBarFont" ) ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mLineWidth ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "unitLabel" ), mUnitLabeling ); - composerScaleBarElem.setAttribute( QStringLiteral( "units" ), mUnits ); - composerScaleBarElem.setAttribute( QStringLiteral( "lineJoinStyle" ), QgsSymbolLayerUtils::encodePenJoinStyle( mLineJoinStyle ) ); - composerScaleBarElem.setAttribute( QStringLiteral( "lineCapStyle" ), QgsSymbolLayerUtils::encodePenCapStyle( mLineCapStyle ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QString::number( mSettings.mapUnitsPerScaleBarUnit() ) ); + composerScaleBarElem.appendChild( QgsFontUtils::toXmlElement( mSettings.font(), doc, QStringLiteral( "scaleBarFont" ) ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mSettings.lineWidth() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "unitLabel" ), mSettings.unitLabel() ); + composerScaleBarElem.setAttribute( QStringLiteral( "unitType" ), QgsUnitTypes::encodeUnit( mSettings.units() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "lineJoinStyle" ), QgsSymbolLayerUtils::encodePenJoinStyle( mSettings.lineJoinStyle() ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "lineCapStyle" ), QgsSymbolLayerUtils::encodePenCapStyle( mSettings.lineCapStyle() ) ); //style if ( mStyle ) @@ -738,38 +677,38 @@ bool QgsComposerScaleBar::writeXml( QDomElement &elem, QDomDocument &doc ) const //fill color QDomElement fillColorElem = doc.createElement( QStringLiteral( "fillColor" ) ); - fillColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mFillColor.red() ) ); - fillColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mFillColor.green() ) ); - fillColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mFillColor.blue() ) ); - fillColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mFillColor.alpha() ) ); + fillColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.fillColor().red() ) ); + fillColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.fillColor().green() ) ); + fillColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.fillColor().blue() ) ); + fillColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.fillColor().alpha() ) ); composerScaleBarElem.appendChild( fillColorElem ); //fill color 2 QDomElement fillColor2Elem = doc.createElement( QStringLiteral( "fillColor2" ) ); - fillColor2Elem.setAttribute( QStringLiteral( "red" ), QString::number( mFillColor2.red() ) ); - fillColor2Elem.setAttribute( QStringLiteral( "green" ), QString::number( mFillColor2.green() ) ); - fillColor2Elem.setAttribute( QStringLiteral( "blue" ), QString::number( mFillColor2.blue() ) ); - fillColor2Elem.setAttribute( QStringLiteral( "alpha" ), QString::number( mFillColor2.alpha() ) ); + fillColor2Elem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.fillColor2().red() ) ); + fillColor2Elem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.fillColor2().green() ) ); + fillColor2Elem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.fillColor2().blue() ) ); + fillColor2Elem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.fillColor2().alpha() ) ); composerScaleBarElem.appendChild( fillColor2Elem ); //pen color QDomElement strokeColorElem = doc.createElement( QStringLiteral( "strokeColor" ) ); - strokeColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mLineColor.red() ) ); - strokeColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mLineColor.green() ) ); - strokeColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mLineColor.blue() ) ); - strokeColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mLineColor.alpha() ) ); + strokeColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.lineColor().red() ) ); + strokeColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.lineColor().green() ) ); + strokeColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.lineColor().blue() ) ); + strokeColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.lineColor().alpha() ) ); composerScaleBarElem.appendChild( strokeColorElem ); //font color QDomElement fontColorElem = doc.createElement( QStringLiteral( "textColor" ) ); - fontColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mFontColor.red() ) ); - fontColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mFontColor.green() ) ); - fontColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mFontColor.blue() ) ); - fontColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mFontColor.alpha() ) ); + fontColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mSettings.fontColor().red() ) ); + fontColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mSettings.fontColor().green() ) ); + fontColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mSettings.fontColor().blue() ) ); + fontColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mSettings.fontColor().alpha() ) ); composerScaleBarElem.appendChild( fontColorElem ); //alignment - composerScaleBarElem.setAttribute( QStringLiteral( "alignment" ), QString::number( static_cast< int >( mAlignment ) ) ); + composerScaleBarElem.setAttribute( QStringLiteral( "alignment" ), QString::number( static_cast< int >( mSettings.alignment() ) ) ); elem.appendChild( composerScaleBarElem ); return _writeXml( composerScaleBarElem, doc ); @@ -782,28 +721,27 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume return false; } - mHeight = itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble(); - mLabelBarSpace = itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble(); - mBoxContentSpace = itemElem.attribute( QStringLiteral( "boxContentSpace" ), QStringLiteral( "1.0" ) ).toDouble(); - mNumSegments = itemElem.attribute( QStringLiteral( "numSegments" ), QStringLiteral( "2" ) ).toInt(); - mNumSegmentsLeft = itemElem.attribute( QStringLiteral( "numSegmentsLeft" ), QStringLiteral( "0" ) ).toInt(); - mNumUnitsPerSegment = itemElem.attribute( QStringLiteral( "numUnitsPerSegment" ), QStringLiteral( "1.0" ) ).toDouble(); - mSegmentSizeMode = static_cast( itemElem.attribute( QStringLiteral( "segmentSizeMode" ), QStringLiteral( "0" ) ).toInt() ); - mMinBarWidth = itemElem.attribute( QStringLiteral( "minBarWidth" ), QStringLiteral( "50" ) ).toInt(); - mMaxBarWidth = itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toInt(); + mSettings.setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() ); + mSettings.setLabelBarSpace( itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble() ); + mSettings.setBoxContentSpace( itemElem.attribute( QStringLiteral( "boxContentSpace" ), QStringLiteral( "1.0" ) ).toDouble() ); + mSettings.setNumberOfSegments( itemElem.attribute( QStringLiteral( "numSegments" ), QStringLiteral( "2" ) ).toInt() ); + mSettings.setNumberOfSegmentsLeft( itemElem.attribute( QStringLiteral( "numSegmentsLeft" ), QStringLiteral( "0" ) ).toInt() ); + mSettings.setUnitsPerSegment( itemElem.attribute( QStringLiteral( "numUnitsPerSegment" ), QStringLiteral( "1.0" ) ).toDouble() ); + mSettings.setSegmentSizeMode( static_cast( itemElem.attribute( QStringLiteral( "segmentSizeMode" ), QStringLiteral( "0" ) ).toInt() ) ); + mSettings.setMinimumBarWidth( itemElem.attribute( QStringLiteral( "minBarWidth" ), QStringLiteral( "50" ) ).toInt() ); + mSettings.setMaximumBarWidth( itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toInt() ); mSegmentMillimeters = itemElem.attribute( QStringLiteral( "segmentMillimeters" ), QStringLiteral( "0.0" ) ).toDouble(); - mNumMapUnitsPerScaleBarUnit = itemElem.attribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QStringLiteral( "1.0" ) ).toDouble(); - mLineWidth = itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "0.3" ) ).toDouble(); - mPen.setWidthF( mLineWidth ); - mUnitLabeling = itemElem.attribute( QStringLiteral( "unitLabel" ) ); - mLineJoinStyle = QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "lineJoinStyle" ), QStringLiteral( "miter" ) ) ); - mPen.setJoinStyle( mLineJoinStyle ); - mLineCapStyle = QgsSymbolLayerUtils::decodePenCapStyle( itemElem.attribute( QStringLiteral( "lineCapStyle" ), QStringLiteral( "square" ) ) ); - mPen.setCapStyle( mLineCapStyle ); - if ( !QgsFontUtils::setFromXmlChildNode( mFont, itemElem, QStringLiteral( "scaleBarFont" ) ) ) + mSettings.setMapUnitsPerScaleBarUnit( itemElem.attribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QStringLiteral( "1.0" ) ).toDouble() ); + mSettings.setLineWidth( itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "0.3" ) ).toDouble() ); + mSettings.setUnitLabel( itemElem.attribute( QStringLiteral( "unitLabel" ) ) ); + mSettings.setLineJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "lineJoinStyle" ), QStringLiteral( "miter" ) ) ) ); + mSettings.setLineCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( itemElem.attribute( QStringLiteral( "lineCapStyle" ), QStringLiteral( "square" ) ) ) ); + QFont f; + if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, QStringLiteral( "scaleBarFont" ) ) ) { - mFont.fromString( itemElem.attribute( QStringLiteral( "font" ), QLatin1String( "" ) ) ); + f.fromString( itemElem.attribute( QStringLiteral( "font" ), QLatin1String( "" ) ) ); } + mSettings.setFont( f ); //colors //fill color @@ -821,14 +759,12 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume if ( redOk && greenOk && blueOk && alphaOk ) { - mFillColor = QColor( fillRed, fillGreen, fillBlue, fillAlpha ); - mBrush.setColor( mFillColor ); + mSettings.setFillColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) ); } } else { - mFillColor = QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ); - mBrush.setColor( mFillColor ); + mSettings.setFillColor( QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ) ); } //fill color 2 @@ -846,14 +782,12 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume if ( redOk && greenOk && blueOk && alphaOk ) { - mFillColor2 = QColor( fillRed, fillGreen, fillBlue, fillAlpha ); - mBrush2.setColor( mFillColor2 ); + mSettings.setFillColor2( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) ); } } else { - mFillColor2 = QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ); - mBrush2.setColor( mFillColor2 ); + mSettings.setFillColor2( QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ) ); } //stroke color @@ -871,14 +805,18 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume if ( redOk && greenOk && blueOk && alphaOk ) { - mLineColor = QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ); - mPen.setColor( mLineColor ); + mSettings.setLineColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) ); + QPen p = mSettings.pen(); + p.setColor( mSettings.lineColor() ); + mSettings.setPen( p ); } } else { - mLineColor = QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ); - mPen.setColor( mLineColor ); + mSettings.setLineColor( QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ) ); + QPen p = mSettings.pen(); + p.setColor( mSettings.lineColor() ); + mSettings.setPen( p ); } //font color @@ -896,12 +834,14 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume if ( redOk && greenOk && blueOk && alphaOk ) { - mFontColor = QColor( textRed, textGreen, textBlue, textAlpha ); + mSettings.setFontColor( QColor( textRed, textGreen, textBlue, textAlpha ) ); } } else { - mFontColor.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) ); + QColor c; + c.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) ); + mSettings.setFontColor( c ); } //style @@ -910,15 +850,38 @@ bool QgsComposerScaleBar::readXml( const QDomElement &itemElem, const QDomDocume QString styleString = itemElem.attribute( QStringLiteral( "style" ), QLatin1String( "" ) ); setStyle( tr( styleString.toLocal8Bit().data() ) ); - mUnits = static_cast< ScaleBarUnits >( itemElem.attribute( QStringLiteral( "units" ) ).toInt() ); - mAlignment = static_cast< Alignment >( itemElem.attribute( QStringLiteral( "alignment" ), QStringLiteral( "0" ) ).toInt() ); + if ( itemElem.attribute( QStringLiteral( "unitType" ) ).isEmpty() ) + { + QgsUnitTypes::DistanceUnit u = QgsUnitTypes::DistanceUnknownUnit; + switch ( itemElem.attribute( QStringLiteral( "units" ) ).toInt() ) + { + case 0: + u = QgsUnitTypes::DistanceUnknownUnit; + break; + case 1: + u = QgsUnitTypes::DistanceMeters; + break; + case 2: + u = QgsUnitTypes::DistanceFeet; + break; + case 3: + u = QgsUnitTypes::DistanceNauticalMiles; + break; + } + mSettings.setUnits( u ); + } + else + { + mSettings.setUnits( QgsUnitTypes::decodeDistanceUnit( itemElem.attribute( QStringLiteral( "unitType" ) ) ) ); + } + mSettings.setAlignment( static_cast< QgsScaleBarSettings::Alignment >( itemElem.attribute( QStringLiteral( "alignment" ), QStringLiteral( "0" ) ).toInt() ) ); //map int mapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) ).toInt(); if ( mapId >= 0 ) { const QgsComposerMap *composerMap = mComposition->getComposerMapById( mapId ); - mComposerMap = composerMap; + mComposerMap = const_cast< QgsComposerMap *>( composerMap ); if ( mComposerMap ) { connect( mComposerMap, &QgsComposerMap::extentChanged, this, &QgsComposerScaleBar::updateSegmentSize ); @@ -947,11 +910,11 @@ void QgsComposerScaleBar::correctXPositionAlignment( double width, double widthA return; } - if ( mAlignment == Middle ) + if ( mSettings.alignment() == QgsScaleBarSettings::AlignMiddle ) { move( -( widthAfter - width ) / 2.0, 0 ); } - else if ( mAlignment == Right ) + else if ( mSettings.alignment() == QgsScaleBarSettings::AlignRight ) { move( -( widthAfter - width ), 0 ); } diff --git a/src/core/composer/qgscomposerscalebar.h b/src/core/composer/qgscomposerscalebar.h index a4e91ab926e..182bc11218d 100644 --- a/src/core/composer/qgscomposerscalebar.h +++ b/src/core/composer/qgscomposerscalebar.h @@ -18,12 +18,13 @@ #include "qgis_core.h" #include "qgscomposeritem.h" +#include "scalebar/qgsscalebarsettings.h" +#include "scalebar/qgsscalebarrenderer.h" #include #include #include class QgsComposerMap; -class QgsScaleBarStyle; /** \ingroup core * A scale bar item that can be added to a map composition. @@ -35,29 +36,6 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem public: - enum Alignment - { - Left = 0, - Middle, - Right - }; - - enum ScaleBarUnits - { - MapUnits = 0, - Meters, - Feet, - NauticalMiles - }; - - /** Modes for setting size for scale bar segments - */ - enum SegmentSizeMode - { - SegmentSizeFixed = 0, //!< Scale bar segment size is fixed to a map unit - SegmentSizeFitWidth = 1 //!< Scale bar segment size is calculated to fit a size range - }; - QgsComposerScaleBar( QgsComposition *composition ); ~QgsComposerScaleBar(); @@ -68,13 +46,13 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override; //getters and setters - int numSegments() const {return mNumSegments;} + int numSegments() const {return mSettings.numberOfSegments();} void setNumSegments( int nSegments ); - int numSegmentsLeft() const {return mNumSegmentsLeft;} + int numSegmentsLeft() const {return mSettings.numberOfSegmentsLeft();} void setNumSegmentsLeft( int nSegmentsLeft ); - double numUnitsPerSegment() const {return mNumUnitsPerSegment;} + double numUnitsPerSegment() const {return mSettings.unitsPerSegment();} void setNumUnitsPerSegment( double units ); /** Returns the size mode for scale bar segments. @@ -83,7 +61,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see maxBarWidth * \since QGIS 2.9 */ - SegmentSizeMode segmentSizeMode() const { return mSegmentSizeMode; } + QgsScaleBarSettings::SegmentSizeMode segmentSizeMode() const { return mSettings.segmentSizeMode(); } /** Sets the size mode for scale bar segments. * \param mode size mode @@ -92,7 +70,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see setMaxBarWidth * \since QGIS 2.9 */ - void setSegmentSizeMode( SegmentSizeMode mode ); + void setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode mode ); /** Returns the minimum size (in millimeters) for scale bar segments. This * property is only effective if the segmentSizeMode() is set @@ -102,7 +80,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see maxBarWidth * \since QGIS 2.9 */ - double minBarWidth() const { return mMinBarWidth; } + double minBarWidth() const { return mSettings.minimumBarWidth(); } /** Sets the minimum size (in millimeters) for scale bar segments. This * property is only effective if the segmentSizeMode() is set @@ -123,7 +101,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see minBarWidth * \since QGIS 2.9 */ - double maxBarWidth() const { return mMaxBarWidth; } + double maxBarWidth() const { return mSettings.maximumBarWidth(); } /** Sets the maximum size (in millimeters) for scale bar segments. This * property is only effective if the segmentSizeMode() is set @@ -136,11 +114,11 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem */ void setMaxBarWidth( double maxWidth ); - double numMapUnitsPerScaleBarUnit() const {return mNumMapUnitsPerScaleBarUnit;} - void setNumMapUnitsPerScaleBarUnit( double d ) {mNumMapUnitsPerScaleBarUnit = d;} + double numMapUnitsPerScaleBarUnit() const {return mSettings.mapUnitsPerScaleBarUnit();} + void setNumMapUnitsPerScaleBarUnit( double d ) { mSettings.setMapUnitsPerScaleBarUnit( d );} - QString unitLabeling() const {return mUnitLabeling;} - void setUnitLabeling( const QString &label ) {mUnitLabeling = label;} + QString unitLabeling() const {return mSettings.unitLabel();} + void setUnitLabeling( const QString &label ) { mSettings.setUnitLabel( label );} QFont font() const; void setFont( const QFont &font ); @@ -150,73 +128,73 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see setFontColor * \see font */ - QColor fontColor() const {return mFontColor;} + QColor fontColor() const {return mSettings.fontColor();} /** Sets the color used for drawing text in the scalebar. * \param c font color for scalebar. * \see fontColor * \see setFont */ - void setFontColor( const QColor &c ) {mFontColor = c;} + void setFontColor( const QColor &c ) {mSettings.setFontColor( c );} /** Returns the color used for fills in the scalebar. * \see setFillColor() * \see fillColor2() * \since QGIS 3.0 */ - QColor fillColor() const {return mFillColor;} + QColor fillColor() const {return mSettings.fillColor();} /** Sets the color used for fills in the scalebar. * \see fillColor() * \see setFillColor2() * \since QGIS 3.0 */ - void setFillColor( const QColor &color ) {mFillColor = color; mBrush.setColor( color ); } + void setFillColor( const QColor &color ) {mSettings.setFillColor( color ); } /** Returns the secondary color used for fills in the scalebar. * \see setFillColor2() * \see fillColor() * \since QGIS 3.0 */ - QColor fillColor2() const {return mFillColor2;} + QColor fillColor2() const {return mSettings.fillColor2();} /** Sets the secondary color used for fills in the scalebar. * \see fillColor2() * \see setFillColor2() * \since QGIS 3.0 */ - void setFillColor2( const QColor &color ) {mFillColor2 = color; mBrush2.setColor( color ); } + void setFillColor2( const QColor &color ) {mSettings.setFillColor2( color ); } /** Returns the color used for lines in the scalebar. * \see setLineColor() * \since QGIS 3.0 */ - QColor lineColor() const {return mLineColor;} + QColor lineColor() const {return mSettings.lineColor();} /** Sets the color used for lines in the scalebar. * \see lineColor() * \since QGIS 3.0 */ - void setLineColor( const QColor &color ) { mLineColor = color; mPen.setColor( mLineColor ); } + void setLineColor( const QColor &color ) { mSettings.setLineColor( color ); } /** Returns the line width in millimeters for lines in the scalebar. * \see setLineWidth() * \since QGIS 3.0 */ - double lineWidth() const {return mLineWidth;} + double lineWidth() const {return mSettings.lineWidth();} /** Sets the line width in millimeters for lines in the scalebar. * \see lineWidth() * \since QGIS 3.0 */ - void setLineWidth( double width ) { mLineWidth = width; mPen.setWidthF( width ); } + void setLineWidth( double width ) { mSettings.setLineWidth( width ); } /** Returns the pen used for drawing the scalebar. * \returns QPen used for drawing the scalebar outlines. * \see setPen * \see brush */ - QPen pen() const {return mPen;} + QPen pen() const {return mSettings.pen();} /** Returns the primary brush for the scalebar. * \returns QBrush used for filling the scalebar @@ -224,7 +202,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see brush2 * \see pen */ - QBrush brush() const {return mBrush;} + QBrush brush() const {return mSettings.brush();} /** Returns the secondary brush for the scalebar. This is used for alternating color style scalebars, such * as single and double box styles. @@ -232,37 +210,35 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \see setBrush2 * \see brush */ - QBrush brush2() const {return mBrush2;} + QBrush brush2() const {return mSettings.brush2(); } - double height() const {return mHeight;} - void setHeight( double h ) {mHeight = h;} + double height() const { return mSettings.height(); } + void setHeight( double h ) { mSettings.setHeight( h );} - void setComposerMap( const QgsComposerMap *map ); - const QgsComposerMap *composerMap() const {return mComposerMap;} + void setComposerMap( QgsComposerMap *map ); + QgsComposerMap *composerMap() const {return mComposerMap;} - double labelBarSpace() const {return mLabelBarSpace;} - void setLabelBarSpace( double space ) {mLabelBarSpace = space;} + double labelBarSpace() const {return mSettings.labelBarSpace();} + void setLabelBarSpace( double space ) {mSettings.setLabelBarSpace( space );} - double boxContentSpace() const {return mBoxContentSpace;} + double boxContentSpace() const {return mSettings.boxContentSpace();} void setBoxContentSpace( double space ); - double segmentMillimeters() const {return mSegmentMillimeters;} - //! Left / Middle/ Right - Alignment alignment() const { return mAlignment; } + QgsScaleBarSettings::Alignment alignment() const { return mSettings.alignment(); } - void setAlignment( Alignment a ); + void setAlignment( QgsScaleBarSettings::Alignment a ); - ScaleBarUnits units() const { return mUnits; } + QgsUnitTypes::DistanceUnit units() const { return mSettings.units(); } - void setUnits( ScaleBarUnits u ); + void setUnits( QgsUnitTypes::DistanceUnit u ); /** Returns the join style used for drawing lines in the scalebar * \returns Join style for lines * \since QGIS 2.3 * \see setLineJoinStyle */ - Qt::PenJoinStyle lineJoinStyle() const { return mLineJoinStyle; } + Qt::PenJoinStyle lineJoinStyle() const { return mSettings.lineJoinStyle(); } /** Sets join style used when drawing the lines in the scalebar * \param style Join style for lines @@ -277,7 +253,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem * \since QGIS 2.3 * \see setLineCapStyle */ - Qt::PenCapStyle lineCapStyle() const { return mLineCapStyle; } + Qt::PenCapStyle lineCapStyle() const { return mSettings.lineCapStyle(); } /** Sets cap style used when drawing the lines in the scalebar * \param style Cap style for lines @@ -290,7 +266,7 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem //! Apply default settings void applyDefaultSettings(); //! Apply default size (scale bar 1/5 of map item width) - void applyDefaultSize( ScaleBarUnits u = Meters ); + void applyDefaultSize( QgsUnitTypes::DistanceUnit u = QgsUnitTypes::DistanceMeters ); /** Sets style by name \param styleName (untranslated) style name. Possibilities are: 'Single Box', 'Double Box', 'Line Ticks Middle', 'Line Ticks Down', 'Line Ticks Up', 'Numeric'*/ @@ -299,20 +275,12 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem //! Returns style name QString style() const; - /** Returns the x - positions of the segment borders (in item coordinates) and the width - * of the segment - * \note not available in Python bindings - */ - void segmentPositions( QList > &posWidthList ) const; - //! Sets box size suitable to content void adjustBoxSize(); //! Adjusts box size and calls QgsComposerItem::update() void update(); - //! Returns string of first label (important for drawing, labeling, size calculation - QString firstLabelString() const; /** Stores state in Dom element * \param elem is Dom element corresponding to 'Composer' tag @@ -338,70 +306,27 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem void invalidateCurrentMap(); virtual void refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property = QgsComposerObject::AllProperties, const QgsExpressionContext *context = nullptr ) override; - protected: + private: //! Reference to composer map object - const QgsComposerMap *mComposerMap = nullptr; - //! Number of segments on right side - int mNumSegments; - //! Number of segments on left side - int mNumSegmentsLeft; - //! Size of a segment (in map units) - double mNumUnitsPerSegment; - //! Number of map units per scale bar units (e.g. 1000 to have km for a map with m units) - double mNumMapUnitsPerScaleBarUnit; - //! Either fixed (i.e. mNumUnitsPerSegment) or try to best fit scale bar width (mMinBarWidth, mMaxBarWidth) - SegmentSizeMode mSegmentSizeMode; - //! Minimum allowed bar width, when mSegmentSizeMode is FitWidth - double mMinBarWidth; - //! Maximum allowed bar width, when mSegmentSizeMode is FitWidth - double mMaxBarWidth; + QgsComposerMap *mComposerMap = nullptr; + + QgsScaleBarSettings mSettings; - //! Labeling of map units - QString mUnitLabeling; - //! Font - QFont mFont; - QColor mFontColor; - //! Fill color - QColor mFillColor = QColor( 0, 0, 0 ); - //! Secondary fill color - QColor mFillColor2 = QColor( 255, 255, 255 ); - //! Line color - QColor mLineColor = QColor( 0, 0, 0 ); - //! Line width - double mLineWidth = 0.3; - //! Stroke - QPen mPen; - //! Fill - QBrush mBrush; - //! Secondary fill - QBrush mBrush2; - //! Height of bars/lines - double mHeight; //! Scalebar style - QgsScaleBarStyle *mStyle = nullptr; - - //! Space between bar and Text labels - double mLabelBarSpace; - - //! Space between content and item box - double mBoxContentSpace; + QgsScaleBarRenderer *mStyle = nullptr; //! Width of a segment (in mm) double mSegmentMillimeters; - Alignment mAlignment; - - ScaleBarUnits mUnits; - - Qt::PenJoinStyle mLineJoinStyle; - Qt::PenCapStyle mLineCapStyle; - //! Calculates with of a segment in mm and stores it in mSegmentMillimeters void refreshSegmentMillimeters(); //! Returns diagonal of composer map in selected units (map units / meters / feet / nautical miles) double mapWidth() const; + + QgsScaleBarRenderer::ScaleBarContext createScaleContext() const; + }; #endif //QGSCOMPOSERSCALEBAR_H diff --git a/src/core/composer/qgsdoubleboxscalebarstyle.cpp b/src/core/composer/qgsdoubleboxscalebarstyle.cpp deleted file mode 100644 index e089e3287e5..00000000000 --- a/src/core/composer/qgsdoubleboxscalebarstyle.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************** - qgsdoubleboxscalebarstyle.cpp - ----------------------------- - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgsdoubleboxscalebarstyle.h" -#include "qgscomposerscalebar.h" -#include "qgscomposerutils.h" -#include -#include - -QgsDoubleBoxScaleBarStyle::QgsDoubleBoxScaleBarStyle( const QgsComposerScaleBar *bar ): QgsScaleBarStyle( bar ) -{ - -} - -QgsDoubleBoxScaleBarStyle::QgsDoubleBoxScaleBarStyle(): QgsScaleBarStyle( nullptr ) -{ - -} - -QString QgsDoubleBoxScaleBarStyle::name() const -{ - return QStringLiteral( "Double Box" ); -} - -void QgsDoubleBoxScaleBarStyle::draw( QPainter *p, double xOffset ) const -{ - if ( !mScaleBar ) - { - return; - } - double barTopPosition = QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->labelBarSpace() + mScaleBar->boxContentSpace(); - double segmentHeight = mScaleBar->height() / 2; - - p->save(); - //antialiasing on - p->setRenderHint( QPainter::Antialiasing, true ); - p->setPen( mScaleBar->pen() ); - - QList > segmentInfo; - mScaleBar->segmentPositions( segmentInfo ); - - bool useColor = true; //alternate brush color/white - - QList >::const_iterator segmentIt = segmentInfo.constBegin(); - for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt ) - { - //draw top half - if ( useColor ) - { - p->setBrush( mScaleBar->brush() ); - } - else //secondary color - { - p->setBrush( mScaleBar->brush2() ); - } - - QRectF segmentRectTop( segmentIt->first + xOffset, barTopPosition, segmentIt->second, segmentHeight ); - p->drawRect( segmentRectTop ); - - //draw bottom half - if ( useColor ) - { - //secondary color - p->setBrush( mScaleBar->brush2() ); - } - else //primary color - { - p->setBrush( mScaleBar->brush() ); - } - - QRectF segmentRectBottom( segmentIt->first + xOffset, barTopPosition + segmentHeight, segmentIt->second, segmentHeight ); - p->drawRect( segmentRectBottom ); - useColor = !useColor; - } - - p->restore(); - - //draw labels using the default method - drawLabels( p ); -} diff --git a/src/core/composer/qgsnumericscalebarstyle.cpp b/src/core/composer/qgsnumericscalebarstyle.cpp deleted file mode 100644 index 63672091467..00000000000 --- a/src/core/composer/qgsnumericscalebarstyle.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************** - qgsnumericscalebarstyle.cpp - --------------------------- - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgsnumericscalebarstyle.h" -#include "qgscomposermap.h" -#include "qgscomposerscalebar.h" -#include "qgscomposerutils.h" -#include -#include - -QgsNumericScaleBarStyle::QgsNumericScaleBarStyle( QgsComposerScaleBar *bar ): QgsScaleBarStyle( bar ), mLastScaleBarWidth( 0 ) -{ - -} - -QgsNumericScaleBarStyle::QgsNumericScaleBarStyle(): QgsScaleBarStyle( nullptr ), mLastScaleBarWidth( 0 ) -{ - -} - -QString QgsNumericScaleBarStyle::name() const -{ - return QStringLiteral( "Numeric" ); -} - -void QgsNumericScaleBarStyle::draw( QPainter *p, double xOffset ) const -{ - Q_UNUSED( xOffset ); - if ( !p || !mScaleBar ) - { - return; - } - - p->save(); - //antialiasing on - p->setRenderHint( QPainter::Antialiasing, true ); - p->setFont( mScaleBar->font() ); - - //call QgsComposerItem's pen() function, since that refers to the frame pen - //and QgsComposerScalebar's pen() function refers to the scale bar line width, - //which is not used for numeric scale bars. Divide the pen width by 2 since - //half the width of the frame is drawn outside the item. - double penWidth = mScaleBar->QgsComposerItem::pen().widthF() / 2.0; - double margin = mScaleBar->boxContentSpace(); - //map scalebar alignment to Qt::AlignmentFlag type - Qt::AlignmentFlag hAlign; - switch ( mScaleBar->alignment() ) - { - case QgsComposerScaleBar::Left: - hAlign = Qt::AlignLeft; - break; - case QgsComposerScaleBar::Middle: - hAlign = Qt::AlignHCenter; - break; - case QgsComposerScaleBar::Right: - hAlign = Qt::AlignRight; - break; - default: - hAlign = Qt::AlignLeft; - break; - } - - //text destination is item's rect, excluding the margin and frame - QRectF painterRect( penWidth + margin, penWidth + margin, mScaleBar->rect().width() - 2 * penWidth - 2 * margin, mScaleBar->rect().height() - 2 * penWidth - 2 * margin ); - QgsComposerUtils::drawText( p, painterRect, scaleText(), mScaleBar->font(), mScaleBar->fontColor(), hAlign, Qt::AlignTop ); - - p->restore(); -} - -QRectF QgsNumericScaleBarStyle::calculateBoxSize() const -{ - QRectF rect; - if ( !mScaleBar ) - { - return rect; - } - - double textWidth = QgsComposerUtils::textWidthMM( mScaleBar->font(), scaleText() ); - double textHeight = QgsComposerUtils::fontAscentMM( mScaleBar->font() ); - - rect = QRectF( mScaleBar->pos().x(), mScaleBar->pos().y(), 2 * mScaleBar->boxContentSpace() - + 2 * mScaleBar->pen().width() + textWidth, - textHeight + 2 * mScaleBar->boxContentSpace() ); - - if ( !qgsDoubleNear( mLastScaleBarWidth, rect.width() ) && mLastScaleBarWidth > 0 && rect.width() > 0 ) - { - //hack to move scale bar the left / right in order to keep the bar alignment - const_cast( mScaleBar )->correctXPositionAlignment( mLastScaleBarWidth, rect.width() ); - } - mLastScaleBarWidth = rect.width(); - return rect; -} - -QString QgsNumericScaleBarStyle::scaleText() const -{ - QString scaleBarText; - if ( mScaleBar ) - { - //find out scale - double scaleDenominator = 1; - const QgsComposerMap *composerMap = mScaleBar->composerMap(); - if ( composerMap ) - { - scaleDenominator = composerMap->scale(); - scaleBarText = "1:" + QStringLiteral( "%L1" ).arg( scaleDenominator, 0, 'f', 0 ); - } - scaleBarText = "1:" + QStringLiteral( "%L1" ).arg( scaleDenominator, 0, 'f', 0 ); - } - return scaleBarText; -} diff --git a/src/core/composer/qgsscalebarstyle.cpp b/src/core/composer/qgsscalebarstyle.cpp deleted file mode 100644 index a6054ccf6c9..00000000000 --- a/src/core/composer/qgsscalebarstyle.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - qgsscalebarstyle.cpp - -------------------- - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgsscalebarstyle.h" -#include "qgscomposerscalebar.h" -#include "qgscomposerutils.h" -#include -#include - -QgsScaleBarStyle::QgsScaleBarStyle( const QgsComposerScaleBar *bar ): mScaleBar( bar ) -{ - -} - -QgsScaleBarStyle::QgsScaleBarStyle(): mScaleBar( nullptr ) -{ - -} - -void QgsScaleBarStyle::drawLabels( QPainter *p ) const -{ - if ( !p || !mScaleBar ) - { - return; - } - - p->save(); - - p->setFont( mScaleBar->font() ); - p->setPen( QPen( mScaleBar->fontColor() ) ); - - QString firstLabel = mScaleBar->firstLabelString(); - double xOffset = QgsComposerUtils::textWidthMM( mScaleBar->font(), firstLabel ) / 2; - - //double mCurrentXCoord = mScaleBar->pen().widthF() + mScaleBar->boxContentSpace(); - QList > segmentInfo; - mScaleBar->segmentPositions( segmentInfo ); - - double currentLabelNumber = 0.0; - - int nSegmentsLeft = mScaleBar->numSegmentsLeft(); - int segmentCounter = 0; - QString currentNumericLabel; - - QList >::const_iterator segmentIt = segmentInfo.constBegin(); - for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt ) - { - if ( segmentCounter == 0 && nSegmentsLeft > 0 ) - { - //label first left segment - currentNumericLabel = firstLabel; - } - else if ( segmentCounter != 0 && segmentCounter == nSegmentsLeft ) //reset label number to 0 if there are left segments - { - currentLabelNumber = 0; - } - - if ( segmentCounter >= nSegmentsLeft ) - { - currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() ); - } - - if ( segmentCounter == 0 || segmentCounter >= nSegmentsLeft ) //don't draw label for intermediate left segments - { - QgsComposerUtils::drawText( p, QPointF( segmentIt->first - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ), - currentNumericLabel, mScaleBar->font(), mScaleBar->fontColor() ); - } - - if ( segmentCounter >= nSegmentsLeft ) - { - currentLabelNumber += mScaleBar->numUnitsPerSegment(); - } - ++segmentCounter; - } - - //also draw the last label - if ( !segmentInfo.isEmpty() ) - { - currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() ); - QgsComposerUtils::drawText( p, QPointF( segmentInfo.last().first + mScaleBar->segmentMillimeters() - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ), - currentNumericLabel + ' ' + mScaleBar->unitLabeling(), mScaleBar->font(), mScaleBar->fontColor() ); - } - - p->restore(); -} - -QRectF QgsScaleBarStyle::calculateBoxSize() const -{ - if ( !mScaleBar ) - { - return QRectF(); - } - - //consider centered first label - double firstLabelLeft = QgsComposerUtils::textWidthMM( mScaleBar->font(), mScaleBar->firstLabelString() ) / 2; - - //consider last number and label - - double largestLabelNumber = mScaleBar->numSegments() * mScaleBar->numUnitsPerSegment() / mScaleBar->numMapUnitsPerScaleBarUnit(); - QString largestNumberLabel = QString::number( largestLabelNumber ); - QString largestLabel = QString::number( largestLabelNumber ) + ' ' + mScaleBar->unitLabeling(); - double largestLabelWidth = QgsComposerUtils::textWidthMM( mScaleBar->font(), largestLabel ) - QgsComposerUtils::textWidthMM( mScaleBar->font(), largestNumberLabel ) / 2; - - double totalBarLength = 0.0; - - QList< QPair > segmentList; - mScaleBar->segmentPositions( segmentList ); - - QList< QPair >::const_iterator segmentIt = segmentList.constBegin(); - for ( ; segmentIt != segmentList.constEnd(); ++segmentIt ) - { - totalBarLength += segmentIt->second; - } - - double width = firstLabelLeft + totalBarLength + 2 * mScaleBar->pen().widthF() + largestLabelWidth + 2 * mScaleBar->boxContentSpace(); - double height = mScaleBar->height() + mScaleBar->labelBarSpace() + 2 * mScaleBar->boxContentSpace() + QgsComposerUtils::fontAscentMM( mScaleBar->font() ); - - return QRectF( mScaleBar->pos().x(), mScaleBar->pos().y(), width, height ); -} diff --git a/src/core/composer/qgsscalebarstyle.h b/src/core/composer/qgsscalebarstyle.h deleted file mode 100644 index f44fc19832a..00000000000 --- a/src/core/composer/qgsscalebarstyle.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - qgsscalebarstyle.h - ------------------ - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef QGSSCALEBARSTYLE_H -#define QGSSCALEBARSTYLE_H - -#include -#include - -#include "qgis_core.h" - -class QgsComposerScaleBar; -class QPainter; - -/** \ingroup core - * Abstraction of composer scale bar style. Subclasses draw themselves, have the -possibility to implement custom labeling and calculate corresponding box size. -*/ -class CORE_EXPORT QgsScaleBarStyle -{ - public: - QgsScaleBarStyle( const QgsComposerScaleBar *bar ); - virtual ~QgsScaleBarStyle() = default; - - /** Draws the style - \param p painter object - \param xOffset offset to account for centered labeling*/ - virtual void draw( QPainter *p, double xOffset = 0 ) const = 0; //to do by every subclass - virtual void drawLabels( QPainter *p ) const; //default implementation provided - virtual QRectF calculateBoxSize() const; //default implementation provided - - /** - * Get a name for this style. - * Needs to be remiplmeented by subclasses. - */ - virtual QString name() const = 0; - - private: - QgsScaleBarStyle(); //default constructor forbidden - - protected: - const QgsComposerScaleBar *mScaleBar = nullptr; -}; - -#endif diff --git a/src/core/composer/qgssingleboxscalebarstyle.cpp b/src/core/composer/qgssingleboxscalebarstyle.cpp deleted file mode 100644 index 9a104a17ba3..00000000000 --- a/src/core/composer/qgssingleboxscalebarstyle.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - qgssingleboxscalebarstyle.h - ------------------ - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgssingleboxscalebarstyle.h" -#include "qgscomposerscalebar.h" -#include "qgscomposerutils.h" -#include -#include - -QgsSingleBoxScaleBarStyle::QgsSingleBoxScaleBarStyle( const QgsComposerScaleBar *bar ): QgsScaleBarStyle( bar ) -{ - -} - -QgsSingleBoxScaleBarStyle::QgsSingleBoxScaleBarStyle(): QgsScaleBarStyle( nullptr ) -{ - -} - -QgsSingleBoxScaleBarStyle::~QgsSingleBoxScaleBarStyle() -{ - //nothing to do... -} - -void QgsSingleBoxScaleBarStyle::draw( QPainter *p, double xOffset ) const -{ - if ( !mScaleBar ) - { - return; - } - double barTopPosition = QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->labelBarSpace() + mScaleBar->boxContentSpace(); - - p->save(); - //antialiasing on - p->setRenderHint( QPainter::Antialiasing, true ); - p->setPen( mScaleBar->pen() ); - - QList > segmentInfo; - mScaleBar->segmentPositions( segmentInfo ); - - bool useColor = true; //alternate brush color/white - - QList >::const_iterator segmentIt = segmentInfo.constBegin(); - for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt ) - { - if ( useColor ) //alternating colors - { - p->setBrush( mScaleBar->brush() ); - } - else //secondary color - { - p->setBrush( mScaleBar->brush2() ); - } - - QRectF segmentRect( segmentIt->first + xOffset, barTopPosition, segmentIt->second, mScaleBar->height() ); - p->drawRect( segmentRect ); - useColor = !useColor; - } - - p->restore(); - - //draw labels using the default method - drawLabels( p ); -} - -QString QgsSingleBoxScaleBarStyle::name() const -{ - return QStringLiteral( "Single Box" ); -} - diff --git a/src/core/composer/qgsticksscalebarstyle.cpp b/src/core/composer/qgsticksscalebarstyle.cpp deleted file mode 100644 index 1fd69b5d48d..00000000000 --- a/src/core/composer/qgsticksscalebarstyle.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - qgsticksscalebarstyle.cpp - ------------------------- - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgsticksscalebarstyle.h" -#include "qgscomposerscalebar.h" -#include "qgscomposerutils.h" -#include - -QgsTicksScaleBarStyle::QgsTicksScaleBarStyle( const QgsComposerScaleBar *bar ): QgsScaleBarStyle( bar ) -{ - mTickPosition = TicksMiddle; -} - -QgsTicksScaleBarStyle::QgsTicksScaleBarStyle(): QgsScaleBarStyle( nullptr ) -{ - mTickPosition = TicksMiddle; -} - -QString QgsTicksScaleBarStyle::name() const -{ - switch ( mTickPosition ) - { - case TicksUp: - return QStringLiteral( "Line Ticks Up" ); - case TicksDown: - return QStringLiteral( "Line Ticks Down" ); - case TicksMiddle: - return QStringLiteral( "Line Ticks Middle" ); - } - return QLatin1String( "" ); // to make gcc happy -} - -void QgsTicksScaleBarStyle::draw( QPainter *p, double xOffset ) const -{ - if ( !mScaleBar ) - { - return; - } - double barTopPosition = QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->labelBarSpace() + mScaleBar->boxContentSpace(); - double middlePosition = barTopPosition + mScaleBar->height() / 2.0; - double bottomPosition = barTopPosition + mScaleBar->height(); - - p->save(); - //antialiasing on - p->setRenderHint( QPainter::Antialiasing, true ); - p->setPen( mScaleBar->pen() ); - - QList > segmentInfo; - mScaleBar->segmentPositions( segmentInfo ); - - QList >::const_iterator segmentIt = segmentInfo.constBegin(); - for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt ) - { - p->drawLine( QLineF( segmentIt->first + xOffset, barTopPosition, segmentIt->first + xOffset, barTopPosition + mScaleBar->height() ) ); - } - - //draw last tick and horizontal line - if ( !segmentInfo.isEmpty() ) - { - double lastTickPositionX = segmentInfo.last().first + mScaleBar->segmentMillimeters() + xOffset; - double verticalPos = 0.0; - switch ( mTickPosition ) - { - case TicksDown: - verticalPos = barTopPosition; - break; - case TicksMiddle: - verticalPos = middlePosition; - break; - case TicksUp: - verticalPos = bottomPosition; - break; - } - //horizontal line - p->drawLine( QLineF( xOffset + segmentInfo.at( 0 ).first, verticalPos, lastTickPositionX, verticalPos ) ); - //last vertical line - p->drawLine( QLineF( lastTickPositionX, barTopPosition, lastTickPositionX, barTopPosition + mScaleBar->height() ) ); - } - - p->restore(); - - //draw labels using the default method - drawLabels( p ); -} - - diff --git a/src/core/composer/qgsticksscalebarstyle.h b/src/core/composer/qgsticksscalebarstyle.h deleted file mode 100644 index 76cbbe6ce65..00000000000 --- a/src/core/composer/qgsticksscalebarstyle.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - qgsticksscalebarstyle.h - ----------------------------- - begin : June 2008 - copyright : (C) 2008 by Marco Hugentobler - email : marco.hugentobler@karto.baug.ethz.ch - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef QGSTICKSSCALEBARSTYLE_H -#define QGSTICKSSCALEBARSTYLE_H - -#include "qgis_core.h" -#include "qgsscalebarstyle.h" - -/** \ingroup core - * A scale bar that draws segments using short ticks. - */ -class CORE_EXPORT QgsTicksScaleBarStyle: public QgsScaleBarStyle -{ - public: - enum TickPosition - { - TicksUp, - TicksDown, - TicksMiddle - }; - - QgsTicksScaleBarStyle( const QgsComposerScaleBar *bar ); - - QString name() const override; - - /** Draw method - \param p painter object - \param xOffset offset - */ - void draw( QPainter *p, double xOffset = 0 ) const override; - - void setTickPosition( TickPosition p ) {mTickPosition = p;} - - private: - QgsTicksScaleBarStyle(); //forbidden - - TickPosition mTickPosition; -}; - -#endif diff --git a/src/core/scalebar/qgsdoubleboxscalebarrenderer.cpp b/src/core/scalebar/qgsdoubleboxscalebarrenderer.cpp new file mode 100644 index 00000000000..4959928f14a --- /dev/null +++ b/src/core/scalebar/qgsdoubleboxscalebarrenderer.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + qgsdoubleboxscalebarrenderer.cpp + -------------------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsdoubleboxscalebarrenderer.h" +#include "qgsscalebarsettings.h" +#include "qgscomposerutils.h" +#include +#include + +void QgsDoubleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const +{ + if ( !context.painter() ) + { + return; + } + QPainter *painter = context.painter(); + + double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(); + double segmentHeight = settings.height() / 2; + + painter->save(); + if ( context.flags() & QgsRenderContext::Antialiasing ) + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setPen( settings.pen() ); + + bool useColor = true; //alternate brush color/white + + double xOffset = firstLabelXOffset( settings ); + + QList positions = segmentPositions( scaleContext, settings ); + QList widths = segmentWidths( scaleContext, settings ); + + for ( int i = 0; i < positions.size(); ++i ) + { + //draw top half + if ( useColor ) + { + painter->setBrush( settings.brush() ); + } + else //secondary color + { + painter->setBrush( settings.brush2() ); + } + + QRectF segmentRectTop( positions.at( i ) + xOffset, barTopPosition, widths.at( i ), segmentHeight ); + painter->drawRect( segmentRectTop ); + + //draw bottom half + if ( useColor ) + { + //secondary color + painter->setBrush( settings.brush2() ); + } + else //primary color + { + painter->setBrush( settings.brush() ); + } + + QRectF segmentRectBottom( positions.at( i ) + xOffset, barTopPosition + segmentHeight, widths.at( i ), segmentHeight ); + painter->drawRect( segmentRectBottom ); + useColor = !useColor; + } + + painter->restore(); + + //draw labels using the default method + drawDefaultLabels( context, settings, scaleContext ); +} diff --git a/src/core/composer/qgsdoubleboxscalebarstyle.h b/src/core/scalebar/qgsdoubleboxscalebarrenderer.h similarity index 55% rename from src/core/composer/qgsdoubleboxscalebarstyle.h rename to src/core/scalebar/qgsdoubleboxscalebarrenderer.h index f18d7681c7d..8443ec0a0cf 100644 --- a/src/core/composer/qgsdoubleboxscalebarstyle.h +++ b/src/core/scalebar/qgsdoubleboxscalebarrenderer.h @@ -1,6 +1,6 @@ /*************************************************************************** - qgsdoubleboxscalebarstyle.h - --------------------------- + qgsdoubleboxscalebarrenderer.h + ------------------------------ begin : June 2008 copyright : (C) 2008 by Marco Hugentobler email : marco.hugentobler@karto.baug.ethz.ch @@ -14,26 +14,30 @@ * * ***************************************************************************/ -#ifndef QGSDOUBLEBOXSCALEBARSTYLE_H -#define QGSDOUBLEBOXSCALEBARSTYLE_H +#ifndef QGSDOUBLEBOXSCALEBARRENDERER_H +#define QGSDOUBLEBOXSCALEBARRENDERER_H #include "qgis_core.h" -#include "qgsscalebarstyle.h" +#include "qgsscalebarrenderer.h" +#include -/** \ingroup core - * Double box with alternating colors - */ -class CORE_EXPORT QgsDoubleBoxScaleBarStyle: public QgsScaleBarStyle +/** + * \class QgsDoubleBoxScaleBarRenderer + * \ingroup core + * Double box with alternating colors. + * \since QGIS 3.0 + */ +class CORE_EXPORT QgsDoubleBoxScaleBarRenderer: public QgsScaleBarRenderer { public: - QgsDoubleBoxScaleBarStyle( const QgsComposerScaleBar *bar ); + QgsDoubleBoxScaleBarRenderer() = default; - QString name() const override; + QString name() const override { return QStringLiteral( "Double Box" ); } - void draw( QPainter *p, double xOffset = 0 ) const override; + void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const override; - private: - QgsDoubleBoxScaleBarStyle(); //forbidden }; -#endif +#endif // QGSDOUBLEBOXSCALEBARRENDERER_H diff --git a/src/core/scalebar/qgsnumericscalebarrenderer.cpp b/src/core/scalebar/qgsnumericscalebarrenderer.cpp new file mode 100644 index 00000000000..063e8e17826 --- /dev/null +++ b/src/core/scalebar/qgsnumericscalebarrenderer.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + qgsnumericscalebarrenderer.cpp + ------------------------------ + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsnumericscalebarrenderer.h" +#include "qgsscalebarsettings.h" +#include "qgscomposerutils.h" +#include +#include + +void QgsNumericScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const +{ + if ( !context.painter() ) + { + return; + } + + QPainter *painter = context.painter(); + + painter->save(); + if ( context.flags() & QgsRenderContext::Antialiasing ) + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setFont( settings.font() ); + + double margin = settings.boxContentSpace(); + //map scalebar alignment to Qt::AlignmentFlag type + Qt::AlignmentFlag hAlign = Qt::AlignLeft; + switch ( settings.alignment() ) + { + case QgsScaleBarSettings::AlignLeft: + hAlign = Qt::AlignLeft; + break; + case QgsScaleBarSettings::AlignMiddle: + hAlign = Qt::AlignHCenter; + break; + case QgsScaleBarSettings::AlignRight: + hAlign = Qt::AlignRight; + break; + } + + //text destination is item's rect, excluding the margin + QRectF painterRect( margin, margin, scaleContext.size.width() - 2 * margin, scaleContext.size.height() - 2 * margin ); + QgsComposerUtils::drawText( painter, painterRect, scaleText( scaleContext.scale ), settings.font(), settings.fontColor(), hAlign, Qt::AlignTop ); + + painter->restore(); +} + +QSizeF QgsNumericScaleBarRenderer::calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const +{ + QRectF rect; + + double textWidth = QgsComposerUtils::textWidthMM( settings.font(), scaleText( scaleContext.scale ) ); + double textHeight = QgsComposerUtils::fontAscentMM( settings.font() ); + + return QSizeF( 2 * settings.boxContentSpace() + 2 * settings.pen().width() + textWidth, + textHeight + 2 * settings.boxContentSpace() ); +} + +QString QgsNumericScaleBarRenderer::scaleText( double scale ) const +{ + return "1:" + QStringLiteral( "%L1" ).arg( scale, 0, 'f', 0 ); +} diff --git a/src/core/composer/qgsnumericscalebarstyle.h b/src/core/scalebar/qgsnumericscalebarrenderer.h similarity index 51% rename from src/core/composer/qgsnumericscalebarstyle.h rename to src/core/scalebar/qgsnumericscalebarrenderer.h index c8f968aab94..68284f226aa 100644 --- a/src/core/composer/qgsnumericscalebarstyle.h +++ b/src/core/scalebar/qgsnumericscalebarrenderer.h @@ -1,6 +1,6 @@ /*************************************************************************** - qgsnumericscalebarstyle.h - --------------------------- + qgsnumericscalebarrenderer.h + ---------------------------- begin : June 2008 copyright : (C) 2008 by Marco Hugentobler email : marco.hugentobler@karto.baug.ethz.ch @@ -14,34 +14,38 @@ * * ***************************************************************************/ -#ifndef QGSNUMERICSCALEBARSTYLE_H -#define QGSNUMERICSCALEBARSTYLE_H +#ifndef QGSNUMERICSCALEBARRENDERER_H +#define QGSNUMERICSCALEBARRENDERER_H #include "qgis_core.h" -#include "qgsscalebarstyle.h" +#include "qgsscalebarrenderer.h" +#include -/** \ingroup core - * A scale bar style that draws text in the form of '1:XXXXX' +/** + * \class QgsNumericScaleBarRenderer + * \ingroup core + * A scale bar style that draws text in the form of '1:XXXXX'. + * \since QGIS 3.0 */ -class CORE_EXPORT QgsNumericScaleBarStyle: public QgsScaleBarStyle +class CORE_EXPORT QgsNumericScaleBarRenderer: public QgsScaleBarRenderer { public: - QgsNumericScaleBarStyle( QgsComposerScaleBar *bar ); + QgsNumericScaleBarRenderer() = default; - QString name() const override; + QString name() const override { return QStringLiteral( "Numeric" ); } - void draw( QPainter *p, double xOffset = 0 ) const override; + void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const override; - //calculation of box size is different compared to segment based scale bars - QRectF calculateBoxSize() const override; + QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const override; private: - QgsNumericScaleBarStyle(); //forbidden - //! Returns the text for the scale bar or an empty string in case of error - QString scaleText() const; - //! Store last width (in mm) to keep alignment to left/middle/right side - mutable double mLastScaleBarWidth; + //! Returns the text for the scale bar or an empty string in case of error + QString scaleText( double scale ) const; + }; -#endif +#endif // QGSNUMERICSCALEBARRENDERER_H diff --git a/src/core/scalebar/qgsscalebarrenderer.cpp b/src/core/scalebar/qgsscalebarrenderer.cpp new file mode 100644 index 00000000000..49002503f0d --- /dev/null +++ b/src/core/scalebar/qgsscalebarrenderer.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + qgsscalebarrenderer.cpp + ----------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsscalebarrenderer.h" +#include "qgsscalebarsettings.h" +#include "qgscomposerutils.h" +#include +#include + +void QgsScaleBarRenderer::drawDefaultLabels( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const +{ + if ( !context.painter() ) + { + return; + } + + QPainter *painter = context.painter(); + + painter->save(); + + painter->setFont( settings.font() ); + painter->setPen( QPen( settings.fontColor() ) ); + + QString firstLabel = firstLabelString( settings ); + double xOffset = QgsComposerUtils::textWidthMM( settings.font(), firstLabel ) / 2; + + double currentLabelNumber = 0.0; + + int nSegmentsLeft = settings.numberOfSegmentsLeft(); + int segmentCounter = 0; + QString currentNumericLabel; + + QList positions = segmentPositions( scaleContext, settings ); + + for ( int i = 0; i < positions.size(); ++i ) + { + if ( segmentCounter == 0 && nSegmentsLeft > 0 ) + { + //label first left segment + currentNumericLabel = firstLabel; + } + else if ( segmentCounter != 0 && segmentCounter == nSegmentsLeft ) //reset label number to 0 if there are left segments + { + currentLabelNumber = 0; + } + + if ( segmentCounter >= nSegmentsLeft ) + { + currentNumericLabel = QString::number( currentLabelNumber / settings.mapUnitsPerScaleBarUnit() ); + } + + if ( segmentCounter == 0 || segmentCounter >= nSegmentsLeft ) //don't draw label for intermediate left segments + { + QgsComposerUtils::drawText( painter, QPointF( positions.at( i ) - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace() ), + currentNumericLabel, settings.font(), settings.fontColor() ); + } + + if ( segmentCounter >= nSegmentsLeft ) + { + currentLabelNumber += settings.unitsPerSegment(); + } + ++segmentCounter; + } + + //also draw the last label + if ( !positions.isEmpty() ) + { + currentNumericLabel = QString::number( currentLabelNumber / settings.mapUnitsPerScaleBarUnit() ); + QgsComposerUtils::drawText( painter, QPointF( positions.at( positions.size() - 1 ) + scaleContext.segmentWidth - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace() ), + currentNumericLabel + ' ' + settings.unitLabel(), settings.font(), settings.fontColor() ); + } + + painter->restore(); +} + +QSizeF QgsScaleBarRenderer::calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const +{ + //consider centered first label + double firstLabelLeft = QgsComposerUtils::textWidthMM( settings.font(), firstLabelString( settings ) ) / 2; + + //consider last number and label + + double largestLabelNumber = settings.numberOfSegments() * settings.unitsPerSegment() / settings.mapUnitsPerScaleBarUnit(); + QString largestNumberLabel = QString::number( largestLabelNumber ); + QString largestLabel = QString::number( largestLabelNumber ) + ' ' + settings.unitLabel(); + double largestLabelWidth = QgsComposerUtils::textWidthMM( settings.font(), largestLabel ) - QgsComposerUtils::textWidthMM( settings.font(), largestNumberLabel ) / 2; + + double totalBarLength = scaleContext.segmentWidth * ( settings.numberOfSegments() + ( settings.numberOfSegmentsLeft() > 0 ? 1 : 0 ) ); + + double width = firstLabelLeft + totalBarLength + 2 * settings.pen().widthF() + largestLabelWidth + 2 * settings.boxContentSpace(); + double height = settings.height() + settings.labelBarSpace() + 2 * settings.boxContentSpace() + QgsComposerUtils::fontAscentMM( settings.font() ); + + return QSizeF( width, height ); +} + +QString QgsScaleBarRenderer::firstLabelString( const QgsScaleBarSettings &settings ) const +{ + if ( settings.numberOfSegmentsLeft() > 0 ) + { + return QString::number( settings.unitsPerSegment() / settings.mapUnitsPerScaleBarUnit() ); + } + else + { + return QStringLiteral( "0" ); + } +} + +double QgsScaleBarRenderer::firstLabelXOffset( const QgsScaleBarSettings &settings ) const +{ + QString firstLabel = firstLabelString( settings ); + return QgsComposerUtils::textWidthMM( settings.font(), firstLabel ) / 2.0; +} + +QList QgsScaleBarRenderer::segmentPositions( const ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const +{ + QList positions; + + double currentXCoord = settings.pen().widthF() + settings.boxContentSpace(); + + //left segments + double leftSegmentSize = scaleContext.segmentWidth / settings.numberOfSegmentsLeft(); + for ( int i = 0; i < settings.numberOfSegmentsLeft(); ++i ) + { + positions << currentXCoord; + currentXCoord += leftSegmentSize; + } + + //right segments + for ( int i = 0; i < settings.numberOfSegments(); ++i ) + { + positions << currentXCoord; + currentXCoord += scaleContext.segmentWidth; + } + return positions; +} + +QList QgsScaleBarRenderer::segmentWidths( const ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const +{ + QList widths; + + //left segments + if ( settings.numberOfSegmentsLeft() > 0 ) + { + double leftSegmentSize = scaleContext.segmentWidth / settings.numberOfSegmentsLeft(); + for ( int i = 0; i < settings.numberOfSegmentsLeft(); ++i ) + { + widths << leftSegmentSize; + } + } + + //right segments + for ( int i = 0; i < settings.numberOfSegments(); ++i ) + { + widths << scaleContext.segmentWidth; + } + + return widths; +} diff --git a/src/core/scalebar/qgsscalebarrenderer.h b/src/core/scalebar/qgsscalebarrenderer.h new file mode 100644 index 00000000000..cbe590faf2e --- /dev/null +++ b/src/core/scalebar/qgsscalebarrenderer.h @@ -0,0 +1,113 @@ +/*************************************************************************** + qgsscalebarrenderer.h + --------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSCALEBARRENDERER_H +#define QGSSCALEBARRENDERER_H + +#include "qgis_core.h" +#include +#include + +class QgsRenderContext; +class QgsScaleBarSettings; + +/** + * \ingroup core + * \class QgsScaleBarRenderer + * Abstract base class for scale bar renderers. + * + * Scalebar renderer subclasses implement custom drawing logic, with the possibility to implement + * custom labeling. + * + * \since QGIS 3.0 +*/ +class CORE_EXPORT QgsScaleBarRenderer +{ + public: + + /** + * Contains parameters regarding scalebar calculations. + */ + struct ScaleBarContext + { + //! Width of each individual segment (in millimeters) + double segmentWidth { 0.0 }; + + /** + * Destination size for scalebar. This is used for scalebars which + * alter their appearance or alignment based on the desired scalebar + * size (e.g. correctly aligning text in a numeric scale bar). + */ + QSizeF size; + + //! Scale denominator + double scale { 1.0 }; + + }; + + QgsScaleBarRenderer() = default; + virtual ~QgsScaleBarRenderer() = default; + + /** + * Returns the unique name for this style. + */ + virtual QString name() const = 0; + + /** + * Draws the scalebar using the specified \a settings and \a scaleContext to a destination render \a context. + */ + virtual void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const = 0; + + /** + * Calculates the required box size (in millimeters) for a scalebar using the specified \a settings and \a scaleContext. + */ + virtual QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + + protected: + + /** + * Draws default scalebar labels using the specified \a settings and \a scaleContext to a destination render \a context. + */ + void drawDefaultLabels( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const; + + /** + * Returns the text used for the first label in the scalebar. + */ + QString firstLabelString( const QgsScaleBarSettings &settings ) const; + + /** + * Returns the x-offset (in millimeters) used for the first label in the scalebar. + */ + double firstLabelXOffset( const QgsScaleBarSettings &settings ) const; + + /** + * Returns a list of positions for each segment within the scalebar. + */ + QList segmentPositions( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const; + + /** + * Returns a list of widths of each segment of the scalebar. + */ + QList segmentWidths( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const; + +}; + +#endif //QGSSCALEBARRENDERER_H diff --git a/src/core/scalebar/qgsscalebarsettings.h b/src/core/scalebar/qgsscalebarsettings.h new file mode 100644 index 00000000000..227132a745c --- /dev/null +++ b/src/core/scalebar/qgsscalebarsettings.h @@ -0,0 +1,456 @@ +/*************************************************************************** + qgsscalebarsettings.h + --------------------- + begin : April 2017 + copyright : (C) 2017 by Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSCALEBARSETTINGS_H +#define QGSSCALEBARSETTINGS_H + +#include "qgis_core.h" +#include "qgis.h" +#include "qgsunittypes.h" +#include +#include +#include +#include + +/** + * \class QgsScaleBarSettings + * \ingroup core + * The QgsScaleBarSettings class stores the appearance and layout settings + * for scalebar drawing with QgsScaleBarRenderer. + * \since QGIS 3.0 +*/ +class CORE_EXPORT QgsScaleBarSettings +{ + public: + + /** + * Scalebar alignment. + */ + enum Alignment + { + AlignLeft = 0, //!< Left aligned + AlignMiddle, //!< Center aligned + AlignRight, //!< Right aligned + }; + + /** + * Modes for setting size for scale bar segments. + */ + enum SegmentSizeMode + { + SegmentSizeFixed = 0, //!< Scale bar segment size is fixed to a map unit + SegmentSizeFitWidth = 1 //!< Scale bar segment size is calculated to fit a size range + }; + + /** + * Constructor for QgsScaleBarSettings. + */ + QgsScaleBarSettings() + { + mPen = QPen( mLineColor ); + mPen.setJoinStyle( mLineJoinStyle ); + mPen.setCapStyle( mLineCapStyle ); + mPen.setWidthF( mLineWidth ); + + mBrush.setColor( mFillColor ); + mBrush.setStyle( Qt::SolidPattern ); + + mBrush2.setColor( mFillColor2 ); + mBrush2.setStyle( Qt::SolidPattern ); + + mFont.setPointSizeF( 12.0 ); + mFontColor = QColor( 0, 0, 0 ); + } + + /** + * Returns the number of segments included in the scalebar. + * \see setNumberOfSegments() + * \see numberOfSegmentsLeft() + */ + int numberOfSegments() const { return mNumSegments; } + + /** + * Sets the number of \a segments included in the scalebar. + * \see numberOfSegments() + * \see setNumberOfSegmentsLeft() + */ + void setNumberOfSegments( int segments ) { mNumSegments = segments; } + + /** + * Returns the number of segments included in the left part of the scalebar. + * \see setNumberOfSegmentsLeft() + * \see numberOfSegments() + */ + int numberOfSegmentsLeft() const { return mNumSegmentsLeft; } + + /** + * Sets the number of \a segments included in the left part of the scalebar. + * \see numberOfSegmentsLeft() + * \see setNumberOfSegments() + */ + void setNumberOfSegmentsLeft( int segments ) { mNumSegmentsLeft = segments; } + + /** + * Returns the number of scalebar units per segment. + * \see setUnitsPerSegment() + */ + double unitsPerSegment() const { return mNumUnitsPerSegment; } + + /** + * Sets the number of scalebar \a units per segment. + * \see unitsPerSegment() + */ + void setUnitsPerSegment( double units ) { mNumUnitsPerSegment = units; } + + /** + * Returns the size mode for the scale bar segments. + * \see setSegmentSizeMode() + * \see minBarWidth() + * \see maxBarWidth() + */ + SegmentSizeMode segmentSizeMode() const { return mSegmentSizeMode; } + + /** + * Sets the size \a mode for scale bar segments. + * \see segmentSizeMode() + * \see setMinimumBarWidth() + * \see setMaximumBarWidth() + */ + void setSegmentSizeMode( SegmentSizeMode mode ) { mSegmentSizeMode = mode; } + + /** + * Returns the minimum width (in millimeters) for scale bar segments. This + * property is only effective if the segmentSizeMode() is set + * to SegmentSizeFitWidth. + * \see segmentSizeMode() + * \see setMinimumBarWidth() + * \see maximumBarWidth() + */ + double minimumBarWidth() const { return mMinBarWidth; } + + /** + * Sets the minimum \a width (in millimeters) for scale bar segments. This + * property is only effective if the segmentSizeMode() is set + * to SegmentSizeFitWidth. + * \see minimumBarWidth() + * \see setMaximumBarWidth() + * \see setSegmentSizeMode() + */ + void setMinimumBarWidth( double width ) { mMinBarWidth = width; } + + /** + * Returns the maximum width (in millimeters) for scale bar segments. This + * property is only effective if the segmentSizeMode() is set + * to SegmentSizeFitWidth. + * \see segmentSizeMode() + * \see setMaximumBarWidth() + * \see minimumBarWidth() + */ + double maximumBarWidth() const { return mMaxBarWidth; } + + /** + * Sets the maximum \a width (in millimeters) for scale bar segments. This + * property is only effective if the segmentSizeMode() is set + * to SegmentSizeFitWidth. + * \see minimumBarWidth() + * \see setMinimumBarWidth() + * \see setSegmentSizeMode() + */ + void setMaximumBarWidth( double width ) { mMaxBarWidth = width; } + + /** + * Returns the distance units used by the scalebar. + * \see setUnits() + */ + QgsUnitTypes::DistanceUnit units() const { return mUnits; } + + /** + * Sets the distance \a units used by the scalebar. + * \see units() + */ + void setUnits( QgsUnitTypes::DistanceUnit units ) { mUnits = units; } + + /** + * Returns the number of map units per scale bar unit used by the scalebar. + * \see setMapUnitsPerScaleBarUnit() + */ + double mapUnitsPerScaleBarUnit() const { return mNumMapUnitsPerScaleBarUnit; } + + /** + * Sets the number of map \a units per scale bar unit used by the scalebar. + * \see mapUnitsPerScaleBarUnit() + */ + void setMapUnitsPerScaleBarUnit( double units ) { mNumMapUnitsPerScaleBarUnit = units; } + + /** + * Returns the label for units. + * \see setUnitLabel() + */ + QString unitLabel() const { return mUnitLabeling; } + + /** + * Sets the \a label for units. + * \see unitLabel() + */ + void setUnitLabel( const QString &label ) { mUnitLabeling = label; } + + /** + * Returns the font used for drawing text in the scalebar. + * \see setFont() + */ + QFont font() const { return mFont; } + + /** + * Sets the \a font used for drawing text in the scalebar. + * \see setFont() + */ + void setFont( const QFont &font ) { mFont = font; } + + /** + * Returns the color used for drawing text in the scalebar. + * \see setFontColor() + * \see font() + */ + QColor fontColor() const { return mFontColor; } + + /** + * Sets the \a color used for drawing text in the scalebar. + * \see fontColor() + * \see setFont() + */ + void setFontColor( const QColor &color ) { mFontColor = color; } + + /** + * Returns the color used for fills in the scalebar. + * \see setFillColor() + * \see fillColor2() + */ + QColor fillColor() const { return mFillColor; } + + /** + * Sets the \a color used for fills in the scalebar. + * \see fillColor() + * \see setFillColor2() + */ + void setFillColor( const QColor &color ) { mFillColor = color; mBrush.setColor( color ); } + + /** + * Returns the secondary color used for fills in the scalebar. + * \see setFillColor2() + * \see fillColor() + */ + QColor fillColor2() const {return mFillColor2;} + + /** + * Sets the secondary \a color used for fills in the scalebar. + * \see fillColor2() + * \see setFillColor2() + */ + void setFillColor2( const QColor &color ) { mFillColor2 = color; mBrush2.setColor( color ); } + + /** + * Returns the color used for lines in the scalebar. + * \see setLineColor() + */ + QColor lineColor() const { return mLineColor; } + + /** + * Sets the \a color used for lines in the scalebar. + * \see lineColor() + */ + void setLineColor( const QColor &color ) { mLineColor = color; mPen.setColor( mLineColor ); } + + /** + * Returns the line width in millimeters for lines in the scalebar. + * \see setLineWidth() + */ + double lineWidth() const { return mLineWidth; } + + /** + * Sets the line \a width in millimeters for lines in the scalebar. + * \see lineWidth() + */ + void setLineWidth( double width ) { mLineWidth = width; mPen.setWidthF( width ); } + + /** + * Returns the pen used for drawing outlines in the scalebar. + * \see setPen() + * \see brush() + */ + QPen pen() const { return mPen; } + + /** + * Sets the pen used for drawing outlines in the scalebar. + * \see pen() + */ + void setPen( const QPen &pen ) { mPen = pen; } + + /** + * Returns the primary brush used for filling the scalebar. + * \see setBrush() + * \see brush2() + * \see pen() + */ + QBrush brush() const { return mBrush; } + + /** + * Sets the primary brush used for filling the scalebar. + * \see brush() + */ + void setBrush( const QBrush &brush ) { mBrush = brush; } + + /** + * Returns the secondary brush for the scalebar. This is used for alternating color style scalebars, such + * as single and double box styles. + * \see setBrush2() + * \see brush() + */ + QBrush brush2() const { return mBrush2; } + + /** + * Sets the secondary brush used for filling the scalebar. + * \see brush() + */ + void setBrush2( const QBrush &brush ) { mBrush2 = brush; } + + /** + * Returns the scalebar height (in millimeters). + * \see setHeight() + */ + double height() const { return mHeight; } + + /** + * Sets the scalebar \a height (in millimeters). + * \see height() + */ + void setHeight( double height ) { mHeight = height; } + + /** + * Returns the spacing (in millimeters) between labels and the scalebar. + * \see setLabelBarSpace() + */ + double labelBarSpace() const { return mLabelBarSpace; } + + /** + * Sets the spacing (in millimeters) between labels and the scalebar. + * \see labelBarSpace() + */ + void setLabelBarSpace( double space ) { mLabelBarSpace = space; } + + /** + * Returns the spacing (margin) between the scalebar box and content in millimeters. + * \see setBoxContentSpace() + */ + double boxContentSpace() const { return mBoxContentSpace; } + + /** + * Sets the \a space (margin) between the scalebar box and content in millimeters. + * \see boxContentSpace() + */ + void setBoxContentSpace( double space ) { mBoxContentSpace = space; } + + /** + * Returns the scalebar alignment. + * \see setAlignment() + */ + Alignment alignment() const { return mAlignment; } + + /** + * Sets the scalebar \a alignment. + * \see alignment() + */ + void setAlignment( Alignment alignment ) { mAlignment = alignment; } + + /** + * Returns the join style used for drawing lines in the scalebar. + * \see setLineJoinStyle() + */ + Qt::PenJoinStyle lineJoinStyle() const { return mLineJoinStyle; } + + /** + * Sets the join \a style used when drawing the lines in the scalebar + * \see lineJoinStyle() + */ + void setLineJoinStyle( Qt::PenJoinStyle style ) { mLineJoinStyle = style; mPen.setJoinStyle( style ); } + + /** + * Returns the cap style used for drawing lines in the scalebar. + * \see setLineCapStyle() + */ + Qt::PenCapStyle lineCapStyle() const { return mLineCapStyle; } + + /** + * Sets the cap \a style used when drawing the lines in the scalebar. + * \see lineCapStyle() + */ + void setLineCapStyle( Qt::PenCapStyle style ) { mLineCapStyle = style; mPen.setCapStyle( style ); } + + private: + + //! Number of segments on right side + int mNumSegments = 2; + //! Number of segments on left side + int mNumSegmentsLeft = 0; + //! Size of a segment (in map units) + double mNumUnitsPerSegment = 0; + //! Number of map units per scale bar units (e.g. 1000 to have km for a map with m units) + double mNumMapUnitsPerScaleBarUnit = 1.0; + //! Either fixed (i.e. mNumUnitsPerSegment) or try to best fit scale bar width (mMinBarWidth, mMaxBarWidth) + SegmentSizeMode mSegmentSizeMode = SegmentSizeFixed; + //! Minimum allowed bar width, when mSegmentSizeMode is FitWidth + double mMinBarWidth = 50.0; + //! Maximum allowed bar width, when mSegmentSizeMode is FitWidth + double mMaxBarWidth = 150.0; + + //! Labeling of map units + QString mUnitLabeling; + //! Font + QFont mFont; + QColor mFontColor; + //! Fill color + QColor mFillColor = QColor( 0, 0, 0 ); + //! Secondary fill color + QColor mFillColor2 = QColor( 255, 255, 255 ); + //! Line color + QColor mLineColor = QColor( 0, 0, 0 ); + //! Line width + double mLineWidth = 0.3; + //! Stroke + QPen mPen; + //! Fill + QBrush mBrush; + //! Secondary fill + QBrush mBrush2; + //! Height of bars/lines + double mHeight = 3.0; + + //! Space between bar and Text labels + double mLabelBarSpace = 3.0; + + //! Space between content and item box + double mBoxContentSpace = 1.0; + + Alignment mAlignment = AlignLeft; + + QgsUnitTypes::DistanceUnit mUnits = QgsUnitTypes::DistanceMeters; + + Qt::PenJoinStyle mLineJoinStyle = Qt::MiterJoin; + Qt::PenCapStyle mLineCapStyle = Qt::SquareCap; + +}; + +#endif // QGSSCALEBARSETTINGS_H + diff --git a/src/core/scalebar/qgssingleboxscalebarrenderer.cpp b/src/core/scalebar/qgssingleboxscalebarrenderer.cpp new file mode 100644 index 00000000000..cde08dda5f4 --- /dev/null +++ b/src/core/scalebar/qgssingleboxscalebarrenderer.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + qgssingleboxscalebarrenderer.cpp + -------------------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgssingleboxscalebarrenderer.h" +#include "qgsscalebarsettings.h" +#include "qgscomposerutils.h" +#include +#include + +void QgsSingleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const +{ + if ( !context.painter() ) + { + return; + } + QPainter *painter = context.painter(); + + double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(); + + painter->save(); + if ( context.flags() & QgsRenderContext::Antialiasing ) + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setPen( settings.pen() ); + + bool useColor = true; //alternate brush color/white + double xOffset = firstLabelXOffset( settings ); + + QList positions = segmentPositions( scaleContext, settings ); + QList widths = segmentWidths( scaleContext, settings ); + + for ( int i = 0; i < positions.size(); ++i ) + { + if ( useColor ) //alternating colors + { + painter->setBrush( settings.brush() ); + } + else //secondary color + { + painter->setBrush( settings.brush2() ); + } + + QRectF segmentRect( positions.at( i ) + xOffset, barTopPosition, widths.at( i ), settings.height() ); + painter->drawRect( segmentRect ); + useColor = !useColor; + } + + painter->restore(); + + //draw labels using the default method + drawDefaultLabels( context, settings, scaleContext ); +} + + + diff --git a/src/core/composer/qgssingleboxscalebarstyle.h b/src/core/scalebar/qgssingleboxscalebarrenderer.h similarity index 58% rename from src/core/composer/qgssingleboxscalebarstyle.h rename to src/core/scalebar/qgssingleboxscalebarrenderer.h index 0ba2104e1cc..a58ae418e3c 100644 --- a/src/core/composer/qgssingleboxscalebarstyle.h +++ b/src/core/scalebar/qgssingleboxscalebarrenderer.h @@ -1,6 +1,6 @@ /*************************************************************************** - qgssingleboxscalebarstyle.h - ------------------ + qgssingleboxscalebarrenderer.h + ------------------------------ begin : June 2008 copyright : (C) 2008 by Marco Hugentobler email : marco.hugentobler@karto.baug.ethz.ch @@ -14,32 +14,32 @@ * * ***************************************************************************/ -#ifndef QGSSINGLEBOXSCALEBARSTYLE_H -#define QGSSINGLEBOXSCALEBARSTYLE_H +#ifndef QGSSINGLEBOXSCALEBARRENDERER_H +#define QGSSINGLEBOXSCALEBARRENDERER_H #include "qgis_core.h" -#include "qgsscalebarstyle.h" +#include "qgsscalebarrenderer.h" +#include -/** \ingroup core +/** + * \class QgsSingleBoxScaleBarRenderer + * \ingroup core * Scalebar style that draws a single box with alternating * color for the segments. + * \since QGIS 3.0 */ -class CORE_EXPORT QgsSingleBoxScaleBarStyle: public QgsScaleBarStyle +class CORE_EXPORT QgsSingleBoxScaleBarRenderer: public QgsScaleBarRenderer { public: - QgsSingleBoxScaleBarStyle( const QgsComposerScaleBar *bar ); - ~QgsSingleBoxScaleBarStyle(); - QString name() const override; + QgsSingleBoxScaleBarRenderer() = default; - /** Draw method - \param p painter object - \param xOffset x offset - */ - void draw( QPainter *p, double xOffset = 0 ) const override; + QString name() const override { return QStringLiteral( "Single Box" ); } + + void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const override; - private: - QgsSingleBoxScaleBarStyle(); //forbidden }; -#endif +#endif // QGSSINGLEBOXSCALEBARRENDERER_H diff --git a/src/core/scalebar/qgsticksscalebarrenderer.cpp b/src/core/scalebar/qgsticksscalebarrenderer.cpp new file mode 100644 index 00000000000..5ce8972cf6d --- /dev/null +++ b/src/core/scalebar/qgsticksscalebarrenderer.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + qgsticksscalebarrenderer.cpp + ---------------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsticksscalebarrenderer.h" +#include "qgsscalebarsettings.h" +#include "qgscomposerutils.h" +#include + +QString QgsTicksScaleBarRenderer::name() const +{ + switch ( mTickPosition ) + { + case TicksUp: + return QStringLiteral( "Line Ticks Up" ); + case TicksDown: + return QStringLiteral( "Line Ticks Down" ); + case TicksMiddle: + return QStringLiteral( "Line Ticks Middle" ); + } + return QString(); // to make gcc happy +} + +void QgsTicksScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const +{ + if ( !context.painter() ) + return; + + QPainter *painter = context.painter(); + + double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(); + double middlePosition = barTopPosition + settings.height() / 2.0; + double bottomPosition = barTopPosition + settings.height(); + + double xOffset = firstLabelXOffset( settings ); + + painter->save(); + if ( context.flags() & QgsRenderContext::Antialiasing ) + painter->setRenderHint( QPainter::Antialiasing, true ); + + painter->setPen( settings.pen() ); + + QList positions = segmentPositions( scaleContext, settings ); + + for ( int i = 0; i < positions.size(); ++i ) + { + painter->drawLine( QLineF( positions.at( i ) + xOffset, barTopPosition, + positions.at( i ) + xOffset, barTopPosition + settings.height() ) ); + } + + //draw last tick and horizontal line + if ( !positions.isEmpty() ) + { + double lastTickPositionX = positions.at( positions.size() - 1 ) + scaleContext.segmentWidth + xOffset; + double verticalPos = 0.0; + switch ( mTickPosition ) + { + case TicksDown: + verticalPos = barTopPosition; + break; + case TicksMiddle: + verticalPos = middlePosition; + break; + case TicksUp: + verticalPos = bottomPosition; + break; + } + //horizontal line + painter->drawLine( QLineF( xOffset + positions.at( 0 ), verticalPos, lastTickPositionX, verticalPos ) ); + //last vertical line + painter->drawLine( QLineF( lastTickPositionX, barTopPosition, lastTickPositionX, barTopPosition + settings.height() ) ); + } + + painter->restore(); + + //draw labels using the default method + drawDefaultLabels( context, settings, scaleContext ); +} + + diff --git a/src/core/scalebar/qgsticksscalebarrenderer.h b/src/core/scalebar/qgsticksscalebarrenderer.h new file mode 100644 index 00000000000..25e1e874619 --- /dev/null +++ b/src/core/scalebar/qgsticksscalebarrenderer.h @@ -0,0 +1,66 @@ +/*************************************************************************** + qgsticksscalebarrenderer.h + -------------------------- + begin : June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco.hugentobler@karto.baug.ethz.ch + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSTICKSSCALEBARRENDERER_H +#define QGSTICKSSCALEBARRENDERER_H + +#include "qgis_core.h" +#include "qgsscalebarrenderer.h" + +/** + * \class QgsTicksScaleBarRenderer + * \ingroup core + * A scale bar that draws segments using short ticks. + * \since QGIS 3.0 + */ +class CORE_EXPORT QgsTicksScaleBarRenderer: public QgsScaleBarRenderer +{ + public: + + //! Tick positions + enum TickPosition + { + TicksUp, //!< Render ticks above line + TicksDown, //!< Render ticks below line + TicksMiddle, //!< Render ticks crossing line + }; + + QgsTicksScaleBarRenderer() = default; + + QString name() const override; + + void draw( QgsRenderContext &context, + const QgsScaleBarSettings &settings, + const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const override; + + /** + * Sets the \a position for tick marks in the scalebar. + * \see tickPosition() + */ + void setTickPosition( TickPosition position ) { mTickPosition = position; } + + /** + * Returns the position for tick marks in the scalebar. + * \see setTickPosition() + */ + TickPosition tickPosition() const { return mTickPosition; } + + private: + + TickPosition mTickPosition = TicksMiddle; +}; + +#endif // QGSTICKSSCALEBARRENDERER_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e70b35f3fca..e1eac3aee59 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -749,6 +749,7 @@ INCLUDE_DIRECTORIES( ../core/geometry ../core/layertree ../core/raster + ../core/scalebar ../core/symbology-ng ../core/effects ${CMAKE_CURRENT_BINARY_DIR} diff --git a/src/gui/qgscomposerview.cpp b/src/gui/qgscomposerview.cpp index b19d5172005..8f0db178539 100644 --- a/src/gui/qgscomposerview.cpp +++ b/src/gui/qgscomposerview.cpp @@ -444,7 +444,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent *e ) QList mapItemList = composition()->composerMapItems(); if ( !mapItemList.isEmpty() ) { - newScaleBar->setComposerMap( mapItemList.at( 0 ) ); + newScaleBar->setComposerMap( const_cast< QgsComposerMap *>( mapItemList.at( 0 ) ) ); } newScaleBar->applyDefaultSize(); //4 segments, 1/5 of composer map width diff --git a/tests/src/core/CMakeLists.txt b/tests/src/core/CMakeLists.txt old mode 100644 new mode 100755 index b70b95d5b5b..42a5e2a2a91 --- a/tests/src/core/CMakeLists.txt +++ b/tests/src/core/CMakeLists.txt @@ -16,6 +16,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/layertree ${CMAKE_SOURCE_DIR}/src/core/processing ${CMAKE_SOURCE_DIR}/src/core/raster + ${CMAKE_SOURCE_DIR}/src/core/scalebar ${CMAKE_SOURCE_DIR}/src/core/symbology-ng ${CMAKE_SOURCE_DIR}/src/test ${CMAKE_BINARY_DIR}/src/core diff --git a/tests/src/core/testqgscomposerscalebar.cpp b/tests/src/core/testqgscomposerscalebar.cpp index d66ebaeb85a..43f3f6598bf 100644 --- a/tests/src/core/testqgscomposerscalebar.cpp +++ b/tests/src/core/testqgscomposerscalebar.cpp @@ -102,7 +102,7 @@ void TestQgsComposerScaleBar::initTestCase() mComposition->addComposerScaleBar( mComposerScaleBar ); mComposerScaleBar->setComposerMap( mComposerMap ); mComposerScaleBar->setFont( QgsFontUtils::getStandardTestFont() ); - mComposerScaleBar->setUnits( QgsComposerScaleBar::Meters ); + mComposerScaleBar->setUnits( QgsUnitTypes::DistanceMeters ); mComposerScaleBar->setNumUnitsPerSegment( 2000 ); mComposerScaleBar->setNumSegmentsLeft( 0 ); mComposerScaleBar->setNumSegments( 2 ); From fa21311e4cc0bd02d745bd74dff088e059e2e985 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 23 Apr 2017 08:02:41 +1000 Subject: [PATCH 2/4] More robust test for numeric scale bar --- tests/src/core/testqgscomposerscalebar.cpp | 10 +++++++++- .../expected_composerscalebar_numeric.png | Bin 120059 -> 119767 bytes ...expected_composerscalebar_numeric_mask.png | Bin 16541 -> 0 bytes 3 files changed, 9 insertions(+), 1 deletion(-) delete mode 100644 tests/testdata/control_images/composer_scalebar/expected_composerscalebar_numeric/expected_composerscalebar_numeric_mask.png diff --git a/tests/src/core/testqgscomposerscalebar.cpp b/tests/src/core/testqgscomposerscalebar.cpp index 43f3f6598bf..fec6ed3ae7b 100644 --- a/tests/src/core/testqgscomposerscalebar.cpp +++ b/tests/src/core/testqgscomposerscalebar.cpp @@ -179,11 +179,19 @@ void TestQgsComposerScaleBar::doubleBox() void TestQgsComposerScaleBar::numeric() { + QFont f = mComposerScaleBar->font(); + + QFont newFont = QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ); + newFont.setPointSizeF( 12 ); + mComposerScaleBar->setFont( newFont ); + mComposerScaleBar->setStyle( QStringLiteral( "Numeric" ) ); mComposerScaleBar->setSceneRect( QRectF( 20, 180, 50, 20 ) ); QgsCompositionChecker checker( QStringLiteral( "composerscalebar_numeric" ), mComposition ); checker.setControlPathPrefix( QStringLiteral( "composer_scalebar" ) ); - QVERIFY( checker.testComposition( mReport, 0, 0 ) ); + bool result = checker.testComposition( mReport, 0, 0 ); + mComposerScaleBar->setFont( f ); + QVERIFY( result ); } void TestQgsComposerScaleBar::tick() diff --git a/tests/testdata/control_images/composer_scalebar/expected_composerscalebar_numeric/expected_composerscalebar_numeric.png b/tests/testdata/control_images/composer_scalebar/expected_composerscalebar_numeric/expected_composerscalebar_numeric.png index 5d83747c7be2e98394b0f582650d037551014e70..b79fcd021db0e44cdb096598cd530baafc5de89e 100644 GIT binary patch delta 111691 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 delta 112093 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 diff --git a/tests/testdata/control_images/composer_scalebar/expected_composerscalebar_numeric/expected_composerscalebar_numeric_mask.png b/tests/testdata/control_images/composer_scalebar/expected_composerscalebar_numeric/expected_composerscalebar_numeric_mask.png deleted file mode 100644 index 7ce508f75f76ef2d3640c253b630b5c245f65a17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16541 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 @Yd6t`de7G&gBG2XXk{0KWS)zrW!!;16rY0s~ z@FP*8zSHr2imq-L;L(X6pJ(s>I%sTs^Y`!H61u;B^dEcTIX&7vG2FgGNJ!`#TvJVL zt*NPLc(|0IXUv(2fd)lIMav18eM4P(eZmS$&cpXf3X7D^{rD88=DjsUW5H|fx^>%Z zN*RA;4tJJZ!dUjYkgC#|zBjrMmhoOaL29F=J4b$Cg$e1Oz$6Xn4KE_){v~7S+ek3|F)vc^5x5AWMsY- zogJVzH8t6{J#*B3-#hkT_f-xDn1uS)QS5UdUM(gyHPy__EG0KLw>D1w;_np01a*O8 z9C^>fxD=u+9$OcWeY6X?b8dBw)w$2NB)+viJz?$D{f`=?h3@+qiMzh@zkB`Hxm2YZ z#Aeegg5y*?HhOq?L_G`n{{8!P!JS)mTeex9pBjpR_jyoJ4m82Pv3K`rl)RL?n z!o5yOR$QC;CUW!9Esh%Sv9253L!xU3^84dq4fpR05xzqa-**p7p`;jl0_ zv(tCZD=ekBco)>>8jx|rW=Bd&&dfKZnT}7jpFRP}o0ggR;wvlMQYESvEq@rywSV^d zawA5;ZXeu_dspdYwTX9{t$C-9y}rIC{KJP2f~uafx?4}Yjf;qk?E7%^^l;I``!8Oo zYcmDE&B@5g)x*h6;fg@A#)+?+4JG6HdJXlfOL-6I>guNI$Aqbl6m6>vSzn)jrhn}B z;A5$oN%#9P+fMYs*G8%!#-gnXJvZpSzOgRK=SRL2EUlxHQ;i?jN_WV<>ua`2!lv)n z*4BQpxG>ATR#6(DaDAp#;rphhh}j>7a`66{nf`?F*XvH7?MVCusex|=pA91EKGYJZ zf7RIzweR1*4}-GJKX(kafU&q}dHZY-RNAdRQ$ufOGbE}*MK!}DAYAKeZfzQGG}N#f z>wjpOzg1&yRP%Vo1cJmdc*eua2CFuY|nMB zg^IZK?7%xkC8fT1Nt!X+PaZ7r7>o>2|2+`4XpO^lh1IREpL#pWORQjFp*C!pw)XMy z>9>$55o-DHArb;yBko+?_Lda*89x=hIJ*-%O8$?6!S@{<@o)p@y!SNx_*{tdxoEoQ znnm$>j{|p9Zb`^&-fZCL_-%>C$n?)IR`Ji9?i(gR0g{K3jN<@O+vjD@#n~x?#fACC zwzk`v0X*LH6>vp!Tqnxs$Zz9zHhRxAXt-IPJUO^NQ{(J_5s#3{M8HW{+8FXuo|L4d zq;0PxW@@L$eGCi?V0VAleqjo!PUS5~!bwWkfd7rqKR=r!;DK?4lX$v>LdQp!iNT}{ z%nR-%5TkS;9~qt*@rmNExF(A1!Ihe}+mHCB>;L}Y|1J)M1Nv`A&imq{dBGwo@D&au xh5x?*B`tJFf!RFfwtBVkH~;lNBd^961Xeq Date: Sun, 23 Apr 2017 08:06:03 +1000 Subject: [PATCH 3/4] Add missing docs --- .../scalebar/qgsdoubleboxscalebarrenderer.sip | 4 ++++ .../scalebar/qgsnumericscalebarrenderer.sip | 4 ++++ python/core/scalebar/qgsscalebarrenderer.sip | 3 +++ .../scalebar/qgssingleboxscalebarrenderer.sip | 3 +++ .../scalebar/qgsticksscalebarrenderer.sip | 3 +++ src/core/composer/qgscomposerscalebar.h | 22 +++++++++++++++++-- .../scalebar/qgsdoubleboxscalebarrenderer.h | 4 ++++ .../scalebar/qgsnumericscalebarrenderer.h | 4 ++++ src/core/scalebar/qgsscalebarrenderer.h | 3 +++ .../scalebar/qgssingleboxscalebarrenderer.h | 3 +++ src/core/scalebar/qgsticksscalebarrenderer.h | 3 +++ 11 files changed, 54 insertions(+), 2 deletions(-) diff --git a/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip index 88fee9494b9..665583872d5 100644 --- a/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip +++ b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip @@ -19,7 +19,11 @@ class QgsDoubleBoxScaleBarRenderer: QgsScaleBarRenderer #include "qgsdoubleboxscalebarrenderer.h" %End public: + QgsDoubleBoxScaleBarRenderer(); +%Docstring + Constructor for QgsDoubleBoxScaleBarRenderer. +%End virtual QString name() const; diff --git a/python/core/scalebar/qgsnumericscalebarrenderer.sip b/python/core/scalebar/qgsnumericscalebarrenderer.sip index e8b12daf1de..31e79f80808 100644 --- a/python/core/scalebar/qgsnumericscalebarrenderer.sip +++ b/python/core/scalebar/qgsnumericscalebarrenderer.sip @@ -19,7 +19,11 @@ class QgsNumericScaleBarRenderer: QgsScaleBarRenderer #include "qgsnumericscalebarrenderer.h" %End public: + QgsNumericScaleBarRenderer(); +%Docstring + Constructor for QgsNumericScaleBarRenderer. +%End virtual QString name() const; diff --git a/python/core/scalebar/qgsscalebarrenderer.sip b/python/core/scalebar/qgsscalebarrenderer.sip index 2bbc6c7da24..65cafa0820a 100644 --- a/python/core/scalebar/qgsscalebarrenderer.sip +++ b/python/core/scalebar/qgsscalebarrenderer.sip @@ -47,6 +47,9 @@ Scale denominator }; QgsScaleBarRenderer(); +%Docstring + Constructor for QgsScaleBarRenderer. +%End virtual ~QgsScaleBarRenderer(); virtual QString name() const = 0; diff --git a/python/core/scalebar/qgssingleboxscalebarrenderer.sip b/python/core/scalebar/qgssingleboxscalebarrenderer.sip index e9855a9b110..268c6027727 100644 --- a/python/core/scalebar/qgssingleboxscalebarrenderer.sip +++ b/python/core/scalebar/qgssingleboxscalebarrenderer.sip @@ -22,6 +22,9 @@ class QgsSingleBoxScaleBarRenderer: QgsScaleBarRenderer public: QgsSingleBoxScaleBarRenderer(); +%Docstring + Constructor for QgsSingleBoxScaleBarRenderer. +%End virtual QString name() const; diff --git a/python/core/scalebar/qgsticksscalebarrenderer.sip b/python/core/scalebar/qgsticksscalebarrenderer.sip index 18768445cef..d0af4c8ca98 100644 --- a/python/core/scalebar/qgsticksscalebarrenderer.sip +++ b/python/core/scalebar/qgsticksscalebarrenderer.sip @@ -28,6 +28,9 @@ class QgsTicksScaleBarRenderer: QgsScaleBarRenderer }; QgsTicksScaleBarRenderer(); +%Docstring + Constructor for QgsTicksScaleBarRenderer. +%End virtual QString name() const; diff --git a/src/core/composer/qgscomposerscalebar.h b/src/core/composer/qgscomposerscalebar.h index 182bc11218d..2b595a8c435 100644 --- a/src/core/composer/qgscomposerscalebar.h +++ b/src/core/composer/qgscomposerscalebar.h @@ -215,7 +215,14 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem double height() const { return mSettings.height(); } void setHeight( double h ) { mSettings.setHeight( h );} + /** + * Sets the \a map item linked to the scalebar. + */ void setComposerMap( QgsComposerMap *map ); + + /** + * Returns the map item linked to the scalebar. + */ QgsComposerMap *composerMap() const {return mComposerMap;} double labelBarSpace() const {return mSettings.labelBarSpace();} @@ -224,13 +231,24 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem double boxContentSpace() const {return mSettings.boxContentSpace();} void setBoxContentSpace( double space ); - //! Left / Middle/ Right + /** + * Returns the alignment of the scalebar. + */ QgsScaleBarSettings::Alignment alignment() const { return mSettings.alignment(); } - void setAlignment( QgsScaleBarSettings::Alignment a ); + /** + * Sets the \a alignment of the scalebar. + */ + void setAlignment( QgsScaleBarSettings::Alignment alignment ); + /** + * Returns the scalebar distance units. + */ QgsUnitTypes::DistanceUnit units() const { return mSettings.units(); } + /** + * Sets the scalebar distance units. + */ void setUnits( QgsUnitTypes::DistanceUnit u ); /** Returns the join style used for drawing lines in the scalebar diff --git a/src/core/scalebar/qgsdoubleboxscalebarrenderer.h b/src/core/scalebar/qgsdoubleboxscalebarrenderer.h index 8443ec0a0cf..1971823758a 100644 --- a/src/core/scalebar/qgsdoubleboxscalebarrenderer.h +++ b/src/core/scalebar/qgsdoubleboxscalebarrenderer.h @@ -30,6 +30,10 @@ class CORE_EXPORT QgsDoubleBoxScaleBarRenderer: public QgsScaleBarRenderer { public: + + /** + * Constructor for QgsDoubleBoxScaleBarRenderer. + */ QgsDoubleBoxScaleBarRenderer() = default; QString name() const override { return QStringLiteral( "Double Box" ); } diff --git a/src/core/scalebar/qgsnumericscalebarrenderer.h b/src/core/scalebar/qgsnumericscalebarrenderer.h index 68284f226aa..b18925e4446 100644 --- a/src/core/scalebar/qgsnumericscalebarrenderer.h +++ b/src/core/scalebar/qgsnumericscalebarrenderer.h @@ -30,6 +30,10 @@ class CORE_EXPORT QgsNumericScaleBarRenderer: public QgsScaleBarRenderer { public: + + /** + * Constructor for QgsNumericScaleBarRenderer. + */ QgsNumericScaleBarRenderer() = default; QString name() const override { return QStringLiteral( "Numeric" ); } diff --git a/src/core/scalebar/qgsscalebarrenderer.h b/src/core/scalebar/qgsscalebarrenderer.h index cbe590faf2e..94c752fd458 100644 --- a/src/core/scalebar/qgsscalebarrenderer.h +++ b/src/core/scalebar/qgsscalebarrenderer.h @@ -58,6 +58,9 @@ class CORE_EXPORT QgsScaleBarRenderer }; + /** + * Constructor for QgsScaleBarRenderer. + */ QgsScaleBarRenderer() = default; virtual ~QgsScaleBarRenderer() = default; diff --git a/src/core/scalebar/qgssingleboxscalebarrenderer.h b/src/core/scalebar/qgssingleboxscalebarrenderer.h index a58ae418e3c..72481b2de05 100644 --- a/src/core/scalebar/qgssingleboxscalebarrenderer.h +++ b/src/core/scalebar/qgssingleboxscalebarrenderer.h @@ -32,6 +32,9 @@ class CORE_EXPORT QgsSingleBoxScaleBarRenderer: public QgsScaleBarRenderer { public: + /** + * Constructor for QgsSingleBoxScaleBarRenderer. + */ QgsSingleBoxScaleBarRenderer() = default; QString name() const override { return QStringLiteral( "Single Box" ); } diff --git a/src/core/scalebar/qgsticksscalebarrenderer.h b/src/core/scalebar/qgsticksscalebarrenderer.h index 25e1e874619..9af953bc8cc 100644 --- a/src/core/scalebar/qgsticksscalebarrenderer.h +++ b/src/core/scalebar/qgsticksscalebarrenderer.h @@ -38,6 +38,9 @@ class CORE_EXPORT QgsTicksScaleBarRenderer: public QgsScaleBarRenderer TicksMiddle, //!< Render ticks crossing line }; + /** + * Constructor for QgsTicksScaleBarRenderer. + */ QgsTicksScaleBarRenderer() = default; QString name() const override; From 9e4f9d4ac63137b163f012148ca7eb78ece287fa Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 26 Apr 2017 11:47:06 +1000 Subject: [PATCH 4/4] Sipify update --- python/core/scalebar/qgsdoubleboxscalebarrenderer.sip | 1 - python/core/scalebar/qgsnumericscalebarrenderer.sip | 1 - python/core/scalebar/qgsscalebarrenderer.sip | 1 - python/core/scalebar/qgsscalebarsettings.sip | 2 -- python/core/scalebar/qgssingleboxscalebarrenderer.sip | 1 - python/core/scalebar/qgsticksscalebarrenderer.sip | 1 - 6 files changed, 7 deletions(-) diff --git a/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip index 665583872d5..0857b5c52c3 100644 --- a/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip +++ b/python/core/scalebar/qgsdoubleboxscalebarrenderer.sip @@ -40,4 +40,3 @@ class QgsDoubleBoxScaleBarRenderer: QgsScaleBarRenderer * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ - diff --git a/python/core/scalebar/qgsnumericscalebarrenderer.sip b/python/core/scalebar/qgsnumericscalebarrenderer.sip index 31e79f80808..265145a7ab4 100644 --- a/python/core/scalebar/qgsnumericscalebarrenderer.sip +++ b/python/core/scalebar/qgsnumericscalebarrenderer.sip @@ -43,4 +43,3 @@ class QgsNumericScaleBarRenderer: QgsScaleBarRenderer * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ - diff --git a/python/core/scalebar/qgsscalebarrenderer.sip b/python/core/scalebar/qgsscalebarrenderer.sip index 65cafa0820a..573518bafc1 100644 --- a/python/core/scalebar/qgsscalebarrenderer.sip +++ b/python/core/scalebar/qgsscalebarrenderer.sip @@ -114,4 +114,3 @@ Scale denominator * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ - diff --git a/python/core/scalebar/qgsscalebarsettings.sip b/python/core/scalebar/qgsscalebarsettings.sip index 48023b5f493..3647f86d21f 100644 --- a/python/core/scalebar/qgsscalebarsettings.sip +++ b/python/core/scalebar/qgsscalebarsettings.sip @@ -8,7 +8,6 @@ - class QgsScaleBarSettings { %Docstring @@ -396,4 +395,3 @@ class QgsScaleBarSettings * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ - diff --git a/python/core/scalebar/qgssingleboxscalebarrenderer.sip b/python/core/scalebar/qgssingleboxscalebarrenderer.sip index 268c6027727..cad258744bd 100644 --- a/python/core/scalebar/qgssingleboxscalebarrenderer.sip +++ b/python/core/scalebar/qgssingleboxscalebarrenderer.sip @@ -41,4 +41,3 @@ class QgsSingleBoxScaleBarRenderer: QgsScaleBarRenderer * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ - diff --git a/python/core/scalebar/qgsticksscalebarrenderer.sip b/python/core/scalebar/qgsticksscalebarrenderer.sip index d0af4c8ca98..b375206bebe 100644 --- a/python/core/scalebar/qgsticksscalebarrenderer.sip +++ b/python/core/scalebar/qgsticksscalebarrenderer.sip @@ -61,4 +61,3 @@ class QgsTicksScaleBarRenderer: QgsScaleBarRenderer * * * Do not edit manually ! Edit header and run scripts/sipify.pl again * ************************************************************************/ -