QGIS API Documentation 3.99.0-Master (d270888f95f)
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 <QString>
28#include <QStringListModel>
29
30#include "moc_qgsrelationreferencesearchwidgetwrapper.cpp"
31
32using namespace Qt::StringLiterals;
33
35 : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
36 , mCanvas( canvas )
37{
38}
39
44
49
51{
52 if ( !mWidget )
53 return QVariant();
54
55 const QVariantList fkeys = mWidget->foreignKeys();
56
57 if ( fkeys.isEmpty() )
58 {
59 return QVariant();
60 }
61 else
62 {
63 const QList<QgsRelation::FieldPair> fieldPairs = mWidget->relation().fieldPairs();
64 Q_ASSERT( fieldPairs.count() == fkeys.count() );
65 for ( int i = 0; i < fieldPairs.count(); i++ )
66 {
67 if ( fieldPairs.at( i ).referencingField() == layer()->fields().at( fieldIndex() ).name() )
68 return fkeys.at( i );
69 }
70 return QVariant(); // should not happen
71 }
72}
73
78
83
85{
86 const QString fieldName = createFieldIdentifier();
87
88 //clear any unsupported flags
89 flags &= supportedFlags();
90 if ( flags & IsNull )
91 return fieldName + " IS NULL";
92 if ( flags & IsNotNull )
93 return fieldName + " IS NOT NULL";
94
95 const QVariant v = value();
96 if ( !v.isValid() )
97 return QString();
98
99 switch ( v.userType() )
100 {
101 case QMetaType::Type::Int:
102 case QMetaType::Type::UInt:
103 case QMetaType::Type::Double:
104 case QMetaType::Type::LongLong:
105 case QMetaType::Type::ULongLong:
106 {
107 if ( flags & EqualTo )
108 {
109 if ( QgsVariantUtils::isNull( v ) )
110 return fieldName + " IS NULL";
111 return fieldName + '=' + v.toString();
112 }
113 else if ( flags & NotEqualTo )
114 {
115 if ( QgsVariantUtils::isNull( v ) )
116 return fieldName + " IS NOT NULL";
117 return fieldName + "<>" + v.toString();
118 }
119 break;
120 }
121
122 default:
123 {
124 if ( flags & EqualTo )
125 return fieldName + "='" + v.toString() + '\'';
126 else if ( flags & NotEqualTo )
127 return fieldName + "<>'" + v.toString() + '\'';
128 break;
129 }
130 }
131
132 return QString();
133}
134
136{
137 if ( mWidget )
138 {
139 mWidget->showIndeterminateState();
140 }
141}
142
144{
145 if ( mWidget )
146 {
147 mWidget->setEnabled( enabled );
148 }
149}
150
152{
153 return true;
154}
155
157{
158 onValuesChanged( QVariantList() << value );
159}
160
161void QgsRelationReferenceSearchWidgetWrapper::onValuesChanged( const QVariantList &values )
162{
163 if ( values.isEmpty() )
164 {
166 emit valueCleared();
167 }
168 else
169 {
170 const QgsSettings settings;
171 // TODO: adapt for composite keys
172 const QVariant value = values.at( 0 );
174 emit valueChanged();
175 }
177}
178
180{
181 QString exp = expression;
182 const QString nullValue = QgsApplication::nullRepresentation();
183 const QString fieldName = layer()->fields().at( mFieldIdx ).name();
184
185 QString str;
186 if ( exp == nullValue )
187 {
188 str = u"%1 IS NULL"_s.arg( QgsExpression::quotedColumnRef( fieldName ) );
189 }
190 else
191 {
192 str = u"%1 = '%3'"_s
193 .arg( QgsExpression::quotedColumnRef( fieldName ), exp.replace( '\'', "''"_L1 ) );
194 }
195 mExpression = str;
196}
197
199{
200 return new QgsRelationReferenceWidget( parent );
201}
202
204{
205 mWidget = qobject_cast<QgsRelationReferenceWidget *>( editor );
206 if ( !mWidget )
207 return;
208
209 mWidget->setEditorContext( context(), mCanvas, nullptr );
210
211 mWidget->setEmbedForm( false );
212 mWidget->setReadOnlySelector( false );
213 mWidget->setAllowMapIdentification( config( u"MapIdentification"_s, false ).toBool() );
214 mWidget->setAllowAddFeatures( false );
215 mWidget->setOpenFormButtonVisible( false );
216
217 const bool fetchLimitActive = config( u"FetchLimitActive"_s, QgsSettings().value( u"maxEntriesRelationWidget"_s, 100, QgsSettings::Gui ).toInt() > 0 ).toBool();
218 if ( fetchLimitActive )
219 {
220 mWidget->setFetchLimit( config( u"FetchLimitNumber"_s, QgsSettings().value( u"maxEntriesRelationWidget"_s, 100, QgsSettings::Gui ) ).toInt() );
221 }
222
223 if ( config( u"FilterFields"_s, QVariant() ).isValid() )
224 {
225 mWidget->setFilterFields( config( u"FilterFields"_s ).toStringList() );
226 mWidget->setChainFilters( config( u"ChainFilters"_s ).toBool() );
227 mWidget->setFilterExpression( config( u"FilterExpression"_s ).toString() );
228 }
229 mWidget->setOrderExpression( config( u"OrderExpression"_s ).toString() );
230 mWidget->setSortOrder( config( u"OrderDescending"_s, false ).toBool() ? Qt::DescendingOrder : Qt::AscendingOrder );
231
232 QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( u"Relation"_s ).toString() );
233 // if no relation is given from the config, fetch one if there is only one available
234 if ( !relation.isValid() && !layer()->referencingRelations( mFieldIdx ).isEmpty() && layer()->referencingRelations( mFieldIdx ).count() == 1 )
235 relation = layer()->referencingRelations( mFieldIdx )[0];
236 mWidget->setRelation( relation, config( u"AllowNULL"_s ).toBool() );
237
238 mWidget->showIndeterminateState();
239 connect( mWidget, &QgsRelationReferenceWidget::foreignKeysChanged, this, &QgsRelationReferenceSearchWidgetWrapper::onValuesChanged );
240}
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:65
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:123
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:68
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.