Skip to content

Commit a59dce5

Browse files
committed
Move containsAdvancedEffects test to QgsLayoutItem
And start a generic test library for all item types to ensure correct behavior for QgsLayoutItem subclasses Currently justs tests to ensure that overriden containsAdvancedEffects methods also call the base class test
1 parent 0110b43 commit a59dce5

17 files changed

+226
-10
lines changed

python/core/layout/qgslayoutitem.sip

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,16 @@ Sets whether the item should be excluded from composer exports and prints.
820820
.. seealso:: :py:func:`excludeFromExports()`
821821
%End
822822

823+
virtual bool containsAdvancedEffects() const;
824+
%Docstring
825+
Returns true if the item contains contents with blend modes or transparency
826+
effects which can only be reproduced by rastering the item.
827+
828+
Subclasses should ensure that implemented overrides of this method
829+
also check the base class result.
830+
:rtype: bool
831+
%End
832+
823833
virtual double estimatedFrameBleed() const;
824834
%Docstring
825835
Returns the estimated amount the item's frame bleeds outside the item's

src/core/layout/qgslayoutitem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,11 @@ void QgsLayoutItem::setExcludeFromExports( bool exclude )
840840
refreshDataDefinedProperty( QgsLayoutObject::ExcludeFromExports );
841841
}
842842

843+
bool QgsLayoutItem::containsAdvancedEffects() const
844+
{
845+
return blendMode() != QPainter::CompositionMode_SourceOver;
846+
}
847+
843848
double QgsLayoutItem::estimatedFrameBleed() const
844849
{
845850
if ( !hasFrame() )

src/core/layout/qgslayoutitem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,15 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
742742
*/
743743
void setExcludeFromExports( bool exclude );
744744

745+
/**
746+
* Returns true if the item contains contents with blend modes or transparency
747+
* effects which can only be reproduced by rastering the item.
748+
*
749+
* Subclasses should ensure that implemented overrides of this method
750+
* also check the base class result.
751+
*/
752+
virtual bool containsAdvancedEffects() const;
753+
745754
/**
746755
* Returns the estimated amount the item's frame bleeds outside the item's
747756
* actual rectangle. For instance, if the item has a 2mm frame stroke, then

src/core/layout/qgslayoutitemmap.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ bool QgsLayoutItemMap::containsWmsLayer() const
379379

380380
bool QgsLayoutItemMap::containsAdvancedEffects() const
381381
{
382+
if ( QgsLayoutItem::containsAdvancedEffects() )
383+
return true;
384+
382385
//check easy things first
383386

384387
//overviews

src/core/layout/qgslayoutitemmap.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
9191
int numberExportLayers() const override;
9292
void setFrameStrokeWidth( const QgsLayoutMeasurement &width ) override;
9393

94-
9594
/**
9695
* Returns the map scale.
9796
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
@@ -276,8 +275,7 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
276275
//! Returns true if the map contains a WMS layer.
277276
bool containsWmsLayer() const;
278277

279-
//! Returns true if the map contains layers with blend modes or flattened layers for vectors
280-
bool containsAdvancedEffects() const;
278+
bool containsAdvancedEffects() const override;
281279

282280
/**
283281
* Sets the \a rotation for the map - this does not affect the composer item shape, only the

tests/src/python/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ ADD_PYTHON_TEST(PyQgsLayerTree test_qgslayertree.py)
8484
ADD_PYTHON_TEST(PyQgsLayout test_qgslayout.py)
8585
ADD_PYTHON_TEST(PyQgsLayoutAlign test_qgslayoutaligner.py)
8686
ADD_PYTHON_TEST(PyQgsLayoutExporter test_qgslayoutexporter.py)
87+
ADD_PYTHON_TEST(PyQgsLayoutFrame test_qgslayoutframe.py)
8788
ADD_PYTHON_TEST(PyQgsLayoutManager test_qgslayoutmanager.py)
8889
ADD_PYTHON_TEST(PyQgsLayoutPageCollection test_qgslayoutpagecollection.py)
8990
ADD_PYTHON_TEST(PyQgsLayoutView test_qgslayoutview.py)
@@ -96,9 +97,12 @@ ADD_PYTHON_TEST(PyQgsLayoutLabel test_qgslayoutlabel.py)
9697
ADD_PYTHON_TEST(PyQgsLayoutLegend test_qgslayoutlegend.py)
9798
ADD_PYTHON_TEST(PyQgsLayoutMap test_qgslayoutmap.py)
9899
ADD_PYTHON_TEST(PyQgsLayoutMapGrid test_qgslayoutmapgrid.py)
100+
ADD_PYTHON_TEST(PyQgsLayoutPage test_qgslayoutpage.py)
99101
ADD_PYTHON_TEST(PyQgsLayoutPicture test_qgslayoutpicture.py)
100102
ADD_PYTHON_TEST(PyQgsLayoutPolygon test_qgslayoutpolygon.py)
101103
ADD_PYTHON_TEST(PyQgsLayoutPolyline test_qgslayoutpolyline.py)
104+
ADD_PYTHON_TEST(PyQgsLayoutScaleBar test_qgslayoutscalebar.py)
105+
ADD_PYTHON_TEST(PyQgsLayoutShape test_qgslayoutshape.py)
102106
ADD_PYTHON_TEST(PyQgsLayoutSnapper test_qgslayoutsnapper.py)
103107
ADD_PYTHON_TEST(PyQgsLayoutUnitsComboBox test_qgslayoutunitscombobox.py)
104108
ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsLayoutFrame.
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = '(C) 2017 by Nyall Dawson'
10+
__date__ = '23/10/2017'
11+
__copyright__ = 'Copyright 2017, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
import qgis # NOQA
16+
17+
from qgis.testing import start_app, unittest
18+
from qgis.core import QgsLayoutFrame, QgsLayoutItemHtml
19+
20+
from test_qgslayoutitem import LayoutItemTestCase
21+
22+
start_app()
23+
24+
25+
class TestQgsLayoutFrame(unittest.TestCase, LayoutItemTestCase):
26+
27+
@classmethod
28+
def setUpClass(cls):
29+
cls.mf = None
30+
31+
@classmethod
32+
def createItem(cls, layout):
33+
cls.mf = QgsLayoutItemHtml(layout)
34+
return QgsLayoutFrame(layout, cls.mf)
35+
36+
37+
if __name__ == '__main__':
38+
unittest.main()

tests/src/python/test_qgslayoutitem.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,34 @@
2626
QgsLayoutSize,
2727
QgsApplication)
2828
from qgis.PyQt.QtCore import QRectF
29-
from qgis.PyQt.QtGui import QColor
29+
from qgis.PyQt.QtGui import QColor, QPainter
3030
from qgis.PyQt.QtTest import QSignalSpy
3131

3232

3333
start_app()
3434

3535

36+
class LayoutItemTestCase(object):
37+
38+
'''
39+
This is a collection of generic tests for QgsLayoutItem subclasses.
40+
To make use of it, subclass it and set self.item_class to a QgsLayoutItem subclass you want to test.
41+
'''
42+
43+
def make_item(self, layout):
44+
if hasattr(self, 'item_class'):
45+
return self.item_class(layout)
46+
else:
47+
return self.createItem(layout)
48+
49+
def testContainsAdvancedEffects(self):
50+
l = QgsLayout(QgsProject.instance())
51+
item = self.make_item(l)
52+
self.assertFalse(item.containsAdvancedEffects())
53+
item.setBlendMode(QPainter.CompositionMode_SourceIn)
54+
self.assertTrue(item.containsAdvancedEffects())
55+
56+
3657
class TestQgsLayoutItem(unittest.TestCase):
3758

3859
def testDataDefinedFrameColor(self):

tests/src/python/test_qgslayoutlabel.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
from qgis.core import QgsVectorLayer, QgsLayout, QgsLayoutItemLabel, QgsProject
2020
from utilities import unitTestDataPath
2121

22+
from test_qgslayoutitem import LayoutItemTestCase
2223

2324
start_app()
2425

2526

26-
class TestQgsLayoutItemLabel(unittest.TestCase):
27+
class TestQgsLayoutItemLabel(unittest.TestCase, LayoutItemTestCase):
28+
29+
@classmethod
30+
def setUpClass(cls):
31+
cls.item_class = QgsLayoutItemLabel
2732

2833
def testCase(self):
2934
TEST_DATA_DIR = unitTestDataPath()

tests/src/python/test_qgslayoutlegend.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,17 @@
3434
from qgslayoutchecker import QgsLayoutChecker
3535
import os
3636

37+
from test_qgslayoutitem import LayoutItemTestCase
38+
3739
start_app()
3840
TEST_DATA_DIR = unitTestDataPath()
3941

4042

41-
class TestQgsLayoutItemLegend(unittest.TestCase):
43+
class TestQgsLayoutItemLegend(unittest.TestCase, LayoutItemTestCase):
44+
45+
@classmethod
46+
def setUpClass(cls):
47+
cls.item_class = QgsLayoutItemLegend
4248

4349
def testInitialSizeSymbolMapUnits(self):
4450
"""Test initial size of legend with a symbol size in map units"""

0 commit comments

Comments
 (0)