QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsrelationreferencesearchwidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrelationreferencesearchwidgetwrapper.cpp
3 ------------------------------------------
4 Date : 2016-05-25
5 Copyright : (C) 2016 Nyall Dawson
6 Email : nyall dot dawson at gmail 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
17
18#include "qgsapplication.h"
19#include "qgsfields.h"
20#include "qgsproject.h"
21#include "qgsrelationmanager.h"
23#include "qgssettings.h"
25#include "qgsvectorlayer.h"
26
27#include <QStringListModel>
28
29#include "moc_qgsrelationreferencesearchwidgetwrapper.cpp"
30
32 : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
33 , mCanvas( canvas )
34{
35}
36
41
46
48{
49 if ( !mWidget )
50 return QVariant();
51
52 const QVariantList fkeys = mWidget->foreignKeys();
53
54 if ( fkeys.isEmpty() )
55 {
56 return QVariant();
57 }
58 else
59 {
60 const QList<QgsRelation::FieldPair> fieldPairs = mWidget->relation().fieldPairs();
61 Q_ASSERT( fieldPairs.count() == fkeys.count() );
62 for ( int i = 0; i < fieldPairs.count(); i++ )
63 {
64 if ( fieldPairs.at( i ).referencingField() == layer()->fields().at( fieldIndex() ).name() )
65 return fkeys.at( i );
66 }
67 return QVariant(); // should not happen
68 }
69}
70
75
80
82{
83 const QString fieldName = createFieldIdentifier();
84
85 //clear any unsupported flags
86 flags &= supportedFlags();
87 if ( flags & IsNull )
88 return fieldName + " IS NULL";
89 if ( flags & IsNotNull )
90 return fieldName + " IS NOT NULL";
91
92 const QVariant v = value();
93 if ( !v.isValid() )
94 return QString();
95
96 switch ( v.userType() )
97 {
98 case QMetaType::Type::Int:
99 case QMetaType::Type::UInt:
100 case QMetaType::Type::Double:
101 case QMetaType::Type::LongLong:
102 case QMetaType::Type::ULongLong:
103 {
104 if ( flags & EqualTo )
105 {
106 if ( QgsVariantUtils::isNull( v ) )
107 return fieldName + " IS NULL";
108 return fieldName + '=' + v.toString();
109 }
110 else if ( flags & NotEqualTo )
111 {
112 if ( QgsVariantUtils::isNull( v ) )
113 return fieldName + " IS NOT NULL";
114 return fieldName + "<>" + v.toString();
115 }
116 break;
117 }
118
119 default:
120 {
121 if ( flags & EqualTo )
122 return fieldName + "='" + v.toString() + '\'';
123 else if ( flags & NotEqualTo )
124 return fieldName + "<>'" + v.toString() + '\'';
125 break;
126 }
127 }
128
129 return QString();
130}
131
133{
134 if ( mWidget )
135 {
136 mWidget->showIndeterminateState();
137 }
138}
139
141{
142 if ( mWidget )
143 {
144 mWidget->setEnabled( enabled );
145 }
146}
147
149{
150 return true;
151}
152
154{
155 onValuesChanged( QVariantList() << value );
156}
157
158void QgsRelationReferenceSearchWidgetWrapper::onValuesChanged( const QVariantList &values )
159{
160 if ( values.isEmpty() )
161 {
163 emit valueCleared();
164 }
165 else
166 {
167 const QgsSettings settings;
168 // TODO: adapt for composite keys
169 const QVariant value = values.at( 0 );
171 emit valueChanged();
172 }
174}
175
177{
178 QString exp = expression;
179 const QString nullValue = QgsApplication::nullRepresentation();
180 const QString fieldName = layer()->fields().at( mFieldIdx ).name();
181
182 QString str;
183 if ( exp == nullValue )
184 {
185 str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
186 }
187 else
188 {
189 str = QStringLiteral( "%1 = '%3'" )
190 .arg( QgsExpression::quotedColumnRef( fieldName ), exp.replace( '\'', QLatin1String( "''" ) ) );
191 }
192 mExpression = str;
193}
194
196{
197 return new QgsRelationReferenceWidget( parent );
198}
199
201{
202 mWidget = qobject_cast<QgsRelationReferenceWidget *>( editor );
203 if ( !mWidget )
204 return;
205
206 mWidget->setEditorContext( context(), mCanvas, nullptr );
207
208 mWidget->setEmbedForm( false );
209 mWidget->setReadOnlySelector( false );
210 mWidget->setAllowMapIdentification( config( QStringLiteral( "MapIdentification" ), false ).toBool() );
211 mWidget->setAllowAddFeatures( false );
212 mWidget->setOpenFormButtonVisible( false );
213
214 const bool fetchLimitActive = config( QStringLiteral( "FetchLimitActive" ), QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() > 0 ).toBool();
215 if ( fetchLimitActive )
216 {
217 mWidget->setFetchLimit( config( QStringLiteral( "FetchLimitNumber" ), QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ) ).toInt() );
218 }
219
220 if ( config( QStringLiteral( "FilterFields" ), QVariant() ).isValid() )
221 {
222 mWidget->setFilterFields( config( QStringLiteral( "FilterFields" ) ).toStringList() );
223 mWidget->setChainFilters( config( QStringLiteral( "ChainFilters" ) ).toBool() );
224 mWidget->setFilterExpression( config( QStringLiteral( "FilterExpression" ) ).toString() );
225 }
226 mWidget->setOrderExpression( config( QStringLiteral( "OrderExpression" ) ).toString() );
227 mWidget->setSortOrder( config( QStringLiteral( "OrderDescending" ), false ).toBool() ? Qt::DescendingOrder : Qt::AscendingOrder );
228
229 QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( QStringLiteral( "Relation" ) ).toString() );
230 // if no relation is given from the config, fetch one if there is only one available
231 if ( !relation.isValid() && !layer()->referencingRelations( mFieldIdx ).isEmpty() && layer()->referencingRelations( mFieldIdx ).count() == 1 )
232 relation = layer()->referencingRelations( mFieldIdx )[0];
233 mWidget->setRelation( relation, config( QStringLiteral( "AllowNULL" ) ).toBool() );
234
235 mWidget->showIndeterminateState();
236 connect( mWidget, &QgsRelationReferenceWidget::foreignKeysChanged, this, &QgsRelationReferenceSearchWidgetWrapper::onValuesChanged );
237}
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
QString name
Definition qgsfield.h:63
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Map canvas is a class for displaying all GIS data types on a canvas.
QgsRelationManager * relationManager
Definition qgsproject.h:120
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Q_DECL_DEPRECATED void onValueChanged(const QVariant &value)
Called when current value of search widget changes.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QString expression() const override
Will be used to access the widget's value.
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes.
QgsRelationReferenceSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QgsMapCanvas *canvas, QWidget *parent=nullptr)
Constructor for QgsRelationReferenceSearchWidgetWrapper.
QgsSearchWidgetWrapper::FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
QVariant value() const
Returns a variant representing the current state of the widget.
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
Creates a filter expression based on the current state of the search widget and the specified filter ...
QgsSearchWidgetWrapper::FilterFlags defaultFlags() const override
Returns the default flags (equalTo).
bool valid() const override
Returns true if the widget has been properly initialized.
A widget which shows related features.
void foreignKeysChanged(const QVariantList &keys)
Emitted when the foreign keys changed.
Represents a relationship between two vector layers.
Definition qgsrelation.h:42
@ IsNull
Supports searching for null values.
@ IsNotNull
Supports searching for non-null values.
@ NotEqualTo
Supports not equal to.
int fieldIndex() const
Returns the field index.
void valueChanged()
Emitted when a user changes the value of the search widget.
QgsSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
Create a new widget wrapper.
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state.
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QString createFieldIdentifier() const
Gets a field name or expression to use as field comparison.
void clearExpression()
clears the expression to search for all features
QFlags< FilterFlag > FilterFlags
static QString toString(QgsSearchWidgetWrapper::FilterFlag flag)
Returns a translated string representing a filter flag.
Stores settings for use within QGIS.
Definition qgssettings.h:65
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based dataset.
QList< QgsRelation > referencingRelations(int idx) const
Returns the layer's relations, where the foreign key is on this layer.
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
QVariantMap config() const
Returns the whole config.