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 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%*/
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
* @param enabled Set to true to enable the preview effect on the view
* @note added in 2.3
Expand Down
4 changes: 2 additions & 2 deletions src/app/composer/qgscomposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1227,15 +1227,15 @@ void QgsComposer::on_mActionZoomAll_triggered()

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

void QgsComposer::on_mActionZoomOut_triggered()
{
mView->scale( .5, .5 );
mView->scaleSafe( 0.5 );
mView->updateRulers();
mView->update();
emit zoomLevelChanged();
Expand Down
17 changes: 14 additions & 3 deletions src/gui/qgscomposerview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
#include "qgscursors.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 )
: QGraphicsView( parent )
, mCurrentTool( Select )
Expand Down Expand Up @@ -1651,11 +1654,11 @@ void QgsComposerView::wheelZoom( QWheelEvent * event )
//zoom composition
if ( zoomIn )
{
scale( zoomFactor, zoomFactor );
scaleSafe( zoomFactor );
}
else
{
scale( 1 / zoomFactor, 1 / zoomFactor );
scaleSafe( 1 / zoomFactor );
}

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

//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 ) );

updateRulers();
update();
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 )
{
if ( !mPreviewEffect )
Expand Down
7 changes: 7 additions & 0 deletions src/gui/qgscomposerview.h
Original file line number 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%*/
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
* @param enabled Set to true to enable the preview effect on the view
* @note added in 2.3
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Original file line number 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(PyQgsComposerPicture test_qgscomposerpicture.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(PyQgsConditionalStyle test_qgsconditionalstyle.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 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.