QGIS API Documentation  2.99.0-Master (a411669)
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 
42 class GUI_EXPORT QgsAttributeForm : public QWidget
43 {
44  Q_OBJECT
45 
46  public:
47 
49  enum Mode
50  {
52  AddFeatureMode,
56  };
57 
60  {
64  };
65 
66  explicit QgsAttributeForm( QgsVectorLayer *vl,
67  const QgsFeature &feature = QgsFeature(),
69  QWidget *parent SIP_TRANSFERTHIS = nullptr );
71 
72  const QgsFeature &feature() { return mFeature; }
73 
78  // TODO QGIS 3.0 - make private
79  void hideButtonBox();
80 
85  // TODO QGIS 3.0 - make private
86  void showButtonBox();
87 
92  // TODO QGIS 3.0 - make private
93  void disconnectButtonBox();
94 
99  void addInterface( QgsAttributeFormInterface *iface SIP_TRANSFER );
100 
106  QgsVectorLayer *layer() { return mLayer; }
107 
113  bool editable();
114 
120  Mode mode() const { return mMode; }
121 
128  void setMode( Mode mode );
129 
135  void setEditCommandMessage( const QString &message ) { mEditCommandMessage = message; }
136 
145  bool eventFilter( QObject *object, QEvent *event ) override;
146 
152  void setMultiEditFeatureIds( const QgsFeatureIds &fids );
153 
160  void setMessageBar( QgsMessageBar *messageBar );
161 
162  signals:
163 
170  void attributeChanged( const QString &attribute, const QVariant &value );
171 
180  void beforeSave( bool &ok ) SIP_SKIP;
181 
185  void featureSaved( const QgsFeature &feature );
186 
193  void filterExpressionSet( const QString &expression, QgsAttributeForm::FilterType type );
194 
199  void modeChanged( QgsAttributeForm::Mode mode );
200 
205  void closed();
206 
211  void zoomToFeatures( const QString &filter );
212 
217  void flashFeatures( const QString &filter );
218 
219  public slots:
220 
228  void changeAttribute( const QString &field, const QVariant &value, const QString &hintText = QString() );
229 
235  void setFeature( const QgsFeature &feature );
236 
242  bool save();
243 
247  void resetValues();
248 
253  void resetSearch();
254 
258  void refreshFeature();
259 
260  private slots:
261  void onAttributeChanged( const QVariant &value );
262  void onAttributeAdded( int idx );
263  void onAttributeDeleted( int idx );
264  void onUpdatedFields();
265  void onConstraintStatusChanged( const QString &constraint,
266  const QString &description, const QString &err, QgsEditorWidgetWrapper::ConstraintResult result );
267  void preventFeatureRefresh();
268  void synchronizeEnabledState();
269  void layerSelectionChanged();
270 
272  bool saveMultiEdits();
273  void resetMultiEdit( bool promptToSave = false );
274  void multiEditMessageClicked( const QString &link );
275 
276  void filterAndTriggered();
277  void filterOrTriggered();
278  void filterTriggered();
279 
280  void searchZoomTo();
281  void searchFlash();
282  void searchSetSelection();
283  void searchAddToSelection();
284  void searchRemoveFromSelection();
285  void searchIntersectSelection();
286 
287  private:
288  void init();
289 
290  void cleanPython();
291 
292  void initPython();
293 
294  void updateJoinedFields( const QgsEditorWidgetWrapper &eww );
295 
296  bool fieldIsEditable( int fieldIndex ) const;
297 
298  bool fieldIsEditable( const QgsVectorLayer &layer, int fieldIndex, QgsFeatureId fid ) const;
299 
300  struct WidgetInfo
301  {
302  WidgetInfo()
303  {}
304 
305  QWidget *widget = nullptr;
306  QString labelText;
307  bool labelOnTop = false;
308  bool labelAlignRight = false;
309  bool showLabel = true;
310  };
311 
312  WidgetInfo createWidgetFromDef( const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributeEditorContext &context );
313 
314  void addWidgetWrapper( QgsEditorWidgetWrapper *eww );
315 
320  void createWrappers();
321  void afterWidgetInit();
322 
323  void scanForEqualAttributes( QgsFeatureIterator &fit, QSet< int > &mixedValueFields, QHash< int, QVariant > &fieldSharedValues ) const;
324 
326  bool saveEdits();
327 
328  int messageTimeout();
329  void clearMultiEditMessages();
330  void pushSelectedFeaturesMessage();
331  void runSearchSelect( QgsVectorLayer::SelectBehavior behavior );
332 
333  QString createFilterExpression() const;
334 
336  void updateAllConstraints();
337  void updateConstraints( QgsEditorWidgetWrapper *w );
338  void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
339  bool currentFormFeature( QgsFeature &feature );
340  bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
341  QList<QgsEditorWidgetWrapper *> constraintDependencies( QgsEditorWidgetWrapper *w );
342  void clearInvalidConstraintsMessage();
343  void displayInvalidConstraintMessage( const QStringList &invalidFields,
344  const QStringList &description );
345 
346  QgsVectorLayer *mLayer = nullptr;
347  QgsFeature mFeature;
348  QgsMessageBar *mMessageBar = nullptr;
349  bool mOwnsMessageBar;
350  QgsMessageBarItem *mMultiEditUnsavedMessageBarItem = nullptr;
351  QgsMessageBarItem *mMultiEditMessageBarItem = nullptr;
352  QLabel *mInvalidConstraintMessage = nullptr;
353  QWidget *mTopMessageWidget = nullptr;
354  QList<QgsWidgetWrapper *> mWidgets;
355  QgsAttributeEditorContext mContext;
356  QDialogButtonBox *mButtonBox = nullptr;
357  QWidget *mSearchButtonBox = nullptr;
358  QList<QgsAttributeFormInterface *> mInterfaces;
359  QMap< int, QgsAttributeFormEditorWidget * > mFormEditorWidgets;
360  QgsExpressionContext mExpressionContext;
361  QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
362 
363  struct ContainerInformation
364  {
365  ContainerInformation( QgsTabWidget *tabWidget, QWidget *widget, const QgsExpression &expression )
366  : tabWidget( tabWidget )
367  , widget( widget )
368  , expression( expression )
369  , isVisible( true )
370  {}
371 
372  ContainerInformation( QWidget *widget, const QgsExpression &expression )
373  : widget( widget )
374  , expression( expression )
375  , isVisible( true )
376  {}
377 
378  QgsTabWidget *tabWidget = nullptr;
379  QWidget *widget = nullptr;
380  QgsExpression expression;
381  bool isVisible;
382 
383  void apply( QgsExpressionContext *expressionContext );
384  };
385 
386  void registerContainerInformation( ContainerInformation *info );
387 
388  void updateIcon( QgsEditorWidgetWrapper *eww );
389 
390  void reloadIcon( const QString &file, const QString &tooltip, QSvgWidget *sw );
391 
392  // Contains information about tabs and groupboxes, their visibility state visibility conditions
393  QVector<ContainerInformation *> mContainerVisibilityInformation;
394  QMap<QString, QVector<ContainerInformation *> > mContainerInformationDependency;
395 
396  // Variables below are used for Python
397  static int sFormCounter;
398  int mFormNr;
399  QString mPyFormVarName;
400 
402  bool mIsSaving;
403 
405  bool mPreventFeatureRefresh;
406 
408  bool mIsSettingFeature;
409  bool mIsSettingMultiEditFeatures;
410 
411  QgsFeatureIds mMultiEditFeatureIds;
412  bool mUnsavedMultiEditChanges;
413 
414  QString mEditCommandMessage;
415 
416  Mode mMode;
417 
419  QMap<QWidget *, QLabel *> mBuddyMap;
420  QMap<QWidget *, QSvgWidget *> mIconMap;
421 
422  friend class TestQgsDualView;
423  friend class TestQgsAttributeForm;
424 };
425 
426 #endif // QGSATTRIBUTEFORM_H
427 
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:544
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:45
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
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:29
Manages an editor widget Widget and wrapper share the same parent.