QGIS API Documentation  3.27.0-Master (e113457133)
qgsattributeform.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributeform.h
3  --------------------------------------
4  Date : 3.5.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 
16 #ifndef QGSATTRIBUTEFORM_H
17 #define QGSATTRIBUTEFORM_H
18 
19 #include "qgsfeature.h"
20 #include "qgis_sip.h"
22 #include "qgseditorwidgetwrapper.h"
23 
24 #include <QWidget>
25 #include <QLabel>
26 #include <QDialogButtonBox>
27 #include "qgis_gui.h"
28 
29 
32 class QgsMessageBar;
33 class QgsMessageBarItem;
34 class QgsWidgetWrapper;
35 class QgsTabWidget;
38 class QSvgWidget;
39 
44 class GUI_EXPORT QgsAttributeForm : public QWidget
45 {
46  Q_OBJECT
47 
48  public:
49 
51  enum Mode
52  {
54  AddFeatureMode,
59  IdentifyMode
60  };
61 
64  {
68  };
69 
70  explicit QgsAttributeForm( QgsVectorLayer *vl,
71  const QgsFeature &feature = QgsFeature(),
73  QWidget *parent SIP_TRANSFERTHIS = nullptr );
74  ~QgsAttributeForm() override;
75 
76  const QgsFeature &feature() { return mFeature; }
77 
84  QgsFeature currentFormFeature() const { return mCurrentFormFeature; }
85 
92  void displayWarning( const QString &message );
93 
94  // TODO QGIS 4.0 - make private
95 
100  void hideButtonBox();
101 
102  // TODO QGIS 4.0 - make private
103 
108  void showButtonBox();
109 
110  // TODO QGIS 4.0 - make private
111 
116  void disconnectButtonBox();
117 
122  void addInterface( QgsAttributeFormInterface *iface SIP_TRANSFER );
123 
129  QgsVectorLayer *layer() { return mLayer; }
130 
136  bool editable();
137 
143  QgsAttributeEditorContext::Mode mode() const { return mMode; }
144 
151  void setMode( QgsAttributeEditorContext::Mode mode );
152 
158  void setEditCommandMessage( const QString &message ) { mEditCommandMessage = message; }
159 
168  bool eventFilter( QObject *object, QEvent *event ) override;
169 
175  void setMultiEditFeatureIds( const QgsFeatureIds &fids );
176 
183  void setMessageBar( QgsMessageBar *messageBar );
184 
192  QString aggregateFilter() const;
193 
200  void setExtraContextScope( QgsExpressionContextScope *extraScope SIP_TRANSFER );
201 
202  signals:
203 
212  Q_DECL_DEPRECATED void attributeChanged( const QString &attribute, const QVariant &value ) SIP_DEPRECATED;
213 
222  void widgetValueChanged( const QString &attribute, const QVariant &value, bool attributeChanged );
223 
232  void beforeSave( bool &ok ) SIP_SKIP;
233 
237  void featureSaved( const QgsFeature &feature );
238 
245  void filterExpressionSet( const QString &expression, QgsAttributeForm::FilterType type );
246 
252 
257  void closed();
258 
263  void zoomToFeatures( const QString &filter );
264 
269  void flashFeatures( const QString &filter );
270 
275  void openFilteredFeaturesAttributeTable( const QString &filter );
276 
277 
278  public slots:
279 
287  void changeAttribute( const QString &field, const QVariant &value, const QString &hintText = QString() );
288 
294  void setFeature( const QgsFeature &feature );
295 
301  bool save();
302 
312  bool saveWithDetails( QString *error SIP_OUT = nullptr );
313 
317  void resetValues();
318 
323  void resetSearch();
324 
328  void refreshFeature();
329 
339  void parentFormValueChanged( const QString &attribute, const QVariant &newValue );
340 
345  bool needsGeometry() const;
346 
347  private slots:
348  void onAttributeChanged( const QVariant &value, const QVariantList &additionalFieldValues );
349  void onAttributeAdded( int idx );
350  void onAttributeDeleted( int idx );
351  void onRelatedFeaturesChanged();
352  void onUpdatedFields();
353  void onConstraintStatusChanged( const QString &constraint,
354  const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result );
355  void preventFeatureRefresh();
356  void synchronizeState();
357  void layerSelectionChanged();
358 
360  bool saveMultiEdits();
361  void resetMultiEdit( bool promptToSave = false );
362  void multiEditMessageClicked( const QString &link );
363 
364  void filterAndTriggered();
365  void filterOrTriggered();
366  void filterTriggered();
367 
368  void searchZoomTo();
369  void searchFlash();
370  void searchSetSelection();
371  void searchAddToSelection();
372  void searchRemoveFromSelection();
373  void searchIntersectSelection();
374 
375  private:
376  void init();
377 
378  void cleanPython();
379 
380  void initPython();
381 
382  void updateJoinedFields( const QgsEditorWidgetWrapper &eww );
383 
384  bool fieldIsEditable( int fieldIndex ) const;
385 
386  bool fieldIsEditable( const QgsVectorLayer &layer, int fieldIndex, QgsFeatureId fid ) const;
387 
388  void updateFieldDependencies();
389  void updateFieldDependenciesDefaultValue( QgsEditorWidgetWrapper *eww );
390  void updateFieldDependenciesVirtualFields( QgsEditorWidgetWrapper *eww );
391  void updateRelatedLayerFieldsDependencies( QgsEditorWidgetWrapper *eww = nullptr );
392 
393  void setMultiEditFeatureIdsRelations( const QgsFeatureIds &fids );
394 
395  struct WidgetInfo
396  {
397  QWidget *widget = nullptr;
398  QString labelText;
399  QString toolTip;
400  QString hint;
401  bool labelOnTop = false;
402  bool labelAlignRight = false;
403  bool showLabel = true;
405  };
406 
407  WidgetInfo createWidgetFromDef( const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributeEditorContext &context );
408 
409  void addWidgetWrapper( QgsEditorWidgetWrapper *eww );
410 
415  void createWrappers();
416  void afterWidgetInit();
417 
418  void scanForEqualAttributes( QgsFeatureIterator &fit, QSet< int > &mixedValueFields, QHash< int, QVariant > &fieldSharedValues ) const;
419 
421  bool saveEdits( QString *error );
422 
423  QgsFeature getUpdatedFeature() const;
424 
426  void updateValuesDependencies( const int originIdx );
427  void updateValuesDependenciesDefaultValues( const int originIdx );
428  void updateValuesDependenciesVirtualFields( const int originIdx );
429  void updateRelatedLayerFields();
430 
431  void clearMultiEditMessages();
432  void pushSelectedFeaturesMessage();
433  void runSearchSelect( Qgis::SelectBehavior behavior );
434 
435  QString createFilterExpression() const;
436 
437  QgsExpressionContext createExpressionContext( const QgsFeature &feature ) const;
438 
440  void updateAllConstraints();
441  void updateConstraints( QgsEditorWidgetWrapper *w );
442  void updateContainersVisibility();
443  void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
444  void updateLabels();
445  bool currentFormValuesFeature( QgsFeature &feature );
446  bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
447  bool currentFormValidHardConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
448  QList<QgsEditorWidgetWrapper *> constraintDependencies( QgsEditorWidgetWrapper *w );
449 
450  Q_DECL_DEPRECATED QgsRelationWidgetWrapper *setupRelationWidgetWrapper( const QgsRelation &rel, const QgsAttributeEditorContext &context ) SIP_DEPRECATED;
451  QgsRelationWidgetWrapper *setupRelationWidgetWrapper( const QString &relationWidgetTypeId, const QgsRelation &rel, const QgsAttributeEditorContext &context );
452 
453  QgsVectorLayer *mLayer = nullptr;
454  QgsFeature mFeature;
455  QgsFeature mCurrentFormFeature;
456  QgsMessageBar *mMessageBar = nullptr;
457  bool mOwnsMessageBar;
458  QgsMessageBarItem *mMultiEditUnsavedMessageBarItem = nullptr;
459  QgsMessageBarItem *mMultiEditMessageBarItem = nullptr;
460  QList<QgsWidgetWrapper *> mWidgets;
461  QgsAttributeEditorContext mContext;
462  std::unique_ptr<QgsExpressionContextScope> mExtraContextScope;
463  QDialogButtonBox *mButtonBox = nullptr;
464  QWidget *mSearchButtonBox = nullptr;
465  QList<QgsAttributeFormInterface *> mInterfaces;
466  QMap< int, QgsAttributeFormEditorWidget * > mFormEditorWidgets;
467  QList< QgsAttributeFormWidget *> mFormWidgets;
468  QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
469  QMap<QLabel *, QgsProperty> mLabelDataDefinedProperties;
470  bool mValuesInitialized = false;
471  bool mDirty = false;
472  bool mIsSettingFeature = false;
473 
474  bool mValidConstraints = true;
475  QgsMessageBarItem *mConstraintsFailMessageBarItem = nullptr;
476 
477  struct ContainerInformation
478  {
479  ContainerInformation( QgsTabWidget *tabWidget, QWidget *widget, const QgsExpression &expression )
480  : tabWidget( tabWidget )
481  , widget( widget )
482  , expression( expression )
483  , isVisible( true )
484  {}
485 
486  ContainerInformation( QWidget *widget, const QgsExpression &expression )
487  : widget( widget )
488  , expression( expression )
489  , isVisible( true )
490  {}
491 
492  ContainerInformation( QWidget *widget, const QgsExpression &visibilityExpression, bool collapsed, const QgsExpression &collapsedExpression )
493  : widget( widget )
494  , expression( visibilityExpression )
495  , isVisible( true )
496  , isCollapsed( collapsed )
497  , collapsedExpression( collapsedExpression )
498  {}
499 
500 
501  QgsTabWidget *tabWidget = nullptr;
502  QWidget *widget = nullptr;
503  QgsExpression expression;
504  bool isVisible;
505  bool isCollapsed = false;
506  QgsExpression collapsedExpression;
507 
508  void apply( QgsExpressionContext *expressionContext );
509  };
510 
511  void registerContainerInformation( ContainerInformation *info );
512 
513  void updateIcon( QgsEditorWidgetWrapper *eww );
514 
515  void reloadIcon( const QString &file, const QString &tooltip, QSvgWidget *sw );
516 
517  // Contains information about tabs and groupboxes, their visibility/collapsed state conditions
518  QVector<ContainerInformation *> mContainerVisibilityCollapsedInformation;
519  QMap<QString, QVector<ContainerInformation *> > mContainerInformationDependency;
520 
521  // Variables below are used for Python
522  static int sFormCounter;
523  int mFormNr;
524  QString mPyFormVarName;
525 
527  bool mIsSaving;
528 
530  bool mPreventFeatureRefresh;
531 
532  bool mIsSettingMultiEditFeatures;
533 
534  QgsFeatureIds mMultiEditFeatureIds;
535  bool mUnsavedMultiEditChanges;
536 
537  QString mEditCommandMessage;
538 
540 
541  QMap<QWidget *, QSvgWidget *> mIconMap;
542 
547  QMap<int, QgsWidgetWrapper *> mDefaultValueDependencies;
548 
553  QMap<int, QgsWidgetWrapper *> mVirtualFieldsDependencies;
554 
558  QSet<QgsEditorWidgetWrapper *> mRelatedLayerFieldsDependencies;
559 
561  QList<int> mAlreadyUpdatedFields;
562 
563  bool mNeedsGeometry = false;
564 
565  friend class TestQgsDualView;
566  friend class TestQgsAttributeForm;
567 };
568 
569 #endif // QGSATTRIBUTEFORM_H
SelectBehavior
Specifies how a selection should be applied.
Definition: qgis.h:778
This class contains context information for attribute editor widgets.
This is an abstract base class for any elements of a drag and drop form.
A widget consisting of both an editor widget and additional widgets for controlling the behavior of t...
Base class for all widgets shown on a QgsAttributeForm.
void beforeSave(bool &ok)
Will be emitted before the feature is saved.
QgsVectorLayer * layer()
Returns the layer for which this form is shown.
@ SearchMode
Form values are used for searching/filtering the layer.
@ MultiEditMode
Multi edit mode, for editing fields of multiple features at once.
@ AggregateSearchMode
Form is in aggregate search mode, show each widget in this mode.
@ SingleEditMode
Single edit mode, for editing a single feature.
void filterExpressionSet(const QString &expression, QgsAttributeForm::FilterType type)
Emitted when a filter expression is set using the form.
const QgsFeature & feature()
void closed()
Emitted when the user selects the close option from the form's button bar.
void setEditCommandMessage(const QString &message)
Sets the edit command message (Undo) that will be used when the dialog is accepted.
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
void openFilteredFeaturesAttributeTable(const QString &filter)
Emitted when the user chooses to open the attribute table dialog with a filtered set of features.
void flashFeatures(const QString &filter)
Emitted when the user chooses to flash a filtered set of features.
void modeChanged(QgsAttributeEditorContext::Mode mode)
Emitted when the form changes mode.
void featureSaved(const QgsFeature &feature)
Emitted when a feature is changed or added.
void zoomToFeatures(const QString &filter)
Emitted when the user chooses to zoom to a filtered set of features.
QgsFeature currentFormFeature() const
Returns the feature that is currently displayed in the form with all the changes received on editing ...
Q_DECL_DEPRECATED void attributeChanged(const QString &attribute, const QVariant &value)
Notifies about changes of attributes, this signal is not emitted when the value is set back to the or...
FilterType
Filter types.
@ ReplaceFilter
Filter should replace any existing filter.
@ FilterOr
Filter should be combined using "OR".
@ FilterAnd
Filter should be combined using "AND".
QgsAttributeEditorContext::Mode mode() const
Returns the current mode of the form.
Manages an editor widget Widget and wrapper share the same parent.
ConstraintResult
Result of constraint checks.
Single scope for storing variables and functions for use within a QgsExpressionContext.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Represents an item shown within a QgsMessageBar widget.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
The QgsTabWidget class is the same as the QTabWidget but with additional methods to temporarily hide/...
Definition: qgstabwidget.h:33
Represents a vector layer which manages a vector based data sets.
Manages an editor widget Widget and wrapper share the same parent.
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_TRANSFERTHIS
Definition: qgis_sip.h:53
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_OUT
Definition: qgis_sip.h:58
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
const QgsField & field
Definition: qgsfield.h:463
The TabStyle struct defines color and font overrides for form fields, tabs and groups labels.