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