diff --git a/python/core/layout/qgslayoutpagecollection.sip b/python/core/layout/qgslayoutpagecollection.sip index 5c8e388faba..0fe4e318585 100644 --- a/python/core/layout/qgslayoutpagecollection.sip +++ b/python/core/layout/qgslayoutpagecollection.sip @@ -59,6 +59,13 @@ class QgsLayoutPageCollection : QObject :rtype: QgsLayoutItemPage %End + int pageNumber( QgsLayoutItemPage *page ) const; +%Docstring + Returns the page number for the specified ``page``, or -1 if the page + is not contained in the collection. + :rtype: int +%End + void addPage( QgsLayoutItemPage *page /Transfer/ ); %Docstring Adds a ``page`` to the collection. Ownership of the ``page`` is transferred diff --git a/python/gui/layout/qgslayoutruler.sip b/python/gui/layout/qgslayoutruler.sip index 9316109b843..93b271ca1ea 100644 --- a/python/gui/layout/qgslayoutruler.sip +++ b/python/gui/layout/qgslayoutruler.sip @@ -67,6 +67,12 @@ class QgsLayoutRuler: QWidget ``position`` is in layout coordinates. %End + signals: + void cursorPosChanged( QPointF ); +%Docstring +Is emitted when mouse cursor coordinates change +%End + protected: virtual void paintEvent( QPaintEvent *event ); @@ -77,12 +83,6 @@ class QgsLayoutRuler: QWidget virtual void mouseReleaseEvent( QMouseEvent *event ); - signals: - void cursorPosChanged( QPointF ); -%Docstring -Is emitted when mouse cursor coordinates change -%End - }; /************************************************************************ diff --git a/src/core/layout/qgslayoutpagecollection.cpp b/src/core/layout/qgslayoutpagecollection.cpp index 5aae95110e6..82beba9ce89 100644 --- a/src/core/layout/qgslayoutpagecollection.cpp +++ b/src/core/layout/qgslayoutpagecollection.cpp @@ -163,6 +163,11 @@ QgsLayoutItemPage *QgsLayoutPageCollection::page( int pageNumber ) return mPages.value( pageNumber ); } +int QgsLayoutPageCollection::pageNumber( QgsLayoutItemPage *page ) const +{ + return mPages.indexOf( page ); +} + void QgsLayoutPageCollection::addPage( QgsLayoutItemPage *page ) { mPages.append( page ); diff --git a/src/core/layout/qgslayoutpagecollection.h b/src/core/layout/qgslayoutpagecollection.h index 20024de3d80..06e1da72a6d 100644 --- a/src/core/layout/qgslayoutpagecollection.h +++ b/src/core/layout/qgslayoutpagecollection.h @@ -73,6 +73,12 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject */ QgsLayoutItemPage *page( int pageNumber ); + /** + * Returns the page number for the specified \a page, or -1 if the page + * is not contained in the collection. + */ + int pageNumber( QgsLayoutItemPage *page ) const; + /** * Adds a \a page to the collection. Ownership of the \a page is transferred * to the collection, and the page will automatically be added to the collection's diff --git a/src/gui/layout/qgslayoutruler.cpp b/src/gui/layout/qgslayoutruler.cpp index dc8b18fe985..fe5091bec9e 100644 --- a/src/gui/layout/qgslayoutruler.cpp +++ b/src/gui/layout/qgslayoutruler.cpp @@ -260,6 +260,25 @@ void QgsLayoutRuler::drawMarkerPos( QPainter *painter ) } } +void QgsLayoutRuler::createTemporaryGuideItem() +{ + mGuideItem.reset( new QGraphicsLineItem() ); + + mGuideItem->setZValue( QgsLayout::ZGuide ); + QPen linePen( Qt::DashLine ); + linePen.setColor( Qt::red ); + linePen.setWidthF( 0 ); + mGuideItem->setPen( linePen ); + + mView->currentLayout()->addItem( mGuideItem.get() ); +} + +QPointF QgsLayoutRuler::convertLocalPointToLayout( QPoint localPoint ) const +{ + QPoint viewPoint = mView->mapFromGlobal( mapToGlobal( localPoint ) ); + return mView->mapToScene( viewPoint ); +} + void QgsLayoutRuler::drawRotatedText( QPainter *painter, QPointF pos, const QString &text ) { painter->save(); @@ -432,9 +451,9 @@ void QgsLayoutRuler::mouseMoveEvent( QMouseEvent *event ) if ( mCreatingGuide ) { // event -> layout coordinates + displayPos = convertLocalPointToLayout( event->pos() ); + QgsLayout *layout = mView->currentLayout(); - QPoint viewPoint = mView->mapFromGlobal( mapToGlobal( event->pos() ) ); - displayPos = mView->mapToScene( viewPoint ); int pageNo = layout->pageCollection()->pageNumberForPoint( displayPos ); QgsLayoutItemPage *page = layout->pageCollection()->page( pageNo ); @@ -484,15 +503,7 @@ void QgsLayoutRuler::mousePressEvent( QMouseEvent *event ) if ( event->button() == Qt::LeftButton ) { mCreatingGuide = true; - mGuideItem.reset( new QGraphicsLineItem() ); - - mGuideItem->setZValue( QgsLayout::ZGuide ); - QPen linePen( Qt::DashLine ); - linePen.setColor( Qt::red ); - linePen.setWidthF( 0 ); - mGuideItem->setPen( linePen ); - - mView->currentLayout()->addItem( mGuideItem.get() ); + createTemporaryGuideItem(); switch ( mOrientation ) { @@ -516,12 +527,32 @@ void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event ) QApplication::restoreOverrideCursor(); mGuideItem.reset(); + // check that cursor left the ruler + switch ( mOrientation ) + { + case Qt::Horizontal: + { + if ( event->pos().y() <= height() ) + return; + break; + } + case Qt::Vertical: + { + if ( event->pos().x() <= width() ) + return; + break; + } + } + QgsLayout *layout = mView->currentLayout(); // create guide - QPoint viewPoint = mView->mapFromGlobal( mapToGlobal( event->pos() ) ); - QPointF scenePos = mView->mapToScene( viewPoint ); - int page = layout->pageCollection()->pageNumberForPoint( scenePos ); + QPointF scenePos = convertLocalPointToLayout( event->pos() ); + QgsLayoutItemPage *page = layout->pageCollection()->pageAtPoint( scenePos ); + if ( !page ) + return; // dragged outside of a page + + int pageNumber = layout->pageCollection()->pageNumber( page ); std::unique_ptr< QgsLayoutGuide > guide; switch ( mOrientation ) { @@ -539,7 +570,7 @@ void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event ) break; } } - guide->setPage( page ); + guide->setPage( pageNumber ); mView->currentLayout()->guides().addGuide( guide.release() ); } } diff --git a/src/gui/layout/qgslayoutruler.h b/src/gui/layout/qgslayoutruler.h index 01560bfe2c2..b87fdbc8fec 100644 --- a/src/gui/layout/qgslayoutruler.h +++ b/src/gui/layout/qgslayoutruler.h @@ -78,6 +78,10 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget */ void setCursorPosition( QPointF position ); + signals: + //! Is emitted when mouse cursor coordinates change + void cursorPosChanged( QPointF ); + protected: void paintEvent( QPaintEvent *event ) override; void mouseMoveEvent( QMouseEvent *event ) override; @@ -129,9 +133,10 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget //! Draw current marker pos on ruler void drawMarkerPos( QPainter *painter ); - signals: - //! Is emitted when mouse cursor coordinates change - void cursorPosChanged( QPointF ); + void createTemporaryGuideItem(); + + QPointF convertLocalPointToLayout( QPoint localPoint ) const; + }; diff --git a/tests/src/python/test_qgslayoutpagecollection.py b/tests/src/python/test_qgslayoutpagecollection.py index 21f5311de91..009d724753c 100644 --- a/tests/src/python/test_qgslayoutpagecollection.py +++ b/tests/src/python/test_qgslayoutpagecollection.py @@ -76,6 +76,8 @@ class TestQgsLayoutPageCollection(unittest.TestCase): # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') + self.assertEqual(collection.pageNumber(page), -1) + collection.addPage(page) self.assertTrue(page in l.items()) @@ -85,6 +87,7 @@ class TestQgsLayoutPageCollection(unittest.TestCase): self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertFalse(collection.page(1)) + self.assertEqual(collection.pageNumber(page), 0) # add a second page page2 = QgsLayoutItemPage(l) @@ -96,6 +99,7 @@ class TestQgsLayoutPageCollection(unittest.TestCase): self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page2) + self.assertEqual(collection.pageNumber(page2), 1) # insert a page page3 = QgsLayoutItemPage(l) @@ -108,6 +112,7 @@ class TestQgsLayoutPageCollection(unittest.TestCase): self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page3) self.assertEqual(collection.page(2), page2) + self.assertEqual(collection.pageNumber(page3), 1) # delete page collection.deletePage(-1)