QGIS API Documentation  2.99.0-Master (9caa722)
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 <QSvgWidget>
26 #include <QLabel>
27 #include <QDialogButtonBox>
28 #include "qgis_gui.h"
29 
30 
33 class QgsMessageBar;
34 class QgsMessageBarItem;
35 class QgsWidgetWrapper;
36 class QgsTabWidget;
37 
41 class GUI_EXPORT QgsAttributeForm : public QWidget
42 {
43  Q_OBJECT
44 
45  public:
46 
48  enum Mode
49  {
51  AddFeatureMode,
55  };
56 
59  {
63  };
64 
65  explicit QgsAttributeForm( QgsVectorLayer *vl,
66  const QgsFeature &feature = QgsFeature(),
68  QWidget *parent SIP_TRANSFERTHIS = nullptr );
70 
71  const QgsFeature &feature() { return mFeature; }
72 
77  // TODO QGIS 3.0 - make private
78  void hideButtonBox();
79 
84  // TODO QGIS 3.0 - make private
85  void showButtonBox();
86 
91  // TODO QGIS 3.0 - make private
92  void disconnectButtonBox();
93 
98  void addInterface( QgsAttributeFormInterface *iface SIP_TRANSFER );
99 
105  QgsVectorLayer *layer() { return mLayer; }
106 
112  bool editable();
113 
118  Mode mode() const { return mMode; }
119 
125  void setMode( Mode mode );
126 
132  void setEditCommandMessage( const QString &message ) { mEditCommandMessage = message; }
133 
142  bool eventFilter( QObject *object, QEvent *event ) override;
143 
148  void setMultiEditFeatureIds( const QgsFeatureIds &fids );
149 
155  void setMessageBar( QgsMessageBar *messageBar );
156 
157  signals:
158 
165  void attributeChanged( const QString &attribute, const QVariant &value );
166 
175  void beforeSave( bool &ok ) SIP_SKIP;
176 
180  void featureSaved( const QgsFeature &feature );
181 
187  void filterExpressionSet( const QString &expression, QgsAttributeForm::FilterType type );
188 
192  void modeChanged( QgsAttributeForm::Mode mode );
193 
197  void closed();
198 
203  void zoomToFeatures( const QString &filter );
204 
205  public slots:
206 
214  void changeAttribute( const QString &field, const QVariant &value, const QString &hintText = QString() );
215 
221  void setFeature( const QgsFeature &feature );
222 
228  bool save();
229 
233  void resetValues();
234 
238  void resetSearch();
239 
243  void refreshFeature();
244 
245  private slots:
246  void onAttributeChanged( const QVariant &value );
247  void onAttributeAdded( int idx );
248  void onAttributeDeleted( int idx );
249  void onUpdatedFields();
250  void onConstraintStatusChanged( const QString &constraint,
251  const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result );
252  void preventFeatureRefresh();
253  void synchronizeEnabledState();
254  void layerSelectionChanged();
255 
257  bool saveMultiEdits();
258  void resetMultiEdit( bool promptToSave = false );
259  void multiEditMessageClicked( const QString &link );
260 
261  void filterAndTriggered();
262  void filterOrTriggered();
263  void filterTriggered();
264 
265  void searchZoomTo();
266  void searchSetSelection();
267  void searchAddToSelection();
268  void searchRemoveFromSelection();
269  void searchIntersectSelection();
270 
271  private:
272  void init();
273 
274  void cleanPython();
275 
276  void initPython();
277 
278  void updateJoinedFields( const QgsEditorWidgetWrapper &eww );
279 
280  bool fieldIsEditable( int fieldIndex ) const;
281 
282  bool fieldIsEditable( const QgsVectorLayer &layer, int fieldIndex, QgsFeatureId fid ) const ;
283 
284  struct WidgetInfo
285  {
286  WidgetInfo()
287  : widget( nullptr )
288  , labelOnTop( false )
289  , labelAlignRight( false )
290  , showLabel( true )
291  {}
292 
293  QWidget *widget = nullptr;
294  QString labelText;
295  bool labelOnTop;
296  bool labelAlignRight;
297  bool showLabel;
298  };
299 
300  WidgetInfo createWidgetFromDef( const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributeEditorContext &context );
301 
302  void addWidgetWrapper( QgsEditorWidgetWrapper *eww );
303 
308  void createWrappers();
309  void afterWidgetInit();
310 
311  void scanForEqualAttributes( QgsFeatureIterator &fit, QSet< int > &mixedValueFields, QHash< int, QVariant > &fieldSharedValues ) const;
312 
314  bool saveEdits();
315 
316  int messageTimeout();
317  void clearMultiEditMessages();
318  void pushSelectedFeaturesMessage();
319  void runSearchSelect( QgsVectorLayer::SelectBehavior behavior );
320 
321  QString createFilterExpression() const;
322 
324  void updateAllConstraints();
325  void updateConstraints( QgsEditorWidgetWrapper *w );
326  void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
327  bool currentFormFeature( QgsFeature &feature );
328  bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
329  QList<QgsEditorWidgetWrapper *> constraintDependencies( QgsEditorWidgetWrapper *w );
330  void clearInvalidConstraintsMessage();
331  void displayInvalidConstraintMessage( const QStringList &invalidFields,
332  const QStringList &description );
333 
334  QgsVectorLayer *mLayer = nullptr;
335  QgsFeature mFeature;
336  QgsMessageBar *mMessageBar = nullptr;
337  bool mOwnsMessageBar;
338  QgsMessageBarItem *mMultiEditUnsavedMessageBarItem = nullptr;
339  QgsMessageBarItem *mMultiEditMessageBarItem = nullptr;
340  QLabel *mInvalidConstraintMessage = nullptr;
341  QWidget *mTopMessageWidget = nullptr;
342  QList<QgsWidgetWrapper *> mWidgets;
343  QgsAttributeEditorContext mContext;
344  QDialogButtonBox *mButtonBox = nullptr;
345  QWidget *mSearchButtonBox = nullptr;
346  QList<QgsAttributeFormInterface *> mInterfaces;
347  QMap< int, QgsAttributeFormEditorWidget * > mFormEditorWidgets;
348  QgsExpressionContext mExpressionContext;
349  QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
350 
351  struct ContainerInformation
352  {
353  ContainerInformation( QgsTabWidget *tabWidget, QWidget *widget, const QgsExpression &expression )
354  : tabWidget( tabWidget )
355  , widget( widget )
356  , expression( expression )
357  , isVisible( true )
358  {}
359 
360  ContainerInformation( QWidget *widget, const QgsExpression &expression )
361  : tabWidget( nullptr )
362  , widget( widget )
363  , expression( expression )
364  , isVisible( true )
365  {}
366 
367  QgsTabWidget *tabWidget = nullptr;
368  QWidget *widget = nullptr;
369  QgsExpression expression;
370  bool isVisible;
371 
372  void apply( QgsExpressionContext *expressionContext );
373  };
374 
375  void registerContainerInformation( ContainerInformation *info );
376 
377  void updateIcon( QgsEditorWidgetWrapper *eww );
378 
379  void reloadIcon( const QString &file, const QString &tooltip, QSvgWidget *sw );
380 
381  // Contains information about tabs and groupboxes, their visibility state visibility conditions
382  QVector<ContainerInformation *> mContainerVisibilityInformation;
383  QMap<QString, QVector<ContainerInformation *> > mContainerInformationDependency;
384 
385  // Variables below are used for Python
386  static int sFormCounter;
387  int mFormNr;
388  QString mPyFormVarName;
389 
391  bool mIsSaving;
392 
394  bool mPreventFeatureRefresh;
395 
397  bool mIsSettingFeature;
398  bool mIsSettingMultiEditFeatures;
399 
400  QgsFeatureIds mMultiEditFeatureIds;
401  bool mUnsavedMultiEditChanges;
402 
403  QString mEditCommandMessage;
404 
405  Mode mMode;
406 
408  QMap<QWidget *, QLabel *> mBuddyMap;
409  QMap<QWidget *, QSvgWidget *> mIconMap;
410 
411  friend class TestQgsDualView;
412  friend class TestQgsAttributeForm;
413 };
414 
415 #endif // QGSATTRIBUTEFORM_H
416 
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.
qint64 QgsFeatureId
Definition: qgsfeature.h:37
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.