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