38#include <QStackedWidget>
41#include "moc_qgsprocessingmodelerparameterwidget.cpp"
47 , mParameterDefinition( parameter )
50 setFocusPolicy( Qt::StrongFocus );
55 QHBoxLayout *hLayout =
new QHBoxLayout();
58 const QVariantList acceptedSourcesMetadata = mParameterDefinition->metadata().value( QStringLiteral(
"model_widget" ) ).toMap().value( QStringLiteral(
"accepted_sources" ) ).toList();
59 for (
const QVariant &acceptedSource : acceptedSourcesMetadata )
65 mSourceButton =
new QToolButton();
66 mSourceButton->setFocusPolicy( Qt::StrongFocus );
69 mSourceButton->setFixedSize( 2 *
static_cast<int>( 1.25 * iconSize / 2.0 ), 2 *
static_cast<int>( iconSize * 1.1 / 2.0 ) );
70 mSourceButton->setIconSize( QSize( iconSize, iconSize ) );
71 mSourceButton->setPopupMode( QToolButton::InstantPopup );
73 mSourceMenu =
new QMenu(
this );
74 connect( mSourceMenu, &QMenu::aboutToShow,
this, &QgsProcessingModelerParameterWidget::sourceMenuAboutToShow );
75 connect( mSourceMenu, &QMenu::triggered,
this, &QgsProcessingModelerParameterWidget::sourceMenuActionTriggered );
76 mSourceButton->setMenu( mSourceMenu );
78 hLayout->addWidget( mSourceButton );
80 mStackedWidget =
new QStackedWidget();
83 if ( mStaticWidgetWrapper )
85 QWidget *widget = mStaticWidgetWrapper->createWrappedWidget( context );
88 mHasStaticWrapper =
true;
89 mStackedWidget->addWidget( widget );
92 mStackedWidget->addWidget(
new QWidget() );
96 mStackedWidget->addWidget(
new QWidget() );
100 mExpressionWidget->registerExpressionContextGenerator(
this );
101 mStackedWidget->addWidget( mExpressionWidget );
103 mModelInputCombo =
new QComboBox();
104 QHBoxLayout *hLayout2 =
new QHBoxLayout();
105 hLayout2->setContentsMargins( 0, 0, 0, 0 );
106 hLayout2->addWidget(
new QLabel( tr(
"Using model input" ) ) );
107 hLayout2->addWidget( mModelInputCombo, 1 );
108 QWidget *hWidget2 =
new QWidget();
109 hWidget2->setLayout( hLayout2 );
110 mStackedWidget->addWidget( hWidget2 );
112 mChildOutputCombo =
new QComboBox();
113 QHBoxLayout *hLayout3 =
new QHBoxLayout();
114 hLayout3->setContentsMargins( 0, 0, 0, 0 );
115 hLayout3->addWidget(
new QLabel( tr(
"Using algorithm output" ) ) );
116 hLayout3->addWidget( mChildOutputCombo, 1 );
117 QWidget *hWidget3 =
new QWidget();
118 hWidget3->setLayout( hLayout3 );
119 mStackedWidget->addWidget( hWidget3 );
121 if ( mParameterDefinition->isDestination() )
124 mModelOutputName->setPlaceholderText( tr(
"[Enter name if this is a final result]" ) );
125 QHBoxLayout *hLayout4 =
new QHBoxLayout();
126 hLayout4->setContentsMargins( 0, 0, 0, 0 );
127 hLayout4->addWidget( mModelOutputName );
128 QWidget *hWidget4 =
new QWidget();
129 hWidget4->setLayout( hLayout4 );
130 mStackedWidget->addWidget( hWidget4 );
133 hLayout->setContentsMargins( 0, 0, 0, 0 );
134 hLayout->addWidget( mStackedWidget, 1 );
136 setLayout( hLayout );
144 if ( mStaticWidgetWrapper )
145 mStaticWidgetWrapper->setWidgetContext( context );
150 if ( mStaticWidgetWrapper )
151 mStaticWidgetWrapper->registerProcessingContextGenerator( generator );
156 return mParameterDefinition;
161 if ( mStaticWidgetWrapper )
162 return mStaticWidgetWrapper->createWrappedLabel();
171 mStaticValue =
value.staticValue();
172 mModelInputParameterName =
value.parameterName();
173 mOutputChildId =
value.outputChildId();
174 mOutputName =
value.outputName();
175 mExpression =
value.expression();
183 if ( values.size() == 1 )
188 for (
const QgsProcessingModelChildParameterSource &v : values )
189 r << QVariant::fromValue( v );
198 if ( mModelOutputName )
199 mModelOutputName->setText(
value );
205 return currentSourceType() == ModelOutput;
210 return mModelOutputName ? mModelOutputName->text().trimmed() : QString();
215 switch ( currentSourceType() )
219 const QVariant v = mStaticWidgetWrapper->parameterValue();
221 if ( v.userType() == QMetaType::Type::QVariantList )
223 const QVariantList vList = v.toList();
224 if ( std::all_of( vList.begin(), vList.end(), [](
const QVariant &val ) {
225 return val.userType() == qMetaTypeId<QgsProcessingModelChildParameterSource>();
231 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromStaticValue( v ) );
235 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromExpression( mExpressionWidget->expression() ) );
238 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromModelParameter( mModelInputCombo->currentData().toString() ) );
242 const QStringList parts = mChildOutputCombo->currentData().toStringList();
243 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromChildOutput( parts.value( 0, QString() ), parts.value( 1, QString() ) ) );
247 return mModelOutputName ? ( mModelOutputName->text().trimmed().isEmpty() ? QVariant() : mModelOutputName->text() ) : QVariant();
250 return QVariant::fromValue( QgsProcessingModelChildParameterSource() );
255 if ( mStaticWidgetWrapper )
256 mStaticWidgetWrapper->setDialog( dialog );
265 if ( mModel->childAlgorithms().contains( mChildId ) )
266 alg = mModel->childAlgorithm( mChildId ).algorithm();
271 QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( mChildId, mContext, QVariantMap(), QVariantMap() );
274 QStringList highlightedVariables = childScope->
variableNames();
275 QStringList highlightedFunctions = childScope->
functionNames();
277 highlightedVariables += mModel->variables().keys();
279 c.setHighlightedVariables( highlightedVariables );
280 c.setHighlightedFunctions( highlightedFunctions );
286void QgsProcessingModelerParameterWidget::sourceMenuAboutToShow()
288 mSourceMenu->clear();
290 const SourceType currentSource = currentSourceType();
295 QAction *modelOutputAction = mSourceMenu->addAction( tr(
"Model Output" ) );
296 modelOutputAction->setCheckable( currentSource == ModelOutput );
297 modelOutputAction->setChecked( currentSource == ModelOutput );
301 if ( mHasStaticWrapper
304 QAction *fixedValueAction = mSourceMenu->addAction( tr(
"Value" ) );
305 fixedValueAction->setCheckable( currentSource == StaticValue );
306 fixedValueAction->setChecked( currentSource == StaticValue );
312 QAction *calculatedValueAction = mSourceMenu->addAction( tr(
"Pre-calculated Value" ) );
313 calculatedValueAction->setCheckable( currentSource == Expression );
314 calculatedValueAction->setChecked( currentSource == Expression );
320 QAction *inputValueAction = mSourceMenu->addAction( tr(
"Model Input" ) );
321 inputValueAction->setCheckable( currentSource == ModelParameter );
322 inputValueAction->setChecked( currentSource == ModelParameter );
328 QAction *childOutputValueAction = mSourceMenu->addAction( tr(
"Algorithm Output" ) );
329 childOutputValueAction->setCheckable( currentSource == ChildOutput );
330 childOutputValueAction->setChecked( currentSource == ChildOutput );
337void QgsProcessingModelerParameterWidget::sourceMenuActionTriggered( QAction *action )
343QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
const
345 return static_cast<SourceType
>( mStackedWidget->currentIndex() );
350 if ( !mLimitedSources.empty() && !mLimitedSources.contains( type ) )
354 type = mLimitedSources.at( 0 );
360 mStackedWidget->setCurrentIndex(
static_cast<int>( StaticValue ) );
362 mSourceButton->setToolTip( tr(
"Value" ) );
367 mStackedWidget->setCurrentIndex(
static_cast<int>( Expression ) );
368 mSourceButton->setToolTip( tr(
"Pre-calculated Value" ) );
374 mStackedWidget->setCurrentIndex(
static_cast<int>( ModelParameter ) );
375 mSourceButton->setToolTip( tr(
"Model Input" ) );
382 mStackedWidget->setCurrentIndex(
static_cast<int>( ChildOutput ) );
383 mSourceButton->setToolTip( tr(
"Algorithm Output" ) );
390 mStackedWidget->setCurrentIndex(
static_cast<int>( ModelOutput ) );
391 mSourceButton->setToolTip( tr(
"Model Output" ) );
400void QgsProcessingModelerParameterWidget::updateUi()
402 mStaticWidgetWrapper->setParameterValue( mStaticValue, mContext );
406 int currentIndex = mModelInputCombo->findData( mModelInputParameterName );
407 if ( currentIndex == -1 && mModelInputCombo->count() > 0 )
409 mModelInputCombo->setCurrentIndex( currentIndex );
411 const QStringList parts = QStringList() << mOutputChildId << mOutputName;
412 currentIndex = mChildOutputCombo->findData( parts );
413 if ( currentIndex == -1 && mChildOutputCombo->count() > 0 )
415 mChildOutputCombo->setCurrentIndex( currentIndex );
420 QgsProcessingModelChildParameterSources sources = mModel->availableSourcesForChild( mChildId, compatibleParameterTypes, compatibleOutputTypes, compatibleDataTypes );
422 for (
const QgsProcessingModelChildParameterSource &source : sources )
424 switch ( source.source() )
427 mModelInputCombo->addItem( mModel->parameterDefinition( source.parameterName() )->description(), source.parameterName() );
432 if ( !mModel->childAlgorithms().contains( source.outputChildId() ) )
435 const QgsProcessingModelChildAlgorithm &alg = mModel->childAlgorithm( source.outputChildId() );
436 if ( !alg.algorithm() )
438 const QString outputDescription = alg.algorithm()->outputDefinition( source.outputName() )->description();
439 const QString childDescription = alg.description();
441 mChildOutputCombo->addItem( tr(
"“%1” from algorithm “%2”" ).arg( outputDescription, childDescription ), QStringList() << source.outputChildId() << source.outputName() );
456 mExpressionWidget->setExpectedOutputFormat( text );
ProcessingModelChildParameterSource
Processing model child parameter sources.
@ ExpressionText
Parameter value is taken from a text with expressions, evaluated just before the algorithm runs.
@ ModelOutput
Parameter value is linked to an output parameter for the model.
@ ChildOutput
Parameter value is taken from an output generated by a child algorithm.
@ ModelParameter
Parameter value is taken from a parent model parameter.
@ StaticValue
Parameter value is a static value.
@ Expression
Parameter value is taken from an expression, evaluated just before the algorithm runs.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Single scope for storing variables and functions for use within a QgsExpressionContext.
QStringList functionNames() const
Retrieves a list of names of functions contained in the scope.
QStringList variableNames() const
Returns a list of variable names contained within the scope.
static QgsExpressionContextScope * processingModelAlgorithmScope(const QgsProcessingModelAlgorithm *model, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing model algorithm,...
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm,...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A widget which includes a line edit for entering expressions together with a button to open the expre...
void setExpression(const QString &expression)
Sets the current expression to show in the widget.
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
static QgsProcessingGuiRegistry * processingGuiRegistry()
Returns the global processing gui registry, used for registering the GUI behavior of processing algor...
Abstract base class for processing algorithms.
An interface for objects which can create Processing contexts.
Contains information about the context in which a processing algorithm is executed.
Base class for the definition of processing parameters.
virtual bool isDestination() const
Returns true if this parameter represents a file or layer destination, e.g.
Contains settings which reflect the context in which a Processing parameter widget is shown.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c