Refactor scale bar rendering

Move all scalebar rendering code out of composer and ensure that
all scalebar rendering is done independant of QgsComposerScaleBar

This allows scalebar rendering code to be reused by plugins
and by non-composer code.

Also rename QgsScaleBarStyle -> QgsScaleBarRenderer, (and all
subclasses too). This name better reflects what these classes do.
This commit is contained in:
Nyall Dawson 2017-04-21 15:47:25 +10:00
parent 13b44722ca
commit b40bc0c1f7
43 changed files with 2189 additions and 1226 deletions

1
doc/CMakeLists.txt Normal file → Executable file
View File

@ -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

View File

@ -85,6 +85,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes}
<tr><td>QgsCurveV2<td>QgsCurve
<tr><td>QgsDbFilterProxyModel<td>QgsDatabaseFilterProxyModel
<tr><td>QgsDiagramRendererV2<td>QgsDiagramRenderer
<tr><td>QgsDoubleBoxBarStyle<td>QgsDoubleBoxScaleBarRenderer
<tr><td>QgsEditorWidgetV2<td>QgsEditorWidget
<tr><td>QgsEllipseSymbolLayerV2<td>QgsEllipseSymbolLayer
<tr><td>QgsEllipseSymbolLayerV2Widget<td>QgsEllipseSymbolLayerWidget
@ -115,6 +116,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes}
<tr><td>QgsMultiCurveV2<td>QgsMultiCurve
<tr><td>QgsMultiLineStringV2<td>QgsMultiLineString
<tr><td>QgsMultiSurfaceV2<td>QgsMultiSurface
<tr><td>QgsNumericScaleBarStyle<td>QgsNumericScaleBarRenderer
<tr><td>QgsPointSequenceV2<td>QgsPointSequence
<tr><td>QgsProperty<td>QgsProjectProperty
<tr><td>QgsPropertyKey<td>QgsProjectPropertyKey
@ -140,6 +142,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes}
<tr><td>QgsRuleBasedRendererV2Count<td>QgsRuleBasedRendererCount
<tr><td>QgsRuleBasedRendererV2Model<td>QgsRuleBasedRendererModel
<tr><td>QgsRuleBasedRendererV2Widget<td>QgsRuleBasedRendererWidget
<tr><td>QgsScaleBarStyle<td>QgsScaleBarRenderer
<tr><td>QgsShapeburstFillSymbolLayerV2<td>QgsShapeburstFillSymbolLayer
<tr><td>QgsShapeburstFillSymbolLayerV2Widget<td>QgsShapeburstFillSymbolLayerWidget
<tr><td>QgsSimpleFillSymbolLayerV2<td>QgsSimpleFillSymbolLayer
@ -148,6 +151,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes}
<tr><td>QgsSimpleLineSymbolLayerV2Widget<td>QgsSimpleLineSymbolLayerWidget
<tr><td>QgsSimpleMarkerSymbolLayerV2<td>QgsSimpleMarkerSymbolLayer
<tr><td>QgsSimpleMarkerSymbolLayerV2Widget<td>QgsSimpleMarkerSymbolLayerWidget
<tr><td>QgsSingleBoxScaleBarStyle<td>QgsSingleBoxScaleBarRenderer
<tr><td>QgsSingleSymbolRendererV2<td>QgsSingleSymbolRenderer
<tr><td>QgsSingleSymbolRendererV2Widget<td>QgsSingleSymbolRendererWidget
<tr><td>QgsStyleV2<td>QgsStyle
@ -171,6 +175,7 @@ Renamed Classes {#qgis_api_break_3_0_renamed_classes}
<tr><td>QgsSymbolV2RenderContext<td>QgsSymbolRenderContext
<tr><td>QgsSymbolV2SelectorDialog<td>QgsSymbolSelectorDialog
<tr><td>QgsSymbolV2SelectorWidget<td>QgsSymbolSelectorWidget
<tr><td>QgsTicksScaleBarStyle<td>QgsTicksScaleBarRenderer
<tr><td>QgsVectorColorBrewerColorRampV2<td>QgsColorBrewerColorRamp
<tr><td>QgsVectorColorBrewerColorRampV2Dialog<td>QgsColorBrewerColorRampDialog
<tr><td>QgsVectorColorBrewerColorRampV2DialogBase<td>QgsColorBrewerColorRampDialogBase
@ -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}
----------

1
python/CMakeLists.txt Normal file → Executable file
View File

@ -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

View File

@ -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<QPair<double, double> >& 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;
};

View File

@ -1,13 +0,0 @@
class QgsDoubleBoxScaleBarStyle: QgsScaleBarStyle
{
%TypeHeaderCode
#include <qgsdoubleboxscalebarstyle.h>
%End
public:
QgsDoubleBoxScaleBarStyle( const QgsComposerScaleBar* bar );
~QgsDoubleBoxScaleBarStyle();
QString name() const;
void draw( QPainter* p, double xOffset = 0 ) const;
};

View File

@ -1,16 +0,0 @@
class QgsNumericScaleBarStyle : QgsScaleBarStyle
{
%TypeHeaderCode
#include <qgsnumericscalebarstyle.h>
%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;
};

View File

@ -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
};

View File

@ -1,17 +0,0 @@
class QgsSingleBoxScaleBarStyle : QgsScaleBarStyle
{
%TypeHeaderCode
#include <qgssingleboxscalebarstyle.h>
%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;
};

View File

@ -1,26 +0,0 @@
class QgsTicksScaleBarStyle: QgsScaleBarStyle
{
%TypeHeaderCode
#include <qgsticksscalebarstyle.h>
%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 );
};

View File

@ -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

View File

@ -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 *
************************************************************************/

View File

@ -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 *
************************************************************************/

View File

@ -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<double> 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<double> 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 *
************************************************************************/

View File

@ -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 *
************************************************************************/

View File

@ -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 *
************************************************************************/

View File

@ -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 *
************************************************************************/

View File

@ -560,6 +560,7 @@ INCLUDE_DIRECTORIES(
../core/geometry
../core/layertree
../core/raster
../core/scalebar
../core/symbology-ng
../gui
../gui/symbology-ng

View File

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

View File

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

View File

@ -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<QPair<double, double> > &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<SegmentSizeMode>( 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<QgsScaleBarSettings::SegmentSizeMode>( 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 );
}

View File

@ -18,12 +18,13 @@
#include "qgis_core.h"
#include "qgscomposeritem.h"
#include "scalebar/qgsscalebarsettings.h"
#include "scalebar/qgsscalebarrenderer.h"
#include <QFont>
#include <QPen>
#include <QColor>
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<QPair<double, double> > &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

View File

@ -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 <QList>
#include <QPainter>
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<QPair<double, double> > segmentInfo;
mScaleBar->segmentPositions( segmentInfo );
bool useColor = true; //alternate brush color/white
QList<QPair<double, double> >::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 );
}

View File

@ -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 <QList>
#include <QPainter>
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<QgsComposerScaleBar *>( 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;
}

View File

@ -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 <QFontMetricsF>
#include <QPainter>
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<QPair<double, double> > segmentInfo;
mScaleBar->segmentPositions( segmentInfo );
double currentLabelNumber = 0.0;
int nSegmentsLeft = mScaleBar->numSegmentsLeft();
int segmentCounter = 0;
QString currentNumericLabel;
QList<QPair<double, double> >::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<double, double> > segmentList;
mScaleBar->segmentPositions( segmentList );
QList< QPair<double, double> >::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 );
}

View File

@ -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 <QIcon>
#include <QRectF>
#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

View File

@ -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 <QList>
#include <QPainter>
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<QPair<double, double> > segmentInfo;
mScaleBar->segmentPositions( segmentInfo );
bool useColor = true; //alternate brush color/white
QList<QPair<double, double> >::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" );
}

View File

@ -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 <QPainter>
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<QPair<double, double> > segmentInfo;
mScaleBar->segmentPositions( segmentInfo );
QList<QPair<double, double> >::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 );
}

View File

@ -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

View File

@ -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 <QList>
#include <QPainter>
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<double> positions = segmentPositions( scaleContext, settings );
QList<double> 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 );
}

View File

@ -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 <QString>
/** \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

View File

@ -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 <QList>
#include <QPainter>
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 );
}

View File

@ -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 <QString>
/** \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

View File

@ -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 <QFontMetricsF>
#include <QPainter>
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<double> 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<double> QgsScaleBarRenderer::segmentPositions( const ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const
{
QList<double> 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<double> QgsScaleBarRenderer::segmentWidths( const ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const
{
QList<double> 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;
}

View File

@ -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 <QRectF>
#include <QList>
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<double> segmentPositions( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const;
/**
* Returns a list of widths of each segment of the scalebar.
*/
QList<double> segmentWidths( const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings ) const;
};
#endif //QGSSCALEBARRENDERER_H

View File

@ -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 <QColor>
#include <QFont>
#include <QPen>
#include <QBrush>
/**
* \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

View File

@ -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 <QList>
#include <QPainter>
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<double> positions = segmentPositions( scaleContext, settings );
QList<double> 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 );
}

View File

@ -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 <QString>
/** \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

View File

@ -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 <QPainter>
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<double> 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 );
}

View File

@ -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

View File

@ -749,6 +749,7 @@ INCLUDE_DIRECTORIES(
../core/geometry
../core/layertree
../core/raster
../core/scalebar
../core/symbology-ng
../core/effects
${CMAKE_CURRENT_BINARY_DIR}

View File

@ -444,7 +444,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent *e )
QList<const QgsComposerMap *> 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

1
tests/src/core/CMakeLists.txt Normal file → Executable file
View File

@ -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

View File

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