Skip to content

Commit a714a18

Browse files
manisandronyalldawson
authored andcommittedApr 13, 2014
[FEATURE][composer] Add support for specifying legend title horizontal alignment in composer
1 parent ca2e68c commit a714a18

File tree

6 files changed

+157
-36
lines changed

6 files changed

+157
-36
lines changed
 

‎python/core/composer/qgscomposerlegend.sip

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ class QgsComposerLegend : QgsComposerItem
3131
void setTitle( const QString& t );
3232
QString title() const;
3333

34+
/*Returns the alignment of the legend title
35+
* @returns Qt::AlignmentFlag for the legend title
36+
* @note added in 2.3
37+
* @see setTitleAlignment
38+
*/
39+
Qt::AlignmentFlag titleAlignment() const;
40+
/**Sets the alignment of the legend title
41+
* @param alignment Text alignment for drawing the legend title
42+
* @note added in 2.3
43+
* @see titleAlignment
44+
*/
45+
void setTitleAlignment( Qt::AlignmentFlag alignment );
46+
3447
/** Returns reference to modifiable style */
3548
QgsComposerLegendStyle & rstyle( QgsComposerLegendStyle::Style s );
3649
/** Returns style */

‎src/app/composer/qgscomposerlegendwidget.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,11 @@ void QgsComposerLegendWidget::setGuiElements()
161161
return;
162162
}
163163

164+
int alignment = mLegend->titleAlignment() == Qt::AlignLeft ? 0 : mLegend->titleAlignment() == Qt::AlignHCenter ? 1 : 2;
165+
164166
blockAllSignals( true );
165167
mTitleLineEdit->setText( mLegend->title() );
168+
mTitleAlignCombo->setCurrentIndex( alignment );
166169
mColumnCountSpinBox->setValue( mLegend->columnCount() );
167170
mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
168171
mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
@@ -220,6 +223,18 @@ void QgsComposerLegendWidget::on_mTitleLineEdit_textChanged( const QString& text
220223
}
221224
}
222225

226+
void QgsComposerLegendWidget::on_mTitleAlignCombo_currentIndexChanged( int index )
227+
{
228+
if ( mLegend )
229+
{
230+
Qt::AlignmentFlag alignment = index == 0 ? Qt::AlignLeft : index == 1 ? Qt::AlignHCenter : Qt::AlignRight;
231+
mLegend->beginCommand( tr( "Legend title alignment changed" ) );
232+
mLegend->setTitleAlignment( alignment );
233+
mLegend->update();
234+
mLegend->endCommand();
235+
}
236+
}
237+
223238
void QgsComposerLegendWidget::on_mColumnCountSpinBox_valueChanged( int c )
224239
{
225240
if ( mLegend )
@@ -916,6 +931,7 @@ void QgsComposerLegendWidget::updateLegend()
916931
void QgsComposerLegendWidget::blockAllSignals( bool b )
917932
{
918933
mTitleLineEdit->blockSignals( b );
934+
mTitleAlignCombo->blockSignals( b );
919935
mItemTreeView->blockSignals( b );
920936
mCheckBoxAutoUpdate->blockSignals( b );
921937
mMapComboBox->blockSignals( b );
@@ -997,3 +1013,4 @@ void QgsComposerLegendWidget::selectedChanged( const QModelIndex & current, cons
9971013
mCountToolButton->setChecked( layerItem->showFeatureCount() );
9981014
mCountToolButton->setEnabled( true );
9991015
}
1016+

‎src/app/composer/qgscomposerlegendwidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
5454

5555
void on_mWrapCharLineEdit_textChanged( const QString& text );
5656
void on_mTitleLineEdit_textChanged( const QString& text );
57+
void on_mTitleAlignCombo_currentIndexChanged( int index );
5758
void on_mColumnCountSpinBox_valueChanged( int c );
5859
void on_mSplitLayerCheckBox_toggled( bool checked );
5960
void on_mEqualColumnWidthCheckBox_toggled( bool checked );
@@ -106,3 +107,4 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
106107
};
107108

108109
#endif
110+

‎src/core/composer/qgscomposerlegend.cpp

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
3636
, mFontColor( QColor( 0, 0, 0 ) )
3737
, mBoxSpace( 2 )
3838
, mColumnSpace( 2 )
39+
, mTitleAlignment( Qt::AlignLeft )
3940
, mColumnCount( 1 )
4041
, mComposerMap( 0 )
4142
, mSplitLayer( false )
@@ -106,7 +107,10 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
106107
}
107108
}
108109

110+
//calculate size of title
109111
QSizeF titleSize = drawTitle();
112+
//add title margin to size of title text
113+
titleSize.rwidth() += mBoxSpace * 2.0;
110114
double columnTop = mBoxSpace + titleSize.height() + style( QgsComposerLegendStyle::Title ).margin( QgsComposerLegendStyle::Bottom );
111115

112116
QPointF point( mBoxSpace, columnTop );
@@ -149,30 +153,12 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
149153

150154
size.rheight() = columnTop + columnMaxHeight + mBoxSpace;
151155
size.rwidth() = point.x();
152-
153-
// Now we know total width and can draw the title centered
154156
if ( !mTitle.isEmpty() )
155157
{
156-
// For multicolumn center if we stay in totalWidth, otherwise allign to left
157-
// and expand total width. With single column keep alligned to left be cause
158-
// it looks better alligned with items bellow instead of centered
159-
Qt::AlignmentFlag halignment;
160-
if ( mColumnCount > 1 && titleSize.width() + 2 * mBoxSpace < size.width() )
161-
{
162-
halignment = Qt::AlignHCenter;
163-
point.rx() = mBoxSpace + size.rwidth() / 2;
164-
}
165-
else
166-
{
167-
halignment = Qt::AlignLeft;
168-
point.rx() = mBoxSpace;
169-
size.rwidth() = qMax( titleSize.width() + 2 * mBoxSpace, size.width() );
170-
}
171-
point.ry() = mBoxSpace;
172-
drawTitle( painter, point, halignment );
158+
size.rwidth() = qMax( titleSize.width(), size.width() );
173159
}
174160

175-
//adjust box if width or height is to small
161+
//adjust box if width or height is too small
176162
if ( painter && size.height() > rect().height() )
177163
{
178164
setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), size.height() ) );
@@ -182,6 +168,25 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
182168
setSceneRect( QRectF( pos().x(), pos().y(), size.width(), rect().height() ) );
183169
}
184170

171+
// Now we have set the correct total item width and can draw the title centered
172+
if ( !mTitle.isEmpty() )
173+
{
174+
if ( mTitleAlignment == Qt::AlignLeft )
175+
{
176+
point.rx() = mBoxSpace;
177+
}
178+
else if ( mTitleAlignment == Qt::AlignHCenter )
179+
{
180+
point.rx() = rect().width() / 2;
181+
}
182+
else
183+
{
184+
point.rx() = rect().width() - mBoxSpace;
185+
}
186+
point.ry() = mBoxSpace;
187+
drawTitle( painter, point, mTitleAlignment );
188+
}
189+
185190
if ( painter )
186191
{
187192
painter->restore();
@@ -200,27 +205,55 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
200205
QSizeF QgsComposerLegend::drawTitle( QPainter* painter, QPointF point, Qt::AlignmentFlag halignment )
201206
{
202207
QSizeF size( 0, 0 );
203-
if ( mTitle.isEmpty() ) return size;
208+
if ( mTitle.isEmpty() )
209+
{
210+
return size;
211+
}
204212

205213
QStringList lines = splitStringForWrapping( mTitle );
206-
207214
double y = point.y();
208215

209-
if ( painter ) painter->setPen( mFontColor );
216+
if ( painter )
217+
{
218+
painter->setPen( mFontColor );
219+
}
220+
221+
//calculate width and left pos of rectangle to draw text into
222+
double textBoxWidth;
223+
double textBoxLeft;
224+
switch ( halignment )
225+
{
226+
case Qt::AlignHCenter:
227+
textBoxWidth = ( qMin( point.x(), rect().width() - point.x() ) - mBoxSpace ) * 2.0;
228+
textBoxLeft = point.x() - textBoxWidth / 2.;
229+
break;
230+
case Qt::AlignRight:
231+
textBoxLeft = mBoxSpace;
232+
textBoxWidth = point.x() - mBoxSpace;
233+
break;
234+
case Qt::AlignLeft:
235+
default:
236+
textBoxLeft = point.x();
237+
textBoxWidth = rect().width() - point.x() - mBoxSpace;
238+
break;
239+
}
210240

211241
for ( QStringList::Iterator titlePart = lines.begin(); titlePart != lines.end(); ++titlePart )
212242
{
213-
// it does not draw the last world if rectangle width is exactly text width
243+
//last word is not drawn if rectangle width is exactly text width, so add 1
244+
//TODO - correctly calculate size of italicized text, since QFontMetrics does not
214245
qreal width = textWidthMillimeters( styleFont( QgsComposerLegendStyle::Title ), *titlePart ) + 1;
215246
qreal height = fontAscentMillimeters( styleFont( QgsComposerLegendStyle::Title ) ) + fontDescentMillimeters( styleFont( QgsComposerLegendStyle::Title ) );
216247

217-
double left = halignment == Qt::AlignLeft ? point.x() : point.x() - width / 2;
248+
QRectF r( textBoxLeft, y, textBoxWidth, height );
218249

219-
QRectF rect( left, y, width, height );
250+
if ( painter )
251+
{
252+
drawText( painter, r, *titlePart, styleFont( QgsComposerLegendStyle::Title ), halignment, Qt::AlignVCenter );
253+
}
220254

221-
if ( painter ) drawText( painter, rect, *titlePart, styleFont( QgsComposerLegendStyle::Title ), halignment, Qt::AlignVCenter );
222-
223-
size.rwidth() = qMax( width, size.width() );
255+
//update max width of title
256+
size.rwidth() = qMax( width, size.rwidth() );
224257

225258
y += height;
226259
if ( titlePart != lines.end() )
@@ -1039,3 +1072,4 @@ void QgsComposerLegend::setColumns( QList<Atom>& atomList )
10391072
}
10401073
}
10411074

1075+

‎src/core/composer/qgscomposerlegend.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
5858
void setTitle( const QString& t ) {mTitle = t;}
5959
QString title() const {return mTitle;}
6060

61+
/*Returns the alignment of the legend title
62+
* @returns Qt::AlignmentFlag for the legend title
63+
* @note added in 2.3
64+
* @see setTitleAlignment
65+
*/
66+
Qt::AlignmentFlag titleAlignment() const { return mTitleAlignment; }
67+
/**Sets the alignment of the legend title
68+
* @param alignment Text alignment for drawing the legend title
69+
* @note added in 2.3
70+
* @see titleAlignment
71+
*/
72+
void setTitleAlignment( Qt::AlignmentFlag alignment ) { mTitleAlignment = alignment; }
73+
6174
/** Returns reference to modifiable style */
6275
QgsComposerLegendStyle & rstyle( QgsComposerLegendStyle::Style s ) { return mStyleMap[s]; }
6376
/** Returns style */
@@ -153,6 +166,9 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
153166
/** Spacing between lines when wrapped */
154167
double mlineSpacing;
155168

169+
/** Title alignment, one of Qt::AlignLeft, Qt::AlignHCenter, Qt::AlignRight) */
170+
Qt::AlignmentFlag mTitleAlignment;
171+
156172
/** Number of legend columns */
157173
int mColumnCount;
158174

@@ -214,6 +230,9 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
214230

215231
QgsComposerLegend(); //forbidden
216232

233+
/**Draws title in the legend using the title font and the specified alignment
234+
* If no painter is specified, function returns the required width/height to draw the title.
235+
*/
217236
QSizeF drawTitle( QPainter* painter = 0, QPointF point = QPointF(), Qt::AlignmentFlag halignment = Qt::AlignLeft );
218237

219238
/**Draws a group item and all subitems
@@ -247,3 +266,4 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
247266
};
248267

249268
#endif
269+

‎src/ui/qgscomposerlegendwidgetbase.ui

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@
2323
<property name="spacing">
2424
<number>0</number>
2525
</property>
26-
<property name="margin">
26+
<property name="leftMargin">
27+
<number>0</number>
28+
</property>
29+
<property name="topMargin">
30+
<number>0</number>
31+
</property>
32+
<property name="rightMargin">
33+
<number>0</number>
34+
</property>
35+
<property name="bottomMargin">
2736
<number>0</number>
2837
</property>
2938
<item>
@@ -55,8 +64,8 @@
5564
<rect>
5665
<x>0</x>
5766
<y>0</y>
58-
<width>375</width>
59-
<height>1287</height>
67+
<width>377</width>
68+
<height>1251</height>
6069
</rect>
6170
</property>
6271
<layout class="QVBoxLayout" name="mainLayout">
@@ -94,7 +103,7 @@
94103
<item row="0" column="1">
95104
<widget class="QLineEdit" name="mTitleLineEdit"/>
96105
</item>
97-
<item row="1" column="0">
106+
<item row="2" column="0">
98107
<widget class="QLabel" name="mMapLabel">
99108
<property name="text">
100109
<string>Map</string>
@@ -104,10 +113,10 @@
104113
</property>
105114
</widget>
106115
</item>
107-
<item row="1" column="1">
116+
<item row="2" column="1">
108117
<widget class="QComboBox" name="mMapComboBox"/>
109118
</item>
110-
<item row="2" column="0">
119+
<item row="3" column="0">
111120
<widget class="QLabel" name="label">
112121
<property name="text">
113122
<string>Wrap text on</string>
@@ -117,13 +126,39 @@
117126
</property>
118127
</widget>
119128
</item>
120-
<item row="2" column="1">
129+
<item row="3" column="1">
121130
<widget class="QLineEdit" name="mWrapCharLineEdit">
122131
<property name="frame">
123132
<bool>true</bool>
124133
</property>
125134
</widget>
126135
</item>
136+
<item row="1" column="0">
137+
<widget class="QLabel" name="label_15">
138+
<property name="text">
139+
<string>Title alignment:</string>
140+
</property>
141+
</widget>
142+
</item>
143+
<item row="1" column="1">
144+
<widget class="QComboBox" name="mTitleAlignCombo">
145+
<item>
146+
<property name="text">
147+
<string>Left</string>
148+
</property>
149+
</item>
150+
<item>
151+
<property name="text">
152+
<string>Center</string>
153+
</property>
154+
</item>
155+
<item>
156+
<property name="text">
157+
<string>Right</string>
158+
</property>
159+
</item>
160+
</widget>
161+
</item>
127162
</layout>
128163
</widget>
129164
</item>

0 commit comments

Comments
 (0)
Please sign in to comment.