Skip to content

Commit 5b9210b

Browse files
committed
[composer] Respect reference point when resizing scalebar and legend
Previously, the reference point (and data defined position/size) were ignored when scalebars or legends resized themselves. Fix #11321, #11380
1 parent ba8a60f commit 5b9210b

File tree

5 files changed

+79
-22
lines changed

5 files changed

+79
-22
lines changed

python/core/composer/qgscomposeritem.sip

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,17 @@ class QgsComposerItem : QgsComposerObject, QGraphicsRectItem
761761
void deleteVAlignSnapItem();
762762
void deleteAlignItems();
763763

764-
/**Update an item rect to consider data defined position and size of item*/
765-
QRectF evalItemRect( const QRectF &newRect );
764+
/**Evaluates an item's bounding rect to consider data defined position and size of item
765+
* and reference point
766+
* @param newRect target bouding rect for item
767+
* @param resizeOnly set to true if the item is only being resized. If true then
768+
* the position of the returned rect will be adjusted to account for the item's
769+
* position mode
770+
* @returns bounding box rectangle for item after data defined size and position have been
771+
* set and position mode has been accounted for
772+
* @note added in QGIS 2.5
773+
*/
774+
QRectF evalItemRect( const QRectF &newRect, const bool resizeOnly = false );
766775

767776
/**Returns whether the item should be drawn in the current context
768777
* @returns true if item should be drawn

src/core/composer/qgscomposeritem.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ void QgsComposerItem::setSceneRect( const QRectF& rectangle )
708708
emit sizeChanged();
709709
}
710710

711-
QRectF QgsComposerItem::evalItemRect( const QRectF &newRect )
711+
QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOnly )
712712
{
713713
QRectF result = newRect;
714714

@@ -737,14 +737,29 @@ QRectF QgsComposerItem::evalItemRect( const QRectF &newRect )
737737
}
738738

739739
double x = result.left();
740-
//initially adjust for position mode to get top-left coordinate
741-
if ( mLastUsedPositionMode == UpperMiddle || mLastUsedPositionMode == Middle || mLastUsedPositionMode == LowerMiddle )
740+
//initially adjust for position mode to get x coordinate
741+
if ( !resizeOnly )
742742
{
743-
x += newRect.width() / 2.0;
743+
//adjust x-coordinate if placement is not done to a left point
744+
if ( mLastUsedPositionMode == UpperMiddle || mLastUsedPositionMode == Middle || mLastUsedPositionMode == LowerMiddle )
745+
{
746+
x += newRect.width() / 2.0;
747+
}
748+
else if ( mLastUsedPositionMode == UpperRight || mLastUsedPositionMode == MiddleRight || mLastUsedPositionMode == LowerRight )
749+
{
750+
x += newRect.width();
751+
}
744752
}
745-
else if ( mLastUsedPositionMode == UpperRight || mLastUsedPositionMode == MiddleRight || mLastUsedPositionMode == LowerRight )
753+
else
746754
{
747-
x += newRect.width();
755+
if ( mLastUsedPositionMode == UpperMiddle || mLastUsedPositionMode == Middle || mLastUsedPositionMode == LowerMiddle )
756+
{
757+
x += rect().width() / 2.0;
758+
}
759+
else if ( mLastUsedPositionMode == UpperRight || mLastUsedPositionMode == MiddleRight || mLastUsedPositionMode == LowerRight )
760+
{
761+
x += rect().width();
762+
}
748763
}
749764
if ( dataDefinedEvaluate( QgsComposerObject::PositionX, exprVal ) )
750765
{
@@ -758,16 +773,30 @@ QRectF QgsComposerItem::evalItemRect( const QRectF &newRect )
758773
}
759774

760775
double y = result.top();
761-
//adjust y-coordinate if placement is not done to an upper point
762-
if ( mLastUsedPositionMode == MiddleLeft || mLastUsedPositionMode == Middle || mLastUsedPositionMode == MiddleRight )
776+
//initially adjust for position mode to get y coordinate
777+
if ( !resizeOnly )
763778
{
764-
y += newRect.height() / 2.0;
779+
//adjust y-coordinate if placement is not done to an upper point
780+
if ( mLastUsedPositionMode == MiddleLeft || mLastUsedPositionMode == Middle || mLastUsedPositionMode == MiddleRight )
781+
{
782+
y += newRect.height() / 2.0;
783+
}
784+
else if ( mLastUsedPositionMode == LowerLeft || mLastUsedPositionMode == LowerMiddle || mLastUsedPositionMode == LowerRight )
785+
{
786+
y += newRect.height();
787+
}
765788
}
766-
else if ( mLastUsedPositionMode == LowerLeft || mLastUsedPositionMode == LowerMiddle || mLastUsedPositionMode == LowerRight )
789+
else
767790
{
768-
y += newRect.height();
791+
if ( mLastUsedPositionMode == MiddleLeft || mLastUsedPositionMode == Middle || mLastUsedPositionMode == MiddleRight )
792+
{
793+
y += rect().height() / 2.0;
794+
}
795+
else if ( mLastUsedPositionMode == LowerLeft || mLastUsedPositionMode == LowerMiddle || mLastUsedPositionMode == LowerRight )
796+
{
797+
y += rect().height();
798+
}
769799
}
770-
771800
if ( dataDefinedEvaluate( QgsComposerObject::PositionY, exprVal ) )
772801
{
773802
bool ok;

src/core/composer/qgscomposeritem.h

100755100644
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,17 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
774774
void deleteVAlignSnapItem();
775775
void deleteAlignItems();
776776

777-
/**Update an item rect to consider data defined position and size of item*/
778-
QRectF evalItemRect( const QRectF &newRect );
777+
/**Evaluates an item's bounding rect to consider data defined position and size of item
778+
* and reference point
779+
* @param newRect target bouding rect for item
780+
* @param resizeOnly set to true if the item is only being resized. If true then
781+
* the position of the returned rect will be adjusted to account for the item's
782+
* position mode
783+
* @returns bounding box rectangle for item after data defined size and position have been
784+
* set and position mode has been accounted for
785+
* @note added in QGIS 2.5
786+
*/
787+
QRectF evalItemRect( const QRectF &newRect, const bool resizeOnly = false );
779788

780789
/**Returns whether the item should be drawn in the current context
781790
* @returns true if item should be drawn

src/core/composer/qgscomposerlegend.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,18 @@ void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem
103103

104104
//adjust box if width or height is too small
105105
QSizeF size = legendRenderer.minimumSize();
106-
if ( size.height() > rect().height() )
107-
setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), size.height() ) );
108-
if ( size.width() > rect().width() )
109-
setSceneRect( QRectF( pos().x(), pos().y(), size.width(), rect().height() ) );
106+
if ( size.height() > rect().height() || size.width() > rect().width() )
107+
{
108+
//need to resize box
109+
QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
110+
if ( size.height() > targetRect.height() )
111+
targetRect.setHeight( size.height() );
112+
if ( size.width() > rect().width() )
113+
targetRect.setWidth( size.width() );
114+
115+
//set new rect, respecting position mode and data defined size/position
116+
setSceneRect( evalItemRect( targetRect, true ) );
117+
}
110118

111119
legendRenderer.drawLegend( painter );
112120

@@ -137,7 +145,9 @@ void QgsComposerLegend::adjustBoxSize()
137145
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) );
138146
if ( size.isValid() )
139147
{
140-
setSceneRect( QRectF( pos().x(), pos().y(), size.width(), size.height() ) );
148+
QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() );
149+
//set new rect, respecting position mode and data defined size/position
150+
setSceneRect( evalItemRect( targetRect, true ) );
141151
}
142152
}
143153

src/core/composer/qgscomposerscalebar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ void QgsComposerScaleBar::adjustBoxSize()
389389
QRectF box = mStyle->calculateBoxSize();
390390

391391
//update rect for data defined size and position
392-
QRectF newRect = evalItemRect( box );
392+
QRectF newRect = evalItemRect( box, true );
393393

394394
//scale bars have a minimum size, respect that regardless of data defined settings
395395
if ( newRect.width() < box.width() )

0 commit comments

Comments
 (0)