1 /***************************************************************************
2 qgsfeaturefiltermodel.cpp - QgsFeatureFilterModel
3 ---------------------
4 begin : 10.3.2017
5 copyright : (C) 2017 by Matthias Kuhn
6 email : matthias@opengis.ch
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"
16 #include "qgsfeatureexpressionvaluesgatherer.h"
17
18 #include "qgsvectorlayer.h"
19 #include "qgsconditionalstyle.h"
20 #include "qgsapplication.h"
21 #include "qgssettings.h"
22
23
qVariantListCompare(const QVariantList & a,const QVariantList & b)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
QgsFeatureFilterModel(QObject * parent)38 QgsFeatureFilterModel::QgsFeatureFilterModel( QObject *parent )
39 : QgsFeaturePickerModelBase( parent )
40 {
41 setFetchGeometry( false );
42 setFetchLimit( QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() );
43 setExtraIdentifierValueUnguarded( nullIdentifier() );
44 }
45
identifierField() const46 QString QgsFeatureFilterModel::identifierField() const
47 {
48 return mIdentifierFields.value( 0 );
49 }
50
requestToReloadCurrentFeature(QgsFeatureRequest & request)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
requestedAttributes() const68 QSet<QString> QgsFeatureFilterModel::requestedAttributes() const
69 {
70 return qgis::listToSet( mIdentifierFields );
71 }
72
entryIdentifier(const QgsFeatureExpressionValuesGatherer::Entry & entry) const73 QVariant QgsFeatureFilterModel::entryIdentifier( const QgsFeatureExpressionValuesGatherer::Entry &entry ) const
74 {
75 return entry.featureId;
76 }
77
createEntry(const QVariant & identifier) const78 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
compareEntries(const QgsFeatureExpressionValuesGatherer::Entry & a,const QgsFeatureExpressionValuesGatherer::Entry & b) const89 bool QgsFeatureFilterModel::compareEntries( const QgsFeatureExpressionValuesGatherer::Entry &a, const QgsFeatureExpressionValuesGatherer::Entry &b ) const
90 {
91 return qVariantListCompare( a.identifierFields, b.identifierFields );
92 }
93
identifierIsNull(const QVariant & identifier) const94 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
nullIdentifier() const107 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
identifierFields() const115 QStringList QgsFeatureFilterModel::identifierFields() const
116 {
117 return mIdentifierFields;
118 }
119
120
setIdentifierFields(const QStringList & identifierFields)121 void QgsFeatureFilterModel::setIdentifierFields( const QStringList &identifierFields )
122 {
123 if ( mIdentifierFields == identifierFields )
124 return;
125
126 mIdentifierFields = identifierFields;
127 emit identifierFieldsChanged();
128 setExtraIdentifierValueToNull();
129 }
130
createValuesGatherer(const QgsFeatureRequest & request) const131 QgsFeatureExpressionValuesGatherer *QgsFeatureFilterModel::createValuesGatherer( const QgsFeatureRequest &request ) const
132 {
133 return new QgsFeatureExpressionValuesGatherer( sourceLayer(), displayExpression(), request, mIdentifierFields );
134 }
135
136
extraIdentifierValues() const137 QVariantList QgsFeatureFilterModel::extraIdentifierValues() const
138 {
139 QVariantList values = mExtraIdentifierValue.toList();
140 if ( values.count() != mIdentifierFields.count() )
141 {
142 return nullIdentifier().toList();
143 }
144 return values;
145 }
146
setExtraIdentifierValues(const QVariantList & extraIdentifierValues)147 void QgsFeatureFilterModel::setExtraIdentifierValues( const QVariantList &extraIdentifierValues )
148 {
149 setExtraIdentifierValue( extraIdentifierValues );
150 }
151
setExtraIdentifierValueToNull()152 void QgsFeatureFilterModel::setExtraIdentifierValueToNull()
153 {
154 setExtraIdentifierValue( nullIdentifier() );
155 }
156
157