QGIS API Documentation 4.1.0-Master (64029b4150b)
Loading...
Searching...
No Matches
qgscategorizedsymbolutils.h
Go to the documentation of this file.
1/***************************************************************************
2 qgscategorizedsymbolutils.h
3 ---------------------
4 begin : May 2026
5 copyright : (C) 2026 by Jean Felder
6 email : jean dot felder at oslandia dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsexpression.h"
17#include "qgsfields.h"
18#include "qgsvariantutils.h"
19
20#include <QString>
21
22#define SIP_NO_FILE
23
24using namespace Qt::StringLiterals;
25
26
32template<typename RendererType> class QgsCategorizedSymbolUtils
33{
34 public:
35 using Categories = RendererType::Categories;
36
48 static QString buildCategorizedFilter( const QString &attributeName, const QgsFields &fields, const Categories &categories )
49 {
50 const int attributeNumber = fields.lookupField( attributeName );
51 const bool isExpression = ( attributeNumber == -1 );
52
53 bool hasDefault = false;
54 bool defaultActive = false;
55 bool allActive = true;
56 bool noneActive = true;
57
58 // we need to build lists of both inactive and active values, as either list may be required
59 // depending on whether the default category is active or not
60 QString activeValues;
61 QString inactiveValues;
62
63 for ( const typename RendererType::Category &category : categories )
64 {
65 const QVariant variantValue = category.value();
66 if ( variantValue == "" || QgsVariantUtils::isNull( variantValue ) )
67 {
68 hasDefault = true;
69 defaultActive = category.renderState();
70 }
71 noneActive = noneActive && !category.renderState();
72 allActive = allActive && category.renderState();
73
74 const bool isList = variantValue.userType() == QMetaType::Type::QVariantList;
75 const QString quotedValue = QgsExpression::quotedValue( variantValue, static_cast<QMetaType::Type>( variantValue.userType() ) );
76
77 if ( !category.renderState() )
78 {
79 if ( quotedValue != "" )
80 {
81 if ( isList )
82 {
83 const QVariantList list = variantValue.toList();
84 for ( const QVariant &v : list )
85 {
86 if ( !inactiveValues.isEmpty() )
87 inactiveValues.append( ',' );
88
89 inactiveValues.append( QgsExpression::quotedValue( v, isExpression ? static_cast<QMetaType::Type>( v.userType() ) : fields.at( attributeNumber ).type() ) );
90 }
91 }
92 else
93 {
94 if ( !inactiveValues.isEmpty() )
95 inactiveValues.append( ',' );
96
97 inactiveValues.append( quotedValue );
98 }
99 }
100 }
101 else
102 {
103 if ( quotedValue != "" )
104 {
105 if ( isList )
106 {
107 const QVariantList list = variantValue.toList();
108 for ( const QVariant &v : list )
109 {
110 if ( !activeValues.isEmpty() )
111 activeValues.append( ',' );
112
113 activeValues.append( QgsExpression::quotedValue( v, isExpression ? static_cast<QMetaType::Type>( v.userType() ) : fields.at( attributeNumber ).type() ) );
114 }
115 }
116 else
117 {
118 if ( !activeValues.isEmpty() )
119 activeValues.append( ',' );
120
121 activeValues.append( quotedValue );
122 }
123 }
124 }
125 }
126
127 const QString attr = isExpression ? attributeName : u"\"%1\""_s.arg( attributeName );
128
129 if ( allActive && hasDefault )
130 {
131 return QString();
132 }
133 if ( noneActive )
134 {
135 return u"FALSE"_s;
136 }
137 if ( defaultActive )
138 {
139 return u"(%1) NOT IN (%2) OR (%1) IS NULL"_s.arg( attr, inactiveValues );
140 }
141 return u"(%1) IN (%2)"_s.arg( attr, activeValues );
142 }
143};
Helper class to manipulate categories.
static QString buildCategorizedFilter(const QString &attributeName, const QgsFields &fields, const Categories &categories)
Builds a filter expression from categories.
RendererType::Categories Categories
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
QMetaType::Type type
Definition qgsfield.h:63
Container of fields for a vector layer.
Definition qgsfields.h:46
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.