Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] Allow parent layer to be specified for field mapping inp…
…uts in models

Fixes #26493
  • Loading branch information
nyalldawson committed Jun 1, 2020
1 parent ac6afaa commit b8d4a39
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 2 deletions.
72 changes: 71 additions & 1 deletion src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp
Expand Up @@ -25,7 +25,7 @@
#include "qgspanelwidget.h"

#include "qgsprocessingcontext.h"
#include "qgsvectortilewriter.h"
#include "qgsprocessingmodelalgorithm.h"

#include "qgsprocessingparameterfieldmap.h"

Expand Down Expand Up @@ -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<const QgsProcessingParameterFieldMapping *>( definition ) )
initialParent = mapParam->parentLayerParameterName();

if ( widgetContext.model() )
{
// populate combo box with other model input choices
const QMap<QString, QgsProcessingModelParameter> 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
//
Expand Down Expand Up @@ -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<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
{
QgsAbstractProcessingParameterWidgetWrapper::postInitialize( wrappers );
Expand Down Expand Up @@ -318,3 +386,5 @@ const QgsVectorLayer *QgsProcessingFieldMapWidgetWrapper::linkedVectorLayer() co
}

/// @endcond


25 changes: 24 additions & 1 deletion src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h
Expand Up @@ -19,7 +19,7 @@
#define SIP_NO_FILE

#include "qgsprocessingwidgetwrapper.h"
#include "qgsprocessingmultipleselectiondialog.h"
#include "qgsprocessingparameterdefinitionwidget.h"

#include "ui_qgsprocessingfieldsmappingpanelbase.h"

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
28 changes: 28 additions & 0 deletions tests/src/gui/testprocessinggui.cpp
Expand Up @@ -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()
Expand Down

0 comments on commit b8d4a39

Please sign in to comment.