diff --git a/python/core/layout/qgslayoutitem.sip b/python/core/layout/qgslayoutitem.sip index 3b6ce6c4330..ea914223f3a 100644 --- a/python/core/layout/qgslayoutitem.sip +++ b/python/core/layout/qgslayoutitem.sip @@ -105,6 +105,20 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt UndoLegendGroupFont, UndoLegendLayerFont, UndoLegendItemFont, + UndoScaleBarLineWidth, + UndoScaleBarSegmentSize, + UndoScaleBarSegmentsLeft, + UndoScaleBarSegments, + UndoScaleBarHeight, + UndoScaleBarFontColor, + UndoScaleBarFillColor, + UndoScaleBarFillColor2, + UndoScaleBarStrokeColor, + UndoScaleBarUnitText, + UndoScaleBarMapUnitsSegment, + UndoScaleBarLabelBarSize, + UndoScaleBarBoxContentSpace, + UndoCustomCommand, }; diff --git a/python/core/layout/qgslayoutitemscalebar.sip b/python/core/layout/qgslayoutitemscalebar.sip index 2e0e513ff3b..fd9b0cd1ec6 100644 --- a/python/core/layout/qgslayoutitemscalebar.sip +++ b/python/core/layout/qgslayoutitemscalebar.sip @@ -24,7 +24,6 @@ class QgsLayoutItemScaleBar: QgsLayoutItem %Docstring Constructor for QgsLayoutItemScaleBar, with the specified parent ``layout``. %End - ~QgsLayoutItemScaleBar(); virtual int type() const; @@ -38,6 +37,8 @@ class QgsLayoutItemScaleBar: QgsLayoutItem The caller takes responsibility for deleting the returned object. :rtype: QgsLayoutItemScaleBar %End + virtual QgsLayoutSize minimumSize() const; + int numberOfSegments() const; %Docstring @@ -413,15 +414,11 @@ class QgsLayoutItemScaleBar: QgsLayoutItem :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 ); diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 2fe4656fbf6..9bc3de32a8f 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -193,6 +193,7 @@ SET(QGIS_APP_SRCS layout/qgslayoutpolygonwidget.cpp layout/qgslayoutpolylinewidget.cpp layout/qgslayoutpropertieswidget.cpp + layout/qgslayoutscalebarwidget.cpp layout/qgslayoutshapewidget.cpp locator/qgsinbuiltlocatorfilters.cpp @@ -402,6 +403,7 @@ SET (QGIS_APP_MOC_HDRS layout/qgslayoutpolygonwidget.h layout/qgslayoutpolylinewidget.h layout/qgslayoutpropertieswidget.h + layout/qgslayoutscalebarwidget.h layout/qgslayoutshapewidget.h locator/qgsinbuiltlocatorfilters.h diff --git a/src/app/layout/qgslayoutapputils.cpp b/src/app/layout/qgslayoutapputils.cpp index 1d17f319fb6..a61882b2bd0 100644 --- a/src/app/layout/qgslayoutapputils.cpp +++ b/src/app/layout/qgslayoutapputils.cpp @@ -37,6 +37,7 @@ #include "qgslayoutframe.h" #include "qgslayoutitemhtml.h" #include "qgslayouthtmlwidget.h" +#include "qgslayoutscalebarwidget.h" #include "qgisapp.h" #include "qgsmapcanvas.h" @@ -143,10 +144,10 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes() // scalebar item - auto scalebarItemMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddScalebar.svg" ) ), + auto scalebarItemMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleBar.svg" ) ), [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget * { - return nullptr;//new QgsLayoutLegendWidget( qobject_cast< QgsLayoutItemLegend * >( item ) ); + return new QgsLayoutScaleBarWidget( qobject_cast< QgsLayoutItemScaleBar * >( item ) ); }, createRubberBand ); scalebarItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item ) { diff --git a/src/app/layout/qgslayoutscalebarwidget.cpp b/src/app/layout/qgslayoutscalebarwidget.cpp new file mode 100644 index 00000000000..6f3e8ca1d20 --- /dev/null +++ b/src/app/layout/qgslayoutscalebarwidget.cpp @@ -0,0 +1,731 @@ +/*************************************************************************** + qgslayoutscalebarwidget.cpp + ----------------------------- + begin : 11 June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco dot hugentobler at karto dot baug dot ethz dot 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 "qgslayoutscalebarwidget.h" +#include "qgslayoutitemmap.h" +#include "qgslayoutitemscalebar.h" +#include "qgslayout.h" +#include "qgsguiutils.h" +#include +#include +#include + +QgsLayoutScaleBarWidget::QgsLayoutScaleBarWidget( QgsLayoutItemScaleBar *scaleBar ) + : QgsLayoutItemBaseWidget( nullptr, scaleBar ) + , mScalebar( scaleBar ) +{ + setupUi( this ); + connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mHeightSpinBox_valueChanged ); + connect( mLineWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mLineWidthSpinBox_valueChanged ); + connect( mSegmentSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mSegmentSizeSpinBox_valueChanged ); + connect( mSegmentsLeftSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mSegmentsLeftSpinBox_valueChanged ); + connect( mNumberOfSegmentsSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mNumberOfSegmentsSpinBox_valueChanged ); + connect( mUnitLabelLineEdit, &QLineEdit::textChanged, this, &QgsLayoutScaleBarWidget::mUnitLabelLineEdit_textChanged ); + connect( mMapUnitsPerBarUnitSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMapUnitsPerBarUnitSpinBox_valueChanged ); + connect( mFontColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutScaleBarWidget::mFontColorButton_colorChanged ); + connect( mFillColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutScaleBarWidget::mFillColorButton_colorChanged ); + connect( mFillColor2Button, &QgsColorButton::colorChanged, this, &QgsLayoutScaleBarWidget::mFillColor2Button_colorChanged ); + connect( mStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutScaleBarWidget::mStrokeColorButton_colorChanged ); + connect( mStyleComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mStyleComboBox_currentIndexChanged ); + connect( mLabelBarSpaceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mLabelBarSpaceSpinBox_valueChanged ); + connect( mBoxSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mBoxSizeSpinBox_valueChanged ); + connect( mAlignmentComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mAlignmentComboBox_currentIndexChanged ); + connect( mUnitsComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mUnitsComboBox_currentIndexChanged ); + connect( mLineJoinStyleCombo, static_cast( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mLineJoinStyleCombo_currentIndexChanged ); + connect( mLineCapStyleCombo, static_cast( &QComboBox::currentIndexChanged ), this, &QgsLayoutScaleBarWidget::mLineCapStyleCombo_currentIndexChanged ); + connect( mMinWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMinWidthSpinBox_valueChanged ); + connect( mMaxWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutScaleBarWidget::mMaxWidthSpinBox_valueChanged ); + setPanelTitle( tr( "Scalebar properties" ) ); + + mFontButton->setMode( QgsFontButton::ModeQFont ); + + connectUpdateSignal(); + + //add widget for general composer item properties + mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, scaleBar ); + mainLayout->addWidget( mItemPropertiesWidget ); + + mSegmentSizeRadioGroup.addButton( mFixedSizeRadio ); + mSegmentSizeRadioGroup.addButton( mFitWidthRadio ); + connect( &mSegmentSizeRadioGroup, static_cast < void ( QButtonGroup::* )( QAbstractButton * ) > ( &QButtonGroup::buttonClicked ), this, &QgsLayoutScaleBarWidget::segmentSizeRadioChanged ); + + blockMemberSignals( true ); + + //style combo box + mStyleComboBox->insertItem( 0, tr( "Single Box" ) ); + mStyleComboBox->insertItem( 1, tr( "Double Box" ) ); + mStyleComboBox->insertItem( 2, tr( "Line Ticks Middle" ) ); + mStyleComboBox->insertItem( 3, tr( "Line Ticks Down" ) ); + mStyleComboBox->insertItem( 4, tr( "Line Ticks Up" ) ); + mStyleComboBox->insertItem( 5, tr( "Numeric" ) ); + + //alignment combo box + mAlignmentComboBox->insertItem( 0, tr( "Left" ) ); + mAlignmentComboBox->insertItem( 1, tr( "Middle" ) ); + mAlignmentComboBox->insertItem( 2, tr( "Right" ) ); + + //units combo box + 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->setAllowOpacity( true ); + mFillColorButton->setContext( QStringLiteral( "composer" ) ); + mFillColorButton->setNoColorString( tr( "Transparent Fill" ) ); + mFillColorButton->setShowNoColor( true ); + + mFillColor2Button->setColorDialogTitle( tr( "Select Alternate Fill Color" ) ); + mFillColor2Button->setAllowOpacity( true ); + mFillColor2Button->setContext( QStringLiteral( "composer" ) ); + mFillColor2Button->setNoColorString( tr( "Transparent fill" ) ); + mFillColor2Button->setShowNoColor( true ); + + mFontColorButton->setColorDialogTitle( tr( "Select Font Color" ) ); + mFontColorButton->setAllowOpacity( true ); + mFontColorButton->setContext( QStringLiteral( "composer" ) ); + + mStrokeColorButton->setColorDialogTitle( tr( "Select Line Color" ) ); + mStrokeColorButton->setAllowOpacity( true ); + mStrokeColorButton->setContext( QStringLiteral( "composer" ) ); + mStrokeColorButton->setNoColorString( tr( "Transparent line" ) ); + mStrokeColorButton->setShowNoColor( true ); + + if ( mScalebar ) + { + mFillColorDDBtn->registerExpressionContextGenerator( mScalebar ); + mFillColor2DDBtn->registerExpressionContextGenerator( mScalebar ); + mLineColorDDBtn->registerExpressionContextGenerator( mScalebar ); + mLineWidthDDBtn->registerExpressionContextGenerator( mScalebar ); + QgsLayout *scaleBarLayout = mScalebar->layout(); + if ( scaleBarLayout ) + { + mMapItemComboBox->setCurrentLayout( scaleBarLayout ); + mMapItemComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap ); + } + } + + connect( mMapItemComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutScaleBarWidget::mapChanged ); + + registerDataDefinedButton( mFillColorDDBtn, QgsLayoutObject::ScalebarFillColor ); + registerDataDefinedButton( mFillColor2DDBtn, QgsLayoutObject::ScalebarFillColor2 ); + registerDataDefinedButton( mLineColorDDBtn, QgsLayoutObject::ScalebarLineColor ); + registerDataDefinedButton( mLineWidthDDBtn, QgsLayoutObject::ScalebarLineWidth ); + + blockMemberSignals( false ); + setGuiElements(); //set the GUI elements to the state of scaleBar + + connect( mFontButton, &QgsFontButton::changed, this, &QgsLayoutScaleBarWidget::fontChanged ); +} + +bool QgsLayoutScaleBarWidget::setNewItem( QgsLayoutItem *item ) +{ + if ( item->type() != QgsLayoutItemRegistry::LayoutScaleBar ) + return false; + + disconnectUpdateSignal(); + + mScalebar = qobject_cast< QgsLayoutItemScaleBar * >( item ); + mItemPropertiesWidget->setItem( mScalebar ); + + if ( mScalebar ) + { + connectUpdateSignal(); + mFillColorDDBtn->registerExpressionContextGenerator( mScalebar ); + mFillColor2DDBtn->registerExpressionContextGenerator( mScalebar ); + mLineColorDDBtn->registerExpressionContextGenerator( mScalebar ); + mLineWidthDDBtn->registerExpressionContextGenerator( mScalebar ); + } + + setGuiElements(); + + return true; +} + +void QgsLayoutScaleBarWidget::setGuiElements() +{ + if ( !mScalebar ) + { + return; + } + + blockMemberSignals( true ); + mNumberOfSegmentsSpinBox->setValue( mScalebar->numberOfSegments() ); + mSegmentsLeftSpinBox->setValue( mScalebar->numberOfSegmentsLeft() ); + mSegmentSizeSpinBox->setValue( mScalebar->unitsPerSegment() ); + mLineWidthSpinBox->setValue( mScalebar->lineWidth() ); + mHeightSpinBox->setValue( mScalebar->height() ); + mMapUnitsPerBarUnitSpinBox->setValue( mScalebar->mapUnitsPerScaleBarUnit() ); + mLabelBarSpaceSpinBox->setValue( mScalebar->labelBarSpace() ); + mBoxSizeSpinBox->setValue( mScalebar->boxContentSpace() ); + mUnitLabelLineEdit->setText( mScalebar->unitLabel() ); + mLineJoinStyleCombo->setPenJoinStyle( mScalebar->lineJoinStyle() ); + mLineCapStyleCombo->setPenCapStyle( mScalebar->lineCapStyle() ); + mFontColorButton->setColor( mScalebar->fontColor() ); + mFillColorButton->setColor( mScalebar->fillColor() ); + mFillColor2Button->setColor( mScalebar->fillColor2() ); + mStrokeColorButton->setColor( mScalebar->lineColor() ); + mFontButton->setCurrentFont( mScalebar->font() ); + + //map combo box + mMapItemComboBox->setItem( mScalebar->map() ); + + //style... + QString style = mScalebar->style(); + mStyleComboBox->setCurrentIndex( mStyleComboBox->findText( tr( style.toLocal8Bit().data() ) ) ); + toggleStyleSpecificControls( style ); + + //alignment + mAlignmentComboBox->setCurrentIndex( ( int )( mScalebar->alignment() ) ); + + //units + mUnitsComboBox->setCurrentIndex( mUnitsComboBox->findData( ( int )mScalebar->units() ) ); + + if ( mScalebar->segmentSizeMode() == QgsScaleBarSettings::SegmentSizeFixed ) + { + mFixedSizeRadio->setChecked( true ); + mSegmentSizeSpinBox->setEnabled( true ); + mMinWidthSpinBox->setEnabled( false ); + mMaxWidthSpinBox->setEnabled( false ); + } + else /*if(mComposerScaleBar->segmentSizeMode() == QgsComposerScaleBar::SegmentSizeFitWidth)*/ + { + mFitWidthRadio->setChecked( true ); + mSegmentSizeSpinBox->setEnabled( false ); + mMinWidthSpinBox->setEnabled( true ); + mMaxWidthSpinBox->setEnabled( true ); + } + mMinWidthSpinBox->setValue( mScalebar->minimumBarWidth() ); + mMaxWidthSpinBox->setValue( mScalebar->maximumBarWidth() ); + updateDataDefinedButton( mFillColorDDBtn ); + updateDataDefinedButton( mFillColor2DDBtn ); + updateDataDefinedButton( mLineColorDDBtn ); + updateDataDefinedButton( mLineWidthDDBtn ); + blockMemberSignals( false ); +} + +//slots + +void QgsLayoutScaleBarWidget::mLineWidthSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Line Width" ), QgsLayoutItem::UndoScaleBarLineWidth ); + disconnectUpdateSignal(); + mScalebar->setLineWidth( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mSegmentSizeSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Segment Size" ), QgsLayoutItem::UndoScaleBarSegmentSize ); + disconnectUpdateSignal(); + mScalebar->setUnitsPerSegment( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mSegmentsLeftSpinBox_valueChanged( int i ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Segments" ), QgsLayoutItem::UndoScaleBarSegmentsLeft ); + disconnectUpdateSignal(); + mScalebar->setNumberOfSegmentsLeft( i ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mNumberOfSegmentsSpinBox_valueChanged( int i ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Segments" ), QgsLayoutItem::UndoScaleBarSegments ); + disconnectUpdateSignal(); + mScalebar->setNumberOfSegments( i ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mHeightSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + mScalebar->beginCommand( tr( "Set Scalebar Height" ), QgsLayoutItem::UndoScaleBarHeight ); + disconnectUpdateSignal(); + mScalebar->setHeight( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::fontChanged() +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Font" ) ); + disconnectUpdateSignal(); + mScalebar->setFont( mFontButton->currentFont() ); + connectUpdateSignal(); + mScalebar->endCommand(); + mScalebar->update(); +} + +void QgsLayoutScaleBarWidget::mFontColorButton_colorChanged( const QColor &newColor ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Font Color" ), QgsLayoutItem::UndoScaleBarFontColor ); + disconnectUpdateSignal(); + mScalebar->setFontColor( newColor ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mFillColorButton_colorChanged( const QColor &newColor ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Fill Color" ), QgsLayoutItem::UndoScaleBarFillColor ); + disconnectUpdateSignal(); + mScalebar->setFillColor( newColor ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mFillColor2Button_colorChanged( const QColor &newColor ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Fill Color" ), QgsLayoutItem::UndoScaleBarFillColor2 ); + disconnectUpdateSignal(); + mScalebar->setFillColor2( newColor ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mStrokeColorButton_colorChanged( const QColor &newColor ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Stroke Color" ), QgsLayoutItem::UndoScaleBarStrokeColor ); + disconnectUpdateSignal(); + mScalebar->setLineColor( newColor ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mUnitLabelLineEdit_textChanged( const QString &text ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Unit Text" ), QgsLayoutItem::UndoScaleBarUnitText ); + disconnectUpdateSignal(); + mScalebar->setUnitLabel( text ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mMapUnitsPerBarUnitSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Map Units per Segment" ), QgsLayoutItem::UndoScaleBarMapUnitsSegment ); + disconnectUpdateSignal(); + mScalebar->setMapUnitsPerScaleBarUnit( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mStyleComboBox_currentIndexChanged( const QString &text ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Style" ) ); + disconnectUpdateSignal(); + QString untranslatedStyleName; + if ( text == tr( "Single Box" ) ) + { + untranslatedStyleName = QStringLiteral( "Single Box" ); + } + else if ( text == tr( "Double Box" ) ) + { + untranslatedStyleName = QStringLiteral( "Double Box" ); + } + else if ( text == tr( "Line Ticks Middle" ) ) + { + untranslatedStyleName = QStringLiteral( "Line Ticks Middle" ); + } + else if ( text == tr( "Line Ticks Middle" ) ) + { + untranslatedStyleName = QStringLiteral( "Line Ticks Middle" ); + } + else if ( text == tr( "Line Ticks Down" ) ) + { + untranslatedStyleName = QStringLiteral( "Line Ticks Down" ); + } + else if ( text == tr( "Line Ticks Up" ) ) + { + untranslatedStyleName = QStringLiteral( "Line Ticks Up" ); + } + else if ( text == tr( "Numeric" ) ) + { + untranslatedStyleName = QStringLiteral( "Numeric" ); + } + + //disable or enable controls which apply to specific scale bar styles + toggleStyleSpecificControls( untranslatedStyleName ); + + mScalebar->setStyle( untranslatedStyleName ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::toggleStyleSpecificControls( const QString &style ) +{ + if ( style == QLatin1String( "Numeric" ) ) + { + //Disable controls which don't apply to numeric scale bars + mGroupBoxUnits->setEnabled( false ); + mGroupBoxUnits->setCollapsed( true ); + mGroupBoxSegments->setEnabled( false ); + mGroupBoxSegments->setCollapsed( true ); + mLabelBarSpaceSpinBox->setEnabled( false ); + mLineWidthSpinBox->setEnabled( false ); + mFillColorButton->setEnabled( false ); + mFillColor2Button->setEnabled( false ); + mStrokeColorButton->setEnabled( false ); + mLineJoinStyleCombo->setEnabled( false ); + mLineCapStyleCombo->setEnabled( false ); + } + else + { + //Enable controls + mGroupBoxUnits->setEnabled( true ); + mGroupBoxSegments->setEnabled( true ); + mLabelBarSpaceSpinBox->setEnabled( true ); + mLineWidthSpinBox->setEnabled( true ); + mFillColorButton->setEnabled( true ); + mFillColor2Button->setEnabled( true ); + mStrokeColorButton->setEnabled( true ); + if ( style == QLatin1String( "Single Box" ) || style == QLatin1String( "Double Box" ) ) + { + mLineJoinStyleCombo->setEnabled( true ); + mLineCapStyleCombo->setEnabled( false ); + } + else + { + mLineJoinStyleCombo->setEnabled( false ); + mLineCapStyleCombo->setEnabled( true ); + } + + } +} + +void QgsLayoutScaleBarWidget::mLabelBarSpaceSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Label Space" ), QgsLayoutItem::UndoScaleBarLabelBarSize ); + disconnectUpdateSignal(); + mScalebar->setLabelBarSpace( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mBoxSizeSpinBox_valueChanged( double d ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Box Space" ), QgsLayoutItem::UndoScaleBarBoxContentSpace ); + disconnectUpdateSignal(); + mScalebar->setBoxContentSpace( d ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mAlignmentComboBox_currentIndexChanged( int index ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Alignment" ) ); + disconnectUpdateSignal(); + mScalebar->setAlignment( ( QgsScaleBarSettings::Alignment ) index ); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mUnitsComboBox_currentIndexChanged( int index ) +{ + if ( !mScalebar ) + { + return; + } + + QVariant unitData = mUnitsComboBox->itemData( index ); + if ( unitData.type() == QVariant::Invalid ) + { + return; + } + + disconnectUpdateSignal(); + mScalebar->setUnits( ( QgsUnitTypes::DistanceUnit )unitData.toInt() ); + switch ( mUnitsComboBox->currentIndex() ) + { + case 0: + { + mScalebar->beginCommand( tr( "Set Scalebar Units" ) ); + mScalebar->applyDefaultSize( QgsUnitTypes::DistanceUnknownUnit ); + break; + } + case 2: + { + mScalebar->beginCommand( tr( "Set Scalebar Units" ) ); + mScalebar->applyDefaultSize( QgsUnitTypes::DistanceFeet ); + break; + } + case 3: + { + mScalebar->beginCommand( tr( "Set Scalebar Units" ) ); + mScalebar->applyDefaultSize( QgsUnitTypes::DistanceNauticalMiles ); + break; + } + case 1: + default: + { + mScalebar->beginCommand( tr( "Set Scalebar Units" ) ); + mScalebar->applyDefaultSize( QgsUnitTypes::DistanceMeters ); + break; + } + } + + mScalebar->update(); + + mUnitLabelLineEdit->setText( mScalebar->unitLabel() ); + mSegmentSizeSpinBox->setValue( mScalebar->unitsPerSegment() ); + mMapUnitsPerBarUnitSpinBox->setValue( mScalebar->mapUnitsPerScaleBarUnit() ); + + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::blockMemberSignals( bool block ) +{ + mSegmentSizeSpinBox->blockSignals( block ); + mNumberOfSegmentsSpinBox->blockSignals( block ); + mSegmentsLeftSpinBox->blockSignals( block ); + mStyleComboBox->blockSignals( block ); + mUnitLabelLineEdit->blockSignals( block ); + mMapUnitsPerBarUnitSpinBox->blockSignals( block ); + mHeightSpinBox->blockSignals( block ); + mLineWidthSpinBox->blockSignals( block ); + mLabelBarSpaceSpinBox->blockSignals( block ); + mBoxSizeSpinBox->blockSignals( block ); + mAlignmentComboBox->blockSignals( block ); + mUnitsComboBox->blockSignals( block ); + mLineJoinStyleCombo->blockSignals( block ); + mLineCapStyleCombo->blockSignals( block ); + mFontColorButton->blockSignals( block ); + mFillColorButton->blockSignals( block ); + mFillColor2Button->blockSignals( block ); + mStrokeColorButton->blockSignals( block ); + mSegmentSizeRadioGroup.blockSignals( block ); + mMapItemComboBox->blockSignals( block ); + mFontButton->blockSignals( block ); + mMinWidthSpinBox->blockSignals( block ); + mMaxWidthSpinBox->blockSignals( block ); +} + +void QgsLayoutScaleBarWidget::connectUpdateSignal() +{ + if ( mScalebar ) + { + connect( mScalebar, &QgsLayoutObject::changed, this, &QgsLayoutScaleBarWidget::setGuiElements ); + } +} + +void QgsLayoutScaleBarWidget::disconnectUpdateSignal() +{ + if ( mScalebar ) + { + disconnect( mScalebar, &QgsLayoutObject::changed, this, &QgsLayoutScaleBarWidget::setGuiElements ); + } +} + +void QgsLayoutScaleBarWidget::mLineJoinStyleCombo_currentIndexChanged( int index ) +{ + Q_UNUSED( index ); + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Join Style" ) ); + mScalebar->setLineJoinStyle( mLineJoinStyleCombo->penJoinStyle() ); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mLineCapStyleCombo_currentIndexChanged( int index ) +{ + Q_UNUSED( index ); + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Cap Style" ) ); + mScalebar->setLineCapStyle( mLineCapStyleCombo->penCapStyle() ); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::segmentSizeRadioChanged( QAbstractButton *radio ) +{ + bool fixedSizeMode = radio == mFixedSizeRadio; + mMinWidthSpinBox->setEnabled( !fixedSizeMode ); + mMaxWidthSpinBox->setEnabled( !fixedSizeMode ); + mSegmentSizeSpinBox->setEnabled( fixedSizeMode ); + + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize ); + disconnectUpdateSignal(); + if ( mFixedSizeRadio->isChecked() ) + { + mScalebar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFixed ); + mScalebar->setUnitsPerSegment( mSegmentSizeSpinBox->value() ); + } + else /*if(mFitWidthRadio->isChecked())*/ + { + mScalebar->setSegmentSizeMode( QgsScaleBarSettings::SegmentSizeFitWidth ); + } + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mapChanged( QgsLayoutItem *item ) +{ + QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( item ); + if ( !map ) + { + return; + } + + //set it to scale bar + mScalebar->beginCommand( tr( "Set Scalebar Map" ) ); + disconnectUpdateSignal(); + mScalebar->setMap( map ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mMinWidthSpinBox_valueChanged( double ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize ); + disconnectUpdateSignal(); + mScalebar->setMinimumBarWidth( mMinWidthSpinBox->value() ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} + +void QgsLayoutScaleBarWidget::mMaxWidthSpinBox_valueChanged( double ) +{ + if ( !mScalebar ) + { + return; + } + + mScalebar->beginCommand( tr( "Set Scalebar Size Mode" ), QgsLayoutItem::UndoScaleBarSegmentSize ); + disconnectUpdateSignal(); + mScalebar->setMaximumBarWidth( mMaxWidthSpinBox->value() ); + mScalebar->update(); + connectUpdateSignal(); + mScalebar->endCommand(); +} diff --git a/src/app/layout/qgslayoutscalebarwidget.h b/src/app/layout/qgslayoutscalebarwidget.h new file mode 100644 index 00000000000..b478fb07ca1 --- /dev/null +++ b/src/app/layout/qgslayoutscalebarwidget.h @@ -0,0 +1,85 @@ +/*************************************************************************** + qgslayoutscalebarwidget.h + --------------------------- + begin : 11 June 2008 + copyright : (C) 2008 by Marco Hugentobler + email : marco dot hugentobler at karto dot baug dot ethz dot 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 QGSLAYOUTSCALEBARWIDGET_H +#define QGSLAYOUTSCALEBARWIDGET_H + +#include "ui_qgslayoutscalebarwidgetbase.h" +#include "qgslayoutitemwidget.h" + +class QgsLayoutItemScaleBar; + +/** + * \ingroup app + * A widget to define the properties of a QgsLayoutItemScaleBar. + */ +class QgsLayoutScaleBarWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutScaleBarWidgetBase +{ + Q_OBJECT + + public: + explicit QgsLayoutScaleBarWidget( QgsLayoutItemScaleBar *scaleBar ); + + protected: + + bool setNewItem( QgsLayoutItem *item ) override; + + public slots: + + void mHeightSpinBox_valueChanged( double d ); + void mLineWidthSpinBox_valueChanged( double d ); + void mSegmentSizeSpinBox_valueChanged( double d ); + void mSegmentsLeftSpinBox_valueChanged( int i ); + void mNumberOfSegmentsSpinBox_valueChanged( int i ); + void mUnitLabelLineEdit_textChanged( const QString &text ); + void mMapUnitsPerBarUnitSpinBox_valueChanged( double d ); + void mFontColorButton_colorChanged( const QColor &newColor ); + void mFillColorButton_colorChanged( const QColor &newColor ); + void mFillColor2Button_colorChanged( const QColor &newColor ); + void mStrokeColorButton_colorChanged( const QColor &newColor ); + void mStyleComboBox_currentIndexChanged( const QString &text ); + void mLabelBarSpaceSpinBox_valueChanged( double d ); + void mBoxSizeSpinBox_valueChanged( double d ); + void mAlignmentComboBox_currentIndexChanged( int index ); + void mUnitsComboBox_currentIndexChanged( int index ); + void mLineJoinStyleCombo_currentIndexChanged( int index ); + void mLineCapStyleCombo_currentIndexChanged( int index ); + void mMinWidthSpinBox_valueChanged( double d ); + void mMaxWidthSpinBox_valueChanged( double d ); + + private slots: + void setGuiElements(); + void segmentSizeRadioChanged( QAbstractButton *radio ); + void mapChanged( QgsLayoutItem *item ); + void fontChanged(); + + private: + QgsLayoutItemScaleBar *mScalebar = nullptr; + QgsLayoutItemPropertiesWidget *mItemPropertiesWidget = nullptr; + + QButtonGroup mSegmentSizeRadioGroup; + + //! Enables/disables the signals of the input gui elements + void blockMemberSignals( bool enable ); + + //! Enables/disables controls based on scale bar style + void toggleStyleSpecificControls( const QString &style ); + + void connectUpdateSignal(); + void disconnectUpdateSignal(); +}; + +#endif //QGSLAYOUTSCALEBARWIDGET_H diff --git a/src/core/layout/qgslayoutitem.h b/src/core/layout/qgslayoutitem.h index 746a211205a..23bcccdbed5 100644 --- a/src/core/layout/qgslayoutitem.h +++ b/src/core/layout/qgslayoutitem.h @@ -138,6 +138,20 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt UndoLegendGroupFont, //!< Legend group font UndoLegendLayerFont, //!< Legend layer font UndoLegendItemFont, //!< Legend item font + UndoScaleBarLineWidth, //!< Scalebar line width + UndoScaleBarSegmentSize, //!< Scalebar segment size + UndoScaleBarSegmentsLeft, //!< Scalebar segments left + UndoScaleBarSegments, //!< Scalebar number of segments + UndoScaleBarHeight, //!< Scalebar height + UndoScaleBarFontColor, //!< Scalebar font color + UndoScaleBarFillColor, //!< Scalebar fill color + UndoScaleBarFillColor2, //!< Scalebar secondary fill color + UndoScaleBarStrokeColor, //!< Scalebar stroke color + UndoScaleBarUnitText, //!< Scalebar unit text + UndoScaleBarMapUnitsSegment, //!< Scalebar map units per segment + UndoScaleBarLabelBarSize, //!< Scalebar label bar size + UndoScaleBarBoxContentSpace, //!< Scalebar box context space + UndoCustomCommand, //!< Base id for plugin based item undo commands }; diff --git a/src/core/layout/qgslayoutitemregistry.cpp b/src/core/layout/qgslayoutitemregistry.cpp index 00bf92cd61b..96c1e0f1908 100644 --- a/src/core/layout/qgslayoutitemregistry.cpp +++ b/src/core/layout/qgslayoutitemregistry.cpp @@ -60,7 +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( LayoutScaleBar, QStringLiteral( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleBar.svg" ) ), QgsLayoutItemScaleBar::create ) ); addLayoutItemType( new QgsLayoutItemMetadata( LayoutShape, QStringLiteral( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), []( QgsLayout * layout ) { QgsLayoutItemShape *shape = new QgsLayoutItemShape( layout ); diff --git a/src/core/layout/qgslayoutitemscalebar.cpp b/src/core/layout/qgslayoutitemscalebar.cpp index 1263821e872..2a5b43c4c9d 100644 --- a/src/core/layout/qgslayoutitemscalebar.cpp +++ b/src/core/layout/qgslayoutitemscalebar.cpp @@ -42,17 +42,11 @@ QgsLayoutItemScaleBar::QgsLayoutItemScaleBar( QgsLayout *layout ) : QgsLayoutItem( layout ) - , mSegmentMillimeters( 0.0 ) { applyDefaultSettings(); applyDefaultSize(); } -QgsLayoutItemScaleBar::~QgsLayoutItemScaleBar() -{ - delete mStyle; -} - int QgsLayoutItemScaleBar::type() const { return QgsLayoutItemRegistry::LayoutScaleBar; @@ -68,6 +62,11 @@ QgsLayoutItemScaleBar *QgsLayoutItemScaleBar::create( QgsLayout *layout ) return new QgsLayoutItemScaleBar( layout ); } +QgsLayoutSize QgsLayoutItemScaleBar::minimumSize() const +{ + return QgsLayoutSize( mStyle->calculateBoxSize( mSettings, createScaleContext() ), QgsUnitTypes::LayoutMillimeters ); +} + void QgsLayoutItemScaleBar::draw( QgsRenderContext &context, const QStyleOptionGraphicsItem * ) { if ( !mStyle ) @@ -87,6 +86,7 @@ void QgsLayoutItemScaleBar::setNumberOfSegments( int nSegments ) mSettings.setNumberOfSegments( nSegments ); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -102,6 +102,7 @@ void QgsLayoutItemScaleBar::setUnitsPerSegment( double units ) refreshSegmentMillimeters(); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -117,6 +118,7 @@ void QgsLayoutItemScaleBar::setSegmentSizeMode( QgsScaleBarSettings::SegmentSize refreshSegmentMillimeters(); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -132,6 +134,7 @@ void QgsLayoutItemScaleBar::setMinimumBarWidth( double minWidth ) refreshSegmentMillimeters(); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -147,6 +150,7 @@ void QgsLayoutItemScaleBar::setMaximumBarWidth( double maxWidth ) refreshSegmentMillimeters(); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -161,6 +165,7 @@ void QgsLayoutItemScaleBar::setNumberOfSegmentsLeft( int nSegmentsLeft ) mSettings.setNumberOfSegmentsLeft( nSegmentsLeft ); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -175,6 +180,7 @@ void QgsLayoutItemScaleBar::setBoxContentSpace( double space ) mSettings.setBoxContentSpace( space ); double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); correctXPositionAlignment( width, widthAfter ); + refreshItemSize(); emit changed(); } @@ -247,6 +253,7 @@ void QgsLayoutItemScaleBar::refreshDataDefinedProperty( const QgsLayoutObject::D } if ( forceUpdate ) { + refreshItemSize(); update(); } @@ -353,7 +360,7 @@ QgsScaleBarRenderer::ScaleBarContext QgsLayoutItemScaleBar::createScaleContext() void QgsLayoutItemScaleBar::setAlignment( QgsScaleBarSettings::Alignment a ) { mSettings.setAlignment( a ); - update(); + refreshItemSize(); emit changed(); } @@ -361,6 +368,7 @@ void QgsLayoutItemScaleBar::setUnits( QgsUnitTypes::DistanceUnit u ) { mSettings.setUnits( u ); refreshSegmentMillimeters(); + refreshItemSize(); emit changed(); } @@ -391,8 +399,7 @@ void QgsLayoutItemScaleBar::setLineCapStyle( Qt::PenCapStyle style ) void QgsLayoutItemScaleBar::applyDefaultSettings() { //style - delete mStyle; - mStyle = new QgsSingleBoxScaleBarRenderer(); + mStyle = qgis::make_unique< QgsSingleBoxScaleBarRenderer >(); //default to no background setBackgroundEnabled( false ); @@ -409,6 +416,7 @@ void QgsLayoutItemScaleBar::applyDefaultSettings() mSettings.setFont( f ); mSettings.setUnits( QgsUnitTypes::DistanceUnknownUnit ); + refreshItemSize(); emit changed(); } @@ -483,76 +491,16 @@ void QgsLayoutItemScaleBar::applyDefaultSize( QgsUnitTypes::DistanceUnit units ) } refreshSegmentMillimeters(); - adjustBoxSize(); + refreshItemSize(); 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(); + refreshItemSize(); } QgsLayoutItem::update(); } @@ -563,31 +511,31 @@ void QgsLayoutItemScaleBar::updateSegmentSize() { return; } - double width = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + double widthMM = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); refreshSegmentMillimeters(); - double widthAfter = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); - correctXPositionAlignment( width, widthAfter ); + double widthAfterMM = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width(); + correctXPositionAlignment( widthMM, widthAfterMM ); + QgsLayoutSize currentSize = sizeWithUnits(); + currentSize.setWidth( mLayout->context().measurementConverter().convert( QgsLayoutMeasurement( widthAfterMM, QgsUnitTypes::LayoutMillimeters ), currentSize.units() ).length() ); + attemptResize( currentSize ); 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(); + mStyle = qgis::make_unique< QgsSingleBoxScaleBarRenderer >(); } else if ( styleName == QLatin1String( "Double Box" ) ) { - mStyle = new QgsDoubleBoxScaleBarRenderer(); + mStyle = qgis::make_unique< QgsDoubleBoxScaleBarRenderer >(); } else if ( styleName == QLatin1String( "Line Ticks Middle" ) || styleName == QLatin1String( "Line Ticks Down" ) || styleName == QLatin1String( "Line Ticks Up" ) ) { - QgsTicksScaleBarRenderer *tickStyle = new QgsTicksScaleBarRenderer(); + std::unique_ptr< QgsTicksScaleBarRenderer > tickStyle = qgis::make_unique< QgsTicksScaleBarRenderer >(); if ( styleName == QLatin1String( "Line Ticks Middle" ) ) { tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksMiddle ); @@ -600,12 +548,13 @@ void QgsLayoutItemScaleBar::setStyle( const QString &styleName ) { tickStyle->setTickPosition( QgsTicksScaleBarRenderer::TicksUp ); } - mStyle = tickStyle; + mStyle = std::move( tickStyle ); } else if ( styleName == QLatin1String( "Numeric" ) ) { - mStyle = new QgsNumericScaleBarRenderer(); + mStyle = qgis::make_unique< QgsNumericScaleBarRenderer >(); } + refreshItemSize(); emit changed(); } @@ -629,7 +578,7 @@ QFont QgsLayoutItemScaleBar::font() const void QgsLayoutItemScaleBar::setFont( const QFont &font ) { mSettings.setFont( font ); - update(); + refreshItemSize(); emit changed(); } @@ -705,7 +654,7 @@ bool QgsLayoutItemScaleBar::writePropertiesToElement( QDomElement &composerScale return true; } -bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context ) +bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext & ) { mSettings.setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() ); mSettings.setLabelBarSpace( itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble() ); @@ -831,10 +780,8 @@ bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemEl } //style - delete mStyle; - mStyle = nullptr; QString styleString = itemElem.attribute( QStringLiteral( "style" ), QLatin1String( "" ) ); - setStyle( tr( styleString.toLocal8Bit().data() ) ); + setStyle( styleString.toLocal8Bit().data() ); if ( itemElem.attribute( QStringLiteral( "unitType" ) ).isEmpty() ) { @@ -897,23 +844,28 @@ bool QgsLayoutItemScaleBar::readPropertiesFromElement( const QDomElement &itemEl return true; } -void QgsLayoutItemScaleBar::correctXPositionAlignment( double width, double widthAfter ) +void QgsLayoutItemScaleBar::correctXPositionAlignment( double widthMM, double widthAfterMM ) { //Don't adjust position for numeric scale bars: if ( mStyle->name() == QLatin1String( "Numeric" ) ) { return; } -#if 0 //TODO + QgsLayoutPoint currentPos = positionWithUnits(); + + double deltaMM = 0.0; if ( mSettings.alignment() == QgsScaleBarSettings::AlignMiddle ) { - move( -( widthAfter - width ) / 2.0, 0 ); + deltaMM = -( widthAfterMM - widthMM ) / 2.0; } else if ( mSettings.alignment() == QgsScaleBarSettings::AlignRight ) { - move( -( widthAfter - width ), 0 ); + deltaMM = -( widthAfterMM - widthMM ); } -#endif + + double delta = mLayout->context().measurementConverter().convert( QgsLayoutMeasurement( deltaMM, QgsUnitTypes::LayoutMillimeters ), currentPos.units() ).length(); + currentPos.setX( currentPos.x() + delta ); + attemptMove( currentPos ); } diff --git a/src/core/layout/qgslayoutitemscalebar.h b/src/core/layout/qgslayoutitemscalebar.h index d7b1fbb351e..d0433bc04aa 100644 --- a/src/core/layout/qgslayoutitemscalebar.h +++ b/src/core/layout/qgslayoutitemscalebar.h @@ -42,7 +42,6 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem * Constructor for QgsLayoutItemScaleBar, with the specified parent \a layout. */ QgsLayoutItemScaleBar( QgsLayout *layout ); - ~QgsLayoutItemScaleBar(); int type() const override; QString stringType() const override; @@ -53,6 +52,7 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem * The caller takes responsibility for deleting the returned object. */ static QgsLayoutItemScaleBar *create( QgsLayout *layout ) SIP_FACTORY; + QgsLayoutSize minimumSize() const override; /** * Returns the number of segments included in the scalebar. @@ -402,19 +402,11 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem */ 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: @@ -436,13 +428,13 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem QgsScaleBarSettings mSettings; //! Scalebar style - QgsScaleBarRenderer *mStyle = nullptr; + std::unique_ptr< QgsScaleBarRenderer > mStyle; //! Width of a segment (in mm) - double mSegmentMillimeters; + double mSegmentMillimeters = 0.0; //! Moves scalebar position to the left / right depending on alignment and change in item width - void correctXPositionAlignment( double width, double widthAfter ); + void correctXPositionAlignment( double widthMM, double widthAfterMM ); //! Calculates with of a segment in mm and stores it in mSegmentMillimeters void refreshSegmentMillimeters(); diff --git a/src/ui/layout/qgslayoutscalebarwidgetbase.ui b/src/ui/layout/qgslayoutscalebarwidgetbase.ui new file mode 100644 index 00000000000..58ce0041b8a --- /dev/null +++ b/src/ui/layout/qgslayoutscalebarwidgetbase.ui @@ -0,0 +1,778 @@ + + + QgsLayoutScaleBarWidgetBase + + + + 0 + 0 + 456 + 662 + + + + + 0 + 0 + + + + Scalebar Options + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + padding: 2px; font-weight: bold; background-color: rgb(200, 200, 200); + + + Scalebar + + + + + + + true + + + + + 0 + 0 + 440 + 1004 + + + + + + + Qt::StrongFocus + + + Main properties + + + composeritem + + + false + + + + + + + + + + + + St&yle + + + mStyleComboBox + + + + + + + + 0 + 0 + + + + &Map + + + true + + + mMapItemComboBox + + + + + + + + + + Qt::StrongFocus + + + Units + + + composeritem + + + false + + + + + + Scalebar units + + + + + + + &Label for units + + + true + + + mUnitLabelLineEdit + + + + + + + Specifies how many scalebar units per labeled unit. For example, if your scalebar units are set to "meters", a multiplier of 1000 will result in the scalebar labels in kilometers. + + + 6 + + + 9999999999999.000000000000000 + + + false + + + + + + + Text used for labeling the scalebar units, e.g., "m" or "km". This should be matched to reflect the multiplier above. + + + + + + + Specifies the underlying units used for scalebar calculations, e.g., "meters" or "feet" + + + + + + + Label unit multiplier + + + false + + + mMapUnitsPerBarUnitSpinBox + + + + + + + + + + Qt::StrongFocus + + + Segments + + + composeritem + + + false + + + + + + Segments + + + + + + + Number of scalebar units per scalebar segment + + + units + + + 6 + + + 9999999999999.000000000000000 + + + false + + + + + + + Height + + + + + + + + + + right + + + 0 + + + + + + + + + + left + + + + + + + Fi&xed width + + + true + + + + + + + Fit segment width + + + + + + + mm + + + 999.990000000000009 + + + + + + + false + + + mm + + + 999.990000000000009 + + + + + + + false + + + mm + + + 999.990000000000009 + + + + + + + + + + Qt::StrongFocus + + + Display + + + composeritem + + + true + + + + + + + 0 + 0 + + + + + + + mm + + + 0.010000000000000 + + + 0.100000000000000 + + + 0.200000000000000 + + + false + + + + + + + Box margin + + + + + + + Alignment + + + + + + + Labels margin + + + + + + + Line width + + + + + + + Cap style + + + + + + + Join style + + + + + + + + + + + + + + + + + mm + + + + + + + + + + mm + + + + + + + + + + + + + + + + + + + Qt::StrongFocus + + + Fonts and colors + + + composeritem + + + true + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Font color + + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Secondary fill color + + + + + + + Fill color + + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Line color + + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + Font + + + + + + + + + + + + + + + + QgsScrollArea + QScrollArea +
qgsscrollarea.h
+ 1 +
+ + QgsColorButton + QToolButton +
qgscolorbutton.h
+ 1 +
+ + QgsCollapsibleGroupBoxBasic + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+ + QgsDoubleSpinBox + QDoubleSpinBox +
qgsdoublespinbox.h
+
+ + QgsFontButton + QToolButton +
qgsfontbutton.h
+
+ + QgsSpinBox + QSpinBox +
qgsspinbox.h
+
+ + QgsLayoutItemComboBox + QComboBox +
qgslayoutitemcombobox.h
+
+ + QgsPropertyOverrideButton + QToolButton +
qgspropertyoverridebutton.h
+
+ + QgsPenJoinStyleComboBox + QComboBox +
qgspenstylecombobox.h
+
+ + QgsPenCapStyleComboBox + QComboBox +
qgspenstylecombobox.h
+
+
+ + scrollArea + groupBox + mMapItemComboBox + mStyleComboBox + mGroupBoxUnits + mUnitsComboBox + mMapUnitsPerBarUnitSpinBox + mUnitLabelLineEdit + mGroupBoxSegments + mSegmentsLeftSpinBox + mNumberOfSegmentsSpinBox + mFixedSizeRadio + mSegmentSizeSpinBox + mFitWidthRadio + mMinWidthSpinBox + mMaxWidthSpinBox + mHeightSpinBox + groupBox_5 + mBoxSizeSpinBox + mLabelBarSpaceSpinBox + mLineWidthSpinBox + mLineWidthDDBtn + mLineJoinStyleCombo + mLineCapStyleCombo + mAlignmentComboBox + groupBox_4 + mFontButton + mFontColorButton + mFillColorButton + mFillColorDDBtn + mFillColor2Button + mFillColor2DDBtn + mStrokeColorButton + mLineColorDDBtn + + + +