Skip to content

Commit 1c3ae78

Browse files
committedMar 1, 2018
Fix crash when using the identify tool on a categorized render
with an unchecked category corresponding to the feature at the clicked point Also fix count of default category symbols (cherry-picked from 0acdcfa)
1 parent 6d9c553 commit 1c3ae78

File tree

6 files changed

+106
-20
lines changed

6 files changed

+106
-20
lines changed
 

‎python/core/symbology/qgscategorizedsymbolrenderer.sip.in

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,22 @@ copy constructor
4545
void setLabel( const QString &label );
4646

4747
bool renderState() const;
48+
%Docstring
49+
Returns true if the category is currently enabled and should be rendered.
50+
51+
.. seealso:: :py:func:`setRenderState`
52+
53+
.. versionadded:: 2.5
54+
%End
55+
4856
void setRenderState( bool render );
57+
%Docstring
58+
Sets whether the category is currently enabled and should be rendered.
59+
60+
.. seealso:: :py:func:`renderState`
61+
62+
.. versionadded:: 2.5
63+
%End
4964

5065
QString dump() const;
5166

@@ -252,9 +267,36 @@ Will return null if the functionality is disabled.
252267
hashtable for faster access to symbols
253268
%End
254269

255-
QgsSymbol *skipRender();
270+
QgsSymbol *skipRender() /Deprecated/;
271+
%Docstring
256272

257-
QgsSymbol *symbolForValue( const QVariant &value );
273+
.. deprecated:: No longer used, will be removed in QGIS 4.0
274+
%End
275+
276+
QgsSymbol *symbolForValue( const QVariant &value ) /Deprecated/;
277+
%Docstring
278+
Returns the matching symbol corresponding to an attribute ``value``.
279+
280+
.. deprecated:: use variant which takes a second bool argument instead.
281+
%End
282+
283+
284+
QgsSymbol *symbolForValue( const QVariant &value, bool &foundMatchingSymbol /Out/ ) /PyName=symbolForValue2/;
285+
%Docstring
286+
Returns the matching symbol corresponding to an attribute ``value``.
287+
288+
Will return None if no matching symbol was found for ``value``, or
289+
if the category corresponding to ``value`` is currently disabled (see QgsRendererCategory.renderState()).
290+
291+
If ``foundMatchingSymbol`` is specified then it will be set to true if
292+
a matching category was found. This can be used to differentiate between
293+
a None returned as a result of no matching category vs a None as a result
294+
of disabled categories.
295+
296+
.. note::
297+
298+
available in Python bindings as symbolForValue2
299+
%End
258300

259301
private:
260302
QgsCategorizedSymbolRenderer( const QgsCategorizedSymbolRenderer & );

‎python/gui/qgisinterface.sip.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,7 @@ Unregister a previously registered custom drop ``handler`` for layout windows.
849849
%End
850850

851851

852+
852853
virtual void openURL( const QString &url, bool useQgisDocDirectory = true ) = 0 /Deprecated/;
853854
%Docstring
854855
Open a url in the users browser. By default the QGIS doc directory is used

‎python/server/qgsmapserviceexception.sip.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class QgsMapServiceException : QgsOgcServiceException
1616
%Docstring
1717
Exception class for WMS service exceptions (for compatibility only).
1818

19-
\deprecated Use QsgServerException
19+
.. deprecated:: Use QsgServerException
2020

2121
The most important codes are:
2222
* "InvalidFormat"

‎scripts/sipify.pl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ sub processDoxygenLine {
192192
if ( $line =~ m/\\since .*?([\d\.]+)/i ) {
193193
return "\n.. versionadded:: $1\n";
194194
}
195+
if ( $line =~ m/\\deprecated (.*)/i ) {
196+
return "\n.. deprecated:: $1\n";
197+
}
195198

196199
# create links in see also
197200
if ( $line =~ m/\\see +(\w+(\.\w+)*)(\([^()]*\))?/ ) {
@@ -596,7 +599,7 @@ sub detect_non_method_member{
596599
next;
597600
}
598601
# Skip Q_OBJECT, Q_PROPERTY, Q_ENUM, Q_GADGET etc.
599-
if ($LINE =~ m/^\s*Q_(OBJECT|ENUMS|ENUM|FLAG|PROPERTY|GADGET|DECLARE_METATYPE|DECLARE_TYPEINFO|DECL_DEPRECATED|NOWARN_DEPRECATED_(PUSH|POP))\b.*?$/){
602+
if ($LINE =~ m/^\s*Q_(OBJECT|ENUMS|ENUM|FLAG|PROPERTY|GADGET|DECLARE_METATYPE|DECLARE_TYPEINFO|NOWARN_DEPRECATED_(PUSH|POP))\b.*?$/){
600603
next;
601604
}
602605

@@ -847,6 +850,7 @@ sub detect_non_method_member{
847850
$LINE =~ s/^(\s*template\s*<)(?:class|typename) (\w+>)(.*)$/$1$2$3/;
848851
$LINE =~ s/\s*\boverride\b//;
849852
$LINE =~ s/\s*\bextern \b//;
853+
$LINE =~ s/\s*\bQ_DECL_DEPRECATED\b//;
850854
$LINE =~ s/^(\s*)?(const )?(virtual |static )?inline /$1$2$3/;
851855
$LINE =~ s/\bconstexpr\b/const/;
852856
$LINE =~ s/\bnullptr\b/0/g;

‎src/core/symbology/qgscategorizedsymbolrenderer.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,25 @@ void QgsCategorizedSymbolRenderer::rebuildHash()
168168
for ( int i = 0; i < mCategories.size(); ++i )
169169
{
170170
const QgsRendererCategory &cat = mCategories.at( i );
171-
mSymbolHash.insert( cat.value().toString(), ( cat.renderState() || mCounting ) ? cat.symbol() : skipRender() );
171+
mSymbolHash.insert( cat.value().toString(), ( cat.renderState() || mCounting ) ? cat.symbol() : nullptr );
172172
}
173173
}
174174

175175
QgsSymbol *QgsCategorizedSymbolRenderer::skipRender()
176176
{
177-
static QgsMarkerSymbol *skipRender = nullptr;
178-
if ( !skipRender )
179-
skipRender = new QgsMarkerSymbol();
180-
181-
return skipRender;
177+
return nullptr;
182178
}
183179

184180
QgsSymbol *QgsCategorizedSymbolRenderer::symbolForValue( const QVariant &value )
185181
{
182+
bool found = false;
183+
return symbolForValue( value, found );
184+
}
185+
186+
QgsSymbol *QgsCategorizedSymbolRenderer::symbolForValue( const QVariant &value, bool &foundMatchingSymbol )
187+
{
188+
foundMatchingSymbol = false;
189+
186190
// TODO: special case for int, double
187191
QHash<QString, QgsSymbol *>::const_iterator it = mSymbolHash.constFind( value.isNull() ? QLatin1String( "" ) : value.toString() );
188192
if ( it == mSymbolHash.constEnd() )
@@ -198,6 +202,8 @@ QgsSymbol *QgsCategorizedSymbolRenderer::symbolForValue( const QVariant &value )
198202
return nullptr;
199203
}
200204

205+
foundMatchingSymbol = true;
206+
201207
return *it;
202208
}
203209

@@ -228,15 +234,14 @@ QgsSymbol *QgsCategorizedSymbolRenderer::originalSymbolForFeature( QgsFeature &f
228234
{
229235
QVariant value = valueForFeature( feature, context );
230236

237+
bool foundCategory = false;
231238
// find the right symbol for the category
232-
QgsSymbol *symbol = symbolForValue( value );
233-
if ( symbol == skipRender() )
234-
return nullptr;
239+
QgsSymbol *symbol = symbolForValue( value, foundCategory );
235240

236-
if ( !symbol )
241+
if ( !foundCategory )
237242
{
238-
// if no symbol found use default one
239-
return symbolForValue( QVariant( "" ) );
243+
// if no symbol found, use default symbol
244+
return symbolForValue( QVariant( "" ), foundCategory );
240245
}
241246

242247
return symbol;
@@ -793,7 +798,7 @@ QSet<QString> QgsCategorizedSymbolRenderer::legendKeysForFeature( QgsFeature &fe
793798
{
794799
if ( value == cat.value() )
795800
{
796-
if ( cat.renderState() )
801+
if ( cat.renderState() || mCounting )
797802
return QSet< QString >() << QString::number( i );
798803
else
799804
return QSet< QString >();

‎src/core/symbology/qgscategorizedsymbolrenderer.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,18 @@ class CORE_EXPORT QgsRendererCategory
5656
void setSymbol( QgsSymbol *s SIP_TRANSFER );
5757
void setLabel( const QString &label );
5858

59-
// \since QGIS 2.5
59+
/**
60+
* Returns true if the category is currently enabled and should be rendered.
61+
* \see setRenderState()
62+
* \since QGIS 2.5
63+
*/
6064
bool renderState() const;
65+
66+
/**
67+
* Sets whether the category is currently enabled and should be rendered.
68+
* \see renderState()
69+
* \since QGIS 2.5
70+
*/
6171
void setRenderState( bool render );
6272

6373
// debugging
@@ -233,9 +243,33 @@ class CORE_EXPORT QgsCategorizedSymbolRenderer : public QgsFeatureRenderer
233243

234244
void rebuildHash();
235245

236-
QgsSymbol *skipRender();
246+
/**
247+
* \deprecated No longer used, will be removed in QGIS 4.0
248+
*/
249+
Q_DECL_DEPRECATED QgsSymbol *skipRender() SIP_DEPRECATED;
250+
251+
/**
252+
* Returns the matching symbol corresponding to an attribute \a value.
253+
* \deprecated use variant which takes a second bool argument instead.
254+
*/
255+
Q_DECL_DEPRECATED QgsSymbol *symbolForValue( const QVariant &value ) SIP_DEPRECATED;
237256

238-
QgsSymbol *symbolForValue( const QVariant &value );
257+
// TODO QGIS 4.0 - rename Python method to symbolForValue
258+
259+
/**
260+
* Returns the matching symbol corresponding to an attribute \a value.
261+
*
262+
* Will return nullptr if no matching symbol was found for \a value, or
263+
* if the category corresponding to \a value is currently disabled (see QgsRendererCategory::renderState()).
264+
*
265+
* If \a foundMatchingSymbol is specified then it will be set to true if
266+
* a matching category was found. This can be used to differentiate between
267+
* a nullptr returned as a result of no matching category vs a nullptr as a result
268+
* of disabled categories.
269+
*
270+
* \note available in Python bindings as symbolForValue2
271+
*/
272+
QgsSymbol *symbolForValue( const QVariant &value, bool &foundMatchingSymbol SIP_OUT ) SIP_PYNAME( symbolForValue2 );
239273

240274
private:
241275
#ifdef SIP_RUN

0 commit comments

Comments
 (0)
Please sign in to comment.