Skip to content

Commit

Permalink
[composer] Prevent zooming out/in too far
Browse files Browse the repository at this point in the history
Would cause issues when scale became 0 and it was impossible
to further interact with the composer.

(cherry-picked from aa53cfe)
  • Loading branch information
nyalldawson committed Jun 30, 2016
1 parent 0cc424d commit 7113224
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 5 deletions.
7 changes: 7 additions & 0 deletions python/gui/qgscomposerview.sip
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ class QgsComposerView : QGraphicsView
/** Set zoom level, where a zoom level of 1.0 corresponds to 100%*/ /** Set zoom level, where a zoom level of 1.0 corresponds to 100%*/
void setZoomLevel( double zoomLevel ); void setZoomLevel( double zoomLevel );


/** Scales the view in a safe way, by limiting the acceptable range
* of the scale applied.
* @param scale factor to scale view by
* @note added in QGIS 2.16
*/
void scaleSafe( double scale );

/** Sets whether a preview effect should be used to alter the view's appearance /** Sets whether a preview effect should be used to alter the view's appearance
* @param enabled Set to true to enable the preview effect on the view * @param enabled Set to true to enable the preview effect on the view
* @note added in 2.3 * @note added in 2.3
Expand Down
4 changes: 2 additions & 2 deletions src/app/composer/qgscomposer.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1227,15 +1227,15 @@ void QgsComposer::on_mActionZoomAll_triggered()


void QgsComposer::on_mActionZoomIn_triggered() void QgsComposer::on_mActionZoomIn_triggered()
{ {
mView->scale( 2, 2 ); mView->scaleSafe( 2 );
mView->updateRulers(); mView->updateRulers();
mView->update(); mView->update();
emit zoomLevelChanged(); emit zoomLevelChanged();
} }


void QgsComposer::on_mActionZoomOut_triggered() void QgsComposer::on_mActionZoomOut_triggered()
{ {
mView->scale( .5, .5 ); mView->scaleSafe( 0.5 );
mView->updateRulers(); mView->updateRulers();
mView->update(); mView->update();
emit zoomLevelChanged(); emit zoomLevelChanged();
Expand Down
17 changes: 14 additions & 3 deletions src/gui/qgscomposerview.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
#include "qgscursors.h" #include "qgscursors.h"
#include "qgscomposerutils.h" #include "qgscomposerutils.h"


#define MIN_VIEW_SCALE 0.05
#define MAX_VIEW_SCALE 1000.0

QgsComposerView::QgsComposerView( QWidget* parent, const char* name, const Qt::WindowFlags& f ) QgsComposerView::QgsComposerView( QWidget* parent, const char* name, const Qt::WindowFlags& f )
: QGraphicsView( parent ) : QGraphicsView( parent )
, mCurrentTool( Select ) , mCurrentTool( Select )
Expand Down Expand Up @@ -1651,11 +1654,11 @@ void QgsComposerView::wheelZoom( QWheelEvent * event )
//zoom composition //zoom composition
if ( zoomIn ) if ( zoomIn )
{ {
scale( zoomFactor, zoomFactor ); scaleSafe( zoomFactor );
} }
else else
{ {
scale( 1 / zoomFactor, 1 / zoomFactor ); scaleSafe( 1 / zoomFactor );
} }


//update composition for new zoom //update composition for new zoom
Expand Down Expand Up @@ -1683,14 +1686,22 @@ void QgsComposerView::setZoomLevel( double zoomLevel )
dpi = 72; dpi = 72;


//desired pixel width for 1mm on screen //desired pixel width for 1mm on screen
double scale = zoomLevel * dpi / 25.4; double scale = qBound( MIN_VIEW_SCALE, zoomLevel * dpi / 25.4, MAX_VIEW_SCALE );
setTransform( QTransform::fromScale( scale, scale ) ); setTransform( QTransform::fromScale( scale, scale ) );


updateRulers(); updateRulers();
update(); update();
emit zoomLevelChanged(); emit zoomLevelChanged();
} }


void QgsComposerView::scaleSafe( double scale )
{
double currentScale = transform().m11();
scale *= currentScale;
scale = qBound( MIN_VIEW_SCALE, scale, MAX_VIEW_SCALE );
setTransform( QTransform::fromScale( scale, scale ) );
}

void QgsComposerView::setPreviewModeEnabled( bool enabled ) void QgsComposerView::setPreviewModeEnabled( bool enabled )
{ {
if ( !mPreviewEffect ) if ( !mPreviewEffect )
Expand Down
7 changes: 7 additions & 0 deletions src/gui/qgscomposerview.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
/** Set zoom level, where a zoom level of 1.0 corresponds to 100%*/ /** Set zoom level, where a zoom level of 1.0 corresponds to 100%*/
void setZoomLevel( double zoomLevel ); void setZoomLevel( double zoomLevel );


/** Scales the view in a safe way, by limiting the acceptable range
* of the scale applied.
* @param scale factor to scale view by
* @note added in QGIS 2.16
*/
void scaleSafe( double scale );

/** Sets whether a preview effect should be used to alter the view's appearance /** Sets whether a preview effect should be used to alter the view's appearance
* @param enabled Set to true to enable the preview effect on the view * @param enabled Set to true to enable the preview effect on the view
* @note added in 2.3 * @note added in 2.3
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ADD_PYTHON_TEST(PyQgsComposerMap test_qgscomposermap.py)
ADD_PYTHON_TEST(PyQgsComposerMapGrid test_qgscomposermapgrid.py) ADD_PYTHON_TEST(PyQgsComposerMapGrid test_qgscomposermapgrid.py)
ADD_PYTHON_TEST(PyQgsComposerPicture test_qgscomposerpicture.py) ADD_PYTHON_TEST(PyQgsComposerPicture test_qgscomposerpicture.py)
ADD_PYTHON_TEST(PyQgsComposerShapes test_qgscomposershapes.py) ADD_PYTHON_TEST(PyQgsComposerShapes test_qgscomposershapes.py)
ADD_PYTHON_TEST(PyQgsComposerView test_qgscomposerview.py)
ADD_PYTHON_TEST(PyQgsComposition test_qgscomposition.py) ADD_PYTHON_TEST(PyQgsComposition test_qgscomposition.py)
ADD_PYTHON_TEST(PyQgsConditionalStyle test_qgsconditionalstyle.py) ADD_PYTHON_TEST(PyQgsConditionalStyle test_qgsconditionalstyle.py)
ADD_PYTHON_TEST(PyQgsCoordinateTransform test_qgscoordinatetransform.py) ADD_PYTHON_TEST(PyQgsCoordinateTransform test_qgscoordinatetransform.py)
Expand Down
65 changes: 65 additions & 0 deletions tests/src/python/test_qgscomposerview.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsComposerView.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '29/05/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

import qgis # NOQA

import os

from qgis.gui import (QgsComposerView)
from qgis.PyQt.QtCore import QRectF
from qgis.PyQt.QtGui import QTransform

from qgis.testing import start_app, unittest

start_app()


class TestQgsComposerView(unittest.TestCase):

def testScaleSafe(self):
""" test scaleSafe method """

view = QgsComposerView()
view.fitInView(QRectF(0, 0, 10, 10))
scale = view.transform().m11()
view.scaleSafe(2)
self.assertAlmostEqual(view.transform().m11(), 2)
view.scaleSafe(4)
self.assertAlmostEqual(view.transform().m11(), 8)

# try to zoom in heaps
view.scaleSafe(99999999)
# assume we have hit the limit
scale = view.transform().m11()
view.scaleSafe(2)
self.assertAlmostEqual(view.transform().m11(), scale)

view.setTransform(QTransform.fromScale(1, 1))
self.assertAlmostEqual(view.transform().m11(), 1)
# test zooming out
view.scaleSafe(0.5)
self.assertAlmostEqual(view.transform().m11(), 0.5)
view.scaleSafe(0.1)
self.assertAlmostEqual(view.transform().m11(), 0.05)

# try zooming out heaps
view.scaleSafe(0.000000001)
# assume we have hit the limit
scale = view.transform().m11()
view.scaleSafe(0.5)
self.assertAlmostEqual(view.transform().m11(), scale)


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

0 comments on commit 7113224

Please sign in to comment.