[FEATURE] allow customization of line spacing for legend item labels (#3632)

* [FEATURE] allow customization of line spacing for legend item labels
* add test for legend line spacing and update control images
This commit is contained in:
Mathieu Pellerin 2016-12-13 12:09:13 +07:00 committed by GitHub
parent dc509f458f
commit a8b9723cbc
66 changed files with 96 additions and 11 deletions

View File

@ -121,6 +121,18 @@ class QgsComposerLegend : QgsComposerItem
void setStyleMargin( QgsLegendStyle::Style s, double margin );
void setStyleMargin( QgsLegendStyle::Style s, QgsLegendStyle::Side side, double margin );
/** Returns the spacing in-between lines in mm
* @note added in 3.0
* @see setLineSpacing
*/
double lineSpacing() const;
/** Sets the spacing in-between multiple lines
* @param spacing Double value to use as spacing in between multiple lines
* @note added in 3.0
* @see lineSpacing
*/
void setLineSpacing( double spacing );
double boxSpace() const;
void setBoxSpace( double s );

View File

@ -144,6 +144,7 @@ void QgsComposerLegendWidget::setGuiElements()
mIconLabelSpaceSpinBox->setValue( mLegend->style( QgsLegendStyle::SymbolLabel ).margin( QgsLegendStyle::Left ) );
mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
mLineSpacingSpinBox->setValue( mLegend->lineSpacing() );
mRasterBorderGroupBox->setChecked( mLegend->drawRasterBorder() );
mRasterBorderWidthSpinBox->setValue( mLegend->rasterBorderWidth() );
@ -450,6 +451,17 @@ void QgsComposerLegendWidget::on_mColumnSpaceSpinBox_valueChanged( double d )
}
}
void QgsComposerLegendWidget::on_mLineSpacingSpinBox_valueChanged( double d )
{
if ( mLegend )
{
mLegend->beginCommand( tr( "Legend line space" ), QgsComposerMergeCommand::LegendLineSpacing );
mLegend->setLineSpacing( d );
mLegend->adjustBoxSize();
mLegend->update();
mLegend->endCommand();
}
}
static void _moveLegendNode( QgsLayerTreeLayer* nodeLayer, int legendNodeIndex, int offset )
{

View File

@ -66,6 +66,7 @@ class QgsComposerLegendWidget: public QgsComposerItemBaseWidget, private Ui::Qgs
void on_mFontColorButton_colorChanged( const QColor& newFontColor );
void on_mBoxSpaceSpinBox_valueChanged( double d );
void on_mColumnSpaceSpinBox_valueChanged( double d );
void on_mLineSpacingSpinBox_valueChanged( double d );
void on_mCheckBoxAutoUpdate_stateChanged( int state );
void composerMapChanged( QgsComposerItem* item );
void on_mCheckboxResizeContents_toggled( bool checked );

View File

@ -111,6 +111,7 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
LegendIconSymbolSpace,
LegendBoxSpace,
LegendColumnSpace,
LegendLineSpacing,
LegendRasterBorderWidth,
LegendFontColor,
LegendRasterBorderColor,

View File

@ -288,6 +288,9 @@ void QgsComposerLegend::setStyleFont( QgsLegendStyle::Style s, const QFont& f )
void QgsComposerLegend::setStyleMargin( QgsLegendStyle::Style s, double margin ) { rstyle( s ).setMargin( margin ); }
void QgsComposerLegend::setStyleMargin( QgsLegendStyle::Style s, QgsLegendStyle::Side side, double margin ) { rstyle( s ).setMargin( side, margin ); }
double QgsComposerLegend::lineSpacing() const { return mSettings.lineSpacing(); }
void QgsComposerLegend::setLineSpacing( double spacing ) { mSettings.setLineSpacing( spacing ); }
double QgsComposerLegend::boxSpace() const { return mSettings.boxSpace(); }
void QgsComposerLegend::setBoxSpace( double s ) { mSettings.setBoxSpace( s ); }
@ -370,6 +373,7 @@ bool QgsComposerLegend::writeXml( QDomElement& elem, QDomDocument & doc ) const
composerLegendElem.setAttribute( QStringLiteral( "symbolWidth" ), QString::number( mSettings.symbolSize().width() ) );
composerLegendElem.setAttribute( QStringLiteral( "symbolHeight" ), QString::number( mSettings.symbolSize().height() ) );
composerLegendElem.setAttribute( QStringLiteral( "lineSpacing" ), QString::number( mSettings.lineSpacing() ) );
composerLegendElem.setAttribute( QStringLiteral( "rasterBorder" ), mSettings.drawRasterBorder() );
composerLegendElem.setAttribute( QStringLiteral( "rasterBorderColor" ), QgsSymbolLayerUtils::encodeColor( mSettings.rasterBorderColor() ) );
@ -501,6 +505,7 @@ bool QgsComposerLegend::readXml( const QDomElement& itemElem, const QDomDocument
mSettings.setSymbolSize( QSizeF( itemElem.attribute( QStringLiteral( "symbolWidth" ), QStringLiteral( "7.0" ) ).toDouble(), itemElem.attribute( QStringLiteral( "symbolHeight" ), QStringLiteral( "14.0" ) ).toDouble() ) );
mSettings.setWmsLegendSize( QSizeF( itemElem.attribute( QStringLiteral( "wmsLegendWidth" ), QStringLiteral( "50" ) ).toDouble(), itemElem.attribute( QStringLiteral( "wmsLegendHeight" ), QStringLiteral( "25" ) ).toDouble() ) );
mSettings.setLineSpacing( itemElem.attribute( QStringLiteral( "lineSpacing" ), "1.0" ).toDouble() );
mSettings.setDrawRasterBorder( itemElem.attribute( QStringLiteral( "rasterBorder" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
mSettings.setRasterBorderColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "rasterBorderColor" ), QStringLiteral( "0,0,0" ) ) ) );

View File

@ -149,6 +149,19 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
void setStyleMargin( QgsLegendStyle::Style s, double margin );
void setStyleMargin( QgsLegendStyle::Style s, QgsLegendStyle::Side side, double margin );
/** Returns the spacing in-between lines in mm
* @note added in 3.0
* @see setLineSpacing
*/
double lineSpacing() const;
/** Sets the spacing in-between multiple lines
* @param spacing Double value to use as spacing in between multiple lines
* @note added in 3.0
* @see lineSpacing
*/
void setLineSpacing( double spacing );
double boxSpace() const;
void setBoxSpace( double s );

View File

@ -93,10 +93,11 @@ QSizeF QgsLayerTreeModelLegendNode::drawSymbolText( const QgsLegendSettings& set
QFont symbolLabelFont = settings.style( QgsLegendStyle::SymbolLabel ).font();
double textHeight = settings.fontHeightCharacterMM( symbolLabelFont, QChar( '0' ) );
double textDescent = settings.fontDescentMillimeters( symbolLabelFont );
QStringList lines = settings.splitStringForWrapping( data( Qt::DisplayRole ).toString() );
labelSize.rheight() = lines.count() * textHeight + ( lines.count() - 1 ) * settings.lineSpacing();
labelSize.rheight() = lines.count() * textHeight + ( lines.count() - 1 ) * ( settings.lineSpacing() + textDescent );
double labelX = 0.0, labelY = 0.0;
if ( ctx )
@ -120,8 +121,8 @@ QSizeF QgsLayerTreeModelLegendNode::drawSymbolText( const QgsLegendSettings& set
if ( ctx )
{
settings.drawText( ctx->painter, labelX, labelY, *itemPart, symbolLabelFont );
if ( itemPart != lines.end() )
labelY += settings.lineSpacing() + textHeight;
if ( itemPart != ( lines.end() - 1 ) )
labelY += textDescent + settings.lineSpacing() + textHeight;
}
}

View File

@ -411,7 +411,7 @@ QSizeF QgsLegendRenderer::drawTitle( QPainter* painter, QPointF point, Qt::Align
size.rwidth() = qMax( width, size.rwidth() );
y += height;
if ( titlePart != lines.end() )
if ( titlePart != ( lines.end() - 1 ) )
{
y += mSettings.lineSpacing();
}
@ -537,7 +537,7 @@ QSizeF QgsLegendRenderer::drawLayerTitle( QgsLayerTreeLayer* nodeLayer, QPainter
if ( painter ) mSettings.drawText( painter, point.x(), y, *layerItemPart, layerFont );
qreal width = mSettings.textWidthMillimeters( layerFont, *layerItemPart );
size.rwidth() = qMax( width, size.width() );
if ( layerItemPart != lines.end() )
if ( layerItemPart != ( lines.end() - 1 ) )
{
y += mSettings.lineSpacing();
}
@ -566,7 +566,7 @@ QSizeF QgsLegendRenderer::drawGroupTitle( QgsLayerTreeGroup* nodeGroup, QPainter
if ( painter ) mSettings.drawText( painter, point.x(), y, *groupPart, groupFont );
qreal width = mSettings.textWidthMillimeters( groupFont, *groupPart );
size.rwidth() = qMax( width, size.width() );
if ( groupPart != lines.end() )
if ( groupPart != ( lines.end() - 1 ) )
{
y += mSettings.lineSpacing();
}

View File

@ -25,7 +25,7 @@ QgsLegendSettings::QgsLegendSettings()
, mBoxSpace( 2 )
, mSymbolSize( 7, 4 )
, mWmsLegendSize( 50, 25 )
, mLineSpacing( 1.5 )
, mLineSpacing( 1 )
, mColumnSpace( 2 )
, mColumnCount( 1 )
, mSplitLayer( false )
@ -38,10 +38,10 @@ QgsLegendSettings::QgsLegendSettings()
, mMapScale( 1 )
, mDpi( 96 ) // based on QImage's default DPI
{
rstyle( QgsLegendStyle::Title ).setMargin( QgsLegendStyle::Bottom, 2 );
rstyle( QgsLegendStyle::Group ).setMargin( QgsLegendStyle::Top, 2 );
rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, 2 );
rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, 2 );
rstyle( QgsLegendStyle::Title ).setMargin( QgsLegendStyle::Bottom, 3.5 );
rstyle( QgsLegendStyle::Group ).setMargin( QgsLegendStyle::Top, 3 );
rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, 3 );
rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, 2.5 );
rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Top, 2 );
rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Left, 2 );
rstyle( QgsLegendStyle::Title ).rfont().setPointSizeF( 16.0 );

View File

@ -965,6 +965,23 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Line space</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QgsDoubleSpinBox" name="mLineSpacingSpinBox">
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string> mm</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="toolTip">

View File

@ -114,6 +114,7 @@ class TestQgsLegendRenderer : public QObject
void testBigMarker();
void testMapUnits();
void testTallSymbol();
void testLineSpacing();
void testLongSymbolText();
void testThreeColumns();
void testFilterByMap();
@ -360,6 +361,28 @@ void TestQgsLegendRenderer::testTallSymbol()
mVL2->setName( QStringLiteral( "Polygon Layer" ) );
}
void TestQgsLegendRenderer::testLineSpacing()
{
QString testName = "legend_line_spacing";
QgsCategorizedSymbolRenderer* catRenderer = dynamic_cast<QgsCategorizedSymbolRenderer*>( mVL3->renderer() );
QVERIFY( catRenderer );
catRenderer->updateCategoryLabel( 1, "This is\nthree lines\nlong label" );
mVL2->setName( "This is a two lines\nlong label" );
QgsLayerTreeModel legendModel( mRoot );
QgsLegendSettings settings;
settings.setWrapChar( "\n" );
settings.setLineSpacing( 3 );
_setStandardTestFont( settings );
_renderLegend( testName, &legendModel, settings );
QVERIFY( _verifyImage( testName, mReport ) );
mVL2->setName( "Polygon Layer" );
}
void TestQgsLegendRenderer::testLongSymbolText()
{
QString testName = QStringLiteral( "legend_long_symbol_text" );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 B

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 360 B