QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 "qgsfields.h"
20 #include "qgsvectorlayer.h"
21 #include "qgsproject.h"
23 #include "qgsrelationmanager.h"
24 #include "qgssettings.h"
25 #include "qgsapplication.h"
26 
27 #include <QStringListModel>
28 
30  : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
31  , mCanvas( canvas )
32 {
33 
34 }
35 
37 {
38  return true;
39 }
40 
42 {
43  return mExpression;
44 }
45 
47 {
48  if ( !mWidget )
49  return QVariant( );
50 
51  const QVariantList fkeys = mWidget->foreignKeys();
52 
53  if ( fkeys.isEmpty() )
54  {
55  return QVariant( );
56  }
57  else
58  {
59  const QList<QgsRelation::FieldPair> fieldPairs = mWidget->relation().fieldPairs();
60  Q_ASSERT( fieldPairs.count() == fkeys.count() );
61  for ( int i = 0; i < fieldPairs.count(); i++ )
62  {
63  if ( fieldPairs.at( i ).referencingField() == layer()->fields().at( fieldIndex() ).name() )
64  return fkeys.at( i );
65  }
66  return QVariant(); // should not happen
67  }
68 }
69 
70 QgsSearchWidgetWrapper::FilterFlags QgsRelationReferenceSearchWidgetWrapper::supportedFlags() const
71 {
72  return EqualTo | NotEqualTo | IsNull | IsNotNull;
73 }
74 
75 QgsSearchWidgetWrapper::FilterFlags QgsRelationReferenceSearchWidgetWrapper::defaultFlags() const
76 {
77  return EqualTo;
78 }
79 
80 QString QgsRelationReferenceSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
81 {
82  QString fieldName = createFieldIdentifier();
83 
84  //clear any unsupported flags
85  flags &= supportedFlags();
86  if ( flags & IsNull )
87  return fieldName + " IS NULL";
88  if ( flags & IsNotNull )
89  return fieldName + " IS NOT NULL";
90 
91  QVariant v = value();
92  if ( !v.isValid() )
93  return QString();
94 
95  switch ( v.type() )
96  {
97  case QVariant::Int:
98  case QVariant::UInt:
99  case QVariant::Double:
100  case QVariant::LongLong:
101  case QVariant::ULongLong:
102  {
103  if ( flags & EqualTo )
104  {
105  if ( v.isNull() )
106  return fieldName + " IS NULL";
107  return fieldName + '=' + v.toString();
108  }
109  else if ( flags & NotEqualTo )
110  {
111  if ( v.isNull() )
112  return fieldName + " IS NOT NULL";
113  return fieldName + "<>" + v.toString();
114  }
115  break;
116  }
117 
118  default:
119  {
120  if ( flags & EqualTo )
121  return fieldName + "='" + v.toString() + '\'';
122  else if ( flags & NotEqualTo )
123  return fieldName + "<>'" + v.toString() + '\'';
124  break;
125  }
126  }
127 
128  return QString();
129 }
130 
132 {
133  if ( mWidget )
134  {
135  mWidget->showIndeterminateState();
136  }
137 }
138 
140 {
141  if ( mWidget )
142  {
143  mWidget->setEnabled( enabled );
144  }
145 }
146 
148 {
149  return true;
150 }
151 
153 {
154  onValuesChanged( QVariantList() << value );
155 }
156 
157 void QgsRelationReferenceSearchWidgetWrapper::onValuesChanged( const QVariantList &values )
158 {
159  if ( values.isEmpty() )
160  {
161  clearExpression();
162  emit valueCleared();
163  }
164  else
165  {
166  QgsSettings settings;
167  // TODO: adapt for composite keys
168  QVariant value = values.at( 0 );
169  setExpression( value.isNull() ? QgsApplication::nullRepresentation() : value.toString() );
170  emit valueChanged();
171  }
173 }
174 
176 {
177  QString exp = expression;
178  QString nullValue = QgsApplication::nullRepresentation();
179  QString fieldName = layer()->fields().at( mFieldIdx ).name();
180 
181  QString str;
182  if ( exp == nullValue )
183  {
184  str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
185  }
186  else
187  {
188  str = QStringLiteral( "%1 = '%3'" )
189  .arg( QgsExpression::quotedColumnRef( fieldName ),
190  exp.replace( '\'', QLatin1String( "''" ) )
191  );
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( QStringLiteral( "MapIdentification" ), false ).toBool() );
212  mWidget->setOrderByValue( config( QStringLiteral( "OrderByValue" ), false ).toBool() );
213  mWidget->setAllowAddFeatures( false );
214  mWidget->setOpenFormButtonVisible( false );
215 
216  if ( config( QStringLiteral( "FilterFields" ), QVariant() ).isValid() )
217  {
218  mWidget->setFilterFields( config( QStringLiteral( "FilterFields" ) ).toStringList() );
219  mWidget->setChainFilters( config( QStringLiteral( "ChainFilters" ) ).toBool() );
220  mWidget->setFilterExpression( config( QStringLiteral( "FilterExpression" ) ).toString() );
221  }
222 
223  QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( QStringLiteral( "Relation" ) ).toString() );
224  // if no relation is given from the config, fetch one if there is only one available
225  if ( !relation.isValid() && !layer()->referencingRelations( mFieldIdx ).isEmpty() && layer()->referencingRelations( mFieldIdx ).count() == 1 )
226  relation = layer()->referencingRelations( mFieldIdx )[0];
227  mWidget->setRelation( relation, config( QStringLiteral( "AllowNULL" ) ).toBool() );
228 
229  mWidget->showIndeterminateState();
230  connect( mWidget, &QgsRelationReferenceWidget::foreignKeysChanged, this, &QgsRelationReferenceSearchWidgetWrapper::onValuesChanged );
231 }
232 
233 
QgsRelationReferenceWidget
Definition: qgsrelationreferencewidget.h:58
QgsProject::relationManager
QgsRelationManager * relationManager
Definition: qgsproject.h:105
qgsfields.h
QgsSearchWidgetWrapper::expressionChanged
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QgsSearchWidgetWrapper::valueChanged
void valueChanged()
Emitted when a user changes the value of the search widget.
QgsRelationReferenceWidget::setFilterFields
void setFilterFields(const QStringList &filterFields)
Sets the fields for which filter comboboxes will be created.
Definition: qgsrelationreferencewidget.cpp:476
QgsSearchWidgetWrapper::NotEqualTo
@ NotEqualTo
Supports not equal to.
Definition: qgssearchwidgetwrapper.h:97
QgsRelationReferenceSearchWidgetWrapper::supportedFlags
QgsSearchWidgetWrapper::FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:70
QgsRelationReferenceSearchWidgetWrapper::valid
bool valid() const override
Returns true if the widget has been properly initialized.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:147
QgsRelationReferenceWidget::showIndeterminateState
void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
Definition: qgsrelationreferencewidget.cpp:392
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:85
QgsSearchWidgetWrapper
Shows a search widget on a filter form.
Definition: qgssearchwidgetwrapper.h:86
QgsRelationReferenceSearchWidgetWrapper::createExpression
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:80
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsRelationManager::relation
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Definition: qgsrelationmanager.cpp:96
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsRelationReferenceSearchWidgetWrapper::setExpression
void setExpression(const QString &exp) override
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:175
QgsRelationReferenceSearchWidgetWrapper::setEnabled
void setEnabled(bool enabled) override
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:139
QgsWidgetWrapper::context
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
Definition: qgswidgetwrapper.cpp:86
QgsField::name
QString name
Definition: qgsfield.h:59
QgsSearchWidgetWrapper::valueCleared
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state.
qgsapplication.h
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
QgsRelationReferenceWidget::setAllowMapIdentification
void setAllowMapIdentification(bool allowMapIdentification)
Definition: qgsrelationreferencewidget.cpp:464
QgsRelationReferenceWidget::setAllowAddFeatures
void setAllowAddFeatures(bool allowAddFeatures)
Determines if a button for adding new features should be shown.
Definition: qgsrelationreferencewidget.cpp:751
QgsRelationReferenceSearchWidgetWrapper::expression
QString expression() const override
Will be used to access the widget's value.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:41
QgsWidgetWrapper::layer
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Definition: qgswidgetwrapper.cpp:91
QgsSearchWidgetWrapper::mFieldIdx
int mFieldIdx
Definition: qgssearchwidgetwrapper.h:266
QgsApplication::nullRepresentation
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
Definition: qgsapplication.cpp:1851
QgsRelationReferenceWidget::setEditorContext
void setEditorContext(const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar)
Sets the editor context.
Definition: qgsrelationreferencewidget.cpp:427
QgsRelationReferenceWidget::foreignKeysChanged
void foreignKeysChanged(const QVariantList &)
Emitted when the foreign keys changed.
QgsRelationReferenceWidget::setEmbedForm
void setEmbedForm(bool display)
Definition: qgsrelationreferencewidget.cpp:444
QgsRelationReferenceSearchWidgetWrapper::value
QVariant value() const
Returns a variant representing the current state of the widget.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:46
QgsRelationReferenceSearchWidgetWrapper::applyDirectly
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:36
QgsVectorLayer::referencingRelations
QList< QgsRelation > referencingRelations(int idx) const
Returns the layer's relations, where the foreign key is on this layer.
Definition: qgsvectorlayer.cpp:5177
QgsRelationReferenceSearchWidgetWrapper::defaultFlags
QgsSearchWidgetWrapper::FilterFlags defaultFlags() const override
Returns the default flags (equalTo)
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:75
QgsRelationReferenceSearchWidgetWrapper::createWidget
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:196
QgsSearchWidgetWrapper::mExpression
QString mExpression
Definition: qgssearchwidgetwrapper.h:265
qgsrelationmanager.h
QgsSearchWidgetWrapper::IsNull
@ IsNull
Supports searching for null values.
Definition: qgssearchwidgetwrapper.h:106
qgsvectorlayer.h
QgsRelationReferenceSearchWidgetWrapper::onValueChanged
Q_DECL_DEPRECATED void onValueChanged(const QVariant &value)
Called when current value of search widget changes.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:152
QgsRelation::fieldPairs
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
Definition: qgsrelation.cpp:292
QgsRelationReferenceWidget::relation
QgsRelation relation() const
Returns the current relation, which might be invalid.
Definition: qgsrelationreferencewidget.cpp:757
QgsSearchWidgetWrapper::fieldIndex
int fieldIndex() const
Returns the field index.
Definition: qgssearchwidgetwrapper.cpp:133
QgsWidgetWrapper::config
QVariantMap config() const
Returns the whole config.
Definition: qgswidgetwrapper.cpp:81
QgsRelationReferenceWidget::foreignKeys
QVariantList foreignKeys() const
returns the related feature foreign key
Definition: qgsrelationreferencewidget.cpp:415
QgsRelationReferenceWidget::setRelation
void setRelation(const QgsRelation &relation, bool allowNullValue)
Definition: qgsrelationreferencewidget.cpp:176
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsRelationReferenceWidget::setChainFilters
void setChainFilters(bool chainFilters)
Set if filters are chained.
Definition: qgsrelationreferencewidget.cpp:487
QgsRelation::isValid
bool isValid
Definition: qgsrelation.h:49
qgssettings.h
QgsRelationReferenceWidget::setOrderByValue
void setOrderByValue(bool orderByValue)
Sets if the widget will order the combobox entries by value.
Definition: qgsrelationreferencewidget.cpp:471
QgsExpression::quotedColumnRef
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Definition: qgsexpression.cpp:65
qgsvaluerelationwidgetfactory.h
QgsRelation
Definition: qgsrelation.h:42
QgsRelationReferenceWidget::setOpenFormButtonVisible
void setOpenFormButtonVisible(bool openFormButtonVisible)
Definition: qgsrelationreferencewidget.cpp:481
QgsSearchWidgetWrapper::createFieldIdentifier
QString createFieldIdentifier() const
Gets a field name or expression to use as field comparison.
Definition: qgssearchwidgetwrapper.cpp:104
QgsSearchWidgetWrapper::EqualTo
@ EqualTo
Supports equal to.
Definition: qgssearchwidgetwrapper.h:96
qgsrelationreferencewidget.h
QgsRelationReferenceWidget::setFilterExpression
void setFilterExpression(const QString &filterExpression)
If not empty, will be used as filter expression.
Definition: qgsrelationreferencewidget.cpp:492
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsSearchWidgetWrapper::clearExpression
void clearExpression()
clears the expression to search for all features
Definition: qgssearchwidgetwrapper.cpp:118
QgsSearchWidgetWrapper::toString
static QString toString(QgsSearchWidgetWrapper::FilterFlag flag)
Returns a translated string representing a filter flag.
Definition: qgssearchwidgetwrapper.cpp:49
QgsSearchWidgetWrapper::IsNotNull
@ IsNotNull
Supports searching for non-null values.
Definition: qgssearchwidgetwrapper.h:108
QgsRelationReferenceWidget::setReadOnlySelector
void setReadOnlySelector(bool readOnly)
Definition: qgsrelationreferencewidget.cpp:456
QgsRelationReferenceSearchWidgetWrapper::clearWidget
void clearWidget() override
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:131
QgsRelationReferenceSearchWidgetWrapper::QgsRelationReferenceSearchWidgetWrapper
QgsRelationReferenceSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QgsMapCanvas *canvas, QWidget *parent=nullptr)
Constructor for QgsRelationReferenceSearchWidgetWrapper.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:29
QgsRelationReferenceSearchWidgetWrapper::initWidget
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
Definition: qgsrelationreferencesearchwidgetwrapper.cpp:201
qgsproject.h
qgsrelationreferencesearchwidgetwrapper.h