QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsattributeformeditorwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributeformeditorwidget.cpp
3  -------------------------------
4  Date : March 2016
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 #include "qgsattributeform.h"
18 #include "qgsmultiedittoolbutton.h"
20 #include "qgseditorwidgetwrapper.h"
21 #include "qgssearchwidgetwrapper.h"
24 #include "qgsaggregatetoolbutton.h"
25 #include "qgsgui.h"
27 #include "qgsvectorlayerutils.h"
28 
29 #include <QLayout>
30 #include <QLabel>
31 #include <QStackedWidget>
32 
34  : QgsAttributeFormWidget( editorWidget, form )
35  , mWidgetType( widgetType )
36  , mEditorWidget( editorWidget )
37  , mForm( form )
38  , mMultiEditButton( new QgsMultiEditToolButton() )
39  , mBlockValueUpdate( false )
40  , mIsMixed( false )
41  , mIsChanged( false )
42 {
43  mConstraintResultLabel = new QLabel( this );
44  mConstraintResultLabel->setObjectName( QStringLiteral( "ConstraintStatus" ) );
45  mConstraintResultLabel->setSizePolicy( QSizePolicy::Fixed, mConstraintResultLabel->sizePolicy().verticalPolicy() );
46 
47  mMultiEditButton->setField( mEditorWidget->field() );
48  mAggregateButton = new QgsAggregateToolButton();
49  mAggregateButton->setType( editorWidget->field().type() );
50  connect( mAggregateButton, &QgsAggregateToolButton::aggregateChanged, this, &QgsAttributeFormEditorWidget::onAggregateChanged );
51 
52  if ( mEditorWidget->widget() )
53  {
54  mEditorWidget->widget()->setObjectName( mEditorWidget->field().name() );
55  }
56 
57  connect( mEditorWidget, &QgsEditorWidgetWrapper::valuesChanged, this, &QgsAttributeFormEditorWidget::editorWidgetValuesChanged );
58 
59  connect( mMultiEditButton, &QgsMultiEditToolButton::resetFieldValueTriggered, this, &QgsAttributeFormEditorWidget::resetValue );
60  connect( mMultiEditButton, &QgsMultiEditToolButton::setFieldValueTriggered, this, &QgsAttributeFormEditorWidget::setFieldTriggered );
61 
62  mMultiEditButton->setField( mEditorWidget->field() );
63 
64  updateWidgets();
65 }
66 
68 {
69  //there's a chance these widgets are not currently added to the layout, so have no parent set
70  delete mMultiEditButton;
71 }
72 
74 {
75  Q_ASSERT( !mWidgetType.isEmpty() );
76  const QVariantMap config = mEditorWidget->config();
77  const int fieldIdx = mEditorWidget->fieldIdx();
78 
79  QgsSearchWidgetWrapper *sww = QgsGui::editorWidgetRegistry()->createSearchWidget( mWidgetType, layer(), fieldIdx, config,
80  searchWidgetFrame(), context );
82  searchWidgetFrame()->layout()->addWidget( mAggregateButton );
85  {
86  // create secondary widget for between type searches
87  QgsSearchWidgetWrapper *sww2 = QgsGui::editorWidgetRegistry()->createSearchWidget( mWidgetType, layer(), fieldIdx, config,
88  searchWidgetFrame(), context );
90  }
91 }
92 
93 void QgsAttributeFormEditorWidget::setConstraintStatus( const QString &constraint, const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result )
94 {
95  switch ( result )
96  {
98  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#FF9800\">%1</font>" ).arg( QChar( 0x2718 ) ) );
99  mConstraintResultLabel->setToolTip( description.isEmpty() ? QStringLiteral( "<b>%1</b>: %2" ).arg( constraint, err ) : description );
100  break;
101 
103  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#FFC107\">%1</font>" ).arg( QChar( 0x2718 ) ) );
104  mConstraintResultLabel->setToolTip( description.isEmpty() ? QStringLiteral( "<b>%1</b>: %2" ).arg( constraint, err ) : description );
105  break;
106 
108  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#259B24\">%1</font>" ).arg( QChar( 0x2714 ) ) );
109  mConstraintResultLabel->setToolTip( description );
110  break;
111  }
112 }
113 
115 {
116  mConstraintResultLabel->setHidden( !editable );
117 }
118 
120 {
121  return mEditorWidget;
122 }
123 
125 {
126  if ( mEditorWidget && mixed )
127  mEditorWidget->showIndeterminateState();
128  mMultiEditButton->setIsMixed( mixed );
129  mIsMixed = mixed;
130 }
131 
133 {
134  if ( mEditorWidget )
135  {
136  mPreviousValue = mEditorWidget->value();
137  mPreviousAdditionalValues = mEditorWidget->additionalFieldValues();
138  }
139 
140  setIsMixed( false );
141  mMultiEditButton->changesCommitted();
142  mIsChanged = false;
143 }
144 
145 
146 
147 void QgsAttributeFormEditorWidget::initialize( const QVariant &initialValue, bool mixedValues, const QVariantList &additionalFieldValues )
148 {
149  if ( mEditorWidget )
150  {
151  mBlockValueUpdate = true;
152  mEditorWidget->setValues( initialValue, additionalFieldValues );
153  mBlockValueUpdate = false;
154  }
155  mPreviousValue = initialValue;
156  mPreviousAdditionalValues = additionalFieldValues;
157  setIsMixed( mixedValues );
158  mMultiEditButton->setIsChanged( false );
159  mIsChanged = false;
160  updateWidgets();
161 }
162 
164 {
165  return mEditorWidget->value();
166 }
167 
168 
169 
170 void QgsAttributeFormEditorWidget::editorWidgetValuesChanged( const QVariant &value, const QVariantList &additionalFieldValues )
171 {
172  if ( mBlockValueUpdate )
173  return;
174 
175  mIsChanged = true;
176 
177  switch ( mode() )
178  {
179  case DefaultMode:
180  case SearchMode:
181  case AggregateSearchMode:
182  break;
183  case MultiEditMode:
184  mMultiEditButton->setIsChanged( true );
185  }
186 
188  emit valueChanged( value );
190  emit valuesChanged( value, additionalFieldValues );
191 }
192 
193 void QgsAttributeFormEditorWidget::resetValue()
194 {
195  mIsChanged = false;
196  mBlockValueUpdate = true;
197  if ( mEditorWidget )
198  mEditorWidget->setValues( mPreviousValue, mPreviousAdditionalValues );
199  mBlockValueUpdate = false;
200 
201  switch ( mode() )
202  {
203  case DefaultMode:
204  case SearchMode:
205  case AggregateSearchMode:
206  break;
207  case MultiEditMode:
208  {
209  mMultiEditButton->setIsChanged( false );
210  if ( mEditorWidget && mIsMixed )
211  mEditorWidget->showIndeterminateState();
212  break;
213  }
214  }
215 }
216 
217 void QgsAttributeFormEditorWidget::setFieldTriggered()
218 {
219  mIsChanged = true;
220 }
221 
222 void QgsAttributeFormEditorWidget::onAggregateChanged()
223 {
224  for ( QgsSearchWidgetWrapper *searchWidget : searchWidgetWrappers() )
225  searchWidget->setAggregate( mAggregateButton->aggregate() );
226 }
227 
228 void QgsAttributeFormEditorWidget::updateWidgets()
229 {
230  //first update the tool buttons
231  bool hasMultiEditButton = ( editPage()->layout()->indexOf( mMultiEditButton ) >= 0 );
232 
233  const int fieldIndex = mEditorWidget->fieldIdx();
234 
235  bool fieldReadOnly = false;
236  QgsFeature feature;
237  auto it = layer()->getSelectedFeatures();
238  while ( it.nextFeature( feature ) )
239  {
240  fieldReadOnly |= !QgsVectorLayerUtils::fieldIsEditable( layer(), fieldIndex, feature );
241  }
242 
243  if ( hasMultiEditButton )
244  {
245  if ( mode() != MultiEditMode || fieldReadOnly )
246  {
247  editPage()->layout()->removeWidget( mMultiEditButton );
248  mMultiEditButton->setParent( nullptr );
249  }
250  }
251  else
252  {
253  if ( mode() == MultiEditMode && !fieldReadOnly )
254  {
255  editPage()->layout()->addWidget( mMultiEditButton );
256  }
257  }
258 
259  switch ( mode() )
260  {
261  case DefaultMode:
262  case MultiEditMode:
263  {
264  stack()->setCurrentWidget( editPage() );
265 
266  editPage()->layout()->addWidget( mConstraintResultLabel );
267 
268  break;
269  }
270 
271  case AggregateSearchMode:
272  {
273  mAggregateButton->setVisible( true );
274  stack()->setCurrentWidget( searchPage() );
275  break;
276  }
277 
278  case SearchMode:
279  {
280  mAggregateButton->setVisible( false );
281  stack()->setCurrentWidget( searchPage() );
282  break;
283  }
284  }
285 }
QgsAttributeFormWidget::DefaultMode
@ DefaultMode
Default mode, only the editor widget is shown.
Definition: qgsattributeformwidget.h:47
QgsGui::editorWidgetRegistry
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
Definition: qgsgui.cpp:74
qgssearchwidgettoolbutton.h
qgseditorwidgetwrapper.h
QgsAttributeFormEditorWidget::currentValue
QVariant currentValue() const
Returns the current value of the attached editor widget.
Definition: qgsattributeformeditorwidget.cpp:163
QgsEditorWidgetWrapper::setValues
void setValues(const QVariant &value, const QVariantList &additionalValues)
Is called when the value of the widget or additional field values needs to be changed.
Definition: qgseditorwidgetwrapper.cpp:86
qgsattributeform.h
QgsAttributeFormWidget::mode
Mode mode() const
Returns the current mode for the widget.
Definition: qgsattributeformwidget.h:86
QgsSearchWidgetWrapper::Between
@ Between
Supports searches between two values.
Definition: qgssearchwidgetwrapper.h:102
QgsMultiEditToolButton::setFieldValueTriggered
void setFieldValueTriggered()
Emitted when the "set field value for all features" option is selected.
QgsEditorWidgetWrapper::ConstraintResultFailHard
@ ConstraintResultFailHard
Widget failed at least one hard (enforced) constraint.
Definition: qgseditorwidgetwrapper.h:63
qgsaggregatetoolbutton.h
qgsgui.h
QgsEditorWidgetWrapper::additionalFieldValues
virtual QVariantList additionalFieldValues() const
Will be used to access the widget's values for potential additional fields handled by the widget.
Definition: qgseditorwidgetwrapper.h:100
QgsSearchWidgetWrapper
Shows a search widget on a filter form.
Definition: qgssearchwidgetwrapper.h:86
QgsAttributeFormWidget::layer
QgsVectorLayer * layer()
The layer for which this widget and its form is shown.
Definition: qgsattributeformwidget.cpp:143
QgsMultiEditToolButton::resetFieldValueTriggered
void resetFieldValueTriggered()
Emitted when the "reset to original values" option is selected.
QgsAttributeFormWidget::AggregateSearchMode
@ AggregateSearchMode
Embedded in a search form, show additional aggregate function toolbutton.
Definition: qgsattributeformwidget.h:50
QgsMultiEditToolButton::setIsChanged
void setIsChanged(bool changed)
Sets whether the associated field has changed.
Definition: qgsmultiedittoolbutton.h:80
QgsEditorWidgetWrapper::value
virtual QVariant value() const =0
Will be used to access the widget's value.
QgsAttributeFormEditorWidget::setConstraintStatus
void setConstraintStatus(const QString &constraint, const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result)
Set the constraint status for this widget.
Definition: qgsattributeformeditorwidget.cpp:93
QgsAttributeFormEditorWidget::editorWidget
QgsEditorWidgetWrapper * editorWidget() const
Returns the editor widget wrapper.
Definition: qgsattributeformeditorwidget.cpp:119
QgsAggregateToolButton::aggregateChanged
void aggregateChanged()
The function name of the selected aggregate has changed.
QgsEditorWidgetWrapper::ConstraintResult
ConstraintResult
Result of constraint checks.
Definition: qgseditorwidgetwrapper.h:61
QgsField::name
QString name
Definition: qgsfield.h:59
QgsAttributeFormWidget::addAdditionalSearchWidgetWrapper
void addAdditionalSearchWidgetWrapper(QgsSearchWidgetWrapper *wrapper)
Adds an additional search widget wrapper.
Definition: qgsattributeformwidget.cpp:94
QgsAttributeFormEditorWidget::valueChanged
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emitted when the widget's value changes.
QgsSearchWidgetWrapper::supportedFlags
virtual FilterFlags supportedFlags() const
Returns filter flags supported by the search widget.
Definition: qgssearchwidgetwrapper.cpp:94
QgsWidgetWrapper::widget
QWidget * widget()
Access the widget managed by this wrapper.
Definition: qgswidgetwrapper.cpp:46
QgsEditorWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgseditorwidgetwrapper.h:48
QgsMultiEditToolButton::setField
void setField(const QgsField &field)
Sets the field associated with this button.
Definition: qgsmultiedittoolbutton.h:62
QgsAggregateToolButton::aggregate
QString aggregate() const
The function name of the selected aggregate or a Null String if none is chosen.
Definition: qgsaggregatetoolbutton.cpp:89
QgsEditorWidgetWrapper::fieldIdx
int fieldIdx() const
Access the field index.
Definition: qgseditorwidgetwrapper.cpp:34
QgsAttributeFormEditorWidget::createSearchWidgetWrappers
void createSearchWidgetWrappers(const QgsAttributeEditorContext &context=QgsAttributeEditorContext()) override
Creates the search widget wrappers for the widget used when the form is in search mode.
Definition: qgsattributeformeditorwidget.cpp:73
QgsAttributeFormWidget::MultiEditMode
@ MultiEditMode
Multi edit mode, both the editor widget and a QgsMultiEditToolButton is shown.
Definition: qgsattributeformwidget.h:48
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:797
QgsEditorWidgetWrapper::ConstraintResultPass
@ ConstraintResultPass
Widget passed constraints successfully.
Definition: qgseditorwidgetwrapper.h:62
QgsAttributeFormEditorWidget::~QgsAttributeFormEditorWidget
~QgsAttributeFormEditorWidget() override
Definition: qgsattributeformeditorwidget.cpp:67
QgsMultiEditToolButton::setIsMixed
void setIsMixed(bool mixed)
Sets whether the associated field contains mixed values.
Definition: qgsmultiedittoolbutton.h:72
QgsWidgetWrapper::config
QVariant config(const QString &key, const QVariant &defaultVal=QVariant()) const
Use this inside your overridden classes to access the configuration.
Definition: qgswidgetwrapper.cpp:72
QgsAttributeFormEditorWidget::changesCommitted
void changesCommitted()
Called when field values have been committed;.
Definition: qgsattributeformeditorwidget.cpp:132
qgsvectorlayerjoinbuffer.h
QgsEditorWidgetRegistry::createSearchWidget
QgsSearchWidgetWrapper * createSearchWidget(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Definition: qgseditorwidgetregistry.cpp:128
QgsAttributeFormEditorWidget::valuesChanged
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues)
Emitted when the widget's value changes.
QgsAttributeFormEditorWidget::initialize
void initialize(const QVariant &initialValue, bool mixedValues=false, const QVariantList &additionalFieldValues=QVariantList())
Resets the widget to an initial value.
Definition: qgsattributeformeditorwidget.cpp:147
qgssearchwidgetwrapper.h
qgsattributeformeditorwidget.h
QgsAttributeFormWidget::searchWidgetFrame
QWidget * searchWidgetFrame()
Returns the widget which should be used as a parent during construction of the search widget wrapper.
Definition: qgsattributeformwidget.cpp:77
QgsSearchWidgetWrapper::IsNotBetween
@ IsNotBetween
Supports searching for values outside of a set range.
Definition: qgssearchwidgetwrapper.h:107
qgsvectorlayerutils.h
QgsAttributeFormEditorWidget::setConstraintResultVisible
void setConstraintResultVisible(bool editable)
Set the constraint result label visible or invisible according to the layer editable status.
Definition: qgsattributeformeditorwidget.cpp:114
QgsEditorWidgetWrapper::field
QgsField field() const
Access the field.
Definition: qgseditorwidgetwrapper.cpp:39
qgsattributeeditorcontext.h
qgsmultiedittoolbutton.h
QgsAttributeFormWidget::SearchMode
@ SearchMode
Layer search/filter mode.
Definition: qgsattributeformwidget.h:49
QgsMultiEditToolButton
A tool button widget which is displayed next to editor widgets in attribute forms,...
Definition: qgsmultiedittoolbutton.h:33
QgsMultiEditToolButton::changesCommitted
void changesCommitted()
Called when field values have been changed and field now contains all the same values.
Definition: qgsmultiedittoolbutton.h:94
QgsVectorLayer::getSelectedFeatures
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
Definition: qgsvectorlayer.cpp:3476
QgsEditorWidgetWrapper::valuesChanged
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
qgseditorwidgetregistry.h
QgsEditorWidgetWrapper::ConstraintResultFailSoft
@ ConstraintResultFailSoft
Widget failed at least one soft (non-enforced) constraint.
Definition: qgseditorwidgetwrapper.h:64
QgsVectorLayerUtils::fieldIsEditable
static bool fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
Definition: qgsvectorlayerutils.cpp:861
QgsAttributeFormWidget::stack
QStackedWidget * stack() const
Returns a pointer to the stacked widget managing edit and search page.
Definition: qgsattributeformwidget.cpp:202
QgsAggregateToolButton
Offers a toolbutton to choose between different aggregate functions.
Definition: qgsaggregatetoolbutton.h:34
QgsAttributeFormEditorWidget::setIsMixed
void setIsMixed(bool mixed)
Sets whether the widget should be displayed in a "mixed values" mode.
Definition: qgsattributeformeditorwidget.cpp:124
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsAttributeForm
Definition: qgsattributeform.h:45
QgsAttributeFormEditorWidget::QgsAttributeFormEditorWidget
QgsAttributeFormEditorWidget(QgsEditorWidgetWrapper *editorWidget, const QString &widgetType, QgsAttributeForm *form)
Constructor for QgsAttributeFormEditorWidget.
Definition: qgsattributeformeditorwidget.cpp:33
QgsAttributeEditorContext
This class contains context information for attribute editor widgets.
Definition: qgsattributeeditorcontext.h:41
QgsAggregateToolButton::setType
void setType(QVariant::Type type)
Based on the type of underlying data, some aggregates will be available or not.
Definition: qgsaggregatetoolbutton.cpp:34
QgsAttributeFormWidget::searchWidgetWrappers
QList< QgsSearchWidgetWrapper * > searchWidgetWrappers()
Returns the search widget wrapper used in this widget.
Definition: qgsattributeformwidget.cpp:102
QgsAttributeFormWidget::searchPage
QWidget * searchPage() const
Returns a pointer to the search page widget.
Definition: qgsattributeformwidget.cpp:197
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:796
QgsAttributeFormWidget::setSearchWidgetWrapper
void setSearchWidgetWrapper(QgsSearchWidgetWrapper *wrapper)
Sets the search widget wrapper for the widget used when the form is in search mode.
Definition: qgsattributeformwidget.cpp:82
QgsAttributeFormWidget
Base class for all widgets shown on a QgsAttributeForm.
Definition: qgsattributeformwidget.h:39
QgsField::type
QVariant::Type type
Definition: qgsfield.h:57
QgsEditorWidgetWrapper::showIndeterminateState
virtual void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
Definition: qgseditorwidgetwrapper.h:155
QgsAttributeFormWidget::editPage
QWidget * editPage() const
Returns a pointer to the EDIT page widget.
Definition: qgsattributeformwidget.cpp:207