23 #include "models/qgsprocessingmodelalgorithm.h"
30 #include <QHBoxLayout>
31 #include <QToolButton>
32 #include <QStackedWidget>
38 const QString &childId,
44 , mParameterDefinition( parameter )
47 setFocusPolicy( Qt::StrongFocus );
52 QHBoxLayout *hLayout =
new QHBoxLayout();
54 mSourceButton =
new QToolButton();
55 mSourceButton->setFocusPolicy( Qt::StrongFocus );
58 mSourceButton->setFixedSize( 2 *
static_cast< int >( 1.25 *
iconSize / 2.0 ), 2 *
static_cast< int >(
iconSize * 1.1 / 2.0 ) );
60 mSourceButton->setPopupMode( QToolButton::InstantPopup );
62 mSourceMenu =
new QMenu(
this );
63 connect( mSourceMenu, &QMenu::aboutToShow,
this, &QgsProcessingModelerParameterWidget::sourceMenuAboutToShow );
64 connect( mSourceMenu, &QMenu::triggered,
this, &QgsProcessingModelerParameterWidget::sourceMenuActionTriggered );
65 mSourceButton->setMenu( mSourceMenu );
67 hLayout->addWidget( mSourceButton );
69 mStackedWidget =
new QStackedWidget();
72 if ( mStaticWidgetWrapper )
74 QWidget *widget = mStaticWidgetWrapper->createWrappedWidget( context );
77 mHasStaticWrapper =
true;
78 mStackedWidget->addWidget( widget );
81 mStackedWidget->addWidget(
new QWidget() );
85 mStackedWidget->addWidget(
new QWidget() );
90 mStackedWidget->addWidget( mExpressionWidget );
92 mModelInputCombo =
new QComboBox();
93 QHBoxLayout *hLayout2 =
new QHBoxLayout();
94 hLayout2->setContentsMargins( 0, 0, 0, 0 );
95 hLayout2->addWidget(
new QLabel( tr(
"Using model input" ) ) );
96 hLayout2->addWidget( mModelInputCombo, 1 );
97 QWidget *hWidget2 =
new QWidget();
98 hWidget2->setLayout( hLayout2 );
99 mStackedWidget->addWidget( hWidget2 );
101 mChildOutputCombo =
new QComboBox();
102 QHBoxLayout *hLayout3 =
new QHBoxLayout();
103 hLayout3->setContentsMargins( 0, 0, 0, 0 );
104 hLayout3->addWidget(
new QLabel( tr(
"Using algorithm output" ) ) );
105 hLayout3->addWidget( mChildOutputCombo, 1 );
106 QWidget *hWidget3 =
new QWidget();
107 hWidget3->setLayout( hLayout3 );
108 mStackedWidget->addWidget( hWidget3 );
113 mModelOutputName->setPlaceholderText( tr(
"[Enter name if this is a final result]" ) );
114 QHBoxLayout *hLayout4 =
new QHBoxLayout();
115 hLayout4->setContentsMargins( 0, 0, 0, 0 );
116 hLayout4->addWidget( mModelOutputName );
117 QWidget *hWidget4 =
new QWidget();
118 hWidget4->setLayout( hLayout4 );
119 mStackedWidget->addWidget( hWidget4 );
122 hLayout->setContentsMargins( 0, 0, 0, 0 );
123 hLayout->addWidget( mStackedWidget, 1 );
125 setLayout( hLayout );
126 setSourceType( mParameterDefinition->
isDestination() ? QgsProcessingModelChildParameterSource::ModelOutput : QgsProcessingModelChildParameterSource::StaticValue );
133 if ( mStaticWidgetWrapper )
134 mStaticWidgetWrapper->setWidgetContext( context );
139 if ( mStaticWidgetWrapper )
140 mStaticWidgetWrapper->registerProcessingContextGenerator( generator );
145 return mParameterDefinition;
150 if ( mStaticWidgetWrapper )
151 return mStaticWidgetWrapper->createWrappedLabel();
160 mStaticValue =
value.staticValue();
161 mModelInputParameterName =
value.parameterName();
162 mOutputChildId =
value.outputChildId();
163 mOutputName =
value.outputName();
164 mExpression =
value.expression();
167 setSourceType(
value.source() );
172 if ( values.size() == 1 )
177 for (
const QgsProcessingModelChildParameterSource &v : values )
178 r << QVariant::fromValue( v );
181 setSourceType( QgsProcessingModelChildParameterSource::StaticValue );
187 if ( mModelOutputName )
188 mModelOutputName->setText(
value );
189 setSourceType( QgsProcessingModelChildParameterSource::ModelOutput );
194 return currentSourceType() == ModelOutput;
199 return mModelOutputName ? mModelOutputName->text().trimmed() : QString();
204 switch ( currentSourceType() )
208 const QVariant v = mStaticWidgetWrapper->parameterValue();
210 if ( v.type() == QVariant::List )
212 const QVariantList vList = v.toList();
213 if ( std::all_of( vList.begin(), vList.end(), [](
const QVariant & val )
215 return val.canConvert< QgsProcessingModelChildParameterSource >();
221 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromStaticValue( v ) );
225 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromExpression( mExpressionWidget->
expression() ) );
228 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromModelParameter( mModelInputCombo->currentData().toString() ) );
232 const QStringList parts = mChildOutputCombo->currentData().toStringList();
233 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromChildOutput( parts.value( 0, QString() ), parts.value( 1, QString() ) ) );
237 return mModelOutputName ? ( mModelOutputName->text().trimmed().isEmpty() ? QVariant() : mModelOutputName->text() ) : QVariant();
240 return QVariant::fromValue( QgsProcessingModelChildParameterSource() );
245 if ( mStaticWidgetWrapper )
246 mStaticWidgetWrapper->setDialog( dialog );
255 if ( mModel->childAlgorithms().contains( mChildId ) )
256 alg = mModel->childAlgorithm( mChildId ).algorithm();
261 QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( mChildId, mContext, QVariantMap(), QVariantMap() );
264 QStringList highlightedVariables = childScope->
variableNames();
265 QStringList highlightedFunctions = childScope->
functionNames();
267 highlightedVariables += mModel->variables().keys();
269 c.setHighlightedVariables( highlightedVariables );
270 c.setHighlightedFunctions( highlightedFunctions );
276 void QgsProcessingModelerParameterWidget::sourceMenuAboutToShow()
278 mSourceMenu->clear();
280 const SourceType currentSource = currentSourceType();
284 QAction *modelOutputAction = mSourceMenu->addAction( tr(
"Model Output" ) );
285 modelOutputAction->setCheckable( currentSource == ModelOutput );
286 modelOutputAction->setChecked( currentSource == ModelOutput );
287 modelOutputAction->setData( QgsProcessingModelChildParameterSource::ModelOutput );
290 if ( mHasStaticWrapper )
292 QAction *fixedValueAction = mSourceMenu->addAction( tr(
"Value" ) );
293 fixedValueAction->setCheckable( currentSource == StaticValue );
294 fixedValueAction->setChecked( currentSource == StaticValue );
295 fixedValueAction->setData( QgsProcessingModelChildParameterSource::StaticValue );
298 QAction *calculatedValueAction = mSourceMenu->addAction( tr(
"Pre-calculated Value" ) );
299 calculatedValueAction->setCheckable( currentSource == Expression );
300 calculatedValueAction->setChecked( currentSource == Expression );
301 calculatedValueAction->setData( QgsProcessingModelChildParameterSource::Expression );
303 QAction *inputValueAction = mSourceMenu->addAction( tr(
"Model Input" ) );
304 inputValueAction->setCheckable( currentSource == ModelParameter );
305 inputValueAction->setChecked( currentSource == ModelParameter );
306 inputValueAction->setData( QgsProcessingModelChildParameterSource::ModelParameter );
308 QAction *childOutputValueAction = mSourceMenu->addAction( tr(
"Algorithm Output" ) );
309 childOutputValueAction->setCheckable( currentSource == ChildOutput );
310 childOutputValueAction->setChecked( currentSource == ChildOutput );
311 childOutputValueAction->setData( QgsProcessingModelChildParameterSource::ChildOutput );
316 void QgsProcessingModelerParameterWidget::sourceMenuActionTriggered( QAction *action )
318 QgsProcessingModelChildParameterSource::Source sourceType =
static_cast< QgsProcessingModelChildParameterSource::Source
>( action->data().toInt() );
319 setSourceType( sourceType );
322 QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
const
324 return static_cast< SourceType
>( mStackedWidget->currentIndex() );
327 void QgsProcessingModelerParameterWidget::setSourceType( QgsProcessingModelChildParameterSource::Source type )
331 case QgsProcessingModelChildParameterSource::StaticValue:
332 mStackedWidget->setCurrentIndex(
static_cast< int >( StaticValue ) );
334 mSourceButton->setToolTip( tr(
"Value" ) );
337 case QgsProcessingModelChildParameterSource::Expression:
339 mStackedWidget->setCurrentIndex(
static_cast< int >( Expression ) );
340 mSourceButton->setToolTip( tr(
"Pre-calculated Value" ) );
343 case QgsProcessingModelChildParameterSource::ModelParameter:
346 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelParameter ) );
347 mSourceButton->setToolTip( tr(
"Model Input" ) );
351 case QgsProcessingModelChildParameterSource::ChildOutput:
354 mStackedWidget->setCurrentIndex(
static_cast< int >( ChildOutput ) );
355 mSourceButton->setToolTip( tr(
"Algorithm Output" ) );
359 case QgsProcessingModelChildParameterSource::ModelOutput:
362 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelOutput ) );
363 mSourceButton->setToolTip( tr(
"Model Output" ) );
367 case QgsProcessingModelChildParameterSource::ExpressionText:
372 void QgsProcessingModelerParameterWidget::updateUi()
374 mStaticWidgetWrapper->setParameterValue( mStaticValue, mContext );
378 int currentIndex = mModelInputCombo->findData( mModelInputParameterName );
379 if ( currentIndex == -1 && mModelInputCombo->count() > 0 )
381 mModelInputCombo->setCurrentIndex( currentIndex );
383 const QStringList parts = QStringList() << mOutputChildId << mOutputName;
384 currentIndex = mChildOutputCombo->findData( parts );
385 if ( currentIndex == -1 && mChildOutputCombo->count() > 0 )
387 mChildOutputCombo->setCurrentIndex( currentIndex );
392 const QList< QgsProcessingModelChildParameterSource > sources = mModel->availableSourcesForChild( mChildId,
393 compatibleParameterTypes, compatibleOutputTypes, compatibleDataTypes );
395 for (
const QgsProcessingModelChildParameterSource &source : sources )
397 switch ( source.source() )
399 case QgsProcessingModelChildParameterSource::ModelParameter:
400 mModelInputCombo->addItem( mModel->parameterDefinition( source.parameterName() )->description(), source.parameterName() );
403 case QgsProcessingModelChildParameterSource::ChildOutput:
405 if ( !mModel->childAlgorithms().contains( source.outputChildId() ) )
408 const QgsProcessingModelChildAlgorithm &alg = mModel->childAlgorithm( source.outputChildId() );
409 if ( !alg.algorithm() )
411 const QString outputDescription = alg.algorithm()->outputDefinition( source.outputName() )->description();
412 const QString childDescription = alg.description();
414 mChildOutputCombo->addItem( tr(
"“%1” from algorithm “%2”" ).arg( outputDescription, childDescription ), QStringList() << source.outputChildId() << source.outputName() );
418 case QgsProcessingModelChildParameterSource::StaticValue:
419 case QgsProcessingModelChildParameterSource::Expression:
420 case QgsProcessingModelChildParameterSource::ExpressionText:
421 case QgsProcessingModelChildParameterSource::ModelOutput:
static QIcon getThemeIcon(const QString &name)
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...
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
QString expression() const
Returns the current expression shown in the widget.
void registerExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void setExpectedOutputFormat(const QString &expected)
Set the expected format string, which is shown in the expression builder dialog for the widget.
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.
QgsExpressionContext & expressionContext()
Returns the expression context.
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,...
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
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