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