1 
2 /**
3  * \brief The qgsrasterlayerproperties class is used to set up how raster layers are displayed.
4  */
5 /* **************************************************************************
6                           qgsrasterlayerproperties.h  -  description
7                              -------------------
8     begin                : Sun Aug 11 2002
9     copyright            : (C) 2002 by Tim Sutton
10     email                : tim@linfiniti.com
11  ***************************************************************************/
12 
13 /***************************************************************************
14  *                                                                         *
15  *   This program is free software; you can redistribute it and/or modify  *
16  *   it under the terms of the GNU General Public License as published by  *
17  *   the Free Software Foundation; either version 2 of the License, or     *
18  *   (at your option) any later version.                                   *
19  *                                                                         *
20  ***************************************************************************/
21 #ifndef QGSRASTERLAYERPROPERTIES_H
22 #define QGSRASTERLAYERPROPERTIES_H
23 
24 #include "qgsoptionsdialogbase.h"
25 #include "ui_qgsrasterlayerpropertiesbase.h"
26 #include "qgsguiutils.h"
27 #include "qgshelp.h"
28 #include "qgsmaplayerstylemanager.h"
29 #include "qgsmaptoolemitpoint.h"
30 #include "qgis_gui.h"
31 #include "qgsresamplingutils.h"
32 #include "qgsrasterpipe.h"
33 
34 class QgsPointXY;
35 class QgsMapLayer;
36 class QgsMapCanvas;
37 class QgsRasterLayer;
38 class QgsMetadataWidget;
39 class QgsRasterRenderer;
40 class QgsRasterRendererWidget;
41 class QgsRasterHistogramWidget;
42 class QgsRasterLayerTemporalPropertiesWidget;
43 class QgsWebView;
44 class QgsProviderSourceWidget;
45 class QgsMapLayerConfigWidgetFactory;
46 class QgsMapLayerConfigWidget;
47 class QgsPropertyOverrideButton;
48 class QgsRasterTransparencyWidget;
49 
50 
51 /**
52  * \ingroup gui
53  * \class QgsRasterLayerProperties
54  * \brief Property sheet for a raster map layer
55  * \since QGIS 3.12 (in the GUI API)
56  */
57 
58 class GUI_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private Ui::QgsRasterLayerPropertiesBase, private QgsExpressionContextGenerator
59 {
60     Q_OBJECT
61 
62   public:
63 
64     /**
65      * enumeration for the different types of style
66      */
67 #ifndef SIP_RUN
68     enum StyleType
69     {
70       QML,
71       SLD
72     };
73     Q_ENUM( StyleType )
74 #endif
75 
76     /**
77      * Constructor
78      * \param lyr Map layer for which properties will be displayed
79      * \param canvas the QgsMapCanvas instance
80      * \param parent the parent of this widget
81      * \param fl windows flag
82      */
83     QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags );
84 
85     /**
86      * Adds a properties page factory to the raster layer properties dialog.
87      * \since QGIS 3.18
88      */
89     void addPropertiesPageFactory( const QgsMapLayerConfigWidgetFactory *factory );
90 
91     QgsExpressionContext createExpressionContext() const override;
92 
93   protected slots:
94     //! \brief auto slot executed when the active page in the main widget stack is changed
95     void optionsStackedWidget_CurrentChanged( int index ) override SIP_SKIP ;
96 
97   private:
98 
99     // TODO -- consider moving these to a common raster widget base class
100 
101     /**
102      * Registers a property override button, setting up its initial value, connections and description.
103      * \param button button to register
104      * \param key corresponding data defined property key
105      * \since QGIS 3.22
106      */
107     void initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key );
108 
109     /**
110      * Updates all property override buttons to reflect the widgets's current properties.
111      * \since QGIS 3.22
112      */
113     void updateDataDefinedButtons();
114 
115     /**
116      * Updates a specific property override \a button to reflect the widgets's current properties.
117      * \since QGIS 3.22
118      */
119     void updateDataDefinedButton( QgsPropertyOverrideButton *button );
120 
121     //! Temporary property collection
122     QgsPropertyCollection mPropertyCollection;
123 
124   private slots:
125 
126     void updateProperty();
127 
128     //! \brief Applies the settings made in the dialog without closing the box
129     void apply();
130     //! \brief Called when cancel button is pressed
131     void onCancel();
132     //! \brief this slot asks the rasterlayer to construct pyramids
133     void buttonBuildPyramids_clicked();
134     //! \brief slot executed when user changes the layer's CRS
135     void mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs );
136 
137     // Server properties
138     void addMetadataUrl();
139     void removeSelectedMetadataUrl();
140 
141     /**
142      * updates gamma spinbox on slider changes
143      * \since QGIS 3.16
144      */
145     void updateGammaSpinBox( int value );
146 
147     /**
148      * updates gamma slider on spinbox changes
149      * \since QGIS 3.16
150      */
151     void updateGammaSlider( double value );
152 
153     void mRenderTypeComboBox_currentIndexChanged( int index );
154     //! Load the default style when appropriate button is pressed.
155     void loadDefaultStyle_clicked();
156     //! Save the default style when appropriate button is pressed.
157     void saveDefaultStyle_clicked();
158     //! Load a saved style when appropriate button is pressed.
159     void loadStyle_clicked();
160     //! Save a style when appriate button is pressed.
161     void saveStyleAs_clicked();
162     //! Restore dialog modality and focus, usually after a pixel clicked to pick transparency color
163     void restoreWindowModality();
164 
165 
166     //! Load a saved metadata file.
167     void loadMetadata();
168     //! Save a metadata.
169     void saveMetadataAs();
170     //! Save the default metadata.
171     void saveDefaultMetadata();
172     //! Load the default metadata.
173     void loadDefaultMetadata();
174 
175     //! Help button
176     void showHelp();
177 
178     //! Slot to reset all color rendering options to default
179     void mResetColorRenderingBtn_clicked();
180 
181     //! Enable or disable Build pyramids button depending on selection in pyramids list
182     void toggleBuildPyramidsButton();
183 
184     //! Enable or disable saturation controls depending on choice of grayscale mode
185     void toggleSaturationControls( int grayscaleMode );
186 
187     //! Enable or disable colorize controls depending on checkbox
188     void toggleColorizeControls( bool colorizeEnabled );
189 
190     //! Transparency cell changed
191     void transparencyCellTextEdited( const QString &text );
192 
193     void aboutToShowStyleMenu();
194 
195     //! Make GUI reflect the layer's state
196     void syncToLayer();
197 
198     void urlClicked( const QUrl &url );
199 
200   private:
201     QPushButton *mBtnStyle = nullptr;
202     QPushButton *mBtnMetadata = nullptr;
203     QAction *mActionLoadMetadata = nullptr;
204     QAction *mActionSaveMetadataAs = nullptr;
205 
206     QStandardItemModel *mMetadataUrlModel = nullptr;
207 
208     //! A list of additional pages provided by plugins
209     QList<QgsMapLayerConfigWidget *> mLayerPropertiesPages;
210 
211     //! \brief  A constant that signals property not used
212     const QString TRSTRING_NOT_SET;
213 
214     //! \brief Default contrast enhancement algorithm
215     QString mDefaultContrastEnhancementAlgorithm;
216 
217     //! \brief default standard deviation
218     double mDefaultStandardDeviation;
219 
220     //! \brief Default band combination
221     int mDefaultRedBand;
222     int mDefaultGreenBand;
223     int mDefaultBlueBand;
224 
225     //! \brief Flag to indicate if Gray minimum maximum values are actual minimum maximum values
226     bool mGrayMinimumMaximumEstimated;
227 
228     //! \brief Flag to indicate if RGB minimum maximum values are actual minimum maximum values
229     bool mRGBMinimumMaximumEstimated;
230 
231     //! \brief Pointer to the raster layer that this property dilog changes the behavior of.
232     QgsRasterLayer *mRasterLayer = nullptr;
233 
234     QgsRasterRendererWidget *mRendererWidget = nullptr;
235     QgsMetadataWidget *mMetadataWidget = nullptr;
236 
237     QgsRasterTransparencyWidget *mRasterTransparencyWidget = nullptr;
238 
239     /**
240      * Widget with temporal inputs, to be used by temporal based raster layers.
241      */
242     QgsRasterLayerTemporalPropertiesWidget *mTemporalWidget = nullptr;
243 
244     bool rasterIsMultiBandColor();
245 
246     /**
247      * Updates the information tab by reloading metadata
248      */
249     void updateInformationContent();
250 
251     void setTransparencyCell( int row, int column, double value );
252     void setTransparencyCellValue( int row, int column, double value );
253     double transparencyCellValue( int row, int column );
254     void setTransparencyToEdited( int row );
255     void adjustTransparencyCellWidth( int row, int column );
256 
257     void setRendererWidget( const QString &rendererName );
258 
259     //TODO: we should move these gradient generators somewhere more generic
260     //so they can be used generically throughout the app
261     QLinearGradient greenGradient();
262     QLinearGradient redGradient();
263     QLinearGradient blueGradient();
264     QLinearGradient grayGradient();
265     QLinearGradient highlightGradient();
266     qreal mGradientHeight;
267     qreal mGradientWidth;
268 
269     QgsMapCanvas *mMapCanvas = nullptr;
270 
271     QgsRasterHistogramWidget *mHistogramWidget = nullptr;
272 
273     QVector<bool> mTransparencyToEdited;
274 
275     /**
276      * Previous layer style. Used to reset style to previous state if new style
277      * was loaded but dialog is canceled.
278     */
279     QgsMapLayerStyle mOldStyle;
280 
281     bool mDisableRenderTypeComboBoxCurrentIndexChanged = false;
282 
283     bool mMetadataFilled;
284 
285     //! Synchronize state with associated raster layer
286     void sync();
287 
288     QgsResamplingUtils mResamplingUtils;
289 
290     QgsProviderSourceWidget *mSourceWidget = nullptr;
291 
292     QgsWebView *mMetadataViewer = nullptr;
293 
294     QgsExpressionContext mContext;
295 
296     friend class QgsAppScreenShots;
297 
298     QgsCoordinateReferenceSystem mBackupCrs;
299 };
300 #endif
301