Skip to content

Commit

Permalink
Add method to retrieve page at a specified layout position
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 25, 2017
1 parent f1dfd3d commit e885966
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
22 changes: 22 additions & 0 deletions python/core/layout/qgslayoutpagecollection.sip
Expand Up @@ -134,10 +134,32 @@ class QgsLayoutPageCollection : QObject
Page numbers in collections begin at 0 - so a page number of 0 indicates the
first page.

.. note::

This is a relaxed check, which will always return a page number. For instance,
it does not consider x coordinates and vertical coordinates before the first page or
after the last page will still return the nearest page.

.. seealso:: pageAtPoint()
.. seealso:: positionOnPage()
:rtype: int
%End

QgsLayoutItemPage *pageAtPoint( QPointF point ) const;
%Docstring
Returns the page at a specified ``point`` (in layout coordinates).

If no page exists at ``point``, None will be returned.

.. note::

Unlike pageNumberForPoint(), this method only returns pages which
directly intersect with the specified point.

.. seealso:: pageNumberForPoint()
:rtype: QgsLayoutItemPage
%End

QPointF positionOnPage( QPointF point ) const;
%Docstring
Returns the position within a page of a ``point`` in the layout (in layout units).
Expand Down
14 changes: 14 additions & 0 deletions src/core/layout/qgslayoutpagecollection.cpp
Expand Up @@ -82,6 +82,20 @@ int QgsLayoutPageCollection::pageNumberForPoint( QPointF point ) const
return pageNumber;
}

QgsLayoutItemPage *QgsLayoutPageCollection::pageAtPoint( QPointF point ) const
{
Q_FOREACH ( QGraphicsItem *item, mLayout->items( point ) )
{
if ( item->type() == QgsLayoutItemRegistry::LayoutPage )
{
QgsLayoutItemPage *page = static_cast< QgsLayoutItemPage * >( item );
if ( page->mapToScene( page->rect() ).boundingRect().contains( point ) )
return page;
}
}
return nullptr;
}

QPointF QgsLayoutPageCollection::positionOnPage( QPointF position ) const
{
double startCurrentPageY = 0;
Expand Down
17 changes: 17 additions & 0 deletions src/core/layout/qgslayoutpagecollection.h
Expand Up @@ -145,10 +145,27 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
* Page numbers in collections begin at 0 - so a page number of 0 indicates the
* first page.
*
* \note This is a relaxed check, which will always return a page number. For instance,
* it does not consider x coordinates and vertical coordinates before the first page or
* after the last page will still return the nearest page.
*
* \see pageAtPoint()
* \see positionOnPage()
*/
int pageNumberForPoint( QPointF point ) const;

/**
* Returns the page at a specified \a point (in layout coordinates).
*
* If no page exists at \a point, nullptr will be returned.
*
* \note Unlike pageNumberForPoint(), this method only returns pages which
* directly intersect with the specified point.
*
* \see pageNumberForPoint()
*/
QgsLayoutItemPage *pageAtPoint( QPointF point ) const;

/**
* Returns the position within a page of a \a point in the layout (in layout units).
*
Expand Down
36 changes: 36 additions & 0 deletions tests/src/python/test_qgslayoutpagecollection.py
Expand Up @@ -296,6 +296,42 @@ def testPositionOnPage(self):
self.assertEqual(collection.positionOnPage(QPointF(-100, 370)), QPointF(-100, 63))
self.assertEqual(collection.positionOnPage(QPointF(-100, 1270)), QPointF(-100, 753))

def testPageAtPoint(self):
"""
Test pageAtPoint
"""
p = QgsProject()
l = QgsLayout(p)
collection = l.pageCollection()

self.assertFalse(collection.pageAtPoint(QPointF(0, 0)))
self.assertFalse(collection.pageAtPoint(QPointF(10, 10)))

# add a page
page = QgsLayoutItemPage(l)
page.setPageSize('A4')
collection.addPage(page)

self.assertFalse(collection.pageAtPoint(QPointF(10, -1)))
self.assertEqual(collection.pageAtPoint(QPointF(1, 1)), page)
self.assertEqual(collection.pageAtPoint(QPointF(10, 10)), page)
self.assertFalse(collection.pageAtPoint(QPointF(-10, 10)))
self.assertFalse(collection.pageAtPoint(QPointF(1000, 10)))
self.assertFalse(collection.pageAtPoint(QPointF(10, -10)))
self.assertFalse(collection.pageAtPoint(QPointF(10, 1000)))

page2 = QgsLayoutItemPage(l)
page2.setPageSize('A5')
collection.addPage(page2)

self.assertEqual(collection.pageAtPoint(QPointF(1, 1)), page)
self.assertEqual(collection.pageAtPoint(QPointF(10, 10)), page)
self.assertFalse(collection.pageAtPoint(QPointF(-10, 10)))
self.assertFalse(collection.pageAtPoint(QPointF(1000, 10)))
self.assertFalse(collection.pageAtPoint(QPointF(10, -10)))
self.assertEqual(collection.pageAtPoint(QPointF(10, 330)), page2)
self.assertEqual(collection.pageAtPoint(QPointF(10, 500)), page2)
self.assertFalse(collection.pageAtPoint(QPointF(10, 600)))

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

0 comments on commit e885966

Please sign in to comment.