QGIS API Documentation  2.99.0-Master (7d4f81d)
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 
213  void changeAttribute( const QString &field, const QVariant &value, const QString &hintText = QString() );
214 
220  void setFeature( const QgsFeature &feature );
221 
227  bool save();
228 
232  void resetValues();
233 
237  void resetSearch();
238 
242  void refreshFeature();
243 
244  private slots:
245  void onAttributeChanged( const QVariant &value );
246  void onAttributeAdded( int idx );
247  void onAttributeDeleted( int idx );
248  void onUpdatedFields();
249  void onConstraintStatusChanged( const QString &constraint,
250  const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result );
251  void preventFeatureRefresh();
252  void synchronizeEnabledState();
253  void layerSelectionChanged();
254 
256  bool saveMultiEdits();
257  void resetMultiEdit( bool promptToSave = false );
258  void multiEditMessageClicked( const QString &link );
259 
260  void filterAndTriggered();
261  void filterOrTriggered();
262  void filterTriggered();
263 
264  void searchZoomTo();
265  void searchSetSelection();
266  void searchAddToSelection();
267  void searchRemoveFromSelection();
268  void searchIntersectSelection();
269 
270  private:
271  void init();
272 
273  void cleanPython();
274 
275  void initPython();
276 
277  void updateJoinedFields( const QgsEditorWidgetWrapper &eww );
278 
279  struct WidgetInfo
280  {
281  WidgetInfo()
282  : widget( nullptr )
283  , labelOnTop( false )
284  , labelAlignRight( false )
285  , showLabel( true )
286  {}
287 
288  QWidget *widget = nullptr;
289  QString labelText;
290  bool labelOnTop;
291  bool labelAlignRight;
292  bool showLabel;
293  };
294 
295  WidgetInfo createWidgetFromDef( const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributeEditorContext &context );
296 
297  void addWidgetWrapper( QgsEditorWidgetWrapper *eww );
298 
303  void createWrappers();
304  void afterWidgetInit();
305 
306  void scanForEqualAttributes( QgsFeatureIterator &fit, QSet< int > &mixedValueFields, QHash< int, QVariant > &fieldSharedValues ) const;
307 
309  bool saveEdits();
310 
311  int messageTimeout();
312  void clearMultiEditMessages();
313  void pushSelectedFeaturesMessage();
314  void runSearchSelect( QgsVectorLayer::SelectBehavior behavior );
315 
316  QString createFilterExpression() const;
317 
319  void updateAllConstraints();
320  void updateConstraints( QgsEditorWidgetWrapper *w );
321  void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
322  bool currentFormFeature( QgsFeature &feature );
323  bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
324  QList<QgsEditorWidgetWrapper *> constraintDependencies( QgsEditorWidgetWrapper *w );
325  void clearInvalidConstraintsMessage();
326  void displayInvalidConstraintMessage( const QStringList &invalidFields,
327  const QStringList &description );
328 
329  QgsVectorLayer *mLayer = nullptr;
330  QgsFeature mFeature;
331  QgsMessageBar *mMessageBar = nullptr;
332  bool mOwnsMessageBar;
333  QgsMessageBarItem *mMultiEditUnsavedMessageBarItem = nullptr;
334  QgsMessageBarItem *mMultiEditMessageBarItem = nullptr;
335  QLabel *mInvalidConstraintMessage = nullptr;
336  QWidget *mTopMessageWidget = nullptr;
337  QList<QgsWidgetWrapper *> mWidgets;
338  QgsAttributeEditorContext mContext;
339  QDialogButtonBox *mButtonBox = nullptr;
340  QWidget *mSearchButtonBox = nullptr;
341  QList<QgsAttributeFormInterface *> mInterfaces;
342  QMap< int, QgsAttributeFormEditorWidget * > mFormEditorWidgets;
343  QgsExpressionContext mExpressionContext;
344  QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
345 
346  struct ContainerInformation
347  {
348  ContainerInformation( QgsTabWidget *tabWidget, QWidget *widget, const QgsExpression &expression )
349  : tabWidget( tabWidget )
350  , widget( widget )
351  , expression( expression )
352  , isVisible( true )
353  {}
354 
355  ContainerInformation( QWidget *widget, const QgsExpression &expression )
356  : tabWidget( nullptr )
357  , widget( widget )
358  , expression( expression )
359  , isVisible( true )
360  {}
361 
362  QgsTabWidget *tabWidget = nullptr;
363  QWidget *widget = nullptr;
364  QgsExpression expression;
365  bool isVisible;
366 
367  void apply( QgsExpressionContext *expressionContext );
368  };
369 
370  void registerContainerInformation( ContainerInformation *info );
371 
372  // Contains information about tabs and groupboxes, their visibility state visibility conditions
373  QVector<ContainerInformation *> mContainerVisibilityInformation;
374  QMap<QString, QVector<ContainerInformation *> > mContainerInformationDependency;
375 
376  // Variables below are used for Python
377  static int sFormCounter;
378  int mFormNr;
379  QString mPyFormVarName;
380 
382  bool mIsSaving;
383 
385  bool mPreventFeatureRefresh;
386 
388  bool mIsSettingFeature;
389  bool mIsSettingMultiEditFeatures;
390 
391  QgsFeatureIds mMultiEditFeatureIds;
392  bool mUnsavedMultiEditChanges;
393 
394  QString mEditCommandMessage;
395 
396  Mode mMode;
397 
399  QMap<QWidget *, QLabel *> mBuddyMap;
400 
401  friend class TestQgsDualView;
402  friend class TestQgsAttributeForm;
403 };
404 
405 #endif // QGSATTRIBUTEFORM_H
406 
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:46
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:119
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:36
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.