mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[composer] Fix setting legend content by map not resizing legend
When a legend was set to filter content by map, it wasn't consistently being resized to fit the legend contents. This caused issues for atlas exports where legends could grow but never shrink. Fix #14707 On behalf of Faunalia, sponsored by ENEL
This commit is contained in:
parent
93f2eec711
commit
4f31ab656e
@ -43,6 +43,7 @@ QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
|
||||
, mFilterAskedForUpdate( false )
|
||||
, mInAtlas( false )
|
||||
, mInitialMapScaleCalculated( false )
|
||||
, mForceResize( false )
|
||||
{
|
||||
mLegendModel2 = new QgsLegendModelV2( QgsProject::instance()->layerTreeRoot() );
|
||||
|
||||
@ -66,6 +67,8 @@ QgsComposerLegend::QgsComposerLegend()
|
||||
, mFilterOutAtlas( false )
|
||||
, mFilterAskedForUpdate( false )
|
||||
, mInAtlas( false )
|
||||
, mInitialMapScaleCalculated( false )
|
||||
, mForceResize( false )
|
||||
{
|
||||
|
||||
}
|
||||
@ -117,11 +120,18 @@ void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem
|
||||
mInitialMapScaleCalculated = true;
|
||||
|
||||
QgsLegendRenderer legendRenderer( mLegendModel2, mSettings );
|
||||
legendRenderer.setLegendSize( rect().size() );
|
||||
legendRenderer.setLegendSize( mForceResize ? QSize() : rect().size() );
|
||||
|
||||
//adjust box if width or height is too small
|
||||
QSizeF size = legendRenderer.minimumSize();
|
||||
if ( size.height() > rect().height() || size.width() > rect().width() )
|
||||
if ( mForceResize )
|
||||
{
|
||||
mForceResize = false;
|
||||
//set new rect, respecting position mode and data defined size/position
|
||||
QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() );
|
||||
setSceneRect( evalItemRect( targetRect, true ) );
|
||||
}
|
||||
else if ( size.height() > rect().height() || size.width() > rect().width() )
|
||||
{
|
||||
//need to resize box
|
||||
QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
|
||||
@ -673,6 +683,8 @@ void QgsComposerLegend::doUpdateFilterByMap()
|
||||
}
|
||||
else
|
||||
mLegendModel2->setLegendFilterByMap( nullptr );
|
||||
|
||||
mForceResize = true;
|
||||
}
|
||||
|
||||
void QgsComposerLegend::setLegendFilterOutAtlas( bool doFilter )
|
||||
|
@ -296,6 +296,9 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
|
||||
|
||||
//! Will be false until the associated map scale and DPI have been calculated
|
||||
bool mInitialMapScaleCalculated;
|
||||
|
||||
//! Will be true if the legend size should be totally reset at next paint
|
||||
bool mForceResize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -22,7 +22,8 @@ from qgis.core import (QgsComposerLegend,
|
||||
QgsVectorLayer,
|
||||
QgsMapLayerRegistry,
|
||||
QgsMarkerSymbolV2,
|
||||
QgsSingleSymbolRendererV2
|
||||
QgsSingleSymbolRendererV2,
|
||||
QgsRectangle
|
||||
)
|
||||
from qgis.testing import (start_app,
|
||||
unittest
|
||||
@ -37,22 +38,19 @@ TEST_DATA_DIR = unitTestDataPath()
|
||||
|
||||
class TestQgsComposerLegend(unittest.TestCase):
|
||||
|
||||
def __init__(self, methodName):
|
||||
"""Run once on class initialization."""
|
||||
unittest.TestCase.__init__(self, methodName)
|
||||
point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
|
||||
self.point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
|
||||
QgsMapLayerRegistry.instance().addMapLayers([self.point_layer])
|
||||
|
||||
def testInitialSizeSymbolMapUnits(self):
|
||||
"""Test initial size of legend with a symbol size in map units"""
|
||||
|
||||
point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
|
||||
point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
|
||||
QgsMapLayerRegistry.instance().addMapLayers([point_layer])
|
||||
|
||||
marker_symbol = QgsMarkerSymbolV2.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'})
|
||||
|
||||
self.point_layer.setRendererV2(QgsSingleSymbolRendererV2(marker_symbol))
|
||||
point_layer.setRendererV2(QgsSingleSymbolRendererV2(marker_symbol))
|
||||
|
||||
s = QgsMapSettings()
|
||||
s.setLayers([self.point_layer.id()])
|
||||
s.setLayers([point_layer.id()])
|
||||
s.setCrsTransformEnabled(False)
|
||||
composition = QgsComposition(s)
|
||||
composition.setPaperSize(297, 210)
|
||||
@ -60,7 +58,7 @@ class TestQgsComposerLegend(unittest.TestCase):
|
||||
composer_map = QgsComposerMap(composition, 20, 20, 80, 80)
|
||||
composer_map.setFrameEnabled(True)
|
||||
composition.addComposerMap(composer_map)
|
||||
composer_map.setNewExtent(self.point_layer.extent())
|
||||
composer_map.setNewExtent(point_layer.extent())
|
||||
|
||||
legend = QgsComposerLegend(composition)
|
||||
legend.setSceneRect(QRectF(120, 20, 80, 80))
|
||||
@ -77,6 +75,46 @@ class TestQgsComposerLegend(unittest.TestCase):
|
||||
result, message = checker.testComposition()
|
||||
self.assertTrue(result, message)
|
||||
|
||||
QgsMapLayerRegistry.instance().removeMapLayers([point_layer])
|
||||
|
||||
def testResizeWithMapContent(self):
|
||||
"""Test test legend resizes to match map content"""
|
||||
|
||||
point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
|
||||
point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
|
||||
QgsMapLayerRegistry.instance().addMapLayers([point_layer])
|
||||
|
||||
s = QgsMapSettings()
|
||||
s.setLayers([point_layer.id()])
|
||||
s.setCrsTransformEnabled(False)
|
||||
composition = QgsComposition(s)
|
||||
composition.setPaperSize(297, 210)
|
||||
|
||||
composer_map = QgsComposerMap(composition, 20, 20, 80, 80)
|
||||
composer_map.setFrameEnabled(True)
|
||||
composition.addComposerMap(composer_map)
|
||||
composer_map.setNewExtent(point_layer.extent())
|
||||
|
||||
legend = QgsComposerLegend(composition)
|
||||
legend.setSceneRect(QRectF(120, 20, 80, 80))
|
||||
legend.setFrameEnabled(True)
|
||||
legend.setFrameOutlineWidth(2)
|
||||
legend.setBackgroundColor(QColor(200, 200, 200))
|
||||
legend.setTitle('')
|
||||
legend.setLegendFilterByMapEnabled(True)
|
||||
composition.addComposerLegend(legend)
|
||||
legend.setComposerMap(composer_map)
|
||||
|
||||
composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30))
|
||||
|
||||
checker = QgsCompositionChecker(
|
||||
'composer_legend_size_content', composition)
|
||||
checker.setControlPathPrefix("composer_legend")
|
||||
result, message = checker.testComposition()
|
||||
self.assertTrue(result, message)
|
||||
|
||||
QgsMapLayerRegistry.instance().removeMapLayers([point_layer])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
Loading…
x
Reference in New Issue
Block a user