QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsvaluerelationwidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvaluerelationwidgetwrapper.cpp
3  --------------------------------------
4  Date : 5.1.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
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 "qgis.h"
19 #include "qgsfields.h"
20 #include "qgsproject.h"
22 #include "qgsvectorlayer.h"
23 #include "qgsfilterlineedit.h"
24 #include "qgsfeatureiterator.h"
26 #include "qgsattributeform.h"
27 #include "qgsattributes.h"
28 #include "qgsjsonutils.h"
29 #include "qgspostgresstringutils.h"
30 
31 #include <QHeaderView>
32 #include <QComboBox>
33 #include <QLineEdit>
34 #include <QTableWidget>
35 #include <QStringListModel>
36 #include <QCompleter>
37 
38 #include <nlohmann/json.hpp>
39 using namespace nlohmann;
40 
41 
42 QgsValueRelationWidgetWrapper::QgsValueRelationWidgetWrapper( QgsVectorLayer *layer, int fieldIdx, QWidget *editor, QWidget *parent )
43  : QgsEditorWidgetWrapper( layer, fieldIdx, editor, parent )
44 {
45 }
46 
47 
49 {
50  QVariant v;
51 
52  if ( mComboBox )
53  {
54  int cbxIdx = mComboBox->currentIndex();
55  if ( cbxIdx > -1 )
56  {
57  v = mComboBox->currentData();
58  }
59  }
60 
61  const int nofColumns = columnCount();
62 
63  if ( mTableWidget )
64  {
65  QStringList selection;
66  for ( int j = 0; j < mTableWidget->rowCount(); j++ )
67  {
68  for ( int i = 0; i < nofColumns; ++i )
69  {
70  QTableWidgetItem *item = mTableWidget->item( j, i );
71  if ( item )
72  {
73  if ( item->checkState() == Qt::Checked )
74  selection << item->data( Qt::UserRole ).toString();
75  }
76  }
77  }
78 
79  QVariantList vl;
80  //store as QVariantList because the field type supports data structure
81  for ( const QString &s : qgis::as_const( selection ) )
82  {
83  // Convert to proper type
84  const QVariant::Type type { fkType() };
85  switch ( type )
86  {
87  case QVariant::Type::Int:
88  vl.push_back( s.toInt() );
89  break;
90  case QVariant::Type::LongLong:
91  vl.push_back( s.toLongLong() );
92  break;
93  default:
94  vl.push_back( s );
95  break;
96  }
97  }
98 
99  if ( layer()->fields().at( fieldIdx() ).type() == QVariant::Map ||
100  layer()->fields().at( fieldIdx() ).type() == QVariant::List )
101  {
102  v = vl;
103  }
104  else
105  {
106  //make string
108  }
109  }
110 
111  if ( mLineEdit )
112  {
113  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( mCache ) )
114  {
115  if ( item.value == mLineEdit->text() )
116  {
117  v = item.key;
118  break;
119  }
120  }
121  }
122 
123  return v;
124 }
125 
127 {
128  QgsAttributeForm *form = qobject_cast<QgsAttributeForm *>( parent );
129  if ( form )
131 
132  mExpression = config().value( QStringLiteral( "FilterExpression" ) ).toString();
133 
134  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
135  {
136  return new QTableWidget( parent );
137  }
138  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
139  {
140  return new QgsFilterLineEdit( parent );
141  }
142  {
143  return new QComboBox( parent );
144  }
145 }
146 
148 {
149 
150  mComboBox = qobject_cast<QComboBox *>( editor );
151  mTableWidget = qobject_cast<QTableWidget *>( editor );
152  mLineEdit = qobject_cast<QLineEdit *>( editor );
153 
154  // Read current initial form values from the editor context
156 
157  if ( mComboBox )
158  {
159  connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
160  this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::emitValueChanged ), Qt::UniqueConnection );
161  }
162  else if ( mTableWidget )
163  {
164  mTableWidget->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
165  mTableWidget->horizontalHeader()->setVisible( false );
166  mTableWidget->verticalHeader()->setSectionResizeMode( QHeaderView::Stretch );
167  mTableWidget->verticalHeader()->setVisible( false );
168  mTableWidget->setShowGrid( false );
169  mTableWidget->setEditTriggers( QAbstractItemView::NoEditTriggers );
170  mTableWidget->setSelectionMode( QAbstractItemView::NoSelection );
171  connect( mTableWidget, &QTableWidget::itemChanged, this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::emitValueChanged ), Qt::UniqueConnection );
172  }
173  else if ( mLineEdit )
174  {
175  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsValueRelationWidgetWrapper::emitValueChangedInternal, Qt::UniqueConnection );
176  }
177 }
178 
180 {
181  return mTableWidget || mLineEdit || mComboBox;
182 }
183 
184 void QgsValueRelationWidgetWrapper::updateValues( const QVariant &value, const QVariantList & )
185 {
186  if ( mTableWidget )
187  {
188  QStringList checkList;
189 
190  if ( layer()->fields().at( fieldIdx() ).type() == QVariant::Map ||
191  layer()->fields().at( fieldIdx() ).type() == QVariant::List )
192  {
193  checkList = value.toStringList();
194  }
195  else
196  {
198  }
199 
200  QTableWidgetItem *lastChangedItem = nullptr;
201 
202  const int nofColumns = columnCount();
203 
204  // This block is needed because item->setCheckState triggers dataChanged gets back to value()
205  // and iterate over all items again! This can be extremely slow on large items sets.
206  for ( int j = 0; j < mTableWidget->rowCount(); j++ )
207  {
208  auto signalBlockedTableWidget = whileBlocking( mTableWidget );
209  Q_UNUSED( signalBlockedTableWidget )
210 
211  for ( int i = 0; i < nofColumns; ++i )
212  {
213  QTableWidgetItem *item = mTableWidget->item( j, i );
214  if ( item )
215  {
216  item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
217  //re-set enabled state because it's lost after reloading items
218  item->setFlags( mEnabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
219  lastChangedItem = item;
220  }
221  }
222  }
223  // let's trigger the signal now, once and for all
224  if ( lastChangedItem )
225  lastChangedItem->setCheckState( checkList.contains( lastChangedItem->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
226 
227  }
228  else if ( mComboBox )
229  {
230  // findData fails to tell a 0 from a NULL
231  // See: "Value relation, value 0 = NULL" - https://github.com/qgis/QGIS/issues/27803
232  int idx = -1; // default to not found
233  for ( int i = 0; i < mComboBox->count(); i++ )
234  {
235  QVariant v( mComboBox->itemData( i ) );
236  if ( qgsVariantEqual( v, value ) )
237  {
238  idx = i;
239  break;
240  }
241  }
242  mComboBox->setCurrentIndex( idx );
243  }
244  else if ( mLineEdit )
245  {
246  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : qgis::as_const( mCache ) )
247  {
248  if ( i.key == value )
249  {
250  mLineEdit->setText( i.value );
251  break;
252  }
253  }
254  }
255 }
256 
257 void QgsValueRelationWidgetWrapper::widgetValueChanged( const QString &attribute, const QVariant &newValue, bool attributeChanged )
258 {
259 
260  // Do nothing if the value has not changed
261  if ( attributeChanged )
262  {
263  QVariant oldValue( value( ) );
264  setFormFeatureAttribute( attribute, newValue );
265  // Update combos if the value used in the filter expression has changed
267  && QgsValueRelationFieldFormatter::expressionFormAttributes( mExpression ).contains( attribute ) )
268  {
269  populate();
270  // Restore value
271  updateValues( value( ) );
272  // If the value has changed as a result of another widget's value change,
273  // we need to emit the signal to make sure other dependent widgets are
274  // updated.
275  if ( oldValue != value() && fieldIdx() < formFeature().fields().count() )
276  {
277  QString attributeName( formFeature().fields().names().at( fieldIdx() ) );
278  setFormFeatureAttribute( attributeName, value( ) );
280  }
281  }
282  }
283 }
284 
285 
287 {
288  setFormFeature( feature );
289  whileBlocking( this )->populate();
290  whileBlocking( this )->setValue( feature.attribute( fieldIdx() ) );
291 
292  // As we block any signals, possible depending widgets will not being updated
293  // so we force emit signal once and for all
295 
296  // A bit of logic to set the default value if AllowNull is false and this is a new feature
297  // Note that this needs to be here after the cache has been created/updated by populate()
298  // and signals unblocked (we want this to propagate to the feature itself)
299  if ( formFeature().isValid()
300  && ! formFeature().attribute( fieldIdx() ).isValid()
301  && ! mCache.isEmpty()
302  && ! config( QStringLiteral( "AllowNull" ) ).toBool( ) )
303  {
304  // This is deferred because at the time the feature is set in one widget it is not
305  // set in the next, which is typically the "down" in a drill-down
306  QTimer::singleShot( 0, this, [ this ]
307  {
308  if ( ! mCache.isEmpty() )
309  {
310  updateValues( mCache.at( 0 ).key );
311  }
312  } );
313  }
314 }
315 
316 int QgsValueRelationWidgetWrapper::columnCount() const
317 {
318  return std::max( 1, config( QStringLiteral( "NofColumns" ) ).toInt() );
319 }
320 
321 
322 QVariant::Type QgsValueRelationWidgetWrapper::fkType() const
323 {
325  if ( layer )
326  {
327  QgsFields fields = layer->fields();
328  int idx { fields.lookupField( config().value( QStringLiteral( "Key" ) ).toString() ) };
329  if ( idx >= 0 )
330  {
331  return fields.at( idx ).type();
332  }
333  }
334  return QVariant::Type::Invalid;
335 }
336 
337 void QgsValueRelationWidgetWrapper::populate( )
338 {
339  // Initialize, note that signals are blocked, to avoid double signals on new features
342  {
343  if ( context().parentFormFeature().isValid() )
344  {
345  mCache = QgsValueRelationFieldFormatter::createCache( config(), formFeature(), context().parentFormFeature() );
346  }
347  else
348  {
350  }
351  }
352  else if ( mCache.empty() )
353  {
355  }
356 
357  if ( mComboBox )
358  {
359  mComboBox->clear();
360  if ( config( QStringLiteral( "AllowNull" ) ).toBool( ) )
361  {
362  whileBlocking( mComboBox )->addItem( tr( "(no selection)" ), QVariant( field().type( ) ) );
363  }
364 
365  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : qgis::as_const( mCache ) )
366  {
367  whileBlocking( mComboBox )->addItem( element.value, element.key );
368  if ( !element.description.isEmpty() )
369  mComboBox->setItemData( mComboBox->count() - 1, element.description, Qt::ToolTipRole );
370  }
371 
372  }
373  else if ( mTableWidget )
374  {
375  const int nofColumns = columnCount();
376 
377  if ( ! mCache.empty() )
378  {
379  mTableWidget->setRowCount( ( mCache.size() + nofColumns - 1 ) / nofColumns );
380  }
381  else
382  mTableWidget->setRowCount( 1 );
383  mTableWidget->setColumnCount( nofColumns );
384 
385  whileBlocking( mTableWidget )->clear();
386  int row = 0;
387  int column = 0;
388  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : qgis::as_const( mCache ) )
389  {
390  if ( column == nofColumns )
391  {
392  row++;
393  column = 0;
394  }
395  QTableWidgetItem *item = nullptr;
396  item = new QTableWidgetItem( element.value );
397  item->setData( Qt::UserRole, element.key );
398  whileBlocking( mTableWidget )->setItem( row, column, item );
399  column++;
400  }
401 
402  }
403  else if ( mLineEdit )
404  {
405  QStringList values;
406  values.reserve( mCache.size() );
407  for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : qgis::as_const( mCache ) )
408  {
409  values << i.value;
410  }
411  QStringListModel *m = new QStringListModel( values, mLineEdit );
412  QCompleter *completer = new QCompleter( m, mLineEdit );
413  completer->setCaseSensitivity( Qt::CaseInsensitive );
414  mLineEdit->setCompleter( completer );
415  }
416 }
417 
419 {
420  const int nofColumns = columnCount();
421 
422  if ( mTableWidget )
423  {
424  for ( int j = 0; j < mTableWidget->rowCount(); j++ )
425  {
426  for ( int i = 0; i < nofColumns; ++i )
427  {
428  whileBlocking( mTableWidget )->item( j, i )->setCheckState( Qt::PartiallyChecked );
429  }
430  }
431  }
432  else if ( mComboBox )
433  {
434  whileBlocking( mComboBox )->setCurrentIndex( -1 );
435  }
436  else if ( mLineEdit )
437  {
438  whileBlocking( mLineEdit )->clear();
439  }
440 }
441 
443 {
444  if ( mEnabled == enabled )
445  return;
446 
447  mEnabled = enabled;
448 
449  if ( mTableWidget )
450  {
451  auto signalBlockedTableWidget = whileBlocking( mTableWidget );
452  Q_UNUSED( signalBlockedTableWidget )
453 
454  for ( int j = 0; j < mTableWidget->rowCount(); j++ )
455  {
456  for ( int i = 0; i < mTableWidget->columnCount(); ++i )
457  {
458  QTableWidgetItem *item = mTableWidget->item( j, i );
459  if ( item )
460  {
461  item->setFlags( enabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
462  }
463  }
464  }
465  }
466  else
468 }
469 
470 void QgsValueRelationWidgetWrapper::parentFormValueChanged( const QString &attribute, const QVariant &value )
471 {
472 
473  // Update the parent feature in the context ( which means to replace the whole context :/ )
475  QgsFeature feature { context().parentFormFeature() };
476  feature.setAttribute( attribute, value );
477  ctx.setParentFormFeature( feature );
478  setContext( ctx );
479 
480  // Check if the change might affect the filter expression and the cache needs updates
482  && ( config( QStringLiteral( "Value" ) ).toString() == attribute ||
483  config( QStringLiteral( "Key" ) ).toString() == attribute ||
485  QgsValueRelationFieldFormatter::expressionParentFormAttributes( mExpression ).contains( attribute ) ) )
486  {
487  populate();
488  }
489 
490 }
491 
492 void QgsValueRelationWidgetWrapper::emitValueChangedInternal( const QString &value )
493 {
495  emit valueChanged( value );
497  emit valuesChanged( value );
498 }
qgsfields.h
QgsPostgresStringUtils::buildArray
static QString buildArray(const QVariantList &list)
Build a postgres array like formatted list in a string from a QVariantList.
Definition: qgspostgresstringutils.cpp:119
qgsvaluerelationfieldformatter.h
qgsattributeform.h
QgsValueRelationFieldFormatter::valueToStringList
static QStringList valueToStringList(const QVariant &value)
Utility to convert a list or a string representation of an (hstore style: {1,2...}) list in value to ...
Definition: qgsvaluerelationfieldformatter.cpp:228
qgspostgresstringutils.h
QgsEditorWidgetWrapper::setFormFeatureAttribute
bool setFormFeatureAttribute(const QString &attributeName, const QVariant &attributeValue)
Update the feature currently being edited by changing its attribute attributeName to attributeValue.
Definition: qgseditorwidgetwrapper.cpp:130
QgsValueRelationWidgetWrapper::value
QVariant value() const override
Will be used to access the widget's value.
Definition: qgsvaluerelationwidgetwrapper.cpp:48
QgsValueRelationWidgetWrapper::setFeature
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
Definition: qgsvaluerelationwidgetwrapper.cpp:286
qgsfeatureiterator.h
QgsFields
Definition: qgsfields.h:44
qgsfilterlineedit.h
QgsFilterLineEdit
Definition: qgsfilterlineedit.h:39
qgis.h
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsValueRelationFieldFormatter::expressionParentFormVariables
static QSet< QString > expressionParentFormVariables(const QString &expression)
Returns a list of variables required by the parent form's form context expression.
Definition: qgsvaluerelationfieldformatter.cpp:300
QgsValueRelationWidgetWrapper::valid
bool valid() const override
Returns true if the widget has been properly initialized.
Definition: qgsvaluerelationwidgetwrapper.cpp:179
QgsValueRelationFieldFormatter::expressionRequiresParentFormScope
static bool expressionRequiresParentFormScope(const QString &expression)
Check if the expression requires a parent form scope (i.e.
Definition: qgsvaluerelationfieldformatter.cpp:314
QgsValueRelationFieldFormatter::expressionFormAttributes
static QSet< QString > expressionFormAttributes(const QString &expression)
Returns a list of attributes required by the form context expression.
Definition: qgsvaluerelationfieldformatter.cpp:343
QgsValueRelationWidgetWrapper::showIndeterminateState
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
Definition: qgsvaluerelationwidgetwrapper.cpp:418
QgsWidgetWrapper::context
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
Definition: qgswidgetwrapper.cpp:86
QgsEditorWidgetWrapper
Definition: qgseditorwidgetwrapper.h:47
QgsValueRelationWidgetWrapper::widgetValueChanged
void widgetValueChanged(const QString &attribute, const QVariant &newValue, bool attributeChanged)
Will be called when a value in the current edited form or table row changes.
Definition: qgsvaluerelationwidgetwrapper.cpp:257
QgsEditorWidgetWrapper::fieldIdx
int fieldIdx() const
Access the field index.
Definition: qgseditorwidgetwrapper.cpp:34
QgsEditorWidgetWrapper::valueChanged
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3280
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:752
QgsWidgetWrapper::layer
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Definition: qgswidgetwrapper.cpp:91
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
QgsValueRelationWidgetWrapper::initWidget
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
Definition: qgsvaluerelationwidgetwrapper.cpp:147
QgsEditorWidgetWrapper::field
QgsField field() const
Access the field.
Definition: qgseditorwidgetwrapper.cpp:39
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
QgsEditorWidgetWrapper::emitValueChanged
void emitValueChanged()
Will call the value() method to determine the emitted value.
Definition: qgseditorwidgetwrapper.cpp:91
QgsAttributeEditorContext::parentFormFeature
QgsFeature parentFormFeature() const
Returns the feature of the currently edited parent form in its actual state.
Definition: qgsattributeeditorcontext.h:250
qgsvaluerelationwidgetwrapper.h
QgsValueRelationFieldFormatter::resolveLayer
static QgsVectorLayer * resolveLayer(const QVariantMap &config, const QgsProject *project)
Returns the (possibly NULL) layer from the widget's config and project.
Definition: qgsvaluerelationfieldformatter.cpp:395
qgsvectorlayer.h
QgsEditorWidgetWrapper::setFormFeature
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
Definition: qgseditorwidgetwrapper.h:352
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:211
QgsEditorWidgetWrapper::valuesChanged
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
QgsValueRelationWidgetWrapper::parentFormValueChanged
void parentFormValueChanged(const QString &attribute, const QVariant &value) override
Definition: qgsvaluerelationwidgetwrapper.cpp:470
qgsattributes.h
QgsValueRelationWidgetWrapper::setEnabled
void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
Definition: qgsvaluerelationwidgetwrapper.cpp:442
QgsWidgetWrapper::config
QVariantMap config() const
Returns the whole config.
Definition: qgswidgetwrapper.cpp:81
qgsVariantEqual
bool qgsVariantEqual(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether they are equal, two NULL values are always treated a...
Definition: qgis.cpp:265
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsValueRelationFieldFormatter::createCache
QVariant createCache(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config) const override
Create a cache for a given field.
Definition: qgsvaluerelationfieldformatter.cpp:116
QgsValueRelationWidgetWrapper::createWidget
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
Definition: qgsvaluerelationwidgetwrapper.cpp:126
QgsEditorWidgetWrapper::setEnabled
void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
Definition: qgseditorwidgetwrapper.cpp:60
QgsValueRelationFieldFormatter::expressionRequiresFormScope
static bool expressionRequiresFormScope(const QString &expression)
Check if the expression requires a form scope (i.e.
Definition: qgsvaluerelationfieldformatter.cpp:309
qgsvaluerelationwidgetfactory.h
QgsAttributeForm::widgetValueChanged
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
QgsFeature
Definition: qgsfeature.h:55
QgsValueRelationWidgetWrapper::QgsValueRelationWidgetWrapper
QgsValueRelationWidgetWrapper(QgsVectorLayer *layer, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Constructor for QgsValueRelationWidgetWrapper.
Definition: qgsvaluerelationwidgetwrapper.cpp:42
QgsAttributeForm
Definition: qgsattributeform.h:44
QgsValueRelationFieldFormatter::expressionParentFormAttributes
static QSet< QString > expressionParentFormAttributes(const QString &expression)
Returns a list of attributes required by the parent form's form context expression.
Definition: qgsvaluerelationfieldformatter.cpp:319
qgsjsonutils.h
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:324
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsAttributeEditorContext
Definition: qgsattributeeditorcontext.h:40
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:751
QgsWidgetWrapper::setContext
void setContext(const QgsAttributeEditorContext &context)
Set the context in which this widget is shown.
Definition: qgswidgetwrapper.cpp:66
QgsValueRelationFieldFormatter::ValueRelationItem
Definition: qgsvaluerelationfieldformatter.h:53
qgsproject.h
QgsField::type
QVariant::Type type
Definition: qgsfield.h:57
QgsEditorWidgetWrapper::formFeature
QgsFeature formFeature() const
The feature currently being edited, in its current state.
Definition: qgseditorwidgetwrapper.h:345