Skip to content

Commit

Permalink
Add Last & Next zoom actions in layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
YoannQDQ committed Sep 18, 2024
1 parent a6f34a3 commit be685de
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 9 deletions.
4 changes: 2 additions & 2 deletions python/PyQt6/gui/auto_additions/qgslayoutview.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
QgsLayoutView.PasteModeCenter = QgsLayoutView.PasteMode.PasteModeCenter
QgsLayoutView.PasteModeInPlace = QgsLayoutView.PasteMode.PasteModeInPlace
try:
QgsLayoutView.__attribute_docs__ = {'layoutSet': 'Emitted when a ``layout`` is set for the view.\n\n.. seealso:: :py:func:`currentLayout`\n\n.. seealso:: :py:func:`setCurrentLayout`\n', 'toolSet': 'Emitted when the current ``tool`` is changed.\n\n.. seealso:: :py:func:`setTool`\n', 'zoomLevelChanged': 'Emitted whenever the zoom level of the view is changed.\n', 'cursorPosChanged': 'Emitted when the mouse cursor coordinates change within the view.\nThe ``layoutPoint`` argument indicates the cursor position within\nthe layout coordinate system.\n', 'pageChanged': 'Emitted when the page visible in the view is changed. This signal\nconsiders the page at the center of the view as the current visible\npage.\n\n.. seealso:: :py:func:`currentPage`\n', 'statusMessage': "Emitted when the view has a ``message`` for display in a parent window's\nstatus bar.\n\n.. seealso:: :py:func:`pushStatusMessage`\n", 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the active\nitem and should have its properties displayed in any designer windows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted,\nbut is still in a perfectly valid state.\n'}
QgsLayoutView.__signal_arguments__ = {'layoutSet': ['layout: QgsLayout'], 'toolSet': ['tool: QgsLayoutViewTool'], 'cursorPosChanged': ['layoutPoint: QPointF'], 'pageChanged': ['page: int'], 'statusMessage': ['message: str'], 'itemFocused': ['item: QgsLayoutItem']}
QgsLayoutView.__attribute_docs__ = {'layoutSet': 'Emitted when a ``layout`` is set for the view.\n\n.. seealso:: :py:func:`currentLayout`\n\n.. seealso:: :py:func:`setCurrentLayout`\n', 'toolSet': 'Emitted when the current ``tool`` is changed.\n\n.. seealso:: :py:func:`setTool`\n', 'zoomLevelChanged': 'Emitted whenever the zoom level of the view is changed.\n', 'cursorPosChanged': 'Emitted when the mouse cursor coordinates change within the view.\nThe ``layoutPoint`` argument indicates the cursor position within\nthe layout coordinate system.\n', 'pageChanged': 'Emitted when the page visible in the view is changed. This signal\nconsiders the page at the center of the view as the current visible\npage.\n\n.. seealso:: :py:func:`currentPage`\n', 'statusMessage': "Emitted when the view has a ``message`` for display in a parent window's\nstatus bar.\n\n.. seealso:: :py:func:`pushStatusMessage`\n", 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the active\nitem and should have its properties displayed in any designer windows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted,\nbut is still in a perfectly valid state.\n', 'zoomLastStatusChanged': 'Emitted when zoom last status changed\n', 'zoomNextStatusChanged': 'Emitted when zoom next status changed\n'}
QgsLayoutView.__signal_arguments__ = {'layoutSet': ['layout: QgsLayout'], 'toolSet': ['tool: QgsLayoutViewTool'], 'zoomLevelChanged': ['appendToHistory: bool = True'], 'cursorPosChanged': ['layoutPoint: QPointF'], 'pageChanged': ['page: int'], 'statusMessage': ['message: str'], 'itemFocused': ['item: QgsLayoutItem'], 'zoomLastStatusChanged': [': bool'], 'zoomNextStatusChanged': [': bool']}
QgsLayoutView.__group__ = ['layout']
except NameError:
pass
Expand Down
28 changes: 27 additions & 1 deletion python/PyQt6/gui/auto_generated/layout/qgslayoutview.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,22 @@ Zooms to the actual size of the layout.
.. seealso:: :py:func:`zoomOut`
%End

void zoomLast();
%Docstring
Zooms to the previous zoom level

.. versionadded:: 3.38
%End

void zoomNext();
%Docstring
Zooms to the next zoom level

.. versionadded:: 3.38
%End



void emitZoomLevelChanged();


Expand Down Expand Up @@ -513,7 +529,7 @@ Emitted when the current ``tool`` is changed.
.. seealso:: :py:func:`setTool`
%End

void zoomLevelChanged();
void zoomLevelChanged( bool appendToHistory = true );
%Docstring
Emitted whenever the zoom level of the view is changed.
%End
Expand Down Expand Up @@ -552,6 +568,16 @@ item and should have its properties displayed in any designer windows.
%Docstring
Emitted in the destructor when the view is about to be deleted,
but is still in a perfectly valid state.
%End

void zoomLastStatusChanged( bool );
%Docstring
Emitted when zoom last status changed
%End

void zoomNextStatusChanged( bool );
%Docstring
Emitted when zoom next status changed
%End

protected:
Expand Down
4 changes: 2 additions & 2 deletions python/gui/auto_additions/qgslayoutview.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# The following has been generated automatically from src/gui/layout/qgslayoutview.h
try:
QgsLayoutView.__attribute_docs__ = {'layoutSet': 'Emitted when a ``layout`` is set for the view.\n\n.. seealso:: :py:func:`currentLayout`\n\n.. seealso:: :py:func:`setCurrentLayout`\n', 'toolSet': 'Emitted when the current ``tool`` is changed.\n\n.. seealso:: :py:func:`setTool`\n', 'zoomLevelChanged': 'Emitted whenever the zoom level of the view is changed.\n', 'cursorPosChanged': 'Emitted when the mouse cursor coordinates change within the view.\nThe ``layoutPoint`` argument indicates the cursor position within\nthe layout coordinate system.\n', 'pageChanged': 'Emitted when the page visible in the view is changed. This signal\nconsiders the page at the center of the view as the current visible\npage.\n\n.. seealso:: :py:func:`currentPage`\n', 'statusMessage': "Emitted when the view has a ``message`` for display in a parent window's\nstatus bar.\n\n.. seealso:: :py:func:`pushStatusMessage`\n", 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the active\nitem and should have its properties displayed in any designer windows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted,\nbut is still in a perfectly valid state.\n'}
QgsLayoutView.__signal_arguments__ = {'layoutSet': ['layout: QgsLayout'], 'toolSet': ['tool: QgsLayoutViewTool'], 'cursorPosChanged': ['layoutPoint: QPointF'], 'pageChanged': ['page: int'], 'statusMessage': ['message: str'], 'itemFocused': ['item: QgsLayoutItem']}
QgsLayoutView.__attribute_docs__ = {'layoutSet': 'Emitted when a ``layout`` is set for the view.\n\n.. seealso:: :py:func:`currentLayout`\n\n.. seealso:: :py:func:`setCurrentLayout`\n', 'toolSet': 'Emitted when the current ``tool`` is changed.\n\n.. seealso:: :py:func:`setTool`\n', 'zoomLevelChanged': 'Emitted whenever the zoom level of the view is changed.\n', 'cursorPosChanged': 'Emitted when the mouse cursor coordinates change within the view.\nThe ``layoutPoint`` argument indicates the cursor position within\nthe layout coordinate system.\n', 'pageChanged': 'Emitted when the page visible in the view is changed. This signal\nconsiders the page at the center of the view as the current visible\npage.\n\n.. seealso:: :py:func:`currentPage`\n', 'statusMessage': "Emitted when the view has a ``message`` for display in a parent window's\nstatus bar.\n\n.. seealso:: :py:func:`pushStatusMessage`\n", 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the active\nitem and should have its properties displayed in any designer windows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted,\nbut is still in a perfectly valid state.\n', 'zoomLastStatusChanged': 'Emitted when zoom last status changed\n', 'zoomNextStatusChanged': 'Emitted when zoom next status changed\n'}
QgsLayoutView.__signal_arguments__ = {'layoutSet': ['layout: QgsLayout'], 'toolSet': ['tool: QgsLayoutViewTool'], 'zoomLevelChanged': ['appendToHistory: bool = True'], 'cursorPosChanged': ['layoutPoint: QPointF'], 'pageChanged': ['page: int'], 'statusMessage': ['message: str'], 'itemFocused': ['item: QgsLayoutItem'], 'zoomLastStatusChanged': [': bool'], 'zoomNextStatusChanged': [': bool']}
QgsLayoutView.__group__ = ['layout']
except NameError:
pass
Expand Down
28 changes: 27 additions & 1 deletion python/gui/auto_generated/layout/qgslayoutview.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,22 @@ Zooms to the actual size of the layout.
.. seealso:: :py:func:`zoomOut`
%End

void zoomLast();
%Docstring
Zooms to the previous zoom level

.. versionadded:: 3.38
%End

void zoomNext();
%Docstring
Zooms to the next zoom level

.. versionadded:: 3.38
%End



void emitZoomLevelChanged();


Expand Down Expand Up @@ -513,7 +529,7 @@ Emitted when the current ``tool`` is changed.
.. seealso:: :py:func:`setTool`
%End

void zoomLevelChanged();
void zoomLevelChanged( bool appendToHistory = true );
%Docstring
Emitted whenever the zoom level of the view is changed.
%End
Expand Down Expand Up @@ -552,6 +568,16 @@ item and should have its properties displayed in any designer windows.
%Docstring
Emitted in the destructor when the view is about to be deleted,
but is still in a perfectly valid state.
%End

void zoomLastStatusChanged( bool );
%Docstring
Emitted when zoom last status changed
%End

void zoomNextStatusChanged( bool );
%Docstring
Emitted when zoom next status changed
%End

protected:
Expand Down
7 changes: 7 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,11 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
connect( mActionZoomActual, &QAction::triggered, mView, &QgsLayoutView::zoomActual );
connect( mActionZoomToWidth, &QAction::triggered, mView, &QgsLayoutView::zoomWidth );

connect( mActionZoomLast, &QAction::triggered, mView, &QgsLayoutView::zoomLast );
connect( mActionZoomNext, &QAction::triggered, mView, &QgsLayoutView::zoomNext );
connect( mView, &QgsLayoutView::zoomLastStatusChanged, mActionZoomLast, &QAction::setEnabled );
connect( mView, &QgsLayoutView::zoomNextStatusChanged, mActionZoomNext, &QAction::setEnabled );

connect( mActionSelectAll, &QAction::triggered, mView, &QgsLayoutView::selectAll );
connect( mActionDeselectAll, &QAction::triggered, mView, &QgsLayoutView::deselectAll );
connect( mActionInvertSelection, &QAction::triggered, mView, &QgsLayoutView::invertSelection );
Expand Down Expand Up @@ -4768,6 +4773,8 @@ void QgsLayoutDesignerDialog::toggleActions( bool layoutAvailable )
mActionZoomOut->setEnabled( layoutAvailable );
mActionZoomActual->setEnabled( layoutAvailable );
mActionZoomToWidth->setEnabled( layoutAvailable );
mActionZoomLast->setEnabled( layoutAvailable );
mActionZoomNext->setEnabled( layoutAvailable );
mActionAddPages->setEnabled( layoutAvailable );
mActionShowGrid->setEnabled( layoutAvailable );
mActionSnapGrid->setEnabled( layoutAvailable );
Expand Down
55 changes: 54 additions & 1 deletion src/gui/layout/qgslayoutview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ QgsLayoutView::QgsLayoutView( QWidget *parent )
mPreviewEffect = new QgsPreviewEffect( this );
viewport()->setGraphicsEffect( mPreviewEffect );

connect( this, &QgsLayoutView::zoomLevelChanged, this, &QgsLayoutView::onZoomLevelChanged );
connect( this, &QgsLayoutView::zoomLevelChanged, this, &QgsLayoutView::invalidateCachedRenders );

mScreenHelper = new QgsScreenHelper( this );
Expand Down Expand Up @@ -580,11 +581,63 @@ void QgsLayoutView::zoomActual()
setZoomLevel( 1.0 );
}

void QgsLayoutView::zoomLast()
{
mLastTransformIndex--;
setTransform( mLastTransform[mLastTransformIndex] );
invalidateCachedRenders();
// update controls' enabled state
emit zoomLastStatusChanged( mLastTransformIndex > 0 );
emit zoomNextStatusChanged( mLastTransformIndex < mLastTransform.size() - 1 );
}

void QgsLayoutView::zoomNext()
{
mLastTransformIndex++;
setTransform( mLastTransform[mLastTransformIndex] );
invalidateCachedRenders();
// update controls' enabled state
emit zoomLastStatusChanged( mLastTransformIndex > 0 );
emit zoomNextStatusChanged( mLastTransformIndex < mLastTransform.size() - 1 );
}

void QgsLayoutView::emitZoomLevelChanged()
{
emit zoomLevelChanged();
}


void QgsLayoutView::onZoomLevelChanged( bool appendToHistory )
{
if ( !appendToHistory )
{
return;
}
//clear all transforms items after current index
for ( int i = mLastTransform.size() - 1; i > mLastTransformIndex; i-- )
{
mLastTransform.removeAt( i );
}

if ( mLastTransform.isEmpty() || mLastTransform.last() != transform() )
{
mLastTransform.append( transform() );
}

// adjust history to no more than 100
if ( mLastTransform.size() > 100 )
{
mLastTransform.removeAt( 0 );
}

// the last item is the current transform
mLastTransformIndex = mLastTransform.size() - 1;

// update controls' enabled state
emit zoomLastStatusChanged( mLastTransformIndex > 0 );
emit zoomNextStatusChanged( mLastTransformIndex < mLastTransform.size() - 1 );
}

void QgsLayoutView::selectAll()
{
if ( !currentLayout() )
Expand Down Expand Up @@ -1119,7 +1172,7 @@ void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
void QgsLayoutView::resizeEvent( QResizeEvent *event )
{
QGraphicsView::resizeEvent( event );
emit zoomLevelChanged();
emit zoomLevelChanged( false );
viewChanged();
}

Expand Down
27 changes: 26 additions & 1 deletion src/gui/layout/qgslayoutview.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,20 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void zoomActual();

/**
* Zooms to the previous zoom level
* \since QGIS 3.38
*/
void zoomLast();

/**
* Zooms to the next zoom level
* \since QGIS 3.38
*/
void zoomNext();



/**
* Emits the zoomLevelChanged() signal. This should be called after
* calling any of the QGraphicsView base class methods which alter
Expand Down Expand Up @@ -496,7 +510,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
/**
* Emitted whenever the zoom level of the view is changed.
*/
void zoomLevelChanged();
void zoomLevelChanged( bool appendToHistory = true );

/**
* Emitted when the mouse cursor coordinates change within the view.
Expand Down Expand Up @@ -532,6 +546,12 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void willBeDeleted();

//! Emitted when zoom last status changed
void zoomLastStatusChanged( bool );

//! Emitted when zoom next status changed
void zoomNextStatusChanged( bool );

protected:
void mousePressEvent( QMouseEvent *event ) override;
void mouseReleaseEvent( QMouseEvent *event ) override;
Expand All @@ -548,6 +568,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
private slots:

void invalidateCachedRenders();
void onZoomLevelChanged( bool appendToHistory = true );

private:

Expand Down Expand Up @@ -584,6 +605,10 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
friend class QgsLayoutMouseHandles;

QGraphicsLineItem *createSnapLine() const;

//! recently used extent
QList <QTransform> mLastTransform;
int mLastTransformIndex = -1;
};


Expand Down
28 changes: 27 additions & 1 deletion src/ui/layout/qgslayoutdesignerbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
<addaction name="mActionZoomOut"/>
<addaction name="mActionZoomActual"/>
<addaction name="mActionZoomAll"/>
<addaction name="mActionZoomLast"/>
<addaction name="mActionZoomNext"/>
<addaction name="mActionRefreshView"/>
</widget>
<widget class="QToolBar" name="mActionsToolbar">
Expand Down Expand Up @@ -182,7 +184,7 @@
<x>0</x>
<y>0</y>
<width>2180</width>
<height>22</height>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="mLayoutMenu">
Expand Down Expand Up @@ -1585,6 +1587,30 @@
<string>&amp;Keyboard Shortcuts...</string>
</property>
</action>
<action name="mActionZoomLast">
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionZoomLast.svg</normaloff>:/images/themes/default/mActionZoomLast.svg</iconset>
</property>
<property name="text">
<string>Zoom Last</string>
</property>
<property name="shortcut">
<string>Alt+Left</string>
</property>
</action>
<action name="mActionZoomNext">
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionZoomNext.svg</normaloff>:/images/themes/default/mActionZoomNext.svg</iconset>
</property>
<property name="text">
<string>Zoom Next</string>
</property>
<property name="shortcut">
<string>Alt+Right</string>
</property>
</action>
</widget>
<resources>
<include location="../../../images/images.qrc"/>
Expand Down

0 comments on commit be685de

Please sign in to comment.