Skip to content

Commit ab726c4

Browse files
committed
Add methods to determine visible pages in a view
1 parent 9458f1f commit ab726c4

10 files changed

+162
-1
lines changed

python/core/layout/qgslayout.sip

+1
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
228228
:rtype: QgsLayoutPageCollection
229229
%End
230230

231+
231232
QRectF layoutBounds( bool ignorePages = false, double margin = 0.0 ) const;
232233
%Docstring
233234
Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles

python/core/layout/qgslayoutpagecollection.sip

+16
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,22 @@ class QgsLayoutPageCollection : QObject
6666
:rtype: int
6767
%End
6868

69+
QList< QgsLayoutItemPage * > visiblePages( QRectF region ) const;
70+
%Docstring
71+
Returns a list of the pages which are visible within the specified
72+
``region`` (in layout coordinates).
73+
.. seealso:: visiblePageNumbers()
74+
:rtype: list of QgsLayoutItemPage
75+
%End
76+
77+
QList< int > visiblePageNumbers( QRectF region ) const;
78+
%Docstring
79+
Returns a list of the page numbers which are visible within the specified
80+
``region`` (in layout coordinates).
81+
.. seealso:: visiblePages()
82+
:rtype: list of int
83+
%End
84+
6985
void addPage( QgsLayoutItemPage *page /Transfer/ );
7086
%Docstring
7187
Adds a ``page`` to the collection. Ownership of the ``page`` is transferred

python/gui/layout/qgslayoutview.sip

+15
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class QgsLayoutView: QGraphicsView
3737
:rtype: QgsLayout
3838
%End
3939

40+
4041
void setCurrentLayout( QgsLayout *layout /KeepReference/ );
4142
%Docstring
4243
Sets the current ``layout`` to edit in the view.
@@ -112,6 +113,20 @@ class QgsLayoutView: QGraphicsView
112113
:rtype: int
113114
%End
114115

116+
QList< QgsLayoutItemPage * > visiblePages() const;
117+
%Docstring
118+
Returns a list of page items which are currently visible in the view.
119+
.. seealso:: visiblePageNumbers()
120+
:rtype: list of QgsLayoutItemPage
121+
%End
122+
123+
QList< int > visiblePageNumbers() const;
124+
%Docstring
125+
Returns a list of page numbers for pages which are currently visible in the view.
126+
.. seealso:: visiblePages()
127+
:rtype: list of int
128+
%End
129+
115130
public slots:
116131

117132
void zoomFull();

src/core/layout/qgslayout.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ QgsLayoutPageCollection *QgsLayout::pageCollection()
135135
return mPageCollection.get();
136136
}
137137

138+
const QgsLayoutPageCollection *QgsLayout::pageCollection() const
139+
{
140+
return mPageCollection.get();
141+
}
142+
138143
QRectF QgsLayout::layoutBounds( bool ignorePages, double margin ) const
139144
{
140145
//start with an empty rectangle

src/core/layout/qgslayout.h

+6
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
262262
*/
263263
QgsLayoutPageCollection *pageCollection();
264264

265+
/**
266+
* Returns a pointer to the layout's page collection, which stores and manages
267+
* page items in the layout.
268+
*/
269+
SIP_SKIP const QgsLayoutPageCollection *pageCollection() const;
270+
265271
/**
266272
* Calculates the bounds of all non-gui items in the layout. Ignores snap lines, mouse handles
267273
* and other cosmetic items.

src/core/layout/qgslayoutpagecollection.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,30 @@ int QgsLayoutPageCollection::pageNumber( QgsLayoutItemPage *page ) const
168168
return mPages.indexOf( page );
169169
}
170170

171+
QList<QgsLayoutItemPage *> QgsLayoutPageCollection::visiblePages( QRectF region ) const
172+
{
173+
QList<QgsLayoutItemPage *> pages;
174+
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
175+
{
176+
if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
177+
pages << page;
178+
}
179+
return pages;
180+
}
181+
182+
QList<int> QgsLayoutPageCollection::visiblePageNumbers( QRectF region ) const
183+
{
184+
QList< int > pages;
185+
int p = 0;
186+
Q_FOREACH ( QgsLayoutItemPage *page, mPages )
187+
{
188+
if ( page->mapToScene( page->rect() ).boundingRect().intersects( region ) )
189+
pages << p;
190+
p++;
191+
}
192+
return pages;
193+
}
194+
171195
void QgsLayoutPageCollection::addPage( QgsLayoutItemPage *page )
172196
{
173197
mPages.append( page );

src/core/layout/qgslayoutpagecollection.h

+14
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
7979
*/
8080
int pageNumber( QgsLayoutItemPage *page ) const;
8181

82+
/**
83+
* Returns a list of the pages which are visible within the specified
84+
* \a region (in layout coordinates).
85+
* \see visiblePageNumbers()
86+
*/
87+
QList< QgsLayoutItemPage * > visiblePages( QRectF region ) const;
88+
89+
/**
90+
* Returns a list of the page numbers which are visible within the specified
91+
* \a region (in layout coordinates).
92+
* \see visiblePages()
93+
*/
94+
QList< int > visiblePageNumbers( QRectF region ) const;
95+
8296
/**
8397
* Adds a \a page to the collection. Ownership of the \a page is transferred
8498
* to the collection, and the page will automatically be added to the collection's

src/gui/layout/qgslayoutview.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ QgsLayout *QgsLayoutView::currentLayout()
5757
return qobject_cast<QgsLayout *>( scene() );
5858
}
5959

60+
const QgsLayout *QgsLayoutView::currentLayout() const
61+
{
62+
return qobject_cast<const QgsLayout *>( scene() );
63+
}
64+
6065
void QgsLayoutView::setCurrentLayout( QgsLayout *layout )
6166
{
6267
setScene( layout );
@@ -163,6 +168,22 @@ QgsLayoutViewMenuProvider *QgsLayoutView::menuProvider() const
163168
return mMenuProvider.get();
164169
}
165170

171+
QList<QgsLayoutItemPage *> QgsLayoutView::visiblePages() const
172+
{
173+
//get current visible part of scene
174+
QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
175+
QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
176+
return currentLayout()->pageCollection()->visiblePages( visibleRect );
177+
}
178+
179+
QList<int> QgsLayoutView::visiblePageNumbers() const
180+
{
181+
//get current visible part of scene
182+
QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
183+
QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
184+
return currentLayout()->pageCollection()->visiblePageNumbers( visibleRect );
185+
}
186+
166187
void QgsLayoutView::zoomFull()
167188
{
168189
fitInView( scene()->sceneRect(), Qt::KeepAspectRatio );

src/gui/layout/qgslayoutview.h

+20
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "qgis.h"
2121
#include "qgsprevieweffect.h" // for QgsPreviewEffect::PreviewMode
2222
#include "qgis_gui.h"
23+
#include "qgslayoutitempage.h"
2324
#include <QPointer>
2425
#include <QGraphicsView>
2526
#include <QGraphicsRectItem>
@@ -65,6 +66,13 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
6566
*/
6667
QgsLayout *currentLayout();
6768

69+
/**
70+
* Returns the current layout associated with the view.
71+
* \see setCurrentLayout()
72+
* \see layoutSet()
73+
*/
74+
SIP_SKIP const QgsLayout *currentLayout() const;
75+
6876
/**
6977
* Sets the current \a layout to edit in the view.
7078
* \see currentLayout()
@@ -137,6 +145,18 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
137145
*/
138146
int currentPage() const { return mCurrentPage; }
139147

148+
/**
149+
* Returns a list of page items which are currently visible in the view.
150+
* \see visiblePageNumbers()
151+
*/
152+
QList< QgsLayoutItemPage * > visiblePages() const;
153+
154+
/**
155+
* Returns a list of page numbers for pages which are currently visible in the view.
156+
* \see visiblePages()
157+
*/
158+
QList< int > visiblePageNumbers() const;
159+
140160
public slots:
141161

142162
/**

tests/src/python/test_qgslayoutpagecollection.py

+40-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
QgsLayoutPageCollection,
2626
QgsSimpleFillSymbolLayer,
2727
QgsFillSymbol)
28-
from qgis.PyQt.QtCore import Qt, QCoreApplication, QEvent, QPointF
28+
from qgis.PyQt.QtCore import Qt, QCoreApplication, QEvent, QPointF, QRectF
29+
2930
from qgis.testing import start_app, unittest
3031

3132
start_app()
@@ -378,6 +379,44 @@ def testPageAtPoint(self):
378379
self.assertEqual(collection.pageAtPoint(QPointF(10, 500)), page2)
379380
self.assertFalse(collection.pageAtPoint(QPointF(10, 600)))
380381

382+
def testVisiblePages(self):
383+
p = QgsProject()
384+
l = QgsLayout(p)
385+
collection = l.pageCollection()
386+
387+
self.assertFalse(collection.visiblePages(QRectF(0, 0, 10, 10)))
388+
self.assertFalse(collection.visiblePageNumbers(QRectF(0, 0, 10, 10)))
389+
390+
# add a page
391+
page = QgsLayoutItemPage(l)
392+
page.setPageSize('A4')
393+
collection.addPage(page)
394+
395+
self.assertFalse(collection.visiblePages(QRectF(-10, -10, 5, 5)))
396+
self.assertFalse(collection.visiblePageNumbers(QRectF(-10, -10, 5, 5)))
397+
self.assertEqual(collection.visiblePages(QRectF(-10, -10, 15, 15)), [page])
398+
self.assertEqual(collection.visiblePageNumbers(QRectF(-10, -10, 15, 15)), [0])
399+
self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 115)), [page])
400+
self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0])
401+
402+
page2 = QgsLayoutItemPage(l)
403+
page2.setPageSize('A5')
404+
collection.addPage(page2)
405+
406+
self.assertFalse(collection.visiblePages(QRectF(-10, -10, 5, 5)))
407+
self.assertFalse(collection.visiblePageNumbers(QRectF(-10, -10, 5, 5)))
408+
self.assertEqual(collection.visiblePages(QRectF(-10, -10, 15, 15)), [page])
409+
self.assertEqual(collection.visiblePageNumbers(QRectF(-10, -10, 15, 15)), [0])
410+
self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 115)), [page])
411+
self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0])
412+
413+
self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 615)), [page])
414+
self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0])
415+
self.assertEqual(collection.visiblePages(QRectF(100, 200, 115, 615)), [page, page2])
416+
self.assertEqual(collection.visiblePageNumbers(QRectF(100, 200, 115, 115)), [0, 1])
417+
self.assertEqual(collection.visiblePages(QRectF(100, 310, 115, 615)), [page2])
418+
self.assertEqual(collection.visiblePageNumbers(QRectF(100, 310, 115, 115)), [1])
419+
381420

382421
if __name__ == '__main__':
383422
unittest.main()

0 commit comments

Comments
 (0)