QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 QString QgsRelationReferenceSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
76 {
77  QString fieldName = createFieldIdentifier();
78 
79  //clear any unsupported flags
80  flags &= supportedFlags();
81  if ( flags & IsNull )
82  return fieldName + " IS NULL";
83  if ( flags & IsNotNull )
84  return fieldName + " IS NOT NULL";
85 
86  QVariant v = value();
87  if ( !v.isValid() )
88  return QString();
89 
90  switch ( v.type() )
91  {
92  case QVariant::Int:
93  case QVariant::UInt:
94  case QVariant::Double:
95  case QVariant::LongLong:
96  case QVariant::ULongLong:
97  {
98  if ( flags & EqualTo )
99  return fieldName + '=' + v.toString();
100  else if ( flags & NotEqualTo )
101  return fieldName + "<>" + v.toString();
102  break;
103  }
104 
105  default:
106  {
107  if ( flags & EqualTo )
108  return fieldName + "='" + v.toString() + '\'';
109  else if ( flags & NotEqualTo )
110  return fieldName + "<>'" + v.toString() + '\'';
111  break;
112  }
113  }
114 
115  return QString();
116 }
117 
119 {
120  if ( mWidget )
121  {
122  mWidget->showIndeterminateState();
123  }
124 }
125 
127 {
128  if ( mWidget )
129  {
130  mWidget->setEnabled( enabled );
131  }
132 }
133 
135 {
136  return true;
137 }
138 
140 {
141  onValuesChanged( QVariantList() << value );
142 }
143 
144 void QgsRelationReferenceSearchWidgetWrapper::onValuesChanged( const QVariantList &values )
145 {
146  if ( !values.isEmpty() )
147  {
148  clearExpression();
149  emit valueCleared();
150  }
151  else
152  {
153  QgsSettings settings;
154  // TODO: adapt for composite keys
155  QVariant value = values.at( 0 );
156  setExpression( value.isNull() ? QgsApplication::nullRepresentation() : value.toString() );
157  emit valueChanged();
158  }
160 }
161 
163 {
164  QString exp = expression;
165  QString nullValue = QgsApplication::nullRepresentation();
166  QString fieldName = layer()->fields().at( mFieldIdx ).name();
167 
168  QString str;
169  if ( exp == nullValue )
170  {
171  str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
172  }
173  else
174  {
175  str = QStringLiteral( "%1 = '%3'" )
176  .arg( QgsExpression::quotedColumnRef( fieldName ),
177  exp.replace( '\'', QLatin1String( "''" ) )
178  );
179  }
180  mExpression = str;
181 }
182 
184 {
185  return new QgsRelationReferenceWidget( parent );
186 }
187 
189 {
190  mWidget = qobject_cast<QgsRelationReferenceWidget *>( editor );
191  if ( !mWidget )
192  return;
193 
194  mWidget->setEditorContext( context(), mCanvas, nullptr );
195 
196  mWidget->setEmbedForm( false );
197  mWidget->setReadOnlySelector( false );
198  mWidget->setAllowMapIdentification( config( QStringLiteral( "MapIdentification" ), false ).toBool() );
199  mWidget->setOrderByValue( config( QStringLiteral( "OrderByValue" ), false ).toBool() );
200  mWidget->setAllowAddFeatures( false );
201  mWidget->setOpenFormButtonVisible( false );
202 
203  if ( config( QStringLiteral( "FilterFields" ), QVariant() ).isValid() )
204  {
205  mWidget->setFilterFields( config( QStringLiteral( "FilterFields" ) ).toStringList() );
206  mWidget->setChainFilters( config( QStringLiteral( "ChainFilters" ) ).toBool() );
207  }
208 
209  QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( QStringLiteral( "Relation" ) ).toString() );
210  mWidget->setRelation( relation, false );
211 
212  mWidget->showIndeterminateState();
213  connect( mWidget, &QgsRelationReferenceWidget::foreignKeysChanged, this, &QgsRelationReferenceSearchWidgetWrapper::onValuesChanged );
214 }
215 
216 
QVariant value() const
Returns a variant representing the current state of the widget.
void setEditorContext(const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar)
Shows a search widget on a filter form.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
QVariantList foreignKeys() const
returns the related feature foreign key
QString name
Definition: qgsfield.h:58
QgsRelationReferenceSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QgsMapCanvas *canvas, QWidget *parent=nullptr)
Constructor for QgsRelationReferenceSearchWidgetWrapper.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
void setFilterFields(const QStringList &filterFields)
Sets the fields for which filter comboboxes will be created.
int fieldIndex() const
Returns the field index.
void setOpenFormButtonVisible(bool openFormButtonVisible)
Supports searching for non-null values.
QgsRelation relation() const
Returns the current relation, which might be invalid.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
void clearExpression()
clears the expression to search for all features
QVariantMap config() const
Returns the whole config.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:75
QString expression() const override
Will be used to access the widget&#39;s value.
QString createFieldIdentifier() const
Gets a field name or expression to use as field comparison.
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
void setAllowMapIdentification(bool allowMapIdentification)
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes...
Supports searching for null values.
static QString toString(QgsSearchWidgetWrapper::FilterFlag flag)
Returns a translated string representing a filter flag.
void setOrderByValue(bool orderByValue)
Sets if the widget will order the combobox entries by value.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
void valueChanged()
Emitted when a user changes the value of the search widget.
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QgsRelationManager relationManager
Definition: qgsproject.h:100
void setRelation(const QgsRelation &relation, bool allowNullValue)
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
Q_DECL_DEPRECATED void onValueChanged(const QVariant &value)
Called when current value of search widget changes.
void setAllowAddFeatures(bool allowAddFeatures)
Determines if a button for adding new features should be shown.
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state...
bool valid() const override
Returns true if the widget has been properly initialized.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:442
void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
QgsSearchWidgetWrapper::FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
void foreignKeysChanged(const QVariantList &)
Emitted when the foreign keys changed.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Represents a vector layer which manages a vector based data sets.
void setChainFilters(bool chainFilters)
Set if filters are chained.