mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Start on reflow support for page collections (needs tests)
This commit is contained in:
parent
79a4694177
commit
39bf23a5d5
@ -29,6 +29,16 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
|
||||
QgsLayout( QgsProject *project );
|
||||
%Docstring
|
||||
Construct a new layout linked to the specified ``project``.
|
||||
|
||||
If the layout is a "new" layout (as opposed to a layout which will
|
||||
restore a previous state from XML) then initializeDefaults() should be
|
||||
called on the new layout.
|
||||
%End
|
||||
|
||||
void initializeDefaults();
|
||||
%Docstring
|
||||
Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
|
||||
a new layout.
|
||||
%End
|
||||
|
||||
QgsProject *project() const;
|
||||
@ -191,6 +201,29 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
|
||||
:rtype: QgsLayoutPageCollection
|
||||
%End
|
||||
|
||||
QRectF layoutBounds( bool ignorePages = false, double margin = 0.0 ) const;
|
||||
%Docstring
|
||||
Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles
|
||||
and other cosmetic items.
|
||||
\param ignorePages set to true to ignore page items
|
||||
\param margin optional marginal (in percent, e.g., 0.05 = 5% ) to add around items
|
||||
:return: layout bounds, in layout units.
|
||||
:rtype: QRectF
|
||||
%End
|
||||
|
||||
void addLayoutItem( QgsLayoutItem *item /Transfer/ );
|
||||
%Docstring
|
||||
Adds an ``item`` to the layout. This should be called instead of the base class addItem()
|
||||
method. Ownership of the item is transferred to the layout.
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
||||
void updateBounds();
|
||||
%Docstring
|
||||
Updates the scene bounds of the layout.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void variablesChanged();
|
||||
|
@ -65,6 +65,9 @@ class QgsLayoutPageCollection : QObject
|
||||
to the collection, and the page will automatically be added to the collection's
|
||||
layout() (there is no need to manually add the page item to the layout).
|
||||
The page will be added after all pages currently contained in the collection.
|
||||
|
||||
Calling addPage() automatically triggers a reflow() of pages.
|
||||
|
||||
.. seealso:: insertPage()
|
||||
%End
|
||||
|
||||
@ -80,6 +83,8 @@ class QgsLayoutPageCollection : QObject
|
||||
(Page numbers in collections begin at 0 - so a ``beforePage`` of 0 will insert
|
||||
the page before all existing pages).
|
||||
|
||||
Calling insertPage() automatically triggers a reflow() of pages.
|
||||
|
||||
.. seealso:: addPage()
|
||||
%End
|
||||
|
||||
@ -90,6 +95,8 @@ class QgsLayoutPageCollection : QObject
|
||||
|
||||
Page numbers in collections begin at 0 - so a ``pageNumber`` of 0 will delete
|
||||
the first page in the collection.
|
||||
|
||||
Calling deletePage() automatically triggers a reflow() of pages.
|
||||
%End
|
||||
|
||||
void setPageStyleSymbol( QgsFillSymbol *symbol );
|
||||
@ -107,6 +114,19 @@ class QgsLayoutPageCollection : QObject
|
||||
:rtype: QgsFillSymbol
|
||||
%End
|
||||
|
||||
void reflow();
|
||||
%Docstring
|
||||
Forces the page collection to reflow the arrangement of pages, e.g. to account
|
||||
for page size/orientation change.
|
||||
%End
|
||||
|
||||
double maximumPageWidth() const;
|
||||
%Docstring
|
||||
Returns the maximum width of pages in the collection. The returned value is
|
||||
in layout units.
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
@ -25,6 +25,14 @@ QgsLayout::QgsLayout( QgsProject *project )
|
||||
setBackgroundBrush( QColor( 215, 215, 215 ) );
|
||||
}
|
||||
|
||||
void QgsLayout::initializeDefaults()
|
||||
{
|
||||
// default to a A4 landscape page
|
||||
QgsLayoutItemPage *page = new QgsLayoutItemPage( this );
|
||||
page->setPageSize( QgsLayoutSize( 297, 210, QgsUnitTypes::LayoutMillimeters ) );
|
||||
mPageCollection->addPage( page );
|
||||
}
|
||||
|
||||
QgsProject *QgsLayout::project() const
|
||||
{
|
||||
return mProject;
|
||||
@ -112,3 +120,48 @@ QgsLayoutPageCollection *QgsLayout::pageCollection()
|
||||
{
|
||||
return mPageCollection.get();
|
||||
}
|
||||
|
||||
QRectF QgsLayout::layoutBounds( bool ignorePages, double margin ) const
|
||||
{
|
||||
//start with an empty rectangle
|
||||
QRectF bounds;
|
||||
|
||||
//add all QgsComposerItems and QgsPaperItems which are in the composition
|
||||
Q_FOREACH ( const QGraphicsItem *item, items() )
|
||||
{
|
||||
const QgsLayoutItem *layoutItem = dynamic_cast<const QgsLayoutItem *>( item );
|
||||
if ( !layoutItem )
|
||||
continue;
|
||||
|
||||
bool isPage = layoutItem->type() == QgsLayoutItemRegistry::LayoutPage;
|
||||
if ( !isPage || !ignorePages )
|
||||
{
|
||||
//expand bounds with current item's bounds
|
||||
if ( bounds.isValid() )
|
||||
bounds = bounds.united( item->sceneBoundingRect() );
|
||||
else
|
||||
bounds = item->sceneBoundingRect();
|
||||
}
|
||||
}
|
||||
|
||||
if ( bounds.isValid() && margin > 0.0 )
|
||||
{
|
||||
//finally, expand bounds out by specified margin of page size
|
||||
double maxWidth = mPageCollection->maximumPageWidth();
|
||||
bounds.adjust( -maxWidth * margin, -maxWidth * margin, maxWidth * margin, maxWidth * margin );
|
||||
}
|
||||
|
||||
return bounds;
|
||||
|
||||
}
|
||||
|
||||
void QgsLayout::addLayoutItem( QgsLayoutItem *item )
|
||||
{
|
||||
addItem( item );
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
void QgsLayout::updateBounds()
|
||||
{
|
||||
setSceneRect( layoutBounds( false, 0.05 ) );
|
||||
}
|
||||
|
@ -45,9 +45,19 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
|
||||
|
||||
/**
|
||||
* Construct a new layout linked to the specified \a project.
|
||||
*
|
||||
* If the layout is a "new" layout (as opposed to a layout which will
|
||||
* restore a previous state from XML) then initializeDefaults() should be
|
||||
* called on the new layout.
|
||||
*/
|
||||
QgsLayout( QgsProject *project );
|
||||
|
||||
/**
|
||||
* Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
|
||||
* a new layout.
|
||||
*/
|
||||
void initializeDefaults();
|
||||
|
||||
/**
|
||||
* The project associated with the layout. Used to get access to layers, map themes,
|
||||
* relations and various other bits. It is never null.
|
||||
@ -211,6 +221,28 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
|
||||
*/
|
||||
QgsLayoutPageCollection *pageCollection();
|
||||
|
||||
/**
|
||||
* Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles
|
||||
* and other cosmetic items.
|
||||
* \param ignorePages set to true to ignore page items
|
||||
* \param margin optional marginal (in percent, e.g., 0.05 = 5% ) to add around items
|
||||
* \returns layout bounds, in layout units.
|
||||
*/
|
||||
QRectF layoutBounds( bool ignorePages = false, double margin = 0.0 ) const;
|
||||
|
||||
/**
|
||||
* Adds an \a item to the layout. This should be called instead of the base class addItem()
|
||||
* method. Ownership of the item is transferred to the layout.
|
||||
*/
|
||||
void addLayoutItem( QgsLayoutItem *item SIP_TRANSFER );
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* Updates the scene bounds of the layout.
|
||||
*/
|
||||
void updateBounds();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "qgslayoutpagecollection.h"
|
||||
#include "qgslayout.h"
|
||||
|
||||
#define SPACE_BETWEEN_PAGES 10
|
||||
|
||||
QgsLayoutPageCollection::QgsLayoutPageCollection( QgsLayout *layout )
|
||||
: QObject( layout )
|
||||
, mLayout( layout )
|
||||
@ -41,6 +43,29 @@ void QgsLayoutPageCollection::setPageStyleSymbol( QgsFillSymbol *symbol )
|
||||
mPageStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
|
||||
}
|
||||
|
||||
void QgsLayoutPageCollection::reflow()
|
||||
{
|
||||
double currentY = 0;
|
||||
QgsLayoutPoint p( 0, 0, mLayout->units() );
|
||||
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
|
||||
{
|
||||
page->attemptMove( p );
|
||||
currentY += mLayout->convertToLayoutUnits( page->pageSize() ).height() + SPACE_BETWEEN_PAGES;
|
||||
p.setY( currentY );
|
||||
}
|
||||
mLayout->updateBounds();
|
||||
}
|
||||
|
||||
double QgsLayoutPageCollection::maximumPageWidth() const
|
||||
{
|
||||
double maxWidth = 0;
|
||||
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
|
||||
{
|
||||
maxWidth = qMax( maxWidth, mLayout->convertToLayoutUnits( page->pageSize() ).width() );
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
QgsLayout *QgsLayoutPageCollection::layout() const
|
||||
{
|
||||
return mLayout;
|
||||
@ -65,6 +90,7 @@ void QgsLayoutPageCollection::addPage( QgsLayoutItemPage *page )
|
||||
{
|
||||
mPages.append( page );
|
||||
mLayout->addItem( page );
|
||||
reflow();
|
||||
}
|
||||
|
||||
void QgsLayoutPageCollection::insertPage( QgsLayoutItemPage *page, int beforePage )
|
||||
@ -81,6 +107,7 @@ void QgsLayoutPageCollection::insertPage( QgsLayoutItemPage *page, int beforePag
|
||||
mPages.insert( beforePage, page );
|
||||
}
|
||||
mLayout->addItem( page );
|
||||
reflow();
|
||||
}
|
||||
|
||||
void QgsLayoutPageCollection::deletePage( int pageNumber )
|
||||
@ -91,6 +118,7 @@ void QgsLayoutPageCollection::deletePage( int pageNumber )
|
||||
QgsLayoutItemPage *page = mPages.takeAt( pageNumber );
|
||||
mLayout->removeItem( page );
|
||||
page->deleteLater();
|
||||
reflow();
|
||||
}
|
||||
|
||||
void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
|
||||
|
@ -78,6 +78,9 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
|
||||
* to the collection, and the page will automatically be added to the collection's
|
||||
* layout() (there is no need to manually add the page item to the layout).
|
||||
* The page will be added after all pages currently contained in the collection.
|
||||
*
|
||||
* Calling addPage() automatically triggers a reflow() of pages.
|
||||
*
|
||||
* \see insertPage()
|
||||
*/
|
||||
void addPage( QgsLayoutItemPage *page SIP_TRANSFER );
|
||||
@ -93,6 +96,8 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
|
||||
* (Page numbers in collections begin at 0 - so a \a beforePage of 0 will insert
|
||||
* the page before all existing pages).
|
||||
*
|
||||
* Calling insertPage() automatically triggers a reflow() of pages.
|
||||
*
|
||||
* \see addPage()
|
||||
*/
|
||||
void insertPage( QgsLayoutItemPage *page SIP_TRANSFER, int beforePage );
|
||||
@ -103,6 +108,8 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
|
||||
*
|
||||
* Page numbers in collections begin at 0 - so a \a pageNumber of 0 will delete
|
||||
* the first page in the collection.
|
||||
*
|
||||
* Calling deletePage() automatically triggers a reflow() of pages.
|
||||
*/
|
||||
void deletePage( int pageNumber );
|
||||
|
||||
@ -120,6 +127,18 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
|
||||
*/
|
||||
const QgsFillSymbol *pageStyleSymbol() const { return mPageStyleSymbol.get(); }
|
||||
|
||||
/**
|
||||
* Forces the page collection to reflow the arrangement of pages, e.g. to account
|
||||
* for page size/orientation change.
|
||||
*/
|
||||
void reflow();
|
||||
|
||||
/**
|
||||
* Returns the maximum width of pages in the collection. The returned value is
|
||||
* in layout units.
|
||||
*/
|
||||
double maximumPageWidth() const;
|
||||
|
||||
private:
|
||||
|
||||
QgsLayout *mLayout = nullptr;
|
||||
|
@ -115,7 +115,7 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
|
||||
settings.setValue( QStringLiteral( "LayoutDesigner/lastItemHeight" ), item->sizeWithUnits().height() );
|
||||
settings.setValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), static_cast< int >( item->sizeWithUnits().units() ) );
|
||||
|
||||
layout()->addItem( item );
|
||||
layout()->addLayoutItem( item );
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddItem::deactivate()
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "qgstest.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgslayoutitemmap.h"
|
||||
#include "qgslayoutitemshape.h"
|
||||
#include "qgstestutils.h"
|
||||
|
||||
class TestQgsLayout: public QObject
|
||||
{
|
||||
@ -36,6 +38,8 @@ class TestQgsLayout: public QObject
|
||||
void variablesEdited();
|
||||
void scope();
|
||||
void referenceMap();
|
||||
void bounds();
|
||||
void addItem();
|
||||
|
||||
private:
|
||||
QString mReport;
|
||||
@ -246,6 +250,117 @@ void TestQgsLayout::referenceMap()
|
||||
|
||||
}
|
||||
|
||||
void TestQgsLayout::bounds()
|
||||
{
|
||||
//add some items to a layout
|
||||
QgsProject p;
|
||||
QgsLayout l( &p );
|
||||
l.initializeDefaults();
|
||||
|
||||
QgsLayoutItemRectangularShape *shape1 = new QgsLayoutItemRectangularShape( &l );
|
||||
shape1->attemptResize( QgsLayoutSize( 90, 50 ) );
|
||||
shape1->attemptMove( QgsLayoutPoint( 90, 50 ) );
|
||||
shape1->setItemRotation( 45 );
|
||||
l.addLayoutItem( shape1 );
|
||||
QgsLayoutItemRectangularShape *shape2 = new QgsLayoutItemRectangularShape( &l );
|
||||
shape2->attemptResize( QgsLayoutSize( 110, 50 ) );
|
||||
shape2->attemptMove( QgsLayoutPoint( 100, 150 ) );
|
||||
l.addLayoutItem( shape2 );
|
||||
|
||||
#if 0
|
||||
QgsLayoutItemRectangularShape *shape3 = new QgsLayoutItemRectangularShape( &l );
|
||||
l.addLayoutItem( shape3 );
|
||||
shape3->setItemPosition( 210, 30, 50, 100, QgsComposerItem::UpperLeft, false, 2 );
|
||||
QgsLayoutItemRectangularShape *shape4 = new QgsLayoutItemRectangularShape( &l );
|
||||
l.addLayoutItem( shape4 );
|
||||
shape4->setItemPosition( 10, 120, 50, 30, QgsComposerItem::UpperLeft, false, 2 );
|
||||
shape4->setVisibility( false );
|
||||
#endif
|
||||
|
||||
//check bounds
|
||||
QRectF layoutBounds = l.layoutBounds( false );
|
||||
#if 0 // correct values when 2nd page items are added back in
|
||||
QGSCOMPARENEAR( layoutBounds.height(), 372.15, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.width(), 301.00, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.left(), -2, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.top(), -2, 0.01 );
|
||||
|
||||
QRectF compositionBoundsNoPage = l.layoutBounds( true );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 320.36, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 250.30, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 9.85, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 49.79, 0.01 );
|
||||
#endif
|
||||
|
||||
QGSCOMPARENEAR( layoutBounds.height(), 211.000000, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.width(), 298.000000, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.left(), -0.500000, 0.01 );
|
||||
QGSCOMPARENEAR( layoutBounds.top(), -0.500000, 0.01 );
|
||||
|
||||
QRectF compositionBoundsNoPage = l.layoutBounds( true );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 175.704581, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 125.704581, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 84.795419, 0.01 );
|
||||
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 24.795419, 0.01 );
|
||||
|
||||
#if 0
|
||||
QRectF page1Bounds = composition->pageItemBounds( 0, true );
|
||||
QGSCOMPARENEAR( page1Bounds.height(), 150.36, 0.01 );
|
||||
QGSCOMPARENEAR( page1Bounds.width(), 155.72, 0.01 );
|
||||
QGSCOMPARENEAR( page1Bounds.left(), 54.43, 0.01 );
|
||||
QGSCOMPARENEAR( page1Bounds.top(), 49.79, 0.01 );
|
||||
|
||||
QRectF page2Bounds = composition->pageItemBounds( 1, true );
|
||||
QGSCOMPARENEAR( page2Bounds.height(), 100.30, 0.01 );
|
||||
QGSCOMPARENEAR( page2Bounds.width(), 50.30, 0.01 );
|
||||
QGSCOMPARENEAR( page2Bounds.left(), 209.85, 0.01 );
|
||||
QGSCOMPARENEAR( page2Bounds.top(), 249.85, 0.01 );
|
||||
|
||||
QRectF page2BoundsWithHidden = composition->pageItemBounds( 1, false );
|
||||
QGSCOMPARENEAR( page2BoundsWithHidden.height(), 120.30, 0.01 );
|
||||
QGSCOMPARENEAR( page2BoundsWithHidden.width(), 250.30, 0.01 );
|
||||
QGSCOMPARENEAR( page2BoundsWithHidden.left(), 9.85, 0.01 );
|
||||
QGSCOMPARENEAR( page2BoundsWithHidden.top(), 249.85, 0.01 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestQgsLayout::addItem()
|
||||
{
|
||||
QgsProject p;
|
||||
QgsLayout l( &p );
|
||||
l.pageCollection()->deletePage( 0 );
|
||||
|
||||
QgsLayoutItemRectangularShape *shape1 = new QgsLayoutItemRectangularShape( &l );
|
||||
shape1->attemptResize( QgsLayoutSize( 140, 70 ) );
|
||||
shape1->attemptMove( QgsLayoutPoint( 90, 50 ) );
|
||||
|
||||
l.addLayoutItem( shape1 );
|
||||
QVERIFY( l.items().contains( shape1 ) );
|
||||
// bounds should be updated to include item
|
||||
QGSCOMPARENEAR( l.sceneRect().left(), 89.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().top(), 49.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().width(), 141, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().height(), 71, 0.001 );
|
||||
|
||||
QgsLayoutItemRectangularShape *shape2 = new QgsLayoutItemRectangularShape( &l );
|
||||
shape2->attemptResize( QgsLayoutSize( 240, 170 ) );
|
||||
shape2->attemptMove( QgsLayoutPoint( 30, 20 ) );
|
||||
|
||||
// don't use addLayoutItem - we want to manually trigger a bounds update
|
||||
l.addItem( shape2 );
|
||||
QGSCOMPARENEAR( l.sceneRect().left(), 89.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().top(), 49.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().width(), 141, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().height(), 71, 0.001 );
|
||||
|
||||
l.updateBounds();
|
||||
// bounds should be updated to include item
|
||||
QGSCOMPARENEAR( l.sceneRect().left(), 29.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().top(), 19.5, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().width(), 241, 0.001 );
|
||||
QGSCOMPARENEAR( l.sceneRect().height(), 171, 0.001 );
|
||||
}
|
||||
|
||||
|
||||
QGSTEST_MAIN( TestQgsLayout )
|
||||
#include "testqgslayout.moc"
|
||||
|
@ -15,7 +15,14 @@ __revision__ = '$Format:%H$'
|
||||
import qgis # NOQA
|
||||
import sip
|
||||
|
||||
from qgis.core import QgsUnitTypes, QgsLayout, QgsLayoutItemPage, QgsProject, QgsLayoutPageCollection, QgsSimpleFillSymbolLayer, QgsFillSymbol
|
||||
from qgis.core import (QgsUnitTypes,
|
||||
QgsLayout,
|
||||
QgsLayoutItemPage,
|
||||
QgsLayoutSize,
|
||||
QgsProject,
|
||||
QgsLayoutPageCollection,
|
||||
QgsSimpleFillSymbolLayer,
|
||||
QgsFillSymbol)
|
||||
from qgis.PyQt.QtCore import Qt, QCoreApplication, QEvent
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
@ -120,6 +127,86 @@ class TestQgsLayoutPageCollection(unittest.TestCase):
|
||||
self.assertTrue(sip.isdeleted(page))
|
||||
self.assertTrue(sip.isdeleted(page2))
|
||||
|
||||
def testMaxPageWidth(self):
|
||||
"""
|
||||
Test calculating maximum page width
|
||||
"""
|
||||
p = QgsProject()
|
||||
l = QgsLayout(p)
|
||||
collection = l.pageCollection()
|
||||
|
||||
# add a page
|
||||
page = QgsLayoutItemPage(l)
|
||||
page.setPageSize('A4')
|
||||
collection.addPage(page)
|
||||
self.assertEqual(collection.maximumPageWidth(), 210.0)
|
||||
|
||||
# add a second page
|
||||
page2 = QgsLayoutItemPage(l)
|
||||
page2.setPageSize('A3')
|
||||
collection.addPage(page2)
|
||||
self.assertEqual(collection.maximumPageWidth(), 297.0)
|
||||
|
||||
# add a page with other units
|
||||
page3 = QgsLayoutItemPage(l)
|
||||
page3.setPageSize(QgsLayoutSize(100, 100, QgsUnitTypes.LayoutMeters))
|
||||
collection.addPage(page3)
|
||||
self.assertEqual(collection.maximumPageWidth(), 100000.0)
|
||||
|
||||
def testReflow(self):
|
||||
"""
|
||||
Test reflowing pages
|
||||
"""
|
||||
p = QgsProject()
|
||||
l = QgsLayout(p)
|
||||
collection = l.pageCollection()
|
||||
|
||||
#add a page
|
||||
page = QgsLayoutItemPage(l)
|
||||
page.setPageSize('A4')
|
||||
collection.addPage(page)
|
||||
|
||||
#should be positioned at origin
|
||||
self.assertEqual(page.pos().x(), 0)
|
||||
self.assertEqual(page.pos().y(), 0)
|
||||
|
||||
#second page
|
||||
page2 = QgsLayoutItemPage(l)
|
||||
page2.setPageSize('A5')
|
||||
collection.addPage(page2)
|
||||
|
||||
self.assertEqual(page.pos().x(), 0)
|
||||
self.assertEqual(page.pos().y(), 0)
|
||||
self.assertEqual(page2.pos().x(), 0)
|
||||
self.assertEqual(page2.pos().y(), 307)
|
||||
|
||||
#third page, slotted in middle
|
||||
page3 = QgsLayoutItemPage(l)
|
||||
page3.setPageSize('A3')
|
||||
collection.insertPage(page3, 1)
|
||||
|
||||
self.assertEqual(page.pos().x(), 0)
|
||||
self.assertEqual(page.pos().y(), 0)
|
||||
self.assertEqual(page2.pos().x(), 0)
|
||||
self.assertEqual(page2.pos().y(), 737)
|
||||
self.assertEqual(page3.pos().x(), 0)
|
||||
self.assertEqual(page3.pos().y(), 307)
|
||||
|
||||
page.setPageSize(QgsLayoutSize(100, 120))
|
||||
# no update until reflow is called
|
||||
self.assertEqual(page.pos().x(), 0)
|
||||
self.assertEqual(page.pos().y(), 0)
|
||||
self.assertEqual(page2.pos().x(), 0)
|
||||
self.assertEqual(page2.pos().y(), 737)
|
||||
self.assertEqual(page3.pos().x(), 0)
|
||||
self.assertEqual(page3.pos().y(), 307)
|
||||
collection.reflow()
|
||||
self.assertEqual(page.pos().x(), 0)
|
||||
self.assertEqual(page.pos().y(), 0)
|
||||
self.assertEqual(page2.pos().x(), 0)
|
||||
self.assertEqual(page2.pos().y(), 560)
|
||||
self.assertEqual(page3.pos().x(), 0)
|
||||
self.assertEqual(page3.pos().y(), 130)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user