Skip to content

Commit b8d4a39

Browse files
committedJun 1, 2020
[processing] Allow parent layer to be specified for field mapping inputs in models
Fixes #26493
1 parent ac6afaa commit b8d4a39

File tree

3 files changed

+123
-2
lines changed

3 files changed

+123
-2
lines changed
 

‎src/gui/processing/qgsprocessingfieldmapwidgetwrapper.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "qgspanelwidget.h"
2626

2727
#include "qgsprocessingcontext.h"
28-
#include "qgsvectortilewriter.h"
28+
#include "qgsprocessingmodelalgorithm.h"
2929

3030
#include "qgsprocessingparameterfieldmap.h"
3131

@@ -178,6 +178,69 @@ void QgsProcessingFieldMapPanelWidget::loadLayerFields()
178178
}
179179
}
180180

181+
//
182+
// QgsProcessingFieldMapParameterDefinitionWidget
183+
//
184+
185+
QgsProcessingFieldMapParameterDefinitionWidget::QgsProcessingFieldMapParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
186+
: QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
187+
{
188+
QVBoxLayout *vlayout = new QVBoxLayout();
189+
vlayout->setMargin( 0 );
190+
vlayout->setContentsMargins( 0, 0, 0, 0 );
191+
192+
vlayout->addWidget( new QLabel( tr( "Parent layer" ) ) );
193+
194+
mParentLayerComboBox = new QComboBox();
195+
mParentLayerComboBox->addItem( tr( "None" ), QVariant() );
196+
197+
QString initialParent;
198+
if ( const QgsProcessingParameterFieldMapping *mapParam = dynamic_cast<const QgsProcessingParameterFieldMapping *>( definition ) )
199+
initialParent = mapParam->parentLayerParameterName();
200+
201+
if ( widgetContext.model() )
202+
{
203+
// populate combo box with other model input choices
204+
const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
205+
for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
206+
{
207+
if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
208+
{
209+
mParentLayerComboBox-> addItem( definition->description(), definition->name() );
210+
if ( !initialParent.isEmpty() && initialParent == definition->name() )
211+
{
212+
mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
213+
}
214+
}
215+
else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
216+
{
217+
mParentLayerComboBox-> addItem( definition->description(), definition->name() );
218+
if ( !initialParent.isEmpty() && initialParent == definition->name() )
219+
{
220+
mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
221+
}
222+
}
223+
}
224+
}
225+
226+
if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() )
227+
{
228+
// if no parent candidates found, we just add the existing one as a placeholder
229+
mParentLayerComboBox->addItem( initialParent, initialParent );
230+
mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
231+
}
232+
233+
vlayout->addWidget( mParentLayerComboBox );
234+
setLayout( vlayout );
235+
}
236+
237+
QgsProcessingParameterDefinition *QgsProcessingFieldMapParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
238+
{
239+
auto param = qgis::make_unique< QgsProcessingParameterFieldMapping >( name, description, mParentLayerComboBox->currentData().toString() );
240+
param->setFlags( flags );
241+
return param.release();
242+
}
243+
181244
//
182245
// QgsProcessingFieldMapWidgetWrapper
183246
//
@@ -210,6 +273,11 @@ QWidget *QgsProcessingFieldMapWidgetWrapper::createWidget()
210273
return mPanel;
211274
}
212275

276+
QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFieldMapWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
277+
{
278+
return new QgsProcessingFieldMapParameterDefinitionWidget( context, widgetContext, definition, algorithm );
279+
}
280+
213281
void QgsProcessingFieldMapWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
214282
{
215283
QgsAbstractProcessingParameterWidgetWrapper::postInitialize( wrappers );
@@ -318,3 +386,5 @@ const QgsVectorLayer *QgsProcessingFieldMapWidgetWrapper::linkedVectorLayer() co
318386
}
319387

320388
/// @endcond
389+
390+

‎src/gui/processing/qgsprocessingfieldmapwidgetwrapper.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#define SIP_NO_FILE
2020

2121
#include "qgsprocessingwidgetwrapper.h"
22-
#include "qgsprocessingmultipleselectiondialog.h"
22+
#include "qgsprocessingparameterdefinitionwidget.h"
2323

2424
#include "ui_qgsprocessingfieldsmappingpanelbase.h"
2525

@@ -58,6 +58,24 @@ class GUI_EXPORT QgsProcessingFieldMapPanelWidget : public QgsPanelWidget, priva
5858
};
5959

6060

61+
class GUI_EXPORT QgsProcessingFieldMapParameterDefinitionWidget : public QgsProcessingAbstractParameterDefinitionWidget
62+
{
63+
Q_OBJECT
64+
public:
65+
66+
QgsProcessingFieldMapParameterDefinitionWidget( QgsProcessingContext &context,
67+
const QgsProcessingParameterWidgetContext &widgetContext,
68+
const QgsProcessingParameterDefinition *definition = nullptr,
69+
const QgsProcessingAlgorithm *algorithm = nullptr, QWidget *parent SIP_TRANSFERTHIS = nullptr );
70+
QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const override;
71+
72+
private:
73+
74+
QComboBox *mParentLayerComboBox = nullptr;
75+
76+
};
77+
78+
6179
class GUI_EXPORT QgsProcessingFieldMapWidgetWrapper : public QgsAbstractProcessingParameterWidgetWrapper, public QgsProcessingParameterWidgetFactoryInterface
6280
{
6381
Q_OBJECT
@@ -73,6 +91,11 @@ class GUI_EXPORT QgsProcessingFieldMapWidgetWrapper : public QgsAbstractProcessi
7391

7492
// QgsProcessingParameterWidgetWrapper interface
7593
QWidget *createWidget() override SIP_FACTORY;
94+
QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget(
95+
QgsProcessingContext &context,
96+
const QgsProcessingParameterWidgetContext &widgetContext,
97+
const QgsProcessingParameterDefinition *definition = nullptr,
98+
const QgsProcessingAlgorithm *algorithm = nullptr ) override;
7699

77100
void postInitialize( const QList< QgsAbstractProcessingParameterWidgetWrapper * > &wrappers ) override;
78101
int stretch() const override;

‎tests/src/gui/testprocessinggui.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7350,6 +7350,34 @@ void TestProcessingGui::testFieldMapWrapper()
73507350

73517351
// modeler wrapper
73527352
testWrapper( QgsProcessingGui::Modeler );
7353+
7354+
// config widget
7355+
QgsProcessingParameterWidgetContext widgetContext;
7356+
QgsProcessingContext context;
7357+
std::unique_ptr< QgsProcessingParameterDefinitionWidget > widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext );
7358+
std::unique_ptr< QgsProcessingParameterDefinition > def( widget->createParameter( QStringLiteral( "param_name" ) ) );
7359+
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
7360+
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) ); // should default to mandatory
7361+
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) );
7362+
7363+
// using a parameter definition as initial values
7364+
QgsProcessingParameterFieldMapping mapParam( QStringLiteral( "n" ), QStringLiteral( "test desc" ), QStringLiteral( "parent" ) );
7365+
widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext, &mapParam );
7366+
def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) );
7367+
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
7368+
QCOMPARE( def->description(), QStringLiteral( "test desc" ) );
7369+
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) );
7370+
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) );
7371+
QCOMPARE( static_cast< QgsProcessingParameterFieldMapping * >( def.get() )->parentLayerParameterName(), QStringLiteral( "parent" ) );
7372+
mapParam.setFlags( QgsProcessingParameterDefinition::FlagAdvanced | QgsProcessingParameterDefinition::FlagOptional );
7373+
mapParam.setParentLayerParameterName( QString() );
7374+
widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "fields_mapping" ), context, widgetContext, &mapParam );
7375+
def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) );
7376+
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
7377+
QCOMPARE( def->description(), QStringLiteral( "test desc" ) );
7378+
QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagOptional );
7379+
QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced );
7380+
QVERIFY( static_cast< QgsProcessingParameterFieldMapping * >( def.get() )->parentLayerParameterName().isEmpty() );
73537381
}
73547382

73557383
void TestProcessingGui::testOutputDefinitionWidget()

0 commit comments

Comments
 (0)
Please sign in to comment.