Skip to content

Commit f60da58

Browse files
committedDec 6, 2017
Add some unit tests
1 parent b74a0ef commit f60da58

File tree

8 files changed

+276
-13
lines changed

8 files changed

+276
-13
lines changed
 

‎python/core/composer/qgscomposeritem.sip

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,17 @@ class QgsComposerItem: QgsComposerObject, QGraphicsRectItem
3030
#include <qgscomposerpolygon.h>
3131
#include <qgscomposerpolyline.h>
3232
#include <qgscomposertexttable.h>
33-
#include <qgslayoutitemshape.h>
34-
#include <qgslayoutitempage.h>
33+
#include "qgslayoutitemgroup.h"
34+
#include "qgslayoutitemmap.h"
35+
#include "qgslayoutitempicture.h"
36+
#include "qgslayoutitemlabel.h"
37+
#include "qgslayoutitemlegend.h"
38+
#include "qgslayoutitempolygon.h"
39+
#include "qgslayoutitempolyline.h"
40+
#include "qgslayoutitemscalebar.h"
41+
#include "qgslayoutframe.h"
42+
#include "qgslayoutitemshape.h"
43+
#include "qgslayoutitempage.h"
3544
%End
3645
%ConvertToSubClassCode
3746
// the conversions have to be static, because they're using multiple inheritance
@@ -102,9 +111,49 @@ class QgsComposerItem: QgsComposerObject, QGraphicsRectItem
102111
{
103112
// really, these *should* use the constants from QgsLayoutItemRegistry, but sip doesn't like that!
104113
case QGraphicsItem::UserType + 101:
114+
sipType = sipType_QgsLayoutItemGroup;
115+
*sipCppRet = static_cast<QgsLayoutItemGroup *>( sipCpp );
116+
break;
117+
case QGraphicsItem::UserType + 102:
105118
sipType = sipType_QgsLayoutItemPage;
106119
*sipCppRet = static_cast<QgsLayoutItemPage *>( sipCpp );
107120
break;
121+
case QGraphicsItem::UserType + 103:
122+
sipType = sipType_QgsLayoutItemMap;
123+
*sipCppRet = static_cast<QgsLayoutItemMap *>( sipCpp );
124+
break;
125+
case QGraphicsItem::UserType + 104:
126+
sipType = sipType_QgsLayoutItemPicture;
127+
*sipCppRet = static_cast<QgsLayoutItemPicture *>( sipCpp );
128+
break;
129+
case QGraphicsItem::UserType + 105:
130+
sipType = sipType_QgsLayoutItemLabel;
131+
*sipCppRet = static_cast<QgsLayoutItemLabel *>( sipCpp );
132+
break;
133+
case QGraphicsItem::UserType + 106:
134+
sipType = sipType_QgsLayoutItemLegend;
135+
*sipCppRet = static_cast<QgsLayoutItemLegend *>( sipCpp );
136+
break;
137+
case QGraphicsItem::UserType + 107:
138+
sipType = sipType_QgsLayoutItemShape;
139+
*sipCppRet = static_cast<QgsLayoutItemShape *>( sipCpp );
140+
break;
141+
case QGraphicsItem::UserType + 108:
142+
sipType = sipType_QgsLayoutItemPolygon;
143+
*sipCppRet = static_cast<QgsLayoutItemPolygon *>( sipCpp );
144+
break;
145+
case QGraphicsItem::UserType + 109:
146+
sipType = sipType_QgsLayoutItemPolyline;
147+
*sipCppRet = static_cast<QgsLayoutItemPolyline *>( sipCpp );
148+
break;
149+
case QGraphicsItem::UserType + 110:
150+
sipType = sipType_QgsLayoutItemScaleBar;
151+
*sipCppRet = static_cast<QgsLayoutItemScaleBar *>( sipCpp );
152+
break;
153+
case QGraphicsItem::UserType + 111:
154+
sipType = sipType_QgsLayoutFrame;
155+
*sipCppRet = static_cast<QgsLayoutFrame *>( sipCpp );
156+
break;
108157
default:
109158
sipType = 0;
110159
}

‎python/core/layout/qgslayout.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
424424
:rtype: bool
425425
%End
426426

427-
QVector< QgsLayoutItem * > addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document,
427+
QList< QgsLayoutItem * > addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document,
428428
const QgsReadWriteContext &context,
429429
QPointF *position = 0, bool pasteInPlace = false );
430430
%Docstring

‎python/core/layout/qgslayoutitem.sip

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
1818

1919
%TypeHeaderCode
2020
#include "qgslayoutitem.h"
21-
#include <qgslayoutitemshape.h>
22-
#include <qgslayoutitempage.h>
21+
#include "qgslayoutitemgroup.h"
22+
#include "qgslayoutitemmap.h"
23+
#include "qgslayoutitempicture.h"
24+
#include "qgslayoutitemlabel.h"
25+
#include "qgslayoutitemlegend.h"
26+
#include "qgslayoutitempolygon.h"
27+
#include "qgslayoutitempolyline.h"
28+
#include "qgslayoutitemscalebar.h"
29+
#include "qgslayoutframe.h"
30+
#include "qgslayoutitemshape.h"
31+
#include "qgslayoutitempage.h"
2332
%End
2433
%ConvertToSubClassCode
2534
// the conversions have to be static, because they're using multiple inheritance
@@ -28,9 +37,49 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
2837
{
2938
// really, these *should* use the constants from QgsLayoutItemRegistry, but sip doesn't like that!
3039
case QGraphicsItem::UserType + 101:
40+
sipType = sipType_QgsLayoutItemGroup;
41+
*sipCppRet = static_cast<QgsLayoutItemGroup *>( sipCpp );
42+
break;
43+
case QGraphicsItem::UserType + 102:
3144
sipType = sipType_QgsLayoutItemPage;
3245
*sipCppRet = static_cast<QgsLayoutItemPage *>( sipCpp );
3346
break;
47+
case QGraphicsItem::UserType + 103:
48+
sipType = sipType_QgsLayoutItemMap;
49+
*sipCppRet = static_cast<QgsLayoutItemMap *>( sipCpp );
50+
break;
51+
case QGraphicsItem::UserType + 104:
52+
sipType = sipType_QgsLayoutItemPicture;
53+
*sipCppRet = static_cast<QgsLayoutItemPicture *>( sipCpp );
54+
break;
55+
case QGraphicsItem::UserType + 105:
56+
sipType = sipType_QgsLayoutItemLabel;
57+
*sipCppRet = static_cast<QgsLayoutItemLabel *>( sipCpp );
58+
break;
59+
case QGraphicsItem::UserType + 106:
60+
sipType = sipType_QgsLayoutItemLegend;
61+
*sipCppRet = static_cast<QgsLayoutItemLegend *>( sipCpp );
62+
break;
63+
case QGraphicsItem::UserType + 107:
64+
sipType = sipType_QgsLayoutItemShape;
65+
*sipCppRet = static_cast<QgsLayoutItemShape *>( sipCpp );
66+
break;
67+
case QGraphicsItem::UserType + 108:
68+
sipType = sipType_QgsLayoutItemPolygon;
69+
*sipCppRet = static_cast<QgsLayoutItemPolygon *>( sipCpp );
70+
break;
71+
case QGraphicsItem::UserType + 109:
72+
sipType = sipType_QgsLayoutItemPolyline;
73+
*sipCppRet = static_cast<QgsLayoutItemPolyline *>( sipCpp );
74+
break;
75+
case QGraphicsItem::UserType + 110:
76+
sipType = sipType_QgsLayoutItemScaleBar;
77+
*sipCppRet = static_cast<QgsLayoutItemScaleBar *>( sipCpp );
78+
break;
79+
case QGraphicsItem::UserType + 111:
80+
sipType = sipType_QgsLayoutFrame;
81+
*sipCppRet = static_cast<QgsLayoutFrame *>( sipCpp );
82+
break;
3483
default:
3584
sipType = 0;
3685
}

‎src/core/composer/qgscomposeritem.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,17 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
5454
#include <qgscomposerpolygon.h>
5555
#include <qgscomposerpolyline.h>
5656
#include <qgscomposertexttable.h>
57-
#include <qgslayoutitemshape.h>
58-
#include <qgslayoutitempage.h>
57+
#include "qgslayoutitemgroup.h"
58+
#include "qgslayoutitemmap.h"
59+
#include "qgslayoutitempicture.h"
60+
#include "qgslayoutitemlabel.h"
61+
#include "qgslayoutitemlegend.h"
62+
#include "qgslayoutitempolygon.h"
63+
#include "qgslayoutitempolyline.h"
64+
#include "qgslayoutitemscalebar.h"
65+
#include "qgslayoutframe.h"
66+
#include "qgslayoutitemshape.h"
67+
#include "qgslayoutitempage.h"
5968
#endif
6069

6170

@@ -129,9 +138,49 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
129138
{
130139
// really, these *should* use the constants from QgsLayoutItemRegistry, but sip doesn't like that!
131140
case QGraphicsItem::UserType + 101:
141+
sipType = sipType_QgsLayoutItemGroup;
142+
*sipCppRet = static_cast<QgsLayoutItemGroup *>( sipCpp );
143+
break;
144+
case QGraphicsItem::UserType + 102:
132145
sipType = sipType_QgsLayoutItemPage;
133146
*sipCppRet = static_cast<QgsLayoutItemPage *>( sipCpp );
134147
break;
148+
case QGraphicsItem::UserType + 103:
149+
sipType = sipType_QgsLayoutItemMap;
150+
*sipCppRet = static_cast<QgsLayoutItemMap *>( sipCpp );
151+
break;
152+
case QGraphicsItem::UserType + 104:
153+
sipType = sipType_QgsLayoutItemPicture;
154+
*sipCppRet = static_cast<QgsLayoutItemPicture *>( sipCpp );
155+
break;
156+
case QGraphicsItem::UserType + 105:
157+
sipType = sipType_QgsLayoutItemLabel;
158+
*sipCppRet = static_cast<QgsLayoutItemLabel *>( sipCpp );
159+
break;
160+
case QGraphicsItem::UserType + 106:
161+
sipType = sipType_QgsLayoutItemLegend;
162+
*sipCppRet = static_cast<QgsLayoutItemLegend *>( sipCpp );
163+
break;
164+
case QGraphicsItem::UserType + 107:
165+
sipType = sipType_QgsLayoutItemShape;
166+
*sipCppRet = static_cast<QgsLayoutItemShape *>( sipCpp );
167+
break;
168+
case QGraphicsItem::UserType + 108:
169+
sipType = sipType_QgsLayoutItemPolygon;
170+
*sipCppRet = static_cast<QgsLayoutItemPolygon *>( sipCpp );
171+
break;
172+
case QGraphicsItem::UserType + 109:
173+
sipType = sipType_QgsLayoutItemPolyline;
174+
*sipCppRet = static_cast<QgsLayoutItemPolyline *>( sipCpp );
175+
break;
176+
case QGraphicsItem::UserType + 110:
177+
sipType = sipType_QgsLayoutItemScaleBar;
178+
*sipCppRet = static_cast<QgsLayoutItemScaleBar *>( sipCpp );
179+
break;
180+
case QGraphicsItem::UserType + 111:
181+
sipType = sipType_QgsLayoutFrame;
182+
*sipCppRet = static_cast<QgsLayoutFrame *>( sipCpp );
183+
break;
135184
default:
136185
sipType = 0;
137186
}

‎src/core/layout/qgslayout.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,11 @@ bool QgsLayout::readXml( const QDomElement &layoutElement, const QDomDocument &d
716716
return true;
717717
}
718718

719-
QVector< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context, QPointF *position, bool pasteInPlace )
719+
QList< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context, QPointF *position, bool pasteInPlace )
720720
{
721721
std::unique_ptr< QPointF > pasteInPlacePt;
722-
QVector< QgsLayoutItem * > newItems;
723-
QVector< QgsLayoutMultiFrame * > newMultiFrames;
722+
QList< QgsLayoutItem * > newItems;
723+
QList< QgsLayoutMultiFrame * > newMultiFrames;
724724

725725
//if we are adding items to a layout which already contains items, we need to make sure
726726
//these items are placed at the top of the layout and that zValues are not duplicated

‎src/core/layout/qgslayout.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
482482
*
483483
* A list of the newly added items is returned.
484484
*/
485-
QVector< QgsLayoutItem * > addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document,
485+
QList< QgsLayoutItem * > addItemsFromXml( const QDomElement &parentElement, const QDomDocument &document,
486486
const QgsReadWriteContext &context,
487487
QPointF *position = nullptr, bool pasteInPlace = false );
488488

‎src/core/layout/qgslayoutitem.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,17 @@ class QgsLayoutEffect;
4141
class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectItem, public QgsLayoutUndoObjectInterface
4242
{
4343
#ifdef SIP_RUN
44-
#include <qgslayoutitemshape.h>
45-
#include <qgslayoutitempage.h>
44+
#include "qgslayoutitemgroup.h"
45+
#include "qgslayoutitemmap.h"
46+
#include "qgslayoutitempicture.h"
47+
#include "qgslayoutitemlabel.h"
48+
#include "qgslayoutitemlegend.h"
49+
#include "qgslayoutitempolygon.h"
50+
#include "qgslayoutitempolyline.h"
51+
#include "qgslayoutitemscalebar.h"
52+
#include "qgslayoutframe.h"
53+
#include "qgslayoutitemshape.h"
54+
#include "qgslayoutitempage.h"
4655
#endif
4756

4857

@@ -54,9 +63,49 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
5463
{
5564
// really, these *should* use the constants from QgsLayoutItemRegistry, but sip doesn't like that!
5665
case QGraphicsItem::UserType + 101:
66+
sipType = sipType_QgsLayoutItemGroup;
67+
*sipCppRet = static_cast<QgsLayoutItemGroup *>( sipCpp );
68+
break;
69+
case QGraphicsItem::UserType + 102:
5770
sipType = sipType_QgsLayoutItemPage;
5871
*sipCppRet = static_cast<QgsLayoutItemPage *>( sipCpp );
5972
break;
73+
case QGraphicsItem::UserType + 103:
74+
sipType = sipType_QgsLayoutItemMap;
75+
*sipCppRet = static_cast<QgsLayoutItemMap *>( sipCpp );
76+
break;
77+
case QGraphicsItem::UserType + 104:
78+
sipType = sipType_QgsLayoutItemPicture;
79+
*sipCppRet = static_cast<QgsLayoutItemPicture *>( sipCpp );
80+
break;
81+
case QGraphicsItem::UserType + 105:
82+
sipType = sipType_QgsLayoutItemLabel;
83+
*sipCppRet = static_cast<QgsLayoutItemLabel *>( sipCpp );
84+
break;
85+
case QGraphicsItem::UserType + 106:
86+
sipType = sipType_QgsLayoutItemLegend;
87+
*sipCppRet = static_cast<QgsLayoutItemLegend *>( sipCpp );
88+
break;
89+
case QGraphicsItem::UserType + 107:
90+
sipType = sipType_QgsLayoutItemShape;
91+
*sipCppRet = static_cast<QgsLayoutItemShape *>( sipCpp );
92+
break;
93+
case QGraphicsItem::UserType + 108:
94+
sipType = sipType_QgsLayoutItemPolygon;
95+
*sipCppRet = static_cast<QgsLayoutItemPolygon *>( sipCpp );
96+
break;
97+
case QGraphicsItem::UserType + 109:
98+
sipType = sipType_QgsLayoutItemPolyline;
99+
*sipCppRet = static_cast<QgsLayoutItemPolyline *>( sipCpp );
100+
break;
101+
case QGraphicsItem::UserType + 110:
102+
sipType = sipType_QgsLayoutItemScaleBar;
103+
*sipCppRet = static_cast<QgsLayoutItemScaleBar *>( sipCpp );
104+
break;
105+
case QGraphicsItem::UserType + 111:
106+
sipType = sipType_QgsLayoutFrame;
107+
*sipCppRet = static_cast<QgsLayoutFrame *>( sipCpp );
108+
break;
60109
default:
61110
sipType = 0;
62111
}

‎tests/src/python/test_qgslayout.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
QgsLayoutGuide,
2222
QgsLayoutObject,
2323
QgsProject,
24+
QgsLayoutItemGroup,
2425
QgsProperty,
2526
QgsLayoutPageCollection,
2627
QgsLayoutMeasurement,
@@ -62,6 +63,14 @@ def testReadWriteXml(self):
6263
snapper = l.snapper()
6364
snapper.setSnapTolerance(7)
6465

66+
# add some items
67+
item1 = QgsLayoutItemMap(l)
68+
item1.setId('xxyyxx')
69+
l.addItem(item1)
70+
item2 = QgsLayoutItemMap(l)
71+
item2.setId('zzyyzz')
72+
l.addItem(item2)
73+
6574
doc = QDomDocument("testdoc")
6675
elem = l.writeXml(doc, QgsReadWriteContext())
6776

@@ -81,6 +90,64 @@ def testReadWriteXml(self):
8190
self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(), QgsUnitTypes.LayoutCentimeters)
8291
self.assertEqual(l2.snapper().snapTolerance(), 7)
8392

93+
# check restored items
94+
new_item1 = l2.itemByUuid(item1.uuid())
95+
self.assertTrue(new_item1)
96+
self.assertEqual(new_item1.id(), 'xxyyxx')
97+
new_item2 = l2.itemByUuid(item2.uuid())
98+
self.assertTrue(new_item2)
99+
self.assertEqual(new_item2.id(), 'zzyyzz')
100+
101+
def testAddItemsFromXml(self):
102+
p = QgsProject()
103+
l = QgsLayout(p)
104+
105+
# add some items
106+
item1 = QgsLayoutItemMap(l)
107+
item1.setId('xxyyxx')
108+
l.addItem(item1)
109+
item2 = QgsLayoutItemMap(l)
110+
item2.setId('zzyyzz')
111+
l.addItem(item2)
112+
113+
doc = QDomDocument("testdoc")
114+
# store in xml
115+
elem = l.writeXml(doc, QgsReadWriteContext())
116+
117+
l2 = QgsLayout(p)
118+
new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext())
119+
self.assertEqual(len(new_items), 2)
120+
items = l2.items()
121+
self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
122+
self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
123+
self.assertTrue(new_items[0] in l2.items())
124+
self.assertTrue(new_items[1] in l2.items())
125+
126+
# test with a group
127+
group = QgsLayoutItemGroup(l)
128+
group.addItem(item1)
129+
group.addItem(item2)
130+
l.addLayoutItem(group)
131+
elem = l.writeXml(doc, QgsReadWriteContext())
132+
133+
l3 = QgsLayout(p)
134+
new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext())
135+
self.assertEqual(len(new_items), 3)
136+
items = l3.items()
137+
self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
138+
self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
139+
self.assertTrue(new_items[0] in l3.items())
140+
self.assertTrue(new_items[1] in l3.items())
141+
self.assertTrue(new_items[2] in l3.items())
142+
143+
# f*** you sip, I'll just manually cast
144+
new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup)
145+
self.assertIsNotNone(new_group)
146+
other_items = [i for i in new_items if i.type() != new_group.type()]
147+
self.assertCountEqual(new_group.items(), other_items)
148+
149+
#TODO - test restoring multiframe, test item positions
150+
84151
def testSelectedItems(self):
85152
p = QgsProject()
86153
l = QgsLayout(p)

0 commit comments

Comments
 (0)
Please sign in to comment.