1 /***************************************************************************
2     qgspropertyassistantwidget.h
3     ----------------------------
4     begin                : February, 2017
5     copyright            : (C) 2017 Nyall Dawson
6     email                : nyall dot dawson at gmail dot com
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 #ifndef QGSPROPERTYASSISTANTWIDGET_H
19 #define QGSPROPERTYASSISTANTWIDGET_H
20 
21 #include "qgspanelwidget.h"
22 #include "qgis_sip.h"
23 #include "ui_qgspropertyassistantwidgetbase.h"
24 #include "ui_qgspropertysizeassistantwidget.h"
25 #include "ui_qgspropertycolorassistantwidget.h"
26 #include "ui_qgspropertygenericnumericassistantwidget.h"
27 #include "qgsproperty.h"
28 #include "qgslayertreegroup.h"
29 #include "qgslayertreemodellegendnode.h"
30 #include "qgis_gui.h"
31 #include <QStandardItemModel>
32 #include <QItemDelegate>
33 
34 class QgsMapCanvas;
35 
36 #ifndef SIP_RUN
37 
38 ///@cond PRIVATE
39 
40 class GUI_EXPORT QgsPropertyAbstractTransformerWidget : public QWidget
41 {
42     Q_OBJECT
43 
44   public:
45 
46     QgsPropertyAbstractTransformerWidget( QWidget *parent = nullptr, const QgsPropertyDefinition &definition = QgsPropertyDefinition() )
QWidget(parent)47       : QWidget( parent )
48       , mDefinition( definition )
49     {}
50 
51     virtual QgsPropertyTransformer *createTransformer( double minValue, double maxValue ) const = 0;
52 
53     virtual QList< QgsSymbolLegendNode * > generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const;
54 
55   signals:
56 
57     void widgetChanged();
58 
59   protected:
60 
61     QgsPropertyDefinition mDefinition;
62 
63 };
64 
65 class GUI_EXPORT QgsPropertyGenericNumericAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertyGenericNumericAssistant
66 {
67     Q_OBJECT
68 
69   public:
70 
71     QgsPropertyGenericNumericAssistantWidget( QWidget *parent = nullptr, const QgsPropertyDefinition &definition = QgsPropertyDefinition(), const QgsProperty &initialState = QgsProperty() );
72 
73     QgsGenericNumericTransformer *createTransformer( double minValue, double maxValue ) const override;
74 
75 };
76 
77 class GUI_EXPORT QgsPropertySizeAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertySizeAssistant
78 {
79     Q_OBJECT
80 
81   public:
82 
83     QgsPropertySizeAssistantWidget( QWidget *parent = nullptr, const QgsPropertyDefinition &definition = QgsPropertyDefinition(), const QgsProperty &initialState = QgsProperty() );
84 
85     QgsSizeScaleTransformer *createTransformer( double minValue, double maxValue ) const override;
86 
87     QList< QgsSymbolLegendNode * > generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const override;
88 };
89 
90 class GUI_EXPORT QgsPropertyColorAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertyColorAssistant
91 {
92     Q_OBJECT
93 
94   public:
95 
96     QgsPropertyColorAssistantWidget( QWidget *parent = nullptr, const QgsPropertyDefinition &definition = QgsPropertyDefinition(), const QgsProperty &initialState = QgsProperty() );
97 
98     QgsColorRampTransformer *createTransformer( double minValue, double maxValue ) const override;
99 
100     QList< QgsSymbolLegendNode * > generatePreviews( const QList<double> &breaks, QgsLayerTreeLayer *parent, const QgsSymbol *symbol, double minValue, double maxValue, QgsCurveTransform *curve ) const override;
101 };
102 
103 ///@endcond PRIVATE
104 
105 #endif
106 
107 
108 /**
109  * \class QgsPropertyAssistantWidget
110  * \ingroup gui
111  * \brief Shows a user-friendly assistant guiding users through the creation of QgsProperty overrides.
112  * \since QGIS 3.0
113  */
114 class GUI_EXPORT QgsPropertyAssistantWidget : public QgsPanelWidget, private Ui::PropertyAssistantBase
115 {
116     Q_OBJECT
117 
118   public:
119 
120     /**
121      * Constructor for QgsPropertyAssistantWidget. Aside from a \a parent widget, the constructor accepts a
122      * corresponding property \a definition from which it customizes the displayed options (eg a color based
123      * property definition will show an assistant to allow creation of color based properties).
124      * The \a initialState dictates the initial state to show in the widget. A corresponding \a layer
125      * can also be set to allow population of GUI widgets such as field selectors.
126      */
127     QgsPropertyAssistantWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr,
128                                 const QgsPropertyDefinition &definition = QgsPropertyDefinition(),
129                                 const QgsProperty &initialState = QgsProperty(),
130                                 const QgsVectorLayer *layer = nullptr );
131 
132     /**
133      * Register an expression context generator class that will be used to retrieve
134      * an expression context for the button when required.
135      */
136     void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
137 
138     /**
139      * Updates a \a property in place to corresponding to the current settings shown
140      * in the widget.
141      */
142     void updateProperty( QgsProperty &property );
143 
144     /**
145      * Sets a symbol which can be used for previews inside the widget. If not specified, default
146      * created symbols will be used instead.
147      * \note not available in Python bindings
148      */
setSymbol(std::shared_ptr<QgsSymbol> symbol)149     void setSymbol( std::shared_ptr< QgsSymbol > symbol ) { mSymbol = symbol; updatePreview(); } SIP_SKIP
150 
151     void setDockMode( bool dockMode ) override;
152 
153   private slots:
154     void computeValuesFromLayer();
155     void updatePreview();
156 
157 
158   private:
159 
160     QgsPropertyDefinition mDefinition;
161     const QgsVectorLayer *mLayer = nullptr;
162     QgsExpressionContextGenerator *mExpressionContextGenerator = nullptr;
163     QgsPropertyAbstractTransformerWidget *mTransformerWidget = nullptr;
164 
165     QgsLayerTreeLayer *mLayerTreeLayer = nullptr;
166     QgsLayerTreeGroup mRoot;
167     QStandardItemModel mPreviewList;
168 
169     std::shared_ptr< QgsSymbol > mSymbol;
170 
171     bool computeValuesFromExpression( const QString &expression, double &minValue, double &maxValue ) const;
172     bool computeValuesFromField( const QString &fieldName, double &minValue, double &maxValue ) const;
173 
174 };
175 
176 #ifndef SIP_RUN
177 
178 /// @cond PRIVATE
179 class QgsAssistantPreviewItemDelegate : public QItemDelegate
180 {
181     Q_OBJECT
182 
183   public:
QgsAssistantPreviewItemDelegate(QStandardItemModel * model)184     explicit QgsAssistantPreviewItemDelegate( QStandardItemModel *model ) : mModel( model ) {}
185 
sizeHint(const QStyleOptionViewItem &,const QModelIndex & index)186     QSize sizeHint( const QStyleOptionViewItem & /*option*/, const QModelIndex &index ) const override
187     {
188       QSize size = mModel->item( index.row() )->icon().actualSize( QSize( 512, 512 ) );
189       size.rheight() += 6;
190       return size;
191     }
192 
193   private:
194     QStandardItemModel *mModel = nullptr;
195 
196 };
197 
198 ///@endcond
199 
200 #endif
201 
202 #endif // QGSPROPERTYASSISTANTWIDGET_H
203