Skip to content

Commit

Permalink
Fixes #39137
Browse files Browse the repository at this point in the history
  • Loading branch information
roya0045 authored and nyalldawson committed Jan 14, 2021
1 parent 6daf9ef commit 6ea2ff5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
9 changes: 9 additions & 0 deletions python/gui/auto_generated/qgsexpressionlineedit.sip.in
Expand Up @@ -127,6 +127,15 @@ an expression context for the widget.
create an expression context when required.
%End

void setExpressionContext( QgsExpressionContext &context );
%Docstring
Set a default expression context. Will be used if no QgsEcpressionContextGenerator or layer is set.

:param context: The QgsExpressionContext to use.

.. versionadded:: 3.18
%End

signals:

void expressionChanged( const QString &expression );
Expand Down
53 changes: 48 additions & 5 deletions src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp
Expand Up @@ -59,6 +59,8 @@
#include "qgsrasterbandcombobox.h"
#include "qgsprocessingoutputdestinationwidget.h"
#include "qgscheckablecombobox.h"
#include "qgsexpressioncontext.h"
#include "qgsexpressioncontextutils.h"
#include <QToolButton>
#include <QLabel>
#include <QHBoxLayout>
Expand Down Expand Up @@ -1839,12 +1841,15 @@ QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFileWidgetWrapper::
QgsProcessingExpressionParameterDefinitionWidget::QgsProcessingExpressionParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
: QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
{
mModel = widgetContext.model();

QVBoxLayout *vlayout = new QVBoxLayout();
vlayout->setContentsMargins( 0, 0, 0, 0 );

vlayout->addWidget( new QLabel( tr( "Default value" ) ) );

mDefaultLineEdit = new QgsExpressionLineEdit();
QgsExpressionContext expressionContext = createExpressionContext( context, algorithm );
mDefaultLineEdit->setExpressionContext( expressionContext );
if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
mDefaultLineEdit->setExpression( QgsProcessingParameters::parameterAsExpression( expParam, expParam->defaultValueForGui(), context ) );
vlayout->addWidget( mDefaultLineEdit );
Expand All @@ -1858,21 +1863,22 @@ QgsProcessingExpressionParameterDefinitionWidget::QgsProcessingExpressionParamet
if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
initialParent = expParam->parentLayerParameterName();

if ( auto *lModel = widgetContext.model() )

if ( mModel )
{
// populate combo box with other model input choices
const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
const QMap<QString, QgsProcessingModelParameter> components = mModel->parameterComponents();
for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
{
if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( lModel->parameterDefinition( it.value().parameterName() ) ) )
if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( mModel->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 * >( lModel->parameterDefinition( it.value().parameterName() ) ) )
else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( mModel->parameterDefinition( it.value().parameterName() ) ) )
{
mParentLayerComboBox-> addItem( definition->description(), definition->name() );
if ( !initialParent.isEmpty() && initialParent == definition->name() )
Expand All @@ -1898,9 +1904,46 @@ QgsProcessingParameterDefinition *QgsProcessingExpressionParameterDefinitionWidg
{
auto param = qgis::make_unique< QgsProcessingParameterExpression >( name, description, mDefaultLineEdit->expression(), mParentLayerComboBox->currentData().toString() );
param->setFlags( flags );
if ( mModel )
{
QStringList extraVars = mModel->variables().keys();
param->setAdditionalExpressionContextVariables( extraVars );
}
return param.release();
}

QgsExpressionContext QgsProcessingExpressionParameterDefinitionWidget::createExpressionContext( QgsProcessingContext &context, const QgsProcessingAlgorithm *algorithm ) const
{
QgsExpressionContext finalContext = context.expressionContext();
QString childId;

QgsExpressionContextScope *algScope = QgsExpressionContextUtils::processingAlgorithmScope( algorithm, QVariantMap(), context );
finalContext.appendScope( algScope );

QgsExpressionContextScope *modelScope = QgsExpressionContextUtils::processingModelAlgorithmScope( mModel, QVariantMap(), context );
finalContext << modelScope;
const QgsProcessingAlgorithm *childAlg = nullptr;
if ( mModel->childAlgorithms().contains( childId ) )
childAlg = mModel->childAlgorithm( childId ).algorithm();
QgsExpressionContextScope *algorithmScope = QgsExpressionContextUtils::processingAlgorithmScope( childAlg, QVariantMap(), context );
finalContext << algorithmScope;

QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( childId, context, QVariantMap(), QVariantMap() );
finalContext << childScope;

QStringList highlightedVariables = childScope->variableNames();
QStringList highlightedFunctions = childScope->functionNames();
highlightedVariables += algorithmScope->variableNames();
highlightedVariables += algScope->variableNames();
highlightedVariables += mModel->variables().keys();
highlightedFunctions += algScope->functionNames();
highlightedFunctions += algorithmScope->functionNames();
finalContext.setHighlightedVariables( highlightedVariables );
finalContext.setHighlightedFunctions( highlightedFunctions );

return finalContext;
}

QgsProcessingExpressionWidgetWrapper::QgsProcessingExpressionWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
: QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
{
Expand Down
5 changes: 5 additions & 0 deletions src/gui/processing/qgsprocessingwidgetwrapperimpl.h
Expand Up @@ -66,6 +66,8 @@ class QgsProcessingMapLayerComboBox;
class QgsRasterBandComboBox;
class QgsProcessingLayerOutputDestinationWidget;
class QgsCheckableComboBox;
class QgsProcessingModelAlgorithm;
class QgsExpressionContext;

///@cond PRIVATE

Expand Down Expand Up @@ -633,11 +635,13 @@ class GUI_EXPORT QgsProcessingExpressionParameterDefinitionWidget : public QgsPr
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;
QgsExpressionContext createExpressionContext( QgsProcessingContext &context, const QgsProcessingAlgorithm *algorithm ) const;

private:

QComboBox *mParentLayerComboBox = nullptr;
QgsExpressionLineEdit *mDefaultLineEdit = nullptr;
QgsProcessingModelAlgorithm *mModel = nullptr;

};

Expand All @@ -662,6 +666,7 @@ class GUI_EXPORT QgsProcessingExpressionWidgetWrapper : public QgsAbstractProces
// QgsProcessingParameterWidgetWrapper interface
QWidget *createWidget() override SIP_FACTORY;
void postInitialize( const QList< QgsAbstractProcessingParameterWidgetWrapper * > &wrappers ) override;

public slots:
void setParentLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper );
protected:
Expand Down
7 changes: 7 additions & 0 deletions src/gui/qgsexpressionlineedit.h
Expand Up @@ -132,6 +132,13 @@ class GUI_EXPORT QgsExpressionLineEdit : public QWidget
*/
void registerExpressionContextGenerator( const QgsExpressionContextGenerator *generator );

/**
* Set a default expression context. Will be used if no QgsEcpressionContextGenerator or layer is set.
* \param context The QgsExpressionContext to use.
* \since QGIS 3.18
*/
void setExpressionContext( QgsExpressionContext &context ) { mExpressionContext = context; }

signals:

/**
Expand Down

0 comments on commit 6ea2ff5

Please sign in to comment.