mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-03 00:02:25 -05:00
Begin porting scalebar item
This commit is contained in:
parent
604e51d390
commit
8f5e0cb126
@ -422,6 +422,7 @@
|
||||
%Include layout/qgslayoutitempolygon.sip
|
||||
%Include layout/qgslayoutitempolyline.sip
|
||||
%Include layout/qgslayoutitemregistry.sip
|
||||
%Include layout/qgslayoutitemscalebar.sip
|
||||
%Include layout/qgslayoutitemshape.sip
|
||||
%Include layout/qgslayoutmodel.sip
|
||||
%Include layout/qgslayoutmultiframe.sip
|
||||
|
@ -173,6 +173,7 @@ class QgsLayoutItemRegistry : QObject
|
||||
LayoutShape,
|
||||
LayoutPolygon,
|
||||
LayoutPolyline,
|
||||
LayoutScaleBar,
|
||||
LayoutFrame,
|
||||
|
||||
// known
|
||||
|
447
python/core/layout/qgslayoutitemscalebar.sip
Normal file
447
python/core/layout/qgslayoutitemscalebar.sip
Normal file
@ -0,0 +1,447 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/layout/qgslayoutitemscalebar.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
class QgsLayoutItemScaleBar: QgsLayoutItem
|
||||
{
|
||||
%Docstring
|
||||
A layout item subclass for scale bars.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsLayoutItemScaleBar( QgsLayout *layout );
|
||||
%Docstring
|
||||
Constructor for QgsLayoutItemScaleBar, with the specified parent ``layout``.
|
||||
%End
|
||||
~QgsLayoutItemScaleBar();
|
||||
|
||||
virtual int type() const;
|
||||
|
||||
virtual QString stringType() const;
|
||||
|
||||
|
||||
static QgsLayoutItemScaleBar *create( QgsLayout *layout ) /Factory/;
|
||||
%Docstring
|
||||
Returns a new scale bar item for the specified ``layout``.
|
||||
|
||||
The caller takes responsibility for deleting the returned object.
|
||||
:rtype: QgsLayoutItemScaleBar
|
||||
%End
|
||||
|
||||
int numberOfSegments() const;
|
||||
%Docstring
|
||||
Returns the number of segments included in the scalebar.
|
||||
.. seealso:: setNumberOfSegments()
|
||||
.. seealso:: numberOfSegmentsLeft()
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
void setNumberOfSegments( int segments );
|
||||
%Docstring
|
||||
Sets the number of ``segments`` included in the scalebar.
|
||||
.. seealso:: numberOfSegments()
|
||||
.. seealso:: setNumberOfSegmentsLeft()
|
||||
%End
|
||||
|
||||
int numberOfSegmentsLeft() const;
|
||||
%Docstring
|
||||
Returns the number of segments included in the left part of the scalebar.
|
||||
.. seealso:: setNumberOfSegmentsLeft()
|
||||
.. seealso:: numberOfSegments()
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
void setNumberOfSegmentsLeft( int segments );
|
||||
%Docstring
|
||||
Sets the number of ``segments`` included in the left part of the scalebar.
|
||||
.. seealso:: numberOfSegmentsLeft()
|
||||
.. seealso:: setNumberOfSegments()
|
||||
%End
|
||||
|
||||
double unitsPerSegment() const;
|
||||
%Docstring
|
||||
Returns the number of scalebar units per segment.
|
||||
.. seealso:: setUnitsPerSegment()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setUnitsPerSegment( double units );
|
||||
%Docstring
|
||||
Sets the number of scalebar ``units`` per segment.
|
||||
.. seealso:: unitsPerSegment()
|
||||
%End
|
||||
|
||||
QgsScaleBarSettings::SegmentSizeMode segmentSizeMode() const;
|
||||
%Docstring
|
||||
Returns the size mode for the scale bar segments.
|
||||
.. seealso:: setSegmentSizeMode()
|
||||
.. seealso:: minBarWidth()
|
||||
.. seealso:: maxBarWidth()
|
||||
:rtype: QgsScaleBarSettings.SegmentSizeMode
|
||||
%End
|
||||
|
||||
void setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode mode );
|
||||
%Docstring
|
||||
Sets the size ``mode`` for scale bar segments.
|
||||
.. seealso:: segmentSizeMode()
|
||||
.. seealso:: setMinimumBarWidth()
|
||||
.. seealso:: 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.
|
||||
.. seealso:: segmentSizeMode()
|
||||
.. seealso:: setMinimumBarWidth()
|
||||
.. seealso:: maximumBarWidth()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setMinimumBarWidth( double minWidth );
|
||||
%Docstring
|
||||
Sets the minimum ``width`` (in millimeters) for scale bar segments. This
|
||||
property is only effective if the segmentSizeMode() is set
|
||||
to SegmentSizeFitWidth.
|
||||
.. seealso:: minimumBarWidth()
|
||||
.. seealso:: setMaximumBarWidth()
|
||||
.. seealso:: 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.
|
||||
.. seealso:: segmentSizeMode()
|
||||
.. seealso:: setMaximumBarWidth()
|
||||
.. seealso:: minimumBarWidth()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setMaximumBarWidth( double maxWidth );
|
||||
%Docstring
|
||||
Sets the maximum ``width`` (in millimeters) for scale bar segments. This
|
||||
property is only effective if the segmentSizeMode() is set
|
||||
to SegmentSizeFitWidth.
|
||||
.. seealso:: minimumBarWidth()
|
||||
.. seealso:: setMinimumBarWidth()
|
||||
.. seealso:: setSegmentSizeMode()
|
||||
%End
|
||||
|
||||
double mapUnitsPerScaleBarUnit() const;
|
||||
%Docstring
|
||||
Returns the number of map units per scale bar unit used by the scalebar.
|
||||
.. seealso:: setMapUnitsPerScaleBarUnit()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setMapUnitsPerScaleBarUnit( double units );
|
||||
%Docstring
|
||||
Sets the number of map ``units`` per scale bar unit used by the scalebar.
|
||||
.. seealso:: mapUnitsPerScaleBarUnit()
|
||||
%End
|
||||
|
||||
QString unitLabel() const;
|
||||
%Docstring
|
||||
Returns the label for units.
|
||||
.. seealso:: setUnitLabel()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setUnitLabel( const QString &label );
|
||||
%Docstring
|
||||
Sets the ``label`` for units.
|
||||
.. seealso:: unitLabel()
|
||||
%End
|
||||
|
||||
QFont font() const;
|
||||
%Docstring
|
||||
Returns the font used for drawing text in the scalebar.
|
||||
.. seealso:: setFont()
|
||||
:rtype: QFont
|
||||
%End
|
||||
|
||||
void setFont( const QFont &font );
|
||||
%Docstring
|
||||
Sets the ``font`` used for drawing text in the scalebar.
|
||||
.. seealso:: setFont()
|
||||
%End
|
||||
|
||||
QColor fontColor() const;
|
||||
%Docstring
|
||||
Returns the color used for drawing text in the scalebar.
|
||||
.. seealso:: setFontColor()
|
||||
.. seealso:: font()
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setFontColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the ``color`` used for drawing text in the scalebar.
|
||||
.. seealso:: fontColor()
|
||||
.. seealso:: setFont()
|
||||
%End
|
||||
|
||||
QColor fillColor() const;
|
||||
%Docstring
|
||||
Returns the color used for fills in the scalebar.
|
||||
.. seealso:: setFillColor()
|
||||
.. seealso:: fillColor2()
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setFillColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the ``color`` used for fills in the scalebar.
|
||||
.. seealso:: fillColor()
|
||||
.. seealso:: setFillColor2()
|
||||
%End
|
||||
|
||||
QColor fillColor2() const;
|
||||
%Docstring
|
||||
Returns the secondary color used for fills in the scalebar.
|
||||
.. seealso:: setFillColor2()
|
||||
.. seealso:: fillColor()
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setFillColor2( const QColor &color );
|
||||
%Docstring
|
||||
Sets the secondary ``color`` used for fills in the scalebar.
|
||||
.. seealso:: fillColor2()
|
||||
.. seealso:: setFillColor2()
|
||||
%End
|
||||
|
||||
QColor lineColor() const;
|
||||
%Docstring
|
||||
Returns the color used for lines in the scalebar.
|
||||
.. seealso:: setLineColor()
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setLineColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the ``color`` used for lines in the scalebar.
|
||||
.. seealso:: lineColor()
|
||||
%End
|
||||
|
||||
double lineWidth() const;
|
||||
%Docstring
|
||||
Returns the line width in millimeters for lines in the scalebar.
|
||||
.. seealso:: setLineWidth()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setLineWidth( double width );
|
||||
%Docstring
|
||||
Sets the line ``width`` in millimeters for lines in the scalebar.
|
||||
.. seealso:: lineWidth()
|
||||
%End
|
||||
|
||||
QPen pen() const;
|
||||
%Docstring
|
||||
Returns the pen used for drawing outlines in the scalebar.
|
||||
.. seealso:: setPen()
|
||||
.. seealso:: brush()
|
||||
:rtype: QPen
|
||||
%End
|
||||
|
||||
QBrush brush() const;
|
||||
%Docstring
|
||||
Returns the primary brush for the scalebar.
|
||||
:return: QBrush used for filling the scalebar
|
||||
.. seealso:: setBrush
|
||||
.. seealso:: brush2
|
||||
.. seealso:: pen
|
||||
:rtype: QBrush
|
||||
%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.
|
||||
:return: QBrush used for secondary color areas
|
||||
.. seealso:: setBrush2
|
||||
.. seealso:: brush
|
||||
:rtype: QBrush
|
||||
%End
|
||||
|
||||
double height() const;
|
||||
%Docstring
|
||||
Returns the scalebar height (in millimeters).
|
||||
.. seealso:: setHeight()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setHeight( double height );
|
||||
%Docstring
|
||||
Sets the scalebar ``height`` (in millimeters).
|
||||
.. seealso:: height()
|
||||
%End
|
||||
|
||||
void setMap( QgsLayoutItemMap *map );
|
||||
%Docstring
|
||||
Sets the ``map`` item linked to the scalebar.
|
||||
.. seealso:: map()
|
||||
%End
|
||||
|
||||
QgsLayoutItemMap *map() const;
|
||||
%Docstring
|
||||
Returns the map item linked to the scalebar.
|
||||
.. seealso:: setMap()
|
||||
:rtype: QgsLayoutItemMap
|
||||
%End
|
||||
|
||||
double labelBarSpace() const;
|
||||
%Docstring
|
||||
Returns the spacing (in millimeters) between labels and the scalebar.
|
||||
.. seealso:: setLabelBarSpace()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setLabelBarSpace( double space );
|
||||
%Docstring
|
||||
Sets the spacing (in millimeters) between labels and the scalebar.
|
||||
.. seealso:: labelBarSpace()
|
||||
%End
|
||||
|
||||
double boxContentSpace() const;
|
||||
%Docstring
|
||||
Returns the spacing (margin) between the scalebar box and content in millimeters.
|
||||
.. seealso:: setBoxContentSpace()
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
void setBoxContentSpace( double space );
|
||||
%Docstring
|
||||
Sets the ``space`` (margin) between the scalebar box and content in millimeters.
|
||||
.. seealso:: boxContentSpace()
|
||||
%End
|
||||
|
||||
QgsScaleBarSettings::Alignment alignment() const;
|
||||
%Docstring
|
||||
Returns the scalebar alignment.
|
||||
.. seealso:: setAlignment()
|
||||
:rtype: QgsScaleBarSettings.Alignment
|
||||
%End
|
||||
|
||||
void setAlignment( QgsScaleBarSettings::Alignment alignment );
|
||||
%Docstring
|
||||
Sets the scalebar ``alignment``.
|
||||
.. seealso:: alignment()
|
||||
%End
|
||||
|
||||
QgsUnitTypes::DistanceUnit units() const;
|
||||
%Docstring
|
||||
Returns the distance units used by the scalebar.
|
||||
.. seealso:: setUnits()
|
||||
:rtype: QgsUnitTypes.DistanceUnit
|
||||
%End
|
||||
|
||||
void setUnits( QgsUnitTypes::DistanceUnit units );
|
||||
%Docstring
|
||||
Sets the distance ``units`` used by the scalebar.
|
||||
.. seealso:: units()
|
||||
%End
|
||||
|
||||
Qt::PenJoinStyle lineJoinStyle() const;
|
||||
%Docstring
|
||||
Returns the join style used for drawing lines in the scalebar.
|
||||
.. seealso:: setLineJoinStyle()
|
||||
:rtype: Qt.PenJoinStyle
|
||||
%End
|
||||
|
||||
void setLineJoinStyle( Qt::PenJoinStyle style );
|
||||
%Docstring
|
||||
Sets the join ``style`` used when drawing the lines in the scalebar
|
||||
.. seealso:: lineJoinStyle()
|
||||
%End
|
||||
|
||||
Qt::PenCapStyle lineCapStyle() const;
|
||||
%Docstring
|
||||
Returns the cap style used for drawing lines in the scalebar.
|
||||
.. seealso:: setLineCapStyle()
|
||||
:rtype: Qt.PenCapStyle
|
||||
%End
|
||||
|
||||
void setLineCapStyle( Qt::PenCapStyle style );
|
||||
%Docstring
|
||||
Sets the cap ``style`` used when drawing the lines in the scalebar.
|
||||
.. seealso:: lineCapStyle()
|
||||
%End
|
||||
|
||||
void applyDefaultSettings();
|
||||
%Docstring
|
||||
Applies the default scalebar settings to the scale bar.
|
||||
.. seealso:: applyDefaultSize()
|
||||
%End
|
||||
|
||||
void applyDefaultSize( QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceMeters );
|
||||
%Docstring
|
||||
Applies the default size to the scale bar (scale bar 1/5 of map item width)
|
||||
.. seealso:: applyDefaultSettings()
|
||||
%End
|
||||
|
||||
void setStyle( const QString &name );
|
||||
%Docstring
|
||||
Sets the scale bar style by ``name``.
|
||||
|
||||
The ``name`` parameter gives the (untranslated) style name.
|
||||
Possibilities are: 'Single Box', 'Double Box', 'Line Ticks Middle',
|
||||
'Line Ticks Down', 'Line Ticks Up', 'Numeric'
|
||||
|
||||
.. seealso:: style()
|
||||
%End
|
||||
|
||||
QString style() const;
|
||||
%Docstring
|
||||
Returns the scale bar style name.
|
||||
.. seealso:: setStyle()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void adjustBoxSize();
|
||||
%Docstring
|
||||
Sets the scale bar box size to a size suitable for the scalebar content.
|
||||
%End
|
||||
|
||||
void update();
|
||||
%Docstring
|
||||
Adjusts the scale bar box size and updates the item.
|
||||
%End
|
||||
virtual void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = 0 );
|
||||
|
||||
virtual bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
|
||||
virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/layout/qgslayoutitemscalebar.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -184,6 +184,12 @@ class QgsLayoutMultiFrame: QgsLayoutObject, QgsLayoutUndoObjectInterface
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QList<QgsLayoutFrame *> frames() const;
|
||||
%Docstring
|
||||
Returns a list of all child frames for this multiframe.
|
||||
.. seealso:: frameCount()
|
||||
:rtype: list of QgsLayoutFrame
|
||||
%End
|
||||
|
||||
int frameCount() const;
|
||||
%Docstring
|
||||
@ -199,6 +205,14 @@ class QgsLayoutMultiFrame: QgsLayoutObject, QgsLayoutUndoObjectInterface
|
||||
:rtype: QgsLayoutFrame
|
||||
%End
|
||||
|
||||
int frameIndex( QgsLayoutFrame *frame ) const;
|
||||
%Docstring
|
||||
Returns the index of a ``frame`` within the multiframe.
|
||||
:return: index for frame if found, -1 if frame not found in multiframe
|
||||
.. seealso:: frame()
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
QgsLayoutFrame *createNewFrame( QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size );
|
||||
%Docstring
|
||||
Creates a new frame and adds it to the multi frame and layout.
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "qgslayoutitemlabel.h"
|
||||
#include "qgslayoutlabelwidget.h"
|
||||
#include "qgslayoutitemlegend.h"
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
#include "qgslayoutlegendwidget.h"
|
||||
#include "qgslayoutframe.h"
|
||||
#include "qgslayoutitemhtml.h"
|
||||
@ -140,6 +141,29 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
|
||||
|
||||
registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
|
||||
|
||||
// scalebar item
|
||||
|
||||
auto scalebarItemMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddScalebar.svg" ) ),
|
||||
[ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
|
||||
{
|
||||
return nullptr;//new QgsLayoutLegendWidget( qobject_cast< QgsLayoutItemLegend * >( item ) );
|
||||
}, createRubberBand );
|
||||
scalebarItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item )
|
||||
{
|
||||
QgsLayoutItemScaleBar *scalebar = qobject_cast< QgsLayoutItemScaleBar * >( item );
|
||||
Q_ASSERT( scalebar );
|
||||
|
||||
QList<QgsLayoutItemMap *> mapItems;
|
||||
scalebar->layout()->layoutItems( mapItems );
|
||||
|
||||
if ( !mapItems.isEmpty() )
|
||||
{
|
||||
scalebar->setMap( mapItems.at( 0 ) );
|
||||
}
|
||||
scalebar->applyDefaultSize();
|
||||
} );
|
||||
|
||||
registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
|
||||
|
||||
// shape items
|
||||
|
||||
|
@ -386,6 +386,7 @@ SET(QGIS_CORE_SRCS
|
||||
layout/qgslayoutitempolygon.cpp
|
||||
layout/qgslayoutitempolyline.cpp
|
||||
layout/qgslayoutitemregistry.cpp
|
||||
layout/qgslayoutitemscalebar.cpp
|
||||
layout/qgslayoutitemshape.cpp
|
||||
layout/qgslayoutitemundocommand.cpp
|
||||
layout/qgslayoutmeasurement.cpp
|
||||
@ -750,6 +751,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
layout/qgslayoutitempolygon.h
|
||||
layout/qgslayoutitempolyline.h
|
||||
layout/qgslayoutitemregistry.h
|
||||
layout/qgslayoutitemscalebar.h
|
||||
layout/qgslayoutitemshape.h
|
||||
layout/qgslayoutmodel.h
|
||||
layout/qgslayoutmultiframe.h
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qgslayoutitempicture.h"
|
||||
#include "qgslayoutitemgroup.h"
|
||||
#include "qgslayoutitemhtml.h"
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
#include "qgslayoutframe.h"
|
||||
#include "qgsgloweffect.h"
|
||||
#include "qgseffectstack.h"
|
||||
@ -59,6 +60,7 @@ bool QgsLayoutItemRegistry::populate()
|
||||
addLayoutItemType( new QgsLayoutItemMetadata( LayoutPicture, QStringLiteral( "Picture" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddImage.svg" ) ), QgsLayoutItemPicture::create ) );
|
||||
addLayoutItemType( new QgsLayoutItemMetadata( LayoutLabel, QStringLiteral( "Label" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionLabel.svg" ) ), QgsLayoutItemLabel::create ) );
|
||||
addLayoutItemType( new QgsLayoutItemMetadata( LayoutLegend, QStringLiteral( "Legend" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLegend.svg" ) ), QgsLayoutItemLegend::create ) );
|
||||
addLayoutItemType( new QgsLayoutItemMetadata( LayoutScaleBar, QStringLiteral( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddScalebar.svg" ) ), QgsLayoutItemScaleBar::create ) );
|
||||
addLayoutItemType( new QgsLayoutItemMetadata( LayoutShape, QStringLiteral( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), []( QgsLayout * layout )
|
||||
{
|
||||
QgsLayoutItemShape *shape = new QgsLayoutItemShape( layout );
|
||||
|
@ -315,6 +315,7 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
|
||||
LayoutShape, //!< Shape item
|
||||
LayoutPolygon, //!< Polygon shape item
|
||||
LayoutPolyline, //!< Polyline shape item
|
||||
LayoutScaleBar, //!< Scale bar item
|
||||
LayoutFrame, //!< Frame item, part of a QgsLayoutMultiFrame object
|
||||
|
||||
// known multi-frame types
|
||||
|
919
src/core/layout/qgslayoutitemscalebar.cpp
Normal file
919
src/core/layout/qgslayoutitemscalebar.cpp
Normal file
@ -0,0 +1,919 @@
|
||||
/***************************************************************************
|
||||
qgslayoutitemscalebar.cpp
|
||||
-------------------------
|
||||
begin : November 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgslayoutitemmap.h"
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayoututils.h"
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgsscalebarrenderer.h"
|
||||
#include "qgsdoubleboxscalebarrenderer.h"
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgsnumericscalebarrenderer.h"
|
||||
#include "qgssingleboxscalebarrenderer.h"
|
||||
#include "qgsticksscalebarrenderer.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgsfontutils.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QFontMetricsF>
|
||||
#include <QPainter>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
QgsLayoutItemScaleBar::QgsLayoutItemScaleBar( QgsLayout *layout )
|
||||
: QgsLayoutItem( layout )
|
||||
, mSegmentMillimeters( 0.0 )
|
||||
{
|
||||
applyDefaultSettings();
|
||||
applyDefaultSize();
|
||||
}
|
||||
|
||||
QgsLayoutItemScaleBar::~QgsLayoutItemScaleBar()
|
||||
{
|
||||
delete mStyle;
|
||||
}
|
||||
|
||||
int QgsLayoutItemScaleBar::type() const
|
||||
{
|
||||
return QgsLayoutItemRegistry::LayoutScaleBar;
|
||||
}
|
||||
|
||||
QString QgsLayoutItemScaleBar::stringType() const
|
||||
{
|
||||
return QStringLiteral( "ItemScaleBar" );
|
||||
}
|
||||
|
||||
QgsLayoutItemScaleBar *QgsLayoutItemScaleBar::create( QgsLayout *layout )
|
||||
{
|
||||
return new QgsLayoutItemScaleBar( layout );
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::draw( QgsRenderContext &context, const QStyleOptionGraphicsItem * )
|
||||
{
|
||||
if ( !mStyle )
|
||||
return;
|
||||
|
||||
mStyle->draw( context, mSettings, createScaleContext() );
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setNumberOfSegments( int nSegments )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setNumberOfSegments( nSegments );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setNumberOfSegments( nSegments );
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setUnitsPerSegment( double units )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setUnitsPerSegment( units );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setUnitsPerSegment( units );
|
||||
refreshSegmentMillimeters();
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode mode )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setSegmentSizeMode( mode );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setSegmentSizeMode( mode );
|
||||
refreshSegmentMillimeters();
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setMinimumBarWidth( double minWidth )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setMinimumBarWidth( minWidth );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setMinimumBarWidth( minWidth );
|
||||
refreshSegmentMillimeters();
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setMaximumBarWidth( double maxWidth )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setMaximumBarWidth( maxWidth );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setMaximumBarWidth( maxWidth );
|
||||
refreshSegmentMillimeters();
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setNumberOfSegmentsLeft( int nSegmentsLeft )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setBoxContentSpace( double space )
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
mSettings.setBoxContentSpace( space );
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
mSettings.setBoxContentSpace( space );
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setMap( QgsLayoutItemMap *map )
|
||||
{
|
||||
if ( mMap )
|
||||
{
|
||||
disconnect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateSegmentSize );
|
||||
disconnect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::invalidateCurrentMap );
|
||||
}
|
||||
mMap = map;
|
||||
|
||||
if ( !map )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateSegmentSize );
|
||||
connect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::invalidateCurrentMap );
|
||||
|
||||
refreshSegmentMillimeters();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::invalidateCurrentMap()
|
||||
{
|
||||
if ( !mMap )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disconnect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateSegmentSize );
|
||||
disconnect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::invalidateCurrentMap );
|
||||
mMap = nullptr;
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property )
|
||||
{
|
||||
QgsExpressionContext context = createExpressionContext();
|
||||
|
||||
bool forceUpdate = false;
|
||||
//updates data defined properties and redraws item to match
|
||||
if ( property == QgsLayoutObject::ScalebarFillColor || property == QgsLayoutObject::AllProperties )
|
||||
{
|
||||
QBrush b = mSettings.brush();
|
||||
b.setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarFillColor, context, mSettings.fillColor() ) );
|
||||
mSettings.setBrush( b );
|
||||
forceUpdate = true;
|
||||
}
|
||||
if ( property == QgsLayoutObject::ScalebarFillColor2 || property == QgsLayoutObject::AllProperties )
|
||||
{
|
||||
QBrush b = mSettings.brush2();
|
||||
b.setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarFillColor2, context, mSettings.fillColor2() ) );
|
||||
mSettings.setBrush2( b );
|
||||
forceUpdate = true;
|
||||
}
|
||||
if ( property == QgsLayoutObject::ScalebarLineColor || property == QgsLayoutObject::AllProperties )
|
||||
{
|
||||
QPen p = mSettings.pen();
|
||||
p.setColor( mDataDefinedProperties.valueAsColor( QgsLayoutObject::ScalebarLineColor, context, mSettings.lineColor() ) );
|
||||
mSettings.setPen( p );
|
||||
forceUpdate = true;
|
||||
}
|
||||
if ( property == QgsLayoutObject::ScalebarLineWidth || property == QgsLayoutObject::AllProperties )
|
||||
{
|
||||
QPen p = mSettings.pen();
|
||||
p.setWidthF( mDataDefinedProperties.valueAsDouble( QgsLayoutObject::ScalebarLineWidth, context, mSettings.lineWidth() ) );
|
||||
mSettings.setPen( p );
|
||||
forceUpdate = true;
|
||||
}
|
||||
if ( forceUpdate )
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
QgsLayoutItem::refreshDataDefinedProperty( property );
|
||||
}
|
||||
|
||||
// nextNiceNumber(4573.23, d) = 5000 (d=1) -> 4600 (d=10) -> 4580 (d=100) -> 4574 (d=1000) -> etc
|
||||
inline double nextNiceNumber( double a, double d = 1 )
|
||||
{
|
||||
double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
|
||||
return std::ceil( a / s ) * s;
|
||||
}
|
||||
|
||||
// prevNiceNumber(4573.23, d) = 4000 (d=1) -> 4500 (d=10) -> 4570 (d=100) -> 4573 (d=1000) -> etc
|
||||
inline double prevNiceNumber( double a, double d = 1 )
|
||||
{
|
||||
double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
|
||||
return std::floor( a / s ) * s;
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::refreshSegmentMillimeters()
|
||||
{
|
||||
if ( mMap )
|
||||
{
|
||||
//get mm dimension of composer map
|
||||
QRectF composerItemRect = mMap->rect();
|
||||
|
||||
if ( mSettings.segmentSizeMode() == QgsScaleBarSettings::SegmentSizeFixed )
|
||||
{
|
||||
//calculate size depending on mNumUnitsPerSegment
|
||||
mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment();
|
||||
}
|
||||
else /*if(mSegmentSizeMode == SegmentSizeFitWidth)*/
|
||||
{
|
||||
if ( mSettings.maximumBarWidth() < mSettings.minimumBarWidth() )
|
||||
{
|
||||
mSegmentMillimeters = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double nSegments = ( mSettings.numberOfSegmentsLeft() != 0 ) + mSettings.numberOfSegments();
|
||||
// unitsPerSegments which fit minBarWidth resp. maxBarWidth
|
||||
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
|
||||
// lowerNiceUnitsPerSeg nor upperNiceUnitsPerSeg are are in
|
||||
// [minUnitsPerSeg, maxUnitsPerSeg]
|
||||
double lowerNiceUnitsPerSeg = nextNiceNumber( minUnitsPerSeg );
|
||||
double upperNiceUnitsPerSeg = prevNiceNumber( maxUnitsPerSeg );
|
||||
|
||||
double d = 1;
|
||||
while ( lowerNiceUnitsPerSeg > maxUnitsPerSeg && upperNiceUnitsPerSeg < minUnitsPerSeg )
|
||||
{
|
||||
d *= 10;
|
||||
lowerNiceUnitsPerSeg = nextNiceNumber( minUnitsPerSeg, d );
|
||||
upperNiceUnitsPerSeg = prevNiceNumber( maxUnitsPerSeg, d );
|
||||
}
|
||||
|
||||
// Pick mNumUnitsPerSegment from {lowerNiceUnitsPerSeg, upperNiceUnitsPerSeg}, use the larger if possible
|
||||
mSettings.setUnitsPerSegment( upperNiceUnitsPerSeg < minUnitsPerSeg ? lowerNiceUnitsPerSeg : upperNiceUnitsPerSeg );
|
||||
mSegmentMillimeters = composerItemRect.width() / mapWidth() * mSettings.unitsPerSegment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double QgsLayoutItemScaleBar::mapWidth() const
|
||||
{
|
||||
if ( !mMap )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
QgsRectangle mapExtent = mMap->extent();
|
||||
if ( mSettings.units() == QgsUnitTypes::DistanceUnknownUnit )
|
||||
{
|
||||
return mapExtent.width();
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDistanceArea da;
|
||||
da.setSourceCrs( mMap->crs() );
|
||||
da.setEllipsoid( mLayout->project()->ellipsoid() );
|
||||
|
||||
QgsUnitTypes::DistanceUnit units = da.lengthUnits();
|
||||
double measure = da.measureLine( QgsPointXY( mapExtent.xMinimum(), mapExtent.yMinimum() ),
|
||||
QgsPointXY( mapExtent.xMaximum(), mapExtent.yMinimum() ) );
|
||||
measure /= QgsUnitTypes::fromUnitToUnitFactor( mSettings.units(), units );
|
||||
return measure;
|
||||
}
|
||||
}
|
||||
|
||||
QgsScaleBarRenderer::ScaleBarContext QgsLayoutItemScaleBar::createScaleContext() const
|
||||
{
|
||||
QgsScaleBarRenderer::ScaleBarContext scaleContext;
|
||||
scaleContext.size = rect().size();
|
||||
scaleContext.segmentWidth = mSegmentMillimeters;
|
||||
scaleContext.scale = mMap ? mMap->scale() : 1.0;
|
||||
return scaleContext;
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setAlignment( QgsScaleBarSettings::Alignment a )
|
||||
{
|
||||
mSettings.setAlignment( a );
|
||||
update();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setUnits( QgsUnitTypes::DistanceUnit u )
|
||||
{
|
||||
mSettings.setUnits( u );
|
||||
refreshSegmentMillimeters();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setLineJoinStyle( Qt::PenJoinStyle style )
|
||||
{
|
||||
if ( mSettings.lineJoinStyle() == style )
|
||||
{
|
||||
//no change
|
||||
return;
|
||||
}
|
||||
mSettings.setLineJoinStyle( style );
|
||||
update();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setLineCapStyle( Qt::PenCapStyle style )
|
||||
{
|
||||
if ( mSettings.lineCapStyle() == style )
|
||||
{
|
||||
//no change
|
||||
return;
|
||||
}
|
||||
mSettings.setLineCapStyle( style );
|
||||
update();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::applyDefaultSettings()
|
||||
{
|
||||
//style
|
||||
delete mStyle;
|
||||
mStyle = new QgsSingleBoxScaleBarRenderer();
|
||||
|
||||
//default to no background
|
||||
setBackgroundEnabled( false );
|
||||
|
||||
//get default composer font from settings
|
||||
QgsSettings settings;
|
||||
QString defaultFontString = settings.value( QStringLiteral( "Composer/defaultFont" ) ).toString();
|
||||
QFont f;
|
||||
if ( !defaultFontString.isEmpty() )
|
||||
{
|
||||
f.setFamily( defaultFontString );
|
||||
}
|
||||
f.setPointSizeF( 12.0 );
|
||||
mSettings.setFont( f );
|
||||
|
||||
mSettings.setUnits( QgsUnitTypes::DistanceUnknownUnit );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::applyDefaultSize( QgsUnitTypes::DistanceUnit units )
|
||||
{
|
||||
if ( mMap )
|
||||
{
|
||||
setUnits( units );
|
||||
double upperMagnitudeMultiplier = 1.0;
|
||||
double widthInSelectedUnits = mapWidth();
|
||||
double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
|
||||
setUnitsPerSegment( initialUnitsPerSegment );
|
||||
|
||||
switch ( units )
|
||||
{
|
||||
case QgsUnitTypes::DistanceUnknownUnit:
|
||||
{
|
||||
upperMagnitudeMultiplier = 1.0;
|
||||
setUnitLabel( tr( "units" ) );
|
||||
break;
|
||||
}
|
||||
case QgsUnitTypes::DistanceMeters:
|
||||
{
|
||||
if ( initialUnitsPerSegment > 1000.0 )
|
||||
{
|
||||
upperMagnitudeMultiplier = 1000.0;
|
||||
setUnitLabel( tr( "km" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
upperMagnitudeMultiplier = 1.0;
|
||||
setUnitLabel( tr( "m" ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QgsUnitTypes::DistanceFeet:
|
||||
{
|
||||
if ( initialUnitsPerSegment > 5419.95 )
|
||||
{
|
||||
upperMagnitudeMultiplier = 5419.95;
|
||||
setUnitLabel( tr( "miles" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
upperMagnitudeMultiplier = 1.0;
|
||||
setUnitLabel( tr( "ft" ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
setUnitLabel( QgsUnitTypes::toAbbreviatedString( units ) );
|
||||
upperMagnitudeMultiplier = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier;
|
||||
int segmentMagnitude = std::floor( std::log10( segmentWidth ) );
|
||||
double unitsPerSegment = upperMagnitudeMultiplier * ( std::pow( 10.0, segmentMagnitude ) );
|
||||
double multiplier = std::floor( ( widthInSelectedUnits / ( unitsPerSegment * 10.0 ) ) / 2.5 ) * 2.5;
|
||||
|
||||
if ( multiplier > 0 )
|
||||
{
|
||||
unitsPerSegment = unitsPerSegment * multiplier;
|
||||
}
|
||||
setUnitsPerSegment( unitsPerSegment );
|
||||
setMapUnitsPerScaleBarUnit( upperMagnitudeMultiplier );
|
||||
|
||||
setNumberOfSegments( 4 );
|
||||
setNumberOfSegmentsLeft( 2 );
|
||||
}
|
||||
|
||||
refreshSegmentMillimeters();
|
||||
adjustBoxSize();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::adjustBoxSize()
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
box.setHeight( rect().height() );
|
||||
}
|
||||
|
||||
#if 0 //TODO
|
||||
//update rect for data defined size and position
|
||||
QRectF newRect = evalItemRect( box, true );
|
||||
|
||||
//scale bars have a minimum size, respect that regardless of data defined settings
|
||||
if ( newRect.width() < box.width() )
|
||||
{
|
||||
newRect.setWidth( box.width() );
|
||||
}
|
||||
if ( newRect.height() < box.height() )
|
||||
{
|
||||
newRect.setHeight( box.height() );
|
||||
}
|
||||
|
||||
QgsLayoutItem::setSceneRect( newRect );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0 //TODO
|
||||
void QgsLayoutItemScaleBar::setSceneRect( const QRectF &rectangle )
|
||||
{
|
||||
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
|
||||
box.setHeight( rectangle.height() );
|
||||
}
|
||||
box.moveTopLeft( rectangle.topLeft() );
|
||||
|
||||
//update rect for data defined size and position
|
||||
QRectF newRect = evalItemRect( rectangle );
|
||||
|
||||
//scale bars have a minimum size, respect that regardless of data defined settings
|
||||
if ( newRect.width() < box.width() )
|
||||
{
|
||||
newRect.setWidth( box.width() );
|
||||
}
|
||||
if ( newRect.height() < box.height() )
|
||||
{
|
||||
newRect.setHeight( box.height() );
|
||||
}
|
||||
|
||||
QgsComposerItem::setSceneRect( newRect );
|
||||
}
|
||||
#endif
|
||||
|
||||
void QgsLayoutItemScaleBar::update()
|
||||
{
|
||||
//Don't adjust box size for numeric scale bars:
|
||||
if ( mStyle && mStyle->name() != QLatin1String( "Numeric" ) )
|
||||
{
|
||||
adjustBoxSize();
|
||||
}
|
||||
QgsLayoutItem::update();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::updateSegmentSize()
|
||||
{
|
||||
if ( !mStyle )
|
||||
{
|
||||
return;
|
||||
}
|
||||
double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
refreshSegmentMillimeters();
|
||||
double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
|
||||
correctXPositionAlignment( width, widthAfter );
|
||||
update();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setStyle( const QString &styleName )
|
||||
{
|
||||
delete mStyle;
|
||||
mStyle = nullptr;
|
||||
|
||||
//switch depending on style name
|
||||
if ( styleName == QLatin1String( "Single Box" ) )
|
||||
{
|
||||
mStyle = new QgsSingleBoxScaleBarRenderer();
|
||||
}
|
||||
else if ( styleName == QLatin1String( "Double Box" ) )
|
||||
{
|
||||
mStyle = new QgsDoubleBoxScaleBarRenderer();
|
||||
}
|
||||
else if ( styleName == QLatin1String( "Line Ticks Middle" ) || styleName == QLatin1String( "Line Ticks Down" ) || styleName == QLatin1String( "Line Ticks Up" ) )
|
||||
{
|
||||
QgsTicksScaleBarRenderer *tickStyle = new QgsTicksScaleBarRenderer();
|
||||
if ( styleName == QLatin1String( "Line Ticks Middle" ) )
|
||||
{
|
||||
tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksMiddle );
|
||||
}
|
||||
else if ( styleName == QLatin1String( "Line Ticks Down" ) )
|
||||
{
|
||||
tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksDown );
|
||||
}
|
||||
else if ( styleName == QLatin1String( "Line Ticks Up" ) )
|
||||
{
|
||||
tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksUp );
|
||||
}
|
||||
mStyle = tickStyle;
|
||||
}
|
||||
else if ( styleName == QLatin1String( "Numeric" ) )
|
||||
{
|
||||
mStyle = new QgsNumericScaleBarRenderer();
|
||||
}
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QString QgsLayoutItemScaleBar::style() const
|
||||
{
|
||||
if ( mStyle )
|
||||
{
|
||||
return mStyle->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QFont QgsLayoutItemScaleBar::font() const
|
||||
{
|
||||
return mSettings.font();
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::setFont( const QFont &font )
|
||||
{
|
||||
mSettings.setFont( font );
|
||||
update();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
bool QgsLayoutItemScaleBar::writePropertiesToElement( QDomElement &composerScaleBarElem, QDomDocument &doc, const QgsReadWriteContext & ) const
|
||||
{
|
||||
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( 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 )
|
||||
{
|
||||
composerScaleBarElem.setAttribute( QStringLiteral( "style" ), mStyle->name() );
|
||||
}
|
||||
|
||||
//map id
|
||||
if ( mMap )
|
||||
{
|
||||
composerScaleBarElem.setAttribute( QStringLiteral( "mapId" ), mMap->id() );
|
||||
}
|
||||
|
||||
//colors
|
||||
|
||||
//fill color
|
||||
QDomElement fillColorElem = doc.createElement( QStringLiteral( "fillColor" ) );
|
||||
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( 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( 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( 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 >( mSettings.alignment() ) ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context )
|
||||
{
|
||||
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" ) ).toDouble() );
|
||||
mSettings.setMaximumBarWidth( itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toDouble() );
|
||||
mSegmentMillimeters = itemElem.attribute( QStringLiteral( "segmentMillimeters" ), QStringLiteral( "0.0" ) ).toDouble();
|
||||
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" ) ) )
|
||||
{
|
||||
f.fromString( itemElem.attribute( QStringLiteral( "font" ), QLatin1String( "" ) ) );
|
||||
}
|
||||
mSettings.setFont( f );
|
||||
|
||||
//colors
|
||||
//fill color
|
||||
QDomNodeList fillColorList = itemElem.elementsByTagName( QStringLiteral( "fillColor" ) );
|
||||
if ( !fillColorList.isEmpty() )
|
||||
{
|
||||
QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int fillRed, fillGreen, fillBlue, fillAlpha;
|
||||
|
||||
fillRed = fillColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
fillGreen = fillColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
fillBlue = fillColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
fillAlpha = fillColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
mSettings.setFillColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSettings.setFillColor( QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ) );
|
||||
}
|
||||
|
||||
//fill color 2
|
||||
QDomNodeList fillColor2List = itemElem.elementsByTagName( QStringLiteral( "fillColor2" ) );
|
||||
if ( !fillColor2List.isEmpty() )
|
||||
{
|
||||
QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int fillRed, fillGreen, fillBlue, fillAlpha;
|
||||
|
||||
fillRed = fillColor2Elem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
fillGreen = fillColor2Elem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
fillBlue = fillColor2Elem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
fillAlpha = fillColor2Elem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
mSettings.setFillColor2( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSettings.setFillColor2( QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ) );
|
||||
}
|
||||
|
||||
//stroke color
|
||||
QDomNodeList strokeColorList = itemElem.elementsByTagName( QStringLiteral( "strokeColor" ) );
|
||||
if ( !strokeColorList.isEmpty() )
|
||||
{
|
||||
QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
|
||||
|
||||
strokeRed = strokeColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
strokeGreen = strokeColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
strokeBlue = strokeColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
strokeAlpha = strokeColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
mSettings.setLineColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
|
||||
QPen p = mSettings.pen();
|
||||
p.setColor( mSettings.lineColor() );
|
||||
mSettings.setPen( p );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSettings.setLineColor( QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ) );
|
||||
QPen p = mSettings.pen();
|
||||
p.setColor( mSettings.lineColor() );
|
||||
mSettings.setPen( p );
|
||||
}
|
||||
|
||||
//font color
|
||||
QDomNodeList textColorList = itemElem.elementsByTagName( QStringLiteral( "textColor" ) );
|
||||
if ( !textColorList.isEmpty() )
|
||||
{
|
||||
QDomElement textColorElem = textColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int textRed, textGreen, textBlue, textAlpha;
|
||||
|
||||
textRed = textColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
textGreen = textColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
textBlue = textColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
textAlpha = textColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
mSettings.setFontColor( QColor( textRed, textGreen, textBlue, textAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QColor c;
|
||||
c.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
|
||||
mSettings.setFontColor( c );
|
||||
}
|
||||
|
||||
//style
|
||||
delete mStyle;
|
||||
mStyle = nullptr;
|
||||
QString styleString = itemElem.attribute( QStringLiteral( "style" ), QLatin1String( "" ) );
|
||||
setStyle( tr( styleString.toLocal8Bit().data() ) );
|
||||
|
||||
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
|
||||
#if 0 //TODO
|
||||
int mapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) ).toInt();
|
||||
if ( mapId >= 0 )
|
||||
{
|
||||
const QgsLayoutItemMap *composerMap = mComposition->getComposerMapById( mapId );
|
||||
mMap = const_cast< QgsComposerMap *>( composerMap );
|
||||
if ( mMap )
|
||||
{
|
||||
connect( mMap, &QgsComposerMap::extentChanged, this, &QgsLayoutItemScaleBar::updateSegmentSize );
|
||||
connect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::invalidateCurrentMap );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QString mapId = itemElem.attribute( QStringLiteral( "mapUuid" ) );
|
||||
if ( !mLayout || mapId.isEmpty() )
|
||||
{
|
||||
mMap = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidateCurrentMap();
|
||||
mMap = qobject_cast< QgsLayoutItemMap * >( mLayout->itemByUuid( mapId ) );
|
||||
if ( mMap )
|
||||
{
|
||||
connect( mMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemScaleBar::updateSegmentSize );
|
||||
connect( mMap, &QObject::destroyed, this, &QgsLayoutItemScaleBar::invalidateCurrentMap );
|
||||
}
|
||||
}
|
||||
|
||||
updateSegmentSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsLayoutItemScaleBar::correctXPositionAlignment( double width, double widthAfter )
|
||||
{
|
||||
//Don't adjust position for numeric scale bars:
|
||||
if ( mStyle->name() == QLatin1String( "Numeric" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if 0 //TODO
|
||||
|
||||
if ( mSettings.alignment() == QgsScaleBarSettings::AlignMiddle )
|
||||
{
|
||||
move( -( widthAfter - width ) / 2.0, 0 );
|
||||
}
|
||||
else if ( mSettings.alignment() == QgsScaleBarSettings::AlignRight )
|
||||
{
|
||||
move( -( widthAfter - width ), 0 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
459
src/core/layout/qgslayoutitemscalebar.h
Normal file
459
src/core/layout/qgslayoutitemscalebar.h
Normal file
@ -0,0 +1,459 @@
|
||||
/***************************************************************************
|
||||
qgslayoutitemscalebar.h
|
||||
------------------------
|
||||
begin : November 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 QGSLAYOUTITEMSCALEBAR_H
|
||||
#define QGSLAYOUTITEMSCALEBAR_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis.h"
|
||||
#include "qgslayoutitem.h"
|
||||
#include "scalebar/qgsscalebarsettings.h"
|
||||
#include "scalebar/qgsscalebarrenderer.h"
|
||||
#include <QFont>
|
||||
#include <QPen>
|
||||
#include <QColor>
|
||||
|
||||
class QgsLayoutItemMap;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* A layout item subclass for scale bars.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsLayoutItemScaleBar, with the specified parent \a layout.
|
||||
*/
|
||||
QgsLayoutItemScaleBar( QgsLayout *layout );
|
||||
~QgsLayoutItemScaleBar();
|
||||
|
||||
int type() const override;
|
||||
QString stringType() const override;
|
||||
|
||||
/**
|
||||
* Returns a new scale bar item for the specified \a layout.
|
||||
*
|
||||
* The caller takes responsibility for deleting the returned object.
|
||||
*/
|
||||
static QgsLayoutItemScaleBar *create( QgsLayout *layout ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Returns the number of segments included in the scalebar.
|
||||
* \see setNumberOfSegments()
|
||||
* \see numberOfSegmentsLeft()
|
||||
*/
|
||||
int numberOfSegments() const { return mSettings.numberOfSegments(); }
|
||||
|
||||
/**
|
||||
* Sets the number of \a segments included in the scalebar.
|
||||
* \see numberOfSegments()
|
||||
* \see setNumberOfSegmentsLeft()
|
||||
*/
|
||||
void setNumberOfSegments( int segments );
|
||||
|
||||
/**
|
||||
* Returns the number of segments included in the left part of the scalebar.
|
||||
* \see setNumberOfSegmentsLeft()
|
||||
* \see numberOfSegments()
|
||||
*/
|
||||
int numberOfSegmentsLeft() const { return mSettings.numberOfSegmentsLeft(); }
|
||||
|
||||
/**
|
||||
* Sets the number of \a segments included in the left part of the scalebar.
|
||||
* \see numberOfSegmentsLeft()
|
||||
* \see setNumberOfSegments()
|
||||
*/
|
||||
void setNumberOfSegmentsLeft( int segments );
|
||||
|
||||
/**
|
||||
* Returns the number of scalebar units per segment.
|
||||
* \see setUnitsPerSegment()
|
||||
*/
|
||||
double unitsPerSegment() const { return mSettings.unitsPerSegment(); }
|
||||
|
||||
/**
|
||||
* Sets the number of scalebar \a units per segment.
|
||||
* \see unitsPerSegment()
|
||||
*/
|
||||
void setUnitsPerSegment( double units );
|
||||
|
||||
/**
|
||||
* Returns the size mode for the scale bar segments.
|
||||
* \see setSegmentSizeMode()
|
||||
* \see minBarWidth()
|
||||
* \see maxBarWidth()
|
||||
*/
|
||||
QgsScaleBarSettings::SegmentSizeMode segmentSizeMode() const { return mSettings.segmentSizeMode(); }
|
||||
|
||||
/**
|
||||
* Sets the size \a mode for scale bar segments.
|
||||
* \see segmentSizeMode()
|
||||
* \see setMinimumBarWidth()
|
||||
* \see setMaximumBarWidth()
|
||||
*/
|
||||
void setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeMode 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 mSettings.minimumBarWidth(); }
|
||||
|
||||
/**
|
||||
* 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 minWidth );
|
||||
|
||||
/**
|
||||
* 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 mSettings.maximumBarWidth(); }
|
||||
|
||||
/**
|
||||
* 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 maxWidth );
|
||||
|
||||
/**
|
||||
* Returns the number of map units per scale bar unit used by the scalebar.
|
||||
* \see setMapUnitsPerScaleBarUnit()
|
||||
*/
|
||||
double mapUnitsPerScaleBarUnit() const { return mSettings.mapUnitsPerScaleBarUnit(); }
|
||||
|
||||
/**
|
||||
* Sets the number of map \a units per scale bar unit used by the scalebar.
|
||||
* \see mapUnitsPerScaleBarUnit()
|
||||
*/
|
||||
void setMapUnitsPerScaleBarUnit( double units ) { mSettings.setMapUnitsPerScaleBarUnit( units ); }
|
||||
|
||||
/**
|
||||
* Returns the label for units.
|
||||
* \see setUnitLabel()
|
||||
*/
|
||||
QString unitLabel() const { return mSettings.unitLabel(); }
|
||||
|
||||
/**
|
||||
* Sets the \a label for units.
|
||||
* \see unitLabel()
|
||||
*/
|
||||
void setUnitLabel( const QString &label ) { mSettings.setUnitLabel( label );}
|
||||
|
||||
/**
|
||||
* Returns the font used for drawing text in the scalebar.
|
||||
* \see setFont()
|
||||
*/
|
||||
QFont font() const;
|
||||
|
||||
/**
|
||||
* Sets the \a font used for drawing text in the scalebar.
|
||||
* \see setFont()
|
||||
*/
|
||||
void setFont( const QFont &font );
|
||||
|
||||
/**
|
||||
* Returns the color used for drawing text in the scalebar.
|
||||
* \see setFontColor()
|
||||
* \see font()
|
||||
*/
|
||||
QColor fontColor() const { return mSettings.fontColor(); }
|
||||
|
||||
/**
|
||||
* Sets the \a color used for drawing text in the scalebar.
|
||||
* \see fontColor()
|
||||
* \see setFont()
|
||||
*/
|
||||
void setFontColor( const QColor &color ) { mSettings.setFontColor( color ); }
|
||||
|
||||
/**
|
||||
* Returns the color used for fills in the scalebar.
|
||||
* \see setFillColor()
|
||||
* \see fillColor2()
|
||||
*/
|
||||
QColor fillColor() const { return mSettings.fillColor(); }
|
||||
|
||||
/**
|
||||
* Sets the \a color used for fills in the scalebar.
|
||||
* \see fillColor()
|
||||
* \see setFillColor2()
|
||||
*/
|
||||
void setFillColor( const QColor &color ) { mSettings.setFillColor( color ); }
|
||||
|
||||
/**
|
||||
* Returns the secondary color used for fills in the scalebar.
|
||||
* \see setFillColor2()
|
||||
* \see fillColor()
|
||||
*/
|
||||
QColor fillColor2() const { return mSettings.fillColor2(); }
|
||||
|
||||
/**
|
||||
* Sets the secondary \a color used for fills in the scalebar.
|
||||
* \see fillColor2()
|
||||
* \see setFillColor2()
|
||||
*/
|
||||
void setFillColor2( const QColor &color ) { mSettings.setFillColor2( color ); }
|
||||
|
||||
/**
|
||||
* Returns the color used for lines in the scalebar.
|
||||
* \see setLineColor()
|
||||
*/
|
||||
QColor lineColor() const { return mSettings.lineColor(); }
|
||||
|
||||
/**
|
||||
* Sets the \a color used for lines in the scalebar.
|
||||
* \see lineColor()
|
||||
*/
|
||||
void setLineColor( const QColor &color ) { mSettings.setLineColor( color ); }
|
||||
|
||||
/**
|
||||
* Returns the line width in millimeters for lines in the scalebar.
|
||||
* \see setLineWidth()
|
||||
*/
|
||||
double lineWidth() const { return mSettings.lineWidth(); }
|
||||
|
||||
/**
|
||||
* Sets the line \a width in millimeters for lines in the scalebar.
|
||||
* \see lineWidth()
|
||||
*/
|
||||
void setLineWidth( double width ) { mSettings.setLineWidth( width ); }
|
||||
|
||||
/**
|
||||
* Returns the pen used for drawing outlines in the scalebar.
|
||||
* \see setPen()
|
||||
* \see brush()
|
||||
*/
|
||||
QPen pen() const { return mSettings.pen(); }
|
||||
|
||||
/**
|
||||
* Returns the primary brush for the scalebar.
|
||||
* \returns QBrush used for filling the scalebar
|
||||
* \see setBrush
|
||||
* \see brush2
|
||||
* \see pen
|
||||
*/
|
||||
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.
|
||||
* \returns QBrush used for secondary color areas
|
||||
* \see setBrush2
|
||||
* \see brush
|
||||
*/
|
||||
QBrush brush2() const {return mSettings.brush2(); }
|
||||
|
||||
/**
|
||||
* Returns the scalebar height (in millimeters).
|
||||
* \see setHeight()
|
||||
*/
|
||||
double height() const { return mSettings.height(); }
|
||||
|
||||
/**
|
||||
* Sets the scalebar \a height (in millimeters).
|
||||
* \see height()
|
||||
*/
|
||||
void setHeight( double height ) { mSettings.setHeight( height ); }
|
||||
|
||||
/**
|
||||
* Sets the \a map item linked to the scalebar.
|
||||
* \see map()
|
||||
*/
|
||||
void setMap( QgsLayoutItemMap *map );
|
||||
|
||||
/**
|
||||
* Returns the map item linked to the scalebar.
|
||||
* \see setMap()
|
||||
*/
|
||||
QgsLayoutItemMap *map() const { return mMap; }
|
||||
|
||||
/**
|
||||
* Returns the spacing (in millimeters) between labels and the scalebar.
|
||||
* \see setLabelBarSpace()
|
||||
*/
|
||||
double labelBarSpace() const { return mSettings.labelBarSpace(); }
|
||||
|
||||
/**
|
||||
* Sets the spacing (in millimeters) between labels and the scalebar.
|
||||
* \see labelBarSpace()
|
||||
*/
|
||||
void setLabelBarSpace( double space ) {mSettings.setLabelBarSpace( space );}
|
||||
|
||||
/**
|
||||
* Returns the spacing (margin) between the scalebar box and content in millimeters.
|
||||
* \see setBoxContentSpace()
|
||||
*/
|
||||
double boxContentSpace() const { return mSettings.boxContentSpace(); }
|
||||
|
||||
/**
|
||||
* Sets the \a space (margin) between the scalebar box and content in millimeters.
|
||||
* \see boxContentSpace()
|
||||
*/
|
||||
void setBoxContentSpace( double space );
|
||||
|
||||
/**
|
||||
* Returns the scalebar alignment.
|
||||
* \see setAlignment()
|
||||
*/
|
||||
QgsScaleBarSettings::Alignment alignment() const { return mSettings.alignment(); }
|
||||
|
||||
/**
|
||||
* Sets the scalebar \a alignment.
|
||||
* \see alignment()
|
||||
*/
|
||||
void setAlignment( QgsScaleBarSettings::Alignment alignment );
|
||||
|
||||
/**
|
||||
* Returns the distance units used by the scalebar.
|
||||
* \see setUnits()
|
||||
*/
|
||||
QgsUnitTypes::DistanceUnit units() const { return mSettings.units(); }
|
||||
|
||||
/**
|
||||
* Sets the distance \a units used by the scalebar.
|
||||
* \see units()
|
||||
*/
|
||||
void setUnits( QgsUnitTypes::DistanceUnit units );
|
||||
|
||||
/**
|
||||
* Returns the join style used for drawing lines in the scalebar.
|
||||
* \see setLineJoinStyle()
|
||||
*/
|
||||
Qt::PenJoinStyle lineJoinStyle() const { return mSettings.lineJoinStyle(); }
|
||||
|
||||
/**
|
||||
* Sets the join \a style used when drawing the lines in the scalebar
|
||||
* \see lineJoinStyle()
|
||||
*/
|
||||
void setLineJoinStyle( Qt::PenJoinStyle style );
|
||||
|
||||
/**
|
||||
* Returns the cap style used for drawing lines in the scalebar.
|
||||
* \see setLineCapStyle()
|
||||
*/
|
||||
Qt::PenCapStyle lineCapStyle() const { return mSettings.lineCapStyle(); }
|
||||
|
||||
/**
|
||||
* Sets the cap \a style used when drawing the lines in the scalebar.
|
||||
* \see lineCapStyle()
|
||||
*/
|
||||
void setLineCapStyle( Qt::PenCapStyle style );
|
||||
|
||||
/**
|
||||
* Applies the default scalebar settings to the scale bar.
|
||||
* \see applyDefaultSize()
|
||||
*/
|
||||
void applyDefaultSettings();
|
||||
|
||||
/**
|
||||
* Applies the default size to the scale bar (scale bar 1/5 of map item width)
|
||||
* \see applyDefaultSettings()
|
||||
*/
|
||||
void applyDefaultSize( QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceMeters );
|
||||
|
||||
/**
|
||||
* Sets the scale bar style by \a name.
|
||||
*
|
||||
* The \a name parameter gives the (untranslated) style name.
|
||||
* Possibilities are: 'Single Box', 'Double Box', 'Line Ticks Middle',
|
||||
* 'Line Ticks Down', 'Line Ticks Up', 'Numeric'
|
||||
*
|
||||
* \see style()
|
||||
*/
|
||||
void setStyle( const QString &name );
|
||||
|
||||
/**
|
||||
* Returns the scale bar style name.
|
||||
* \see setStyle()
|
||||
*/
|
||||
QString style() const;
|
||||
|
||||
/**
|
||||
* Sets the scale bar box size to a size suitable for the scalebar content.
|
||||
*/
|
||||
void adjustBoxSize();
|
||||
|
||||
/**
|
||||
* Adjusts the scale bar box size and updates the item.
|
||||
*/
|
||||
void update();
|
||||
#if 0 //TODO
|
||||
//overridden to apply minimum size
|
||||
void setSceneRect( const QRectF &rectangle ) override;
|
||||
#endif
|
||||
void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties ) override;
|
||||
|
||||
protected:
|
||||
|
||||
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
|
||||
bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
|
||||
bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
|
||||
|
||||
private slots:
|
||||
void updateSegmentSize();
|
||||
//! Sets mCompositionMap to 0 if the map is deleted
|
||||
void invalidateCurrentMap();
|
||||
|
||||
private:
|
||||
|
||||
//! Linked map
|
||||
QgsLayoutItemMap *mMap = nullptr;
|
||||
|
||||
QgsScaleBarSettings mSettings;
|
||||
|
||||
//! Scalebar style
|
||||
QgsScaleBarRenderer *mStyle = nullptr;
|
||||
|
||||
//! Width of a segment (in mm)
|
||||
double mSegmentMillimeters;
|
||||
|
||||
//! Moves scalebar position to the left / right depending on alignment and change in item width
|
||||
void correctXPositionAlignment( double width, double widthAfter );
|
||||
|
||||
//! 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 //QGSLAYOUTITEMSCALEBAR_H
|
||||
|
||||
|
@ -138,7 +138,7 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
|
||||
|
||||
// it's possible (in certain circumstances, e.g. when adding frame items) that this item
|
||||
// has already been added to the layout
|
||||
if ( item->layout() != layout() )
|
||||
if ( item->scene() != layout() )
|
||||
layout()->addLayoutItem( item );
|
||||
layout()->setSelectedItem( item );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user