diff --git a/src/core/composer/qgscomposerlegend.cpp b/src/core/composer/qgscomposerlegend.cpp index 06a736d15084..0f1ea7f044e9 100644 --- a/src/core/composer/qgscomposerlegend.cpp +++ b/src/core/composer/qgscomposerlegend.cpp @@ -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 ) diff --git a/src/core/composer/qgscomposerlegend.h b/src/core/composer/qgscomposerlegend.h index 31a3645e6133..0da8b5ee3cc0 100644 --- a/src/core/composer/qgscomposerlegend.h +++ b/src/core/composer/qgscomposerlegend.h @@ -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 diff --git a/tests/src/python/test_qgscomposerlegend.py b/tests/src/python/test_qgscomposerlegend.py index 0443b3791f98..7d0fc62c1ece 100644 --- a/tests/src/python/test_qgscomposerlegend.py +++ b/tests/src/python/test_qgscomposerlegend.py @@ -22,7 +22,8 @@ QgsVectorLayer, QgsMapLayerRegistry, QgsMarkerSymbolV2, - QgsSingleSymbolRendererV2 + QgsSingleSymbolRendererV2, + QgsRectangle ) from qgis.testing import (start_app, unittest @@ -37,22 +38,19 @@ 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 @@ def testInitialSizeSymbolMapUnits(self): 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 @@ def testInitialSizeSymbolMapUnits(self): 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() diff --git a/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content.png b/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content.png new file mode 100644 index 000000000000..604dbbcb6dfd Binary files /dev/null and b/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content.png differ diff --git a/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content_mask.png b/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content_mask.png new file mode 100644 index 000000000000..4451dd55ca83 Binary files /dev/null and b/tests/testdata/control_images/composer_legend/expected_composer_legend_size_content/expected_composer_legend_size_content_mask.png differ