diff --git a/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp b/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp index a836cab18f2a..d145bf5d5cca 100644 --- a/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp +++ b/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp @@ -25,7 +25,7 @@ #include "qgspanelwidget.h" #include "qgsprocessingcontext.h" -#include "qgsvectortilewriter.h" +#include "qgsprocessingmodelalgorithm.h" #include "qgsprocessingparameterfieldmap.h" @@ -178,6 +178,69 @@ void QgsProcessingFieldMapPanelWidget::loadLayerFields() } } +// +// QgsProcessingFieldMapParameterDefinitionWidget +// + +QgsProcessingFieldMapParameterDefinitionWidget::QgsProcessingFieldMapParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent ) + : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent ) +{ + QVBoxLayout *vlayout = new QVBoxLayout(); + vlayout->setMargin( 0 ); + vlayout->setContentsMargins( 0, 0, 0, 0 ); + + vlayout->addWidget( new QLabel( tr( "Parent layer" ) ) ); + + mParentLayerComboBox = new QComboBox(); + mParentLayerComboBox->addItem( tr( "None" ), QVariant() ); + + QString initialParent; + if ( const QgsProcessingParameterFieldMapping *mapParam = dynamic_cast( definition ) ) + initialParent = mapParam->parentLayerParameterName(); + + if ( widgetContext.model() ) + { + // populate combo box with other model input choices + const QMap components = widgetContext.model()->parameterComponents(); + for ( auto it = components.constBegin(); it != components.constEnd(); ++it ) + { + if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) ) + { + mParentLayerComboBox-> addItem( definition->description(), definition->name() ); + if ( !initialParent.isEmpty() && initialParent == definition->name() ) + { + mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 ); + } + } + else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) ) + { + mParentLayerComboBox-> addItem( definition->description(), definition->name() ); + if ( !initialParent.isEmpty() && initialParent == definition->name() ) + { + mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 ); + } + } + } + } + + if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() ) + { + // if no parent candidates found, we just add the existing one as a placeholder + mParentLayerComboBox->addItem( initialParent, initialParent ); + mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 ); + } + + vlayout->addWidget( mParentLayerComboBox ); + setLayout( vlayout ); +} + +QgsProcessingParameterDefinition *QgsProcessingFieldMapParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const +{ + auto param = qgis::make_unique< QgsProcessingParameterFieldMapping >( name, description, mParentLayerComboBox->currentData().toString() ); + param->setFlags( flags ); + return param.release(); +} + // // QgsProcessingFieldMapWidgetWrapper // @@ -210,6 +273,11 @@ QWidget *QgsProcessingFieldMapWidgetWrapper::createWidget() return mPanel; } +QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFieldMapWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm ) +{ + return new QgsProcessingFieldMapParameterDefinitionWidget( context, widgetContext, definition, algorithm ); +} + void QgsProcessingFieldMapWidgetWrapper::postInitialize( const QList &wrappers ) { QgsAbstractProcessingParameterWidgetWrapper::postInitialize( wrappers ); @@ -318,3 +386,5 @@ const QgsVectorLayer *QgsProcessingFieldMapWidgetWrapper::linkedVectorLayer() co } /// @endcond + + diff --git a/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h b/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h index 8812af65eb92..37f90bde983e 100644 --- a/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h +++ b/src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h @@ -19,7 +19,7 @@ #define SIP_NO_FILE #include "qgsprocessingwidgetwrapper.h" -#include "qgsprocessingmultipleselectiondialog.h" +#include "qgsprocessingparameterdefinitionwidget.h" #include "ui_qgsprocessingfieldsmappingpanelbase.h" @@ -58,6 +58,24 @@ class GUI_EXPORT QgsProcessingFieldMapPanelWidget : public QgsPanelWidget, priva }; +class GUI_EXPORT QgsProcessingFieldMapParameterDefinitionWidget : public QgsProcessingAbstractParameterDefinitionWidget +{ + Q_OBJECT + public: + + QgsProcessingFieldMapParameterDefinitionWidget( QgsProcessingContext &context, + const QgsProcessingParameterWidgetContext &widgetContext, + const QgsProcessingParameterDefinition *definition = nullptr, + const QgsProcessingAlgorithm *algorithm = nullptr, QWidget *parent SIP_TRANSFERTHIS = nullptr ); + QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const override; + + private: + + QComboBox *mParentLayerComboBox = nullptr; + +}; + + class GUI_EXPORT QgsProcessingFieldMapWidgetWrapper : public QgsAbstractProcessingParameterWidgetWrapper, public QgsProcessingParameterWidgetFactoryInterface { Q_OBJECT @@ -73,6 +91,11 @@ class GUI_EXPORT QgsProcessingFieldMapWidgetWrapper : public QgsAbstractProcessi // QgsProcessingParameterWidgetWrapper interface QWidget *createWidget() override SIP_FACTORY; + QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget( + QgsProcessingContext &context, + const QgsProcessingParameterWidgetContext &widgetContext, + const QgsProcessingParameterDefinition *definition = nullptr, + const QgsProcessingAlgorithm *algorithm = nullptr ) override; void postInitialize( const QList< QgsAbstractProcessingParameterWidgetWrapper * > &wrappers ) override; int stretch() const override; diff --git a/tests/src/gui/testprocessinggui.cpp b/tests/src/gui/testprocessinggui.cpp index 1cedb2ad4a84..8b0f04f1dede 100644 --- a/tests/src/gui/testprocessinggui.cpp +++ b/tests/src/gui/testprocessinggui.cpp @@ -7350,6 +7350,34 @@ void TestProcessingGui::testFieldMapWrapper() // modeler wrapper testWrapper( QgsProcessingGui::Modeler ); + + // config widget + QgsProcessingParameterWidgetContext widgetContext; + QgsProcessingContext context; + std::unique_ptr< QgsProcessingParameterDefinitionWidget > widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext ); + std::unique_ptr< QgsProcessingParameterDefinition > def( widget->createParameter( QStringLiteral( "param_name" ) ) ); + QCOMPARE( def->name(), QStringLiteral( "param_name" ) ); + QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) ); // should default to mandatory + QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) ); + + // using a parameter definition as initial values + QgsProcessingParameterFieldMapping mapParam( QStringLiteral( "n" ), QStringLiteral( "test desc" ), QStringLiteral( "parent" ) ); + widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext, &mapParam ); + def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) ); + QCOMPARE( def->name(), QStringLiteral( "param_name" ) ); + QCOMPARE( def->description(), QStringLiteral( "test desc" ) ); + QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) ); + QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) ); + QCOMPARE( static_cast< QgsProcessingParameterFieldMapping * >( def.get() )->parentLayerParameterName(), QStringLiteral( "parent" ) ); + mapParam.setFlags( QgsProcessingParameterDefinition::FlagAdvanced | QgsProcessingParameterDefinition::FlagOptional ); + mapParam.setParentLayerParameterName( QString() ); + widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext, &mapParam ); + def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) ); + QCOMPARE( def->name(), QStringLiteral( "param_name" ) ); + QCOMPARE( def->description(), QStringLiteral( "test desc" ) ); + QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagOptional ); + QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ); + QVERIFY( static_cast< QgsProcessingParameterFieldMapping * >( def.get() )->parentLayerParameterName().isEmpty() ); } void TestProcessingGui::testOutputDefinitionWidget()