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