1 /***************************************************************************
2     qgsattributeformwidget.h
3     ---------------------
4     begin                : November 2017
5     copyright            : (C) 2017 by 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 #ifndef QGSATTRIBUTEFORMWIDGET_H
16 #define QGSATTRIBUTEFORMWIDGET_H
17 
18 #include "qgis_sip.h"
19 #include "qgis_gui.h"
20 #include "qgsattributeeditorcontext.h"
21 #include "qgssearchwidgetwrapper.h"
22 
23 #include <QWidget>
24 #include <QVariant>
25 
26 class QgsAttributeForm;
27 class QStackedWidget;
28 class QgsSearchWidgetToolButton;
29 
30 /**
31  * \ingroup gui
32  *
33  * \brief Base class for all widgets shown on a QgsAttributeForm.
34  * Consists of the widget which is visible in edit mode as well as the widget visible in search mode.
35  *
36  * \since QGIS 3.0
37  */
38 class GUI_EXPORT QgsAttributeFormWidget : public QWidget // SIP_ABSTRACT
39 {
40     Q_OBJECT
41 
42   public:
43 
44     //! Widget modes
45     enum Mode
46     {
47       DefaultMode, //!< Default mode, only the editor widget is shown
48       MultiEditMode, //!< Multi edit mode, both the editor widget and a QgsMultiEditToolButton is shown
49       SearchMode, //!< Layer search/filter mode
50       AggregateSearchMode, //!< Embedded in a search form, show additional aggregate function toolbutton
51     };
52 
53     /**
54      * A new form widget for the wrapper \a widget on \a form.
55      */
56     explicit QgsAttributeFormWidget( QgsWidgetWrapper *widget, QgsAttributeForm *form );
57 
58     /**
59      * Creates the search widget wrappers for the widget used when the form is in
60      * search mode.
61      *
62      * \param context editor context (not available in Python bindings)
63      */
64     virtual void createSearchWidgetWrappers( const QgsAttributeEditorContext &context SIP_PYARGREMOVE = QgsAttributeEditorContext() ) = 0;
65 
66     /**
67      * Creates an expression matching the current search filter value and
68      * search properties represented in the widget.
69      * \since QGIS 2.16
70      */
71     virtual QString currentFilterExpression() const;
72 
73 
74     /**
75      * Sets the current mode for the widget. The widget will adapt its state and visible widgets to
76      * reflect the updated mode. For example, showing multi edit tool buttons if the mode is set to MultiEditMode.
77      * \param mode widget mode
78      * \see mode()
79      */
80     void setMode( Mode mode );
81 
82     /**
83      * Returns the current mode for the widget.
84      * \see setMode()
85      */
mode()86     Mode mode() const { return mMode; }
87 
88     /**
89      * The layer for which this widget and its form is shown.
90      */
91     QgsVectorLayer *layer();
92 
93     /**
94      * The form on which this widget is shown.
95      */
96     QgsAttributeForm *form() const;
97 
98     /**
99      * Returns the widget which should be used as a parent during construction
100      * of the search widget wrapper.
101      * \note this method is in place for unit testing only, and is not considered
102      * stable API
103      */
104     QWidget *searchWidgetFrame() SIP_SKIP;
105 
106 
107     /**
108      * Sets the search widget wrapper for the widget used when the form is in
109      * search mode.
110      * \param wrapper search widget wrapper.
111      * \note the search widget wrapper should be created using searchWidgetFrame()
112      * as its parent
113      * \note this method is in place for unit testing only, and is not considered
114      * stable API
115      */
116     void setSearchWidgetWrapper( QgsSearchWidgetWrapper *wrapper );
117 
118     /**
119      * Adds an additional search widget wrapper.
120      * Used to register a secondary search widget as used for "between" searches.
121      */
122     void addAdditionalSearchWidgetWrapper( QgsSearchWidgetWrapper *wrapper );
123 
124     /**
125      * Returns the search widget wrapper used in this widget. The wrapper must
126      * first be created using createSearchWidgetWrapper()
127      * \note this method is in place for unit testing only, and is not considered
128      * stable API
129      */
130     QList< QgsSearchWidgetWrapper * > searchWidgetWrappers();
131 
132     /**
133      * Resets the search/filter value of the widget.
134      */
135     void resetSearch();
136 
137     /**
138      * The visibility of the search widget tool button, that allows (de)activating
139      * this search widgte or defines the comparison operator to use.
140      */
141     bool searchWidgetToolButtonVisible() const;
142 
143     /**
144      * The visibility of the search widget tool button, that allows (de)activating
145      * this search widgte or defines the comparison operator to use.
146      */
147     void setSearchWidgetToolButtonVisible( bool searchWidgetToolButtonVisible );
148 
149   protected:
150 
151     /**
152      * Returns a pointer to the EDIT page widget.
153      * \note this method is in place for unit testing only, and is not considered
154      * stable API
155      * \note not available in Python bindings
156      */
157     QWidget *editPage() const SIP_SKIP;
158 
159     /**
160      * Returns a pointer to the stacked widget managing edit and search page.
161      * \note this method is in place for unit testing only, and is not considered
162      * stable API
163      * \note not available in Python bindings
164      */
165     QStackedWidget *stack() const SIP_SKIP;
166 
167     /**
168      * Returns a pointer to the search page widget.
169      * \note this method is in place for unit testing only, and is not considered
170      * stable API
171      * \note not available in Python bindings
172      */
173     QWidget *searchPage() const SIP_SKIP;
174 
175   private slots:
176 
177     //! Triggered when search button flags are changed
178     void searchWidgetFlagsChanged( QgsSearchWidgetWrapper::FilterFlags flags );
179 
180   private:
181     virtual void updateWidgets();
182     QgsAttributeFormWidget::Mode mMode = DefaultMode;
183     QgsSearchWidgetToolButton *mSearchWidgetToolButton = nullptr;
184     QWidget *mEditPage = nullptr;
185     QWidget *mSearchPage = nullptr;
186     QStackedWidget *mStack = nullptr;
187     QWidget *mSearchFrame = nullptr;
188     QgsAttributeForm *mForm = nullptr;
189     QList< QgsSearchWidgetWrapper * > mSearchWidgets;
190     QgsWidgetWrapper *mWidget = nullptr;
191 };
192 
193 #endif // QGSATTRIBUTEFORMWIDGET_H
194