38#include <QStackedWidget>
42#include "moc_qgsprocessingmodelerparameterwidget.cpp"
44using namespace Qt::StringLiterals;
50 , mParameterDefinition( parameter )
53 setFocusPolicy( Qt::StrongFocus );
58 QHBoxLayout *hLayout =
new QHBoxLayout();
61 const QVariantList acceptedSourcesMetadata = mParameterDefinition->metadata().value( u
"model_widget"_s ).toMap().value( u
"accepted_sources"_s ).toList();
62 for (
const QVariant &acceptedSource : acceptedSourcesMetadata )
68 mSourceButton =
new QToolButton();
69 mSourceButton->setFocusPolicy( Qt::StrongFocus );
72 mSourceButton->setFixedSize( 2 *
static_cast<int>( 1.25 * iconSize / 2.0 ), 2 *
static_cast<int>( iconSize * 1.1 / 2.0 ) );
73 mSourceButton->setIconSize( QSize( iconSize, iconSize ) );
74 mSourceButton->setPopupMode( QToolButton::InstantPopup );
76 mSourceMenu =
new QMenu(
this );
77 connect( mSourceMenu, &QMenu::aboutToShow,
this, &QgsProcessingModelerParameterWidget::sourceMenuAboutToShow );
78 connect( mSourceMenu, &QMenu::triggered,
this, &QgsProcessingModelerParameterWidget::sourceMenuActionTriggered );
79 mSourceButton->setMenu( mSourceMenu );
81 hLayout->addWidget( mSourceButton );
83 mStackedWidget =
new QStackedWidget();
86 if ( mStaticWidgetWrapper )
88 QWidget *widget = mStaticWidgetWrapper->createWrappedWidget( context );
91 mHasStaticWrapper =
true;
92 mStackedWidget->addWidget( widget );
95 mStackedWidget->addWidget(
new QWidget() );
99 mStackedWidget->addWidget(
new QWidget() );
103 mExpressionWidget->registerExpressionContextGenerator(
this );
104 mStackedWidget->addWidget( mExpressionWidget );
106 mModelInputCombo =
new QComboBox();
107 QHBoxLayout *hLayout2 =
new QHBoxLayout();
108 hLayout2->setContentsMargins( 0, 0, 0, 0 );
109 hLayout2->addWidget(
new QLabel( tr(
"Using model input" ) ) );
110 hLayout2->addWidget( mModelInputCombo, 1 );
111 QWidget *hWidget2 =
new QWidget();
112 hWidget2->setLayout( hLayout2 );
113 mStackedWidget->addWidget( hWidget2 );
115 mChildOutputCombo =
new QComboBox();
116 QHBoxLayout *hLayout3 =
new QHBoxLayout();
117 hLayout3->setContentsMargins( 0, 0, 0, 0 );
118 hLayout3->addWidget(
new QLabel( tr(
"Using algorithm output" ) ) );
119 hLayout3->addWidget( mChildOutputCombo, 1 );
120 QWidget *hWidget3 =
new QWidget();
121 hWidget3->setLayout( hLayout3 );
122 mStackedWidget->addWidget( hWidget3 );
124 if ( mParameterDefinition->isDestination() )
127 mModelOutputName->setPlaceholderText( tr(
"[Enter name if this is a final result]" ) );
128 QHBoxLayout *hLayout4 =
new QHBoxLayout();
129 hLayout4->setContentsMargins( 0, 0, 0, 0 );
130 hLayout4->addWidget( mModelOutputName );
131 QWidget *hWidget4 =
new QWidget();
132 hWidget4->setLayout( hLayout4 );
133 mStackedWidget->addWidget( hWidget4 );
136 hLayout->setContentsMargins( 0, 0, 0, 0 );
137 hLayout->addWidget( mStackedWidget, 1 );
139 setLayout( hLayout );
147 if ( mStaticWidgetWrapper )
148 mStaticWidgetWrapper->setWidgetContext( context );
153 if ( mStaticWidgetWrapper )
154 mStaticWidgetWrapper->registerProcessingContextGenerator( generator );
159 return mParameterDefinition;
164 if ( mStaticWidgetWrapper )
165 return mStaticWidgetWrapper->createWrappedLabel();
174 mStaticValue =
value.staticValue();
175 mModelInputParameterName =
value.parameterName();
176 mOutputChildId =
value.outputChildId();
177 mOutputName =
value.outputName();
178 mExpression =
value.expression();
186 if ( values.size() == 1 )
191 for (
const QgsProcessingModelChildParameterSource &v : values )
192 r << QVariant::fromValue( v );
201 if ( mModelOutputName )
202 mModelOutputName->setText(
value );
208 return currentSourceType() == ModelOutput;
213 return mModelOutputName ? mModelOutputName->text().trimmed() : QString();
218 switch ( currentSourceType() )
222 const QVariant v = mStaticWidgetWrapper->parameterValue();
224 if ( v.userType() == QMetaType::Type::QVariantList )
226 const QVariantList vList = v.toList();
227 if ( std::all_of( vList.begin(), vList.end(), [](
const QVariant &val ) {
228 return val.userType() == qMetaTypeId<QgsProcessingModelChildParameterSource>();
234 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromStaticValue( v ) );
238 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromExpression( mExpressionWidget->expression() ) );
241 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromModelParameter( mModelInputCombo->currentData().toString() ) );
245 const QStringList parts = mChildOutputCombo->currentData().toStringList();
246 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromChildOutput( parts.value( 0, QString() ), parts.value( 1, QString() ) ) );
250 return mModelOutputName ? ( mModelOutputName->text().trimmed().isEmpty() ? QVariant() : mModelOutputName->text() ) : QVariant();
253 return QVariant::fromValue( QgsProcessingModelChildParameterSource() );
258 if ( mStaticWidgetWrapper )
259 mStaticWidgetWrapper->setDialog( dialog );
268 if ( mModel->childAlgorithms().contains( mChildId ) )
269 alg = mModel->childAlgorithm( mChildId ).algorithm();
274 QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( mChildId, mContext, QVariantMap(), QVariantMap() );
277 QStringList highlightedVariables = childScope->
variableNames();
278 QStringList highlightedFunctions = childScope->
functionNames();
280 highlightedVariables += mModel->variables().keys();
282 c.setHighlightedVariables( highlightedVariables );
283 c.setHighlightedFunctions( highlightedFunctions );
289void QgsProcessingModelerParameterWidget::sourceMenuAboutToShow()
291 mSourceMenu->clear();
293 const SourceType currentSource = currentSourceType();
298 QAction *modelOutputAction = mSourceMenu->addAction( tr(
"Model Output" ) );
299 modelOutputAction->setCheckable( currentSource == ModelOutput );
300 modelOutputAction->setChecked( currentSource == ModelOutput );
304 if ( mHasStaticWrapper
307 QAction *fixedValueAction = mSourceMenu->addAction( tr(
"Value" ) );
308 fixedValueAction->setCheckable( currentSource == StaticValue );
309 fixedValueAction->setChecked( currentSource == StaticValue );
315 QAction *calculatedValueAction = mSourceMenu->addAction( tr(
"Pre-calculated Value" ) );
316 calculatedValueAction->setCheckable( currentSource == Expression );
317 calculatedValueAction->setChecked( currentSource == Expression );
323 QAction *inputValueAction = mSourceMenu->addAction( tr(
"Model Input" ) );
324 inputValueAction->setCheckable( currentSource == ModelParameter );
325 inputValueAction->setChecked( currentSource == ModelParameter );
331 QAction *childOutputValueAction = mSourceMenu->addAction( tr(
"Algorithm Output" ) );
332 childOutputValueAction->setCheckable( currentSource == ChildOutput );
333 childOutputValueAction->setChecked( currentSource == ChildOutput );
340void QgsProcessingModelerParameterWidget::sourceMenuActionTriggered( QAction *action )
346QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
const
348 return static_cast<SourceType
>( mStackedWidget->currentIndex() );
353 if ( !mLimitedSources.empty() && !mLimitedSources.contains( type ) )
357 type = mLimitedSources.at( 0 );
363 mStackedWidget->setCurrentIndex(
static_cast<int>( StaticValue ) );
365 mSourceButton->setToolTip( tr(
"Value" ) );
370 mStackedWidget->setCurrentIndex(
static_cast<int>( Expression ) );
371 mSourceButton->setToolTip( tr(
"Pre-calculated Value" ) );
377 mStackedWidget->setCurrentIndex(
static_cast<int>( ModelParameter ) );
378 mSourceButton->setToolTip( tr(
"Model Input" ) );
385 mStackedWidget->setCurrentIndex(
static_cast<int>( ChildOutput ) );
386 mSourceButton->setToolTip( tr(
"Algorithm Output" ) );
393 mStackedWidget->setCurrentIndex(
static_cast<int>( ModelOutput ) );
394 mSourceButton->setToolTip( tr(
"Model Output" ) );
403void QgsProcessingModelerParameterWidget::updateUi()
405 mStaticWidgetWrapper->setParameterValue( mStaticValue, mContext );
409 int currentIndex = mModelInputCombo->findData( mModelInputParameterName );
410 if ( currentIndex == -1 && mModelInputCombo->count() > 0 )
412 mModelInputCombo->setCurrentIndex( currentIndex );
414 const QStringList parts = QStringList() << mOutputChildId << mOutputName;
415 currentIndex = mChildOutputCombo->findData( parts );
416 if ( currentIndex == -1 && mChildOutputCombo->count() > 0 )
418 mChildOutputCombo->setCurrentIndex( currentIndex );
423 QgsProcessingModelChildParameterSources sources = mModel->availableSourcesForChild( mChildId, compatibleParameterTypes, compatibleOutputTypes, compatibleDataTypes );
425 for (
const QgsProcessingModelChildParameterSource &source : sources )
427 switch ( source.source() )
430 mModelInputCombo->addItem( mModel->parameterDefinition( source.parameterName() )->description(), source.parameterName() );
435 if ( !mModel->childAlgorithms().contains( source.outputChildId() ) )
438 const QgsProcessingModelChildAlgorithm &alg = mModel->childAlgorithm( source.outputChildId() );
439 if ( !alg.algorithm() )
441 const QString outputDescription = alg.algorithm()->outputDefinition( source.outputName() )->description();
442 const QString childDescription = alg.description();
444 mChildOutputCombo->addItem( tr(
"“%1” from algorithm “%2”" ).arg( outputDescription, childDescription ), QStringList() << source.outputChildId() << source.outputName() );
459 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