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