QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
qgsrasterlayerproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlayerproperties.cpp - description
3 -------------------
4 begin : 1/1/2004
5 copyright : (C) 2004 Tim Sutton
6 email : tim@linfiniti.com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include <limits>
19#include <typeinfo>
20
21#include "qgsgui.h"
22#include "qgsapplication.h"
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 {
226 if ( mRasterLayer->canCreateRasterAttributeTable() )
227 {
228 // Create the attribute table from the renderer
229 QgsCreateRasterAttributeTableDialog dlg { mRasterLayer };
230 dlg.setOpenWhenDoneVisible( false );
231 if ( dlg.exec() == QDialog::Accepted )
232 {
233 updateRasterAttributeTableOptionsPage();
234 }
235 }
236 } );
237
238 connect( mLoadRasterAttributeTableFromFileButton, &QPushButton::clicked, this, [ = ]
239 {
240 // Load the attribute table from a VAT.DBF file
241 QgsLoadRasterAttributeTableDialog dlg { mRasterLayer };
242 dlg.setOpenWhenDoneVisible( false );
243 if ( dlg.exec() == QDialog::Accepted )
244 {
245 updateRasterAttributeTableOptionsPage();
246 }
247 } );
248
249 mBackupCrs = mRasterLayer->crs();
250
251 // Handles window modality raising canvas
252 if ( mCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
253 {
254
255 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [ = ]
256 {
257 hide();
258 setModal( true );
259 show();
260 raise();
261 activateWindow();
262 } );
263
264 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [ = ]
265 {
266 hide();
267 setModal( false );
268
269 // Transfer focus to the canvas to use the selector tool
270 mCanvas->window()->raise();
271 mCanvas->window()->activateWindow();
272 mCanvas->window()->setFocus();
273 } );
274 }
275
276 if ( mCanvas )
277 {
278 mContext = mCanvas->createExpressionContext();
279 }
280 else
281 {
286 }
287
288 // Initialize with layer center
289 mContext << QgsExpressionContextUtils::mapLayerPositionScope( mRasterLayer->extent().center() );
290 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
291
292 connect( mInsertExpressionButton, &QAbstractButton::clicked, this, [ = ]
293 {
294 // Get the linear indexes if the start and end of the selection
295 int selectionStart = mMapTipWidget->selectionStart();
296 int selectionEnd = mMapTipWidget->selectionEnd();
297 QString expression = QgsExpressionFinder::findAndSelectActiveExpression( mMapTipWidget );
298 QgsExpressionBuilderDialog exprDlg( nullptr, expression, this, QStringLiteral( "generic" ), mContext );
299
300 exprDlg.setWindowTitle( tr( "Insert Expression" ) );
301 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
302 mMapTipWidget->insertText( "[%" + exprDlg.expressionText().trimmed() + "%]" );
303 else // Restore the selection
304 mMapTipWidget->setLinearSelection( selectionStart, selectionEnd );
305 } );
306
307 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
308
309 // Only do pyramids if dealing directly with GDAL.
310 if ( provider &&
311 ( provider->capabilities() & Qgis::RasterInterfaceCapability::BuildPyramids
312 || provider->providerCapabilities() & Qgis::RasterProviderCapability::BuildPyramids ) )
313 {
314 // initialize resampling methods
315 cboResamplingMethod->clear();
316
317 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
318 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
319 {
320 cboResamplingMethod->addItem( method.second, method.first );
321 }
322
323 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
324 QString prefix = provider->name() + "/driverOptions/_pyramids/";
325 QgsSettings mySettings;
326 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
327 int idx = cboResamplingMethod->findData( defaultMethod );
328 if ( idx >= 0 )
329 cboResamplingMethod->setCurrentIndex( idx );
330
331
332 // build pyramid list
333 const QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
334
335 for ( const QgsRasterPyramid &pyramid : myPyramidList )
336 {
337 if ( pyramid.getExists() )
338 {
339 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
340 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
341 QString::number( pyramid.getYDim() ) ) );
342 }
343 else
344 {
345 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
346 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
347 QString::number( pyramid.getYDim() ) ) );
348 }
349 }
350 }
351 else
352 {
353 // disable Pyramids tab completely
354 mOptsPage_Pyramids->setEnabled( false );
355 }
356
357 // We can calculate histogram for all data sources but estimated only if
358 // size is unknown - could also be enabled if well supported (estimated histogram
359 // and let user know that it is estimated)
360 if ( !provider || !( provider->capabilities() & Qgis::RasterInterfaceCapability::Size ) )
361 {
362 // disable Histogram tab completely
363 mOptsPage_Histogram->setEnabled( false );
364 }
365
366 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
367 layout->setContentsMargins( 0, 0, 0, 0 );
368 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
369 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
370 mMetadataWidget->setMapCanvas( mCanvas );
371 layout->addWidget( mMetadataWidget );
372 metadataFrame->setLayout( layout );
373
374 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
375 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
376 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
377 temporalLayout->addWidget( mTemporalWidget );
378
379 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( Qgis::CrsWktVariant::Preferred ), 2 );
380 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
381 mCrsSelector->setCrs( mRasterLayer->crs() );
382
383 // Set text for pyramid info box
384 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
385 QString pyramidHeader = tr( "Description" );
386 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
387 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." );
388 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
389 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
390 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
391
392 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
393 pyramidSentence1,
394 pyramidSentence2,
395 pyramidSentence3,
396 pyramidSentence4,
397 pyramidSentence5 ) );
398
399 //resampling
400 mResamplingGroupBox->setSaveCheckedState( true );
401 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
402 mResamplingUtils.refreshWidgetsFromLayer();
403
404 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
405
406 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
407 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
408
409 // Hue and saturation color control
410 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
411 //set hue and saturation controls to current values
412 if ( hueSaturationFilter )
413 {
414 sliderSaturation->setValue( hueSaturationFilter->saturation() );
415 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
416
417 // Set initial state of saturation controls based on grayscale mode choice
418 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
419
420 // Set initial state of colorize controls
421 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
422 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
423 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
424 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
425 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
426 }
427
428 //blend mode
429 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
430 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
431
432 //transparency band
433 if ( provider )
434 {
435 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
436 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
437
438// Alpha band is set in sync()
439#if 0
440 if ( renderer )
441 {
442 QgsDebugMsgLevel( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ), 2 );
443 if ( renderer->alphaBand() > 0 )
444 {
445 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
446 }
447 }
448#endif
449 }
450
451 // create histogram widget
452 mHistogramWidget = nullptr;
453 if ( mOptsPage_Histogram->isEnabled() )
454 {
455 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
456 mHistogramStackedWidget->addWidget( mHistogramWidget );
457 }
458
459 //insert renderer widgets into registry
467
468 //fill available renderers into combo box
470 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
471 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
472 for ( const QString &name : constRenderersList )
473 {
474 if ( QgsApplication::rasterRendererRegistry()->rendererData( name, entry ) )
475 {
476 if ( ( mRasterLayer->rasterType() != Qgis::RasterLayerType::SingleBandColorData && entry.name != QLatin1String( "singlebandcolordata" ) ) ||
477 ( mRasterLayer->rasterType() == Qgis::RasterLayerType::SingleBandColorData && entry.name == QLatin1String( "singlebandcolordata" ) ) )
478 {
479 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
480 }
481 }
482 }
483 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
484
485 int widgetIndex = 0;
486 if ( renderer )
487 {
488 QString rendererType = renderer->type();
489 widgetIndex = mRenderTypeComboBox->findData( rendererType );
490 if ( widgetIndex != -1 )
491 {
492 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
493 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
494 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
495 }
496
497 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
498 {
499 // no band rendering options for singlebandcolordata, so minimize group box
500 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
501 sizep.setVerticalStretch( 0 );
502 sizep.setVerticalPolicy( QSizePolicy::Maximum );
503 mBandRenderingGrpBx->setSizePolicy( sizep );
504 mBandRenderingGrpBx->updateGeometry();
505 }
506
507 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
508 {
509 mWMSPrintGroupBox->hide();
510 mPublishDataSourceUrlCheckBox->hide();
511 mBackgroundLayerCheckBox->hide();
512 }
513 }
514
515#ifdef WITH_QTWEBKIT
516 // Setup information tab
517
518 const int horizontalDpi = logicalDpiX();
519
520 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
521 if ( horizontalDpi > 96 )
522 {
523 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
524 }
525 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
526 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::openUrl );
527 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
528 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
529
530#endif
531
532 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::Property::RendererOpacity );
533
534 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
535
536 setMetadataWidget( mMetadataWidget, mOptsPage_Metadata );
537
538 QMenu *menuStyle = new QMenu( this );
539 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle );
540 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs );
541 menuStyle->addSeparator();
542 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveStyleAsDefault );
543 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle );
544 mBtnStyle->setMenu( menuStyle );
545 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
546
547 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
548 QMenu *menuMetadata = new QMenu( this );
549 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadataFromFile );
550 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataToFile );
551 menuMetadata->addSeparator();
552 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveMetadataAsDefault );
553 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
554 mBtnMetadata->setMenu( menuMetadata );
555 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
556
557 // update based on lyr's current state
558 sync();
559
560 QgsSettings settings;
561 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
562 // this will be read by restoreOptionsBaseUi()
563 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
564 {
565 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ),
566 mOptStackedWidget->indexOf( mOptsPage_Style ) );
567 }
568
569 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
570
571 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
572
573 //Add help page references
574 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
575 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
576 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
577 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
578
579 if ( mOptsPage_Histogram )
580 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
581
582 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
583 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
584
585 if ( mOptsPage_Pyramids )
586 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
587
588 if ( mOptsPage_Display )
589 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#display-properties" ) );
590
591 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
592 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
593 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
594
595 initialize();
596}
597
599{
600 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
601 {
602 return;
603 }
604
605 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
606 switch ( factory->parentPage() )
607 {
609 {
610 mConfigWidgets << page;
611
612 const QString beforePage = factory->layerPropertiesPagePositionHint();
613 if ( beforePage.isEmpty() )
614 addPage( factory->title(), factory->title(), factory->icon(), page );
615 else
616 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
617 break;
618 }
619
621 mTemporalWidget->addWidget( page );
622 break;
623 }
624}
625
630
631void QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage( )
632{
633 if ( mRasterAttributeTableWidget )
634 {
635 mOptsPage_RasterAttributeTable->layout()->removeWidget( mRasterAttributeTableWidget );
636 mRasterAttributeTableWidget = nullptr;
637 }
638
639 // Setup raster attribute table
640 if ( mRasterLayer->attributeTableCount() > 0 )
641 {
642 mRasterAttributeTableWidget = new QgsRasterAttributeTableWidget( this, mRasterLayer );
643 mOptsPage_RasterAttributeTable->layout()->addWidget( mRasterAttributeTableWidget );
644 // When the renderer changes we need to sync the style options page
645 connect( mRasterAttributeTableWidget, &QgsRasterAttributeTableWidget::rendererChanged, this, &QgsRasterLayerProperties::syncToLayer );
646 mNoRasterAttributeTableWidget->hide();
647 }
648 else
649 {
650 mNoRasterAttributeTableWidget->show();
651 mCreateRasterAttributeTableButton->setEnabled( mRasterLayer->canCreateRasterAttributeTable() );
652 }
653}
654
655void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
656{
657 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
658 QgsRasterRendererWidget *oldWidget = mRendererWidget;
659 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
660
661 int alphaBand = -1;
662 double opacity = 1;
663 QColor nodataColor;
664 const QList<int> oldBands = oldRenderer ? oldRenderer->usesBands() : QList<int>();
665 if ( oldRenderer )
666 {
667 // Retain alpha band and opacity when switching renderer
668 alphaBand = oldRenderer->alphaBand();
669 opacity = oldRenderer->opacity();
670 nodataColor = oldRenderer->nodataColor();
671 }
672
673 QgsRasterRendererRegistryEntry rendererEntry;
674 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
675 {
676 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
677 {
678 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
679 // Current canvas extent (used to calc min/max) in layer CRS
681 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
682 {
683 if ( rendererName == QLatin1String( "singlebandgray" ) )
684 {
685 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::SingleBandGray, mRasterLayer->dataProvider() ) );
686 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
687 }
688 else if ( rendererName == QLatin1String( "multibandcolor" ) )
689 {
690 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::MultiBandColor, mRasterLayer->dataProvider() ) );
691 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
692 }
693 }
694 mRasterLayer->renderer()->setAlphaBand( alphaBand );
695 mRasterLayer->renderer()->setOpacity( opacity );
696 mRasterLayer->renderer()->setNodataColor( nodataColor );
697 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
698 mRendererWidget->setMapCanvas( mCanvas );
699 mRendererStackedWidget->addWidget( mRendererWidget );
700 if ( oldWidget )
701 {
702 //compare used bands in new and old renderer and reset transparency dialog if different
703 std::unique_ptr<QgsRasterRenderer> newRenderer;
704 newRenderer.reset( mRendererWidget->renderer() );
705 const QList<int> newBands = newRenderer->usesBands();
706 if ( oldBands != newBands )
707 {
708 mRasterTransparencyWidget->syncToLayer();
709 }
710 }
711 }
712 }
713
714 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
715 if ( widgetIndex != -1 )
716 {
717 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
718 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
719 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
720 }
721
722 if ( mRendererWidget != oldWidget )
723 delete oldWidget;
724
725 if ( mHistogramWidget )
726 {
727 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
728 }
729}
730
731void QgsRasterLayerProperties::sync()
732{
733 QgsSettings myQSettings;
734
735 if ( !mSourceWidget )
736 {
737 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
738 if ( mSourceWidget )
739 {
740 QHBoxLayout *layout = new QHBoxLayout();
741 layout->addWidget( mSourceWidget );
742 mSourceGroupBox->setLayout( layout );
743 if ( !mSourceWidget->groupTitle().isEmpty() )
744 mSourceGroupBox->setTitle( mSourceWidget->groupTitle() );
745 mSourceGroupBox->show();
746
747 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [ = ]( bool isValid )
748 {
749 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
750 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
751 } );
752 }
753 }
754
755 if ( mSourceWidget )
756 {
757 mSourceWidget->setMapCanvas( mCanvas );
758 mSourceWidget->setSourceUri( mRasterLayer->source() );
759 }
760
761 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
762 if ( !provider )
763 return;
764
765 mRasterTransparencyWidget->syncToLayer();
766
767 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
769 {
770 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
771 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
772 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
773 }
774
775 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
778 {
779 if ( mOptsPage_Pyramids )
780 {
781 delete mOptsPage_Pyramids;
782 mOptsPage_Pyramids = nullptr;
783 }
784 }
785
787 {
788 if ( mOptsPage_Histogram )
789 {
790 delete mOptsPage_Histogram;
791 mOptsPage_Histogram = nullptr;
792 delete mHistogramWidget;
793 mHistogramWidget = nullptr;
794 }
795 }
796
797 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
798
799 /*
800 * Style tab
801 */
802
803 //set brightness, contrast and gamma
804 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
805 if ( brightnessFilter )
806 {
807 mSliderBrightness->setValue( brightnessFilter->brightness() );
808 mSliderContrast->setValue( brightnessFilter->contrast() );
809 mGammaSpinBox->setValue( brightnessFilter->gamma() );
810 }
811
812 // Hue and saturation color control
813 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
814 //set hue and saturation controls to current values
815 if ( hueSaturationFilter )
816 {
817 sliderSaturation->setValue( hueSaturationFilter->saturation() );
818 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
819
820 // Set state of saturation controls based on grayscale mode choice
821 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
822
823 // Set state of colorize controls
824 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
825 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
826 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
827 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
828 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
829 }
830
831 mRefreshSettingsWidget->syncToLayer();
832
833 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
834 /*
835 * General Tab
836 */
837
838 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
839
840 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
841 /*
842 * Metadata Tab
843 */
844 //populate the metadata tab's text browser widget with gdal metadata info
845 updateInformationContent();
846
847 // WMS Name as layer short name
848 mLayerShortNameLineEdit->setText( mRasterLayer->serverProperties()->shortName() );
849 // WMS Name validator
850 QValidator *shortNameValidator = new QRegularExpressionValidator( QgsApplication::shortNameRegularExpression(), this );
851 mLayerShortNameLineEdit->setValidator( shortNameValidator );
852
853 //layer title and abstract
854 mLayerTitleLineEdit->setText( mRasterLayer->serverProperties()->title() );
855 mLayerAbstractTextEdit->setPlainText( mRasterLayer->serverProperties()->abstract() );
856 mLayerKeywordListLineEdit->setText( mRasterLayer->serverProperties()->keywordList() );
857 mLayerDataUrlLineEdit->setText( mRasterLayer->serverProperties()->dataUrl() );
858 mLayerDataUrlFormatComboBox->setCurrentIndex(
859 mLayerDataUrlFormatComboBox->findText(
860 mRasterLayer->serverProperties()->dataUrlFormat()
861 )
862 );
863
864 //layer attribution
865 mLayerAttributionLineEdit->setText( mRasterLayer->serverProperties()->attribution() );
866 mLayerAttributionUrlLineEdit->setText( mRasterLayer->serverProperties()->attributionUrl() );
867
868 // layer metadata url
869 const QList<QgsMapLayerServerProperties::MetadataUrl> &metaUrls = mRasterLayer->serverProperties()->metadataUrls();
870 for ( const QgsMapLayerServerProperties::MetadataUrl &metaUrl : metaUrls )
871 {
872 const int row = mMetadataUrlModel->rowCount();
873 mMetadataUrlModel->setItem( row, 0, new QStandardItem( metaUrl.url ) );
874 mMetadataUrlModel->setItem( row, 1, new QStandardItem( metaUrl.type ) );
875 mMetadataUrlModel->setItem( row, 2, new QStandardItem( metaUrl.format ) );
876 }
877
878 // layer legend url
879 mLayerLegendUrlLineEdit->setText( mRasterLayer->legendUrl() );
880 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->legendUrlFormat() ) );
881
882 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
883 mMapTipWidget->setText( mRasterLayer->mapTipTemplate() );
884
885 //WMS print layer
886 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
887 if ( wmsPrintLayer.isValid() )
888 {
889 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
890 }
891
892 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
893 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
894
895 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
896 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
897
898 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
899 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
900 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
901
902 mTemporalWidget->syncToLayer();
903
904 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
905 updateDataDefinedButtons();
906
907 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
908 {
909 page->syncToLayer( mRasterLayer );
910 }
911
912}
913
915{
916 if ( mSourceWidget )
917 {
918 const QString newSource = mSourceWidget->sourceUri();
919 if ( newSource != mRasterLayer->source() )
920 {
921 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
922 }
923 }
924
925 // Do nothing on "bad" layers
926 if ( !mRasterLayer->isValid() )
927 return;
928
929 // apply all plugin dialogs
930 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
931 {
932 page->apply();
933 }
934
935
936 /*
937 * Legend Tab
938 */
939 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
940 mLegendConfigEmbeddedWidget->applyToLayer();
941
942 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
943 /*
944 * Symbology Tab
945 */
946
947 //set whether the layer histogram should be inverted
948 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
949
950 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
951 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
952 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
953
954 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
955 /*
956 * Transparent Pixel Tab
957 */
958
959 mRasterTransparencyWidget->applyToRasterProvider( mRasterLayer->dataProvider() );
960
961 //set renderer from widget
962 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
963 if ( rendererWidget )
964 {
965 rendererWidget->doComputations();
966
967 mRasterLayer->setRenderer( rendererWidget->renderer() );
968 }
969
970 mBackupCrs = mRasterLayer->crs();
971 mMetadataWidget->acceptMetadata();
972 mMetadataFilled = false;
973
974 //transparency settings
975 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
976 mRasterTransparencyWidget->applyToRasterRenderer( rasterRenderer );
977
978 if ( rasterRenderer )
979 {
980 // Sync the layer styling widget
981 mRasterLayer->emitStyleChanged();
982 }
983
984 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
985 /*
986 * General Tab
987 */
988 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
989
990 // set up the scale based layer visibility stuff....
991 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
992 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
993 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
994
995 mRefreshSettingsWidget->saveToLayer();
996
997 //update the legend pixmap
998 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
999 // pixmapLegend->setScaledContents( true );
1000 // pixmapLegend->repaint();
1001
1002 mResamplingUtils.refreshLayerFromWidgets();
1003
1004 // Hue and saturation controls
1005 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
1006 if ( hueSaturationFilter )
1007 {
1008 hueSaturationFilter->setSaturation( sliderSaturation->value() );
1009 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
1010 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
1011 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
1012 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
1013 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
1014 }
1015
1016 //set the blend mode for the layer
1017 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
1018
1019 // Update temporal properties
1020 mTemporalWidget->saveTemporalProperties();
1021
1022 mRasterLayer->setCrs( mCrsSelector->crs() );
1023
1024 if ( mRasterLayer->serverProperties()->shortName() != mLayerShortNameLineEdit->text() )
1025 mMetadataFilled = false;
1026 mRasterLayer->serverProperties()->setShortName( mLayerShortNameLineEdit->text() );
1027
1028 if ( mRasterLayer->serverProperties()->title() != mLayerTitleLineEdit->text() )
1029 mMetadataFilled = false;
1030 mRasterLayer->serverProperties()->setTitle( mLayerTitleLineEdit->text() );
1031
1032 if ( mRasterLayer->serverProperties()->abstract() != mLayerAbstractTextEdit->toPlainText() )
1033 mMetadataFilled = false;
1034 mRasterLayer->serverProperties()->setAbstract( mLayerAbstractTextEdit->toPlainText() );
1035
1036 if ( mRasterLayer->serverProperties()->keywordList() != mLayerKeywordListLineEdit->text() )
1037 mMetadataFilled = false;
1038 mRasterLayer->serverProperties()->setKeywordList( mLayerKeywordListLineEdit->text() );
1039
1040 if ( mRasterLayer->serverProperties()->dataUrl() != mLayerDataUrlLineEdit->text() )
1041 mMetadataFilled = false;
1042 mRasterLayer->serverProperties()->setDataUrl( mLayerDataUrlLineEdit->text() );
1043
1044 if ( mRasterLayer->serverProperties()->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1045 mMetadataFilled = false;
1046 mRasterLayer->serverProperties()->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1047
1048 //layer attribution
1049 if ( mRasterLayer->serverProperties()->attribution() != mLayerAttributionLineEdit->text() )
1050 mMetadataFilled = false;
1051 mRasterLayer->serverProperties()->setAttribution( mLayerAttributionLineEdit->text() );
1052
1053 if ( mRasterLayer->serverProperties()->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1054 mMetadataFilled = false;
1055 mRasterLayer->serverProperties()->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
1056
1057 // Metadata URL
1058 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
1059 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
1060 {
1062 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
1063 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
1064 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
1065 metaUrls.append( metaUrl );
1066 mMetadataFilled = false;
1067 }
1068 mRasterLayer->serverProperties()->setMetadataUrls( metaUrls );
1069
1070 if ( mRasterLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
1071 mMetadataFilled = false;
1072 mRasterLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
1073
1074 if ( mRasterLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1075 mMetadataFilled = false;
1076 mRasterLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
1077
1078 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1079 {
1080 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1081 }
1082
1083 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1084 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1085
1086 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
1087
1088 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
1089 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
1090
1091 // Force a redraw of the legend
1092 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
1093
1094 //make sure the layer is redrawn
1095 mRasterLayer->triggerRepaint();
1096
1097 // notify the project we've made a change
1098 QgsProject::instance()->setDirty( true );
1099}
1100
1101void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1102{
1103 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1104
1105 std::unique_ptr< QgsRasterBlockFeedback > feedback( new QgsRasterBlockFeedback() );
1106
1107 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
1108 //
1109 // Go through the list marking any files that are selected in the listview
1110 // as true so that we can generate pyramids for them.
1111 //
1112 QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1113 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1114 {
1115 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1116 //mark to be pyramided
1117 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1118 }
1119
1120 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1121 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1122 QgsSettings mySettings;
1123 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1124 mySettings.setValue( prefix + "resampling", resamplingMethod );
1125
1126 //
1127 // Ask raster layer to build the pyramids
1128 //
1129
1130 // let the user know we're going to possibly be taking a while
1131 QApplication::setOverrideCursor( Qt::WaitCursor );
1132 QString res = provider->buildPyramids(
1133 myPyramidList,
1134 resamplingMethod,
1135 cbxPyramidsFormat->currentData().value< Qgis::RasterPyramidFormat >(),
1136 QStringList(),
1137 feedback.get() );
1138 QApplication::restoreOverrideCursor();
1139 mPyramidProgress->setValue( 0 );
1140 buttonBuildPyramids->setEnabled( false );
1141 if ( !res.isNull() )
1142 {
1143 if ( res == QLatin1String( "CANCELED" ) )
1144 {
1145 // user canceled
1146 }
1147 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1148 {
1149 QMessageBox::warning( this, tr( "Building Pyramids" ),
1150 tr( "Write access denied. Adjust the file permissions and try again." ) );
1151 }
1152 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1153 {
1154 QMessageBox::warning( this, tr( "Building Pyramids" ),
1155 tr( "The file was not writable. Some formats do not "
1156 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1157 }
1158 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1159 {
1160 QMessageBox::warning( this, tr( "Building Pyramids" ),
1161 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1162 }
1163 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1164 {
1165 QMessageBox::warning( this, tr( "Building Pyramids" ),
1166 tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1167 }
1168 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1169 {
1170 QMessageBox::warning( this, tr( "Building Pyramids" ),
1171 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1172 }
1173
1174 }
1175
1176 //
1177 // repopulate the pyramids list
1178 //
1179 lbxPyramidResolutions->clear();
1180 // Need to rebuild list as some or all pyramids may have failed to build
1181 myPyramidList = provider->buildPyramidList();
1182 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1183 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1184
1185 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1186 {
1187 if ( pyramid.getExists() )
1188 {
1189 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
1190 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1191 QString::number( pyramid.getYDim() ) ) );
1192 }
1193 else
1194 {
1195 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
1196 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1197 QString::number( pyramid.getYDim() ) ) );
1198 }
1199 }
1200 //update the legend pixmap
1201 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1202 // pixmapLegend->setScaledContents( true );
1203 // pixmapLegend->repaint();
1204
1205 //populate the metadata tab's text browser widget with gdal metadata info
1206 updateInformationContent();
1207}
1208
1209void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1210{
1211 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1212 {
1213 return;
1214 }
1215
1216 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1217 setRendererWidget( rendererName );
1218}
1219
1220void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1221{
1222 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
1223 mRasterLayer->setCrs( crs );
1224 mMetadataWidget->crsChanged();
1225}
1226
1227void QgsRasterLayerProperties::aboutToShowStyleMenu()
1228{
1229 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1230
1231 QMenu *m = qobject_cast<QMenu *>( sender() );
1232
1234 // re-add style manager actions!
1235 m->addSeparator();
1237}
1238
1239void QgsRasterLayerProperties::syncToLayer()
1240{
1241 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1242 if ( renderer )
1243 {
1244 setRendererWidget( renderer->type() );
1245 }
1246 sync();
1247 mRasterLayer->triggerRepaint();
1248}
1249
1251{
1253
1254 if ( !mHistogramWidget )
1255 return;
1256
1257 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1258 {
1259 mHistogramWidget->setActive( true );
1260 }
1261 else
1262 {
1263 mHistogramWidget->setActive( false );
1264 }
1265
1266 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1267 {
1268 //set the metadata contents (which can be expensive)
1269 updateInformationContent();
1270 }
1271}
1272
1273void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1274{
1275 button->blockSignals( true );
1276 button->init( static_cast< int >( key ), mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1277 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1278 button->registerExpressionContextGenerator( this );
1279 button->blockSignals( false );
1280}
1281
1282void QgsRasterLayerProperties::updateDataDefinedButtons()
1283{
1284 const auto propertyOverrideButtons { findChildren< QgsPropertyOverrideButton * >() };
1285 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1286 {
1287 updateDataDefinedButton( button );
1288 }
1289}
1290
1291void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1292{
1293 if ( !button )
1294 return;
1295
1296 if ( button->propertyKey() < 0 )
1297 return;
1298
1299 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1300 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1301}
1302
1303void QgsRasterLayerProperties::updateProperty()
1304{
1305 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1306 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1307 mPropertyCollection.setProperty( key, button->toProperty() );
1308}
1309
1310void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1311{
1312 // Enable or disable saturation controls based on choice of grayscale mode
1313 if ( grayscaleMode == 0 )
1314 {
1315 sliderSaturation->setEnabled( true );
1316 spinBoxSaturation->setEnabled( true );
1317 }
1318 else
1319 {
1320 sliderSaturation->setEnabled( false );
1321 spinBoxSaturation->setEnabled( false );
1322 }
1323}
1324
1325void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1326{
1327 // Enable or disable colorize controls based on checkbox
1328 btnColorizeColor->setEnabled( colorizeEnabled );
1329 sliderColorizeStrength->setEnabled( colorizeEnabled );
1330 spinColorizeStrength->setEnabled( colorizeEnabled );
1331}
1332
1333
1334QLinearGradient QgsRasterLayerProperties::redGradient()
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( 242, 14, 25, 190 ) );
1340 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1341 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1342 return myGradient;
1343}
1344QLinearGradient QgsRasterLayerProperties::greenGradient()
1345{
1346 //define a gradient
1347 // TODO change this to actual polygon dims
1348 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1349 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1350 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1351 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1352 return myGradient;
1353}
1354QLinearGradient QgsRasterLayerProperties::blueGradient()
1355{
1356 //define a gradient
1357 // TODO change this to actual polygon dims
1358 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1359 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1360 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1361 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1362 return myGradient;
1363}
1364QLinearGradient QgsRasterLayerProperties::grayGradient()
1365{
1366 //define a gradient
1367 // TODO change this to actual polygon dims
1368 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1369 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1370 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1371 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1372 return myGradient;
1373}
1374QLinearGradient QgsRasterLayerProperties::highlightGradient()
1375{
1376 //define another gradient for the highlight
1377 // TODO change this to actual polygon dims
1378 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1379 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1380 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1381 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1382 return myGradient;
1383}
1384
1385void QgsRasterLayerProperties::addMetadataUrl()
1386{
1387 const int row = mMetadataUrlModel->rowCount();
1388 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
1389 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
1390 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
1391}
1392
1393void QgsRasterLayerProperties::removeSelectedMetadataUrl()
1394{
1395 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
1396 if ( selectedRows.empty() )
1397 return;
1398 mMetadataUrlModel->removeRow( selectedRows[0].row() );
1399}
1400
1401
1402//
1403//
1404// Next four methods for saving and restoring qml style state
1405//
1406//
1407
1412
1413void QgsRasterLayerProperties::restoreWindowModality()
1414{
1415 hide();
1416 setModal( true );
1417 show();
1418 raise();
1419 activateWindow();
1420}
1421
1422void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1423{
1424 if ( lbxPyramidResolutions->selectedItems().empty() )
1425 {
1426 buttonBuildPyramids->setEnabled( false );
1427 }
1428 else
1429 {
1430 buttonBuildPyramids->setEnabled( true );
1431 }
1432}
1433
1434void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1435{
1436 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1437 mSliderBrightness->setValue( 0 );
1438 mSliderContrast->setValue( 0 );
1439 mGammaSpinBox->setValue( 1.0 );
1440 sliderSaturation->setValue( 0 );
1441 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1442 mColorizeCheck->setChecked( false );
1443 sliderColorizeStrength->setValue( 100 );
1444 mInvertColorsCheck->setChecked( false );
1445}
1446
1447bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1448{
1449 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1450}
1451
1452void QgsRasterLayerProperties::updateInformationContent()
1453{
1455 // Inject the stylesheet
1456 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1457 mMetadataViewer->setHtml( html );
1458 mMetadataFilled = true;
1459}
1460
1462{
1463 // Give the user a chance to save the raster attribute table edits.
1464 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1465 {
1466 mRasterAttributeTableWidget->setEditable( false, false );
1467 }
1469
1470 if ( mBackupCrs != mRasterLayer->crs() )
1471 mRasterLayer->setCrs( mBackupCrs );
1472}
1473
1474void QgsRasterLayerProperties::showHelp()
1475{
1476 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1477
1478 if ( helpPage.isValid() )
1479 {
1480 QgsHelp::openHelp( helpPage.toString() );
1481 }
1482 else
1483 {
1484 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1485 }
1486}
1487
1488void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1489{
1490 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1491}
1492
1493void QgsRasterLayerProperties::updateGammaSlider( double value )
1494{
1495 whileBlocking( mSliderGamma )->setValue( value * 100 );
1496}
1497
1498
1499bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1500{
1501 // If the map tip preview container is resized, resize the map tip
1502 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1503 {
1504 resizeMapTip();
1505 }
1506 return QgsOptionsDialogBase::eventFilter( obj, ev );
1507}
1508
1509void QgsRasterLayerProperties::initMapTipPreview()
1510{
1511 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1512 mMapTipSplitter->setSizes( { 400, 200 } );
1513 // Event filter is used to resize the map tip when the container is resized
1514 mMapTipPreviewContainer->installEventFilter( this );
1515
1516 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1517 // Create the WebView
1518 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1519
1520#if WITH_QTWEBKIT
1521 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
1522 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1523 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1524#endif
1525
1526 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1527 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1528 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1529
1530 // Disable scrollbars, avoid random resizing issues
1531 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1532 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1533
1534
1535 // Update the map tip preview when the expression or the map tip template changes
1536 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1537}
1538
1539void QgsRasterLayerProperties::updateMapTipPreview()
1540{
1541 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1542 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mCanvas, mMapTipWidget->text() );
1543 mMapTipPreview->setHtml( htmlContent );
1544}
1545
1546void QgsRasterLayerProperties::resizeMapTip()
1547{
1548 // Ensure the map tip is not bigger than the container
1549 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1550#if WITH_QTWEBKIT
1551 // Get the content size
1552 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1553 QStringLiteral( "#QgsWebViewContainer" ) );
1554 const int width = container.geometry().width();
1555 const int height = container.geometry().height();
1556 mMapTipPreview->resize( width, height );
1557
1558 // Move the map tip to the center of the container
1559 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2,
1560 ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1561
1562#else
1563 mMapTipPreview->adjustSize();
1564#endif
1565}
@ 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:4466
@ 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:119
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:5862
#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.