35 #include "qgsnative.h"
68 #include <QDesktopServices>
69 #include <QTableWidgetItem>
70 #include <QHeaderView>
71 #include <QTextStream>
73 #include <QFileDialog>
74 #include <QMessageBox>
76 #include <QLinearGradient>
77 #include <QPainterPath>
79 #include <QColorDialog>
81 #include <QMouseEvent>
90 , TRSTRING_NOT_SET( tr(
"Not Set" ) )
91 , mDefaultStandardDeviation( 0 )
92 , mDefaultRedBand( 0 )
93 , mDefaultGreenBand( 0 )
94 , mDefaultBlueBand( 0 )
96 , mGradientHeight( 0.0 )
97 , mGradientWidth( 0.0 )
98 , mMapCanvas( canvas )
99 , mMetadataFilled( false )
101 mGrayMinimumMaximumEstimated =
true;
102 mRGBMinimumMaximumEstimated =
true;
105 connect( mLayerOrigNameLineEd, &QLineEdit::textEdited,
this, &QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited );
106 connect( buttonBuildPyramids, &QPushButton::clicked,
this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
107 connect( pbnAddValuesFromDisplay, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked );
108 connect( pbnAddValuesManually, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnAddValuesManually_clicked );
110 connect( pbnDefaultValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnDefaultValues_clicked );
111 connect( pbnExportTransparentPixelValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked );
112 connect( pbnImportTransparentPixelValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked );
113 connect( pbnRemoveSelectedRow, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked );
114 connect( mRenderTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
115 connect( mResetColorRenderingBtn, &QToolButton::clicked,
this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
120 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsRasterLayerProperties::showHelp );
122 connect( mSetEndAsStartStaticButton, &QPushButton::clicked,
this, &QgsRasterLayerProperties::setEndAsStartStaticButton_clicked );
123 connect( mProjectTemporalRange, &QRadioButton::toggled,
this, &QgsRasterLayerProperties::passProjectTemporalRange_toggled );
124 connect( mStaticTemporalRange, &QRadioButton::toggled,
this, &QgsRasterLayerProperties::staticTemporalRange_toggled );
126 connect( mStaticTemporalRange, &QRadioButton::toggled, mStaticWmstFrame, &QWidget::setEnabled );
127 connect( mReferenceTime, &QCheckBox::toggled, mWmstReferenceTimeFrame, &QWidget::setEnabled );
132 mBtnStyle =
new QPushButton( tr(
"Style" ) );
133 QMenu *menuStyle =
new QMenu(
this );
134 menuStyle->addAction( tr(
"Load Style…" ),
this, &QgsRasterLayerProperties::loadStyle_clicked );
135 menuStyle->addAction( tr(
"Save Style…" ),
this, &QgsRasterLayerProperties::saveStyleAs_clicked );
136 menuStyle->addSeparator();
137 menuStyle->addAction( tr(
"Save as Default" ),
this, &QgsRasterLayerProperties::saveDefaultStyle_clicked );
138 menuStyle->addAction( tr(
"Restore Default" ),
this, &QgsRasterLayerProperties::loadDefaultStyle_clicked );
139 mBtnStyle->setMenu( menuStyle );
140 connect( menuStyle, &QMenu::aboutToShow,
this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
141 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
143 mBtnMetadata =
new QPushButton( tr(
"Metadata" ),
this );
144 QMenu *menuMetadata =
new QMenu(
this );
145 mActionLoadMetadata = menuMetadata->addAction( tr(
"Load Metadata…" ),
this, &QgsRasterLayerProperties::loadMetadata );
146 mActionSaveMetadataAs = menuMetadata->addAction( tr(
"Save Metadata…" ),
this, &QgsRasterLayerProperties::saveMetadataAs );
147 menuMetadata->addSeparator();
148 menuMetadata->addAction( tr(
"Save as Default" ),
this, &QgsRasterLayerProperties::saveDefaultMetadata );
149 menuMetadata->addAction( tr(
"Restore Default" ),
this, &QgsRasterLayerProperties::loadDefaultMetadata );
150 mBtnMetadata->setMenu( menuMetadata );
151 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
155 connect(
this, &QDialog::accepted,
this, &QgsRasterLayerProperties::apply );
156 connect(
this, &QDialog::rejected,
this, &QgsRasterLayerProperties::onCancel );
158 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked,
this, &QgsRasterLayerProperties::apply );
161 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
162 connect( mBrightnessSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
163 mBrightnessSpinBox->setClearValue( 0 );
165 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
166 connect( mContrastSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
167 mContrastSpinBox->setClearValue( 0 );
170 connect( mSliderGamma, &QAbstractSlider::valueChanged,
this, &QgsRasterLayerProperties::updateGammaSpinBox );
171 connect( mGammaSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsRasterLayerProperties::updateGammaSlider );
172 mGammaSpinBox->setClearValue( 1.0 );
175 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
176 connect( spinBoxSaturation,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
177 spinBoxSaturation->setClearValue( 0 );
180 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
181 connect( spinColorizeStrength,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
182 spinColorizeStrength->setClearValue( 100 );
185 connect( comboGrayscale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerProperties::toggleSaturationControls );
188 connect( mColorizeCheck, &QAbstractButton::toggled,
this, &QgsRasterLayerProperties::toggleColorizeControls );
191 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged,
this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
193 connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
196 mScaleRangeWidget->setMapCanvas( mMapCanvas );
200 leNoDataValue->setValidator(
new QgsDoubleValidator( -std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), 1000,
this ) );
215 mPixelSelectorTool = qgis::make_unique<QgsMapToolEmitPoint>( canvas );
221 pbnAddValuesFromDisplay->setEnabled(
false );
235 cboResamplingMethod->clear();
238 for ( QPair<QString, QString> method : constProviderType )
240 cboResamplingMethod->addItem( method.second, method.first );
244 QString prefix = provider->
name() +
"/driverOptions/_pyramids/";
246 QString defaultMethod = mySettings.
value( prefix +
"resampling",
"AVERAGE" ).toString();
247 int idx = cboResamplingMethod->findData( defaultMethod );
249 cboResamplingMethod->setCurrentIndex( idx );
254 QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
256 for ( myRasterPyramidIterator = myPyramidList.begin();
257 myRasterPyramidIterator != myPyramidList.end();
258 ++myRasterPyramidIterator )
260 if ( myRasterPyramidIterator->exists )
262 lbxPyramidResolutions->addItem(
new QListWidgetItem( myPyramidPixmap,
263 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
264 QString::number( myRasterPyramidIterator->yDim ) ) );
268 lbxPyramidResolutions->addItem(
new QListWidgetItem( myNoPyramidPixmap,
269 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
270 QString::number( myRasterPyramidIterator->yDim ) ) );
277 mOptsPage_Pyramids->setEnabled(
false );
286 mOptsPage_Histogram->setEnabled(
false );
289 QVBoxLayout *layout =
new QVBoxLayout( metadataFrame );
290 layout->setContentsMargins( 0, 0, 0, 0 );
292 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
294 layout->addWidget( mMetadataWidget );
295 metadataFrame->setLayout( layout );
297 QVBoxLayout *temporalLayout =
new QVBoxLayout( temporalFrame );
298 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
300 temporalLayout->addWidget( mTemporalWidget );
302 setSourceStaticTimeState();
308 mPostgresRasterTemporalGroup->setEnabled(
true );
309 mPostgresRasterTemporalGroup->setVisible(
true );
310 mPostgresRasterTemporalGroup->setChecked(
false );
312 mPostgresRasterTemporalFieldComboBox->setFields( fields );
313 mPostgresRasterTemporalFieldComboBox->setFilters( QgsFieldProxyModel::Filter::Date |
314 QgsFieldProxyModel::Filter::DateTime |
315 QgsFieldProxyModel::Filter::String );
316 mPostgresRasterTemporalFieldComboBox->setAllowEmptyFieldName(
true );
319 mPostgresRasterDefaultTime->setEnabled( ! fieldName.isEmpty() );
321 mPostgresRasterDefaultTime->setAllowNull(
true );
322 mPostgresRasterDefaultTime->setEmpty();
326 const int fieldIdx { mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral(
"temporalFieldIndex" ) ).toInt( &ok ) };
327 if ( ok && fields.exists( fieldIdx ) )
329 mPostgresRasterTemporalGroup->setChecked(
true );
330 mPostgresRasterTemporalFieldComboBox->setField( fields.field( fieldIdx ).name() );
333 const QDateTime defaultDateTime { QDateTime::fromString( mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral(
"temporalDefaultTime" ) ), Qt::DateFormat::ISODate ) };
334 if ( defaultDateTime.isValid() )
336 mPostgresRasterDefaultTime->setDateTime( defaultDateTime );
344 mPostgresRasterTemporalGroup->setEnabled(
false );
345 mPostgresRasterTemporalGroup->setVisible(
false );
350 mCrsSelector->setCrs( mRasterLayer->
crs() );
353 QString pyramidFormat( QStringLiteral(
"<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
354 QString pyramidHeader = tr(
"Description" );
355 QString pyramidSentence1 = tr(
"Large resolution raster layers can slow navigation in QGIS." );
356 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." );
357 QString pyramidSentence3 = tr(
"You must have write access in the directory where the original data is stored to build pyramids." );
358 QString pyramidSentence4 = tr(
"Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
359 QString pyramidSentence5 = tr(
"Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
361 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
366 pyramidSentence5 ) );
369 mResamplingGroupBox->setSaveCheckedState(
true );
370 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
371 mResamplingUtils.refreshWidgetsFromLayer();
375 btnColorizeColor->setColorDialogTitle( tr(
"Select Color" ) );
376 btnColorizeColor->setContext( QStringLiteral(
"symbology" ) );
381 if ( hueSaturationFilter )
383 sliderSaturation->setValue( hueSaturationFilter->
saturation() );
384 comboGrayscale->setCurrentIndex( (
int ) hueSaturationFilter->
grayscaleMode() );
387 toggleSaturationControls(
static_cast<int>( hueSaturationFilter->
grayscaleMode() ) );
390 mColorizeCheck->setChecked( hueSaturationFilter->
colorizeOn() );
391 btnColorizeColor->setColor( hueSaturationFilter->
colorizeColor() );
392 toggleColorizeControls( hueSaturationFilter->
colorizeOn() );
393 sliderColorizeStrength->setValue( hueSaturationFilter->
colorizeStrength() );
397 mBlendModeComboBox->setBlendMode( mRasterLayer->
blendMode() );
402 cboxTransparencyBand->setShowNotSetOption(
true, tr(
"None" ) );
403 cboxTransparencyBand->setLayer( mRasterLayer );
412 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->
alphaBand() ) );
419 mHistogramWidget =
nullptr;
420 if ( mOptsPage_Histogram->isEnabled() )
423 mHistogramStackedWidget->addWidget( mHistogramWidget );
436 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
438 for (
const QString &name : constRenderersList )
449 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
454 QString rendererType = renderer->
type();
455 widgetIndex = mRenderTypeComboBox->findData( rendererType );
456 if ( widgetIndex != -1 )
458 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
459 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
460 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
463 if ( rendererType == QLatin1String(
"singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
466 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
467 sizep.setVerticalStretch( 0 );
468 sizep.setVerticalPolicy( QSizePolicy::Maximum );
469 mBandRenderingGrpBx->setSizePolicy( sizep );
470 mBandRenderingGrpBx->updateGeometry();
473 if ( mRasterLayer->
providerType() != QLatin1String(
"wms" ) )
475 mWMSPrintGroupBox->hide();
476 mPublishDataSourceUrlCheckBox->hide();
477 mBackgroundLayerCheckBox->hide();
484 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
485 const int horizontalDpi = qApp->desktop()->screen()->logicalDpiX();
487 const int horizontalDpi = logicalDpiX();
491 if ( horizontalDpi > 96 )
493 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
495 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
496 connect( mMetadataViewer->page(), &QWebPage::linkClicked,
this, &QgsRasterLayerProperties::urlClicked );
497 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled,
true );
498 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled,
true );
502 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
510 if ( !settings.
contains( QStringLiteral(
"/Windows/RasterLayerProperties/tab" ) ) )
512 settings.
setValue( QStringLiteral(
"Windows/RasterLayerProperties/tab" ),
518 QString title = tr(
"Layer Properties — %1" ).arg( lyr->
name() );
526 mOptsPage_Information->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#information-properties" ) );
527 mOptsPage_Source->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#source-properties" ) );
528 mOptsPage_Style->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#symbology-properties" ) );
529 mOptsPage_Transparency->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#transparency-properties" ) );
531 if ( mOptsPage_Histogram )
532 mOptsPage_Histogram->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#histogram-properties" ) );
534 mOptsPage_Rendering->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#rendering-properties" ) );
536 if ( mOptsPage_Pyramids )
537 mOptsPage_Pyramids->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#pyramids-properties" ) );
539 mOptsPage_Metadata->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#metadata-properties" ) );
540 mOptsPage_Legend->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#legend-properties" ) );
541 mOptsPage_Server->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#server-properties" ) );
544 void QgsRasterLayerProperties::setupTransparencyTable(
int nBands )
546 tableTransparency->clear();
547 tableTransparency->setColumnCount( 0 );
548 tableTransparency->setRowCount( 0 );
549 mTransparencyToEdited.clear();
553 tableTransparency->setColumnCount( 4 );
554 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Red" ) ) );
555 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"Green" ) ) );
556 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Blue" ) ) );
557 tableTransparency->setHorizontalHeaderItem( 3,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
561 tableTransparency->setColumnCount( 3 );
564 if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
565 QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
566 QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
567 QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
569 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Gray" ) ) );
573 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Indexed Value" ) ) );
576 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"From" ) ) );
577 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"To" ) ) );
578 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
581 tableTransparency->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
582 tableTransparency->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
585 void QgsRasterLayerProperties::populateTransparencyTable(
QgsRasterRenderer *renderer )
597 int nBands = renderer->
usesBands().size();
598 setupTransparencyTable( nBands );
601 if ( !rasterTransparency )
609 for (
int i = 0; i < pixelList.size(); ++i )
611 tableTransparency->insertRow( i );
612 setTransparencyCell( i, 0, pixelList[i].min );
613 setTransparencyCell( i, 1, pixelList[i].max );
614 setTransparencyCell( i, 2, pixelList[i].percentTransparent );
616 if ( pixelList[i].min != pixelList[i].max )
618 setTransparencyToEdited( i );
622 else if ( nBands == 3 )
625 for (
int i = 0; i < pixelList.size(); ++i )
627 tableTransparency->insertRow( i );
628 setTransparencyCell( i, 0, pixelList[i].red );
629 setTransparencyCell( i, 1, pixelList[i].green );
630 setTransparencyCell( i, 2, pixelList[i].blue );
631 setTransparencyCell( i, 3, pixelList[i].percentTransparent );
635 tableTransparency->resizeColumnsToContents();
636 tableTransparency->resizeRowsToContents();
639 void QgsRasterLayerProperties::setRendererWidget(
const QString &rendererName )
652 opacity = oldRenderer->
opacity();
661 QgsDebugMsg( QStringLiteral(
"renderer has widgetCreateFunction" ) );
664 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->
type() ) )
666 if ( rendererName == QLatin1String(
"singlebandgray" ) )
669 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
671 else if ( rendererName == QLatin1String(
"multibandcolor" ) )
674 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
682 mRendererStackedWidget->addWidget( mRendererWidget );
688 QList<int> oldBands = oldRenderer->
usesBands();
689 QList<int> newBands = newRenderer->
usesBands();
690 if ( oldBands != newBands )
692 populateTransparencyTable( newRenderer );
700 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
701 if ( widgetIndex != -1 )
703 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
704 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
705 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
708 if ( mRendererWidget != oldWidget )
711 if ( mHistogramWidget )
726 void QgsRasterLayerProperties::sync()
737 gboxNoDataValue->setEnabled(
false );
738 gboxCustomTransparency->setEnabled(
false );
739 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
745 if ( mOptsPage_Pyramids )
747 delete mOptsPage_Pyramids;
748 mOptsPage_Pyramids =
nullptr;
754 if ( mOptsPage_Histogram )
756 delete mOptsPage_Histogram;
757 mOptsPage_Histogram =
nullptr;
758 delete mHistogramWidget;
759 mHistogramWidget =
nullptr;
763 QgsDebugMsg( QStringLiteral(
"populate transparency tab" ) );
771 if ( brightnessFilter )
773 mSliderBrightness->setValue( brightnessFilter->
brightness() );
774 mSliderContrast->setValue( brightnessFilter->
contrast() );
775 mGammaSpinBox->setValue( brightnessFilter->
gamma() );
781 if ( hueSaturationFilter )
783 sliderSaturation->setValue( hueSaturationFilter->
saturation() );
784 comboGrayscale->setCurrentIndex( (
int ) hueSaturationFilter->
grayscaleMode() );
787 toggleSaturationControls(
static_cast<int>( hueSaturationFilter->
grayscaleMode() ) );
790 mColorizeCheck->setChecked( hueSaturationFilter->
colorizeOn() );
791 btnColorizeColor->setColor( hueSaturationFilter->
colorizeColor() );
792 toggleColorizeControls( hueSaturationFilter->
colorizeOn() );
793 sliderColorizeStrength->setValue( hueSaturationFilter->
colorizeStrength() );
805 cboxTransparencyBand->setBand( renderer->
alphaBand() );
814 lblSrcNoDataValue->setText( QLocale().toString( v,
'g' ) );
818 lblSrcNoDataValue->setText( tr(
"not defined" ) );
825 mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
826 lblSrcNoDataValue->setEnabled( enableSrcNoData );
829 QgsDebugMsg( QStringLiteral(
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
830 if ( !noDataRangeList.isEmpty() )
836 leNoDataValue->insert( QString() );
843 populateTransparencyTable( mRasterLayer->
renderer() );
845 QgsDebugMsg( QStringLiteral(
"populate colormap tab" ) );
850 QgsDebugMsg( QStringLiteral(
"populate general tab" ) );
856 mLayerOrigNameLineEd->setText( mRasterLayer->
name() );
857 leDisplayName->setText( mRasterLayer->
name() );
860 QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
861 pixmapThumbnail->setPixmap( thumbnail );
867 pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
868 pixmapLegend->setScaledContents(
true );
869 pixmapLegend->repaint();
872 pixmapPalette->setPixmap( mRasterLayer->
paletteAsPixmap( mRasterLayer->bandNumber( mRasterLayer->grayBandName() ) ) );
873 pixmapPalette->setScaledContents(
true );
874 pixmapPalette->repaint();
882 updateInformationContent();
885 mLayerShortNameLineEdit->setText( mRasterLayer->
shortName() );
888 mLayerShortNameLineEdit->setValidator( shortNameValidator );
891 mLayerTitleLineEdit->setText( mRasterLayer->
title() );
892 mLayerAbstractTextEdit->setPlainText( mRasterLayer->
abstract() );
893 mLayerKeywordListLineEdit->setText( mRasterLayer->
keywordList() );
894 mLayerDataUrlLineEdit->setText( mRasterLayer->
dataUrl() );
895 mLayerDataUrlFormatComboBox->setCurrentIndex(
896 mLayerDataUrlFormatComboBox->findText(
902 mLayerAttributionLineEdit->setText( mRasterLayer->
attribution() );
903 mLayerAttributionUrlLineEdit->setText( mRasterLayer->
attributionUrl() );
904 mLayerMetadataUrlLineEdit->setText( mRasterLayer->
metadataUrl() );
905 mLayerMetadataUrlTypeComboBox->setCurrentIndex(
906 mLayerMetadataUrlTypeComboBox->findText(
910 mLayerMetadataUrlFormatComboBox->setCurrentIndex(
911 mLayerMetadataUrlFormatComboBox->findText(
916 mLayerLegendUrlLineEdit->setText( mRasterLayer->
legendUrl() );
917 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->
legendUrlFormat() ) );
920 QVariant wmsPrintLayer = mRasterLayer->
customProperty( QStringLiteral(
"WMSPrintLayer" ) );
921 if ( wmsPrintLayer.isValid() )
923 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
926 QVariant wmsPublishDataSourceUrl = mRasterLayer->
customProperty( QStringLiteral(
"WMSPublishDataSourceUrl" ),
false );
927 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
929 QVariant wmsBackgroundLayer = mRasterLayer->
customProperty( QStringLiteral(
"WMSBackgroundLayer" ),
false );
930 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
932 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
937 void QgsRasterLayerProperties::apply()
941 if ( !mRasterLayer->
isValid() )
947 mLegendConfigEmbeddedWidget->applyToLayer();
949 QgsDebugMsg( QStringLiteral(
"apply processing symbology tab" ) );
961 QgsDebugMsg( QStringLiteral(
"processing transparency tab" ) );
968 if (
"" != leNoDataValue->text() )
970 bool myDoubleOk =
false;
975 myNoDataRangeList << myNoDataRange;
978 for (
int bandNo = 1; bandNo <= mRasterLayer->
dataProvider()->bandCount(); bandNo++ )
986 if ( rendererWidget )
994 mMetadataFilled =
false;
998 if ( rasterRenderer )
1000 rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
1004 if ( tableTransparency->columnCount() == 4 )
1007 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
1008 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
1010 myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
1011 myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
1012 myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
1014 myTransparentThreeValuePixelList.append( myTransparentPixel );
1018 else if ( tableTransparency->columnCount() == 3 )
1021 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
1022 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
1024 myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
1025 myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
1028 myTransparentSingleValuePixelList.append( myTransparentPixel );
1036 rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
1039 QgsDebugMsg( QStringLiteral(
"processing general tab" ) );
1043 mRasterLayer->
setName( mLayerOrigNameLineEd->text() );
1058 mResamplingUtils.refreshLayerFromWidgets();
1062 if ( hueSaturationFilter )
1064 hueSaturationFilter->
setSaturation( sliderSaturation->value() );
1066 hueSaturationFilter->
setColorizeOn( mColorizeCheck->checkState() );
1072 mRasterLayer->
setBlendMode( mBlendModeComboBox->blendMode() );
1074 updateSourceStaticTime();
1080 if ( mPostgresRasterTemporalGroup->isEnabled() &&
1081 mPostgresRasterTemporalGroup->isChecked() &&
1082 ! mPostgresRasterTemporalFieldComboBox->currentField().isEmpty() )
1084 const QString originaUri { uri.
uri() };
1086 uri.removeParam( QStringLiteral(
"temporalFieldIndex" ) );
1087 uri.removeParam( QStringLiteral(
"temporalDefaultTime" ) );
1088 if ( fieldIdx >= 0 )
1090 uri.setParam( QStringLiteral(
"temporalFieldIndex" ), QString::number( fieldIdx ) );
1091 if ( mPostgresRasterDefaultTime->dateTime().isValid() )
1093 QDateTime defaultDateTime { mPostgresRasterDefaultTime->dateTime() };
1094 const QTime defaultTime { defaultDateTime.time() };
1096 defaultDateTime.setTime( { defaultTime.hour(), defaultTime.minute(), 0 } );
1097 uri.setParam( QStringLiteral(
"temporalDefaultTime" ), defaultDateTime.toString( Qt::DateFormat::ISODate ) );
1099 if ( uri.uri( ) != originaUri )
1103 else if ( uri.hasParam( QStringLiteral(
"temporalFieldIndex" ) ) )
1105 uri.removeParam( QStringLiteral(
"temporalFieldIndex" ) );
1106 uri.removeParam( QStringLiteral(
"temporalDefaultTime" ) );
1114 mRasterLayer->
setCrs( mCrsSelector->crs() );
1117 QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
1118 pixmapThumbnail->setPixmap( thumbnail );
1120 if ( mRasterLayer->
shortName() != mLayerShortNameLineEdit->text() )
1121 mMetadataFilled =
false;
1122 mRasterLayer->
setShortName( mLayerShortNameLineEdit->text() );
1124 if ( mRasterLayer->
title() != mLayerTitleLineEdit->text() )
1125 mMetadataFilled =
false;
1126 mRasterLayer->
setTitle( mLayerTitleLineEdit->text() );
1128 if ( mRasterLayer->
abstract() != mLayerAbstractTextEdit->toPlainText() )
1129 mMetadataFilled =
false;
1130 mRasterLayer->
setAbstract( mLayerAbstractTextEdit->toPlainText() );
1132 if ( mRasterLayer->
keywordList() != mLayerKeywordListLineEdit->text() )
1133 mMetadataFilled =
false;
1134 mRasterLayer->
setKeywordList( mLayerKeywordListLineEdit->text() );
1136 if ( mRasterLayer->
dataUrl() != mLayerDataUrlLineEdit->text() )
1137 mMetadataFilled =
false;
1138 mRasterLayer->
setDataUrl( mLayerDataUrlLineEdit->text() );
1140 if ( mRasterLayer->
dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1141 mMetadataFilled =
false;
1142 mRasterLayer->
setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1145 if ( mRasterLayer->
attribution() != mLayerAttributionLineEdit->text() )
1146 mMetadataFilled =
false;
1147 mRasterLayer->
setAttribution( mLayerAttributionLineEdit->text() );
1149 if ( mRasterLayer->
attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1150 mMetadataFilled =
false;
1153 if ( mRasterLayer->
metadataUrl() != mLayerMetadataUrlLineEdit->text() )
1154 mMetadataFilled =
false;
1155 mRasterLayer->
setMetadataUrl( mLayerMetadataUrlLineEdit->text() );
1157 if ( mRasterLayer->
metadataUrlType() != mLayerMetadataUrlTypeComboBox->currentText() )
1158 mMetadataFilled =
false;
1161 if ( mRasterLayer->
metadataUrlFormat() != mLayerMetadataUrlFormatComboBox->currentText() )
1162 mMetadataFilled =
false;
1165 if ( mRasterLayer->
legendUrl() != mLayerLegendUrlLineEdit->text() )
1166 mMetadataFilled =
false;
1167 mRasterLayer->
setLegendUrl( mLayerLegendUrlLineEdit->text() );
1169 if ( mRasterLayer->
legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1170 mMetadataFilled =
false;
1173 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1175 mRasterLayer->
setCustomProperty( QStringLiteral(
"WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1178 mRasterLayer->
setCustomProperty(
"WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1179 mRasterLayer->
setCustomProperty(
"WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1191 void QgsRasterLayerProperties::updateSourceStaticTime()
1197 QVariantMap uri = currentUri;
1199 if ( mWmstGroup->isVisibleTo(
this ) )
1200 uri[ QStringLiteral(
"allowTemporalUpdates" ) ] = mWmstGroup->isChecked();
1203 if ( mWmstGroup->isEnabled() &&
1207 bool enableTime = !mDisableTime->isChecked();
1209 uri[ QStringLiteral(
"enableTime" ) ] = enableTime;
1211 mFetchModeComboBox->currentData().toInt() ) );
1216 if ( mStaticTemporalRange->isChecked() )
1218 QString time = mStartStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs ) +
'/' +
1219 mEndStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
1220 uri[ QStringLiteral(
"time" ) ] = time;
1221 uri[ QStringLiteral(
"temporalSource" ) ] = QLatin1String(
"provider" );
1224 if ( mProjectTemporalRange->isChecked() )
1226 QgsDateTimeRange range;
1230 if ( range.begin().isValid() && range.end().isValid() )
1232 QString time = range.begin().toString( Qt::ISODateWithMs ) +
'/' +
1233 range.end().toString( Qt::ISODateWithMs );
1235 uri[ QStringLiteral(
"time" ) ] = time;
1236 uri[ QStringLiteral(
"temporalSource" ) ] = QLatin1String(
"project" );
1241 if ( mReferenceTime->isChecked() )
1243 QString referenceTime = mReferenceDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
1244 uri[ QStringLiteral(
"referenceTime" ) ] = referenceTime;
1248 if ( uri.contains( QStringLiteral(
"referenceTime" ) ) )
1249 uri.remove( QStringLiteral(
"referenceTime" ) );
1253 if ( currentUri != uri )
1257 void QgsRasterLayerProperties::setSourceStaticTimeState()
1269 mStartStaticDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1270 mEndStaticDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1271 mReferenceDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1274 if ( availableProviderRange.begin().isValid() && availableProviderRange.end().isValid() )
1276 mStartStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
1277 availableProviderRange.end() );
1278 mStartStaticDateTimeEdit->setDateTime( availableProviderRange.begin() );
1279 mEndStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
1280 availableProviderRange.end() );
1281 mEndStaticDateTimeEdit->setDateTime( availableProviderRange.end() );
1283 if ( availableReferenceRange.begin().isValid() && availableReferenceRange.end().isValid() )
1285 mReferenceDateTimeEdit->setDateTimeRange( availableReferenceRange.begin(),
1286 availableReferenceRange.end() );
1287 mReferenceDateTimeEdit->setDateTime( availableReferenceRange.begin() );
1290 const QString time = uri.value( QStringLiteral(
"time" ) ).toString();
1291 if ( !time.isEmpty() )
1293 QStringList parts = time.split(
'/' );
1294 mStartStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 0 ), Qt::ISODateWithMs ) );
1295 mEndStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 1 ), Qt::ISODateWithMs ) );
1298 const QString referenceTimeExtent = uri.value( QStringLiteral(
"referenceTimeDimensionExtent" ) ).toString();
1300 mReferenceTime->setEnabled( !referenceTimeExtent.isEmpty() );
1301 mReferenceDateTimeEdit->setVisible( !referenceTimeExtent.isEmpty() );
1303 QString referenceTimeLabelText = referenceTimeExtent.isEmpty() ?
1304 tr(
"There is no reference time in the layer's capabilities." ) : QString();
1305 mReferenceTimeLabel->setText( referenceTimeLabelText );
1307 const QString referenceTime = uri.value( QStringLiteral(
"referenceTime" ) ).toString();
1309 mReferenceTime->setChecked( !referenceTime.isEmpty() );
1311 if ( !referenceTime.isEmpty() && !referenceTimeExtent.isEmpty() )
1313 mReferenceDateTimeEdit->setDateTime( QDateTime::fromString( referenceTime, Qt::ISODateWithMs ) );
1321 mFetchModeComboBox->setCurrentIndex( mFetchModeComboBox->findData( qobject_cast< QgsRasterLayerTemporalProperties * >( mRasterLayer->
temporalProperties() )->intervalHandlingMethod() ) );
1323 const QString temporalSource = uri.value( QStringLiteral(
"temporalSource" ) ).toString();
1324 bool enableTime = uri.value( QStringLiteral(
"enableTime" ),
true ).toBool();
1326 if ( temporalSource == QLatin1String(
"provider" ) )
1327 mStaticTemporalRange->setChecked( !time.isEmpty() );
1328 else if ( temporalSource == QLatin1String(
"project" ) )
1329 mProjectTemporalRange->setChecked( !time.isEmpty() );
1331 mDisableTime->setChecked( !enableTime );
1336 mWmstOptionsLabel->setText( tr(
"The static temporal options below are disabled because the layer "
1337 "temporal properties are active, to enable them disable temporal properties "
1338 "in the temporal tab. " ) );
1339 QgsDateTimeRange range;
1343 if ( !range.begin().isValid() || !range.end().isValid() )
1345 mProjectTemporalRange->setEnabled(
false );
1346 mProjectTemporalRangeLabel->setText( tr(
"The option below is disabled because the project temporal range "
1347 "is not valid, update the project temporal range in the project properties "
1348 "with valid values in order to use it here." ) );
1351 mWmstGroup->setChecked( uri.contains( QStringLiteral(
"allowTemporalUpdates" ) ) &&
1352 uri.value( QStringLiteral(
"allowTemporalUpdates" ),
true ).toBool() );
1356 void QgsRasterLayerProperties::staticTemporalRange_toggled(
bool checked )
1364 void QgsRasterLayerProperties::passProjectTemporalRange_toggled(
bool checked )
1368 QgsDateTimeRange range;
1372 if ( range.begin().isValid() && range.end().isValid() )
1373 mLabel->setText( tr(
"Project temporal range is set from %1 to %2" ).arg(
1374 range.begin().toString(
"yyyy-MM-dd HH:mm:ss" ),
1375 range.end().toString(
"yyyy-MM-dd HH:mm:ss" )
1378 mLabel->setText( tr(
"Project temporal range is not valid, can't use it here" ) );
1382 void QgsRasterLayerProperties::temporalPropertiesChange()
1387 mWmstOptionsLabel->setText( tr(
"The static temporal options below are disabled because the layer "
1388 "temporal properties are active, to enable them disable temporal properties "
1389 "in the temporal tab. " ) );
1391 mWmstOptionsLabel->clear();
1394 void QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited(
const QString &text )
1399 void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1411 for (
int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1413 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1415 myPyramidList[myCounterInt].build = myItem->isSelected() || myPyramidList[myCounterInt].exists;
1419 QString prefix = provider->
name() +
"/driverOptions/_pyramids/";
1421 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1422 mySettings.
setValue( prefix +
"resampling", resamplingMethod );
1429 QApplication::setOverrideCursor( Qt::WaitCursor );
1436 QApplication::restoreOverrideCursor();
1437 mPyramidProgress->setValue( 0 );
1438 buttonBuildPyramids->setEnabled(
false );
1439 if ( !res.isNull() )
1441 if ( res == QLatin1String(
"CANCELED" ) )
1445 else if ( res == QLatin1String(
"ERROR_WRITE_ACCESS" ) )
1447 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1448 tr(
"Write access denied. Adjust the file permissions and try again." ) );
1450 else if ( res == QLatin1String(
"ERROR_WRITE_FORMAT" ) )
1452 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1453 tr(
"The file was not writable. Some formats do not "
1454 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1456 else if ( res == QLatin1String(
"FAILED_NOT_SUPPORTED" ) )
1458 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1459 tr(
"Building pyramid overviews is not supported on this type of raster." ) );
1461 else if ( res == QLatin1String(
"ERROR_JPEG_COMPRESSION" ) )
1463 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1464 tr(
"Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1466 else if ( res == QLatin1String(
"ERROR_VIRTUAL" ) )
1468 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1469 tr(
"Building pyramid overviews is not supported on this type of raster." ) );
1477 lbxPyramidResolutions->clear();
1483 QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
1484 for ( myRasterPyramidIterator = myPyramidList.begin();
1485 myRasterPyramidIterator != myPyramidList.end();
1486 ++myRasterPyramidIterator )
1488 if ( myRasterPyramidIterator->exists )
1490 lbxPyramidResolutions->addItem(
new QListWidgetItem( myPyramidPixmap,
1491 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
1492 QString::number( myRasterPyramidIterator->yDim ) ) );
1496 lbxPyramidResolutions->addItem(
new QListWidgetItem( myNoPyramidPixmap,
1497 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
1498 QString::number( myRasterPyramidIterator->yDim ) ) );
1507 updateInformationContent();
1510 void QgsRasterLayerProperties::urlClicked(
const QUrl &url )
1512 QFileInfo file( url.toLocalFile() );
1513 if ( file.exists() && !file.isDir() )
1516 QDesktopServices::openUrl( url );
1519 void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged(
int index )
1521 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1526 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1527 setRendererWidget( rendererName );
1530 void QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked()
1532 if ( mMapCanvas && mPixelSelectorTool )
1541 mMapCanvas->window()->raise();
1542 mMapCanvas->window()->activateWindow();
1543 mMapCanvas->window()->setFocus();
1544 mMapCanvas->
setMapTool( mPixelSelectorTool.get() );
1549 void QgsRasterLayerProperties::pbnAddValuesManually_clicked()
1557 tableTransparency->insertRow( tableTransparency->rowCount() );
1562 for (
int i = 0; i < n; i++ )
1564 setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
1567 setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
1569 tableTransparency->resizeColumnsToContents();
1570 tableTransparency->resizeRowsToContents();
1580 void QgsRasterLayerProperties::pbnDefaultValues_clicked()
1582 if ( !mRendererWidget )
1596 setupTransparencyTable( nBands );
1598 tableTransparency->resizeColumnsToContents();
1599 tableTransparency->resizeRowsToContents();
1602 void QgsRasterLayerProperties::setTransparencyCell(
int row,
int column,
double value )
1604 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
1606 if ( !provider )
return;
1609 if ( !renderer )
return;
1610 int nBands = renderer->
usesBands().size();
1612 QLineEdit *lineEdit =
new QLineEdit();
1613 lineEdit->setFrame(
false );
1615 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1617 if ( column == tableTransparency->columnCount() - 1 )
1621 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
1622 lineEdit->setText( QString::number(
static_cast<int>( value ) ) );
1627 QString valueString;
1633 if ( !std::isnan( value ) )
1636 valueString = QLocale().toString( v,
'g' ) ;
1640 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
1641 if ( !std::isnan( value ) )
1643 valueString = QLocale().toString(
static_cast<int>( value ) );
1647 lineEdit->setText( valueString );
1649 tableTransparency->setCellWidget( row, column, lineEdit );
1650 adjustTransparencyCellWidth( row, column );
1652 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1654 connect( lineEdit, &QLineEdit::textEdited,
this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1656 tableTransparency->resizeColumnsToContents();
1659 void QgsRasterLayerProperties::setTransparencyCellValue(
int row,
int column,
double value )
1661 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1662 if ( !lineEdit )
return;
1664 lineEdit->setText( QLocale().toString( v,
'g' ) );
1665 lineEdit->adjustSize();
1666 adjustTransparencyCellWidth( row, column );
1667 tableTransparency->resizeColumnsToContents();
1670 double QgsRasterLayerProperties::transparencyCellValue(
int row,
int column )
1672 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1673 if ( !lineEdit || lineEdit->text().isEmpty() )
1675 return std::numeric_limits<double>::quiet_NaN();
1677 return lineEdit->text().toDouble();
1680 void QgsRasterLayerProperties::adjustTransparencyCellWidth(
int row,
int column )
1682 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1683 if ( !lineEdit )
return;
1685 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1686 width = std::max( width, tableTransparency->columnWidth( column ) );
1688 lineEdit->setFixedWidth( width );
1691 void QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked()
1694 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
1695 QString myFileName = QFileDialog::getSaveFileName(
this, tr(
"Save File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
1696 if ( !myFileName.isEmpty() )
1698 if ( !myFileName.endsWith( QLatin1String(
".txt" ), Qt::CaseInsensitive ) )
1700 myFileName = myFileName +
".txt";
1703 QFile myOutputFile( myFileName );
1704 if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
1706 QTextStream myOutputStream( &myOutputFile );
1707 myOutputStream <<
"# " << tr(
"QGIS Generated Transparent Pixel Value Export File" ) <<
'\n';
1708 if ( rasterIsMultiBandColor() )
1710 myOutputStream <<
"#\n#\n# " << tr(
"Red" ) <<
"\t" << tr(
"Green" ) <<
"\t" << tr(
"Blue" ) <<
"\t" << tr(
"Percent Transparent" );
1711 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
1713 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t"
1714 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t"
1715 << QString::number( transparencyCellValue( myTableRunner, 2 ) ) <<
"\t"
1716 << QString::number( transparencyCellValue( myTableRunner, 3 ) );
1721 myOutputStream <<
"#\n#\n# " << tr(
"Value" ) <<
"\t" << tr(
"Percent Transparent" );
1723 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
1725 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t"
1726 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t"
1727 << QString::number( transparencyCellValue( myTableRunner, 2 ) );
1733 QMessageBox::warning(
this, tr(
"Export Transparent Pixels" ), tr(
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
1738 void QgsRasterLayerProperties::transparencyCellTextEdited(
const QString &text )
1741 QgsDebugMsg( QStringLiteral(
"text = %1" ).arg( text ) );
1747 int nBands = renderer->
usesBands().size();
1750 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1751 if ( !lineEdit )
return;
1754 for (
int r = 0; r < tableTransparency->rowCount(); r++ )
1756 for (
int c = 0;
c < tableTransparency->columnCount();
c++ )
1758 if ( tableTransparency->cellWidget( r,
c ) == sender() )
1765 if ( row != -1 )
break;
1767 QgsDebugMsg( QStringLiteral(
"row = %1 column =%2" ).arg( row ).arg( column ) );
1771 QLineEdit *toLineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
1772 if ( !toLineEdit )
return;
1773 bool toChanged = mTransparencyToEdited.value( row );
1774 QgsDebugMsg( QStringLiteral(
"toChanged = %1" ).arg( toChanged ) );
1777 toLineEdit->setText( lineEdit->text() );
1780 else if ( column == 1 )
1782 setTransparencyToEdited( row );
1787 void QgsRasterLayerProperties::aboutToShowStyleMenu()
1791 QMenu *m = qobject_cast<QMenu *>( sender() );
1799 void QgsRasterLayerProperties::syncToLayer()
1804 setRendererWidget( renderer->
type() );
1810 void QgsRasterLayerProperties::setTransparencyToEdited(
int row )
1812 if ( row >= mTransparencyToEdited.size() )
1814 mTransparencyToEdited.resize( row + 1 );
1816 mTransparencyToEdited[row] =
true;
1823 bool isMetadataPanel = ( index ==
mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
1824 mBtnStyle->setVisible( ! isMetadataPanel );
1825 mBtnMetadata->setVisible( isMetadataPanel );
1827 if ( !mHistogramWidget )
1839 if ( index ==
mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1842 updateInformationContent();
1846 void QgsRasterLayerProperties::setEndAsStartStaticButton_clicked()
1848 mEndStaticDateTimeEdit->setDateTime( mStartStaticDateTimeEdit->dateTime() );
1851 void QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked()
1853 int myLineCounter = 0;
1854 bool myImportError =
false;
1857 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
1858 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Open file" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
1859 QFile myInputFile( myFileName );
1860 if ( myInputFile.open( QFile::ReadOnly ) )
1862 QTextStream myInputStream( &myInputFile );
1863 QString myInputLine;
1864 if ( rasterIsMultiBandColor() )
1866 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
1868 tableTransparency->removeRow( myTableRunner );
1871 while ( !myInputStream.atEnd() )
1874 myInputLine = myInputStream.readLine();
1875 if ( !myInputLine.isEmpty() )
1877 if ( !myInputLine.simplified().startsWith(
'#' ) )
1879 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
1880 if ( myTokens.count() != 4 )
1882 myImportError =
true;
1883 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
1887 tableTransparency->insertRow( tableTransparency->rowCount() );
1888 for (
int col = 0; col < 4; col++ )
1890 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
1899 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
1901 tableTransparency->removeRow( myTableRunner );
1904 while ( !myInputStream.atEnd() )
1907 myInputLine = myInputStream.readLine();
1908 if ( !myInputLine.isEmpty() )
1910 if ( !myInputLine.simplified().startsWith(
'#' ) )
1912 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
1913 if ( myTokens.count() != 3 && myTokens.count() != 2 )
1915 myImportError =
true;
1916 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
1920 if ( myTokens.count() == 2 )
1922 myTokens.insert( 1, myTokens[0] );
1924 tableTransparency->insertRow( tableTransparency->rowCount() );
1925 for (
int col = 0; col < 3; col++ )
1927 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
1935 if ( myImportError )
1937 QMessageBox::warning(
this, tr(
"Import Transparent Pixels" ), tr(
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
1940 else if ( !myFileName.isEmpty() )
1942 QMessageBox::warning(
this, tr(
"Import Transparent Pixels" ), tr(
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
1944 tableTransparency->resizeColumnsToContents();
1945 tableTransparency->resizeRowsToContents();
1948 void QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked()
1950 if ( 0 < tableTransparency->rowCount() )
1952 tableTransparency->removeRow( tableTransparency->currentRow() );
1956 void QgsRasterLayerProperties::pixelSelected(
const QgsPointXY &canvasPoint,
const Qt::MouseButton &btn )
1966 if ( mMapCanvas && mPixelSelectorTool )
1975 int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
1976 int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
1980 QList<int> bands = renderer->
usesBands();
1982 QList<double> values;
1983 for (
int i = 0; i < bands.size(); ++i )
1985 int bandNo = bands.value( i );
1986 if ( myPixelMap.count( bandNo ) == 1 )
1988 if ( myPixelMap.value( bandNo ).isNull() )
1992 double value = myPixelMap.value( bandNo ).toDouble();
1993 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
1994 values.append( value );
1997 if ( bands.size() == 1 )
2000 values.insert( 1, values.value( 0 ) );
2002 tableTransparency->insertRow( tableTransparency->rowCount() );
2003 for (
int i = 0; i < values.size(); i++ )
2005 setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
2007 setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
2011 tableTransparency->resizeColumnsToContents();
2012 tableTransparency->resizeRowsToContents();
2015 void QgsRasterLayerProperties::toggleSaturationControls(
int grayscaleMode )
2018 if ( grayscaleMode == 0 )
2020 sliderSaturation->setEnabled(
true );
2021 spinBoxSaturation->setEnabled(
true );
2025 sliderSaturation->setEnabled(
false );
2026 spinBoxSaturation->setEnabled(
false );
2030 void QgsRasterLayerProperties::toggleColorizeControls(
bool colorizeEnabled )
2033 btnColorizeColor->setEnabled( colorizeEnabled );
2034 sliderColorizeStrength->setEnabled( colorizeEnabled );
2035 spinColorizeStrength->setEnabled( colorizeEnabled );
2039 QLinearGradient QgsRasterLayerProperties::redGradient()
2043 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2044 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
2045 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
2046 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
2049 QLinearGradient QgsRasterLayerProperties::greenGradient()
2053 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2054 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
2055 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
2056 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
2059 QLinearGradient QgsRasterLayerProperties::blueGradient()
2063 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2064 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
2065 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
2066 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
2069 QLinearGradient QgsRasterLayerProperties::grayGradient()
2073 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2074 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
2075 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
2076 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
2079 QLinearGradient QgsRasterLayerProperties::highlightGradient()
2083 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2084 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
2085 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
2086 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
2097 void QgsRasterLayerProperties::loadDefaultStyle_clicked()
2099 bool defaultLoadedFlag =
false;
2102 if ( defaultLoadedFlag )
2109 QMessageBox::information(
this,
2110 tr(
"Default Style" ),
2116 void QgsRasterLayerProperties::saveDefaultStyle_clicked()
2122 bool defaultSavedFlag =
false;
2126 if ( !defaultSavedFlag )
2129 QMessageBox::information(
this,
2130 tr(
"Default Style" ),
2137 void QgsRasterLayerProperties::loadStyle_clicked()
2140 QString lastUsedDir = settings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2142 QString fileName = QFileDialog::getOpenFileName(
2144 tr(
"Load layer properties from style file" ),
2146 tr(
"QGIS Layer Style File" ) +
" (*.qml)" );
2147 if ( fileName.isEmpty() )
2151 if ( !fileName.endsWith( QLatin1String(
".qml" ), Qt::CaseInsensitive ) )
2152 fileName += QLatin1String(
".qml" );
2156 bool defaultLoadedFlag =
false;
2157 QString message = mRasterLayer->
loadNamedStyle( fileName, defaultLoadedFlag );
2158 if ( defaultLoadedFlag )
2160 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
2165 QMessageBox::information(
this, tr(
"Save Style" ), message );
2170 void QgsRasterLayerProperties::saveStyleAs_clicked()
2173 QString lastUsedDir = settings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2175 QString selectedFilter;
2176 QString outputFileName = QFileDialog::getSaveFileName(
2178 tr(
"Save layer properties as style file" ),
2180 tr(
"QGIS Layer Style File" ) +
" (*.qml)" +
";;" + tr(
"Styled Layer Descriptor" ) +
" (*.sld)",
2182 if ( outputFileName.isEmpty() )
2187 if ( selectedFilter.contains( QStringLiteral(
".qml" ), Qt::CaseInsensitive ) )
2190 type = StyleType::QML;
2195 type = StyleType::SLD;
2201 bool defaultLoadedFlag =
false;
2207 message = mRasterLayer->
saveNamedStyle( outputFileName, defaultLoadedFlag );
2212 message = mRasterLayer->
saveSldStyle( outputFileName, defaultLoadedFlag );
2216 if ( defaultLoadedFlag )
2218 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
2222 QMessageBox::information(
this, tr(
"Save Style" ), message );
2225 void QgsRasterLayerProperties::restoreWindowModality()
2240 void QgsRasterLayerProperties::loadMetadata()
2243 QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2245 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Load layer metadata from metadata file" ), myLastUsedDir,
2246 tr(
"QGIS Layer Metadata File" ) +
" (*.qmd)" );
2247 if ( myFileName.isNull() )
2253 bool defaultLoadedFlag =
false;
2257 if ( defaultLoadedFlag )
2264 QMessageBox::warning(
this, tr(
"Load Metadata" ), myMessage );
2267 QFileInfo myFI( myFileName );
2268 QString myPath = myFI.path();
2269 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), myPath );
2274 void QgsRasterLayerProperties::saveMetadataAs()
2277 QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2279 QString myOutputFileName = QFileDialog::getSaveFileName(
this, tr(
"Save Layer Metadata as QMD" ),
2280 myLastUsedDir, tr(
"QMD File" ) +
" (*.qmd)" );
2281 if ( myOutputFileName.isNull() )
2294 bool defaultLoadedFlag =
false;
2295 QString message = mRasterLayer->
saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
2296 if ( defaultLoadedFlag )
2297 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
2299 QMessageBox::information(
this, tr(
"Save Metadata" ), message );
2302 void QgsRasterLayerProperties::saveDefaultMetadata()
2306 bool defaultSavedFlag =
false;
2308 if ( !defaultSavedFlag )
2310 QMessageBox::warning(
this, tr(
"Default Metadata" ), errorMsg );
2314 void QgsRasterLayerProperties::loadDefaultMetadata()
2316 bool defaultLoadedFlag =
false;
2319 if ( defaultLoadedFlag )
2325 QMessageBox::information(
this, tr(
"Default Metadata" ), myMessage );
2330 void QgsRasterLayerProperties::toggleBuildPyramidsButton()
2332 if ( lbxPyramidResolutions->selectedItems().empty() )
2334 buttonBuildPyramids->setEnabled(
false );
2338 buttonBuildPyramids->setEnabled(
true );
2342 void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
2344 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
2345 mSliderBrightness->setValue( 0 );
2346 mSliderContrast->setValue( 0 );
2347 mGammaSpinBox->setValue( 1.0 );
2348 sliderSaturation->setValue( 0 );
2350 mColorizeCheck->setChecked(
false );
2351 sliderColorizeStrength->setValue( 100 );
2354 bool QgsRasterLayerProperties::rasterIsMultiBandColor()
2359 void QgsRasterLayerProperties::updateInformationContent()
2363 const QString html { mRasterLayer->
htmlMetadata().replace( QLatin1String(
"<head>" ), QStringLiteral( R
"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
2364 mMetadataViewer->setHtml( html );
2365 mMetadataFilled = true;
2368 void QgsRasterLayerProperties::onCancel()
2374 QDomDocument doc( QStringLiteral(
"qgis" ) );
2375 int errorLine, errorColumn;
2376 doc.setContent( mOldStyle.
xmlData(),
false, &myMessage, &errorLine, &errorColumn );
2382 void QgsRasterLayerProperties::showHelp()
2384 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property(
"helpPage" );
2386 if ( helpPage.isValid() )
2392 QgsHelp::openHelp( QStringLiteral(
"working_with_raster/raster_properties.html" ) );
2396 void QgsRasterLayerProperties::updateGammaSpinBox(
int value )
2401 void QgsRasterLayerProperties::updateGammaSlider(
double value )