QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgsfeaturefiltermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeaturefiltermodel.cpp - QgsFeatureFilterModel
3  ---------------------
4  begin : 10.3.2017
5  copyright : (C) 2017 by Matthias Kuhn
6  email : [email protected]
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 #include "qgsfeaturefiltermodel.h"
17 
18 #include "qgsvectorlayer.h"
19 #include "qgsconditionalstyle.h"
20 #include "qgsapplication.h"
21 #include "qgssettings.h"
22 
23 
24 bool qVariantListCompare( const QVariantList &a, const QVariantList &b )
25 {
26  if ( a.size() != b.size() )
27  return false;
28 
29  for ( int i = 0; i < a.size(); ++i )
30  {
31  if ( !qgsVariantEqual( a.at( i ), b.at( i ) ) )
32  return false;
33  }
34  return true;
35 }
36 
37 
39  : QgsFeaturePickerModelBase( parent )
40 {
41  setFetchGeometry( false );
42  setFetchLimit( QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() );
43  setExtraIdentifierValueUnguarded( nullIdentifier() );
44 }
45 
47 {
48  return mIdentifierFields.value( 0 );
49 }
50 
51 void QgsFeatureFilterModel::requestToReloadCurrentFeature( QgsFeatureRequest &request )
52 {
53  QStringList conditions;
54  for ( int i = 0; i < mIdentifierFields.count(); i++ )
55  {
56  if ( i >= mExtraIdentifierValue.toList().count() )
57  {
58  conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), QVariant() );
59  }
60  else
61  {
62  conditions << QgsExpression::createFieldEqualityExpression( mIdentifierFields.at( i ), mExtraIdentifierValue.toList().at( i ) );
63  }
64  }
65  request.setFilterExpression( conditions.join( QLatin1String( " AND " ) ) );
66 }
67 
68 QSet<QString> QgsFeatureFilterModel::requestedAttributes() const
69 {
70  return qgis::listToSet( mIdentifierFields );
71 }
72 
73 QVariant QgsFeatureFilterModel::entryIdentifier( const QgsFeatureExpressionValuesGatherer::Entry &entry ) const
74 {
75  return entry.featureId;
76 }
77 
78 QgsFeatureExpressionValuesGatherer::Entry QgsFeatureFilterModel::createEntry( const QVariant &identifier ) const
79 {
80  const QVariantList constValues = identifier.toList();
81 
82  QStringList values;
83  for ( const QVariant &v : constValues )
84  values << QStringLiteral( "(%1)" ).arg( v.toString() );
85 
86  return QgsFeatureExpressionValuesGatherer::Entry( constValues, values.join( QLatin1Char( ' ' ) ), QgsFeature( sourceLayer() ? sourceLayer()->fields() : QgsFields() ) );
87 }
88 
89 bool QgsFeatureFilterModel::compareEntries( const QgsFeatureExpressionValuesGatherer::Entry &a, const QgsFeatureExpressionValuesGatherer::Entry &b ) const
90 {
91  return qVariantListCompare( a.identifierFields, b.identifierFields );
92 }
93 
94 bool QgsFeatureFilterModel::identifierIsNull( const QVariant &identifier ) const
95 {
96  const QVariantList values = identifier.toList();
97  for ( const QVariant &value : values )
98  {
99  if ( !value.isNull() )
100  {
101  return false;
102  }
103  }
104  return true;
105 }
106 
107 QVariant QgsFeatureFilterModel::nullIdentifier() const
108 {
109  QVariantList nullValues;
110  for ( int i = 0; i < mIdentifierFields.count(); i++ )
111  nullValues << QVariant( QVariant::Int );
112  return nullValues;
113 }
114 
116 {
117  return mIdentifierFields;
118 }
119 
120 
121 void QgsFeatureFilterModel::setIdentifierFields( const QStringList &identifierFields )
122 {
123  if ( mIdentifierFields == identifierFields )
124  return;
125 
126  mIdentifierFields = identifierFields;
129 }
130 
131 QgsFeatureExpressionValuesGatherer *QgsFeatureFilterModel::createValuesGatherer( const QgsFeatureRequest &request ) const
132 {
133  return new QgsFeatureExpressionValuesGatherer( sourceLayer(), displayExpression(), request, mIdentifierFields );
134 }
135 
136 
138 {
139  QVariantList values = mExtraIdentifierValue.toList();
140  if ( values.count() != mIdentifierFields.count() )
141  {
142  return nullIdentifier().toList();
143  }
144  return values;
145 }
146 
147 void QgsFeatureFilterModel::setExtraIdentifierValues( const QVariantList &extraIdentifierValues )
148 {
150 }
151 
153 {
154  setExtraIdentifierValue( nullIdentifier() );
155 }
156 
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
void setExtraIdentifierValues(const QVariantList &extraIdentifierValues)
Allows specifying one value that does not need to match the filter criteria but will still be availab...
void setExtraIdentifierValueToNull() override
Allows specifying one value that does not need to match the filter criteria but will still be availab...
Q_DECL_DEPRECATED QString identifierField() const
The identifier field should be a unique field that can be used to identify individual features.
QgsFeatureFilterModel(QObject *parent=nullptr)
Create a new QgsFeatureFilterModel, optionally specifying a parent.
QStringList identifierFields
A set of fields of sourceLayer that is unique and should be used to identify features.
QVariantList extraIdentifierValues
The values that identifies the current feature.
void identifierFieldsChanged()
The identifier field should be a unique field that can be used to identify individual features.
void setIdentifierFields(const QStringList &identifierFields)
The identifier field should be a unique field that can be used to identify individual features.
Provides a list of features based on filter conditions.
void setExtraIdentifierValue(const QVariant &extraIdentifierValue)
Allows specifying one value that does not need to match the filter criteria but will still be availab...
void setFetchLimit(int fetchLimit)
Defines the feature request fetch limit If set to 0, no limit is applied when fetching.
void setFetchGeometry(bool fetchGeometry)
Defines if the geometry will be fetched.
void setExtraIdentifierValueUnguarded(const QVariant &identifierValue)
This will set the identifier value to be set in the model even if it doesn't exist currently in the d...
QVariant mExtraIdentifierValue
The current identifier value.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool qgsVariantEqual(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether they are equal, two NULL values are always treated a...
Definition: qgis.cpp:274
bool qVariantListCompare(const QVariantList &a, const QVariantList &b)