37 #include "qgsnative.h" 
   70 #include <QDesktopServices> 
   71 #include <QTableWidgetItem> 
   72 #include <QHeaderView> 
   73 #include <QTextStream> 
   75 #include <QFileDialog> 
   76 #include <QMessageBox> 
   78 #include <QLinearGradient> 
   79 #include <QPainterPath> 
   81 #include <QColorDialog> 
   83 #include <QMouseEvent> 
   92   , TRSTRING_NOT_SET( tr( 
"Not Set" ) )
 
   93   , mDefaultStandardDeviation( 0 )
 
   94   , mDefaultRedBand( 0 )
 
   95   , mDefaultGreenBand( 0 )
 
   96   , mDefaultBlueBand( 0 )
 
   98   , mGradientHeight( 0.0 )
 
   99   , mGradientWidth( 0.0 )
 
  100   , mMapCanvas( canvas )
 
  101   , mMetadataFilled( false )
 
  103   mGrayMinimumMaximumEstimated = 
true;
 
  104   mRGBMinimumMaximumEstimated = 
true;
 
  107   connect( mLayerOrigNameLineEd, &QLineEdit::textEdited, 
this, &QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited );
 
  108   connect( buttonBuildPyramids, &QPushButton::clicked, 
this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
 
  109   connect( pbnAddValuesFromDisplay, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked );
 
  110   connect( pbnAddValuesManually, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnAddValuesManually_clicked );
 
  112   connect( pbnDefaultValues, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnDefaultValues_clicked );
 
  113   connect( pbnExportTransparentPixelValues, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked );
 
  114   connect( pbnImportTransparentPixelValues, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked );
 
  115   connect( pbnRemoveSelectedRow, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked );
 
  116   connect( mRenderTypeComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
 
  117   connect( mResetColorRenderingBtn, &QToolButton::clicked, 
this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
 
  122   connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsRasterLayerProperties::showHelp );
 
  124   connect( mSetEndAsStartStaticButton, &QPushButton::clicked, 
this, &QgsRasterLayerProperties::setEndAsStartStaticButton_clicked );
 
  125   connect( mProjectTemporalRange, &QRadioButton::toggled, 
this, &QgsRasterLayerProperties::passProjectTemporalRange_toggled );
 
  126   connect( mStaticTemporalRange, &QRadioButton::toggled, 
this, &QgsRasterLayerProperties::staticTemporalRange_toggled );
 
  128   connect( mStaticTemporalRange, &QRadioButton::toggled, mStaticWmstFrame, &QWidget::setEnabled );
 
  129   connect( mReferenceTime, &QCheckBox::toggled, mWmstReferenceTimeFrame, &QWidget::setEnabled );
 
  134   mBtnStyle = 
new QPushButton( tr( 
"Style" ) );
 
  135   QMenu *menuStyle = 
new QMenu( 
this );
 
  136   menuStyle->addAction( tr( 
"Load Style…" ), 
this, &QgsRasterLayerProperties::loadStyle_clicked );
 
  137   menuStyle->addAction( tr( 
"Save Style…" ), 
this, &QgsRasterLayerProperties::saveStyleAs_clicked );
 
  138   menuStyle->addSeparator();
 
  139   menuStyle->addAction( tr( 
"Save as Default" ), 
this, &QgsRasterLayerProperties::saveDefaultStyle_clicked );
 
  140   menuStyle->addAction( tr( 
"Restore Default" ), 
this, &QgsRasterLayerProperties::loadDefaultStyle_clicked );
 
  141   mBtnStyle->setMenu( menuStyle );
 
  142   connect( menuStyle, &QMenu::aboutToShow, 
this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
 
  143   buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
 
  145   mBtnMetadata = 
new QPushButton( tr( 
"Metadata" ), 
this );
 
  146   QMenu *menuMetadata = 
new QMenu( 
this );
 
  147   mActionLoadMetadata = menuMetadata->addAction( tr( 
"Load Metadata…" ), 
this, &QgsRasterLayerProperties::loadMetadata );
 
  148   mActionSaveMetadataAs = menuMetadata->addAction( tr( 
"Save Metadata…" ), 
this, &QgsRasterLayerProperties::saveMetadataAs );
 
  149   menuMetadata->addSeparator();
 
  150   menuMetadata->addAction( tr( 
"Save as Default" ), 
this, &QgsRasterLayerProperties::saveDefaultMetadata );
 
  151   menuMetadata->addAction( tr( 
"Restore Default" ), 
this, &QgsRasterLayerProperties::loadDefaultMetadata );
 
  152   mBtnMetadata->setMenu( menuMetadata );
 
  153   buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
 
  157   connect( 
this, &QDialog::accepted, 
this, &QgsRasterLayerProperties::apply );
 
  158   connect( 
this, &QDialog::rejected, 
this, &QgsRasterLayerProperties::onCancel );
 
  160   connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, 
this, &QgsRasterLayerProperties::apply );
 
  163   connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
 
  164   connect( mBrightnessSpinBox, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
 
  166   connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
 
  167   connect( mContrastSpinBox, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
 
  170   connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
 
  171   connect( spinBoxSaturation, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
 
  174   connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
 
  175   connect( spinColorizeStrength, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
 
  178   connect( comboGrayscale, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsRasterLayerProperties::toggleSaturationControls );
 
  181   connect( mColorizeCheck, &QAbstractButton::toggled, 
this, &QgsRasterLayerProperties::toggleColorizeControls );
 
  184   connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged, 
this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
 
  186   connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
 
  189   mScaleRangeWidget->setMapCanvas( mMapCanvas );
 
  193   leNoDataValue->setValidator( 
new QDoubleValidator( -std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), 1000, 
this ) );
 
  208     mPixelSelectorTool = qgis::make_unique<QgsMapToolEmitPoint>( canvas );
 
  214     pbnAddValuesFromDisplay->setEnabled( 
false );
 
  228     cboResamplingMethod->clear();
 
  231     for ( QPair<QString, QString> method : constProviderType )
 
  233       cboResamplingMethod->addItem( method.second, method.first );
 
  237     QString prefix = provider->
name() + 
"/driverOptions/_pyramids/";
 
  239     QString defaultMethod = mySettings.
value( prefix + 
"resampling", 
"AVERAGE" ).toString();
 
  240     int idx = cboResamplingMethod->findData( defaultMethod );
 
  242       cboResamplingMethod->setCurrentIndex( idx );
 
  247     QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
 
  249     for ( myRasterPyramidIterator = myPyramidList.begin();
 
  250           myRasterPyramidIterator != myPyramidList.end();
 
  251           ++myRasterPyramidIterator )
 
  253       if ( myRasterPyramidIterator->exists )
 
  255         lbxPyramidResolutions->addItem( 
new QListWidgetItem( myPyramidPixmap,
 
  256                                         QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral( 
" x " ) +
 
  257                                         QString::number( myRasterPyramidIterator->yDim ) ) );
 
  261         lbxPyramidResolutions->addItem( 
new QListWidgetItem( myNoPyramidPixmap,
 
  262                                         QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral( 
" x " ) +
 
  263                                         QString::number( myRasterPyramidIterator->yDim ) ) );
 
  270     mOptsPage_Pyramids->setEnabled( 
false );
 
  279     mOptsPage_Histogram->setEnabled( 
false );
 
  282   QVBoxLayout *layout = 
new QVBoxLayout( metadataFrame );
 
  283   layout->setMargin( 0 );
 
  285   mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  287   layout->addWidget( mMetadataWidget );
 
  288   metadataFrame->setLayout( layout );
 
  290   QVBoxLayout *temporalLayout = 
new QVBoxLayout( temporalFrame );
 
  291   temporalLayout->setContentsMargins( 0, 0, 0, 0 );
 
  293   temporalLayout->addWidget( mTemporalWidget );
 
  295   setSourceStaticTimeState();
 
  301     mPostgresRasterTemporalGroup->setEnabled( 
true );
 
  302     mPostgresRasterTemporalGroup->setVisible( 
true );
 
  303     mPostgresRasterTemporalGroup->setChecked( 
false );
 
  305     mPostgresRasterTemporalFieldComboBox->setFields( fields );
 
  306     mPostgresRasterTemporalFieldComboBox->setFilters( QgsFieldProxyModel::Filter::Date |
 
  307         QgsFieldProxyModel::Filter::DateTime |
 
  308         QgsFieldProxyModel::Filter::String );
 
  309     mPostgresRasterTemporalFieldComboBox->setAllowEmptyFieldName( 
true );
 
  312       mPostgresRasterDefaultTime->setEnabled( ! fieldName.isEmpty() );
 
  314     mPostgresRasterDefaultTime->setAllowNull( 
true );
 
  315     mPostgresRasterDefaultTime->setEmpty();
 
  319       const int fieldIdx {  mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral( 
"temporalFieldIndex" ) ).toInt( &ok ) };
 
  320       if ( ok && fields.exists( fieldIdx ) )
 
  322         mPostgresRasterTemporalGroup->setChecked( 
true );
 
  323         mPostgresRasterTemporalFieldComboBox->setField( fields.field( fieldIdx ).name() );
 
  326           const QDateTime defaultDateTime { QDateTime::fromString( mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral( 
"temporalDefaultTime" ) ), Qt::DateFormat::ISODate ) };
 
  327           if ( defaultDateTime.isValid() )
 
  329             mPostgresRasterDefaultTime->setDateTime( defaultDateTime );
 
  337     mPostgresRasterTemporalGroup->setEnabled( 
false );
 
  338     mPostgresRasterTemporalGroup->setVisible( 
false );
 
  343   mCrsSelector->setCrs( mRasterLayer->
crs() );
 
  346   QString pyramidFormat( QStringLiteral( 
"<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
 
  347   QString pyramidHeader    = tr( 
"Description" );
 
  348   QString pyramidSentence1 = tr( 
"Large resolution raster layers can slow navigation in QGIS." );
 
  349   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." );
 
  350   QString pyramidSentence3 = tr( 
"You must have write access in the directory where the original data is stored to build pyramids." );
 
  351   QString pyramidSentence4 = tr( 
"Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
 
  352   QString pyramidSentence5 = tr( 
"Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
 
  354   tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
 
  359                                  pyramidSentence5 ) );
 
  362   mResamplingGroupBox->setSaveCheckedState( 
true );
 
  364   mZoomedInResamplingComboBox->insertItem( 0, tr( 
"Nearest neighbour" ) );
 
  365   mZoomedInResamplingComboBox->insertItem( 1, tr( 
"Bilinear" ) );
 
  366   mZoomedInResamplingComboBox->insertItem( 2, tr( 
"Cubic" ) );
 
  367   mZoomedOutResamplingComboBox->insertItem( 0, tr( 
"Nearest neighbour" ) );
 
  368   mZoomedOutResamplingComboBox->insertItem( 1, tr( 
"Average" ) );
 
  372   if ( resampleFilter )
 
  375     if ( zoomedInResampler )
 
  377       if ( zoomedInResampler->
type() == QLatin1String( 
"bilinear" ) )
 
  379         mZoomedInResamplingComboBox->setCurrentIndex( 1 );
 
  381       else if ( zoomedInResampler->
type() == QLatin1String( 
"cubic" ) )
 
  383         mZoomedInResamplingComboBox->setCurrentIndex( 2 );
 
  388       mZoomedInResamplingComboBox->setCurrentIndex( 0 );
 
  392     if ( zoomedOutResampler )
 
  394       if ( zoomedOutResampler->
type() == QLatin1String( 
"bilinear" ) ) 
 
  396         mZoomedOutResamplingComboBox->setCurrentIndex( 1 );
 
  401       mZoomedOutResamplingComboBox->setCurrentIndex( 0 );
 
  403     mMaximumOversamplingSpinBox->setValue( resampleFilter->
maxOversampling() );
 
  406   btnColorizeColor->setColorDialogTitle( tr( 
"Select Color" ) );
 
  407   btnColorizeColor->setContext( QStringLiteral( 
"symbology" ) );
 
  412   if ( hueSaturationFilter )
 
  414     sliderSaturation->setValue( hueSaturationFilter->
saturation() );
 
  415     comboGrayscale->setCurrentIndex( ( 
int ) hueSaturationFilter->
grayscaleMode() );
 
  418     toggleSaturationControls( 
static_cast<int>( hueSaturationFilter->
grayscaleMode() ) );
 
  421     mColorizeCheck->setChecked( hueSaturationFilter->
colorizeOn() );
 
  422     btnColorizeColor->setColor( hueSaturationFilter->
colorizeColor() );
 
  423     toggleColorizeControls( hueSaturationFilter->
colorizeOn() );
 
  424     sliderColorizeStrength->setValue( hueSaturationFilter->
colorizeStrength() );
 
  428   mBlendModeComboBox->setBlendMode( mRasterLayer->
blendMode() );
 
  433     cboxTransparencyBand->setShowNotSetOption( 
true, tr( 
"None" ) );
 
  434     cboxTransparencyBand->setLayer( mRasterLayer );
 
  443         cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->
alphaBand() ) );
 
  450   mHistogramWidget = 
nullptr;
 
  451   if ( mOptsPage_Histogram->isEnabled() )
 
  454     mHistogramStackedWidget->addWidget( mHistogramWidget );
 
  467   mDisableRenderTypeComboBoxCurrentIndexChanged = 
true;
 
  469   for ( 
const QString &name : constRenderersList )
 
  480   mDisableRenderTypeComboBoxCurrentIndexChanged = 
false;
 
  485     QString rendererType = renderer->
type();
 
  486     widgetIndex = mRenderTypeComboBox->findData( rendererType );
 
  487     if ( widgetIndex != -1 )
 
  489       mDisableRenderTypeComboBoxCurrentIndexChanged = 
true;
 
  490       mRenderTypeComboBox->setCurrentIndex( widgetIndex );
 
  491       mDisableRenderTypeComboBoxCurrentIndexChanged = 
false;
 
  494     if ( rendererType == QLatin1String( 
"singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
 
  497       QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
 
  498       sizep.setVerticalStretch( 0 );
 
  499       sizep.setVerticalPolicy( QSizePolicy::Maximum );
 
  500       mBandRenderingGrpBx->setSizePolicy( sizep );
 
  501       mBandRenderingGrpBx->updateGeometry();
 
  504     if ( mRasterLayer->
providerType() != QStringLiteral( 
"wms" ) )
 
  506       mWMSPrintGroupBox->hide();
 
  507       mPublishDataSourceUrlCheckBox->hide();
 
  508       mBackgroundLayerCheckBox->hide();
 
  515 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) 
  516   const int horizontalDpi = qApp->desktop()->screen()->logicalDpiX();
 
  518   const int horizontalDpi = logicalDpiX();
 
  522   if ( horizontalDpi > 96 )
 
  524     mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
 
  526   mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
 
  527   connect( mMetadataViewer->page(), &QWebPage::linkClicked, 
this, &QgsRasterLayerProperties::urlClicked );
 
  528   mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, 
true );
 
  529   mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, 
true );
 
  533   mRenderTypeComboBox_currentIndexChanged( widgetIndex );
 
  541   if ( !settings.
contains( QStringLiteral( 
"/Windows/RasterLayerProperties/tab" ) ) )
 
  543     settings.
setValue( QStringLiteral( 
"Windows/RasterLayerProperties/tab" ),
 
  549   QString title = tr( 
"Layer Properties — %1" ).arg( lyr->
name() );
 
  557   mOptsPage_Information->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#information-properties" ) );
 
  558   mOptsPage_Source->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#source-properties" ) );
 
  559   mOptsPage_Style->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#symbology-properties" ) );
 
  560   mOptsPage_Transparency->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#transparency-properties" ) );
 
  562   if ( mOptsPage_Histogram )
 
  563     mOptsPage_Histogram->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#histogram-properties" ) );
 
  565   mOptsPage_Rendering->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#rendering-properties" ) );
 
  567   if ( mOptsPage_Pyramids )
 
  568     mOptsPage_Pyramids->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#pyramids-properties" ) );
 
  570   mOptsPage_Metadata->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#metadata-properties" ) );
 
  571   mOptsPage_Legend->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#legend-properties" ) );
 
  572   mOptsPage_Server->setProperty( 
"helpPage", QStringLiteral( 
"working_with_raster/raster_properties.html#server-properties" ) );
 
  575 void QgsRasterLayerProperties::setupTransparencyTable( 
int nBands )
 
  577   tableTransparency->clear();
 
  578   tableTransparency->setColumnCount( 0 );
 
  579   tableTransparency->setRowCount( 0 );
 
  580   mTransparencyToEdited.clear();
 
  584     tableTransparency->setColumnCount( 4 );
 
  585     tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Red" ) ) );
 
  586     tableTransparency->setHorizontalHeaderItem( 1, 
new QTableWidgetItem( tr( 
"Green" ) ) );
 
  587     tableTransparency->setHorizontalHeaderItem( 2, 
new QTableWidgetItem( tr( 
"Blue" ) ) );
 
  588     tableTransparency->setHorizontalHeaderItem( 3, 
new QTableWidgetItem( tr( 
"Percent Transparent" ) ) );
 
  592     tableTransparency->setColumnCount( 3 );
 
  595     if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
 
  596          QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
 
  597          QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
 
  598          QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
 
  600       tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Gray" ) ) );
 
  604       tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Indexed Value" ) ) );
 
  607     tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"From" ) ) );
 
  608     tableTransparency->setHorizontalHeaderItem( 1, 
new QTableWidgetItem( tr( 
"To" ) ) );
 
  609     tableTransparency->setHorizontalHeaderItem( 2, 
new QTableWidgetItem( tr( 
"Percent Transparent" ) ) );
 
  612   tableTransparency->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
 
  613   tableTransparency->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
 
  616 void QgsRasterLayerProperties::populateTransparencyTable( 
QgsRasterRenderer *renderer )
 
  628   int nBands = renderer->
usesBands().size();
 
  629   setupTransparencyTable( nBands );
 
  632   if ( !rasterTransparency )
 
  640     for ( 
int i = 0; i < pixelList.size(); ++i )
 
  642       tableTransparency->insertRow( i );
 
  643       setTransparencyCell( i, 0, pixelList[i].min );
 
  644       setTransparencyCell( i, 1, pixelList[i].max );
 
  645       setTransparencyCell( i, 2, pixelList[i].percentTransparent );
 
  647       if ( pixelList[i].min != pixelList[i].max )
 
  649         setTransparencyToEdited( i );
 
  653   else if ( nBands == 3 )
 
  656     for ( 
int i = 0; i < pixelList.size(); ++i )
 
  658       tableTransparency->insertRow( i );
 
  659       setTransparencyCell( i, 0, pixelList[i].red );
 
  660       setTransparencyCell( i, 1, pixelList[i].green );
 
  661       setTransparencyCell( i, 2, pixelList[i].blue );
 
  662       setTransparencyCell( i, 3, pixelList[i].percentTransparent );
 
  666   tableTransparency->resizeColumnsToContents();
 
  667   tableTransparency->resizeRowsToContents();
 
  670 void QgsRasterLayerProperties::setRendererWidget( 
const QString &rendererName )
 
  683     opacity = oldRenderer->
opacity();
 
  692       QgsDebugMsg( QStringLiteral( 
"renderer has widgetCreateFunction" ) );
 
  695       if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->
type() ) )
 
  697         if ( rendererName == QLatin1String( 
"singlebandgray" ) )
 
  700           whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
 
  702         else if ( rendererName == QLatin1String( 
"multibandcolor" ) )
 
  705           whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
 
  713       mRendererStackedWidget->addWidget( mRendererWidget );
 
  719         QList<int> oldBands = oldRenderer->
usesBands();
 
  720         QList<int> newBands = newRenderer->
usesBands();
 
  721         if ( oldBands != newBands )
 
  723           populateTransparencyTable( newRenderer );
 
  731   const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
 
  732   if ( widgetIndex != -1 )
 
  734     mDisableRenderTypeComboBoxCurrentIndexChanged = 
true;
 
  735     mRenderTypeComboBox->setCurrentIndex( widgetIndex );
 
  736     mDisableRenderTypeComboBoxCurrentIndexChanged = 
false;
 
  739   if ( mRendererWidget != oldWidget )
 
  742   if ( mHistogramWidget )
 
  757 void QgsRasterLayerProperties::sync()
 
  768     gboxNoDataValue->setEnabled( 
false );
 
  769     gboxCustomTransparency->setEnabled( 
false );
 
  770     mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
 
  776     if ( mOptsPage_Pyramids )
 
  778       delete mOptsPage_Pyramids;
 
  779       mOptsPage_Pyramids = 
nullptr;
 
  785     if ( mOptsPage_Histogram )
 
  787       delete mOptsPage_Histogram;
 
  788       mOptsPage_Histogram = 
nullptr;
 
  789       delete mHistogramWidget;
 
  790       mHistogramWidget = 
nullptr;
 
  794   QgsDebugMsg( QStringLiteral( 
"populate transparency tab" ) );
 
  801   if ( brightnessFilter )
 
  803     mSliderBrightness->setValue( brightnessFilter->
brightness() );
 
  804     mSliderContrast->setValue( brightnessFilter->
contrast() );
 
  818     cboxTransparencyBand->setBand( renderer->
alphaBand() );
 
  830     lblSrcNoDataValue->setText( tr( 
"not defined" ) );
 
  837   mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
 
  838   lblSrcNoDataValue->setEnabled( enableSrcNoData );
 
  841   QgsDebugMsg( QStringLiteral( 
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
 
  842   if ( !noDataRangeList.isEmpty() )
 
  848     leNoDataValue->insert( QString() );
 
  855   populateTransparencyTable( mRasterLayer->
renderer() );
 
  857   QgsDebugMsg( QStringLiteral( 
"populate colormap tab" ) );
 
  862   QgsDebugMsg( QStringLiteral( 
"populate general tab" ) );
 
  868   mLayerOrigNameLineEd->setText( mRasterLayer->
name() );
 
  869   leDisplayName->setText( mRasterLayer->
name() );
 
  872   QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
 
  873   pixmapThumbnail->setPixmap( thumbnail );
 
  879   pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
 
  880   pixmapLegend->setScaledContents( 
true );
 
  881   pixmapLegend->repaint();
 
  884   pixmapPalette->setPixmap( mRasterLayer->
paletteAsPixmap( mRasterLayer->bandNumber( mRasterLayer->grayBandName() ) ) );
 
  885   pixmapPalette->setScaledContents( 
true );
 
  886   pixmapPalette->repaint();
 
  889   QgsDebugMsg( QStringLiteral( 
"populate metadata tab" ) );
 
  894   updateInformationContent();
 
  897   mLayerShortNameLineEdit->setText( mRasterLayer->
shortName() );
 
  900   mLayerShortNameLineEdit->setValidator( shortNameValidator );
 
  903   mLayerTitleLineEdit->setText( mRasterLayer->
title() );
 
  904   mLayerAbstractTextEdit->setPlainText( mRasterLayer->
abstract() );
 
  905   mLayerKeywordListLineEdit->setText( mRasterLayer->
keywordList() );
 
  906   mLayerDataUrlLineEdit->setText( mRasterLayer->
dataUrl() );
 
  907   mLayerDataUrlFormatComboBox->setCurrentIndex(
 
  908     mLayerDataUrlFormatComboBox->findText(
 
  914   mLayerAttributionLineEdit->setText( mRasterLayer->
attribution() );
 
  915   mLayerAttributionUrlLineEdit->setText( mRasterLayer->
attributionUrl() );
 
  916   mLayerMetadataUrlLineEdit->setText( mRasterLayer->
metadataUrl() );
 
  917   mLayerMetadataUrlTypeComboBox->setCurrentIndex(
 
  918     mLayerMetadataUrlTypeComboBox->findText(
 
  922   mLayerMetadataUrlFormatComboBox->setCurrentIndex(
 
  923     mLayerMetadataUrlFormatComboBox->findText(
 
  928   mLayerLegendUrlLineEdit->setText( mRasterLayer->
legendUrl() );
 
  929   mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->
legendUrlFormat() ) );
 
  932   QVariant wmsPrintLayer = mRasterLayer->
customProperty( QStringLiteral( 
"WMSPrintLayer" ) );
 
  933   if ( wmsPrintLayer.isValid() )
 
  935     mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
 
  938   QVariant wmsPublishDataSourceUrl = mRasterLayer->
customProperty( QStringLiteral( 
"WMSPublishDataSourceUrl" ), 
false );
 
  939   mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
 
  941   QVariant wmsBackgroundLayer = mRasterLayer->
customProperty( QStringLiteral( 
"WMSBackgroundLayer" ), 
false );
 
  942   mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
 
  944   mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
 
  949 void QgsRasterLayerProperties::apply()
 
  953   if ( !mRasterLayer->
isValid() )
 
  959   mLegendConfigEmbeddedWidget->applyToLayer();
 
  961   QgsDebugMsg( QStringLiteral( 
"apply processing symbology tab" ) );
 
  972   QgsDebugMsg( QStringLiteral( 
"processing transparency tab" ) );
 
  979   if ( 
"" != leNoDataValue->text() )
 
  981     bool myDoubleOk = 
false;
 
  982     double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
 
  986       myNoDataRangeList << myNoDataRange;
 
  989   for ( 
int bandNo = 1; bandNo <= mRasterLayer->
dataProvider()->bandCount(); bandNo++ )
 
  997   if ( rendererWidget )
 
 1005   mMetadataFilled = 
false;
 
 1009   if ( rasterRenderer )
 
 1011     rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
 
 1015     if ( tableTransparency->columnCount() == 4 )
 
 1018       QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
 
 1019       for ( 
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
 
 1021         myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
 
 1022         myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
 
 1023         myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
 
 1025         myTransparentThreeValuePixelList.append( myTransparentPixel );
 
 1029     else if ( tableTransparency->columnCount() == 3 )
 
 1032       QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
 
 1033       for ( 
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
 
 1035         myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
 
 1036         myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
 
 1039         myTransparentSingleValuePixelList.append( myTransparentPixel );
 
 1047     rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
 
 1050   QgsDebugMsg( QStringLiteral( 
"processing general tab" ) );
 
 1054   mRasterLayer->
setName( mLayerOrigNameLineEd->text() );
 
 1070   if ( resampleFilter )
 
 1073     QString zoomedInResamplingMethod = mZoomedInResamplingComboBox->currentText();
 
 1074     if ( zoomedInResamplingMethod == tr( 
"Bilinear" ) )
 
 1078     else if ( zoomedInResamplingMethod == tr( 
"Cubic" ) )
 
 1087     QString zoomedOutResamplingMethod = mZoomedOutResamplingComboBox->currentText();
 
 1088     if ( zoomedOutResamplingMethod == tr( 
"Average" ) )
 
 1100   if ( hueSaturationFilter )
 
 1102     hueSaturationFilter->
setSaturation( sliderSaturation->value() );
 
 1104     hueSaturationFilter->
setColorizeOn( mColorizeCheck->checkState() );
 
 1110   mRasterLayer->
setBlendMode( mBlendModeComboBox->blendMode() );
 
 1112   updateSourceStaticTime();
 
 1118     if ( mPostgresRasterTemporalGroup->isEnabled() &&
 
 1119          mPostgresRasterTemporalGroup->isChecked() &&
 
 1120          ! mPostgresRasterTemporalFieldComboBox->currentField().isEmpty() )
 
 1122       const QString originaUri { uri.
uri() };
 
 1124       uri.removeParam( QStringLiteral( 
"temporalFieldIndex" ) );
 
 1125       uri.removeParam( QStringLiteral( 
"temporalDefaultTime" ) );
 
 1126       if ( fieldIdx >= 0 )
 
 1128         uri.setParam( QStringLiteral( 
"temporalFieldIndex" ), QString::number( fieldIdx ) );
 
 1129         if ( mPostgresRasterDefaultTime->dateTime().isValid() )
 
 1131           QDateTime defaultDateTime  { mPostgresRasterDefaultTime->dateTime() };
 
 1132           const QTime defaultTime { defaultDateTime.time() };
 
 1134           defaultDateTime.setTime( { defaultTime.hour(), defaultTime.minute(), 0 } );
 
 1135           uri.setParam( QStringLiteral( 
"temporalDefaultTime" ), defaultDateTime.toString( Qt::DateFormat::ISODate ) );
 
 1137         if ( uri.uri( ) != originaUri )
 
 1141     else if ( uri.hasParam( QStringLiteral( 
"temporalFieldIndex" ) ) )
 
 1143       uri.removeParam( QStringLiteral( 
"temporalFieldIndex" ) );
 
 1144       uri.removeParam( QStringLiteral( 
"temporalDefaultTime" ) );
 
 1152   mRasterLayer->
setCrs( mCrsSelector->crs() );
 
 1155   QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
 
 1156   pixmapThumbnail->setPixmap( thumbnail );
 
 1158   if ( mRasterLayer->
shortName() != mLayerShortNameLineEdit->text() )
 
 1159     mMetadataFilled = 
false;
 
 1160   mRasterLayer->
setShortName( mLayerShortNameLineEdit->text() );
 
 1162   if ( mRasterLayer->
title() != mLayerTitleLineEdit->text() )
 
 1163     mMetadataFilled = 
false;
 
 1164   mRasterLayer->
setTitle( mLayerTitleLineEdit->text() );
 
 1166   if ( mRasterLayer->
abstract() != mLayerAbstractTextEdit->toPlainText() )
 
 1167     mMetadataFilled = 
false;
 
 1168   mRasterLayer->
setAbstract( mLayerAbstractTextEdit->toPlainText() );
 
 1170   if ( mRasterLayer->
keywordList() != mLayerKeywordListLineEdit->text() )
 
 1171     mMetadataFilled = 
false;
 
 1172   mRasterLayer->
setKeywordList( mLayerKeywordListLineEdit->text() );
 
 1174   if ( mRasterLayer->
dataUrl() != mLayerDataUrlLineEdit->text() )
 
 1175     mMetadataFilled = 
false;
 
 1176   mRasterLayer->
setDataUrl( mLayerDataUrlLineEdit->text() );
 
 1178   if ( mRasterLayer->
dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
 
 1179     mMetadataFilled = 
false;
 
 1180   mRasterLayer->
setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
 
 1183   if ( mRasterLayer->
attribution() != mLayerAttributionLineEdit->text() )
 
 1184     mMetadataFilled = 
false;
 
 1185   mRasterLayer->
setAttribution( mLayerAttributionLineEdit->text() );
 
 1187   if ( mRasterLayer->
attributionUrl() != mLayerAttributionUrlLineEdit->text() )
 
 1188     mMetadataFilled = 
false;
 
 1191   if ( mRasterLayer->
metadataUrl() != mLayerMetadataUrlLineEdit->text() )
 
 1192     mMetadataFilled = 
false;
 
 1193   mRasterLayer->
setMetadataUrl( mLayerMetadataUrlLineEdit->text() );
 
 1195   if ( mRasterLayer->
metadataUrlType() != mLayerMetadataUrlTypeComboBox->currentText() )
 
 1196     mMetadataFilled = 
false;
 
 1199   if ( mRasterLayer->
metadataUrlFormat() != mLayerMetadataUrlFormatComboBox->currentText() )
 
 1200     mMetadataFilled = 
false;
 
 1203   if ( mRasterLayer->
legendUrl() != mLayerLegendUrlLineEdit->text() )
 
 1204     mMetadataFilled = 
false;
 
 1205   mRasterLayer->
setLegendUrl( mLayerLegendUrlLineEdit->text() );
 
 1207   if ( mRasterLayer->
legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
 
 1208     mMetadataFilled = 
false;
 
 1211   if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
 
 1213     mRasterLayer->
setCustomProperty( QStringLiteral( 
"WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
 
 1216   mRasterLayer->
setCustomProperty( 
"WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
 
 1217   mRasterLayer->
setCustomProperty( 
"WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
 
 1229 void QgsRasterLayerProperties::updateSourceStaticTime()
 
 1235   QVariantMap uri = currentUri;
 
 1237   if ( mWmstGroup->isVisibleTo( 
this ) )
 
 1238     uri[ QStringLiteral( 
"allowTemporalUpdates" ) ] = mWmstGroup->isChecked();
 
 1241   if ( mWmstGroup->isEnabled() &&
 
 1245     bool enableTime = !mDisableTime->isChecked();
 
 1247     uri[ QStringLiteral( 
"enableTime" ) ] = enableTime;
 
 1249           mFetchModeComboBox->currentData().toInt() ) );
 
 1254       if ( mStaticTemporalRange->isChecked() )
 
 1256         QString time = mStartStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs ) + 
'/' +
 
 1257                        mEndStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
 
 1258         uri[ QStringLiteral( 
"time" ) ] = time;
 
 1259         uri[ QStringLiteral( 
"temporalSource" ) ] = QLatin1String( 
"provider" );
 
 1262       if ( mProjectTemporalRange->isChecked() )
 
 1264         QgsDateTimeRange range;
 
 1268         if ( range.begin().isValid() && range.end().isValid() )
 
 1270           QString time = range.begin().toString( Qt::ISODateWithMs ) + 
'/' +
 
 1271                          range.end().toString( Qt::ISODateWithMs );
 
 1273           uri[ QStringLiteral( 
"time" ) ] = time;
 
 1274           uri[ QStringLiteral( 
"temporalSource" ) ] = QLatin1String( 
"project" );
 
 1279     if ( mReferenceTime->isChecked() )
 
 1281       QString referenceTime = mReferenceDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
 
 1282       uri[ QStringLiteral( 
"referenceTime" ) ] = referenceTime;
 
 1286       if ( uri.contains( QStringLiteral( 
"referenceTime" ) ) )
 
 1287         uri.remove( QStringLiteral( 
"referenceTime" ) );
 
 1291   if ( currentUri != uri )
 
 1295 void QgsRasterLayerProperties::setSourceStaticTimeState()
 
 1307     mStartStaticDateTimeEdit->setDisplayFormat( 
"yyyy-MM-dd HH:mm:ss" );
 
 1308     mEndStaticDateTimeEdit->setDisplayFormat( 
"yyyy-MM-dd HH:mm:ss" );
 
 1309     mReferenceDateTimeEdit->setDisplayFormat( 
"yyyy-MM-dd HH:mm:ss" );
 
 1312     if ( availableProviderRange.begin().isValid() && availableProviderRange.end().isValid() )
 
 1314       mStartStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
 
 1315           availableProviderRange.end() );
 
 1316       mStartStaticDateTimeEdit->setDateTime( availableProviderRange.begin() );
 
 1317       mEndStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
 
 1318           availableProviderRange.end() );
 
 1319       mEndStaticDateTimeEdit->setDateTime( availableProviderRange.end() );
 
 1321     if ( availableReferenceRange.begin().isValid() && availableReferenceRange.end().isValid() )
 
 1323       mReferenceDateTimeEdit->setDateTimeRange( availableReferenceRange.begin(),
 
 1324           availableReferenceRange.end() );
 
 1325       mReferenceDateTimeEdit->setDateTime( availableReferenceRange.begin() );
 
 1328     const QString time = uri.value( QStringLiteral( 
"time" ) ).toString();
 
 1329     if ( !time.isEmpty() )
 
 1331       QStringList parts = time.split( 
'/' );
 
 1332       mStartStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 0 ), Qt::ISODateWithMs ) );
 
 1333       mEndStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 1 ), Qt::ISODateWithMs ) );
 
 1336     const QString referenceTimeExtent = uri.value( QStringLiteral( 
"referenceTimeDimensionExtent" ) ).toString();
 
 1338     mReferenceTime->setEnabled( !referenceTimeExtent.isEmpty() );
 
 1339     mReferenceDateTimeEdit->setVisible( !referenceTimeExtent.isEmpty() );
 
 1341     QString referenceTimeLabelText = referenceTimeExtent.isEmpty() ?
 
 1342                                      tr( 
"There is no reference time in the layer's capabilities." ) : QString();
 
 1343     mReferenceTimeLabel->setText( referenceTimeLabelText );
 
 1345     const QString referenceTime = uri.value( QStringLiteral( 
"referenceTime" ) ).toString();
 
 1347     mReferenceTime->setChecked( !referenceTime.isEmpty() );
 
 1349     if ( !referenceTime.isEmpty() && !referenceTimeExtent.isEmpty() )
 
 1351       mReferenceDateTimeEdit->setDateTime( QDateTime::fromString( referenceTime, Qt::ISODateWithMs ) );
 
 1359     mFetchModeComboBox->setCurrentIndex( mFetchModeComboBox->findData( qobject_cast< QgsRasterLayerTemporalProperties * >( mRasterLayer->
temporalProperties() )->intervalHandlingMethod() ) );
 
 1361     const QString temporalSource = uri.value( QStringLiteral( 
"temporalSource" ) ).toString();
 
 1362     bool enableTime = uri.value( QStringLiteral( 
"enableTime" ), 
true ).toBool();
 
 1364     if ( temporalSource == QLatin1String( 
"provider" ) )
 
 1365       mStaticTemporalRange->setChecked( !time.isEmpty() );
 
 1366     else if ( temporalSource == QLatin1String( 
"project" ) )
 
 1367       mProjectTemporalRange->setChecked( !time.isEmpty() );
 
 1369     mDisableTime->setChecked( !enableTime );
 
 1374       mWmstOptionsLabel->setText( tr( 
"The static temporal options below are disabled because the layer " 
 1375                                       "temporal properties are active, to enable them disable temporal properties " 
 1376                                       "in the temporal tab. " ) );
 
 1377     QgsDateTimeRange range;
 
 1381     if ( !range.begin().isValid() || !range.end().isValid() )
 
 1383       mProjectTemporalRange->setEnabled( 
false );
 
 1384       mProjectTemporalRangeLabel->setText( tr( 
"The option below is disabled because the project temporal range " 
 1385                                            "is not valid, update the project temporal range in the project properties " 
 1386                                            "with valid values in order to use it here." ) );
 
 1389     mWmstGroup->setChecked( uri.contains( QStringLiteral( 
"allowTemporalUpdates" ) ) &&
 
 1390                             uri.value( QStringLiteral( 
"allowTemporalUpdates" ), 
true ).toBool() );
 
 1394 void QgsRasterLayerProperties::staticTemporalRange_toggled( 
bool checked )
 
 1402 void QgsRasterLayerProperties::passProjectTemporalRange_toggled( 
bool checked )
 
 1406     QgsDateTimeRange range;
 
 1410     if ( range.begin().isValid() && range.end().isValid() )
 
 1411       mLabel->setText( tr( 
"Project temporal range is set from %1 to %2" ).arg(
 
 1412                          range.begin().toString( 
"yyyy-MM-dd HH:mm:ss" ),
 
 1413                          range.end().toString( 
"yyyy-MM-dd HH:mm:ss" )
 
 1416       mLabel->setText( tr( 
"Project temporal range is not valid, can't use it here" ) );
 
 1420 void QgsRasterLayerProperties::temporalPropertiesChange()
 
 1425     mWmstOptionsLabel->setText( tr( 
"The static temporal options below are disabled because the layer " 
 1426                                     "temporal properties are active, to enable them disable temporal properties " 
 1427                                     "in the temporal tab. " ) );
 
 1429     mWmstOptionsLabel->clear();
 
 1432 void QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited( 
const QString &text )
 
 1437 void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
 
 1449   for ( 
int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
 
 1451     QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
 
 1453     myPyramidList[myCounterInt].build = myItem->isSelected() || myPyramidList[myCounterInt].exists;
 
 1457   QString prefix = provider->
name() + 
"/driverOptions/_pyramids/";
 
 1459   QString resamplingMethod( cboResamplingMethod->currentData().toString() );
 
 1460   mySettings.
setValue( prefix + 
"resampling", resamplingMethod );
 
 1467   QApplication::setOverrideCursor( Qt::WaitCursor );
 
 1474   QApplication::restoreOverrideCursor();
 
 1475   mPyramidProgress->setValue( 0 );
 
 1476   buttonBuildPyramids->setEnabled( 
false );
 
 1477   if ( !res.isNull() )
 
 1479     if ( res == QLatin1String( 
"CANCELED" ) )
 
 1483     else if ( res == QLatin1String( 
"ERROR_WRITE_ACCESS" ) )
 
 1485       QMessageBox::warning( 
this, tr( 
"Building Pyramids" ),
 
 1486                             tr( 
"Write access denied. Adjust the file permissions and try again." ) );
 
 1488     else if ( res == QLatin1String( 
"ERROR_WRITE_FORMAT" ) )
 
 1490       QMessageBox::warning( 
this, tr( 
"Building Pyramids" ),
 
 1491                             tr( 
"The file was not writable. Some formats do not " 
 1492                                 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
 
 1494     else if ( res == QLatin1String( 
"FAILED_NOT_SUPPORTED" ) )
 
 1496       QMessageBox::warning( 
this, tr( 
"Building Pyramids" ),
 
 1497                             tr( 
"Building pyramid overviews is not supported on this type of raster." ) );
 
 1499     else if ( res == QLatin1String( 
"ERROR_JPEG_COMPRESSION" ) )
 
 1501       QMessageBox::warning( 
this, tr( 
"Building Pyramids" ),
 
 1502                             tr( 
"Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
 
 1504     else if ( res == QLatin1String( 
"ERROR_VIRTUAL" ) )
 
 1506       QMessageBox::warning( 
this, tr( 
"Building Pyramids" ),
 
 1507                             tr( 
"Building pyramid overviews is not supported on this type of raster." ) );
 
 1515   lbxPyramidResolutions->clear();
 
 1521   QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
 
 1522   for ( myRasterPyramidIterator = myPyramidList.begin();
 
 1523         myRasterPyramidIterator != myPyramidList.end();
 
 1524         ++myRasterPyramidIterator )
 
 1526     if ( myRasterPyramidIterator->exists )
 
 1528       lbxPyramidResolutions->addItem( 
new QListWidgetItem( myPyramidPixmap,
 
 1529                                       QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral( 
" x " ) +
 
 1530                                       QString::number( myRasterPyramidIterator->yDim ) ) );
 
 1534       lbxPyramidResolutions->addItem( 
new QListWidgetItem( myNoPyramidPixmap,
 
 1535                                       QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral( 
" x " ) +
 
 1536                                       QString::number( myRasterPyramidIterator->yDim ) ) );
 
 1545   updateInformationContent();
 
 1548 void QgsRasterLayerProperties::urlClicked( 
const QUrl &url )
 
 1550   QFileInfo file( url.toLocalFile() );
 
 1551   if ( file.exists() && !file.isDir() )
 
 1554     QDesktopServices::openUrl( url );
 
 1557 void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( 
int index )
 
 1559   if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
 
 1564   QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
 
 1565   setRendererWidget( rendererName );
 
 1568 void QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked()
 
 1570   if ( mMapCanvas && mPixelSelectorTool )
 
 1579     mMapCanvas->window()->raise();
 
 1580     mMapCanvas->window()->activateWindow();
 
 1581     mMapCanvas->window()->setFocus();
 
 1582     mMapCanvas->
setMapTool( mPixelSelectorTool.get() );
 
 1587 void QgsRasterLayerProperties::pbnAddValuesManually_clicked()
 
 1595   tableTransparency->insertRow( tableTransparency->rowCount() );
 
 1600   for ( 
int i = 0; i < n; i++ )
 
 1602     setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
 
 1605   setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
 
 1607   tableTransparency->resizeColumnsToContents();
 
 1608   tableTransparency->resizeRowsToContents();
 
 1618 void QgsRasterLayerProperties::pbnDefaultValues_clicked()
 
 1620   if ( !mRendererWidget )
 
 1634   setupTransparencyTable( nBands );
 
 1636   tableTransparency->resizeColumnsToContents(); 
 
 1637   tableTransparency->resizeRowsToContents();
 
 1640 void QgsRasterLayerProperties::setTransparencyCell( 
int row, 
int column, 
double value )
 
 1642   QgsDebugMsg( QStringLiteral( 
"value = %1" ).arg( value, 0, 
'g', 17 ) );
 
 1644   if ( !provider ) 
return;
 
 1647   if ( !renderer ) 
return;
 
 1648   int nBands = renderer->
usesBands().size();
 
 1650   QLineEdit *lineEdit = 
new QLineEdit();
 
 1651   lineEdit->setFrame( 
false ); 
 
 1653   lineEdit->setContentsMargins( 1, 1, 1, 1 );
 
 1655   if ( column == tableTransparency->columnCount() - 1 )
 
 1659     lineEdit->setValidator( 
new QIntValidator( 
nullptr ) );
 
 1660     lineEdit->setText( QString::number( 
static_cast<int>( value ) ) );
 
 1665     QString valueString;
 
 1670         lineEdit->setValidator( 
new QDoubleValidator( 
nullptr ) );
 
 1671         if ( !std::isnan( value ) )
 
 1677         lineEdit->setValidator( 
new QIntValidator( 
nullptr ) );
 
 1678         if ( !std::isnan( value ) )
 
 1680           valueString = QString::number( 
static_cast<int>( value ) );
 
 1684     lineEdit->setText( valueString );
 
 1686   tableTransparency->setCellWidget( row, column, lineEdit );
 
 1687   adjustTransparencyCellWidth( row, column );
 
 1689   if ( nBands == 1 && ( column == 0 || column == 1 ) )
 
 1691     connect( lineEdit, &QLineEdit::textEdited, 
this, &QgsRasterLayerProperties::transparencyCellTextEdited );
 
 1693   tableTransparency->resizeColumnsToContents();
 
 1696 void QgsRasterLayerProperties::setTransparencyCellValue( 
int row, 
int column, 
double value )
 
 1698   QLineEdit *lineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
 
 1699   if ( !lineEdit ) 
return;
 
 1701   lineEdit->adjustSize();
 
 1702   adjustTransparencyCellWidth( row, column );
 
 1703   tableTransparency->resizeColumnsToContents();
 
 1706 double QgsRasterLayerProperties::transparencyCellValue( 
int row, 
int column )
 
 1708   QLineEdit *lineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
 
 1709   if ( !lineEdit || lineEdit->text().isEmpty() )
 
 1711     return std::numeric_limits<double>::quiet_NaN();
 
 1713   return lineEdit->text().toDouble();
 
 1716 void QgsRasterLayerProperties::adjustTransparencyCellWidth( 
int row, 
int column )
 
 1718   QLineEdit *lineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
 
 1719   if ( !lineEdit ) 
return;
 
 1721   int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
 
 1722   width = std::max( width, tableTransparency->columnWidth( column ) );
 
 1724   lineEdit->setFixedWidth( width );
 
 1727 void QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked()
 
 1730   QString myLastDir = myQSettings.
value( QStringLiteral( 
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
 
 1731   QString myFileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save File" ), myLastDir, tr( 
"Textfile" ) + 
" (*.txt)" );
 
 1732   if ( !myFileName.isEmpty() )
 
 1734     if ( !myFileName.endsWith( QLatin1String( 
".txt" ), Qt::CaseInsensitive ) )
 
 1736       myFileName = myFileName + 
".txt";
 
 1739     QFile myOutputFile( myFileName );
 
 1740     if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
 
 1742       QTextStream myOutputStream( &myOutputFile );
 
 1743       myOutputStream << 
"# " << tr( 
"QGIS Generated Transparent Pixel Value Export File" ) << 
'\n';
 
 1744       if ( rasterIsMultiBandColor() )
 
 1746         myOutputStream << 
"#\n#\n# " << tr( 
"Red" ) << 
"\t" << tr( 
"Green" ) << 
"\t" << tr( 
"Blue" ) << 
"\t" << tr( 
"Percent Transparent" );
 
 1747         for ( 
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
 
 1749           myOutputStream << 
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) << 
"\t" 
 1750                          << QString::number( transparencyCellValue( myTableRunner, 1 ) ) << 
"\t" 
 1751                          << QString::number( transparencyCellValue( myTableRunner, 2 ) ) << 
"\t" 
 1752                          << QString::number( transparencyCellValue( myTableRunner, 3 ) );
 
 1757         myOutputStream << 
"#\n#\n# " << tr( 
"Value" ) << 
"\t" << tr( 
"Percent Transparent" );
 
 1759         for ( 
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
 
 1761           myOutputStream << 
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) << 
"\t" 
 1762                          << QString::number( transparencyCellValue( myTableRunner, 1 ) ) << 
"\t" 
 1763                          << QString::number( transparencyCellValue( myTableRunner, 2 ) );
 
 1769       QMessageBox::warning( 
this, tr( 
"Export Transparent Pixels" ), tr( 
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
 
 1774 void QgsRasterLayerProperties::transparencyCellTextEdited( 
const QString &text )
 
 1777   QgsDebugMsg( QStringLiteral( 
"text = %1" ).arg( text ) );
 
 1783   int nBands = renderer->
usesBands().size();
 
 1786     QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
 
 1787     if ( !lineEdit ) 
return;
 
 1790     for ( 
int r = 0; r < tableTransparency->rowCount(); r++ )
 
 1792       for ( 
int c = 0; 
c < tableTransparency->columnCount(); 
c++ )
 
 1794         if ( tableTransparency->cellWidget( r, 
c ) == sender() )
 
 1801       if ( row != -1 ) 
break;
 
 1803     QgsDebugMsg( QStringLiteral( 
"row = %1 column =%2" ).arg( row ).arg( column ) );
 
 1807       QLineEdit *toLineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
 
 1808       if ( !toLineEdit ) 
return;
 
 1809       bool toChanged = mTransparencyToEdited.value( row );
 
 1810       QgsDebugMsg( QStringLiteral( 
"toChanged = %1" ).arg( toChanged ) );
 
 1813         toLineEdit->setText( lineEdit->text() );
 
 1816     else if ( column == 1 )
 
 1818       setTransparencyToEdited( row );
 
 1823 void QgsRasterLayerProperties::aboutToShowStyleMenu()
 
 1827   QMenu *m = qobject_cast<QMenu *>( sender() );
 
 1835 void QgsRasterLayerProperties::syncToLayer()
 
 1840     setRendererWidget( renderer->
type() );
 
 1846 void QgsRasterLayerProperties::setTransparencyToEdited( 
int row )
 
 1848   if ( row >= mTransparencyToEdited.size() )
 
 1850     mTransparencyToEdited.resize( row + 1 );
 
 1852   mTransparencyToEdited[row] = 
true;
 
 1859   bool isMetadataPanel = ( index == 
mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
 
 1860   mBtnStyle->setVisible( ! isMetadataPanel );
 
 1861   mBtnMetadata->setVisible( isMetadataPanel );
 
 1863   if ( !mHistogramWidget )
 
 1875   if ( index == 
mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
 
 1878     updateInformationContent();
 
 1882 void QgsRasterLayerProperties::setEndAsStartStaticButton_clicked()
 
 1884   mEndStaticDateTimeEdit->setDateTime( mStartStaticDateTimeEdit->dateTime() );
 
 1887 void QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked()
 
 1889   int myLineCounter = 0;
 
 1890   bool myImportError = 
false;
 
 1893   QString myLastDir = myQSettings.
value( QStringLiteral( 
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
 
 1894   QString myFileName = QFileDialog::getOpenFileName( 
this, tr( 
"Open file" ), myLastDir, tr( 
"Textfile" ) + 
" (*.txt)" );
 
 1895   QFile myInputFile( myFileName );
 
 1896   if ( myInputFile.open( QFile::ReadOnly ) )
 
 1898     QTextStream myInputStream( &myInputFile );
 
 1899     QString myInputLine;
 
 1900     if ( rasterIsMultiBandColor() )
 
 1902       for ( 
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
 
 1904         tableTransparency->removeRow( myTableRunner );
 
 1907       while ( !myInputStream.atEnd() )
 
 1910         myInputLine = myInputStream.readLine();
 
 1911         if ( !myInputLine.isEmpty() )
 
 1913           if ( !myInputLine.simplified().startsWith( 
'#' ) )
 
 1915             QStringList myTokens = myInputLine.split( QRegExp( 
"\\s+" ), QString::SkipEmptyParts );
 
 1916             if ( myTokens.count() != 4 )
 
 1918               myImportError = 
true;
 
 1919               myBadLines = myBadLines + QString::number( myLineCounter ) + 
":\t[" + myInputLine + 
"]\n";
 
 1923               tableTransparency->insertRow( tableTransparency->rowCount() );
 
 1924               for ( 
int col = 0; col < 4; col++ )
 
 1926                 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
 
 1935       for ( 
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
 
 1937         tableTransparency->removeRow( myTableRunner );
 
 1940       while ( !myInputStream.atEnd() )
 
 1943         myInputLine = myInputStream.readLine();
 
 1944         if ( !myInputLine.isEmpty() )
 
 1946           if ( !myInputLine.simplified().startsWith( 
'#' ) )
 
 1948             QStringList myTokens = myInputLine.split( QRegExp( 
"\\s+" ), QString::SkipEmptyParts );
 
 1949             if ( myTokens.count() != 3 && myTokens.count() != 2 ) 
 
 1951               myImportError = 
true;
 
 1952               myBadLines = myBadLines + QString::number( myLineCounter ) + 
":\t[" + myInputLine + 
"]\n";
 
 1956               if ( myTokens.count() == 2 )
 
 1958                 myTokens.insert( 1, myTokens[0] ); 
 
 1960               tableTransparency->insertRow( tableTransparency->rowCount() );
 
 1961               for ( 
int col = 0; col < 3; col++ )
 
 1963                 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
 
 1971     if ( myImportError )
 
 1973       QMessageBox::warning( 
this, tr( 
"Import Transparent Pixels" ), tr( 
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
 
 1976   else if ( !myFileName.isEmpty() )
 
 1978     QMessageBox::warning( 
this, tr( 
"Import Transparent Pixels" ), tr( 
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
 
 1980   tableTransparency->resizeColumnsToContents();
 
 1981   tableTransparency->resizeRowsToContents();
 
 1984 void QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked()
 
 1986   if ( 0 < tableTransparency->rowCount() )
 
 1988     tableTransparency->removeRow( tableTransparency->currentRow() );
 
 1992 void QgsRasterLayerProperties::pixelSelected( 
const QgsPointXY &canvasPoint, 
const Qt::MouseButton &btn )
 
 2002   if ( mMapCanvas && mPixelSelectorTool )
 
 2011     int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
 
 2012     int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
 
 2016     QList<int> bands = renderer->
usesBands();
 
 2018     QList<double> values;
 
 2019     for ( 
int i = 0; i < bands.size(); ++i )
 
 2021       int bandNo = bands.value( i );
 
 2022       if ( myPixelMap.count( bandNo ) == 1 )
 
 2024         if ( myPixelMap.value( bandNo ).isNull() )
 
 2028         double value = myPixelMap.value( bandNo ).toDouble();
 
 2029         QgsDebugMsg( QStringLiteral( 
"value = %1" ).arg( value, 0, 
'g', 17 ) );
 
 2030         values.append( value );
 
 2033     if ( bands.size() == 1 )
 
 2036       values.insert( 1, values.value( 0 ) );
 
 2038     tableTransparency->insertRow( tableTransparency->rowCount() );
 
 2039     for ( 
int i = 0; i < values.size(); i++ )
 
 2041       setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
 
 2043     setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
 
 2047   tableTransparency->resizeColumnsToContents();
 
 2048   tableTransparency->resizeRowsToContents();
 
 2051 void QgsRasterLayerProperties::toggleSaturationControls( 
int grayscaleMode )
 
 2054   if ( grayscaleMode == 0 )
 
 2056     sliderSaturation->setEnabled( 
true );
 
 2057     spinBoxSaturation->setEnabled( 
true );
 
 2061     sliderSaturation->setEnabled( 
false );
 
 2062     spinBoxSaturation->setEnabled( 
false );
 
 2066 void QgsRasterLayerProperties::toggleColorizeControls( 
bool colorizeEnabled )
 
 2069   btnColorizeColor->setEnabled( colorizeEnabled );
 
 2070   sliderColorizeStrength->setEnabled( colorizeEnabled );
 
 2071   spinColorizeStrength->setEnabled( colorizeEnabled );
 
 2075 QLinearGradient QgsRasterLayerProperties::redGradient()
 
 2079   QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
 
 2080   myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
 
 2081   myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
 
 2082   myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
 
 2085 QLinearGradient QgsRasterLayerProperties::greenGradient()
 
 2089   QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
 
 2090   myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
 
 2091   myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
 
 2092   myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
 
 2095 QLinearGradient QgsRasterLayerProperties::blueGradient()
 
 2099   QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
 
 2100   myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
 
 2101   myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
 
 2102   myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
 
 2105 QLinearGradient QgsRasterLayerProperties::grayGradient()
 
 2109   QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
 
 2110   myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
 
 2111   myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
 
 2112   myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
 
 2115 QLinearGradient QgsRasterLayerProperties::highlightGradient()
 
 2119   QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
 
 2120   myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
 
 2121   myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
 
 2122   myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
 
 2133 void QgsRasterLayerProperties::loadDefaultStyle_clicked()
 
 2135   bool defaultLoadedFlag = 
false;
 
 2138   if ( defaultLoadedFlag )
 
 2145     QMessageBox::information( 
this,
 
 2146                               tr( 
"Default Style" ),
 
 2152 void QgsRasterLayerProperties::saveDefaultStyle_clicked()
 
 2158   bool defaultSavedFlag = 
false;
 
 2162   if ( !defaultSavedFlag )
 
 2165     QMessageBox::information( 
this,
 
 2166                               tr( 
"Default Style" ),
 
 2173 void QgsRasterLayerProperties::loadStyle_clicked()
 
 2176   QString lastUsedDir = settings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 2178   QString fileName = QFileDialog::getOpenFileName(
 
 2180                        tr( 
"Load layer properties from style file" ),
 
 2182                        tr( 
"QGIS Layer Style File" ) + 
" (*.qml)" );
 
 2183   if ( fileName.isEmpty() )
 
 2187   if ( !fileName.endsWith( QLatin1String( 
".qml" ), Qt::CaseInsensitive ) )
 
 2188     fileName += QLatin1String( 
".qml" );
 
 2192   bool defaultLoadedFlag = 
false;
 
 2193   QString message = mRasterLayer->
loadNamedStyle( fileName, defaultLoadedFlag );
 
 2194   if ( defaultLoadedFlag )
 
 2196     settings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
 
 2201     QMessageBox::information( 
this, tr( 
"Save Style" ), message );
 
 2206 void QgsRasterLayerProperties::saveStyleAs_clicked()
 
 2209   QString lastUsedDir = settings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 2211   QString selectedFilter;
 
 2212   QString outputFileName = QFileDialog::getSaveFileName(
 
 2214                              tr( 
"Save layer properties as style file" ),
 
 2216                              tr( 
"QGIS Layer Style File" ) + 
" (*.qml)" + 
";;" + tr( 
"Styled Layer Descriptor" ) + 
" (*.sld)",
 
 2218   if ( outputFileName.isEmpty() )
 
 2223   if ( selectedFilter.contains( QStringLiteral( 
".qml" ), Qt::CaseInsensitive ) )
 
 2226     type = StyleType::QML;
 
 2231     type = StyleType::SLD;
 
 2237   bool defaultLoadedFlag = 
false;
 
 2243       message = mRasterLayer->
saveNamedStyle( outputFileName, defaultLoadedFlag );
 
 2248       message = mRasterLayer->
saveSldStyle( outputFileName, defaultLoadedFlag );
 
 2252   if ( defaultLoadedFlag )
 
 2254     settings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
 
 2258     QMessageBox::information( 
this, tr( 
"Save Style" ), message );
 
 2261 void QgsRasterLayerProperties::restoreWindowModality()
 
 2276 void QgsRasterLayerProperties::loadMetadata()
 
 2279   QString myLastUsedDir = myQSettings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 2281   QString myFileName = QFileDialog::getOpenFileName( 
this, tr( 
"Load layer metadata from metadata file" ), myLastUsedDir,
 
 2282                        tr( 
"QGIS Layer Metadata File" ) + 
" (*.qmd)" );
 
 2283   if ( myFileName.isNull() )
 
 2289   bool defaultLoadedFlag = 
false;
 
 2293   if ( defaultLoadedFlag )
 
 2300     QMessageBox::warning( 
this, tr( 
"Load Metadata" ), myMessage );
 
 2303   QFileInfo myFI( myFileName );
 
 2304   QString myPath = myFI.path();
 
 2305   myQSettings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), myPath );
 
 2310 void QgsRasterLayerProperties::saveMetadataAs()
 
 2313   QString myLastUsedDir = myQSettings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 2315   QString myOutputFileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save Layer Metadata as QMD" ),
 
 2316                              myLastUsedDir, tr( 
"QMD File" ) + 
" (*.qmd)" );
 
 2317   if ( myOutputFileName.isNull() ) 
 
 2330   bool defaultLoadedFlag = 
false;
 
 2331   QString message = mRasterLayer->
saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
 
 2332   if ( defaultLoadedFlag )
 
 2333     myQSettings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
 
 2335     QMessageBox::information( 
this, tr( 
"Save Metadata" ), message );
 
 2338 void QgsRasterLayerProperties::saveDefaultMetadata()
 
 2342   bool defaultSavedFlag = 
false;
 
 2344   if ( !defaultSavedFlag )
 
 2346     QMessageBox::warning( 
this, tr( 
"Default Metadata" ), errorMsg );
 
 2350 void QgsRasterLayerProperties::loadDefaultMetadata()
 
 2352   bool defaultLoadedFlag = 
false;
 
 2355   if ( defaultLoadedFlag )
 
 2361     QMessageBox::information( 
this, tr( 
"Default Metadata" ), myMessage );
 
 2366 void QgsRasterLayerProperties::toggleBuildPyramidsButton()
 
 2368   if ( lbxPyramidResolutions->selectedItems().empty() )
 
 2370     buttonBuildPyramids->setEnabled( 
false );
 
 2374     buttonBuildPyramids->setEnabled( 
true );
 
 2378 void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
 
 2380   mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
 
 2381   mSliderBrightness->setValue( 0 );
 
 2382   mSliderContrast->setValue( 0 );
 
 2383   sliderSaturation->setValue( 0 );
 
 2385   mColorizeCheck->setChecked( 
false );
 
 2386   sliderColorizeStrength->setValue( 100 );
 
 2389 bool QgsRasterLayerProperties::rasterIsMultiBandColor()
 
 2394 void QgsRasterLayerProperties::updateInformationContent()
 
 2398   const QString html { mRasterLayer->
htmlMetadata().replace( QStringLiteral( 
"<head>" ), QStringLiteral( R
"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) }; 
 2399   mMetadataViewer->setHtml( html ); 
 2400   mMetadataFilled = true;
 
 2403 void QgsRasterLayerProperties::onCancel()
 
 2409     QDomDocument doc( QStringLiteral( 
"qgis" ) );
 
 2410     int errorLine, errorColumn;
 
 2411     doc.setContent( mOldStyle.
xmlData(), 
false, &myMessage, &errorLine, &errorColumn );
 
 2417 void QgsRasterLayerProperties::showHelp()
 
 2419   const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( 
"helpPage" );
 
 2421   if ( helpPage.isValid() )
 
 2427     QgsHelp::openHelp( QStringLiteral( 
"working_with_raster/raster_properties.html" ) );