QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
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
19
20#include <limits>
21#include <typeinfo>
22
23#include "qgsapplication.h"
27#include "qgsdoublevalidator.h"
30#include "qgsexpressionfinder.h"
31#include "qgsfileutils.h"
32#include "qgsgui.h"
36#include "qgslogger.h"
37#include "qgsmapcanvas.h"
39#include "qgsmaplayerlegend.h"
42#include "qgsmaptip.h"
43#include "qgsmaptoolemitpoint.h"
45#include "qgsmetadatawidget.h"
49#include "qgsproject.h"
50#include "qgsprojectutils.h"
58#include "qgsrasterlayer.h"
60#include "qgsrasterpyramid.h"
61#include "qgsrasterrange.h"
62#include "qgsrasterrenderer.h"
67#include "qgssettings.h"
70#include "qgsvectorlayer.h"
71#include "qgswebframe.h"
72#include "qgswebview.h"
73
74#include "moc_qgsrasterlayerproperties.cpp"
75
76#if WITH_QTWEBKIT
77#include <QWebElement>
78#endif
79#include "qgshelp.h"
80
81#include <QDesktopServices>
82#include <QTableWidgetItem>
83#include <QHeaderView>
84#include <QTextStream>
85#include <QFile>
86#include <QFileDialog>
87#include <QMessageBox>
88#include <QPainter>
89#include <QLinearGradient>
90#include <QPainterPath>
91#include <QPolygonF>
92#include <QColorDialog>
93#include <QList>
94#include <QMouseEvent>
95#include <QVector>
96#include <QUrl>
97#include <QMenu>
98#include <QScreen>
99#include <QRegularExpressionValidator>
100#include <QRegularExpression>
101
102QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
103 : QgsLayerPropertiesDialog( lyr, canvas, QStringLiteral( "RasterLayerProperties" ), parent, fl )
104 // Constant that signals property not used.
105 , TRSTRING_NOT_SET( tr( "Not Set" ) )
106 , mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
107{
108 mGrayMinimumMaximumEstimated = true;
109 mRGBMinimumMaximumEstimated = true;
110
111 setupUi( this );
112
113 mMetadataViewer = new QgsWebView( this );
114 mOptsPage_Information->layout()->addWidget( mMetadataViewer );
115
116 mRasterTransparencyWidget = new QgsRasterTransparencyWidget( mRasterLayer, canvas, this );
117
118 transparencyScrollArea->setWidget( mRasterTransparencyWidget );
119
120 mLabelingWidget = new QgsRasterLabelingWidget( mRasterLayer, canvas, this );
121 QVBoxLayout *vl = new QVBoxLayout();
122 vl->setContentsMargins( 0, 0, 0, 0 );
123 vl->addWidget( mLabelingWidget );
124 mOptsPage_Labeling->setLayout( vl );
125
126 connect( buttonBuildPyramids, &QPushButton::clicked, this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
127 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsRasterLayerProperties::mCrsSelector_crsChanged );
128 connect( mRenderTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
129 connect( mResetColorRenderingBtn, &QToolButton::clicked, this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
130 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
131 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
132 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
133 initOptionsBase( false );
134 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
135
136 mSourceGroupBox->hide();
137
138 mBtnStyle = new QPushButton( tr( "Style" ) );
139 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
140
141 connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
142
143 connect( this, &QDialog::accepted, this, &QgsRasterLayerProperties::apply );
144 connect( this, &QDialog::rejected, this, &QgsRasterLayerProperties::rollback );
145
146 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsRasterLayerProperties::apply );
147
148 cbxPyramidsFormat->addItem( tr( "External" ), QVariant::fromValue( Qgis::RasterPyramidFormat::GeoTiff ) );
149 cbxPyramidsFormat->addItem( tr( "Internal (if possible)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Internal ) );
150 cbxPyramidsFormat->addItem( tr( "External (Erdas Imagine)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Erdas ) );
151
152 // brightness/contrast controls
153 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
154 connect( mBrightnessSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
155 mBrightnessSpinBox->setClearValue( 0 );
156
157 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
158 connect( mContrastSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
159 mContrastSpinBox->setClearValue( 0 );
160
161 // gamma correction controls
162 connect( mSliderGamma, &QAbstractSlider::valueChanged, this, &QgsRasterLayerProperties::updateGammaSpinBox );
163 connect( mGammaSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterLayerProperties::updateGammaSlider );
164 mGammaSpinBox->setClearValue( 1.0 );
165
166 // Connect saturation slider and spin box
167 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
168 connect( spinBoxSaturation, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
169 spinBoxSaturation->setClearValue( 0 );
170
171 // Connect colorize strength slider and spin box
172 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
173 connect( spinColorizeStrength, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
174 spinColorizeStrength->setClearValue( 100 );
175
176 // enable or disable saturation slider and spin box depending on grayscale combo choice
177 connect( comboGrayscale, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::toggleSaturationControls );
178
179 // enable or disable colorize colorbutton with colorize checkbox
180 connect( mColorizeCheck, &QAbstractButton::toggled, this, &QgsRasterLayerProperties::toggleColorizeControls );
181
182 // enable or disable Build Pyramids button depending on selection in pyramid list
183 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged, this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
184
185 mRefreshSettingsWidget->setLayer( mRasterLayer );
186 mMapLayerServerPropertiesWidget->setHasWfsTitle( false );
187 mMapLayerServerPropertiesWidget->setServerProperties( mRasterLayer->serverProperties() );
188
189 // set up the scale based layer visibility stuff....
190 mScaleRangeWidget->setMapCanvas( mCanvas );
191 chkUseScaleDependentRendering->setChecked( lyr->hasScaleBasedVisibility() );
192 mScaleRangeWidget->setScaleRange( lyr->minimumScale(), lyr->maximumScale() );
193
194 // build GUI components
195 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
196 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
197
198 initMapTipPreview();
199
200 if ( !mRasterLayer )
201 {
202 return;
203 }
204
205 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
206
207 updateRasterAttributeTableOptionsPage();
208
209 connect( mRasterLayer, &QgsRasterLayer::rendererChanged, this, &QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage );
210
211 connect( mCreateRasterAttributeTableButton, &QPushButton::clicked, this, [this] {
212 if ( mRasterLayer->canCreateRasterAttributeTable() )
213 {
214 // Create the attribute table from the renderer
215 QgsCreateRasterAttributeTableDialog dlg { mRasterLayer };
216 dlg.setOpenWhenDoneVisible( false );
217 if ( dlg.exec() == QDialog::Accepted )
218 {
219 updateRasterAttributeTableOptionsPage();
220 }
221 }
222 } );
223
224 connect( mLoadRasterAttributeTableFromFileButton, &QPushButton::clicked, this, [this] {
225 // Load the attribute table from a VAT.DBF file
226 QgsLoadRasterAttributeTableDialog dlg { mRasterLayer };
227 dlg.setOpenWhenDoneVisible( false );
228 if ( dlg.exec() == QDialog::Accepted )
229 {
230 updateRasterAttributeTableOptionsPage();
231 }
232 } );
233
234 mBackupCrs = mRasterLayer->crs();
235
236 // Handles window modality raising canvas
237 if ( mCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
238 {
239 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [this] {
240 hide();
241 setModal( true );
242 show();
243 raise();
244 activateWindow();
245 } );
246
247 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [this] {
248 hide();
249 setModal( false );
250
251 // Transfer focus to the canvas to use the selector tool
252 mCanvas->window()->raise();
253 mCanvas->window()->activateWindow();
254 mCanvas->window()->setFocus();
255 } );
256 }
257
258 if ( mCanvas )
259 {
260 mContext = mCanvas->createExpressionContext();
261 }
262 else
263 {
268 }
269
270 // Initialize with layer center
271 mContext << QgsExpressionContextUtils::mapLayerPositionScope( mRasterLayer->extent().center() );
272 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
273
274 connect( mInsertExpressionButton, &QAbstractButton::clicked, this, [this] {
275 // Get the linear indexes if the start and end of the selection
276 int selectionStart = mMapTipWidget->selectionStart();
277 int selectionEnd = mMapTipWidget->selectionEnd();
278 QString expression = QgsExpressionFinder::findAndSelectActiveExpression( mMapTipWidget );
279 QgsExpressionBuilderDialog exprDlg( nullptr, expression, this, QStringLiteral( "generic" ), mContext );
280
281 exprDlg.setWindowTitle( tr( "Insert Expression" ) );
282 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
283 mMapTipWidget->insertText( "[%" + exprDlg.expressionText().trimmed() + "%]" );
284 else // Restore the selection
285 mMapTipWidget->setLinearSelection( selectionStart, selectionEnd );
286 } );
287
288 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
289
290 // Only do pyramids if dealing directly with GDAL.
291 if ( provider && ( provider->capabilities() & Qgis::RasterInterfaceCapability::BuildPyramids || provider->providerCapabilities() & Qgis::RasterProviderCapability::BuildPyramids ) )
292 {
293 // initialize resampling methods
294 cboResamplingMethod->clear();
295
296 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
297 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
298 {
299 cboResamplingMethod->addItem( method.second, method.first );
300 }
301
302 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
303 QString prefix = provider->name() + "/driverOptions/_pyramids/";
304 QgsSettings mySettings;
305 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
306 int idx = cboResamplingMethod->findData( defaultMethod );
307 if ( idx >= 0 )
308 cboResamplingMethod->setCurrentIndex( idx );
309
310
311 // build pyramid list
312 const QList<QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
313
314 for ( const QgsRasterPyramid &pyramid : myPyramidList )
315 {
316 if ( pyramid.getExists() )
317 {
318 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
319 }
320 else
321 {
322 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
323 }
324 }
325 }
326 else
327 {
328 // disable Pyramids tab completely
329 mOptsPage_Pyramids->setEnabled( false );
330 }
331
332 // We can calculate histogram for all data sources but estimated only if
333 // size is unknown - could also be enabled if well supported (estimated histogram
334 // and let user know that it is estimated)
335 if ( !provider || !( provider->capabilities() & Qgis::RasterInterfaceCapability::Size ) )
336 {
337 // disable Histogram tab completely
338 mOptsPage_Histogram->setEnabled( false );
339 }
340
341 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
342 layout->setContentsMargins( 0, 0, 0, 0 );
343 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
344 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
345 mMetadataWidget->setMapCanvas( mCanvas );
346 layout->addWidget( mMetadataWidget );
347 metadataFrame->setLayout( layout );
348
349 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
350 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
351 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
352 temporalLayout->addWidget( mTemporalWidget );
353
354 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( Qgis::CrsWktVariant::Preferred ), 2 );
355 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
356 mCrsSelector->setCrs( mRasterLayer->crs() );
357
358 // Set text for pyramid info box
359 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
360 QString pyramidHeader = tr( "Description" );
361 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
362 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." );
363 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
364 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
365 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
366
367 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader, pyramidSentence1, pyramidSentence2, pyramidSentence3, pyramidSentence4, pyramidSentence5 ) );
368
369 //resampling
370 mResamplingGroupBox->setSaveCheckedState( true );
371 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
372 mResamplingUtils.refreshWidgetsFromLayer();
373
374 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
375
376 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
377 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
378
379 // Hue and saturation color control
380 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
381 //set hue and saturation controls to current values
382 if ( hueSaturationFilter )
383 {
384 sliderSaturation->setValue( hueSaturationFilter->saturation() );
385 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
386
387 // Set initial state of saturation controls based on grayscale mode choice
388 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
389
390 // Set initial state of colorize controls
391 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
392 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
393 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
394 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
395 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
396 }
397
398 //blend mode
399 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
400 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
401
402 //transparency band
403 if ( provider )
404 {
405 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
406 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
407
408// Alpha band is set in sync()
409#if 0
410 if ( renderer )
411 {
412 QgsDebugMsgLevel( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ), 2 );
413 if ( renderer->alphaBand() > 0 )
414 {
415 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
416 }
417 }
418#endif
419 }
420
421 // create histogram widget
422 mHistogramWidget = nullptr;
423 if ( mOptsPage_Histogram->isEnabled() )
424 {
425 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
426 mHistogramStackedWidget->addWidget( mHistogramWidget );
427 }
428
429 //insert renderer widgets into registry
437
438 //fill available renderers into combo box
440 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
441 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
442 for ( const QString &name : constRenderersList )
443 {
444 if ( QgsApplication::rasterRendererRegistry()->rendererData( name, entry ) )
445 {
446 if ( ( mRasterLayer->rasterType() != Qgis::RasterLayerType::SingleBandColorData && entry.name != QLatin1String( "singlebandcolordata" ) ) || ( mRasterLayer->rasterType() == Qgis::RasterLayerType::SingleBandColorData && entry.name == QLatin1String( "singlebandcolordata" ) ) )
447 {
448 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
449 }
450 }
451 }
452 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
453
454 int widgetIndex = 0;
455 if ( renderer )
456 {
457 QString rendererType = renderer->type();
458 widgetIndex = mRenderTypeComboBox->findData( rendererType );
459 if ( widgetIndex != -1 )
460 {
461 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
462 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
463 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
464 }
465
466 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
467 {
468 // no band rendering options for singlebandcolordata, so minimize group box
469 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
470 sizep.setVerticalStretch( 0 );
471 sizep.setVerticalPolicy( QSizePolicy::Maximum );
472 mBandRenderingGrpBx->setSizePolicy( sizep );
473 mBandRenderingGrpBx->updateGeometry();
474 }
475
476 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
477 {
478 mWMSPrintGroupBox->hide();
479 mPublishDataSourceUrlCheckBox->hide();
480 mBackgroundLayerCheckBox->hide();
481 }
482 }
483
484#ifdef WITH_QTWEBKIT
485 // Setup information tab
486
487 const int horizontalDpi = logicalDpiX();
488
489 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
490 if ( horizontalDpi > 96 )
491 {
492 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
493 }
494 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
495 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::openUrl );
496 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
497 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
498
499#endif
500
501 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::Property::RendererOpacity );
502
503 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
504
505 setMetadataWidget( mMetadataWidget, mOptsPage_Metadata );
506
507 QMenu *menuStyle = new QMenu( this );
508 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle );
509 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs );
510 menuStyle->addSeparator();
511 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveStyleAsDefault );
512 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle );
513 mBtnStyle->setMenu( menuStyle );
514 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
515
516 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
517 QMenu *menuMetadata = new QMenu( this );
518 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadataFromFile );
519 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataToFile );
520 menuMetadata->addSeparator();
521 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveMetadataAsDefault );
522 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
523 mBtnMetadata->setMenu( menuMetadata );
524 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
525
526 // update based on lyr's current state
527 sync();
528
529 QgsSettings settings;
530 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
531 // this will be read by restoreOptionsBaseUi()
532 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
533 {
534 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ), mOptStackedWidget->indexOf( mOptsPage_Style ) );
535 }
536
537 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
538
539 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
540
541 //Add help page references
542 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
543 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
544 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
545 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
546
547 if ( mOptsPage_Histogram )
548 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
549
550 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
551 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
552
553 if ( mOptsPage_Pyramids )
554 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
555
556 if ( mOptsPage_Display )
557 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#display-properties" ) );
558
559 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
560 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
561 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
562
563 initialize();
564}
565
567{
568 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
569 {
570 return;
571 }
572
573 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
574 switch ( factory->parentPage() )
575 {
577 {
578 mConfigWidgets << page;
579
580 const QString beforePage = factory->layerPropertiesPagePositionHint();
581 if ( beforePage.isEmpty() )
582 addPage( factory->title(), factory->title(), factory->icon(), page );
583 else
584 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
585 break;
586 }
587
589 mTemporalWidget->addWidget( page );
590 break;
591 }
592}
593
598
599void QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage()
600{
601 if ( mRasterAttributeTableWidget )
602 {
603 mOptsPage_RasterAttributeTable->layout()->removeWidget( mRasterAttributeTableWidget );
604 mRasterAttributeTableWidget = nullptr;
605 }
606
607 // Setup raster attribute table
608 if ( mRasterLayer->attributeTableCount() > 0 )
609 {
610 mRasterAttributeTableWidget = new QgsRasterAttributeTableWidget( this, mRasterLayer );
611 mOptsPage_RasterAttributeTable->layout()->addWidget( mRasterAttributeTableWidget );
612 // When the renderer changes we need to sync the style options page
613 connect( mRasterAttributeTableWidget, &QgsRasterAttributeTableWidget::rendererChanged, this, &QgsRasterLayerProperties::syncToLayer );
614 mNoRasterAttributeTableWidget->hide();
615 }
616 else
617 {
618 mNoRasterAttributeTableWidget->show();
619 mCreateRasterAttributeTableButton->setEnabled( mRasterLayer->canCreateRasterAttributeTable() );
620 }
621}
622
623void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
624{
625 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
626 QgsRasterRendererWidget *oldWidget = mRendererWidget;
627 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
628
629 int alphaBand = -1;
630 double opacity = 1;
631 QColor nodataColor;
632 const QList<int> oldBands = oldRenderer ? oldRenderer->usesBands() : QList<int>();
633 if ( oldRenderer )
634 {
635 // Retain alpha band and opacity when switching renderer
636 alphaBand = oldRenderer->alphaBand();
637 opacity = oldRenderer->opacity();
638 nodataColor = oldRenderer->nodataColor();
639 }
640
641 QgsRasterRendererRegistryEntry rendererEntry;
642 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
643 {
644 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
645 {
646 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
647 // Current canvas extent (used to calc min/max) in layer CRS
648 QgsRectangle myExtent = mCanvas->mapSettings().outputExtentToLayerExtent( mRasterLayer, mCanvas->extent() );
649 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
650 {
651 if ( rendererName == QLatin1String( "singlebandgray" ) )
652 {
653 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::SingleBandGray, mRasterLayer->dataProvider() ) );
654 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
655 }
656 else if ( rendererName == QLatin1String( "multibandcolor" ) )
657 {
658 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::MultiBandColor, mRasterLayer->dataProvider() ) );
659 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
660 }
661 }
662 mRasterLayer->renderer()->setAlphaBand( alphaBand );
663 mRasterLayer->renderer()->setOpacity( opacity );
664 mRasterLayer->renderer()->setNodataColor( nodataColor );
665 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
666 mRendererWidget->setMapCanvas( mCanvas );
667 mRendererStackedWidget->addWidget( mRendererWidget );
668 if ( oldWidget )
669 {
670 //compare used bands in new and old renderer and reset transparency dialog if different
671 std::unique_ptr<QgsRasterRenderer> newRenderer;
672 newRenderer.reset( mRendererWidget->renderer() );
673 const QList<int> newBands = newRenderer->usesBands();
674 if ( oldBands != newBands )
675 {
676 mRasterTransparencyWidget->syncToLayer();
677 }
678 }
679 }
680 }
681
682 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
683 if ( widgetIndex != -1 )
684 {
685 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
686 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
687 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
688 }
689
690 if ( mRendererWidget != oldWidget )
691 delete oldWidget;
692
693 if ( mHistogramWidget )
694 {
695 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
696 }
697}
698
699void QgsRasterLayerProperties::sync()
700{
701 QgsSettings myQSettings;
702
703 if ( !mSourceWidget )
704 {
705 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
706 if ( mSourceWidget )
707 {
708 QHBoxLayout *layout = new QHBoxLayout();
709 layout->addWidget( mSourceWidget );
710 mSourceGroupBox->setLayout( layout );
711 if ( !mSourceWidget->groupTitle().isEmpty() )
712 mSourceGroupBox->setTitle( mSourceWidget->groupTitle() );
713 mSourceGroupBox->show();
714
715 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [this]( bool isValid ) {
716 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
717 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
718 } );
719 }
720 }
721
722 if ( mSourceWidget )
723 {
724 mSourceWidget->setMapCanvas( mCanvas );
725 mSourceWidget->setSourceUri( mRasterLayer->source() );
726 }
727
728 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
729 if ( !provider )
730 return;
731
732 mRasterTransparencyWidget->syncToLayer();
733 mLabelingWidget->syncToLayer( mRasterLayer );
734
735 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
737 {
738 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
739 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
740 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
741 }
742
743 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
746 {
747 if ( mOptsPage_Pyramids )
748 {
749 delete mOptsPage_Pyramids;
750 mOptsPage_Pyramids = nullptr;
751 }
752 }
753
755 {
756 if ( mOptsPage_Histogram )
757 {
758 delete mOptsPage_Histogram;
759 mOptsPage_Histogram = nullptr;
760 delete mHistogramWidget;
761 mHistogramWidget = nullptr;
762 }
763 }
764
765 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
766
767 /*
768 * Style tab
769 */
770
771 //set brightness, contrast and gamma
772 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
773 if ( brightnessFilter )
774 {
775 mSliderBrightness->setValue( brightnessFilter->brightness() );
776 mSliderContrast->setValue( brightnessFilter->contrast() );
777 mGammaSpinBox->setValue( brightnessFilter->gamma() );
778 }
779
780 // Hue and saturation color control
781 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
782 //set hue and saturation controls to current values
783 if ( hueSaturationFilter )
784 {
785 sliderSaturation->setValue( hueSaturationFilter->saturation() );
786 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
787
788 // Set state of saturation controls based on grayscale mode choice
789 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
790
791 // Set state of colorize controls
792 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
793 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
794 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
795 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
796 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
797 }
798
799 // Resampling
800 mResamplingUtils.refreshWidgetsFromLayer();
801
802 mRefreshSettingsWidget->syncToLayer();
803 mMapLayerServerPropertiesWidget->sync();
804
805 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
806 /*
807 * General Tab
808 */
809
810 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
811
812 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
813 /*
814 * Metadata Tab
815 */
816 //populate the metadata tab's text browser widget with gdal metadata info
817 updateInformationContent();
818
819 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
820 mMapTipWidget->setText( mRasterLayer->mapTipTemplate() );
821
822 //WMS print layer
823 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
824 if ( wmsPrintLayer.isValid() )
825 {
826 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
827 }
828
829 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
830 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
831
832 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
833 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
834
835 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
836 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
837 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
838 mIncludeByDefaultInLayoutLegendsCheck->setChecked( mRasterLayer->legend() && !mRasterLayer->legend()->flags().testFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault ) );
839
840 mTemporalWidget->syncToLayer();
841
842 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
843 updateDataDefinedButtons();
844
845 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
846 {
847 page->syncToLayer( mRasterLayer );
848 }
849}
850
852{
853 if ( mSourceWidget )
854 {
855 const QString newSource = mSourceWidget->sourceUri();
856 if ( newSource != mRasterLayer->source() )
857 {
858 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
859 }
860 }
861
862 // Do nothing on "bad" layers
863 if ( !mRasterLayer->isValid() )
864 return;
865
866 // apply all plugin dialogs
867 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
868 {
869 page->apply();
870 }
871
872
873 /*
874 * Legend Tab
875 */
876 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
877 mLegendConfigEmbeddedWidget->applyToLayer();
878
879 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
880 /*
881 * Symbology Tab
882 */
883
884 //set whether the layer histogram should be inverted
885 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
886
887 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
888 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
889 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
890
891 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
892 /*
893 * Transparent Pixel Tab
894 */
895
896 mRasterTransparencyWidget->applyToRasterProvider( mRasterLayer->dataProvider() );
897
898 //set renderer from widget
899 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
900 if ( rendererWidget )
901 {
902 rendererWidget->doComputations();
903
904 mRasterLayer->setRenderer( rendererWidget->renderer() );
905 }
906
907 mBackupCrs = mRasterLayer->crs();
908 mMetadataWidget->acceptMetadata();
909 mMetadataFilled = false;
910
911 //transparency settings
912 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
913 mRasterTransparencyWidget->applyToRasterRenderer( rasterRenderer );
914
915 mLabelingWidget->apply();
916
917 if ( rasterRenderer )
918 {
919 // Sync the layer styling widget
920 mRasterLayer->emitStyleChanged();
921 }
922
923 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
924 /*
925 * General Tab
926 */
927 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
928
929 // set up the scale based layer visibility stuff....
930 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
931 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
932 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
933
934 mRefreshSettingsWidget->saveToLayer();
935 if ( mMapLayerServerPropertiesWidget->save() )
936 mMetadataFilled = true;
937
938 //update the legend pixmap
939 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
940 // pixmapLegend->setScaledContents( true );
941 // pixmapLegend->repaint();
942
943 mResamplingUtils.refreshLayerFromWidgets();
944
945 // Hue and saturation controls
946 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
947 if ( hueSaturationFilter )
948 {
949 hueSaturationFilter->setSaturation( sliderSaturation->value() );
950 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
951 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
952 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
953 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
954 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
955 }
956
957 //set the blend mode for the layer
958 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
959
960 // Update temporal properties
961 mTemporalWidget->saveTemporalProperties();
962
963 mRasterLayer->setCrs( mCrsSelector->crs() );
964
965 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
966 {
967 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
968 }
969
970 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
971 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
972
973 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
974
975 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
976 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
977
978 // Force a redraw of the legend
979 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
980 if ( QgsMapLayerLegend *legend = mRasterLayer->legend() )
981 {
982 legend->setFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault, !mIncludeByDefaultInLayoutLegendsCheck->isChecked() );
983 }
984
985 //make sure the layer is redrawn
986 mRasterLayer->triggerRepaint();
987
988 // notify the project we've made a change
990}
991
992void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
993{
994 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
995
996 auto feedback = std::make_unique<QgsRasterBlockFeedback>();
997
998 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
999 //
1000 // Go through the list marking any files that are selected in the listview
1001 // as true so that we can generate pyramids for them.
1002 //
1003 QList<QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1004 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1005 {
1006 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1007 //mark to be pyramided
1008 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1009 }
1010
1011 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1012 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1013 QgsSettings mySettings;
1014 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1015 mySettings.setValue( prefix + "resampling", resamplingMethod );
1016
1017 //
1018 // Ask raster layer to build the pyramids
1019 //
1020
1021 // let the user know we're going to possibly be taking a while
1022 QApplication::setOverrideCursor( Qt::WaitCursor );
1023 QString res = provider->buildPyramids(
1024 myPyramidList,
1025 resamplingMethod,
1026 cbxPyramidsFormat->currentData().value<Qgis::RasterPyramidFormat>(),
1027 QStringList(),
1028 feedback.get()
1029 );
1030 QApplication::restoreOverrideCursor();
1031 mPyramidProgress->setValue( 0 );
1032 buttonBuildPyramids->setEnabled( false );
1033 if ( !res.isNull() )
1034 {
1035 if ( res == QLatin1String( "CANCELED" ) )
1036 {
1037 // user canceled
1038 }
1039 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1040 {
1041 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Write access denied. Adjust the file permissions and try again." ) );
1042 }
1043 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1044 {
1045 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "The file was not writable. Some formats do not "
1046 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1047 }
1048 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1049 {
1050 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building pyramid overviews is not supported on this type of raster." ) );
1051 }
1052 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1053 {
1054 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1055 }
1056 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1057 {
1058 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building pyramid overviews is not supported on this type of raster." ) );
1059 }
1060 }
1061
1062 //
1063 // repopulate the pyramids list
1064 //
1065 lbxPyramidResolutions->clear();
1066 // Need to rebuild list as some or all pyramids may have failed to build
1067 myPyramidList = provider->buildPyramidList();
1068 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1069 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1070
1071 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1072 {
1073 if ( pyramid.getExists() )
1074 {
1075 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
1076 }
1077 else
1078 {
1079 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
1080 }
1081 }
1082 //update the legend pixmap
1083 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1084 // pixmapLegend->setScaledContents( true );
1085 // pixmapLegend->repaint();
1086
1087 //populate the metadata tab's text browser widget with gdal metadata info
1088 updateInformationContent();
1089}
1090
1091void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1092{
1093 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || !mRasterLayer->renderer() )
1094 {
1095 return;
1096 }
1097
1098 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1099 setRendererWidget( rendererName );
1100}
1101
1102void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1103{
1104 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
1105 mRasterLayer->setCrs( crs );
1106 mMetadataWidget->crsChanged();
1107}
1108
1109void QgsRasterLayerProperties::aboutToShowStyleMenu()
1110{
1111 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1112
1113 QMenu *m = qobject_cast<QMenu *>( sender() );
1114
1116 // re-add style manager actions!
1117 m->addSeparator();
1119}
1120
1122{
1123 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1124 if ( renderer )
1125 {
1126 setRendererWidget( renderer->type() );
1127 }
1128 sync();
1129 mRasterLayer->triggerRepaint();
1130}
1131
1133{
1135
1136 if ( !mHistogramWidget )
1137 return;
1138
1139 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1140 {
1141 mHistogramWidget->setActive( true );
1142 }
1143 else
1144 {
1145 mHistogramWidget->setActive( false );
1146 }
1147
1148 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1149 {
1150 //set the metadata contents (which can be expensive)
1151 updateInformationContent();
1152 }
1153}
1154
1155void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1156{
1157 button->blockSignals( true );
1158 button->init( static_cast<int>( key ), mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1159 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1160 button->registerExpressionContextGenerator( this );
1161 button->blockSignals( false );
1162}
1163
1164void QgsRasterLayerProperties::updateDataDefinedButtons()
1165{
1166 const QList<QgsPropertyOverrideButton *> propertyOverrideButtons { findChildren<QgsPropertyOverrideButton *>() };
1167 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1168 {
1169 updateDataDefinedButton( button );
1170 }
1171}
1172
1173void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1174{
1175 if ( !button )
1176 return;
1177
1178 if ( button->propertyKey() < 0 )
1179 return;
1180
1181 QgsRasterPipe::Property key = static_cast<QgsRasterPipe::Property>( button->propertyKey() );
1182 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1183}
1184
1185void QgsRasterLayerProperties::updateProperty()
1186{
1187 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1188 QgsRasterPipe::Property key = static_cast<QgsRasterPipe::Property>( button->propertyKey() );
1189 mPropertyCollection.setProperty( key, button->toProperty() );
1190}
1191
1192void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1193{
1194 // Enable or disable saturation controls based on choice of grayscale mode
1195 if ( grayscaleMode == 0 )
1196 {
1197 sliderSaturation->setEnabled( true );
1198 spinBoxSaturation->setEnabled( true );
1199 }
1200 else
1201 {
1202 sliderSaturation->setEnabled( false );
1203 spinBoxSaturation->setEnabled( false );
1204 }
1205}
1206
1207void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1208{
1209 // Enable or disable colorize controls based on checkbox
1210 btnColorizeColor->setEnabled( colorizeEnabled );
1211 sliderColorizeStrength->setEnabled( colorizeEnabled );
1212 spinColorizeStrength->setEnabled( colorizeEnabled );
1213}
1214
1215
1216QLinearGradient QgsRasterLayerProperties::redGradient()
1217{
1218 //define a gradient
1219 // TODO change this to actual polygon dims
1220 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1221 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1222 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1223 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1224 return myGradient;
1225}
1226QLinearGradient QgsRasterLayerProperties::greenGradient()
1227{
1228 //define a gradient
1229 // TODO change this to actual polygon dims
1230 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1231 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1232 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1233 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1234 return myGradient;
1235}
1236QLinearGradient QgsRasterLayerProperties::blueGradient()
1237{
1238 //define a gradient
1239 // TODO change this to actual polygon dims
1240 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1241 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1242 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1243 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1244 return myGradient;
1245}
1246QLinearGradient QgsRasterLayerProperties::grayGradient()
1247{
1248 //define a gradient
1249 // TODO change this to actual polygon dims
1250 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1251 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1252 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1253 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1254 return myGradient;
1255}
1256QLinearGradient QgsRasterLayerProperties::highlightGradient()
1257{
1258 //define another gradient for the highlight
1259 // TODO change this to actual polygon dims
1260 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1261 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1262 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1263 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1264 return myGradient;
1265}
1266
1267//
1268//
1269// Next four methods for saving and restoring qml style state
1270//
1271//
1272
1277
1278void QgsRasterLayerProperties::restoreWindowModality()
1279{
1280 hide();
1281 setModal( true );
1282 show();
1283 raise();
1284 activateWindow();
1285}
1286
1287void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1288{
1289 if ( lbxPyramidResolutions->selectedItems().empty() )
1290 {
1291 buttonBuildPyramids->setEnabled( false );
1292 }
1293 else
1294 {
1295 buttonBuildPyramids->setEnabled( true );
1296 }
1297}
1298
1299void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1300{
1301 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1302 mSliderBrightness->setValue( 0 );
1303 mSliderContrast->setValue( 0 );
1304 mGammaSpinBox->setValue( 1.0 );
1305 sliderSaturation->setValue( 0 );
1306 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1307 mColorizeCheck->setChecked( false );
1308 sliderColorizeStrength->setValue( 100 );
1309 mInvertColorsCheck->setChecked( false );
1310}
1311
1312bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1313{
1314 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1315}
1316
1317void QgsRasterLayerProperties::updateInformationContent()
1318{
1320 // Inject the stylesheet
1321 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1322 mMetadataViewer->setHtml( html );
1323 mMetadataFilled = true;
1324}
1325
1327{
1328 // Give the user a chance to save the raster attribute table edits.
1329 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1330 {
1331 mRasterAttributeTableWidget->setEditable( false, false );
1332 }
1334
1335 if ( mBackupCrs != mRasterLayer->crs() )
1336 mRasterLayer->setCrs( mBackupCrs );
1337}
1338
1339void QgsRasterLayerProperties::showHelp()
1340{
1341 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1342
1343 if ( helpPage.isValid() )
1344 {
1345 QgsHelp::openHelp( helpPage.toString() );
1346 }
1347 else
1348 {
1349 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1350 }
1351}
1352
1353void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1354{
1355 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1356}
1357
1358void QgsRasterLayerProperties::updateGammaSlider( double value )
1359{
1360 whileBlocking( mSliderGamma )->setValue( value * 100 );
1361}
1362
1363
1364bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1365{
1366 // If the map tip preview container is resized, resize the map tip
1367 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1368 {
1369 resizeMapTip();
1370 }
1371 return QgsOptionsDialogBase::eventFilter( obj, ev );
1372}
1373
1374void QgsRasterLayerProperties::initMapTipPreview()
1375{
1376 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1377 mMapTipSplitter->setSizes( { 400, 200 } );
1378 // Event filter is used to resize the map tip when the container is resized
1379 mMapTipPreviewContainer->installEventFilter( this );
1380
1381 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1382 // Create the WebView
1383 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1384 mMapTipPreviewLayout->addWidget( mMapTipPreview );
1385
1386#if WITH_QTWEBKIT
1387 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); //Handle link clicks by yourself
1388 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1389 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1390#endif
1391
1392 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1393 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1394 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1395
1396 // Disable scrollbars, avoid random resizing issues
1397 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1398 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1399
1400
1401 // Update the map tip preview when the expression or the map tip template changes
1402 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1403}
1404
1405void QgsRasterLayerProperties::updateMapTipPreview()
1406{
1407 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1408 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mCanvas, mMapTipWidget->text() );
1409 mMapTipPreview->setHtml( htmlContent );
1410}
1411
1412void QgsRasterLayerProperties::resizeMapTip()
1413{
1414 // Ensure the map tip is not bigger than the container
1415 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1416#if WITH_QTWEBKIT
1417 // Get the content size
1418 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1419 QStringLiteral( "#QgsWebViewContainer" )
1420 );
1421 const int width = container.geometry().width();
1422 const int height = container.geometry().height();
1423 mMapTipPreview->resize( width, height );
1424
1425 // Move the map tip to the center of the container
1426 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2, ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1427
1428#else
1429 mMapTipPreview->adjustSize();
1430#endif
1431}
@ BuildPyramids
Supports building of pyramids (overviews) (since QGIS 3.38 – this is a replacement for RasterInterfac...
Definition qgis.h:4895
@ SingleBandColorData
Single band containing color data.
Definition qgis.h:4767
RasterPyramidFormat
Raster pyramid formats.
Definition qgis.h:4802
@ GeoTiff
Geotiff .ovr (external).
Definition qgis.h:4803
@ Erdas
Erdas Image .aux (external).
Definition qgis.h:4805
@ SingleBandGray
A single band image drawn as a range of gray colors.
Definition qgis.h:4781
@ MultiBandColor
A layer containing 2 or more bands, mapped to RGB color space. In the case of a multiband with only t...
Definition qgis.h:4789
@ BuildPyramids
Supports building of pyramids (overviews) (Deprecated since QGIS 3.38 – use RasterProviderCapability:...
Definition qgis.h:4858
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
Definition qgis.h:4855
@ ExcludeByDefault
If set, the layer should not be included in legends by default, and must be manually added by a user.
Definition qgis.h:4555
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:387
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition qgis.h:386
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition qgis.h:2439
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 embedded browsers (QtWebKit), supports full standard CSS.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
int contrast() const
Returns current contrast level.
int brightness() const
Returns current brightness level.
double gamma() const
Returns current gamma value.
Represents a coordinate reference system (CRS).
A dialog which collects the information required to create a new raster attribute table.
void setOpenWhenDoneVisible(bool visible)
Sets the visibility of the "Open newly created raster attribute table" option to visible,...
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...
A generic dialog for building expression strings.
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 * mapLayerPositionScope(const QgsPointXY &position)
Sets the expression context variables which are available for expressions triggered by moving the mou...
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...
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QgsProviderSourceWidgetProviderRegistry * sourceWidgetProviderRegistry()
Returns the registry of provider source widget providers.
Definition qgsgui.cpp:131
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)
QPushButton * mBtnStyle
Style button.
void saveMetadataToFile()
Allows the user to save the layer's metadata as a file.
virtual void rollback()
Rolls back changes made to the layer.
void optionsStackedWidget_CurrentChanged(int index) override
void saveStyleAsDefault()
Saves the current layer style as the default for the layer.
QList< QgsMapLayerConfigWidget * > mConfigWidgets
Layer config widgets.
void setMetadataWidget(QgsMetadataWidget *widget, QWidget *page)
Sets the metadata widget and page associated with the dialog.
void loadDefaultStyle()
Reloads the default style for the layer.
void saveStyleAs()
Saves a style when appriate button is pressed.
virtual void syncToLayer()=0
Resets the dialog to the current layer state.
void loadStyle()
Triggers a dialog to load a saved style.
QgsMapCanvas * mCanvas
Associated map canvas.
void loadDefaultMetadata()
Reloads the default layer metadata for the layer.
QgsLayerPropertiesDialog(QgsMapLayer *layer, QgsMapCanvas *canvas, const QString &settingsKey, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsSettings *settings=nullptr)
Constructor for QgsLayerPropertiesDialog.
void loadMetadataFromFile()
Allows the user to load layer metadata from a file.
QPushButton * mBtnMetadata
Metadata button.
void initialize()
Initialize the dialog.
void saveMetadataAsDefault()
Saves the current layer metadata as the default for the layer.
void openUrl(const QUrl &url)
Handles opening a url from the dialog.
A dialog allowing selection of a VAT.DBF file and associating the resulting raster attribute table wi...
void setOpenWhenDoneVisible(bool visible)
Sets the visibility of the "Open newly created raster attribute table" option to visible,...
Map canvas is a class for displaying all GIS data types on a 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.
An abstract interface for implementations of legends for one map layer.
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
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
Base class for all map layer types.
Definition qgsmaplayer.h:80
void rendererChanged()
Signal emitted when renderer is changed.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
double maximumScale() const
Returns the maximum map scale (i.e.
Contains configuration for rendering maps.
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
void deactivated()
Emitted when the map tool is deactivated.
A wizard to edit metadata on a map layer.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
void addPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QStringList &path=QStringList(), const QString &key=QString())
Adds a new page to the dialog pages.
QStackedWidget * mOptStackedWidget
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
void insertPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QString &before, const QStringList &path=QStringList(), const QString &key=QString())
Inserts a new page into the dialog pages.
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 &crs)
Emitted when the selected CRS is changed.
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.
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
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.
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", Qgis::RasterPyramidFormat format=Qgis::RasterPyramidFormat::GeoTiff, const QStringList &configOptions=QStringList(), QgsRasterBlockFeedback *feedback=nullptr)
Creates pyramid overviews.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
virtual Qgis::RasterProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
virtual QList< QgsRasterPyramid > buildPyramidList(const QList< int > &overviewList=QList< int >())
Returns the raster layers pyramid list.
A widget for display and configuring a raster layer histogram.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
Master widget for configuration of labeling of a raster layer.
void addPropertiesPageFactory(const QgsMapLayerConfigWidgetFactory *factory) final
Adds properties page from a factory.
Q_DECL_DEPRECATED void saveDefaultStyle()
Saves the default style when appropriate button is pressed.
QgsRasterLayerProperties(QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent=nullptr, Qt::WindowFlags=QgsGuiUtils::ModalDialogFlags)
Constructor.
bool eventFilter(QObject *obj, QEvent *ev) override
void optionsStackedWidget_CurrentChanged(int index) final
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.
Represents a raster layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Property
Data definable properties.
@ RendererOpacity
Raster renderer global opacity.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in raster pipes.
This struct is used to store pyramid info for the raster layer.
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
Sets the widget creation function for a renderer.
QStringList renderersList() const
Returns a list of the names of registered renderers.
Abstract base class for widgets which configure a QgsRasterRenderer.
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.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Widget creation function (use by the renderer registry).
A widget for controlling a raster layer's transparency and related options.
Stores settings for use within QGIS.
Definition qgssettings.h:65
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.
A collection of stubs to mimic the API of QWebView on systems where the real library is not available...
Definition qgswebview.h:66
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
Setting options for creating vector data providers.
Registry for raster renderer entries.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction