[processing] Add spanner button next to Raster input combobox to open an advanced panel to specify raster source options (e.g., reference scale and DPI for WMS rasters). For now, the spanner button is only enabled for WMS layers.

This commit is contained in:
Germán Carrillo 2025-08-20 17:59:45 +02:00 committed by Nyall Dawson
parent c2b5060802
commit 28c8bfd985
2 changed files with 68 additions and 0 deletions

View File

@ -25,6 +25,7 @@
#include "qgsguiutils.h"
#include "qgspanelwidget.h"
#include "qgsprocessingfeaturesourceoptionswidget.h"
#include "qgsprocessingrastersourceoptionswidget.h"
#include "qgsdatasourceselectdialog.h"
#include "qgsprocessingwidgetwrapper.h"
#include "qgsprocessingprovider.h"
@ -84,6 +85,22 @@ QgsProcessingMapLayerComboBox::QgsProcessingMapLayerComboBox( const QgsProcessin
layout->addWidget( mSettingsButton );
layout->setAlignment( mSettingsButton, Qt::AlignTop );
}
else if ( mParameter->type() == QgsProcessingParameterRasterLayer::typeName() )
{
mSettingsButton = new QToolButton();
mSettingsButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionOptions.svg" ) ) );
mSettingsButton->setToolTip( tr( "Advanced options" ) );
mSettingsButton->setEnabled( false ); // Only WMS layers will access raster advanced options for now
// button width is 1.25 * icon size, height 1.1 * icon size. But we round to ensure even pixel sizes for equal margins
mSettingsButton->setFixedSize( 2 * static_cast<int>( 1.25 * iconSize / 2.0 ), 2 * static_cast<int>( iconSize * 1.1 / 2.0 ) );
mSettingsButton->setIconSize( QSize( iconSize, iconSize ) );
mSettingsButton->setAutoRaise( true );
connect( mSettingsButton, &QToolButton::clicked, this, &QgsProcessingMapLayerComboBox::showRasterSourceOptions );
layout->addWidget( mSettingsButton );
layout->setAlignment( mSettingsButton, Qt::AlignTop );
}
mSelectButton = new QToolButton();
mSelectButton->setText( QString( QChar( 0x2026 ) ) );
@ -269,6 +286,19 @@ void QgsProcessingMapLayerComboBox::setValue( const QVariant &value, QgsProcessi
mGeometryCheck = Qgis::InvalidGeometryCheck::AbortOnInvalid;
}
if ( val.userType() == qMetaTypeId<QgsProcessingRasterLayerDefinition>() )
{
QgsProcessingRasterLayerDefinition fromVar = qvariant_cast<QgsProcessingRasterLayerDefinition>( val );
val = fromVar.source;
mRasterReferenceScale = fromVar.referenceScale;
mRasterDpi = fromVar.dpi;
}
else
{
mRasterReferenceScale = 0;
mRasterDpi = 96;
}
if ( val.userType() == qMetaTypeId<QgsProperty>() )
{
if ( val.value<QgsProperty>().propertyType() == Qgis::PropertyType::Static )
@ -367,6 +397,8 @@ QVariant QgsProcessingMapLayerComboBox::value() const
{
if ( selectedOnly || iterate || mFeatureLimit != -1 || mIsOverridingDefaultGeometryCheck || !mFilterExpression.isEmpty() )
return QgsProcessingFeatureSourceDefinition( layer->id(), selectedOnly, mFeatureLimit, ( iterate ? Qgis::ProcessingFeatureSourceDefinitionFlag::CreateIndividualOutputPerInputFeature : Qgis::ProcessingFeatureSourceDefinitionFlags() ) | ( mIsOverridingDefaultGeometryCheck ? Qgis::ProcessingFeatureSourceDefinitionFlag::OverrideDefaultGeometryCheck : Qgis::ProcessingFeatureSourceDefinitionFlags() ), mGeometryCheck, mFilterExpression );
else if ( mRasterReferenceScale != 0 )
return QgsProcessingRasterLayerDefinition( layer->id(), mRasterReferenceScale, mRasterDpi );
else
return layer->id();
}
@ -376,6 +408,8 @@ QVariant QgsProcessingMapLayerComboBox::value() const
{
if ( selectedOnly || iterate || mFeatureLimit != -1 || mIsOverridingDefaultGeometryCheck || !mFilterExpression.isEmpty() )
return QgsProcessingFeatureSourceDefinition( mCombo->currentText(), selectedOnly, mFeatureLimit, ( iterate ? Qgis::ProcessingFeatureSourceDefinitionFlag::CreateIndividualOutputPerInputFeature : Qgis::ProcessingFeatureSourceDefinitionFlags() ) | ( mIsOverridingDefaultGeometryCheck ? Qgis::ProcessingFeatureSourceDefinitionFlag::OverrideDefaultGeometryCheck : Qgis::ProcessingFeatureSourceDefinitionFlags() ), mGeometryCheck, mFilterExpression );
else if ( mRasterReferenceScale != 0 )
return QgsProcessingRasterLayerDefinition( mCombo->currentText(), mRasterReferenceScale, mRasterDpi );
else
return mCombo->currentText();
}
@ -613,6 +647,12 @@ void QgsProcessingMapLayerComboBox::onLayerChanged( QgsMapLayer *layer )
}
}
if ( mParameter->type() == QgsProcessingParameterRasterLayer::typeName() )
{
// Only WMS layers will access raster advanced options for now
mSettingsButton->setEnabled( layer && layer->providerType() == QStringLiteral( "wms" ) );
}
mPrevLayer = layer;
if ( !mBlockChangedSignal )
emit valueChanged();
@ -657,6 +697,31 @@ void QgsProcessingMapLayerComboBox::showSourceOptions()
}
}
void QgsProcessingMapLayerComboBox::showRasterSourceOptions()
{
if ( QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this ) )
{
QgsProcessingRasterSourceOptionsWidget *widget = new QgsProcessingRasterSourceOptionsWidget();
widget->setPanelTitle( tr( "%1 Options" ).arg( mParameter->description() ) );
widget->setReferenceScale( mRasterReferenceScale );
widget->setDpi( mRasterDpi );
panel->openPanel( widget );
connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget] {
bool changed = false;
changed = changed | ( widget->referenceScale() != mRasterReferenceScale );
changed = changed | ( widget->dpi() != mRasterDpi );
mRasterReferenceScale = widget->referenceScale();
mRasterDpi = widget->dpi();
if ( changed )
emit valueChanged();
} );
}
}
void QgsProcessingMapLayerComboBox::selectFromFile()
{
QgsSettings settings;

View File

@ -131,6 +131,7 @@ class GUI_EXPORT QgsProcessingMapLayerComboBox : public QWidget
void onLayerChanged( QgsMapLayer *layer );
void selectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect );
void showSourceOptions();
void showRasterSourceOptions();
void selectFromFile();
void browseForLayer();
@ -146,6 +147,8 @@ class GUI_EXPORT QgsProcessingMapLayerComboBox : public QWidget
QString mFilterExpression;
bool mIsOverridingDefaultGeometryCheck = false;
Qgis::InvalidGeometryCheck mGeometryCheck = Qgis::InvalidGeometryCheck::AbortOnInvalid;
long mRasterReferenceScale = 0;
int mRasterDpi = 0;
QPointer<QgsMapLayer> mPrevLayer;
int mBlockChangedSignal = 0;