QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgsrasterlayerproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlayerproperties.cpp - description
3 -------------------
4 begin : 1/1/2004
5 copyright : (C) 2004 Tim Sutton
6 email : tim@linfiniti.com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include <limits>
19#include <typeinfo>
20
21#include "qgsgui.h"
22#include "qgsapplication.h"
26#include "qgscolorrampimpl.h"
28#include "qgslogger.h"
29#include "qgsmapcanvas.h"
31#include "qgsmaptoolemitpoint.h"
32#include "qgsmaptopixel.h"
33#include "qgsmetadatawidget.h"
37#include "qgsnative.h"
41#include "qgsproject.h"
42#include "qgsrasterbandstats.h"
48#include "qgsrasterlayer.h"
50#include "qgsrasterpyramid.h"
51#include "qgsrasterrange.h"
52#include "qgsrasterrenderer.h"
59#include "qgssettings.h"
61#include "qgsmaplayerlegend.h"
62#include "qgsfileutils.h"
63#include "qgswebview.h"
64#include "qgsvectorlayer.h"
65#include "qgsprovidermetadata.h"
66#include "qgsproviderregistry.h"
68#include "qgsdoublevalidator.h"
70#include "qgsprojectutils.h"
71
75
76#include <QDesktopServices>
77#include <QTableWidgetItem>
78#include <QHeaderView>
79#include <QTextStream>
80#include <QFile>
81#include <QFileDialog>
82#include <QMessageBox>
83#include <QPainter>
84#include <QLinearGradient>
85#include <QPainterPath>
86#include <QPolygonF>
87#include <QColorDialog>
88#include <QList>
89#include <QMouseEvent>
90#include <QVector>
91#include <QUrl>
92#include <QMenu>
93#include <QScreen>
94#include <QRegularExpressionValidator>
95#include <QRegularExpression>
96
97QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
98 : QgsOptionsDialogBase( QStringLiteral( "RasterLayerProperties" ), parent, fl )
99 // Constant that signals property not used.
100 , TRSTRING_NOT_SET( tr( "Not Set" ) )
101 , mDefaultStandardDeviation( 0 )
102 , mDefaultRedBand( 0 )
103 , mDefaultGreenBand( 0 )
104 , mDefaultBlueBand( 0 )
105 , mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
106 , mGradientHeight( 0.0 )
107 , mGradientWidth( 0.0 )
108 , mMapCanvas( canvas )
109 , mMetadataFilled( false )
110{
111 mGrayMinimumMaximumEstimated = true;
112 mRGBMinimumMaximumEstimated = true;
113
114 setupUi( this );
115
116 mMetadataViewer = new QgsWebView( this );
117 mOptsPage_Information->layout()->addWidget( mMetadataViewer );
118
119 mRasterTransparencyWidget = new QgsRasterTransparencyWidget( mRasterLayer, canvas, this );
120
121 transparencyScrollArea->setWidget( mRasterTransparencyWidget );
122
123 connect( buttonBuildPyramids, &QPushButton::clicked, this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
124 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsRasterLayerProperties::mCrsSelector_crsChanged );
125 connect( mRenderTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
126 connect( mResetColorRenderingBtn, &QToolButton::clicked, this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
127 connect( buttonRemoveMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::removeSelectedMetadataUrl );
128 connect( buttonAddMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::addMetadataUrl );
129 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
130 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
131 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
132 initOptionsBase( false );
133 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
134
135 mSourceGroupBox->hide();
136
137 mBtnStyle = new QPushButton( tr( "Style" ) );
138 QMenu *menuStyle = new QMenu( this );
139 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle_clicked );
140 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs_clicked );
141 menuStyle->addSeparator();
142 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveDefaultStyle_clicked );
143 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle_clicked );
144 mBtnStyle->setMenu( menuStyle );
145 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
146 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
147
148 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
149 QMenu *menuMetadata = new QMenu( this );
150 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadata );
151 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataAs );
152 menuMetadata->addSeparator();
153 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveDefaultMetadata );
154 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
155 mBtnMetadata->setMenu( menuMetadata );
156 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
157
158 connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
159
160 connect( this, &QDialog::accepted, this, &QgsRasterLayerProperties::apply );
161 connect( this, &QDialog::rejected, this, &QgsRasterLayerProperties::onCancel );
162
163 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsRasterLayerProperties::apply );
164
165 // brightness/contrast controls
166 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
167 connect( mBrightnessSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
168 mBrightnessSpinBox->setClearValue( 0 );
169
170 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
171 connect( mContrastSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
172 mContrastSpinBox->setClearValue( 0 );
173
174 // gamma correction controls
175 connect( mSliderGamma, &QAbstractSlider::valueChanged, this, &QgsRasterLayerProperties::updateGammaSpinBox );
176 connect( mGammaSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterLayerProperties::updateGammaSlider );
177 mGammaSpinBox->setClearValue( 1.0 );
178
179 // Connect saturation slider and spin box
180 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
181 connect( spinBoxSaturation, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
182 spinBoxSaturation->setClearValue( 0 );
183
184 // Connect colorize strength slider and spin box
185 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
186 connect( spinColorizeStrength, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
187 spinColorizeStrength->setClearValue( 100 );
188
189 // enable or disable saturation slider and spin box depending on grayscale combo choice
190 connect( comboGrayscale, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::toggleSaturationControls );
191
192 // enable or disable colorize colorbutton with colorize checkbox
193 connect( mColorizeCheck, &QAbstractButton::toggled, this, &QgsRasterLayerProperties::toggleColorizeControls );
194
195 // enable or disable Build Pyramids button depending on selection in pyramid list
196 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged, this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
197
198 connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
199
200 // set up the scale based layer visibility stuff....
201 mScaleRangeWidget->setMapCanvas( mMapCanvas );
202 chkUseScaleDependentRendering->setChecked( lyr->hasScaleBasedVisibility() );
203 mScaleRangeWidget->setScaleRange( lyr->minimumScale(), lyr->maximumScale() );
204
205 // Setup the layer metadata URL
206 tableViewMetadataUrl->setSelectionMode( QAbstractItemView::SingleSelection );
207 tableViewMetadataUrl->setSelectionBehavior( QAbstractItemView::SelectRows );
208 tableViewMetadataUrl->horizontalHeader()->setStretchLastSection( true );
209 tableViewMetadataUrl->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
210
211 mMetadataUrlModel = new QStandardItemModel( tableViewMetadataUrl );
212 mMetadataUrlModel->clear();
213 mMetadataUrlModel->setColumnCount( 3 );
214 QStringList metadataUrlHeaders;
215 metadataUrlHeaders << tr( "URL" ) << tr( "Type" ) << tr( "Format" );
216 mMetadataUrlModel->setHorizontalHeaderLabels( metadataUrlHeaders );
217 tableViewMetadataUrl->setModel( mMetadataUrlModel );
218 tableViewMetadataUrl->setItemDelegate( new MetadataUrlItemDelegate( this ) );
219
220 // build GUI components
221 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
222 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
223
224 mRasterTransparencyWidget->pbnAddValuesManually->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) );
225 mRasterTransparencyWidget->pbnAddValuesFromDisplay->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionContextHelp.png" ) ) );
226 mRasterTransparencyWidget->pbnRemoveSelectedRow->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyRemove.svg" ) ) );
227 mRasterTransparencyWidget->pbnDefaultValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionOpenTable.svg" ) ) );
228 mRasterTransparencyWidget->pbnImportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileOpen.svg" ) ) );
229 mRasterTransparencyWidget->pbnExportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileSave.svg" ) ) );
230
231
232 if ( !mRasterLayer )
233 {
234 return;
235 }
236
237 mBackupCrs = mRasterLayer->crs();
238
239 // Handles window modality raising canvas
240 if ( mMapCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
241 {
242
243 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [ = ]
244 {
245 hide();
246 setModal( true );
247 show();
248 raise();
249 activateWindow();
250 } );
251
252 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [ = ]
253 {
254 hide();
255 setModal( false );
256
257 // Transfer focus to the canvas to use the selector tool
258 mMapCanvas->window()->raise();
259 mMapCanvas->window()->activateWindow();
260 mMapCanvas->window()->setFocus();
261 } );
262 }
263
267 if ( mMapCanvas )
268 mContext << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() );
269 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
270
271 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
272
273 // Only do pyramids if dealing directly with GDAL.
274 if ( provider && provider->capabilities() & QgsRasterDataProvider::BuildPyramids )
275 {
276 // initialize resampling methods
277 cboResamplingMethod->clear();
278
279 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
280 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
281 {
282 cboResamplingMethod->addItem( method.second, method.first );
283 }
284
285 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
286 QString prefix = provider->name() + "/driverOptions/_pyramids/";
287 QgsSettings mySettings;
288 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
289 int idx = cboResamplingMethod->findData( defaultMethod );
290 if ( idx >= 0 )
291 cboResamplingMethod->setCurrentIndex( idx );
292
293
294 // build pyramid list
295 const QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
296
297 for ( const QgsRasterPyramid &pyramid : myPyramidList )
298 {
299 if ( pyramid.getExists() )
300 {
301 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
302 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
303 QString::number( pyramid.getYDim() ) ) );
304 }
305 else
306 {
307 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
308 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
309 QString::number( pyramid.getYDim() ) ) );
310 }
311 }
312 }
313 else
314 {
315 // disable Pyramids tab completely
316 mOptsPage_Pyramids->setEnabled( false );
317 }
318
319 // We can calculate histogram for all data sources but estimated only if
320 // size is unknown - could also be enabled if well supported (estimated histogram
321 // and let user know that it is estimated)
322 if ( !provider || !( provider->capabilities() & QgsRasterDataProvider::Size ) )
323 {
324 // disable Histogram tab completely
325 mOptsPage_Histogram->setEnabled( false );
326 }
327
328 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
329 layout->setContentsMargins( 0, 0, 0, 0 );
330 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
331 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
332 mMetadataWidget->setMapCanvas( mMapCanvas );
333 layout->addWidget( mMetadataWidget );
334 metadataFrame->setLayout( layout );
335
336 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
337 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
338 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
339 temporalLayout->addWidget( mTemporalWidget );
340
341 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), 2 );
342 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
343 mCrsSelector->setCrs( mRasterLayer->crs() );
344
345 // Set text for pyramid info box
346 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
347 QString pyramidHeader = tr( "Description" );
348 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
349 QString pyramidSentence2 = tr( "By creating lower resolution copies of the data (pyramids) performance can be considerably improved as QGIS selects the most suitable resolution to use depending on the level of zoom." );
350 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
351 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
352 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
353
354 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
355 pyramidSentence1,
356 pyramidSentence2,
357 pyramidSentence3,
358 pyramidSentence4,
359 pyramidSentence5 ) );
360
361 //resampling
362 mResamplingGroupBox->setSaveCheckedState( true );
363 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
364 mResamplingUtils.refreshWidgetsFromLayer();
365
366 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
367
368 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
369 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
370
371 // Hue and saturation color control
372 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
373 //set hue and saturation controls to current values
374 if ( hueSaturationFilter )
375 {
376 sliderSaturation->setValue( hueSaturationFilter->saturation() );
377 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
378
379 // Set initial state of saturation controls based on grayscale mode choice
380 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
381
382 // Set initial state of colorize controls
383 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
384 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
385 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
386 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
387 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
388 }
389
390 //blend mode
391 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
392 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
393
394 //transparency band
395 if ( provider )
396 {
397 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
398 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
399
400// Alpha band is set in sync()
401#if 0
402 if ( renderer )
403 {
404 QgsDebugMsg( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ) );
405 if ( renderer->alphaBand() > 0 )
406 {
407 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
408 }
409 }
410#endif
411 }
412
413 // create histogram widget
414 mHistogramWidget = nullptr;
415 if ( mOptsPage_Histogram->isEnabled() )
416 {
417 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
418 mHistogramStackedWidget->addWidget( mHistogramWidget );
419 }
420
421 //insert renderer widgets into registry
428
429 //fill available renderers into combo box
431 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
432 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
433 for ( const QString &name : constRenderersList )
434 {
436 {
437 if ( ( mRasterLayer->rasterType() != QgsRasterLayer::ColorLayer && entry.name != QLatin1String( "singlebandcolordata" ) ) ||
438 ( mRasterLayer->rasterType() == QgsRasterLayer::ColorLayer && entry.name == QLatin1String( "singlebandcolordata" ) ) )
439 {
440 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
441 }
442 }
443 }
444 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
445
446 int widgetIndex = 0;
447 if ( renderer )
448 {
449 QString rendererType = renderer->type();
450 widgetIndex = mRenderTypeComboBox->findData( rendererType );
451 if ( widgetIndex != -1 )
452 {
453 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
454 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
455 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
456 }
457
458 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
459 {
460 // no band rendering options for singlebandcolordata, so minimize group box
461 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
462 sizep.setVerticalStretch( 0 );
463 sizep.setVerticalPolicy( QSizePolicy::Maximum );
464 mBandRenderingGrpBx->setSizePolicy( sizep );
465 mBandRenderingGrpBx->updateGeometry();
466 }
467
468 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
469 {
470 mWMSPrintGroupBox->hide();
471 mPublishDataSourceUrlCheckBox->hide();
472 mBackgroundLayerCheckBox->hide();
473 }
474 }
475
476#ifdef WITH_QTWEBKIT
477 // Setup information tab
478
479 const int horizontalDpi = logicalDpiX();
480
481 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
482 if ( horizontalDpi > 96 )
483 {
484 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
485 }
486 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
487 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::urlClicked );
488 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
489 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
490
491#endif
492
493 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::RendererOpacity );
494
495 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
496
497 // update based on lyr's current state
498 sync();
499
500 QgsSettings settings;
501 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
502 // this will be read by restoreOptionsBaseUi()
503 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
504 {
505 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ),
506 mOptStackedWidget->indexOf( mOptsPage_Style ) );
507 }
508
509 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
510
511 QString title = tr( "Layer Properties — %1" ).arg( lyr->name() );
512
513 if ( !mRasterLayer->styleManager()->isDefault( mRasterLayer->styleManager()->currentStyle() ) )
514 title += QStringLiteral( " (%1)" ).arg( mRasterLayer->styleManager()->currentStyle() );
515 restoreOptionsBaseUi( title );
516 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
517
518 //Add help page references
519 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
520 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
521 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
522 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
523
524 if ( mOptsPage_Histogram )
525 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
526
527 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
528 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
529
530 if ( mOptsPage_Pyramids )
531 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
532
533 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
534 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
535 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
536}
537
539{
540 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
541 {
542 return;
543 }
544
545 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
546 switch ( factory->parentPage() )
547 {
549 {
550 mLayerPropertiesPages << page;
551
552 const QString beforePage = factory->layerPropertiesPagePositionHint();
553 if ( beforePage.isEmpty() )
554 addPage( factory->title(), factory->title(), factory->icon(), page );
555 else
556 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
557 break;
558 }
559
561 mTemporalWidget->addWidget( page );
562 break;
563 }
564}
565
570
571void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
572{
573 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
574 QgsRasterRendererWidget *oldWidget = mRendererWidget;
575 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
576
577 int alphaBand = -1;
578 double opacity = 1;
579 QColor nodataColor;
580 if ( oldRenderer )
581 {
582 // Retain alpha band and opacity when switching renderer
583 alphaBand = oldRenderer->alphaBand();
584 opacity = oldRenderer->opacity();
585 nodataColor = oldRenderer->nodataColor();
586 }
587
588 QgsRasterRendererRegistryEntry rendererEntry;
589 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
590 {
591 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
592 {
593 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
594 // Current canvas extent (used to calc min/max) in layer CRS
595 QgsRectangle myExtent = mMapCanvas->mapSettings().outputExtentToLayerExtent( mRasterLayer, mMapCanvas->extent() );
596 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
597 {
598 if ( rendererName == QLatin1String( "singlebandgray" ) )
599 {
600 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( QgsRaster::SingleBandGray, mRasterLayer->dataProvider() ) );
601 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
602 }
603 else if ( rendererName == QLatin1String( "multibandcolor" ) )
604 {
605 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( QgsRaster::MultiBandColor, mRasterLayer->dataProvider() ) );
606 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
607 }
608 }
609 mRasterLayer->renderer()->setAlphaBand( alphaBand );
610 mRasterLayer->renderer()->setOpacity( opacity );
611 mRasterLayer->renderer()->setNodataColor( nodataColor );
612 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
613 mRendererWidget->setMapCanvas( mMapCanvas );
614 mRendererStackedWidget->addWidget( mRendererWidget );
615 if ( oldWidget )
616 {
617 //compare used bands in new and old renderer and reset transparency dialog if different
618 std::unique_ptr<QgsRasterRenderer> oldRenderer;
619 oldRenderer.reset( oldWidget->renderer() );
620 std::unique_ptr<QgsRasterRenderer> newRenderer;
621 newRenderer.reset( mRendererWidget->renderer() );
622 const QList<int> oldBands = oldRenderer->usesBands();
623 const QList<int> newBands = newRenderer->usesBands();
624 if ( oldBands != newBands )
625 {
626 mRasterTransparencyWidget->syncToLayer();
627 }
628 }
629 }
630 }
631
632 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
633 if ( widgetIndex != -1 )
634 {
635 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
636 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
637 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
638 }
639
640 if ( mRendererWidget != oldWidget )
641 delete oldWidget;
642
643 if ( mHistogramWidget )
644 {
645 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
646 }
647}
648
649void QgsRasterLayerProperties::sync()
650{
651 QgsSettings myQSettings;
652
653 if ( !mSourceWidget )
654 {
655 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
656 if ( mSourceWidget )
657 {
658 QHBoxLayout *layout = new QHBoxLayout();
659 layout->addWidget( mSourceWidget );
660 mSourceGroupBox->setLayout( layout );
661 mSourceGroupBox->show();
662
663 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [ = ]( bool isValid )
664 {
665 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
666 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
667 } );
668 }
669 }
670
671 if ( mSourceWidget )
672 {
673 mSourceWidget->setMapCanvas( mMapCanvas );
674 mSourceWidget->setSourceUri( mRasterLayer->source() );
675 }
676
677 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
678 if ( !provider )
679 return;
680
681 mRasterTransparencyWidget->syncToLayer();
682
683 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
685 {
686 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
687 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
688 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
689 }
690
691 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
692 if ( !( provider->capabilities() & QgsRasterDataProvider::BuildPyramids ) )
693 {
694 if ( mOptsPage_Pyramids )
695 {
696 delete mOptsPage_Pyramids;
697 mOptsPage_Pyramids = nullptr;
698 }
699 }
700
701 if ( !( provider->capabilities() & QgsRasterDataProvider::Size ) )
702 {
703 if ( mOptsPage_Histogram )
704 {
705 delete mOptsPage_Histogram;
706 mOptsPage_Histogram = nullptr;
707 delete mHistogramWidget;
708 mHistogramWidget = nullptr;
709 }
710 }
711
712 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
713
714 /*
715 * Style tab
716 */
717
718 //set brightness, contrast and gamma
719 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
720 if ( brightnessFilter )
721 {
722 mSliderBrightness->setValue( brightnessFilter->brightness() );
723 mSliderContrast->setValue( brightnessFilter->contrast() );
724 mGammaSpinBox->setValue( brightnessFilter->gamma() );
725 }
726
727 // Hue and saturation color control
728 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
729 //set hue and saturation controls to current values
730 if ( hueSaturationFilter )
731 {
732 sliderSaturation->setValue( hueSaturationFilter->saturation() );
733 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
734
735 // Set state of saturation controls based on grayscale mode choice
736 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
737
738 // Set state of colorize controls
739 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
740 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
741 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
742 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
743 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
744 }
745
746
747 mRefreshLayerCheckBox->setChecked( mRasterLayer->hasAutoRefreshEnabled() );
748 mRefreshLayerIntervalSpinBox->setEnabled( mRasterLayer->hasAutoRefreshEnabled() );
749 mRefreshLayerIntervalSpinBox->setValue( mRasterLayer->autoRefreshInterval() / 1000.0 );
750
751 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
752 /*
753 * General Tab
754 */
755
756 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
757
758 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
759 /*
760 * Metadata Tab
761 */
762 //populate the metadata tab's text browser widget with gdal metadata info
763 updateInformationContent();
764
765 // WMS Name as layer short name
766 mLayerShortNameLineEdit->setText( mRasterLayer->shortName() );
767 // WMS Name validator
768 QValidator *shortNameValidator = new QRegularExpressionValidator( QgsApplication::shortNameRegularExpression(), this );
769 mLayerShortNameLineEdit->setValidator( shortNameValidator );
770
771 //layer title and abstract
772 mLayerTitleLineEdit->setText( mRasterLayer->title() );
773 mLayerAbstractTextEdit->setPlainText( mRasterLayer->abstract() );
774 mLayerKeywordListLineEdit->setText( mRasterLayer->keywordList() );
775 mLayerDataUrlLineEdit->setText( mRasterLayer->dataUrl() );
776 mLayerDataUrlFormatComboBox->setCurrentIndex(
777 mLayerDataUrlFormatComboBox->findText(
778 mRasterLayer->dataUrlFormat()
779 )
780 );
781
782 //layer attribution
783 mLayerAttributionLineEdit->setText( mRasterLayer->attribution() );
784 mLayerAttributionUrlLineEdit->setText( mRasterLayer->attributionUrl() );
785
786 // layer metadata url
787 const QList<QgsMapLayerServerProperties::MetadataUrl> &metaUrls = mRasterLayer->serverProperties()->metadataUrls();
788 for ( const QgsMapLayerServerProperties::MetadataUrl &metaUrl : metaUrls )
789 {
790 const int row = mMetadataUrlModel->rowCount();
791 mMetadataUrlModel->setItem( row, 0, new QStandardItem( metaUrl.url ) );
792 mMetadataUrlModel->setItem( row, 1, new QStandardItem( metaUrl.type ) );
793 mMetadataUrlModel->setItem( row, 2, new QStandardItem( metaUrl.format ) );
794 }
795
796 // layer legend url
797 mLayerLegendUrlLineEdit->setText( mRasterLayer->legendUrl() );
798 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->legendUrlFormat() ) );
799
800 //WMS print layer
801 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
802 if ( wmsPrintLayer.isValid() )
803 {
804 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
805 }
806
807 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
808 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
809
810 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
811 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
812
813 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
814 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
815 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
816
817 mTemporalWidget->syncToLayer();
818
819 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
820 updateDataDefinedButtons();
821
822 for ( QgsMapLayerConfigWidget *page : std::as_const( mLayerPropertiesPages ) )
823 {
824 page->syncToLayer( mRasterLayer );
825 }
826
827}
828
829void QgsRasterLayerProperties::apply()
830{
831 if ( mSourceWidget )
832 {
833 const QString newSource = mSourceWidget->sourceUri();
834 if ( newSource != mRasterLayer->source() )
835 {
836 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
837 }
838 }
839
840 // Do nothing on "bad" layers
841 if ( !mRasterLayer->isValid() )
842 return;
843
844 // apply all plugin dialogs
845 for ( QgsMapLayerConfigWidget *page : std::as_const( mLayerPropertiesPages ) )
846 {
847 page->apply();
848 }
849
850
851 /*
852 * Legend Tab
853 */
854 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
855 mLegendConfigEmbeddedWidget->applyToLayer();
856
857 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
858 /*
859 * Symbology Tab
860 */
861
862 //set whether the layer histogram should be inverted
863 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
864
865 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
866 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
867 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
868
869 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
870 /*
871 * Transparent Pixel Tab
872 */
873
874 //set NoDataValue
875 QgsRasterRangeList myNoDataRangeList;
876 if ( "" != mRasterTransparencyWidget->leNoDataValue->text() )
877 {
878 bool myDoubleOk = false;
879 double myNoDataValue = QgsDoubleValidator::toDouble( mRasterTransparencyWidget->leNoDataValue->text(), &myDoubleOk );
880 if ( myDoubleOk )
881 {
882 QgsRasterRange myNoDataRange( myNoDataValue, myNoDataValue );
883 myNoDataRangeList << myNoDataRange;
884 }
885 }
886 for ( int bandNo = 1; bandNo <= mRasterLayer->dataProvider()->bandCount(); bandNo++ )
887 {
888 mRasterLayer->dataProvider()->setUserNoDataValue( bandNo, myNoDataRangeList );
889 mRasterLayer->dataProvider()->setUseSourceNoDataValue( bandNo, mRasterTransparencyWidget->mSrcNoDataValueCheckBox->isChecked() );
890 }
891
892 //set renderer from widget
893 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
894 if ( rendererWidget )
895 {
896 rendererWidget->doComputations();
897
898 mRasterLayer->setRenderer( rendererWidget->renderer() );
899 }
900
901 mBackupCrs = mRasterLayer->crs();
902 mMetadataWidget->acceptMetadata();
903 mMetadataFilled = false;
904
905 //transparency settings
906 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
907 if ( rasterRenderer )
908 {
909 rasterRenderer->setAlphaBand( mRasterTransparencyWidget->cboxTransparencyBand->currentBand() );
910 rasterRenderer->setNodataColor( mRasterTransparencyWidget->mNodataColorButton->color() );
911
912 //Walk through each row in table and test value. If not valid set to 0.0 and continue building transparency list
913 QgsRasterTransparency *rasterTransparency = new QgsRasterTransparency();
914 if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 4 )
915 {
917 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
918 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
919 {
920 myTransparentPixel.red = transparencyCellValue( myListRunner, 0 );
921 myTransparentPixel.green = transparencyCellValue( myListRunner, 1 );
922 myTransparentPixel.blue = transparencyCellValue( myListRunner, 2 );
923 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 3 );
924 myTransparentThreeValuePixelList.append( myTransparentPixel );
925 }
926 rasterTransparency->setTransparentThreeValuePixelList( myTransparentThreeValuePixelList );
927 }
928 else if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 3 )
929 {
931 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
932 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
933 {
934 myTransparentPixel.min = transparencyCellValue( myListRunner, 0 );
935 myTransparentPixel.max = transparencyCellValue( myListRunner, 1 );
936 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 2 );
937
938 myTransparentSingleValuePixelList.append( myTransparentPixel );
939 }
940 rasterTransparency->setTransparentSingleValuePixelList( myTransparentSingleValuePixelList );
941 }
942
943 rasterRenderer->setRasterTransparency( rasterTransparency );
944
945 // Sync the layer styling widget
946 mRasterLayer->emitStyleChanged();
947
948 //set global transparency
949 rasterRenderer->setOpacity( mRasterTransparencyWidget->mOpacityWidget->opacity() );
950 }
951
952 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
953 /*
954 * General Tab
955 */
956 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
957
958 // set up the scale based layer visibility stuff....
959 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
960 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
961 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
962
963 mRasterLayer->setAutoRefreshInterval( mRefreshLayerIntervalSpinBox->value() * 1000.0 );
964 mRasterLayer->setAutoRefreshEnabled( mRefreshLayerCheckBox->isChecked() );
965
966 //update the legend pixmap
967 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
968 // pixmapLegend->setScaledContents( true );
969 // pixmapLegend->repaint();
970
971 mResamplingUtils.refreshLayerFromWidgets();
972
973 // Hue and saturation controls
974 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
975 if ( hueSaturationFilter )
976 {
977 hueSaturationFilter->setSaturation( sliderSaturation->value() );
978 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
979 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
980 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
981 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
982 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
983 }
984
985 //set the blend mode for the layer
986 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
987
988 // Update temporal properties
989 mTemporalWidget->saveTemporalProperties();
990
991 mRasterLayer->setCrs( mCrsSelector->crs() );
992
993 if ( mRasterLayer->shortName() != mLayerShortNameLineEdit->text() )
994 mMetadataFilled = false;
995 mRasterLayer->setShortName( mLayerShortNameLineEdit->text() );
996
997 if ( mRasterLayer->title() != mLayerTitleLineEdit->text() )
998 mMetadataFilled = false;
999 mRasterLayer->setTitle( mLayerTitleLineEdit->text() );
1000
1001 if ( mRasterLayer->abstract() != mLayerAbstractTextEdit->toPlainText() )
1002 mMetadataFilled = false;
1003 mRasterLayer->setAbstract( mLayerAbstractTextEdit->toPlainText() );
1004
1005 if ( mRasterLayer->keywordList() != mLayerKeywordListLineEdit->text() )
1006 mMetadataFilled = false;
1007 mRasterLayer->setKeywordList( mLayerKeywordListLineEdit->text() );
1008
1009 if ( mRasterLayer->dataUrl() != mLayerDataUrlLineEdit->text() )
1010 mMetadataFilled = false;
1011 mRasterLayer->setDataUrl( mLayerDataUrlLineEdit->text() );
1012
1013 if ( mRasterLayer->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1014 mMetadataFilled = false;
1015 mRasterLayer->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1016
1017 //layer attribution
1018 if ( mRasterLayer->attribution() != mLayerAttributionLineEdit->text() )
1019 mMetadataFilled = false;
1020 mRasterLayer->setAttribution( mLayerAttributionLineEdit->text() );
1021
1022 if ( mRasterLayer->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1023 mMetadataFilled = false;
1024 mRasterLayer->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
1025
1026 // Metadata URL
1027 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
1028 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
1029 {
1031 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
1032 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
1033 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
1034 metaUrls.append( metaUrl );
1035 mMetadataFilled = false;
1036 }
1037 mRasterLayer->serverProperties()->setMetadataUrls( metaUrls );
1038
1039 if ( mRasterLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
1040 mMetadataFilled = false;
1041 mRasterLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
1042
1043 if ( mRasterLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1044 mMetadataFilled = false;
1045 mRasterLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
1046
1047 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1048 {
1049 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1050 }
1051
1052 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1053 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1054
1055 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
1056
1057 // Force a redraw of the legend
1058 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
1059
1060 //make sure the layer is redrawn
1061 mRasterLayer->triggerRepaint();
1062
1063 // notify the project we've made a change
1064 QgsProject::instance()->setDirty( true );
1065}
1066
1067void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1068{
1069 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1070
1071 std::unique_ptr< QgsRasterBlockFeedback > feedback( new QgsRasterBlockFeedback() );
1072
1073 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
1074 //
1075 // Go through the list marking any files that are selected in the listview
1076 // as true so that we can generate pyramids for them.
1077 //
1078 QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1079 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1080 {
1081 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1082 //mark to be pyramided
1083 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1084 }
1085
1086 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1087 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1088 QgsSettings mySettings;
1089 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1090 mySettings.setValue( prefix + "resampling", resamplingMethod );
1091
1092 //
1093 // Ask raster layer to build the pyramids
1094 //
1095
1096 // let the user know we're going to possibly be taking a while
1097 QApplication::setOverrideCursor( Qt::WaitCursor );
1098 QString res = provider->buildPyramids(
1099 myPyramidList,
1100 resamplingMethod,
1101 ( QgsRaster::RasterPyramidsFormat ) cbxPyramidsFormat->currentIndex(),
1102 QStringList(),
1103 feedback.get() );
1104 QApplication::restoreOverrideCursor();
1105 mPyramidProgress->setValue( 0 );
1106 buttonBuildPyramids->setEnabled( false );
1107 if ( !res.isNull() )
1108 {
1109 if ( res == QLatin1String( "CANCELED" ) )
1110 {
1111 // user canceled
1112 }
1113 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1114 {
1115 QMessageBox::warning( this, tr( "Building Pyramids" ),
1116 tr( "Write access denied. Adjust the file permissions and try again." ) );
1117 }
1118 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1119 {
1120 QMessageBox::warning( this, tr( "Building Pyramids" ),
1121 tr( "The file was not writable. Some formats do not "
1122 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1123 }
1124 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1125 {
1126 QMessageBox::warning( this, tr( "Building Pyramids" ),
1127 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1128 }
1129 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1130 {
1131 QMessageBox::warning( this, tr( "Building Pyramids" ),
1132 tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1133 }
1134 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1135 {
1136 QMessageBox::warning( this, tr( "Building Pyramids" ),
1137 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1138 }
1139
1140 }
1141
1142 //
1143 // repopulate the pyramids list
1144 //
1145 lbxPyramidResolutions->clear();
1146 // Need to rebuild list as some or all pyramids may have failed to build
1147 myPyramidList = provider->buildPyramidList();
1148 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1149 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1150
1151 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1152 {
1153 if ( pyramid.getExists() )
1154 {
1155 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
1156 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1157 QString::number( pyramid.getYDim() ) ) );
1158 }
1159 else
1160 {
1161 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
1162 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1163 QString::number( pyramid.getYDim() ) ) );
1164 }
1165 }
1166 //update the legend pixmap
1167 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1168 // pixmapLegend->setScaledContents( true );
1169 // pixmapLegend->repaint();
1170
1171 //populate the metadata tab's text browser widget with gdal metadata info
1172 updateInformationContent();
1173}
1174
1175void QgsRasterLayerProperties::urlClicked( const QUrl &url )
1176{
1177 QFileInfo file( url.toLocalFile() );
1178 if ( file.exists() && !file.isDir() )
1179 QgsGui::nativePlatformInterface()->openFileExplorerAndSelectFile( url.toLocalFile() );
1180 else
1181 QDesktopServices::openUrl( url );
1182}
1183
1184void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1185{
1186 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1187 {
1188 return;
1189 }
1190
1191 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1192 setRendererWidget( rendererName );
1193}
1194
1195void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1196{
1197 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mMapCanvas, tr( "Select Transformation" ) );
1198 mRasterLayer->setCrs( crs );
1199 mMetadataWidget->crsChanged();
1200}
1201
1202void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double value )
1203{
1204 QgsDebugMsgLevel( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ), 3 );
1205 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1206 if ( !provider ) return;
1207
1208 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1209 if ( !renderer ) return;
1210 int nBands = renderer->usesBands().size();
1211
1212 QLineEdit *lineEdit = new QLineEdit();
1213 lineEdit->setFrame( false ); // frame looks bad in table
1214 // Without margins row selection is not displayed (important for delete row)
1215 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1216
1217 if ( column == mRasterTransparencyWidget->tableTransparency->columnCount() - 1 )
1218 {
1219 // transparency
1220 // Who needs transparency as floating point?
1221 lineEdit->setValidator( new QIntValidator( nullptr ) );
1222 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
1223 }
1224 else
1225 {
1226 // value
1227 QString valueString;
1228 switch ( provider->sourceDataType( 1 ) )
1229 {
1232 lineEdit->setValidator( new QgsDoubleValidator( nullptr ) );
1233 if ( !std::isnan( value ) )
1234 {
1235 double v = QgsRasterBlock::printValue( value ).toDouble();
1236 valueString = QLocale().toString( v, 'g' ) ;
1237 }
1238 break;
1239 default:
1240 lineEdit->setValidator( new QIntValidator( nullptr ) );
1241 if ( !std::isnan( value ) )
1242 {
1243 valueString = QLocale().toString( static_cast<int>( value ) );
1244 }
1245 break;
1246 }
1247 lineEdit->setText( valueString );
1248 }
1249 mRasterTransparencyWidget->tableTransparency->setCellWidget( row, column, lineEdit );
1250 adjustTransparencyCellWidth( row, column );
1251
1252 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1253 {
1254 connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1255 }
1256 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1257}
1258
1259void QgsRasterLayerProperties::setTransparencyCellValue( int row, int column, double value )
1260{
1261 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1262 if ( !lineEdit ) return;
1263 double v = QgsRasterBlock::printValue( value ).toDouble();
1264 lineEdit->setText( QLocale().toString( v, 'g' ) );
1265 lineEdit->adjustSize();
1266 adjustTransparencyCellWidth( row, column );
1267 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1268}
1269
1270double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
1271{
1272 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1273 if ( !lineEdit || lineEdit->text().isEmpty() )
1274 {
1275 return std::numeric_limits<double>::quiet_NaN();
1276 }
1277 return QLocale().toDouble( lineEdit->text() );
1278}
1279
1280void QgsRasterLayerProperties::adjustTransparencyCellWidth( int row, int column )
1281{
1282 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1283 if ( !lineEdit ) return;
1284
1285 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1286 width = std::max( width, mRasterTransparencyWidget->tableTransparency->columnWidth( column ) );
1287
1288 lineEdit->setFixedWidth( width );
1289}
1290
1291void QgsRasterLayerProperties::transparencyCellTextEdited( const QString &text )
1292{
1293 Q_UNUSED( text )
1294 QgsDebugMsgLevel( QStringLiteral( "text = %1" ).arg( text ), 3 );
1295 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1296 if ( !renderer )
1297 {
1298 return;
1299 }
1300 int nBands = renderer->usesBands().size();
1301 if ( nBands == 1 )
1302 {
1303 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1304 if ( !lineEdit ) return;
1305 int row = -1;
1306 int column = -1;
1307 for ( int r = 0; r < mRasterTransparencyWidget->tableTransparency->rowCount(); r++ )
1308 {
1309 for ( int c = 0; c < mRasterTransparencyWidget->tableTransparency->columnCount(); c++ )
1310 {
1311 if ( mRasterTransparencyWidget->tableTransparency->cellWidget( r, c ) == sender() )
1312 {
1313 row = r;
1314 column = c;
1315 break;
1316 }
1317 }
1318 if ( row != -1 ) break;
1319 }
1320 QgsDebugMsgLevel( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ), 3 );
1321
1322 if ( column == 0 )
1323 {
1324 QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, 1 ) );
1325 if ( !toLineEdit ) return;
1326 bool toChanged = mTransparencyToEdited.value( row );
1327 QgsDebugMsgLevel( QStringLiteral( "toChanged = %1" ).arg( toChanged ), 3 );
1328 if ( !toChanged )
1329 {
1330 toLineEdit->setText( lineEdit->text() );
1331 }
1332 }
1333 else if ( column == 1 )
1334 {
1335 setTransparencyToEdited( row );
1336 }
1337 }
1338}
1339
1340void QgsRasterLayerProperties::aboutToShowStyleMenu()
1341{
1342 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1343
1344 QMenu *m = qobject_cast<QMenu *>( sender() );
1345
1347 // re-add style manager actions!
1348 m->addSeparator();
1350}
1351
1352void QgsRasterLayerProperties::syncToLayer()
1353{
1354 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1355 if ( renderer )
1356 {
1357 setRendererWidget( renderer->type() );
1358 }
1359 sync();
1360 mRasterLayer->triggerRepaint();
1361}
1362
1363void QgsRasterLayerProperties::setTransparencyToEdited( int row )
1364{
1365 if ( row >= mTransparencyToEdited.size() )
1366 {
1367 mTransparencyToEdited.resize( row + 1 );
1368 }
1369 mTransparencyToEdited[row] = true;
1370}
1371
1373{
1375
1376 bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
1377 mBtnStyle->setVisible( ! isMetadataPanel );
1378 mBtnMetadata->setVisible( isMetadataPanel );
1379
1380 if ( !mHistogramWidget )
1381 return;
1382
1383 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1384 {
1385 mHistogramWidget->setActive( true );
1386 }
1387 else
1388 {
1389 mHistogramWidget->setActive( false );
1390 }
1391
1392 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1393 {
1394 //set the metadata contents (which can be expensive)
1395 updateInformationContent();
1396 }
1397}
1398
1399void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1400{
1401 button->blockSignals( true );
1402 button->init( key, mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1403 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1404 button->registerExpressionContextGenerator( this );
1405 button->blockSignals( false );
1406}
1407
1408void QgsRasterLayerProperties::updateDataDefinedButtons()
1409{
1410 const auto propertyOverrideButtons { findChildren< QgsPropertyOverrideButton * >() };
1411 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1412 {
1413 updateDataDefinedButton( button );
1414 }
1415}
1416
1417void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1418{
1419 if ( !button )
1420 return;
1421
1422 if ( button->propertyKey() < 0 )
1423 return;
1424
1425 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1426 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1427}
1428
1429void QgsRasterLayerProperties::updateProperty()
1430{
1431 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1432 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1433 mPropertyCollection.setProperty( key, button->toProperty() );
1434}
1435
1436void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1437{
1438 // Enable or disable saturation controls based on choice of grayscale mode
1439 if ( grayscaleMode == 0 )
1440 {
1441 sliderSaturation->setEnabled( true );
1442 spinBoxSaturation->setEnabled( true );
1443 }
1444 else
1445 {
1446 sliderSaturation->setEnabled( false );
1447 spinBoxSaturation->setEnabled( false );
1448 }
1449}
1450
1451void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1452{
1453 // Enable or disable colorize controls based on checkbox
1454 btnColorizeColor->setEnabled( colorizeEnabled );
1455 sliderColorizeStrength->setEnabled( colorizeEnabled );
1456 spinColorizeStrength->setEnabled( colorizeEnabled );
1457}
1458
1459
1460QLinearGradient QgsRasterLayerProperties::redGradient()
1461{
1462 //define a gradient
1463 // TODO change this to actual polygon dims
1464 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1465 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1466 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1467 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1468 return myGradient;
1469}
1470QLinearGradient QgsRasterLayerProperties::greenGradient()
1471{
1472 //define a gradient
1473 // TODO change this to actual polygon dims
1474 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1475 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1476 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1477 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1478 return myGradient;
1479}
1480QLinearGradient QgsRasterLayerProperties::blueGradient()
1481{
1482 //define a gradient
1483 // TODO change this to actual polygon dims
1484 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1485 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1486 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1487 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1488 return myGradient;
1489}
1490QLinearGradient QgsRasterLayerProperties::grayGradient()
1491{
1492 //define a gradient
1493 // TODO change this to actual polygon dims
1494 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1495 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1496 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1497 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1498 return myGradient;
1499}
1500QLinearGradient QgsRasterLayerProperties::highlightGradient()
1501{
1502 //define another gradient for the highlight
1503 // TODO change this to actual polygon dims
1504 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1505 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1506 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1507 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1508 return myGradient;
1509}
1510
1511void QgsRasterLayerProperties::addMetadataUrl()
1512{
1513 const int row = mMetadataUrlModel->rowCount();
1514 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
1515 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
1516 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
1517}
1518
1519void QgsRasterLayerProperties::removeSelectedMetadataUrl()
1520{
1521 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
1522 if ( selectedRows.empty() )
1523 return;
1524 mMetadataUrlModel->removeRow( selectedRows[0].row() );
1525}
1526
1527
1528//
1529//
1530// Next four methods for saving and restoring qml style state
1531//
1532//
1533void QgsRasterLayerProperties::loadDefaultStyle_clicked()
1534{
1535 bool defaultLoadedFlag = false;
1536 QString myMessage = mRasterLayer->loadDefaultStyle( defaultLoadedFlag );
1537 //reset if the default style was loaded OK only
1538 if ( defaultLoadedFlag )
1539 {
1540 syncToLayer();
1541 }
1542 else
1543 {
1544 //otherwise let the user know what went wrong
1545 QMessageBox::information( this,
1546 tr( "Default Style" ),
1547 myMessage
1548 );
1549 }
1550}
1551
1552void QgsRasterLayerProperties::saveDefaultStyle_clicked()
1553{
1554
1555 apply(); // make sure the style to save is up-to-date
1556
1557 // a flag passed by reference
1558 bool defaultSavedFlag = false;
1559 // TODO Once the deprecated `saveDefaultStyle()` method is gone, just
1560 // remove the NOWARN_DEPRECATED tags
1562 // after calling this the above flag will be set true for success
1563 // or false if the save operation failed
1564 QString myMessage = mRasterLayer->saveDefaultStyle( defaultSavedFlag );
1566 if ( !defaultSavedFlag )
1567 {
1568 //let the user know what went wrong
1569 QMessageBox::information( this,
1570 tr( "Default Style" ),
1571 myMessage
1572 );
1573 }
1574}
1575
1576
1577void QgsRasterLayerProperties::loadStyle_clicked()
1578{
1579 QgsSettings settings;
1580 QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1581
1582 QString fileName = QFileDialog::getOpenFileName(
1583 this,
1584 tr( "Load layer properties from style file" ),
1585 lastUsedDir,
1586 tr( "QGIS Layer Style File" ) + " (*.qml)" );
1587 if ( fileName.isEmpty() )
1588 return;
1589
1590 // ensure the user never omits the extension from the file name
1591 if ( !fileName.endsWith( QLatin1String( ".qml" ), Qt::CaseInsensitive ) )
1592 fileName += QLatin1String( ".qml" );
1593
1594 mOldStyle = mRasterLayer->styleManager()->style( mRasterLayer->styleManager()->currentStyle() );
1595
1596 bool defaultLoadedFlag = false;
1597 QString message = mRasterLayer->loadNamedStyle( fileName, defaultLoadedFlag );
1598 if ( defaultLoadedFlag )
1599 {
1600 settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
1601 syncToLayer();
1602 }
1603 else
1604 {
1605 QMessageBox::information( this, tr( "Save Style" ), message );
1606 }
1607}
1608
1609
1610void QgsRasterLayerProperties::saveStyleAs_clicked()
1611{
1612 QgsSettings settings;
1613 QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1614
1615 QString selectedFilter;
1616 QString outputFileName = QFileDialog::getSaveFileName(
1617 this,
1618 tr( "Save layer properties as style file" ),
1619 lastUsedDir,
1620 tr( "QGIS Layer Style File" ) + " (*.qml)" + ";;" + tr( "Styled Layer Descriptor" ) + " (*.sld)",
1621 &selectedFilter );
1622 if ( outputFileName.isEmpty() )
1623 return;
1624
1625 StyleType type;
1626 // use selectedFilter to set style type
1627 if ( selectedFilter.contains( QStringLiteral( ".qml" ), Qt::CaseInsensitive ) )
1628 {
1629 outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "qml" ) );
1630 type = StyleType::QML;
1631 }
1632 else
1633 {
1634 outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "sld" ) );
1635 type = StyleType::SLD;
1636 }
1637
1638 apply(); // make sure the style to save is up-to-date
1639
1640 // then export style
1641 bool defaultLoadedFlag = false;
1642 QString message;
1643 switch ( type )
1644 {
1645 case QML:
1646 {
1647 message = mRasterLayer->saveNamedStyle( outputFileName, defaultLoadedFlag );
1648 break;
1649 }
1650 case SLD:
1651 {
1652 message = mRasterLayer->saveSldStyle( outputFileName, defaultLoadedFlag );
1653 break;
1654 }
1655 }
1656 if ( defaultLoadedFlag )
1657 {
1658 settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
1659 sync();
1660 }
1661 else
1662 QMessageBox::information( this, tr( "Save Style" ), message );
1663}
1664
1665void QgsRasterLayerProperties::restoreWindowModality()
1666{
1667 hide();
1668 setModal( true );
1669 show();
1670 raise();
1671 activateWindow();
1672}
1673
1674//
1675//
1676// Next four methods for saving and restoring QMD metadata
1677//
1678//
1679
1680void QgsRasterLayerProperties::loadMetadata()
1681{
1682 QgsSettings myQSettings; // where we keep last used filter in persistent state
1683 QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1684
1685 QString myFileName = QFileDialog::getOpenFileName( this, tr( "Load layer metadata from metadata file" ), myLastUsedDir,
1686 tr( "QGIS Layer Metadata File" ) + " (*.qmd)" );
1687 if ( myFileName.isNull() )
1688 {
1689 return;
1690 }
1691
1692 QString myMessage;
1693 bool defaultLoadedFlag = false;
1694 myMessage = mRasterLayer->loadNamedMetadata( myFileName, defaultLoadedFlag );
1695
1696 //reset if the default style was loaded OK only
1697 if ( defaultLoadedFlag )
1698 {
1699 mMetadataWidget->setMetadata( &mRasterLayer->metadata() );
1700 }
1701 else
1702 {
1703 //let the user know what went wrong
1704 QMessageBox::warning( this, tr( "Load Metadata" ), myMessage );
1705 }
1706
1707 QFileInfo myFI( myFileName );
1708 QString myPath = myFI.path();
1709 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
1710
1711 activateWindow(); // set focus back to properties dialog
1712}
1713
1714void QgsRasterLayerProperties::saveMetadataAs()
1715{
1716 QgsSettings myQSettings; // where we keep last used filter in persistent state
1717 QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1718
1719 QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Metadata as QMD" ),
1720 myLastUsedDir, tr( "QMD File" ) + " (*.qmd)" );
1721 if ( myOutputFileName.isNull() ) //dialog canceled
1722 {
1723 return;
1724 }
1725
1726 mMetadataWidget->acceptMetadata();
1727
1728 //ensure the user never omitted the extension from the file name
1729 if ( !myOutputFileName.endsWith( QgsMapLayer::extensionPropertyType( QgsMapLayer::Metadata ), Qt::CaseInsensitive ) )
1730 {
1732 }
1733
1734 bool defaultLoadedFlag = false;
1735 QString message = mRasterLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
1736 if ( defaultLoadedFlag )
1737 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
1738 else
1739 QMessageBox::information( this, tr( "Save Metadata" ), message );
1740}
1741
1742void QgsRasterLayerProperties::saveDefaultMetadata()
1743{
1744 mMetadataWidget->acceptMetadata();
1745
1746 bool defaultSavedFlag = false;
1747 QString errorMsg = mRasterLayer->saveDefaultMetadata( defaultSavedFlag );
1748 if ( !defaultSavedFlag )
1749 {
1750 QMessageBox::warning( this, tr( "Default Metadata" ), errorMsg );
1751 }
1752}
1753
1754void QgsRasterLayerProperties::loadDefaultMetadata()
1755{
1756 bool defaultLoadedFlag = false;
1757 QString myMessage = mRasterLayer->loadNamedMetadata( mRasterLayer->metadataUri(), defaultLoadedFlag );
1758 //reset if the default metadata was loaded OK only
1759 if ( defaultLoadedFlag )
1760 {
1761 mMetadataWidget->setMetadata( &mRasterLayer->metadata() );
1762 }
1763 else
1764 {
1765 QMessageBox::information( this, tr( "Default Metadata" ), myMessage );
1766 }
1767}
1768
1769
1770void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1771{
1772 if ( lbxPyramidResolutions->selectedItems().empty() )
1773 {
1774 buttonBuildPyramids->setEnabled( false );
1775 }
1776 else
1777 {
1778 buttonBuildPyramids->setEnabled( true );
1779 }
1780}
1781
1782void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1783{
1784 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1785 mSliderBrightness->setValue( 0 );
1786 mSliderContrast->setValue( 0 );
1787 mGammaSpinBox->setValue( 1.0 );
1788 sliderSaturation->setValue( 0 );
1789 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1790 mColorizeCheck->setChecked( false );
1791 sliderColorizeStrength->setValue( 100 );
1792 mInvertColorsCheck->setChecked( false );
1793}
1794
1795bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1796{
1797 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1798}
1799
1800void QgsRasterLayerProperties::updateInformationContent()
1801{
1803 // Inject the stylesheet
1804 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1805 mMetadataViewer->setHtml( html );
1806 mMetadataFilled = true;
1807}
1808
1809void QgsRasterLayerProperties::onCancel()
1810{
1811 if ( mOldStyle.xmlData() != mRasterLayer->styleManager()->style( mRasterLayer->styleManager()->currentStyle() ).xmlData() )
1812 {
1813 // need to reset style to previous - style applied directly to the layer (not in apply())
1814 QString myMessage;
1815 QDomDocument doc( QStringLiteral( "qgis" ) );
1816 int errorLine, errorColumn;
1817 doc.setContent( mOldStyle.xmlData(), false, &myMessage, &errorLine, &errorColumn );
1818 mRasterLayer->importNamedStyle( doc, myMessage );
1819 syncToLayer();
1820 }
1821 if ( mBackupCrs != mRasterLayer->crs() )
1822 mRasterLayer->setCrs( mBackupCrs );
1823}
1824
1825void QgsRasterLayerProperties::showHelp()
1826{
1827 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1828
1829 if ( helpPage.isValid() )
1830 {
1831 QgsHelp::openHelp( helpPage.toString() );
1832 }
1833 else
1834 {
1835 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1836 }
1837}
1838
1839void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1840{
1841 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1842}
1843
1844void QgsRasterLayerProperties::updateGammaSlider( double value )
1845{
1846 whileBlocking( mSliderGamma )->setValue( value * 100 );
1847}
@ Float32
Thirty two bit floating point (float)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Float64
Sixty four bit floating point (double)
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QgsRasterRendererRegistry * rasterRendererRegistry()
Returns the application's raster renderer registry, used for managing raster layer renderers.
@ WebBrowser
StyleSheet for Qt GUI widgets (based on QLabel or QTextBrowser), supports basic CSS and Qt extensions...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QRegularExpression shortNameRegularExpression()
Returns the short name regular expression for line edit validator.
Brightness/contrast and gamma correction filter pipe for rasters.
int contrast() const
Returns current contrast level.
int brightness() const
Returns current brightness level.
double gamma() const
Returns current gamma value.
void setGamma(double gamma)
Set gamma value.
void setContrast(int contrast)
Set contrast level.
void setBrightness(int brightness)
Set brightness level.
This class represents a coordinate reference system (CRS).
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
virtual QString name() const =0
Returns a provider name.
static bool run(const QgsCoordinateReferenceSystem &sourceCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr, const QString &windowTitle=QString())
Runs the dialog (if required) prompting for the desired transform to use from sourceCrs to destinatio...
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QString ensureFileNameHasExtension(const QString &fileName, const QStringList &extensions)
Ensures that a fileName ends with an extension from the provided list of extensions.
static QgsProviderSourceWidgetProviderRegistry * sourceWidgetProviderRegistry()
Returns the registry of provider source widget providers.
Definition qgsgui.cpp:108
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
Definition qgsgui.cpp:73
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Factory method to create the renderer for this type.
Color and saturation filter pipe for rasters.
void setColorizeOn(bool colorizeOn)
void setSaturation(int saturation)
bool invertColors() const
Returns true if the filter inverts colors.
void setGrayscaleMode(QgsHueSaturationFilter::GrayscaleMode grayscaleMode)
void setInvertColors(bool invertColors)
Sets whether the filter will invert colors.
QgsHueSaturationFilter::GrayscaleMode grayscaleMode() const
void setColorizeColor(const QColor &colorizeColor)
void setColorizeStrength(int colorizeStrength)
Map canvas is a class for displaying all GIS data types on a canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Factory class for creating custom map layer property pages.
virtual bool supportsLayer(QgsMapLayer *layer) const
Check if the layer is supported for this widget.
virtual QIcon icon() const
The icon that will be shown in the UI for the panel.
virtual QgsMapLayerConfigWidget * createWidget(QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget=true, QWidget *parent=nullptr) const =0
Factory function to create the widget on demand as needed by the dock.
virtual ParentPage parentPage() const
Returns the associated parent page, for factories which create sub-components of a standard page.
virtual QString title() const
The title of the panel.
virtual bool supportLayerPropertiesDialog() const
Flag if widget is supported for use in layer properties dialog.
@ Temporal
Factory creates sub-components of the temporal properties page (only supported for raster layer tempo...
@ NoParent
Factory creates pages itself, not sub-components.
virtual QString layerPropertiesPagePositionHint() const
Returns a tab name hinting at where this page should be inserted into the layer properties tab list.
A panel widget that can be shown in the map style dock.
static QgsMapLayerLegend * defaultRasterLegend(QgsRasterLayer *rl)
Create new legend implementation for raster layer.
void removesExtraMenuSeparators(QMenu *m)
removes extra separators from the menu
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
QString currentStyle() const
Returns name of the current style.
static bool isDefault(const QString &styleName)
Returns true if this is the default style.
QgsMapLayerStyle style(const QString &name) const
Returns data of a stored style - accessed by its unique name.
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
QString xmlData() const
Returns XML content of the style.
Base class for all map layer types.
Definition qgsmaplayer.h:73
void setShortName(const QString &shortName)
Sets the short name of the layer used by QGIS Server to identify the layer.
QString name
Definition qgsmaplayer.h:76
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
virtual bool importNamedStyle(QDomDocument &doc, QString &errorMsg, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Import the properties of this layer from a QDomDocument.
void setAbstract(const QString &abstract)
Sets the abstract of the layer used by QGIS Server in GetCapabilities request.
virtual QString saveSldStyle(const QString &uri, bool &resultFlag) const
Saves the properties of this layer to an SLD format file.
QString source() const
Returns the source for the layer.
void setLegendUrl(const QString &legendUrl)
Sets the URL for the layer's legend.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:79
QString legendPlaceholderImage() const
Returns path to the placeholder image or an empty string if a generated legend is shown.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
virtual QString loadDefaultStyle(bool &resultFlag)
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
virtual QString loadNamedMetadata(const QString &uri, bool &resultFlag)
Retrieve a named metadata for this layer if one exists (either as a .qmd file on disk or as a record ...
bool hasAutoRefreshEnabled() const
Returns true if auto refresh is enabled for the layer.
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
void setAttributionUrl(const QString &attribUrl)
Sets the attribution URL of the layer used by QGIS Server in GetCapabilities request.
void setAutoRefreshEnabled(bool enabled)
Sets whether auto refresh is enabled for the layer.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
QgsLayerMetadata metadata
Definition qgsmaplayer.h:78
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
void setDataUrl(const QString &dataUrl)
Sets the DataUrl of the layer used by QGIS Server in GetCapabilities request.
void setKeywordList(const QString &keywords)
Sets the keyword list of the layer used by QGIS Server in GetCapabilities request.
void setAttribution(const QString &attrib)
Sets the attribution of the layer used by QGIS Server in GetCapabilities request.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
virtual QString saveDefaultMetadata(bool &resultFlag)
Save the current metadata of this layer as the default metadata (either as a .qmd file on disk or as ...
void setDataUrlFormat(const QString &dataUrlFormat)
Sets the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
void setScaleBasedVisibility(bool enabled)
Sets whether scale based visibility is enabled for the layer.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
virtual QString loadNamedStyle(const QString &uri, bool &resultFlag, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Retrieve a named style for this layer if one exists (either as a .qml file on disk or as a record in ...
void emitStyleChanged()
Triggers an emission of the styleChanged() signal.
static QString extensionPropertyType(PropertyType type)
Returns the extension of a Property.
void setName(const QString &name)
Set the display name of the layer.
void setAutoRefreshInterval(int interval)
Sets the auto refresh interval (in milliseconds) for the layer.
QString saveNamedMetadata(const QString &uri, bool &resultFlag)
Save the current metadata of this layer as a named metadata (either as a .qmd file on disk or as a re...
void setLegendPlaceholderImage(const QString &imgPath)
Set placeholder image for legend.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
void setDataSource(const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag=false)
Updates the data source of the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
QString legendUrl() const
Returns the URL for the layer's legend.
void setLegendUrlFormat(const QString &legendUrlFormat)
Sets the format for a URL based layer legend.
virtual QString saveNamedStyle(const QString &uri, bool &resultFlag, StyleCategories categories=AllStyleCategories)
Save the properties of this layer as a named style (either as a .qml file on disk or as a record in t...
void setLegend(QgsMapLayerLegend *legend)
Assign a legend controller to the map layer.
virtual QString metadataUri() const
Retrieve the metadata URI for this layer (either as a .qmd file on disk or as a record in the users s...
int autoRefreshInterval
Definition qgsmaplayer.h:77
virtual QString saveDefaultStyle(bool &resultFlag, StyleCategories categories)
Save the properties of this layer as the default style (either as a .qml file on disk or as a record ...
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
void deactivated()
signal emitted once the map tool is deactivated
A wizard to edit metadata on a map layer.
void acceptMetadata()
Saves the metadata to the layer.
void crsChanged()
If the CRS is updated.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas associated with the widget.
void setMetadata(const QgsAbstractMetadataBase *metadata)
Sets the metadata to display in the widget.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Renderer for multiband images with the color components.
A base dialog for options and properties dialogs that offers vertical tabs.
void addPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QStringList &path=QStringList())
Adds a new page to the dialog pages.
virtual void optionsStackedWidget_CurrentChanged(int index)
Select relevant tab on current page change.
void insertPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QString &before, const QStringList &path=QStringList())
Inserts a new page into the dialog pages.
void restoreOptionsBaseUi(const QString &title=QString())
Restore the base ui.
QStackedWidget * mOptStackedWidget
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
static bool layerIsContainedInGroupLayer(QgsProject *project, QgsMapLayer *layer)
Returns true if the specified layer is a child layer from any QgsGroupLayer in the given project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
QgsProviderSourceWidget * createWidget(QgsMapLayer *layer, QWidget *parent=nullptr)
Creates a new widget to configure the source of the specified layer.
void validChanged(bool isValid)
Emitted whenever the validation status of the widget changes.
virtual QString sourceUri() const =0
Returns the source URI as currently defined by the widget.
virtual void setMapCanvas(QgsMapCanvas *mapCanvas)
Sets a map canvas associated with the widget.
virtual void setSourceUri(const QString &uri)=0
Sets the source uri to show in the widget.
Feedback object tailored for raster block reading.
static QString printValue(double value)
Print double value with all necessary significant digits.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Widget creation function (mainly for the use by the renderer registry)
Base class for raster data providers.
virtual QString buildPyramids(const QList< QgsRasterPyramid > &pyramidList, const QString &resamplingMethod="NEAREST", QgsRaster::RasterPyramidsFormat format=QgsRaster::PyramidsGTiff, const QStringList &configOptions=QStringList(), QgsRasterBlockFeedback *feedback=nullptr)
Creates pyramid overviews.
Qgis::DataType sourceDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
virtual QList< QgsRasterPyramid > buildPyramidList(const QList< int > &overviewList=QList< int >())
Returns the raster layers pyramid list.
void setRendererWidget(const QString &name, QgsRasterRendererWidget *rendererWidget=nullptr)
Sets the renderer widget (or just its name if there is no widget)
void setActive(bool activeFlag)
Activate the histogram widget.
@ BuildPyramids
Supports building of pyramids (overviews)
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
StyleType
enumeration for the different types of style
void addPropertiesPageFactory(const QgsMapLayerConfigWidgetFactory *factory)
Adds a properties page factory to the raster layer properties dialog.
QgsRasterLayerProperties(QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent=nullptr, Qt::WindowFlags=QgsGuiUtils::ModalDialogFlags)
Constructor.
void optionsStackedWidget_CurrentChanged(int index) override
auto slot executed when the active page in the main widget stack is changed
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
A widget for configuring the temporal properties for a raster layer.
void syncToLayer()
Updates the widget state to match the current layer state.
void saveTemporalProperties()
Save widget temporal properties inputs.
void addWidget(QgsMapLayerConfigWidget *widget SIP_TRANSFER)
Adds a child widget to the properties widget.
Represents a raster layer.
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
QgsRasterPipe * pipe()
Returns the raster pipe.
QgsBrightnessContrastFilter * brightnessFilter() const
Returns the raster's brightness/contrast filter.
LayerType rasterType()
Returns the raster layer type (which is a read only property).
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
QString providerType() const
[ data provider interface ] Which provider is being used for this Raster Layer?
void setRenderer(QgsRasterRenderer *renderer)
Sets the raster's renderer.
QgsHueSaturationFilter * hueSaturationFilter() const
Returns the raster's hue/saturation filter.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the pipe's property collection, used for data defined overrides.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in raster pipes.
Property
Data definable properties.
@ RendererOpacity
Raster renderer global opacity.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the pipe's property collection, used for data defined overrides.
This struct is used to store pyramid info for the raster layer.
Raster values range container.
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
bool rendererData(const QString &rendererName, QgsRasterRendererRegistryEntry &data) const
Abstract base class for widgets which configure a QgsRasterRenderer.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
virtual void doComputations()
Load programmatically with current values.
virtual QgsRasterRenderer * renderer()=0
Creates a new renderer, using the properties defined in the widget.
Raster renderer pipe that applies colors to a raster.
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
virtual QString type() const
Returns a unique string representation of the renderer type.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
virtual QList< int > usesBands() const
Returns a list of band numbers used by the renderer.
void setAlphaBand(int band)
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
void setRasterTransparency(QgsRasterTransparency *t)
void setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
Widget to control a layers transparency and related options.
void syncToLayer()
Sync the widget state to the layer set for the widget.
QgsMapToolEmitPoint * pixelSelectorTool() const
Returns the (possibly nullptr) map pixel selector tool.
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
void setTransparentSingleValuePixelList(const QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
void setTransparentThreeValuePixelList(const QList< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
RasterPyramidsFormat
Definition qgsraster.h:74
@ MultiBandColor
Definition qgsraster.h:92
@ SingleBandGray
Definition qgsraster.h:84
A rectangle specified with double values.
void setMetadataUrls(const QList< QgsServerMetadataUrlProperties::MetadataUrl > &metaUrls)
Sets a the list of metadata URL for the layer.
QList< QgsServerMetadataUrlProperties::MetadataUrl > metadataUrls() const
Returns a list of metadataUrl resources associated for the layer.
This class is a composition of two QSettings instances:
Definition qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Creates new raster renderer widget.
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
Definition qgswebview.h:66
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:3061
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:3060
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:2453
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugMsg(str)
Definition qgslogger.h:38
QList< QgsRasterRange > QgsRasterRangeList
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.
Registry for raster renderer entries.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction
QString format
Format specification of online resource.