From 3fd2e0921d2005736d6848d29013abfadcec813e Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 7 Aug 2017 22:31:44 +1000 Subject: [PATCH] Fix ownership issue with layout guides --- python/core/layout/qgslayout.sip | 2 + .../core/layout/qgslayoutguidecollection.sip | 30 +++--- src/app/layout/qgslayoutguidewidget.cpp | 6 +- src/core/layout/qgslayout.cpp | 8 +- src/core/layout/qgslayout.h | 5 +- src/core/layout/qgslayoutguidecollection.cpp | 102 +++++++++++++----- src/core/layout/qgslayoutguidecollection.h | 42 +++++--- src/gui/layout/qgslayoutruler.cpp | 16 ++- tests/src/python/test_qgslayoutguides.py | 59 +++++----- 9 files changed, 171 insertions(+), 99 deletions(-) diff --git a/python/core/layout/qgslayout.sip b/python/core/layout/qgslayout.sip index 9e4accbe18f..8e55bc2ce51 100644 --- a/python/core/layout/qgslayout.sip +++ b/python/core/layout/qgslayout.sip @@ -39,6 +39,8 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator called on the new layout. %End + ~QgsLayout(); + void initializeDefaults(); %Docstring Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating diff --git a/python/core/layout/qgslayoutguidecollection.sip b/python/core/layout/qgslayoutguidecollection.sip index 33abad2937c..cf0b56ad440 100644 --- a/python/core/layout/qgslayoutguidecollection.sip +++ b/python/core/layout/qgslayoutguidecollection.sip @@ -26,7 +26,7 @@ class QgsLayoutGuide : QObject Vertical, }; - QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position ); + QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position, QgsLayoutItemPage *page ); %Docstring Constructor for a new guide with the specified ``orientation`` and initial ``position``. @@ -36,6 +36,8 @@ class QgsLayoutGuide : QObject the corresponding layout for you. %End + ~QgsLayoutGuide(); + QgsLayout *layout() const; %Docstring Returns the layout the guide belongs to. @@ -82,21 +84,17 @@ class QgsLayoutGuide : QObject .. seealso:: position() %End - int page() const; + QgsLayoutItemPage *page(); %Docstring - Returns the page number of the guide. - - Page numbering begins at 0. + Returns the page the guide is contained within. .. seealso:: setPage() - :rtype: int + :rtype: QgsLayoutItemPage %End - void setPage( int page ); + void setPage( QgsLayoutItemPage *page ); %Docstring - Sets the ``page`` number of the guide. - - Page numbering begins at 0. + Sets the ``page`` the guide is contained within. .. seealso:: page() %End @@ -155,9 +153,10 @@ class QgsLayoutGuideCollection : QAbstractTableModel LayoutPositionRole, }; - QgsLayoutGuideCollection( QgsLayout *layout ); + QgsLayoutGuideCollection( QgsLayout *layout, QgsLayoutPageCollection *pageCollection ); %Docstring - Constructor for QgsLayoutGuideCollection belonging to the specified layout. + Constructor for QgsLayoutGuideCollection belonging to the specified layout, + and linked to the specified ``pageCollection``. %End ~QgsLayoutGuideCollection(); @@ -210,9 +209,16 @@ class QgsLayoutGuideCollection : QAbstractTableModel Returns the list of guides contained in the collection with the specified ``orientation`` and on a matching ``page``. If ``page`` is -1, guides from all pages will be returned. +.. seealso:: guidesOnPage() :rtype: list of QgsLayoutGuide %End + QList< QgsLayoutGuide * > guidesOnPage( int page ); +%Docstring + Returns the list of guides contained on a matching ``page``. +.. seealso:: guides() + :rtype: list of QgsLayoutGuide +%End bool visible() const; %Docstring diff --git a/src/app/layout/qgslayoutguidewidget.cpp b/src/app/layout/qgslayoutguidewidget.cpp index 3cb16da9ede..6fc13502ea2 100644 --- a/src/app/layout/qgslayoutguidewidget.cpp +++ b/src/app/layout/qgslayoutguidewidget.cpp @@ -60,15 +60,13 @@ QgsLayoutGuideWidget::QgsLayoutGuideWidget( QWidget *parent, QgsLayout *layout, void QgsLayoutGuideWidget::addHorizontalGuide() { - std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( QgsLayoutGuide::Horizontal, QgsLayoutMeasurement( 0 ) ) ); - newGuide->setPage( mPage ); + std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( QgsLayoutGuide::Horizontal, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) ); mLayout->guides().addGuide( newGuide.release() ); } void QgsLayoutGuideWidget::addVerticalGuide() { - std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( QgsLayoutGuide::Vertical, QgsLayoutMeasurement( 0 ) ) ); - newGuide->setPage( mPage ); + std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( QgsLayoutGuide::Vertical, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) ); mLayout->guides().addGuide( newGuide.release() ); } diff --git a/src/core/layout/qgslayout.cpp b/src/core/layout/qgslayout.cpp index 61ef558abc5..bc3545b834b 100644 --- a/src/core/layout/qgslayout.cpp +++ b/src/core/layout/qgslayout.cpp @@ -22,13 +22,19 @@ QgsLayout::QgsLayout( QgsProject *project ) : QGraphicsScene() , mProject( project ) , mSnapper( QgsLayoutSnapper( this ) ) - , mGuideCollection( new QgsLayoutGuideCollection( this ) ) , mPageCollection( new QgsLayoutPageCollection( this ) ) + , mGuideCollection( new QgsLayoutGuideCollection( this, mPageCollection.get() ) ) { // just to make sure - this should be the default, but maybe it'll change in some future Qt version... setBackgroundBrush( Qt::NoBrush ); } +QgsLayout::~QgsLayout() +{ + // delete guide collection FIRST, since it depends on the page collection + mGuideCollection.reset(); +} + void QgsLayout::initializeDefaults() { // default to a A4 landscape page diff --git a/src/core/layout/qgslayout.h b/src/core/layout/qgslayout.h index 5c42e212599..4b3cfc02231 100644 --- a/src/core/layout/qgslayout.h +++ b/src/core/layout/qgslayout.h @@ -59,6 +59,8 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext */ QgsLayout( QgsProject *project ); + ~QgsLayout(); + /** * Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating * a new layout. @@ -309,10 +311,11 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext QgsLayoutContext mContext; QgsLayoutSnapper mSnapper; QgsLayoutGridSettings mGridSettings; - std::unique_ptr< QgsLayoutGuideCollection > mGuideCollection; std::unique_ptr< QgsLayoutPageCollection > mPageCollection; + std::unique_ptr< QgsLayoutGuideCollection > mGuideCollection; + }; #endif //QGSLAYOUT_H diff --git a/src/core/layout/qgslayoutguidecollection.cpp b/src/core/layout/qgslayoutguidecollection.cpp index 2f62f8b1e7a..ac157bab81b 100644 --- a/src/core/layout/qgslayoutguidecollection.cpp +++ b/src/core/layout/qgslayoutguidecollection.cpp @@ -23,20 +23,20 @@ // QgsLayoutGuide // -QgsLayoutGuide::QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position ) +QgsLayoutGuide::QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position, QgsLayoutItemPage *page ) : QObject( nullptr ) , mOrientation( orientation ) , mPosition( position ) - , mLineItem( new QGraphicsLineItem() ) + , mPage( page ) +{} + +QgsLayoutGuide::~QgsLayoutGuide() { - mLineItem->hide(); - mLineItem->setZValue( QgsLayout::ZGuide ); - QPen linePen( Qt::DotLine ); - linePen.setColor( Qt::red ); - // use a pen width of 0, since this activates a cosmetic pen - // which doesn't scale with the composer and keeps a constant size - linePen.setWidthF( 0 ); - mLineItem->setPen( linePen ); + if ( mLayout && mLineItem ) + { + mLayout->removeItem( mLineItem ); + delete mLineItem; + } } QgsLayoutMeasurement QgsLayoutGuide::position() const @@ -51,12 +51,12 @@ void QgsLayoutGuide::setPosition( const QgsLayoutMeasurement &position ) emit positionChanged(); } -int QgsLayoutGuide::page() const +QgsLayoutItemPage *QgsLayoutGuide::page() { return mPage; } -void QgsLayoutGuide::setPage( int page ) +void QgsLayoutGuide::setPage( QgsLayoutItemPage *page ) { mPage = page; update(); @@ -64,43 +64,45 @@ void QgsLayoutGuide::setPage( int page ) void QgsLayoutGuide::update() { - if ( !mLayout ) + if ( !mLayout || !mLineItem ) return; // first find matching page - if ( mPage >= mLayout->pageCollection()->pageCount() ) + if ( !mPage ) { mLineItem->hide(); return; } - QgsLayoutItemPage *page = mLayout->pageCollection()->page( mPage ); - mLineItem->setParentItem( page ); + if ( mLineItem->parentItem() != mPage ) + { + mLineItem->setParentItem( mPage ); + } double layoutPos = mLayout->convertToLayoutUnits( mPosition ); bool showGuide = mLayout->guides().visible(); switch ( mOrientation ) { case Horizontal: - if ( layoutPos > page->rect().height() ) + if ( layoutPos > mPage->rect().height() ) { mLineItem->hide(); } else { - mLineItem->setLine( 0, layoutPos, page->rect().width(), layoutPos ); + mLineItem->setLine( 0, layoutPos, mPage->rect().width(), layoutPos ); mLineItem->setVisible( showGuide ); } break; case Vertical: - if ( layoutPos > page->rect().width() ) + if ( layoutPos > mPage->rect().width() ) { mLineItem->hide(); } else { - mLineItem->setLine( layoutPos, 0, layoutPos, page->rect().height() ); + mLineItem->setLine( layoutPos, 0, layoutPos, mPage->rect().height() ); mLineItem->setVisible( showGuide ); } @@ -110,11 +112,14 @@ void QgsLayoutGuide::update() QGraphicsLineItem *QgsLayoutGuide::item() { - return mLineItem.get(); + return mLineItem; } double QgsLayoutGuide::layoutPosition() const { + if ( !mLineItem ) + return -999; + switch ( mOrientation ) { case Horizontal: @@ -128,6 +133,9 @@ double QgsLayoutGuide::layoutPosition() const void QgsLayoutGuide::setLayoutPosition( double position ) { + if ( !mLayout ) + return; + double p = 0; switch ( mOrientation ) { @@ -152,7 +160,21 @@ QgsLayout *QgsLayoutGuide::layout() const void QgsLayoutGuide::setLayout( QgsLayout *layout ) { mLayout = layout; - mLayout->addItem( mLineItem.get() ); + + if ( !mLineItem ) + { + mLineItem = new QGraphicsLineItem(); + mLineItem->hide(); + mLineItem->setZValue( QgsLayout::ZGuide ); + QPen linePen( Qt::DotLine ); + linePen.setColor( Qt::red ); + // use a pen width of 0, since this activates a cosmetic pen + // which doesn't scale with the composer and keeps a constant size + linePen.setWidthF( 0 ); + mLineItem->setPen( linePen ); + } + + mLayout->addItem( mLineItem ); update(); } @@ -167,12 +189,15 @@ QgsLayoutGuide::Orientation QgsLayoutGuide::orientation() const // QgsLayoutGuideCollection // -QgsLayoutGuideCollection::QgsLayoutGuideCollection( QgsLayout *layout ) +QgsLayoutGuideCollection::QgsLayoutGuideCollection( QgsLayout *layout, QgsLayoutPageCollection *pageCollection ) : QAbstractTableModel( layout ) , mLayout( layout ) + , mPageCollection( pageCollection ) { QFont f; mHeaderSize = QFontMetrics( f ).width( "XX" ); + + connect( mPageCollection, &QgsLayoutPageCollection::pageAboutToBeRemoved, this, &QgsLayoutGuideCollection::pageAboutToBeRemoved ); } QgsLayoutGuideCollection::~QgsLayoutGuideCollection() @@ -223,7 +248,7 @@ QVariant QgsLayoutGuideCollection::data( const QModelIndex &index, int role ) co return guide->position().units(); case PageRole: - return guide->page(); + return mPageCollection->pageNumber( guide->page() ); case LayoutPositionRole: return guide->layoutPosition(); @@ -358,23 +383,23 @@ void QgsLayoutGuideCollection::clear() void QgsLayoutGuideCollection::applyGuidesToAllOtherPages( int sourcePage ) { + QgsLayoutItemPage *page = mPageCollection->page( sourcePage ); // remove other page's guides Q_FOREACH ( QgsLayoutGuide *guide, mGuides ) { - if ( guide->page() != sourcePage ) + if ( guide->page() != page ) removeGuide( guide ); } // remaining guides belong to source page - clone them to other pages Q_FOREACH ( QgsLayoutGuide *guide, mGuides ) { - for ( int p = 0; p < mLayout->pageCollection()->pageCount(); ++p ) + for ( int p = 0; p < mPageCollection->pageCount(); ++p ) { if ( p == sourcePage ) continue; - std::unique_ptr< QgsLayoutGuide> newGuide( new QgsLayoutGuide( guide->orientation(), guide->position() ) ); - newGuide->setPage( p ); + std::unique_ptr< QgsLayoutGuide> newGuide( new QgsLayoutGuide( guide->orientation(), guide->position(), mPageCollection->page( p ) ) ); newGuide->setLayout( mLayout ); if ( newGuide->item()->isVisible() ) { @@ -399,7 +424,18 @@ QList QgsLayoutGuideCollection::guides( QgsLayoutGuide::Orient Q_FOREACH ( QgsLayoutGuide *guide, mGuides ) { if ( guide->orientation() == orientation && guide->item()->isVisible() && - ( page < 0 || page == guide->page() ) ) + ( page < 0 || mPageCollection->page( page ) == guide->page() ) ) + res << guide; + } + return res; +} + +QList QgsLayoutGuideCollection::guidesOnPage( int page ) +{ + QList res; + Q_FOREACH ( QgsLayoutGuide *guide, mGuides ) + { + if ( mPageCollection->page( page ) == guide->page() ) res << guide; } return res; @@ -416,6 +452,14 @@ void QgsLayoutGuideCollection::setVisible( bool visible ) update(); } +void QgsLayoutGuideCollection::pageAboutToBeRemoved( int pageNumber ) +{ + Q_FOREACH ( QgsLayoutGuide *guide, guidesOnPage( pageNumber ) ) + { + removeGuide( guide ); + } +} + // diff --git a/src/core/layout/qgslayoutguidecollection.h b/src/core/layout/qgslayoutguidecollection.h index 7e4c78f9987..4615d980237 100644 --- a/src/core/layout/qgslayoutguidecollection.h +++ b/src/core/layout/qgslayoutguidecollection.h @@ -19,6 +19,7 @@ #include "qgis_core.h" #include "qgslayoutmeasurement.h" #include "qgslayoutpoint.h" +#include "qgslayoutitempage.h" #include #include #include @@ -26,6 +27,7 @@ #include class QgsLayout; +class QgsLayoutPageCollection; /** * \ingroup core @@ -55,7 +57,9 @@ class CORE_EXPORT QgsLayoutGuide : public QObject * Adding the guide to a QgsLayoutGuideCollection will automatically set * the corresponding layout for you. */ - QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position ); + QgsLayoutGuide( Orientation orientation, const QgsLayoutMeasurement &position, QgsLayoutItemPage *page ); + + ~QgsLayoutGuide(); /** * Returns the layout the guide belongs to. @@ -99,22 +103,18 @@ class CORE_EXPORT QgsLayoutGuide : public QObject void setPosition( const QgsLayoutMeasurement &position ); /** - * Returns the page number of the guide. - * - * Page numbering begins at 0. + * Returns the page the guide is contained within. * * \see setPage() */ - int page() const; + QgsLayoutItemPage *page(); /** - * Sets the \a page number of the guide. - * - * Page numbering begins at 0. + * Sets the \a page the guide is contained within. * * \see page() */ - void setPage( int page ); + void setPage( QgsLayoutItemPage *page ); /** * Updates the position of the guide's line item. @@ -152,13 +152,13 @@ class CORE_EXPORT QgsLayoutGuide : public QObject //! Horizontal/vertical position of guide on page QgsLayoutMeasurement mPosition; - //! Page number, 0 index based - int mPage = 0; + //! Page + QPointer< QgsLayoutItemPage > mPage; - QgsLayout *mLayout = nullptr; + QPointer< QgsLayout > mLayout; //! Line item used in scene for guide - std::unique_ptr< QGraphicsLineItem > mLineItem; + QGraphicsLineItem *mLineItem = nullptr; }; @@ -186,9 +186,10 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel }; /** - * Constructor for QgsLayoutGuideCollection belonging to the specified layout. + * Constructor for QgsLayoutGuideCollection belonging to the specified layout, + * and linked to the specified \a pageCollection. */ - QgsLayoutGuideCollection( QgsLayout *layout ); + QgsLayoutGuideCollection( QgsLayout *layout, QgsLayoutPageCollection *pageCollection ); ~QgsLayoutGuideCollection(); int rowCount( const QModelIndex & ) const override; @@ -233,9 +234,15 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel * Returns the list of guides contained in the collection with the specified * \a orientation and on a matching \a page. * If \a page is -1, guides from all pages will be returned. + * \see guidesOnPage() */ QList< QgsLayoutGuide * > guides( QgsLayoutGuide::Orientation orientation, int page = -1 ); + /** + * Returns the list of guides contained on a matching \a page. + * \see guides() + */ + QList< QgsLayoutGuide * > guidesOnPage( int page ); /** * Returns true if the guide lines should be drawn. @@ -249,9 +256,14 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel */ void setVisible( bool visible ); + private slots: + + void pageAboutToBeRemoved( int pageNumber ); + private: QgsLayout *mLayout = nullptr; + QgsLayoutPageCollection *mPageCollection = nullptr; QList< QgsLayoutGuide * > mGuides; int mHeaderSize = 0; diff --git a/src/gui/layout/qgslayoutruler.cpp b/src/gui/layout/qgslayoutruler.cpp index 44dd81b2de5..931dc8a5ed0 100644 --- a/src/gui/layout/qgslayoutruler.cpp +++ b/src/gui/layout/qgslayoutruler.cpp @@ -281,14 +281,14 @@ void QgsLayoutRuler::drawMarkerPos( QPainter *painter ) void QgsLayoutRuler::drawGuideMarkers( QPainter *p, QgsLayout *layout ) { - QList< int > visiblePageNumbers = mView->visiblePageNumbers(); + QList< QgsLayoutItemPage * > visiblePages = mView->visiblePages(); QList< QgsLayoutGuide * > guides = layout->guides().guides( mOrientation == Qt::Horizontal ? QgsLayoutGuide::Vertical : QgsLayoutGuide::Horizontal ); p->save(); p->setRenderHint( QPainter::Antialiasing, true ); p->setPen( Qt::NoPen ); Q_FOREACH ( QgsLayoutGuide *guide, guides ) { - if ( visiblePageNumbers.contains( guide->page() ) ) + if ( visiblePages.contains( guide->page() ) ) { if ( guide == mHoverGuide ) { @@ -364,13 +364,13 @@ QPoint QgsLayoutRuler::convertLayoutPointToLocal( QPointF layoutPoint ) const QgsLayoutGuide *QgsLayoutRuler::guideAtPoint( QPoint localPoint ) const { QPointF layoutPoint = convertLocalPointToLayout( localPoint ); - QList< int > visiblePageNumbers = mView->visiblePageNumbers(); + QList< QgsLayoutItemPage * > visiblePages = mView->visiblePages(); QList< QgsLayoutGuide * > guides = mView->currentLayout()->guides().guides( mOrientation == Qt::Horizontal ? QgsLayoutGuide::Vertical : QgsLayoutGuide::Horizontal ); QgsLayoutGuide *closestGuide = nullptr; double minDelta = DBL_MAX; Q_FOREACH ( QgsLayoutGuide *guide, guides ) { - if ( visiblePageNumbers.contains( guide->page() ) ) + if ( visiblePages.contains( guide->page() ) ) { double currentDelta = 0; switch ( mOrientation ) @@ -707,7 +707,7 @@ void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event ) QPointF layoutPoint = convertLocalPointToLayout( event->pos() ); // delete guide if it ends outside of page - QgsLayoutItemPage *page = mView->currentLayout()->pageCollection()->page( mDraggingGuide->page() ); + QgsLayoutItemPage *page = mDraggingGuide->page(); bool deleteGuide = false; switch ( mDraggingGuide->orientation() ) { @@ -759,7 +759,6 @@ void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event ) if ( !page ) return; // dragged outside of a page - int pageNumber = layout->pageCollection()->pageNumber( page ); std::unique_ptr< QgsLayoutGuide > guide; switch ( mOrientation ) { @@ -767,17 +766,16 @@ void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event ) { //mouse is creating a horizontal guide double posOnPage = layout->pageCollection()->positionOnPage( scenePos ).y(); - guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Horizontal, QgsLayoutMeasurement( posOnPage, layout->units() ) ) ); + guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Horizontal, QgsLayoutMeasurement( posOnPage, layout->units() ), page ) ); break; } case Qt::Vertical: { //mouse is creating a vertical guide - guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Vertical, QgsLayoutMeasurement( scenePos.x(), layout->units() ) ) ); + guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Vertical, QgsLayoutMeasurement( scenePos.x(), layout->units() ), page ) ); break; } } - guide->setPage( pageNumber ); mView->currentLayout()->guides().addGuide( guide.release() ); } } diff --git a/tests/src/python/test_qgslayoutguides.py b/tests/src/python/test_qgslayoutguides.py index 5444f88f8d7..91b965adcb0 100644 --- a/tests/src/python/test_qgslayoutguides.py +++ b/tests/src/python/test_qgslayoutguides.py @@ -41,7 +41,7 @@ class TestQgsLayoutGuide(unittest.TestCase): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page - g = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), None) self.assertEqual(g.orientation(), QgsLayoutGuide.Horizontal) self.assertEqual(g.position().length(), 5.0) self.assertEqual(g.position().units(), QgsUnitTypes.LayoutCentimeters) @@ -55,14 +55,15 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(g.position().units(), QgsUnitTypes.LayoutInches) self.assertEqual(len(position_changed_spy), 1) - g.setPage(1) - self.assertEqual(g.page(), 1) + page = l.pageCollection().page(0) + g.setPage(page) + self.assertEqual(g.page(), page) def testUpdateGuide(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page - g = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g.setLayout(l) g.update() @@ -83,7 +84,7 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(g.layoutPosition(), 15) # vertical guide - g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g2.setLayout(l) g2.update() self.assertTrue(g2.item().isVisible()) @@ -93,11 +94,11 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(g2.item().line().y2(), 210) self.assertEqual(g2.layoutPosition(), 50) - g.setPage(10) + g.setPage(None) g.update() self.assertFalse(g.item().isVisible()) - g.setPage(0) + g.setPage(l.pageCollection().page(0)) g.update() self.assertTrue(g.item().isVisible()) @@ -119,7 +120,7 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) # add a guide - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) self.assertEqual(guides.rowCount(QModelIndex()), 1) self.assertEqual(guides.data(guides.index(0, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Horizontal) @@ -128,8 +129,10 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(guides.data(guides.index(0, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1]) self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) + self.assertEqual(guides.guidesOnPage(0), [g1]) + self.assertEqual(guides.guidesOnPage(1), []) - g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(0)) guides.addGuide(g2) self.assertEqual(guides.rowCount(QModelIndex()), 2) self.assertEqual(guides.data(guides.index(1, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Horizontal) @@ -138,12 +141,12 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(guides.data(guides.index(1, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2]) self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) + self.assertEqual(guides.guidesOnPage(0), [g1, g2]) page2 = QgsLayoutItemPage(l) page2.setPageSize('A3') l.pageCollection().addPage(page2) - g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35)) - g3.setPage(1) + g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(1)) guides.addGuide(g3) self.assertEqual(guides.rowCount(QModelIndex()), 3) self.assertEqual(guides.data(guides.index(2, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Vertical) @@ -157,6 +160,8 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0), []) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 1), [g3]) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 2), []) + self.assertEqual(guides.guidesOnPage(0), [g1, g2]) + self.assertEqual(guides.guidesOnPage(1), [g3]) def testDeleteRows(self): p = QgsProject() @@ -164,11 +169,11 @@ class TestQgsLayoutGuide(unittest.TestCase): l.initializeDefaults() guides = l.guides() - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) - g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(0)) guides.addGuide(g2) - g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35)) + g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(0)) guides.addGuide(g3) self.assertTrue(guides.removeRows(1, 1)) @@ -201,12 +206,11 @@ class TestQgsLayoutGuide(unittest.TestCase): self.assertEqual(vert_filter.rowCount(QModelIndex()), 0) # add some guides - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) - g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15)) - g2.setPage(1) + g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(1)) guides.addGuide(g2) - g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35)) + g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(0)) guides.addGuide(g3) self.assertEqual(hoz_filter.rowCount(QModelIndex()), 1) @@ -228,7 +232,7 @@ class TestQgsLayoutGuide(unittest.TestCase): guides = l.guides() # add a guide - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1]) guides.removeGuide(None) @@ -243,9 +247,9 @@ class TestQgsLayoutGuide(unittest.TestCase): guides = l.guides() # add a guide - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) - g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g2) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2]) guides.clear() @@ -261,14 +265,13 @@ class TestQgsLayoutGuide(unittest.TestCase): guides = l.guides() # add some guides - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5), l.pageCollection().page(0)) guides.addGuide(g1) - g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6), l.pageCollection().page(0)) guides.addGuide(g2) - g3 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(190)) + g3 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(190), l.pageCollection().page(0)) guides.addGuide(g3) - g4 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(1)) - g4.setPage(1) + g4 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(1), l.pageCollection().page(1)) guides.addGuide(g4) # apply guides from page 0 - should delete g4 @@ -300,9 +303,9 @@ class TestQgsLayoutGuide(unittest.TestCase): guides = l.guides() # add some guides - g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5)) + g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5), l.pageCollection().page(0)) guides.addGuide(g1) - g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6)) + g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6), l.pageCollection().page(0)) guides.addGuide(g2) guides.setVisible(False)