Skip to content

Commit ca7008c

Browse files
committedMar 13, 2019
Add API to allow QgsScaleWidget to accept NULL values
1 parent 7c58206 commit ca7008c

File tree

5 files changed

+208
-0
lines changed

5 files changed

+208
-0
lines changed
 

‎python/gui/auto_generated/qgsscalewidget.sip.in

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ Returns the selected scale as a double.
7474
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
7575

7676
.. seealso:: :py:func:`setScale`
77+
%End
78+
79+
bool isNull() const;
80+
%Docstring
81+
Returns true if the widget is currently set to a "null" value.
82+
83+
.. seealso:: :py:func:`setAllowNull`
84+
85+
.. seealso:: :py:func:`clear`
86+
87+
.. versionadded:: 3.8
7788
%End
7889

7990
double minScale() const;
@@ -101,6 +112,32 @@ The returned value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map
101112
If specified, ``ok`` will be set to ``True`` if the string was successfully interpreted as a scale.
102113

103114
.. seealso:: :py:func:`toString`
115+
%End
116+
117+
void setAllowNull( bool allowNull );
118+
%Docstring
119+
Sets whether the scale widget can be set to a NULL value.
120+
121+
.. seealso:: :py:func:`allowNull`
122+
123+
.. seealso:: :py:func:`isNull`
124+
125+
.. seealso:: :py:func:`clear`
126+
127+
.. versionadded:: 3.8
128+
%End
129+
130+
bool allowNull() const;
131+
%Docstring
132+
Returns ``True`` if the widget can be set to a NULL value.
133+
134+
.. seealso:: :py:func:`setAllowNull`
135+
136+
.. seealso:: :py:func:`isNull`
137+
138+
.. seealso:: :py:func:`clear`
139+
140+
.. versionadded:: 3.8
104141
%End
105142

106143
public slots:
@@ -132,6 +169,19 @@ Set the minimum allowed ``scale``. Set to 0 to disable the minimum scale.
132169
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
133170
Any scale lower than the minimum scale will automatically be converted to the minimum scale.
134171
Except for 0 which is always allowed.
172+
%End
173+
174+
void clear();
175+
%Docstring
176+
Sets the widget to the null value.
177+
178+
This only has an effect if allowNull() is true.
179+
180+
.. seealso:: :py:func:`allowNull`
181+
182+
.. seealso:: :py:func:`isNull`
183+
184+
.. versionadded:: 3.8
135185
%End
136186

137187
signals:

‎src/gui/qgsscalewidget.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ void QgsScaleWidget::setMapCanvas( QgsMapCanvas *canvas )
5151
mCurrentScaleButton->setVisible( mShowCurrentScaleButton && mCanvas );
5252
}
5353

54+
bool QgsScaleWidget::isNull() const
55+
{
56+
return mScaleComboBox->isNull();
57+
}
58+
59+
void QgsScaleWidget::setAllowNull( bool allowNull )
60+
{
61+
mScaleComboBox->setAllowNull( allowNull );
62+
}
63+
64+
bool QgsScaleWidget::allowNull() const
65+
{
66+
return mScaleComboBox->allowNull();
67+
}
68+
5469
void QgsScaleWidget::setScaleFromCanvas()
5570
{
5671
if ( !mCanvas )
@@ -59,6 +74,11 @@ void QgsScaleWidget::setScaleFromCanvas()
5974
setScale( mCanvas->scale() );
6075
}
6176

77+
void QgsScaleWidget::clear()
78+
{
79+
mScaleComboBox->clear();
80+
}
81+
6282
void QgsScaleWidget::setScale( double scale )
6383
{
6484
mScaleComboBox->setScale( scale );

‎src/gui/qgsscalewidget.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
8484
*/
8585
double scale() const { return mScaleComboBox->scale(); }
8686

87+
/**
88+
* Returns true if the widget is currently set to a "null" value.
89+
*
90+
* \see setAllowNull()
91+
* \see clear()
92+
* \since QGIS 3.8
93+
*/
94+
bool isNull() const;
95+
8796
/**
8897
* Returns the minimum scale, or 0 if no minimum scale set.
8998
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
@@ -109,6 +118,24 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
109118
*/
110119
static double toDouble( const QString &scaleString, bool *ok = nullptr ) { return QgsScaleComboBox::toDouble( scaleString, ok ); }
111120

121+
/**
122+
* Sets whether the scale widget can be set to a NULL value.
123+
* \see allowNull()
124+
* \see isNull()
125+
* \see clear()
126+
* \since QGIS 3.8
127+
*/
128+
void setAllowNull( bool allowNull );
129+
130+
/**
131+
* Returns TRUE if the widget can be set to a NULL value.
132+
* \see setAllowNull()
133+
* \see isNull()
134+
* \see clear()
135+
* \since QGIS 3.8
136+
*/
137+
bool allowNull() const;
138+
112139
public slots:
113140

114141
/**
@@ -138,6 +165,17 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
138165
*/
139166
void setMinScale( double scale ) { mScaleComboBox->setMinScale( scale ); }
140167

168+
/**
169+
* Sets the widget to the null value.
170+
*
171+
* This only has an effect if allowNull() is true.
172+
*
173+
* \see allowNull()
174+
* \see isNull()
175+
* \since QGIS 3.8
176+
*/
177+
void clear();
178+
141179
signals:
142180

143181
/**

‎tests/src/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ ADD_PYTHON_TEST(PyQgsRenderContext test_qgsrendercontext.py)
178178
ADD_PYTHON_TEST(PyQgsRenderer test_qgsrenderer.py)
179179
ADD_PYTHON_TEST(PyQgsReport test_qgsreport.py)
180180
ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py)
181+
ADD_PYTHON_TEST(PyQgsScaleWidget test_qgsscalewidget.py)
181182
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
182183
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
183184
ADD_PYTHON_TEST(PyQgsSvgCache test_qgssvgcache.py)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsScaleWidget
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = 'Nyall Dawson'
10+
__date__ = '13/03/2019'
11+
__copyright__ = 'Copyright 2019, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
import qgis # NOQA
16+
import math
17+
from qgis.PyQt.QtCore import Qt
18+
from qgis.PyQt.QtTest import QSignalSpy
19+
20+
from qgis.gui import QgsScaleWidget
21+
from qgis.testing import start_app, unittest
22+
23+
start_app()
24+
25+
26+
class TestQgsScaleWidget(unittest.TestCase):
27+
28+
def testBasic(self):
29+
w = QgsScaleWidget()
30+
spy = QSignalSpy(w.scaleChanged)
31+
w.setScaleString('1:2345')
32+
self.assertEqual(w.scaleString(), '1:2,345')
33+
self.assertEqual(w.scale(), 2345)
34+
self.assertEqual(len(spy), 1)
35+
self.assertEqual(spy[-1][0], 2345)
36+
37+
w.setScaleString('0.02')
38+
self.assertEqual(w.scaleString(), '1:50')
39+
self.assertEqual(w.scale(), 50)
40+
self.assertEqual(len(spy), 2)
41+
self.assertEqual(spy[-1][0], 50)
42+
43+
w.setScaleString('1:4,000')
44+
self.assertEqual(w.scaleString(), '1:4,000')
45+
self.assertEqual(w.scale(), 4000)
46+
self.assertEqual(len(spy), 3)
47+
self.assertEqual(spy[-1][0], 4000)
48+
49+
def testNull(self):
50+
w = QgsScaleWidget()
51+
52+
w.setScale(50)
53+
self.assertFalse(w.allowNull())
54+
w.clear() # no effect
55+
self.assertEqual(w.scale(), 50.0)
56+
self.assertFalse(w.isNull())
57+
58+
spy = QSignalSpy(w.scaleChanged)
59+
w.setAllowNull(True)
60+
self.assertTrue(w.allowNull())
61+
62+
w.setScaleString('')
63+
self.assertEqual(len(spy), 1)
64+
self.assertTrue(math.isnan(w.scale()))
65+
self.assertTrue(math.isnan(spy[-1][0]))
66+
self.assertTrue(w.isNull())
67+
w.setScaleString(" ")
68+
self.assertTrue(math.isnan(w.scale()))
69+
self.assertTrue(w.isNull())
70+
71+
w.setScaleString('0.02')
72+
self.assertEqual(w.scale(), 50.0)
73+
self.assertEqual(len(spy), 2)
74+
self.assertEqual(spy[-1][0], 50.0)
75+
self.assertFalse(w.isNull())
76+
77+
w.setScaleString('')
78+
self.assertTrue(math.isnan(w.scale()))
79+
self.assertEqual(len(spy), 3)
80+
self.assertTrue(math.isnan(spy[-1][0]))
81+
self.assertTrue(w.isNull())
82+
83+
w.setScaleString('0.02')
84+
self.assertEqual(w.scale(), 50.0)
85+
self.assertEqual(len(spy), 4)
86+
self.assertEqual(spy[-1][0], 50.0)
87+
self.assertFalse(w.isNull())
88+
w.clear()
89+
self.assertTrue(math.isnan(w.scale()))
90+
self.assertEqual(len(spy), 5)
91+
self.assertTrue(math.isnan(spy[-1][0]))
92+
self.assertTrue(w.isNull())
93+
94+
w.setAllowNull(False)
95+
self.assertFalse(w.allowNull())
96+
97+
98+
if __name__ == '__main__':
99+
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.