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 );