QGIS API Documentation  3.2.0-Bonn (bc43194)
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"
26 
27 #include <QLayout>
28 #include <QLabel>
29 #include <QStackedWidget>
30 
32  : QgsAttributeFormWidget( editorWidget, form )
33  , mWidgetType( widgetType )
34  , mWidget( editorWidget )
35  , mForm( form )
36  , mMultiEditButton( new QgsMultiEditToolButton() )
37  , mBlockValueUpdate( false )
38  , mIsMixed( false )
39  , mIsChanged( false )
40 {
41  mConstraintResultLabel = new QLabel( this );
42  mConstraintResultLabel->setObjectName( QStringLiteral( "ConstraintStatus" ) );
43  mConstraintResultLabel->setSizePolicy( QSizePolicy::Fixed, mConstraintResultLabel->sizePolicy().verticalPolicy() );
44 
45  mMultiEditButton->setField( mWidget->field() );
46  mAggregateButton = new QgsAggregateToolButton();
47  mAggregateButton->setType( editorWidget->field().type() );
48  connect( mAggregateButton, &QgsAggregateToolButton::aggregateChanged, this, &QgsAttributeFormEditorWidget::onAggregateChanged );
49 
50  if ( mWidget->widget() )
51  {
52  mWidget->widget()->setObjectName( mWidget->field().name() );
53  }
54 
55  connect( mWidget, static_cast<void ( QgsEditorWidgetWrapper::* )( const QVariant &value )>( &QgsEditorWidgetWrapper::valueChanged ), this, &QgsAttributeFormEditorWidget::editorWidgetChanged );
56 
57  connect( mMultiEditButton, &QgsMultiEditToolButton::resetFieldValueTriggered, this, &QgsAttributeFormEditorWidget::resetValue );
58  connect( mMultiEditButton, &QgsMultiEditToolButton::setFieldValueTriggered, this, &QgsAttributeFormEditorWidget::setFieldTriggered );
59 
60  mMultiEditButton->setField( mWidget->field() );
61 
62  updateWidgets();
63 }
64 
66 {
67  //there's a chance these widgets are not currently added to the layout, so have no parent set
68  delete mMultiEditButton;
69 }
70 
72 {
73  Q_ASSERT( !mWidgetType.isEmpty() );
74  const QVariantMap config = mWidget->config();
75  const int fieldIdx = mWidget->fieldIdx();
76 
77  QgsSearchWidgetWrapper *sww = QgsGui::editorWidgetRegistry()->createSearchWidget( mWidgetType, layer(), fieldIdx, config,
78  searchWidgetFrame(), context );
80  searchWidgetFrame()->layout()->addWidget( mAggregateButton );
83  {
84  // create secondary widget for between type searches
85  QgsSearchWidgetWrapper *sww2 = QgsGui::editorWidgetRegistry()->createSearchWidget( mWidgetType, layer(), fieldIdx, config,
86  searchWidgetFrame(), context );
88  }
89 }
90 
91 void QgsAttributeFormEditorWidget::setConstraintStatus( const QString &constraint, const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result )
92 {
93  switch ( result )
94  {
96  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#FF9800\">%1</font>" ).arg( QChar( 0x2718 ) ) );
97  mConstraintResultLabel->setToolTip( description.isEmpty() ? QStringLiteral( "<b>%1</b>: %2" ).arg( constraint, err ) : description );
98  break;
99 
101  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#FFC107\">%1</font>" ).arg( QChar( 0x2718 ) ) );
102  mConstraintResultLabel->setToolTip( description.isEmpty() ? QStringLiteral( "<b>%1</b>: %2" ).arg( constraint, err ) : description );
103  break;
104 
106  mConstraintResultLabel->setText( QStringLiteral( "<font color=\"#259B24\">%1</font>" ).arg( QChar( 0x2714 ) ) );
107  mConstraintResultLabel->setToolTip( QString() );
108  break;
109  }
110 }
111 
113 {
114  mConstraintResultLabel->setHidden( !editable );
115 }
116 
118 {
119  if ( mWidget && mixed )
120  mWidget->showIndeterminateState();
121  mMultiEditButton->setIsMixed( mixed );
122  mIsMixed = mixed;
123 }
124 
126 {
127  if ( mWidget )
128  mPreviousValue = mWidget->value();
129 
130  setIsMixed( false );
131  mMultiEditButton->changesCommitted();
132  mIsChanged = false;
133 }
134 
135 
136 
137 void QgsAttributeFormEditorWidget::initialize( const QVariant &initialValue, bool mixedValues )
138 {
139  if ( mWidget )
140  {
141  mBlockValueUpdate = true;
142  mWidget->setValue( initialValue );
143  mBlockValueUpdate = false;
144  }
145  mPreviousValue = initialValue;
146  setIsMixed( mixedValues );
147  mMultiEditButton->setIsChanged( false );
148  mIsChanged = false;
149 }
150 
152 {
153  return mWidget->value();
154 }
155 
156 
157 
158 void QgsAttributeFormEditorWidget::editorWidgetChanged( const QVariant &value )
159 {
160  if ( mBlockValueUpdate )
161  return;
162 
163  mIsChanged = true;
164 
165  switch ( mode() )
166  {
167  case DefaultMode:
168  case SearchMode:
169  case AggregateSearchMode:
170  break;
171  case MultiEditMode:
172  mMultiEditButton->setIsChanged( true );
173  }
174 
175  emit valueChanged( value );
176 }
177 
178 void QgsAttributeFormEditorWidget::resetValue()
179 {
180  mIsChanged = false;
181  mBlockValueUpdate = true;
182  if ( mWidget )
183  mWidget->setValue( mPreviousValue );
184  mBlockValueUpdate = false;
185 
186  switch ( mode() )
187  {
188  case DefaultMode:
189  case SearchMode:
190  case AggregateSearchMode:
191  break;
192  case MultiEditMode:
193  {
194  mMultiEditButton->setIsChanged( false );
195  if ( mWidget && mIsMixed )
196  mWidget->showIndeterminateState();
197  break;
198  }
199  }
200 }
201 
202 void QgsAttributeFormEditorWidget::setFieldTriggered()
203 {
204  mIsChanged = true;
205 }
206 
207 void QgsAttributeFormEditorWidget::onAggregateChanged()
208 {
209  for ( QgsSearchWidgetWrapper *searchWidget : searchWidgetWrappers() )
210  searchWidget->setAggregate( mAggregateButton->aggregate() );
211 }
212 
213 void QgsAttributeFormEditorWidget::updateWidgets()
214 {
215  //first update the tool buttons
216  bool hasMultiEditButton = ( editPage()->layout()->indexOf( mMultiEditButton ) >= 0 );
217  bool fieldReadOnly = layer()->editFormConfig().readOnly( mWidget->fieldIdx() );
218 
219  if ( hasMultiEditButton )
220  {
221  if ( mode() != MultiEditMode || fieldReadOnly )
222  {
223  editPage()->layout()->removeWidget( mMultiEditButton );
224  mMultiEditButton->setParent( nullptr );
225  }
226  }
227  else
228  {
229  if ( mode() == MultiEditMode && !fieldReadOnly )
230  {
231  editPage()->layout()->addWidget( mMultiEditButton );
232  }
233  }
234 
235  switch ( mode() )
236  {
237  case DefaultMode:
238  case MultiEditMode:
239  {
240  stack()->setCurrentWidget( editPage() );
241 
242  editPage()->layout()->addWidget( mConstraintResultLabel );
243 
244  break;
245  }
246 
247  case AggregateSearchMode:
248  {
249  mAggregateButton->setVisible( true );
250  stack()->setCurrentWidget( searchPage() );
251  break;
252  }
253 
254  case SearchMode:
255  {
256  mAggregateButton->setVisible( false );
257  stack()->setCurrentWidget( searchPage() );
258  break;
259  }
260  }
261 }
Shows a search widget on a filter form.
Widget failed at least one soft (non-enforced) constraint.
QVariant config(const QString &key, const QVariant &defaultVal=QVariant()) const
Use this inside your overridden classes to access the configuration.
QString name
Definition: qgsfield.h:57
void setConstraintResultVisible(bool editable)
Set the constraint result lable visible or invisible according to the layer editable status...
QgsField field() const
Access the field.
Base class for all widgets shown on a QgsAttributeForm.
This class contains context information for attribute editor widgets.
Manages an editor widget Widget and wrapper share the same parent.
void setType(QVariant::Type type)
Based on the type of underlying data, some aggregates will be available or not.
Supports searching for values outside of a set range.
Widget failed at least one hard (enforced) constraint.
void initialize(const QVariant &initialValue, bool mixedValues=false)
Resets the widget to an initial value.
A tool button widget which is displayed next to editor widgets in attribute forms, and allows for controlling how the widget behaves and interacts with the form while in multi edit mode.
QStackedWidget * stack() const
Returns a pointer to the stacked widget managing edit and search page.
Default mode, only the editor widget is shown.
QgsAttributeFormEditorWidget(QgsEditorWidgetWrapper *editorWidget, const QString &widgetType, QgsAttributeForm *form)
Constructor for QgsAttributeFormEditorWidget.
Offers a toolbutton to choose between different aggregate functions.
void valueChanged(const QVariant &value)
Emitted when the widget&#39;s value changes.
QList< QgsSearchWidgetWrapper *> searchWidgetWrappers()
Returns the search widget wrapper used in this widget.
QWidget * searchPage() const
Returns a pointer to the search page widget.
void setSearchWidgetWrapper(QgsSearchWidgetWrapper *wrapper)
Sets the search widget wrapper for the widget used when the form is in search mode.
void setIsMixed(bool mixed)
Sets whether the widget should be displayed in a "mixed values" mode.
void changesCommitted()
Called when field values have been changed and field now contains all the same values.
virtual void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories...
Definition: qgsgui.cpp:47
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
QWidget * editPage() const
Returns a pointer to the EDIT page widget.
Mode mode() const
Returns the current mode for the widget.
void resetFieldValueTriggered()
Emitted when the "reset to original values" option is selected.
void setIsChanged(bool changed)
Sets whether the associated field has changed.
QgsEditFormConfig editFormConfig
QVariant currentValue() const
Returns the current value of the attached editor widget.
QgsVectorLayer * layer()
The layer for which this widget and its form is shown.
Multi edit mode, both the editor widget and a QgsMultiEditToolButton is shown.
void setField(const QgsField &field)
Sets the field associated with this button.
Widget passed constraints successfully.
ConstraintResult
Result of constraint checks.
void addAdditionalSearchWidgetWrapper(QgsSearchWidgetWrapper *wrapper)
Adds an additional search widget wrapper.
void setIsMixed(bool mixed)
Sets whether the associated field contains mixed values.
void setFieldValueTriggered()
Emitted when the "set field value for all features" option is selected.
void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
void setConstraintStatus(const QString &constraint, const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result)
Set the constraint status for this widget.
virtual QVariant value() const =0
Will be used to access the widget&#39;s value.
QgsSearchWidgetWrapper * createSearchWidget(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
QWidget * widget()
Access the widget managed by this wrapper.
bool readOnly(int idx) const
This returns true if the field is manually set to read only or if the field does not support editing ...
void changesCommitted()
Called when field values have been committed;.
void aggregateChanged()
The function name of the selected aggregate has changed.
int fieldIdx() const
Access the field index.
void createSearchWidgetWrappers(const QgsAttributeEditorContext &context=QgsAttributeEditorContext()) override
Creates the search widget wrappers for the widget used when the form is in search mode...
Embedded in a search form, show additional aggregate function toolbutton.
virtual FilterFlags supportedFlags() const
Returns filter flags supported by the search widget.
QVariant::Type type
Definition: qgsfield.h:55
QString aggregate() const
The function name of the selected aggregate or a Null String if none is chosen.
Supports searches between two values.
QWidget * searchWidgetFrame()
Returns the widget which should be used as a parent during construction of the search widget wrapper...