Skip to content

Commit 39bf23a

Browse files
committedJul 25, 2017
Start on reflow support for page collections (needs tests)
1 parent 79a4694 commit 39bf23a

File tree

9 files changed

+389
-2
lines changed

9 files changed

+389
-2
lines changed
 

‎python/core/layout/qgslayout.sip

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
2929
QgsLayout( QgsProject *project );
3030
%Docstring
3131
Construct a new layout linked to the specified ``project``.
32+
33+
If the layout is a "new" layout (as opposed to a layout which will
34+
restore a previous state from XML) then initializeDefaults() should be
35+
called on the new layout.
36+
%End
37+
38+
void initializeDefaults();
39+
%Docstring
40+
Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
41+
a new layout.
3242
%End
3343

3444
QgsProject *project() const;
@@ -191,6 +201,29 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
191201
:rtype: QgsLayoutPageCollection
192202
%End
193203

204+
QRectF layoutBounds( bool ignorePages = false, double margin = 0.0 ) const;
205+
%Docstring
206+
Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles
207+
and other cosmetic items.
208+
\param ignorePages set to true to ignore page items
209+
\param margin optional marginal (in percent, e.g., 0.05 = 5% ) to add around items
210+
:return: layout bounds, in layout units.
211+
:rtype: QRectF
212+
%End
213+
214+
void addLayoutItem( QgsLayoutItem *item /Transfer/ );
215+
%Docstring
216+
Adds an ``item`` to the layout. This should be called instead of the base class addItem()
217+
method. Ownership of the item is transferred to the layout.
218+
%End
219+
220+
public slots:
221+
222+
void updateBounds();
223+
%Docstring
224+
Updates the scene bounds of the layout.
225+
%End
226+
194227
signals:
195228

196229
void variablesChanged();

‎python/core/layout/qgslayoutpagecollection.sip

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class QgsLayoutPageCollection : QObject
6565
to the collection, and the page will automatically be added to the collection's
6666
layout() (there is no need to manually add the page item to the layout).
6767
The page will be added after all pages currently contained in the collection.
68+
69+
Calling addPage() automatically triggers a reflow() of pages.
70+
6871
.. seealso:: insertPage()
6972
%End
7073

@@ -80,6 +83,8 @@ class QgsLayoutPageCollection : QObject
8083
(Page numbers in collections begin at 0 - so a ``beforePage`` of 0 will insert
8184
the page before all existing pages).
8285

86+
Calling insertPage() automatically triggers a reflow() of pages.
87+
8388
.. seealso:: addPage()
8489
%End
8590

@@ -90,6 +95,8 @@ class QgsLayoutPageCollection : QObject
9095

9196
Page numbers in collections begin at 0 - so a ``pageNumber`` of 0 will delete
9297
the first page in the collection.
98+
99+
Calling deletePage() automatically triggers a reflow() of pages.
93100
%End
94101

95102
void setPageStyleSymbol( QgsFillSymbol *symbol );
@@ -107,6 +114,19 @@ class QgsLayoutPageCollection : QObject
107114
:rtype: QgsFillSymbol
108115
%End
109116

117+
void reflow();
118+
%Docstring
119+
Forces the page collection to reflow the arrangement of pages, e.g. to account
120+
for page size/orientation change.
121+
%End
122+
123+
double maximumPageWidth() const;
124+
%Docstring
125+
Returns the maximum width of pages in the collection. The returned value is
126+
in layout units.
127+
:rtype: float
128+
%End
129+
110130
};
111131

112132
/************************************************************************

‎src/core/layout/qgslayout.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ QgsLayout::QgsLayout( QgsProject *project )
2525
setBackgroundBrush( QColor( 215, 215, 215 ) );
2626
}
2727

28+
void QgsLayout::initializeDefaults()
29+
{
30+
// default to a A4 landscape page
31+
QgsLayoutItemPage *page = new QgsLayoutItemPage( this );
32+
page->setPageSize( QgsLayoutSize( 297, 210, QgsUnitTypes::LayoutMillimeters ) );
33+
mPageCollection->addPage( page );
34+
}
35+
2836
QgsProject *QgsLayout::project() const
2937
{
3038
return mProject;
@@ -112,3 +120,48 @@ QgsLayoutPageCollection *QgsLayout::pageCollection()
112120
{
113121
return mPageCollection.get();
114122
}
123+
124+
QRectF QgsLayout::layoutBounds( bool ignorePages, double margin ) const
125+
{
126+
//start with an empty rectangle
127+
QRectF bounds;
128+
129+
//add all QgsComposerItems and QgsPaperItems which are in the composition
130+
Q_FOREACH ( const QGraphicsItem *item, items() )
131+
{
132+
const QgsLayoutItem *layoutItem = dynamic_cast<const QgsLayoutItem *>( item );
133+
if ( !layoutItem )
134+
continue;
135+
136+
bool isPage = layoutItem->type() == QgsLayoutItemRegistry::LayoutPage;
137+
if ( !isPage || !ignorePages )
138+
{
139+
//expand bounds with current item's bounds
140+
if ( bounds.isValid() )
141+
bounds = bounds.united( item->sceneBoundingRect() );
142+
else
143+
bounds = item->sceneBoundingRect();
144+
}
145+
}
146+
147+
if ( bounds.isValid() && margin > 0.0 )
148+
{
149+
//finally, expand bounds out by specified margin of page size
150+
double maxWidth = mPageCollection->maximumPageWidth();
151+
bounds.adjust( -maxWidth * margin, -maxWidth * margin, maxWidth * margin, maxWidth * margin );
152+
}
153+
154+
return bounds;
155+
156+
}
157+
158+
void QgsLayout::addLayoutItem( QgsLayoutItem *item )
159+
{
160+
addItem( item );
161+
updateBounds();
162+
}
163+
164+
void QgsLayout::updateBounds()
165+
{
166+
setSceneRect( layoutBounds( false, 0.05 ) );
167+
}

‎src/core/layout/qgslayout.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,19 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
4545

4646
/**
4747
* Construct a new layout linked to the specified \a project.
48+
*
49+
* If the layout is a "new" layout (as opposed to a layout which will
50+
* restore a previous state from XML) then initializeDefaults() should be
51+
* called on the new layout.
4852
*/
4953
QgsLayout( QgsProject *project );
5054

55+
/**
56+
* Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
57+
* a new layout.
58+
*/
59+
void initializeDefaults();
60+
5161
/**
5262
* The project associated with the layout. Used to get access to layers, map themes,
5363
* relations and various other bits. It is never null.
@@ -211,6 +221,28 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
211221
*/
212222
QgsLayoutPageCollection *pageCollection();
213223

224+
/**
225+
* Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles
226+
* and other cosmetic items.
227+
* \param ignorePages set to true to ignore page items
228+
* \param margin optional marginal (in percent, e.g., 0.05 = 5% ) to add around items
229+
* \returns layout bounds, in layout units.
230+
*/
231+
QRectF layoutBounds( bool ignorePages = false, double margin = 0.0 ) const;
232+
233+
/**
234+
* Adds an \a item to the layout. This should be called instead of the base class addItem()
235+
* method. Ownership of the item is transferred to the layout.
236+
*/
237+
void addLayoutItem( QgsLayoutItem *item SIP_TRANSFER );
238+
239+
public slots:
240+
241+
/**
242+
* Updates the scene bounds of the layout.
243+
*/
244+
void updateBounds();
245+
214246
signals:
215247

216248
/**

‎src/core/layout/qgslayoutpagecollection.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "qgslayoutpagecollection.h"
1818
#include "qgslayout.h"
1919

20+
#define SPACE_BETWEEN_PAGES 10
21+
2022
QgsLayoutPageCollection::QgsLayoutPageCollection( QgsLayout *layout )
2123
: QObject( layout )
2224
, mLayout( layout )
@@ -41,6 +43,29 @@ void QgsLayoutPageCollection::setPageStyleSymbol( QgsFillSymbol *symbol )
4143
mPageStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
4244
}
4345

46+
void QgsLayoutPageCollection::reflow()
47+
{
48+
double currentY = 0;
49+
QgsLayoutPoint p( 0, 0, mLayout->units() );
50+
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
51+
{
52+
page->attemptMove( p );
53+
currentY += mLayout->convertToLayoutUnits( page->pageSize() ).height() + SPACE_BETWEEN_PAGES;
54+
p.setY( currentY );
55+
}
56+
mLayout->updateBounds();
57+
}
58+
59+
double QgsLayoutPageCollection::maximumPageWidth() const
60+
{
61+
double maxWidth = 0;
62+
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
63+
{
64+
maxWidth = qMax( maxWidth, mLayout->convertToLayoutUnits( page->pageSize() ).width() );
65+
}
66+
return maxWidth;
67+
}
68+
4469
QgsLayout *QgsLayoutPageCollection::layout() const
4570
{
4671
return mLayout;
@@ -65,6 +90,7 @@ void QgsLayoutPageCollection::addPage( QgsLayoutItemPage *page )
6590
{
6691
mPages.append( page );
6792
mLayout->addItem( page );
93+
reflow();
6894
}
6995

7096
void QgsLayoutPageCollection::insertPage( QgsLayoutItemPage *page, int beforePage )
@@ -81,6 +107,7 @@ void QgsLayoutPageCollection::insertPage( QgsLayoutItemPage *page, int beforePag
81107
mPages.insert( beforePage, page );
82108
}
83109
mLayout->addItem( page );
110+
reflow();
84111
}
85112

86113
void QgsLayoutPageCollection::deletePage( int pageNumber )
@@ -91,6 +118,7 @@ void QgsLayoutPageCollection::deletePage( int pageNumber )
91118
QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
92119
mLayout->removeItem( page );
93120
page->deleteLater();
121+
reflow();
94122
}
95123

96124
void QgsLayoutPageCollection::createDefaultPageStyleSymbol()

‎src/core/layout/qgslayoutpagecollection.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
7878
* to the collection, and the page will automatically be added to the collection's
7979
* layout() (there is no need to manually add the page item to the layout).
8080
* The page will be added after all pages currently contained in the collection.
81+
*
82+
* Calling addPage() automatically triggers a reflow() of pages.
83+
*
8184
* \see insertPage()
8285
*/
8386
void addPage( QgsLayoutItemPage *page SIP_TRANSFER );
@@ -93,6 +96,8 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
9396
* (Page numbers in collections begin at 0 - so a \a beforePage of 0 will insert
9497
* the page before all existing pages).
9598
*
99+
* Calling insertPage() automatically triggers a reflow() of pages.
100+
*
96101
* \see addPage()
97102
*/
98103
void insertPage( QgsLayoutItemPage *page SIP_TRANSFER, int beforePage );
@@ -103,6 +108,8 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
103108
*
104109
* Page numbers in collections begin at 0 - so a \a pageNumber of 0 will delete
105110
* the first page in the collection.
111+
*
112+
* Calling deletePage() automatically triggers a reflow() of pages.
106113
*/
107114
void deletePage( int pageNumber );
108115

@@ -120,6 +127,18 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
120127
*/
121128
const QgsFillSymbol *pageStyleSymbol() const { return mPageStyleSymbol.get(); }
122129

130+
/**
131+
* Forces the page collection to reflow the arrangement of pages, e.g. to account
132+
* for page size/orientation change.
133+
*/
134+
void reflow();
135+
136+
/**
137+
* Returns the maximum width of pages in the collection. The returned value is
138+
* in layout units.
139+
*/
140+
double maximumPageWidth() const;
141+
123142
private:
124143

125144
QgsLayout *mLayout = nullptr;

‎src/gui/layout/qgslayoutviewtooladditem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
115115
settings.setValue( QStringLiteral( "LayoutDesigner/lastItemHeight" ), item->sizeWithUnits().height() );
116116
settings.setValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), static_cast< int >( item->sizeWithUnits().units() ) );
117117

118-
layout()->addItem( item );
118+
layout()->addLayoutItem( item );
119119
}
120120

121121
void QgsLayoutViewToolAddItem::deactivate()

‎tests/src/core/testqgslayout.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "qgstest.h"
2020
#include "qgsproject.h"
2121
#include "qgslayoutitemmap.h"
22+
#include "qgslayoutitemshape.h"
23+
#include "qgstestutils.h"
2224

2325
class TestQgsLayout: public QObject
2426
{
@@ -36,6 +38,8 @@ class TestQgsLayout: public QObject
3638
void variablesEdited();
3739
void scope();
3840
void referenceMap();
41+
void bounds();
42+
void addItem();
3943

4044
private:
4145
QString mReport;
@@ -246,6 +250,117 @@ void TestQgsLayout::referenceMap()
246250

247251
}
248252

253+
void TestQgsLayout::bounds()
254+
{
255+
//add some items to a layout
256+
QgsProject p;
257+
QgsLayout l( &p );
258+
l.initializeDefaults();
259+
260+
QgsLayoutItemRectangularShape *shape1 = new QgsLayoutItemRectangularShape( &l );
261+
shape1->attemptResize( QgsLayoutSize( 90, 50 ) );
262+
shape1->attemptMove( QgsLayoutPoint( 90, 50 ) );
263+
shape1->setItemRotation( 45 );
264+
l.addLayoutItem( shape1 );
265+
QgsLayoutItemRectangularShape *shape2 = new QgsLayoutItemRectangularShape( &l );
266+
shape2->attemptResize( QgsLayoutSize( 110, 50 ) );
267+
shape2->attemptMove( QgsLayoutPoint( 100, 150 ) );
268+
l.addLayoutItem( shape2 );
269+
270+
#if 0
271+
QgsLayoutItemRectangularShape *shape3 = new QgsLayoutItemRectangularShape( &l );
272+
l.addLayoutItem( shape3 );
273+
shape3->setItemPosition( 210, 30, 50, 100, QgsComposerItem::UpperLeft, false, 2 );
274+
QgsLayoutItemRectangularShape *shape4 = new QgsLayoutItemRectangularShape( &l );
275+
l.addLayoutItem( shape4 );
276+
shape4->setItemPosition( 10, 120, 50, 30, QgsComposerItem::UpperLeft, false, 2 );
277+
shape4->setVisibility( false );
278+
#endif
279+
280+
//check bounds
281+
QRectF layoutBounds = l.layoutBounds( false );
282+
#if 0 // correct values when 2nd page items are added back in
283+
QGSCOMPARENEAR( layoutBounds.height(), 372.15, 0.01 );
284+
QGSCOMPARENEAR( layoutBounds.width(), 301.00, 0.01 );
285+
QGSCOMPARENEAR( layoutBounds.left(), -2, 0.01 );
286+
QGSCOMPARENEAR( layoutBounds.top(), -2, 0.01 );
287+
288+
QRectF compositionBoundsNoPage = l.layoutBounds( true );
289+
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 320.36, 0.01 );
290+
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 250.30, 0.01 );
291+
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 9.85, 0.01 );
292+
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 49.79, 0.01 );
293+
#endif
294+
295+
QGSCOMPARENEAR( layoutBounds.height(), 211.000000, 0.01 );
296+
QGSCOMPARENEAR( layoutBounds.width(), 298.000000, 0.01 );
297+
QGSCOMPARENEAR( layoutBounds.left(), -0.500000, 0.01 );
298+
QGSCOMPARENEAR( layoutBounds.top(), -0.500000, 0.01 );
299+
300+
QRectF compositionBoundsNoPage = l.layoutBounds( true );
301+
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 175.704581, 0.01 );
302+
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 125.704581, 0.01 );
303+
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 84.795419, 0.01 );
304+
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 24.795419, 0.01 );
305+
306+
#if 0
307+
QRectF page1Bounds = composition->pageItemBounds( 0, true );
308+
QGSCOMPARENEAR( page1Bounds.height(), 150.36, 0.01 );
309+
QGSCOMPARENEAR( page1Bounds.width(), 155.72, 0.01 );
310+
QGSCOMPARENEAR( page1Bounds.left(), 54.43, 0.01 );
311+
QGSCOMPARENEAR( page1Bounds.top(), 49.79, 0.01 );
312+
313+
QRectF page2Bounds = composition->pageItemBounds( 1, true );
314+
QGSCOMPARENEAR( page2Bounds.height(), 100.30, 0.01 );
315+
QGSCOMPARENEAR( page2Bounds.width(), 50.30, 0.01 );
316+
QGSCOMPARENEAR( page2Bounds.left(), 209.85, 0.01 );
317+
QGSCOMPARENEAR( page2Bounds.top(), 249.85, 0.01 );
318+
319+
QRectF page2BoundsWithHidden = composition->pageItemBounds( 1, false );
320+
QGSCOMPARENEAR( page2BoundsWithHidden.height(), 120.30, 0.01 );
321+
QGSCOMPARENEAR( page2BoundsWithHidden.width(), 250.30, 0.01 );
322+
QGSCOMPARENEAR( page2BoundsWithHidden.left(), 9.85, 0.01 );
323+
QGSCOMPARENEAR( page2BoundsWithHidden.top(), 249.85, 0.01 );
324+
#endif
325+
}
326+
327+
void TestQgsLayout::addItem()
328+
{
329+
QgsProject p;
330+
QgsLayout l( &p );
331+
l.pageCollection()->deletePage( 0 );
332+
333+
QgsLayoutItemRectangularShape *shape1 = new QgsLayoutItemRectangularShape( &l );
334+
shape1->attemptResize( QgsLayoutSize( 140, 70 ) );
335+
shape1->attemptMove( QgsLayoutPoint( 90, 50 ) );
336+
337+
l.addLayoutItem( shape1 );
338+
QVERIFY( l.items().contains( shape1 ) );
339+
// bounds should be updated to include item
340+
QGSCOMPARENEAR( l.sceneRect().left(), 89.5, 0.001 );
341+
QGSCOMPARENEAR( l.sceneRect().top(), 49.5, 0.001 );
342+
QGSCOMPARENEAR( l.sceneRect().width(), 141, 0.001 );
343+
QGSCOMPARENEAR( l.sceneRect().height(), 71, 0.001 );
344+
345+
QgsLayoutItemRectangularShape *shape2 = new QgsLayoutItemRectangularShape( &l );
346+
shape2->attemptResize( QgsLayoutSize( 240, 170 ) );
347+
shape2->attemptMove( QgsLayoutPoint( 30, 20 ) );
348+
349+
// don't use addLayoutItem - we want to manually trigger a bounds update
350+
l.addItem( shape2 );
351+
QGSCOMPARENEAR( l.sceneRect().left(), 89.5, 0.001 );
352+
QGSCOMPARENEAR( l.sceneRect().top(), 49.5, 0.001 );
353+
QGSCOMPARENEAR( l.sceneRect().width(), 141, 0.001 );
354+
QGSCOMPARENEAR( l.sceneRect().height(), 71, 0.001 );
355+
356+
l.updateBounds();
357+
// bounds should be updated to include item
358+
QGSCOMPARENEAR( l.sceneRect().left(), 29.5, 0.001 );
359+
QGSCOMPARENEAR( l.sceneRect().top(), 19.5, 0.001 );
360+
QGSCOMPARENEAR( l.sceneRect().width(), 241, 0.001 );
361+
QGSCOMPARENEAR( l.sceneRect().height(), 171, 0.001 );
362+
}
363+
249364

250365
QGSTEST_MAIN( TestQgsLayout )
251366
#include "testqgslayout.moc"

‎tests/src/python/test_qgslayoutpagecollection.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@
1515
import qgis # NOQA
1616
import sip
1717

18-
from qgis.core import QgsUnitTypes, QgsLayout, QgsLayoutItemPage, QgsProject, QgsLayoutPageCollection, QgsSimpleFillSymbolLayer, QgsFillSymbol
18+
from qgis.core import (QgsUnitTypes,
19+
QgsLayout,
20+
QgsLayoutItemPage,
21+
QgsLayoutSize,
22+
QgsProject,
23+
QgsLayoutPageCollection,
24+
QgsSimpleFillSymbolLayer,
25+
QgsFillSymbol)
1926
from qgis.PyQt.QtCore import Qt, QCoreApplication, QEvent
2027
from qgis.testing import start_app, unittest
2128

@@ -120,6 +127,86 @@ def testPages(self):
120127
self.assertTrue(sip.isdeleted(page))
121128
self.assertTrue(sip.isdeleted(page2))
122129

130+
def testMaxPageWidth(self):
131+
"""
132+
Test calculating maximum page width
133+
"""
134+
p = QgsProject()
135+
l = QgsLayout(p)
136+
collection = l.pageCollection()
137+
138+
# add a page
139+
page = QgsLayoutItemPage(l)
140+
page.setPageSize('A4')
141+
collection.addPage(page)
142+
self.assertEqual(collection.maximumPageWidth(), 210.0)
143+
144+
# add a second page
145+
page2 = QgsLayoutItemPage(l)
146+
page2.setPageSize('A3')
147+
collection.addPage(page2)
148+
self.assertEqual(collection.maximumPageWidth(), 297.0)
149+
150+
# add a page with other units
151+
page3 = QgsLayoutItemPage(l)
152+
page3.setPageSize(QgsLayoutSize(100, 100, QgsUnitTypes.LayoutMeters))
153+
collection.addPage(page3)
154+
self.assertEqual(collection.maximumPageWidth(), 100000.0)
155+
156+
def testReflow(self):
157+
"""
158+
Test reflowing pages
159+
"""
160+
p = QgsProject()
161+
l = QgsLayout(p)
162+
collection = l.pageCollection()
163+
164+
#add a page
165+
page = QgsLayoutItemPage(l)
166+
page.setPageSize('A4')
167+
collection.addPage(page)
168+
169+
#should be positioned at origin
170+
self.assertEqual(page.pos().x(), 0)
171+
self.assertEqual(page.pos().y(), 0)
172+
173+
#second page
174+
page2 = QgsLayoutItemPage(l)
175+
page2.setPageSize('A5')
176+
collection.addPage(page2)
177+
178+
self.assertEqual(page.pos().x(), 0)
179+
self.assertEqual(page.pos().y(), 0)
180+
self.assertEqual(page2.pos().x(), 0)
181+
self.assertEqual(page2.pos().y(), 307)
182+
183+
#third page, slotted in middle
184+
page3 = QgsLayoutItemPage(l)
185+
page3.setPageSize('A3')
186+
collection.insertPage(page3, 1)
187+
188+
self.assertEqual(page.pos().x(), 0)
189+
self.assertEqual(page.pos().y(), 0)
190+
self.assertEqual(page2.pos().x(), 0)
191+
self.assertEqual(page2.pos().y(), 737)
192+
self.assertEqual(page3.pos().x(), 0)
193+
self.assertEqual(page3.pos().y(), 307)
194+
195+
page.setPageSize(QgsLayoutSize(100, 120))
196+
# no update until reflow is called
197+
self.assertEqual(page.pos().x(), 0)
198+
self.assertEqual(page.pos().y(), 0)
199+
self.assertEqual(page2.pos().x(), 0)
200+
self.assertEqual(page2.pos().y(), 737)
201+
self.assertEqual(page3.pos().x(), 0)
202+
self.assertEqual(page3.pos().y(), 307)
203+
collection.reflow()
204+
self.assertEqual(page.pos().x(), 0)
205+
self.assertEqual(page.pos().y(), 0)
206+
self.assertEqual(page2.pos().x(), 0)
207+
self.assertEqual(page2.pos().y(), 560)
208+
self.assertEqual(page3.pos().x(), 0)
209+
self.assertEqual(page3.pos().y(), 130)
123210

124211
if __name__ == '__main__':
125212
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.