QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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
18#include <limits>
19#include <typeinfo>
20
21#include "qgsgui.h"
22#include "qgsapplication.h"
25#include "qgslogger.h"
27#include "qgsmapcanvas.h"
29#include "qgsmaptoolemitpoint.h"
30#include "qgsmetadatawidget.h"
34#include "qgsnative.h"
38#include "qgsproject.h"
43#include "qgsrasterlayer.h"
45#include "qgsrasterpyramid.h"
46#include "qgsrasterrange.h"
47#include "qgsrasterrenderer.h"
54#include "qgssettings.h"
56#include "qgsmaplayerlegend.h"
57#include "qgsfileutils.h"
58#include "qgswebview.h"
59#include "qgsvectorlayer.h"
60#include "qgsdoublevalidator.h"
62#include "qgsprojectutils.h"
66#include "qgsmaptip.h"
67#include "qgswebframe.h"
68#if WITH_QTWEBKIT
69#include <QWebElement>
70#endif
71
72#include <QDesktopServices>
73#include <QTableWidgetItem>
74#include <QHeaderView>
75#include <QTextStream>
76#include <QFile>
77#include <QFileDialog>
78#include <QMessageBox>
79#include <QPainter>
80#include <QLinearGradient>
81#include <QPainterPath>
82#include <QPolygonF>
83#include <QColorDialog>
84#include <QList>
85#include <QMouseEvent>
86#include <QVector>
87#include <QUrl>
88#include <QMenu>
89#include <QScreen>
90#include <QRegularExpressionValidator>
91#include <QRegularExpression>
92
93QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
94 : QgsOptionsDialogBase( QStringLiteral( "RasterLayerProperties" ), parent, fl )
95 // Constant that signals property not used.
96 , TRSTRING_NOT_SET( tr( "Not Set" ) )
97 , mDefaultStandardDeviation( 0 )
98 , mDefaultRedBand( 0 )
99 , mDefaultGreenBand( 0 )
100 , mDefaultBlueBand( 0 )
101 , mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
102 , mGradientHeight( 0.0 )
103 , mGradientWidth( 0.0 )
104 , mMapCanvas( canvas )
105 , mMetadataFilled( false )
106{
107 mGrayMinimumMaximumEstimated = true;
108 mRGBMinimumMaximumEstimated = true;
109
110 setupUi( this );
111
112 mMetadataViewer = new QgsWebView( this );
113 mOptsPage_Information->layout()->addWidget( mMetadataViewer );
114
115 mRasterTransparencyWidget = new QgsRasterTransparencyWidget( mRasterLayer, canvas, this );
116
117 transparencyScrollArea->setWidget( mRasterTransparencyWidget );
118
119 connect( buttonBuildPyramids, &QPushButton::clicked, this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
120 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsRasterLayerProperties::mCrsSelector_crsChanged );
121 connect( mRenderTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
122 connect( mResetColorRenderingBtn, &QToolButton::clicked, this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
123 connect( buttonRemoveMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::removeSelectedMetadataUrl );
124 connect( buttonAddMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::addMetadataUrl );
125 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
126 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
127 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
128 initOptionsBase( false );
129 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
130
131 mSourceGroupBox->hide();
132
133 mBtnStyle = new QPushButton( tr( "Style" ) );
134 QMenu *menuStyle = new QMenu( this );
135 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle );
136 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs );
137 menuStyle->addSeparator();
138 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveDefaultStyle );
139 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle );
140 mBtnStyle->setMenu( menuStyle );
141 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
142 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
143
144 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
145 QMenu *menuMetadata = new QMenu( this );
146 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadata );
147 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataAs );
148 menuMetadata->addSeparator();
149 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveDefaultMetadata );
150 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
151 mBtnMetadata->setMenu( menuMetadata );
152 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
153
154 connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
155
156 connect( this, &QDialog::accepted, this, &QgsRasterLayerProperties::apply );
157 connect( this, &QDialog::rejected, this, &QgsRasterLayerProperties::onCancel );
158
159 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsRasterLayerProperties::apply );
160
161 cbxPyramidsFormat->addItem( tr( "External" ), QVariant::fromValue( Qgis::RasterPyramidFormat::GeoTiff ) );
162 cbxPyramidsFormat->addItem( tr( "Internal (if possible)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Internal ) );
163 cbxPyramidsFormat->addItem( tr( "External (Erdas Imagine)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Erdas ) );
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 initMapTipPreview();
231
232 if ( !mRasterLayer )
233 {
234 return;
235 }
236
237 connect( mEnableMapTips, &QAbstractButton::toggled, mHtmlMapTipGroupBox, &QWidget::setEnabled );
238 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
239
240 updateRasterAttributeTableOptionsPage();
241
242 connect( mRasterLayer, &QgsRasterLayer::rendererChanged, this, &QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage );
243
244 connect( mCreateRasterAttributeTableButton, &QPushButton::clicked, this, [ = ]
245 {
246 if ( mRasterLayer->canCreateRasterAttributeTable() )
247 {
248 // Create the attribute table from the renderer
249 QgsCreateRasterAttributeTableDialog dlg { mRasterLayer };
250 dlg.setOpenWhenDoneVisible( false );
251 if ( dlg.exec() == QDialog::Accepted )
252 {
253 updateRasterAttributeTableOptionsPage();
254 }
255 }
256 } );
257
258 connect( mLoadRasterAttributeTableFromFileButton, &QPushButton::clicked, this, [ = ]
259 {
260 // Load the attribute table from a VAT.DBF file
261 QgsLoadRasterAttributeTableDialog dlg { mRasterLayer };
262 dlg.setOpenWhenDoneVisible( false );
263 if ( dlg.exec() == QDialog::Accepted )
264 {
265 updateRasterAttributeTableOptionsPage();
266 }
267 } );
268
269 mBackupCrs = mRasterLayer->crs();
270
271 // Handles window modality raising canvas
272 if ( mMapCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
273 {
274
275 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [ = ]
276 {
277 hide();
278 setModal( true );
279 show();
280 raise();
281 activateWindow();
282 } );
283
284 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [ = ]
285 {
286 hide();
287 setModal( false );
288
289 // Transfer focus to the canvas to use the selector tool
290 mMapCanvas->window()->raise();
291 mMapCanvas->window()->activateWindow();
292 mMapCanvas->window()->setFocus();
293 } );
294 }
295
299
300 if ( mMapCanvas )
301 {
302 mContext << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() );
303 // Initialize with layer center
304 mContext << QgsExpressionContextUtils::mapLayerPositionScope( mRasterLayer->extent().center() );
305 }
306
307 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
308
309 mMapTipExpressionWidget->registerExpressionContextGenerator( this );
310
311 connect( mInsertExpressionButton, &QAbstractButton::clicked, this, [ = ]
312 {
313 QString expression = QStringLiteral( "[% " );
314 expression += mMapTipExpressionWidget->expression();
315 expression += QLatin1String( " %]" );
316 mMapTipWidget->insertText( expression );
317 } );
318
319 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
320
321 // Only do pyramids if dealing directly with GDAL.
322 if ( provider && provider->capabilities() & QgsRasterDataProvider::BuildPyramids )
323 {
324 // initialize resampling methods
325 cboResamplingMethod->clear();
326
327 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
328 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
329 {
330 cboResamplingMethod->addItem( method.second, method.first );
331 }
332
333 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
334 QString prefix = provider->name() + "/driverOptions/_pyramids/";
335 QgsSettings mySettings;
336 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
337 int idx = cboResamplingMethod->findData( defaultMethod );
338 if ( idx >= 0 )
339 cboResamplingMethod->setCurrentIndex( idx );
340
341
342 // build pyramid list
343 const QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
344
345 for ( const QgsRasterPyramid &pyramid : myPyramidList )
346 {
347 if ( pyramid.getExists() )
348 {
349 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
350 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
351 QString::number( pyramid.getYDim() ) ) );
352 }
353 else
354 {
355 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
356 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
357 QString::number( pyramid.getYDim() ) ) );
358 }
359 }
360 }
361 else
362 {
363 // disable Pyramids tab completely
364 mOptsPage_Pyramids->setEnabled( false );
365 }
366
367 // We can calculate histogram for all data sources but estimated only if
368 // size is unknown - could also be enabled if well supported (estimated histogram
369 // and let user know that it is estimated)
370 if ( !provider || !( provider->capabilities() & QgsRasterDataProvider::Size ) )
371 {
372 // disable Histogram tab completely
373 mOptsPage_Histogram->setEnabled( false );
374 }
375
376 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
377 layout->setContentsMargins( 0, 0, 0, 0 );
378 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
379 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
380 mMetadataWidget->setMapCanvas( mMapCanvas );
381 layout->addWidget( mMetadataWidget );
382 metadataFrame->setLayout( layout );
383
384 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
385 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
386 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
387 temporalLayout->addWidget( mTemporalWidget );
388
389 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), 2 );
390 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
391 mCrsSelector->setCrs( mRasterLayer->crs() );
392
393 // Set text for pyramid info box
394 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
395 QString pyramidHeader = tr( "Description" );
396 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
397 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." );
398 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
399 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
400 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
401
402 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
403 pyramidSentence1,
404 pyramidSentence2,
405 pyramidSentence3,
406 pyramidSentence4,
407 pyramidSentence5 ) );
408
409 //resampling
410 mResamplingGroupBox->setSaveCheckedState( true );
411 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
412 mResamplingUtils.refreshWidgetsFromLayer();
413
414 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
415
416 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
417 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
418
419 // Hue and saturation color control
420 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
421 //set hue and saturation controls to current values
422 if ( hueSaturationFilter )
423 {
424 sliderSaturation->setValue( hueSaturationFilter->saturation() );
425 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
426
427 // Set initial state of saturation controls based on grayscale mode choice
428 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
429
430 // Set initial state of colorize controls
431 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
432 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
433 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
434 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
435 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
436 }
437
438 //blend mode
439 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
440 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
441
442 //transparency band
443 if ( provider )
444 {
445 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
446 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
447
448// Alpha band is set in sync()
449#if 0
450 if ( renderer )
451 {
452 QgsDebugMsgLevel( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ), 2 );
453 if ( renderer->alphaBand() > 0 )
454 {
455 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
456 }
457 }
458#endif
459 }
460
461 // create histogram widget
462 mHistogramWidget = nullptr;
463 if ( mOptsPage_Histogram->isEnabled() )
464 {
465 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
466 mHistogramStackedWidget->addWidget( mHistogramWidget );
467 }
468
469 //insert renderer widgets into registry
476
477 //fill available renderers into combo box
479 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
480 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
481 for ( const QString &name : constRenderersList )
482 {
483 if ( QgsApplication::rasterRendererRegistry()->rendererData( name, entry ) )
484 {
485 if ( ( mRasterLayer->rasterType() != Qgis::RasterLayerType::SingleBandColorData && entry.name != QLatin1String( "singlebandcolordata" ) ) ||
486 ( mRasterLayer->rasterType() == Qgis::RasterLayerType::SingleBandColorData && entry.name == QLatin1String( "singlebandcolordata" ) ) )
487 {
488 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
489 }
490 }
491 }
492 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
493
494 int widgetIndex = 0;
495 if ( renderer )
496 {
497 QString rendererType = renderer->type();
498 widgetIndex = mRenderTypeComboBox->findData( rendererType );
499 if ( widgetIndex != -1 )
500 {
501 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
502 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
503 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
504 }
505
506 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
507 {
508 // no band rendering options for singlebandcolordata, so minimize group box
509 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
510 sizep.setVerticalStretch( 0 );
511 sizep.setVerticalPolicy( QSizePolicy::Maximum );
512 mBandRenderingGrpBx->setSizePolicy( sizep );
513 mBandRenderingGrpBx->updateGeometry();
514 }
515
516 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
517 {
518 mWMSPrintGroupBox->hide();
519 mPublishDataSourceUrlCheckBox->hide();
520 mBackgroundLayerCheckBox->hide();
521 }
522 }
523
524#ifdef WITH_QTWEBKIT
525 // Setup information tab
526
527 const int horizontalDpi = logicalDpiX();
528
529 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
530 if ( horizontalDpi > 96 )
531 {
532 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
533 }
534 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
535 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::urlClicked );
536 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
537 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
538
539#endif
540
541 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::RendererOpacity );
542
543 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
544
545 // update based on lyr's current state
546 sync();
547
548 QgsSettings settings;
549 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
550 // this will be read by restoreOptionsBaseUi()
551 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
552 {
553 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ),
554 mOptStackedWidget->indexOf( mOptsPage_Style ) );
555 }
556
557 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
558
559 QString title = tr( "Layer Properties — %1" ).arg( lyr->name() );
560
561 if ( !mRasterLayer->styleManager()->isDefault( mRasterLayer->styleManager()->currentStyle() ) )
562 title += QStringLiteral( " (%1)" ).arg( mRasterLayer->styleManager()->currentStyle() );
563 restoreOptionsBaseUi( title );
564 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
565
566 //Add help page references
567 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
568 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
569 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
570 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
571
572 if ( mOptsPage_Histogram )
573 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
574
575 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
576 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
577
578 if ( mOptsPage_Pyramids )
579 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
580
581 if ( mOptsPage_Display )
582 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#display-properties" ) );
583
584 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
585 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
586 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
587}
588
590{
591 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
592 {
593 return;
594 }
595
596 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
597 switch ( factory->parentPage() )
598 {
600 {
601 mLayerPropertiesPages << page;
602
603 const QString beforePage = factory->layerPropertiesPagePositionHint();
604 if ( beforePage.isEmpty() )
605 addPage( factory->title(), factory->title(), factory->icon(), page );
606 else
607 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
608 break;
609 }
610
612 mTemporalWidget->addWidget( page );
613 break;
614 }
615}
616
618{
619 return mContext;
620}
621
622void QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage( )
623{
624 if ( mRasterAttributeTableWidget )
625 {
626 mOptsPage_RasterAttributeTable->layout()->removeWidget( mRasterAttributeTableWidget );
627 mRasterAttributeTableWidget = nullptr;
628 }
629
630 // Setup raster attribute table
631 if ( mRasterLayer->attributeTableCount() > 0 )
632 {
633 mRasterAttributeTableWidget = new QgsRasterAttributeTableWidget( this, mRasterLayer );
634 mOptsPage_RasterAttributeTable->layout()->addWidget( mRasterAttributeTableWidget );
635 // When the renderer changes we need to sync the style options page
636 connect( mRasterAttributeTableWidget, &QgsRasterAttributeTableWidget::rendererChanged, this, &QgsRasterLayerProperties::syncToLayer );
637 mNoRasterAttributeTableWidget->hide();
638 }
639 else
640 {
641 mNoRasterAttributeTableWidget->show();
642 mCreateRasterAttributeTableButton->setEnabled( mRasterLayer->canCreateRasterAttributeTable() );
643 }
644}
645
646void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
647{
648 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
649 QgsRasterRendererWidget *oldWidget = mRendererWidget;
650 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
651
652 int alphaBand = -1;
653 double opacity = 1;
654 QColor nodataColor;
655 if ( oldRenderer )
656 {
657 // Retain alpha band and opacity when switching renderer
658 alphaBand = oldRenderer->alphaBand();
659 opacity = oldRenderer->opacity();
660 nodataColor = oldRenderer->nodataColor();
661 }
662
663 QgsRasterRendererRegistryEntry rendererEntry;
664 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
665 {
666 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
667 {
668 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
669 // Current canvas extent (used to calc min/max) in layer CRS
670 QgsRectangle myExtent = mMapCanvas->mapSettings().outputExtentToLayerExtent( mRasterLayer, mMapCanvas->extent() );
671 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
672 {
673 if ( rendererName == QLatin1String( "singlebandgray" ) )
674 {
675 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::SingleBandGray, mRasterLayer->dataProvider() ) );
676 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
677 }
678 else if ( rendererName == QLatin1String( "multibandcolor" ) )
679 {
680 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::MultiBandColor, mRasterLayer->dataProvider() ) );
681 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
682 }
683 }
684 mRasterLayer->renderer()->setAlphaBand( alphaBand );
685 mRasterLayer->renderer()->setOpacity( opacity );
686 mRasterLayer->renderer()->setNodataColor( nodataColor );
687 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
688 mRendererWidget->setMapCanvas( mMapCanvas );
689 mRendererStackedWidget->addWidget( mRendererWidget );
690 if ( oldWidget )
691 {
692 //compare used bands in new and old renderer and reset transparency dialog if different
693 std::unique_ptr<QgsRasterRenderer> oldRenderer;
694 oldRenderer.reset( oldWidget->renderer() );
695 std::unique_ptr<QgsRasterRenderer> newRenderer;
696 newRenderer.reset( mRendererWidget->renderer() );
697 const QList<int> oldBands = oldRenderer->usesBands();
698 const QList<int> newBands = newRenderer->usesBands();
699 if ( oldBands != newBands )
700 {
701 mRasterTransparencyWidget->syncToLayer();
702 }
703 }
704 }
705 }
706
707 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
708 if ( widgetIndex != -1 )
709 {
710 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
711 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
712 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
713 }
714
715 if ( mRendererWidget != oldWidget )
716 delete oldWidget;
717
718 if ( mHistogramWidget )
719 {
720 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
721 }
722}
723
724void QgsRasterLayerProperties::sync()
725{
726 QgsSettings myQSettings;
727
728 if ( !mSourceWidget )
729 {
730 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
731 if ( mSourceWidget )
732 {
733 QHBoxLayout *layout = new QHBoxLayout();
734 layout->addWidget( mSourceWidget );
735 mSourceGroupBox->setLayout( layout );
736 mSourceGroupBox->show();
737
738 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [ = ]( bool isValid )
739 {
740 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
741 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
742 } );
743 }
744 }
745
746 if ( mSourceWidget )
747 {
748 mSourceWidget->setMapCanvas( mMapCanvas );
749 mSourceWidget->setSourceUri( mRasterLayer->source() );
750 }
751
752 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
753 if ( !provider )
754 return;
755
756 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
758 {
759 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
760 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
761 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
762 }
763
764 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
765 if ( !( provider->capabilities() & QgsRasterDataProvider::BuildPyramids ) )
766 {
767 if ( mOptsPage_Pyramids )
768 {
769 delete mOptsPage_Pyramids;
770 mOptsPage_Pyramids = nullptr;
771 }
772 }
773
774 if ( !( provider->capabilities() & QgsRasterDataProvider::Size ) )
775 {
776 if ( mOptsPage_Histogram )
777 {
778 delete mOptsPage_Histogram;
779 mOptsPage_Histogram = nullptr;
780 delete mHistogramWidget;
781 mHistogramWidget = nullptr;
782 }
783 }
784
785 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
786
787 /*
788 * Style tab
789 */
790
791 //set brightness, contrast and gamma
792 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
793 if ( brightnessFilter )
794 {
795 mSliderBrightness->setValue( brightnessFilter->brightness() );
796 mSliderContrast->setValue( brightnessFilter->contrast() );
797 mGammaSpinBox->setValue( brightnessFilter->gamma() );
798 }
799
800 // Hue and saturation color control
801 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
802 //set hue and saturation controls to current values
803 if ( hueSaturationFilter )
804 {
805 sliderSaturation->setValue( hueSaturationFilter->saturation() );
806 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
807
808 // Set state of saturation controls based on grayscale mode choice
809 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
810
811 // Set state of colorize controls
812 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
813 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
814 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
815 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
816 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
817 }
818
819
820 mRefreshLayerCheckBox->setChecked( mRasterLayer->hasAutoRefreshEnabled() );
821 mRefreshLayerIntervalSpinBox->setEnabled( mRasterLayer->hasAutoRefreshEnabled() );
822 mRefreshLayerIntervalSpinBox->setValue( mRasterLayer->autoRefreshInterval() / 1000.0 );
823
824 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
825 /*
826 * General Tab
827 */
828
829 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
830
831 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
832 /*
833 * Metadata Tab
834 */
835 //populate the metadata tab's text browser widget with gdal metadata info
836 updateInformationContent();
837
838 // WMS Name as layer short name
839 mLayerShortNameLineEdit->setText( mRasterLayer->shortName() );
840 // WMS Name validator
841 QValidator *shortNameValidator = new QRegularExpressionValidator( QgsApplication::shortNameRegularExpression(), this );
842 mLayerShortNameLineEdit->setValidator( shortNameValidator );
843
844 //layer title and abstract
845 mLayerTitleLineEdit->setText( mRasterLayer->title() );
846 mLayerAbstractTextEdit->setPlainText( mRasterLayer->abstract() );
847 mLayerKeywordListLineEdit->setText( mRasterLayer->keywordList() );
848 mLayerDataUrlLineEdit->setText( mRasterLayer->dataUrl() );
849 mLayerDataUrlFormatComboBox->setCurrentIndex(
850 mLayerDataUrlFormatComboBox->findText(
851 mRasterLayer->dataUrlFormat()
852 )
853 );
854
855 //layer attribution
856 mLayerAttributionLineEdit->setText( mRasterLayer->attribution() );
857 mLayerAttributionUrlLineEdit->setText( mRasterLayer->attributionUrl() );
858
859 // layer metadata url
860 const QList<QgsMapLayerServerProperties::MetadataUrl> &metaUrls = mRasterLayer->serverProperties()->metadataUrls();
861 for ( const QgsMapLayerServerProperties::MetadataUrl &metaUrl : metaUrls )
862 {
863 const int row = mMetadataUrlModel->rowCount();
864 mMetadataUrlModel->setItem( row, 0, new QStandardItem( metaUrl.url ) );
865 mMetadataUrlModel->setItem( row, 1, new QStandardItem( metaUrl.type ) );
866 mMetadataUrlModel->setItem( row, 2, new QStandardItem( metaUrl.format ) );
867 }
868
869 // layer legend url
870 mLayerLegendUrlLineEdit->setText( mRasterLayer->legendUrl() );
871 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->legendUrlFormat() ) );
872
873 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
874 mMapTipWidget->setText( mRasterLayer->mapTipTemplate() );
875
876 //WMS print layer
877 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
878 if ( wmsPrintLayer.isValid() )
879 {
880 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
881 }
882
883 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
884 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
885
886 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
887 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
888
889 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
890 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
891 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
892
893 mTemporalWidget->syncToLayer();
894
895 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
896 updateDataDefinedButtons();
897
898 for ( QgsMapLayerConfigWidget *page : std::as_const( mLayerPropertiesPages ) )
899 {
900 page->syncToLayer( mRasterLayer );
901 }
902
903}
904
905void QgsRasterLayerProperties::apply()
906{
907 if ( mSourceWidget )
908 {
909 const QString newSource = mSourceWidget->sourceUri();
910 if ( newSource != mRasterLayer->source() )
911 {
912 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
913 }
914 }
915
916 // Do nothing on "bad" layers
917 if ( !mRasterLayer->isValid() )
918 return;
919
920 // apply all plugin dialogs
921 for ( QgsMapLayerConfigWidget *page : std::as_const( mLayerPropertiesPages ) )
922 {
923 page->apply();
924 }
925
926
927 /*
928 * Legend Tab
929 */
930 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
931 mLegendConfigEmbeddedWidget->applyToLayer();
932
933 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
934 /*
935 * Symbology Tab
936 */
937
938 //set whether the layer histogram should be inverted
939 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
940
941 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
942 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
943 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
944
945 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
946 /*
947 * Transparent Pixel Tab
948 */
949
950 //set NoDataValue
951 QgsRasterRangeList myNoDataRangeList;
952 if ( "" != mRasterTransparencyWidget->leNoDataValue->text() )
953 {
954 bool myDoubleOk = false;
955 double myNoDataValue = QgsDoubleValidator::toDouble( mRasterTransparencyWidget->leNoDataValue->text(), &myDoubleOk );
956 if ( myDoubleOk )
957 {
958 QgsRasterRange myNoDataRange( myNoDataValue, myNoDataValue );
959 myNoDataRangeList << myNoDataRange;
960 }
961 }
962 for ( int bandNo = 1; bandNo <= mRasterLayer->dataProvider()->bandCount(); bandNo++ )
963 {
964 mRasterLayer->dataProvider()->setUserNoDataValue( bandNo, myNoDataRangeList );
965 mRasterLayer->dataProvider()->setUseSourceNoDataValue( bandNo, mRasterTransparencyWidget->mSrcNoDataValueCheckBox->isChecked() );
966 }
967
968 //set renderer from widget
969 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
970 if ( rendererWidget )
971 {
972 rendererWidget->doComputations();
973
974 mRasterLayer->setRenderer( rendererWidget->renderer() );
975 }
976
977 mBackupCrs = mRasterLayer->crs();
978 mMetadataWidget->acceptMetadata();
979 mMetadataFilled = false;
980
981 //transparency settings
982 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
983 if ( rasterRenderer )
984 {
985 rasterRenderer->setAlphaBand( mRasterTransparencyWidget->cboxTransparencyBand->currentBand() );
986 rasterRenderer->setNodataColor( mRasterTransparencyWidget->mNodataColorButton->color() );
987
988 //Walk through each row in table and test value. If not valid set to 0.0 and continue building transparency list
989 QgsRasterTransparency *rasterTransparency = new QgsRasterTransparency();
990 if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 4 )
991 {
993 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
994 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
995 {
996 myTransparentPixel.red = transparencyCellValue( myListRunner, 0 );
997 myTransparentPixel.green = transparencyCellValue( myListRunner, 1 );
998 myTransparentPixel.blue = transparencyCellValue( myListRunner, 2 );
999 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 3 );
1000 myTransparentThreeValuePixelList.append( myTransparentPixel );
1001 }
1002 rasterTransparency->setTransparentThreeValuePixelList( myTransparentThreeValuePixelList );
1003 }
1004 else if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 3 )
1005 {
1007 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
1008 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
1009 {
1010 myTransparentPixel.min = transparencyCellValue( myListRunner, 0 );
1011 myTransparentPixel.max = transparencyCellValue( myListRunner, 1 );
1012 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 2 );
1013
1014 myTransparentSingleValuePixelList.append( myTransparentPixel );
1015 }
1016 rasterTransparency->setTransparentSingleValuePixelList( myTransparentSingleValuePixelList );
1017 }
1018
1019 rasterRenderer->setRasterTransparency( rasterTransparency );
1020
1021 // Sync the layer styling widget
1022 mRasterLayer->emitStyleChanged();
1023
1024 //set global transparency
1025 rasterRenderer->setOpacity( mRasterTransparencyWidget->mOpacityWidget->opacity() );
1026 }
1027
1028 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
1029 /*
1030 * General Tab
1031 */
1032 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
1033
1034 // set up the scale based layer visibility stuff....
1035 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
1036 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
1037 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
1038
1039 mRasterLayer->setAutoRefreshInterval( mRefreshLayerIntervalSpinBox->value() * 1000.0 );
1040 mRasterLayer->setAutoRefreshEnabled( mRefreshLayerCheckBox->isChecked() );
1041
1042 //update the legend pixmap
1043 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1044 // pixmapLegend->setScaledContents( true );
1045 // pixmapLegend->repaint();
1046
1047 mResamplingUtils.refreshLayerFromWidgets();
1048
1049 // Hue and saturation controls
1050 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
1051 if ( hueSaturationFilter )
1052 {
1053 hueSaturationFilter->setSaturation( sliderSaturation->value() );
1054 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
1055 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
1056 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
1057 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
1058 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
1059 }
1060
1061 //set the blend mode for the layer
1062 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
1063
1064 // Update temporal properties
1065 mTemporalWidget->saveTemporalProperties();
1066
1067 mRasterLayer->setCrs( mCrsSelector->crs() );
1068
1069 if ( mRasterLayer->shortName() != mLayerShortNameLineEdit->text() )
1070 mMetadataFilled = false;
1071 mRasterLayer->setShortName( mLayerShortNameLineEdit->text() );
1072
1073 if ( mRasterLayer->title() != mLayerTitleLineEdit->text() )
1074 mMetadataFilled = false;
1075 mRasterLayer->setTitle( mLayerTitleLineEdit->text() );
1076
1077 if ( mRasterLayer->abstract() != mLayerAbstractTextEdit->toPlainText() )
1078 mMetadataFilled = false;
1079 mRasterLayer->setAbstract( mLayerAbstractTextEdit->toPlainText() );
1080
1081 if ( mRasterLayer->keywordList() != mLayerKeywordListLineEdit->text() )
1082 mMetadataFilled = false;
1083 mRasterLayer->setKeywordList( mLayerKeywordListLineEdit->text() );
1084
1085 if ( mRasterLayer->dataUrl() != mLayerDataUrlLineEdit->text() )
1086 mMetadataFilled = false;
1087 mRasterLayer->setDataUrl( mLayerDataUrlLineEdit->text() );
1088
1089 if ( mRasterLayer->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1090 mMetadataFilled = false;
1091 mRasterLayer->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1092
1093 //layer attribution
1094 if ( mRasterLayer->attribution() != mLayerAttributionLineEdit->text() )
1095 mMetadataFilled = false;
1096 mRasterLayer->setAttribution( mLayerAttributionLineEdit->text() );
1097
1098 if ( mRasterLayer->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1099 mMetadataFilled = false;
1100 mRasterLayer->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
1101
1102 // Metadata URL
1103 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
1104 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
1105 {
1107 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
1108 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
1109 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
1110 metaUrls.append( metaUrl );
1111 mMetadataFilled = false;
1112 }
1113 mRasterLayer->serverProperties()->setMetadataUrls( metaUrls );
1114
1115 if ( mRasterLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
1116 mMetadataFilled = false;
1117 mRasterLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
1118
1119 if ( mRasterLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1120 mMetadataFilled = false;
1121 mRasterLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
1122
1123 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1124 {
1125 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1126 }
1127
1128 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1129 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1130
1131 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
1132
1133 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
1134 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
1135
1136 // Force a redraw of the legend
1137 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
1138
1139 //make sure the layer is redrawn
1140 mRasterLayer->triggerRepaint();
1141
1142 // notify the project we've made a change
1143 QgsProject::instance()->setDirty( true );
1144}
1145
1146void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1147{
1148 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1149
1150 std::unique_ptr< QgsRasterBlockFeedback > feedback( new QgsRasterBlockFeedback() );
1151
1152 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
1153 //
1154 // Go through the list marking any files that are selected in the listview
1155 // as true so that we can generate pyramids for them.
1156 //
1157 QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1158 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1159 {
1160 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1161 //mark to be pyramided
1162 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1163 }
1164
1165 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1166 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1167 QgsSettings mySettings;
1168 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1169 mySettings.setValue( prefix + "resampling", resamplingMethod );
1170
1171 //
1172 // Ask raster layer to build the pyramids
1173 //
1174
1175 // let the user know we're going to possibly be taking a while
1176 QApplication::setOverrideCursor( Qt::WaitCursor );
1177 QString res = provider->buildPyramids(
1178 myPyramidList,
1179 resamplingMethod,
1180 cbxPyramidsFormat->currentData().value< Qgis::RasterPyramidFormat >(),
1181 QStringList(),
1182 feedback.get() );
1183 QApplication::restoreOverrideCursor();
1184 mPyramidProgress->setValue( 0 );
1185 buttonBuildPyramids->setEnabled( false );
1186 if ( !res.isNull() )
1187 {
1188 if ( res == QLatin1String( "CANCELED" ) )
1189 {
1190 // user canceled
1191 }
1192 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1193 {
1194 QMessageBox::warning( this, tr( "Building Pyramids" ),
1195 tr( "Write access denied. Adjust the file permissions and try again." ) );
1196 }
1197 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1198 {
1199 QMessageBox::warning( this, tr( "Building Pyramids" ),
1200 tr( "The file was not writable. Some formats do not "
1201 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1202 }
1203 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1204 {
1205 QMessageBox::warning( this, tr( "Building Pyramids" ),
1206 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1207 }
1208 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1209 {
1210 QMessageBox::warning( this, tr( "Building Pyramids" ),
1211 tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1212 }
1213 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1214 {
1215 QMessageBox::warning( this, tr( "Building Pyramids" ),
1216 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1217 }
1218
1219 }
1220
1221 //
1222 // repopulate the pyramids list
1223 //
1224 lbxPyramidResolutions->clear();
1225 // Need to rebuild list as some or all pyramids may have failed to build
1226 myPyramidList = provider->buildPyramidList();
1227 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1228 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1229
1230 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1231 {
1232 if ( pyramid.getExists() )
1233 {
1234 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
1235 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1236 QString::number( pyramid.getYDim() ) ) );
1237 }
1238 else
1239 {
1240 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
1241 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1242 QString::number( pyramid.getYDim() ) ) );
1243 }
1244 }
1245 //update the legend pixmap
1246 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1247 // pixmapLegend->setScaledContents( true );
1248 // pixmapLegend->repaint();
1249
1250 //populate the metadata tab's text browser widget with gdal metadata info
1251 updateInformationContent();
1252}
1253
1254void QgsRasterLayerProperties::urlClicked( const QUrl &url )
1255{
1256 QFileInfo file( url.toLocalFile() );
1257 if ( file.exists() && !file.isDir() )
1258 QgsGui::nativePlatformInterface()->openFileExplorerAndSelectFile( url.toLocalFile() );
1259 else
1260 QDesktopServices::openUrl( url );
1261}
1262
1263void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1264{
1265 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1266 {
1267 return;
1268 }
1269
1270 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1271 setRendererWidget( rendererName );
1272}
1273
1274void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1275{
1276 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mMapCanvas, tr( "Select Transformation" ) );
1277 mRasterLayer->setCrs( crs );
1278 mMetadataWidget->crsChanged();
1279}
1280
1281void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double value )
1282{
1283 QgsDebugMsgLevel( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ), 3 );
1284 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1285 if ( !provider ) return;
1286
1287 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1288 if ( !renderer ) return;
1289 int nBands = renderer->usesBands().size();
1290
1291 QLineEdit *lineEdit = new QLineEdit();
1292 lineEdit->setFrame( false ); // frame looks bad in table
1293 // Without margins row selection is not displayed (important for delete row)
1294 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1295
1296 if ( column == mRasterTransparencyWidget->tableTransparency->columnCount() - 1 )
1297 {
1298 // transparency
1299 // Who needs transparency as floating point?
1300 lineEdit->setValidator( new QIntValidator( nullptr ) );
1301 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
1302 }
1303 else
1304 {
1305 // value
1306 QString valueString;
1307 switch ( provider->sourceDataType( 1 ) )
1308 {
1311 lineEdit->setValidator( new QgsDoubleValidator( nullptr ) );
1312 if ( !std::isnan( value ) )
1313 {
1314 double v = QgsRasterBlock::printValue( value ).toDouble();
1315 valueString = QLocale().toString( v, 'g' ) ;
1316 }
1317 break;
1318 default:
1319 lineEdit->setValidator( new QIntValidator( nullptr ) );
1320 if ( !std::isnan( value ) )
1321 {
1322 valueString = QLocale().toString( static_cast<int>( value ) );
1323 }
1324 break;
1325 }
1326 lineEdit->setText( valueString );
1327 }
1328 mRasterTransparencyWidget->tableTransparency->setCellWidget( row, column, lineEdit );
1329 adjustTransparencyCellWidth( row, column );
1330
1331 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1332 {
1333 connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1334 }
1335 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1336}
1337
1338void QgsRasterLayerProperties::setTransparencyCellValue( int row, int column, double value )
1339{
1340 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1341 if ( !lineEdit ) return;
1342 double v = QgsRasterBlock::printValue( value ).toDouble();
1343 lineEdit->setText( QLocale().toString( v, 'g' ) );
1344 lineEdit->adjustSize();
1345 adjustTransparencyCellWidth( row, column );
1346 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1347}
1348
1349double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
1350{
1351 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1352 if ( !lineEdit || lineEdit->text().isEmpty() )
1353 {
1354 return std::numeric_limits<double>::quiet_NaN();
1355 }
1356 return QLocale().toDouble( lineEdit->text() );
1357}
1358
1359void QgsRasterLayerProperties::adjustTransparencyCellWidth( int row, int column )
1360{
1361 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1362 if ( !lineEdit ) return;
1363
1364 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1365 width = std::max( width, mRasterTransparencyWidget->tableTransparency->columnWidth( column ) );
1366
1367 lineEdit->setFixedWidth( width );
1368}
1369
1370void QgsRasterLayerProperties::transparencyCellTextEdited( const QString &text )
1371{
1372 Q_UNUSED( text )
1373 QgsDebugMsgLevel( QStringLiteral( "text = %1" ).arg( text ), 3 );
1374 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1375 if ( !renderer )
1376 {
1377 return;
1378 }
1379 int nBands = renderer->usesBands().size();
1380 if ( nBands == 1 )
1381 {
1382 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1383 if ( !lineEdit ) return;
1384 int row = -1;
1385 int column = -1;
1386 for ( int r = 0; r < mRasterTransparencyWidget->tableTransparency->rowCount(); r++ )
1387 {
1388 for ( int c = 0; c < mRasterTransparencyWidget->tableTransparency->columnCount(); c++ )
1389 {
1390 if ( mRasterTransparencyWidget->tableTransparency->cellWidget( r, c ) == sender() )
1391 {
1392 row = r;
1393 column = c;
1394 break;
1395 }
1396 }
1397 if ( row != -1 ) break;
1398 }
1399 QgsDebugMsgLevel( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ), 3 );
1400
1401 if ( column == 0 )
1402 {
1403 QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, 1 ) );
1404 if ( !toLineEdit ) return;
1405 bool toChanged = mTransparencyToEdited.value( row );
1406 QgsDebugMsgLevel( QStringLiteral( "toChanged = %1" ).arg( toChanged ), 3 );
1407 if ( !toChanged )
1408 {
1409 toLineEdit->setText( lineEdit->text() );
1410 }
1411 }
1412 else if ( column == 1 )
1413 {
1414 setTransparencyToEdited( row );
1415 }
1416 }
1417}
1418
1419void QgsRasterLayerProperties::aboutToShowStyleMenu()
1420{
1421 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1422
1423 QMenu *m = qobject_cast<QMenu *>( sender() );
1424
1426 // re-add style manager actions!
1427 m->addSeparator();
1429}
1430
1431void QgsRasterLayerProperties::syncToLayer()
1432{
1433 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1434 if ( renderer )
1435 {
1436 setRendererWidget( renderer->type() );
1437 }
1438 sync();
1439 mRasterLayer->triggerRepaint();
1440}
1441
1442void QgsRasterLayerProperties::setTransparencyToEdited( int row )
1443{
1444 if ( row >= mTransparencyToEdited.size() )
1445 {
1446 mTransparencyToEdited.resize( row + 1 );
1447 }
1448 mTransparencyToEdited[row] = true;
1449}
1450
1452{
1454
1455 bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
1456 mBtnStyle->setVisible( ! isMetadataPanel );
1457 mBtnMetadata->setVisible( isMetadataPanel );
1458
1459 if ( !mHistogramWidget )
1460 return;
1461
1462 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1463 {
1464 mHistogramWidget->setActive( true );
1465 }
1466 else
1467 {
1468 mHistogramWidget->setActive( false );
1469 }
1470
1471 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1472 {
1473 //set the metadata contents (which can be expensive)
1474 updateInformationContent();
1475 }
1476}
1477
1478void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1479{
1480 button->blockSignals( true );
1481 button->init( key, mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1482 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1483 button->registerExpressionContextGenerator( this );
1484 button->blockSignals( false );
1485}
1486
1487void QgsRasterLayerProperties::updateDataDefinedButtons()
1488{
1489 const auto propertyOverrideButtons { findChildren< QgsPropertyOverrideButton * >() };
1490 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1491 {
1492 updateDataDefinedButton( button );
1493 }
1494}
1495
1496void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1497{
1498 if ( !button )
1499 return;
1500
1501 if ( button->propertyKey() < 0 )
1502 return;
1503
1504 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1505 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1506}
1507
1508void QgsRasterLayerProperties::updateProperty()
1509{
1510 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1511 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1512 mPropertyCollection.setProperty( key, button->toProperty() );
1513}
1514
1515void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1516{
1517 // Enable or disable saturation controls based on choice of grayscale mode
1518 if ( grayscaleMode == 0 )
1519 {
1520 sliderSaturation->setEnabled( true );
1521 spinBoxSaturation->setEnabled( true );
1522 }
1523 else
1524 {
1525 sliderSaturation->setEnabled( false );
1526 spinBoxSaturation->setEnabled( false );
1527 }
1528}
1529
1530void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1531{
1532 // Enable or disable colorize controls based on checkbox
1533 btnColorizeColor->setEnabled( colorizeEnabled );
1534 sliderColorizeStrength->setEnabled( colorizeEnabled );
1535 spinColorizeStrength->setEnabled( colorizeEnabled );
1536}
1537
1538
1539QLinearGradient QgsRasterLayerProperties::redGradient()
1540{
1541 //define a gradient
1542 // TODO change this to actual polygon dims
1543 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1544 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1545 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1546 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1547 return myGradient;
1548}
1549QLinearGradient QgsRasterLayerProperties::greenGradient()
1550{
1551 //define a gradient
1552 // TODO change this to actual polygon dims
1553 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1554 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1555 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1556 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1557 return myGradient;
1558}
1559QLinearGradient QgsRasterLayerProperties::blueGradient()
1560{
1561 //define a gradient
1562 // TODO change this to actual polygon dims
1563 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1564 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1565 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1566 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1567 return myGradient;
1568}
1569QLinearGradient QgsRasterLayerProperties::grayGradient()
1570{
1571 //define a gradient
1572 // TODO change this to actual polygon dims
1573 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1574 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1575 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1576 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1577 return myGradient;
1578}
1579QLinearGradient QgsRasterLayerProperties::highlightGradient()
1580{
1581 //define another gradient for the highlight
1582 // TODO change this to actual polygon dims
1583 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1584 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1585 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1586 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1587 return myGradient;
1588}
1589
1590void QgsRasterLayerProperties::addMetadataUrl()
1591{
1592 const int row = mMetadataUrlModel->rowCount();
1593 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
1594 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
1595 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
1596}
1597
1598void QgsRasterLayerProperties::removeSelectedMetadataUrl()
1599{
1600 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
1601 if ( selectedRows.empty() )
1602 return;
1603 mMetadataUrlModel->removeRow( selectedRows[0].row() );
1604}
1605
1606
1607//
1608//
1609// Next four methods for saving and restoring qml style state
1610//
1611//
1613{
1614 bool defaultLoadedFlag = false;
1615 QString myMessage = mRasterLayer->loadDefaultStyle( defaultLoadedFlag );
1616 //reset if the default style was loaded OK only
1617 if ( defaultLoadedFlag )
1618 {
1619 syncToLayer();
1620 }
1621 else
1622 {
1623 //otherwise let the user know what went wrong
1624 QMessageBox::information( this,
1625 tr( "Default Style" ),
1626 myMessage
1627 );
1628 }
1629}
1630
1632{
1633
1634 apply(); // make sure the style to save is up-to-date
1635
1636 // a flag passed by reference
1637 bool defaultSavedFlag = false;
1638 // TODO Once the deprecated `saveDefaultStyle()` method is gone, just
1639 // remove the NOWARN_DEPRECATED tags
1641 // after calling this the above flag will be set true for success
1642 // or false if the save operation failed
1643 QString myMessage = mRasterLayer->saveDefaultStyle( defaultSavedFlag );
1645 if ( !defaultSavedFlag )
1646 {
1647 //let the user know what went wrong
1648 QMessageBox::information( this,
1649 tr( "Default Style" ),
1650 myMessage
1651 );
1652 }
1653}
1654
1655
1657{
1658 QgsSettings settings;
1659 QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1660
1661 QString fileName = QFileDialog::getOpenFileName(
1662 this,
1663 tr( "Load layer properties from style file" ),
1664 lastUsedDir,
1665 tr( "QGIS Layer Style File" ) + " (*.qml)" );
1666 if ( fileName.isEmpty() )
1667 return;
1668
1669 // ensure the user never omits the extension from the file name
1670 if ( !fileName.endsWith( QLatin1String( ".qml" ), Qt::CaseInsensitive ) )
1671 fileName += QLatin1String( ".qml" );
1672
1673 mOldStyle = mRasterLayer->styleManager()->style( mRasterLayer->styleManager()->currentStyle() );
1674
1675 bool defaultLoadedFlag = false;
1676 QString message = mRasterLayer->loadNamedStyle( fileName, defaultLoadedFlag );
1677 if ( defaultLoadedFlag )
1678 {
1679 settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
1680 syncToLayer();
1681 }
1682 else
1683 {
1684 QMessageBox::information( this, tr( "Save Style" ), message );
1685 }
1686}
1687
1688
1690{
1691 QgsSettings settings;
1692 QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1693
1694 QString selectedFilter;
1695 QString outputFileName = QFileDialog::getSaveFileName(
1696 this,
1697 tr( "Save layer properties as style file" ),
1698 lastUsedDir,
1699 tr( "QGIS Layer Style File" ) + " (*.qml)" + ";;" + tr( "Styled Layer Descriptor" ) + " (*.sld)",
1700 &selectedFilter );
1701 if ( outputFileName.isEmpty() )
1702 return;
1703
1704 StyleType type;
1705 // use selectedFilter to set style type
1706 if ( selectedFilter.contains( QStringLiteral( ".qml" ), Qt::CaseInsensitive ) )
1707 {
1708 outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "qml" ) );
1709 type = StyleType::QML;
1710 }
1711 else
1712 {
1713 outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "sld" ) );
1714 type = StyleType::SLD;
1715 }
1716
1717 apply(); // make sure the style to save is up-to-date
1718
1719 // then export style
1720 bool defaultLoadedFlag = false;
1721 QString message;
1722 switch ( type )
1723 {
1724 case QML:
1725 {
1726 message = mRasterLayer->saveNamedStyle( outputFileName, defaultLoadedFlag );
1727 break;
1728 }
1729 case SLD:
1730 {
1731 message = mRasterLayer->saveSldStyle( outputFileName, defaultLoadedFlag );
1732 break;
1733 }
1734 }
1735 if ( defaultLoadedFlag )
1736 {
1737 settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
1738 sync();
1739 }
1740 else
1741 QMessageBox::information( this, tr( "Save Style" ), message );
1742}
1743
1744void QgsRasterLayerProperties::restoreWindowModality()
1745{
1746 hide();
1747 setModal( true );
1748 show();
1749 raise();
1750 activateWindow();
1751}
1752
1753//
1754//
1755// Next four methods for saving and restoring QMD metadata
1756//
1757//
1758
1759void QgsRasterLayerProperties::loadMetadata()
1760{
1761 QgsSettings myQSettings; // where we keep last used filter in persistent state
1762 QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1763
1764 QString myFileName = QFileDialog::getOpenFileName( this, tr( "Load layer metadata from metadata file" ), myLastUsedDir,
1765 tr( "QGIS Layer Metadata File" ) + " (*.qmd)" );
1766 if ( myFileName.isNull() )
1767 {
1768 return;
1769 }
1770
1771 QString myMessage;
1772 bool defaultLoadedFlag = false;
1773 myMessage = mRasterLayer->loadNamedMetadata( myFileName, defaultLoadedFlag );
1774
1775 //reset if the default style was loaded OK only
1776 if ( defaultLoadedFlag )
1777 {
1778 mMetadataWidget->setMetadata( &mRasterLayer->metadata() );
1779 }
1780 else
1781 {
1782 //let the user know what went wrong
1783 QMessageBox::warning( this, tr( "Load Metadata" ), myMessage );
1784 }
1785
1786 QFileInfo myFI( myFileName );
1787 QString myPath = myFI.path();
1788 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
1789
1790 activateWindow(); // set focus back to properties dialog
1791}
1792
1793void QgsRasterLayerProperties::saveMetadataAs()
1794{
1795 QgsSettings myQSettings; // where we keep last used filter in persistent state
1796 QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
1797
1798 QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Metadata as QMD" ),
1799 myLastUsedDir, tr( "QMD File" ) + " (*.qmd)" );
1800 if ( myOutputFileName.isNull() ) //dialog canceled
1801 {
1802 return;
1803 }
1804
1805 mMetadataWidget->acceptMetadata();
1806
1807 //ensure the user never omitted the extension from the file name
1808 if ( !myOutputFileName.endsWith( QgsMapLayer::extensionPropertyType( QgsMapLayer::Metadata ), Qt::CaseInsensitive ) )
1809 {
1811 }
1812
1813 bool defaultLoadedFlag = false;
1814 QString message = mRasterLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
1815 if ( defaultLoadedFlag )
1816 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
1817 else
1818 QMessageBox::information( this, tr( "Save Metadata" ), message );
1819}
1820
1821void QgsRasterLayerProperties::saveDefaultMetadata()
1822{
1823 mMetadataWidget->acceptMetadata();
1824
1825 bool defaultSavedFlag = false;
1826 QString errorMsg = mRasterLayer->saveDefaultMetadata( defaultSavedFlag );
1827 if ( !defaultSavedFlag )
1828 {
1829 QMessageBox::warning( this, tr( "Default Metadata" ), errorMsg );
1830 }
1831}
1832
1833void QgsRasterLayerProperties::loadDefaultMetadata()
1834{
1835 bool defaultLoadedFlag = false;
1836 QString myMessage = mRasterLayer->loadNamedMetadata( mRasterLayer->metadataUri(), defaultLoadedFlag );
1837 //reset if the default metadata was loaded OK only
1838 if ( defaultLoadedFlag )
1839 {
1840 mMetadataWidget->setMetadata( &mRasterLayer->metadata() );
1841 }
1842 else
1843 {
1844 QMessageBox::information( this, tr( "Default Metadata" ), myMessage );
1845 }
1846}
1847
1848
1849void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1850{
1851 if ( lbxPyramidResolutions->selectedItems().empty() )
1852 {
1853 buttonBuildPyramids->setEnabled( false );
1854 }
1855 else
1856 {
1857 buttonBuildPyramids->setEnabled( true );
1858 }
1859}
1860
1861void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1862{
1863 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1864 mSliderBrightness->setValue( 0 );
1865 mSliderContrast->setValue( 0 );
1866 mGammaSpinBox->setValue( 1.0 );
1867 sliderSaturation->setValue( 0 );
1868 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1869 mColorizeCheck->setChecked( false );
1870 sliderColorizeStrength->setValue( 100 );
1871 mInvertColorsCheck->setChecked( false );
1872}
1873
1874bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1875{
1876 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1877}
1878
1879void QgsRasterLayerProperties::updateInformationContent()
1880{
1881 const QString myStyle = QgsApplication::reportStyleSheet( QgsApplication::StyleSheetType::WebBrowser );
1882 // Inject the stylesheet
1883 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1884 mMetadataViewer->setHtml( html );
1885 mMetadataFilled = true;
1886}
1887
1888void QgsRasterLayerProperties::onCancel()
1889{
1890
1891 // Give the user a chance to save the raster attribute table edits.
1892 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1893 {
1894 mRasterAttributeTableWidget->setEditable( false, false );
1895 }
1896
1897 if ( mOldStyle.xmlData() != mRasterLayer->styleManager()->style( mRasterLayer->styleManager()->currentStyle() ).xmlData() )
1898 {
1899 // need to reset style to previous - style applied directly to the layer (not in apply())
1900 QString myMessage;
1901 QDomDocument doc( QStringLiteral( "qgis" ) );
1902 int errorLine, errorColumn;
1903 doc.setContent( mOldStyle.xmlData(), false, &myMessage, &errorLine, &errorColumn );
1904 mRasterLayer->importNamedStyle( doc, myMessage );
1905 syncToLayer();
1906 }
1907 if ( mBackupCrs != mRasterLayer->crs() )
1908 mRasterLayer->setCrs( mBackupCrs );
1909}
1910
1911void QgsRasterLayerProperties::showHelp()
1912{
1913 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1914
1915 if ( helpPage.isValid() )
1916 {
1917 QgsHelp::openHelp( helpPage.toString() );
1918 }
1919 else
1920 {
1921 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1922 }
1923}
1924
1925void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1926{
1927 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1928}
1929
1930void QgsRasterLayerProperties::updateGammaSlider( double value )
1931{
1932 whileBlocking( mSliderGamma )->setValue( value * 100 );
1933}
1934
1935
1936bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1937{
1938 // If the map tip preview container is resized, resize the map tip
1939 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1940 {
1941 resizeMapTip();
1942 }
1943 return QgsOptionsDialogBase::eventFilter( obj, ev );
1944}
1945
1946void QgsRasterLayerProperties::initMapTipPreview()
1947{
1948 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1949 mMapTipSplitter->setSizes( { 400, 200 } );
1950 // Event filter is used to resize the map tip when the container is resized
1951 mMapTipPreviewContainer->installEventFilter( this );
1952
1953 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1954 // Create the WebView
1955 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1956
1957#if WITH_QTWEBKIT
1958 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
1959 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1960 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1961#endif
1962
1963 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1964 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1965 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1966
1967 // Disable scrollbars, avoid random resizing issues
1968 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1969 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1970
1971
1972 // Update the map tip preview when the expression or the map tip template changes
1973 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1974}
1975
1976void QgsRasterLayerProperties::updateMapTipPreview()
1977{
1978 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1979 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mMapCanvas, mMapTipWidget->text() );
1980 mMapTipPreview->setHtml( htmlContent );
1981}
1982
1983void QgsRasterLayerProperties::resizeMapTip()
1984{
1985 // Ensure the map tip is not bigger than the container
1986 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1987#if WITH_QTWEBKIT
1988 // Get the content size
1989 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1990 QStringLiteral( "#QgsWebViewContainer" ) );
1991 const int width = container.geometry().width();
1992 const int height = container.geometry().height();
1993 mMapTipPreview->resize( width, height );
1994
1995 // Move the map tip to the center of the container
1996 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2,
1997 ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1998
1999#else
2000 mMapTipPreview->adjustSize();
2001#endif
2002}
RasterPyramidFormat
Raster pyramid formats.
Definition: qgis.h:3167
@ SingleBandGray
A single band image drawn as a range of gray colors.
@ MultiBandColor
A layer containing 2 or more bands, mapped to RGB color space. In the case of a multiband with only t...
@ 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.
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).
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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 * 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...
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:113
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
Definition: qgsgui.cpp:78
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)
The QgsLoadRasterAttributeTableDialog dialog let the user select a VAT.DBF file and associate the res...
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.
Definition: qgsmapcanvas.h:90
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.
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.
Definition: qgsmaplayer.h:289
QString name
Definition: qgsmaplayer.h:76
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
Definition: qgsmaplayer.h:1321
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.
Definition: qgsmaplayer.h:318
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.
Definition: qgsmaplayer.h:1306
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.
Definition: qgsmaplayer.h:1540
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
Definition: qgsmaplayer.h:421
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:396
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.
Definition: qgsmaplayer.h:404
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.
Definition: qgsmaplayer.h:326
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:377
void setDataUrl(const QString &dataUrl)
Sets the DataUrl of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:351
void setKeywordList(const QString &keywords)
Sets the keyword list of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:333
void setAttribution(const QString &attrib)
Sets the attribution of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:387
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.
Definition: qgsmaplayer.h:368
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void rendererChanged()
Signal emitted when renderer is changed.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:311
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.
Definition: qgsmaplayer.h:360
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.
Definition: qgsmaplayer.cpp:69
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...
bool isValid
Definition: qgsmaplayer.h:81
void setLegendPlaceholderImage(const QString &imgPath)
Set placeholder image for legend.
Definition: qgsmaplayer.h:1547
void setMapTipsEnabled(bool enabled)
Enable or disable map tips for this layer.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:413
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.
Definition: qgsmaplayer.h:1311
void setLegendUrlFormat(const QString &legendUrlFormat)
Sets the format for a URL based layer legend.
Definition: qgsmaplayer.h:1316
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 setMapTipTemplate(const QString &mapTipTemplate)
The mapTip is a pretty, html representation for feature information.
bool mapTipsEnabled
Definition: qgsmaplayer.h:84
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.
Definition: qgsmaplayer.h:341
QString mapTipTemplate
Definition: qgsmaplayer.h:83
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:303
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
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
Definition: qgsmaptip.cpp:487
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 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.
virtual void optionsStackedWidget_CurrentChanged(int index)
Select relevant tab on current page change.
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.
Definition: qgsproject.cpp:484
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:603
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.
The QgsRasterAttributeTableWidget class provides an attribute table for rasters and methods to edit t...
void rendererChanged()
This signal is emitted after a successful classify operation which changed the raster renderer.
bool isDirty() const
Returns true if the associated raster attribute table is dirty.
bool setEditable(bool editable, bool allowCancel=true)
Set the editable state, it may trigger save changes if the attribute table has unsave changes.
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", Qgis::RasterPyramidFormat format=Qgis::RasterPyramidFormat::GeoTiff, 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 saveDefaultStyle()
Saves the default style when appropriate button is pressed.
void loadDefaultStyle()
Loads the default style when appropriate button is pressed.
void saveStyleAs()
Saves a style when appriate button is pressed.
void addPropertiesPageFactory(const QgsMapLayerConfigWidgetFactory *factory)
Adds a properties page factory to the raster layer properties dialog.
void loadStyle()
Loads a saved 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) 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.
bool canCreateRasterAttributeTable()
Returns true if the raster renderer is suitable for creation of a raster attribute table.
int attributeTableCount() const
Returns the number of attribute tables for the raster by counting the number of bands that have an as...
QgsRasterPipe * pipe()
Returns the raster pipe.
QgsBrightnessContrastFilter * brightnessFilter() const
Returns the raster's brightness/contrast filter.
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.
Definition: qgsrasterpipe.h:58
@ RendererOpacity
Raster renderer global opacity.
Definition: qgsrasterpipe.h:59
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)
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.
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.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
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:63
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:4572
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:4571
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:3914
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
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.