[FEATURE]: alignment (left/middle/right) for composer scale bar to keep bar position when zooming

This commit is contained in:
marco 2011-11-28 21:43:04 +01:00
parent a5b9f92d4e
commit 307b99e24f
8 changed files with 174 additions and 19 deletions

View File

@ -9,6 +9,14 @@ class QgsComposerScaleBar: QgsComposerItem
%End
public:
/**Added in version 1.8*/
enum Alignment
{
Left = 0,
Middle,
Right
};
QgsComposerScaleBar( QgsComposition* composition /TransferThis/);
~QgsComposerScaleBar();
@ -58,6 +66,13 @@ class QgsComposerScaleBar: QgsComposerItem
double segmentMillimeters() const;
/**Left / Middle/ Right
@note: this method was added in version 1.8*/
Alignment alignment() const;
/**@note: this method was added in version 1.8*/
void setAlignment( Alignment a );
/**Apply default settings*/
void applyDefaultSettings();
/**Apply default size (scale bar 1/5 of map item width)

View File

@ -31,12 +31,19 @@ QgsComposerScaleBarWidget::QgsComposerScaleBarWidget( QgsComposerScaleBar* scale
toolBox->addItem( itemPropertiesWidget, tr( "General options" ) );
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" ) );
mAlignmentComboBox->insertItem( 0, tr( "Left" ) );
mAlignmentComboBox->insertItem( 1, tr( "Middle" ) );
mAlignmentComboBox->insertItem( 2, tr( "Right" ) );
setGuiElements(); //set the GUI elements to the state of scaleBar
blockMemberSignals( false );
}
@ -161,6 +168,9 @@ void QgsComposerScaleBarWidget::setGuiElements()
//style...
QString style = mComposerScaleBar->style();
mStyleComboBox->setCurrentIndex( mStyleComboBox->findText( tr( style.toLocal8Bit().data() ) ) );
//alignment
mAlignmentComboBox->setCurrentIndex(( int )( mComposerScaleBar->alignment() ) );
}
//slots
@ -371,6 +381,18 @@ void QgsComposerScaleBarWidget::on_mBoxSizeSpinBox_valueChanged( double d )
mComposerScaleBar->endCommand();
}
void QgsComposerScaleBarWidget::on_mAlignmentComboBox_currentIndexChanged( int index )
{
if ( !mComposerScaleBar )
{
return;
}
mComposerScaleBar->beginCommand( tr( "Scalebar alignment" ) );
mComposerScaleBar->setAlignment(( QgsComposerScaleBar::Alignment ) index );
mComposerScaleBar->endCommand();
}
void QgsComposerScaleBarWidget::blockMemberSignals( bool block )
{
mSegmentSizeSpinBox->blockSignals( block );
@ -384,4 +406,5 @@ void QgsComposerScaleBarWidget::blockMemberSignals( bool block )
mLineWidthSpinBox->blockSignals( block );
mLabelBarSpaceSpinBox->blockSignals( block );
mBoxSizeSpinBox->blockSignals( block );
mAlignmentComboBox->blockSignals( block );
}

View File

@ -46,6 +46,7 @@ class QgsComposerScaleBarWidget: public QWidget, private Ui::QgsComposerScaleBar
void on_mStyleComboBox_currentIndexChanged( const QString& text );
void on_mLabelBarSpaceSpinBox_valueChanged( double d );
void on_mBoxSizeSpinBox_valueChanged( double d );
void on_mAlignmentComboBox_currentIndexChanged( int index );
protected:

View File

@ -28,7 +28,8 @@
#include <QPainter>
#include <cmath>
QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition* composition ): QgsComposerItem( composition ), mComposerMap( 0 ), mStyle( 0 ), mSegmentMillimeters( 0.0 )
QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition* composition ): QgsComposerItem( composition ), mComposerMap( 0 ), mStyle( 0 ),
mSegmentMillimeters( 0.0 ), mAlignment( Left )
{
applyDefaultSettings();
applyDefaultSize();
@ -65,10 +66,57 @@ void QgsComposerScaleBar::paint( QPainter* painter, const QStyleOptionGraphicsIt
}
}
void QgsComposerScaleBar::setNumSegments( int nSegments )
{
if ( !mStyle )
{
mNumSegments = nSegments;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumSegments = nSegments;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}
void QgsComposerScaleBar::setNumUnitsPerSegment( double units )
{
if ( !mStyle )
{
mNumUnitsPerSegment = units;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumUnitsPerSegment = units;
refreshSegmentMillimeters();
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}
void QgsComposerScaleBar::setNumSegmentsLeft( int nSegmentsLeft )
{
if ( !mStyle )
{
mNumSegmentsLeft = nSegmentsLeft;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumSegmentsLeft = nSegmentsLeft;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}
void QgsComposerScaleBar::setBoxContentSpace( double space )
{
if ( !mStyle )
{
mBoxContentSpace = space;
return;
}
double width = mStyle->calculateBoxSize().width();
mBoxContentSpace = space;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}
void QgsComposerScaleBar::setComposerMap( const QgsComposerMap* map )
@ -172,7 +220,14 @@ void QgsComposerScaleBar::update()
void QgsComposerScaleBar::updateSegmentSize()
{
if ( !mStyle )
{
return;
}
double width = mStyle->calculateBoxSize().width();
refreshSegmentMillimeters();
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
update();
}
@ -309,6 +364,9 @@ bool QgsComposerScaleBar::writeXML( QDomElement& elem, QDomDocument & doc ) cons
colorElem.setAttribute( "blue", brushColor.blue() );
composerScaleBarElem.appendChild( colorElem );
//alignment
composerScaleBarElem.setAttribute( "alignment", QString::number(( int ) mAlignment ) );
elem.appendChild( composerScaleBarElem );
return _writeXML( composerScaleBarElem, doc );
}
@ -357,6 +415,9 @@ bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocume
refreshSegmentMillimeters();
//alignment
mAlignment = ( Alignment )( itemElem.attribute( "alignment", "0" ).toInt() );
//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
if ( composerItemList.size() > 0 )
@ -368,4 +429,16 @@ bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocume
return true;
}
void QgsComposerScaleBar::correctXPositionAlignment( double width, double widthAfter )
{
if ( mAlignment == Middle )
{
move( -( widthAfter - width ) / 2.0, 0 );
}
else if ( mAlignment == Right )
{
move( -( widthAfter - width ), 0 );
}
}

View File

@ -32,6 +32,14 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
public:
/**Added in version 1.8*/
enum Alignment
{
Left = 0,
Middle,
Right
};
QgsComposerScaleBar( QgsComposition* composition );
~QgsComposerScaleBar();
@ -43,10 +51,10 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
//getters and setters
int numSegments() const {return mNumSegments;}
void setNumSegments( int nSegments ) {mNumSegments = nSegments;}
void setNumSegments( int nSegments );
int numSegmentsLeft() const {return mNumSegmentsLeft;}
void setNumSegmentsLeft( int nSegmentsLeft ) {mNumSegmentsLeft = nSegmentsLeft;}
void setNumSegmentsLeft( int nSegmentsLeft );
double numUnitsPerSegment() const {return mNumUnitsPerSegment;}
void setNumUnitsPerSegment( double units );
@ -77,10 +85,17 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
void setLabelBarSpace( double space ) {mLabelBarSpace = space;}
double boxContentSpace() const {return mBoxContentSpace;}
void setBoxContentSpace( double space ) {mBoxContentSpace = space;}
void setBoxContentSpace( double space );
double segmentMillimeters() const {return mSegmentMillimeters;}
/**Left / Middle/ Right
@note: this method was added in version 1.8*/
Alignment alignment() const { return mAlignment; }
/**@note: this method was added in version 1.8*/
void setAlignment( Alignment a ) { mAlignment = a; }
/**Apply default settings*/
void applyDefaultSettings();
/**Apply default size (scale bar 1/5 of map item width)
@ -119,6 +134,9 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
*/
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
/**Moves scalebar position to the left / right depending on alignment and change in item width*/
void correctXPositionAlignment( double width, double widthAfter );
public slots:
void updateSegmentSize();
/**Sets mCompositionMap to 0 if the map is deleted*/
@ -159,6 +177,8 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
/**Width of a segment (in mm)*/
double mSegmentMillimeters;
Alignment mAlignment;
/**Calculates with of a segment in mm and stores it in mSegmentMillimeters*/
void refreshSegmentMillimeters();
};

View File

@ -20,12 +20,12 @@
#include <QList>
#include <QPainter>
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle( QgsComposerScaleBar* bar ): QgsScaleBarStyle( bar )
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle( QgsComposerScaleBar* bar ): QgsScaleBarStyle( bar ), mLastScaleBarWidth( 0 )
{
}
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle(): QgsScaleBarStyle( 0 )
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle(): QgsScaleBarStyle( 0 ), mLastScaleBarWidth( 0 )
{
}
@ -67,9 +67,17 @@ QRectF QgsNumericScaleBarStyle::calculateBoxSize() const
double textWidth = mScaleBar->textWidthMillimeters( mScaleBar->font(), scaleText() );
double textHeight = mScaleBar->fontAscentMillimeters( mScaleBar->font() );
return QRectF( mScaleBar->transform().dx(), mScaleBar->transform().dy(), 2 * mScaleBar->boxContentSpace()
rect = QRectF( mScaleBar->transform().dx(), mScaleBar->transform().dy(), 2 * mScaleBar->boxContentSpace()
+ 2 * mScaleBar->pen().width() + textWidth,
textHeight + 2 * mScaleBar->boxContentSpace() );
if ( mLastScaleBarWidth != rect.width() && mLastScaleBarWidth > 0 && rect.width() > 0 )
{
//hack to move scale bar the the left / right in order to keep the bar alignment
const_cast<QgsComposerScaleBar*>( mScaleBar )->correctXPositionAlignment( mLastScaleBarWidth, rect.width() );
}
mLastScaleBarWidth = rect.width();
return rect;
}
QString QgsNumericScaleBarStyle::scaleText() const
@ -78,12 +86,14 @@ QString QgsNumericScaleBarStyle::scaleText() const
if ( mScaleBar )
{
//find out scale
double scaleDenominator = 1;
const QgsComposerMap* composerMap = mScaleBar->composerMap();
if ( composerMap )
{
double scaleDenominator = composerMap->scale();
scaleDenominator = composerMap->scale();
scaleBarText = "1:" + QString::number( scaleDenominator, 'f', 0 );
}
scaleBarText = "1:" + QString::number( scaleDenominator, 'f', 0 );
}
return scaleBarText;
}

View File

@ -39,6 +39,9 @@ class CORE_EXPORT QgsNumericScaleBarStyle: public QgsScaleBarStyle
QgsNumericScaleBarStyle(); //forbidden
/**Returns the text for the scale bar or an empty string in case of error*/
QString scaleText() const;
/**Store last width (in mm) to keep alignement to left/middle/right side*/
mutable double mLastScaleBarWidth;
};
#endif

View File

@ -33,8 +33,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>307</width>
<height>616</height>
<width>298</width>
<height>545</height>
</rect>
</property>
<attribute name="label">
@ -143,7 +143,7 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="12" column="0">
<widget class="QSpinBox" name="mHeightSpinBox">
<property name="suffix">
<string> mm</string>
@ -153,7 +153,7 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="13" column="0">
<widget class="QDoubleSpinBox" name="mLineWidthSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -178,7 +178,7 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="14" column="0">
<widget class="QDoubleSpinBox" name="mLabelBarSpaceSpinBox">
<property name="prefix">
<string>Label space </string>
@ -188,7 +188,7 @@
</property>
</widget>
</item>
<item row="13" column="0">
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="mBoxSizeSpinBox">
<property name="prefix">
<string>Box space </string>
@ -198,7 +198,7 @@
</property>
</widget>
</item>
<item row="14" column="0">
<item row="16" column="0">
<widget class="QLabel" name="mUnitLabelLabel">
<property name="text">
<string>Unit label</string>
@ -211,10 +211,10 @@
</property>
</widget>
</item>
<item row="15" column="0">
<item row="17" column="0">
<widget class="QLineEdit" name="mUnitLabelLineEdit"/>
</item>
<item row="16" column="0">
<item row="18" column="0">
<widget class="QPushButton" name="mFontButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -227,14 +227,14 @@
</property>
</widget>
</item>
<item row="17" column="0">
<item row="19" column="0">
<widget class="QPushButton" name="mColorPushButton">
<property name="text">
<string>Color...</string>
</property>
</widget>
</item>
<item row="18" column="0">
<item row="20" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -247,6 +247,16 @@
</property>
</spacer>
</item>
<item row="11" column="0">
<widget class="QComboBox" name="mAlignmentComboBox"/>
</item>
<item row="10" column="0">
<widget class="QLabel" name="mAlignmentLabel">
<property name="text">
<string>Alignment</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>