QGIS API Documentation  2.99.0-Master (23ddace)
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.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;
36 
40 class GUI_EXPORT QgsAttributeForm : public QWidget
41 {
42  Q_OBJECT
43 
44  public:
45 
47  enum Mode
48  {
50  AddFeatureMode,
54  };
55 
58  {
62  };
63 
64  explicit QgsAttributeForm( QgsVectorLayer *vl,
65  const QgsFeature &feature = QgsFeature(),
67  QWidget *parent SIP_TRANSFERTHIS = nullptr );
69 
70  const QgsFeature &feature() { return mFeature; }
71 
76  // TODO QGIS 3.0 - make private
77  void hideButtonBox();
78 
83  // TODO QGIS 3.0 - make private
84  void showButtonBox();
85 
90  // TODO QGIS 3.0 - make private
91  void disconnectButtonBox();
92 
97  void addInterface( QgsAttributeFormInterface *iface SIP_TRANSFER );
98 
104  QgsVectorLayer *layer() { return mLayer; }
105 
111  bool editable();
112 
117  Mode mode() const { return mMode; }
118 
124  void setMode( Mode mode );
125 
131  void setEditCommandMessage( const QString &message ) { mEditCommandMessage = message; }
132 
141  bool eventFilter( QObject *object, QEvent *event ) override;
142 
147  void setMultiEditFeatureIds( const QgsFeatureIds &fids );
148 
154  void setMessageBar( QgsMessageBar *messageBar );
155 
156  signals:
157 
164  void attributeChanged( const QString &attribute, const QVariant &value );
165 
174  void beforeSave( bool &ok ) SIP_SKIP;
175 
179  void featureSaved( const QgsFeature &feature );
180 
186  void filterExpressionSet( const QString &expression, QgsAttributeForm::FilterType type );
187 
191  void modeChanged( QgsAttributeForm::Mode mode );
192 
196  void closed();
197 
202  void zoomToFeatures( const QString &filter );
203 
204  public slots:
205 
212  void changeAttribute( const QString &field, const QVariant &value );
213 
219  void setFeature( const QgsFeature &feature );
220 
226  bool save();
227 
231  void resetValues();
232 
236  void resetSearch();
237 
241  void refreshFeature();
242 
243  private slots:
244  void onAttributeChanged( const QVariant &value );
245  void onAttributeAdded( int idx );
246  void onAttributeDeleted( int idx );
247  void onUpdatedFields();
248  void onConstraintStatusChanged( const QString &constraint,
249  const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result );
250  void preventFeatureRefresh();
251  void synchronizeEnabledState();
252  void layerSelectionChanged();
253 
255  bool saveMultiEdits();
256  void resetMultiEdit( bool promptToSave = false );
257  void multiEditMessageClicked( const QString &link );
258 
259  void filterAndTriggered();
260  void filterOrTriggered();
261  void filterTriggered();
262 
263  void searchZoomTo();
264  void searchSetSelection();
265  void searchAddToSelection();
266  void searchRemoveFromSelection();
267  void searchIntersectSelection();
268 
269  private:
270  void init();
271 
272  void cleanPython();
273 
274  void initPython();
275 
276  struct WidgetInfo
277  {
278  WidgetInfo()
279  : widget( nullptr )
280  , labelOnTop( false )
281  , labelAlignRight( false )
282  , showLabel( true )
283  {}
284 
285  QWidget *widget = nullptr;
286  QString labelText;
287  bool labelOnTop;
288  bool labelAlignRight;
289  bool showLabel;
290  };
291 
292  WidgetInfo createWidgetFromDef( const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributeEditorContext &context );
293 
294  void addWidgetWrapper( QgsEditorWidgetWrapper *eww );
295 
300  void createWrappers();
301  void afterWidgetInit();
302 
303  void scanForEqualAttributes( QgsFeatureIterator &fit, QSet< int > &mixedValueFields, QHash< int, QVariant > &fieldSharedValues ) const;
304 
306  bool saveEdits();
307 
308  int messageTimeout();
309  void clearMultiEditMessages();
310  void pushSelectedFeaturesMessage();
311  void runSearchSelect( QgsVectorLayer::SelectBehavior behavior );
312 
313  QString createFilterExpression() const;
314 
316  void updateAllConstraints();
317  void updateConstraints( QgsEditorWidgetWrapper *w );
318  bool currentFormFeature( QgsFeature &feature );
319  bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
320  QList<QgsEditorWidgetWrapper *> constraintDependencies( QgsEditorWidgetWrapper *w );
321  void clearInvalidConstraintsMessage();
322  void displayInvalidConstraintMessage( const QStringList &invalidFields,
323  const QStringList &description );
324 
325  QgsVectorLayer *mLayer = nullptr;
326  QgsFeature mFeature;
327  QgsMessageBar *mMessageBar = nullptr;
328  bool mOwnsMessageBar;
329  QgsMessageBarItem *mMultiEditUnsavedMessageBarItem = nullptr;
330  QgsMessageBarItem *mMultiEditMessageBarItem = nullptr;
331  QLabel *mInvalidConstraintMessage = nullptr;
332  QWidget *mTopMessageWidget = nullptr;
333  QList<QgsWidgetWrapper *> mWidgets;
334  QgsAttributeEditorContext mContext;
335  QDialogButtonBox *mButtonBox = nullptr;
336  QWidget *mSearchButtonBox = nullptr;
337  QList<QgsAttributeFormInterface *> mInterfaces;
338  QMap< int, QgsAttributeFormEditorWidget * > mFormEditorWidgets;
339  QgsExpressionContext mExpressionContext;
340 
341  struct ContainerInformation
342  {
343  ContainerInformation( QgsTabWidget *tabWidget, QWidget *widget, const QgsExpression &expression )
344  : tabWidget( tabWidget )
345  , widget( widget )
346  , expression( expression )
347  , isVisible( true )
348  {}
349 
350  ContainerInformation( QWidget *widget, const QgsExpression &expression )
351  : tabWidget( nullptr )
352  , widget( widget )
353  , expression( expression )
354  , isVisible( true )
355  {}
356 
357  QgsTabWidget *tabWidget = nullptr;
358  QWidget *widget = nullptr;
359  QgsExpression expression;
360  bool isVisible;
361 
362  void apply( QgsExpressionContext *expressionContext );
363  };
364 
365  void registerContainerInformation( ContainerInformation *info );
366 
367  // Contains information about tabs and groupboxes, their visibility state visibility conditions
368  QVector<ContainerInformation *> mContainerVisibilityInformation;
369  QMap<QString, QVector<ContainerInformation *> > mContainerInformationDependency;
370 
371  // Variables below are used for Python
372  static int sFormCounter;
373  int mFormNr;
374  QString mPyFormVarName;
375 
377  bool mIsSaving;
378 
380  bool mPreventFeatureRefresh;
381 
383  bool mIsSettingFeature;
384  bool mIsSettingMultiEditFeatures;
385 
386  QgsFeatureIds mMultiEditFeatureIds;
387  bool mUnsavedMultiEditChanges;
388 
389  QString mEditCommandMessage;
390 
391  Mode mMode;
392 
394  QMap<QWidget *, QLabel *> mBuddyMap;
395 
396  friend class TestQgsDualView;
397  friend class TestQgsAttributeForm;
398 };
399 
400 #endif // QGSATTRIBUTEFORM_H
401 
Wrapper for iterator of features from vector data provider or vector layer.
This is an abstract base class for any elements of a drag and drop form.
#define SIP_TRANSFERTHIS
Definition: qgis_sip.h:34
Multi edit mode, for editing fields of multiple features at once.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:519
This class contains context information for attribute editor widgets.
Manages an editor widget Widget and wrapper share the same parent.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:44
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:61
QgsVectorLayer * layer()
Returns the layer for which this form is shown.
A widget consisting of both an editor widget and additional widgets for controlling the behavior of t...
FilterType
Filter types.
#define SIP_SKIP
Definition: qgis_sip.h:107
Form values are used for searching/filtering the layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
#define SIP_TRANSFER
Definition: qgis_sip.h:24
Filter should be combined using "AND".
void setEditCommandMessage(const QString &message)
Sets the edit command message (Undo) that will be used when the dialog is accepted.
SelectBehavior
Selection behavior.
ConstraintResult
Result of constraint checks.
Filter should be combined using "OR".
Mode mode() const
Returns the current mode of the form.
const QgsFeature & feature()
Single edit mode, for editing a single feature.
Filter should replace any existing filter.
Represents a vector layer which manages a vector based data sets.
The QgsTabWidget class is the same as the QTabWidget but with additional methods to temporarily hide/...
Definition: qgstabwidget.h:28
Manages an editor widget Widget and wrapper share the same parent.