mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-16 00:05:45 -04:00
Cleaner approach -- create expression contexts in modeler parameter
definition dialogs using expression context and processing context generators
This commit is contained in:
parent
5a9e8c6290
commit
814b65ba1c
@ -12,7 +12,8 @@
|
||||
|
||||
|
||||
|
||||
class QgsProcessingAbstractParameterDefinitionWidget : QWidget
|
||||
|
||||
class QgsProcessingAbstractParameterDefinitionWidget : QWidget, QgsExpressionContextGenerator
|
||||
{
|
||||
%Docstring
|
||||
Abstract base class for widgets which allow users to specify the properties of a
|
||||
@ -53,6 +54,42 @@ Common properties for parameters, including the ``name``, ``description``, and p
|
||||
method. Subclass implementations must use these properties when crafting a parameter definition which
|
||||
also respects the additional properties specific to the parameter type handled by the widget subclass.
|
||||
%End
|
||||
|
||||
virtual void setWidgetContext( const QgsProcessingParameterWidgetContext &context );
|
||||
%Docstring
|
||||
Sets the ``context`` in which the Processing definition widget is shown, e.g., the
|
||||
parent model algorithm, a linked map canvas, and other relevant information which allows the widget
|
||||
to fine-tune its behavior.
|
||||
|
||||
Subclasses should take care to call the base class method when reimplementing this method.
|
||||
|
||||
.. seealso:: :py:func:`widgetContext`
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
const QgsProcessingParameterWidgetContext &widgetContext() const;
|
||||
%Docstring
|
||||
Returns the context in which the Processing definition widget is shown, e.g., the
|
||||
parent model algorithm, a linked map canvas, and other relevant information which allows the widget
|
||||
to fine-tune its behavior.
|
||||
|
||||
.. seealso:: :py:func:`setWidgetContext`
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
%Docstring
|
||||
Registers a Processing context ``generator`` class that will be used to retrieve
|
||||
a Processing context for the widget when required.
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
virtual QgsExpressionContext createExpressionContext() const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -96,6 +133,14 @@ associated with the parameter.
|
||||
Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
|
||||
The ``name`` parameter specifies the name for the newly created parameter.
|
||||
%End
|
||||
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
%Docstring
|
||||
Registers a Processing context ``generator`` class that will be used to retrieve
|
||||
a Processing context for the widget when required.
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
};
|
||||
@ -181,6 +226,14 @@ Returns the color for the comments for the parameter.
|
||||
void switchToCommentTab();
|
||||
%Docstring
|
||||
Switches the dialog to the comments tab.
|
||||
%End
|
||||
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
%Docstring
|
||||
Registers a Processing context ``generator`` class that will be used to retrieve
|
||||
a Processing context for the widget when required.
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
@ -127,15 +127,6 @@ 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 );
|
||||
|
@ -40,12 +40,13 @@ from qgis.core import (Qgis,
|
||||
QgsProcessing,
|
||||
QgsProject,
|
||||
QgsProcessingModelParameter,
|
||||
QgsSettings
|
||||
QgsSettings,
|
||||
)
|
||||
from qgis.gui import (QgsProcessingParameterDefinitionDialog,
|
||||
QgsProcessingParameterWidgetContext,
|
||||
QgsModelGraphicsScene,
|
||||
QgsModelDesignerDialog)
|
||||
QgsModelDesignerDialog,
|
||||
QgsProcessingContextGenerator)
|
||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
@ -105,6 +106,19 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
|
||||
self.view().centerOn(0, 0)
|
||||
|
||||
self.processing_context = createContext()
|
||||
|
||||
class ContextGenerator(QgsProcessingContextGenerator):
|
||||
|
||||
def __init__(self, context):
|
||||
super().__init__()
|
||||
self.processing_context = context
|
||||
|
||||
def processingContext(self):
|
||||
return self.processing_context
|
||||
|
||||
self.context_generator = ContextGenerator(self.processing_context)
|
||||
|
||||
def editHelp(self):
|
||||
alg = self.model()
|
||||
dlg = HelpEditionDialog(alg)
|
||||
@ -270,6 +284,7 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
context=context,
|
||||
widgetContext=widget_context,
|
||||
algorithm=self.model())
|
||||
dlg.registerProcessingContextGenerator(self.context_generator)
|
||||
if dlg.exec_():
|
||||
new_param = dlg.createParameter()
|
||||
self.autogenerate_parameter_name(new_param)
|
||||
|
@ -31,7 +31,8 @@ from qgis.gui import (
|
||||
QgsProcessingParameterWidgetContext,
|
||||
QgsModelParameterGraphicItem,
|
||||
QgsModelChildAlgorithmGraphicItem,
|
||||
QgsModelOutputGraphicItem
|
||||
QgsModelOutputGraphicItem,
|
||||
QgsProcessingContextGenerator
|
||||
)
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||
@ -50,6 +51,19 @@ class ModelerInputGraphicItem(QgsModelParameterGraphicItem):
|
||||
def __init__(self, element, model):
|
||||
super().__init__(element, model, None)
|
||||
|
||||
self.processing_context = createContext()
|
||||
|
||||
class ContextGenerator(QgsProcessingContextGenerator):
|
||||
|
||||
def __init__(self, context):
|
||||
super().__init__()
|
||||
self.processing_context = context
|
||||
|
||||
def processingContext(self):
|
||||
return self.processing_context
|
||||
|
||||
self.context_generator = ContextGenerator(self.processing_context)
|
||||
|
||||
def create_widget_context(self):
|
||||
"""
|
||||
Returns a new widget context for use in the model editor
|
||||
@ -91,6 +105,8 @@ class ModelerInputGraphicItem(QgsModelParameterGraphicItem):
|
||||
algorithm=self.model())
|
||||
dlg.setComments(comment)
|
||||
dlg.setCommentColor(comment_color)
|
||||
dlg.registerProcessingContextGenerator(self.context_generator)
|
||||
|
||||
if edit_comment:
|
||||
dlg.switchToCommentTab()
|
||||
|
||||
|
@ -34,14 +34,35 @@
|
||||
#include <QTextEdit>
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget::QgsProcessingAbstractParameterDefinitionWidget( QgsProcessingContext &,
|
||||
const QgsProcessingParameterWidgetContext &,
|
||||
const QgsProcessingParameterWidgetContext &context,
|
||||
const QgsProcessingParameterDefinition *,
|
||||
const QgsProcessingAlgorithm *, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mWidgetContext( context )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QgsProcessingAbstractParameterDefinitionWidget::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
|
||||
{
|
||||
mWidgetContext = context;
|
||||
}
|
||||
|
||||
const QgsProcessingParameterWidgetContext &QgsProcessingAbstractParameterDefinitionWidget::widgetContext() const
|
||||
{
|
||||
return mWidgetContext;
|
||||
}
|
||||
|
||||
void QgsProcessingAbstractParameterDefinitionWidget::registerProcessingContextGenerator( QgsProcessingContextGenerator *generator )
|
||||
{
|
||||
mContextGenerator = generator;
|
||||
}
|
||||
|
||||
QgsExpressionContext QgsProcessingAbstractParameterDefinitionWidget::createExpressionContext() const
|
||||
{
|
||||
return QgsProcessingGuiUtils::createExpressionContext( mContextGenerator, mWidgetContext, nullptr, nullptr );
|
||||
}
|
||||
|
||||
//
|
||||
// QgsProcessingParameterDefinitionWidget
|
||||
//
|
||||
@ -120,6 +141,14 @@ QgsProcessingParameterDefinition *QgsProcessingParameterDefinitionWidget::create
|
||||
return param.release();
|
||||
}
|
||||
|
||||
void QgsProcessingParameterDefinitionWidget::registerProcessingContextGenerator( QgsProcessingContextGenerator *generator )
|
||||
{
|
||||
if ( mDefinitionWidget )
|
||||
{
|
||||
mDefinitionWidget->registerProcessingContextGenerator( generator );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// QgsProcessingParameterDefinitionDialog
|
||||
//
|
||||
@ -210,6 +239,14 @@ void QgsProcessingParameterDefinitionDialog::switchToCommentTab()
|
||||
mCommentEdit->selectAll();
|
||||
}
|
||||
|
||||
void QgsProcessingParameterDefinitionDialog::registerProcessingContextGenerator( QgsProcessingContextGenerator *generator )
|
||||
{
|
||||
if ( mWidget )
|
||||
{
|
||||
mWidget->registerProcessingContextGenerator( generator );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsProcessingParameterDefinitionDialog::accept()
|
||||
{
|
||||
if ( mWidget->mDescriptionLineEdit->text().isEmpty() )
|
||||
|
@ -25,8 +25,11 @@
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgsprocessingparameters.h"
|
||||
#include "qgsexpressioncontextgenerator.h"
|
||||
#include "qgsprocessingwidgetwrapper.h"
|
||||
|
||||
class QgsProcessingContextGenerator;
|
||||
|
||||
class QgsProcessingParameterWidgetContext;
|
||||
class QLineEdit;
|
||||
class QCheckBox;
|
||||
class QTabWidget;
|
||||
@ -40,7 +43,7 @@ class QgsColorButton;
|
||||
* \ingroup gui
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class GUI_EXPORT QgsProcessingAbstractParameterDefinitionWidget : public QWidget
|
||||
class GUI_EXPORT QgsProcessingAbstractParameterDefinitionWidget : public QWidget, public QgsExpressionContextGenerator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -73,6 +76,43 @@ class GUI_EXPORT QgsProcessingAbstractParameterDefinitionWidget : public QWidget
|
||||
* also respects the additional properties specific to the parameter type handled by the widget subclass.
|
||||
*/
|
||||
virtual QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const = 0 SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Sets the \a context in which the Processing definition widget is shown, e.g., the
|
||||
* parent model algorithm, a linked map canvas, and other relevant information which allows the widget
|
||||
* to fine-tune its behavior.
|
||||
*
|
||||
* Subclasses should take care to call the base class method when reimplementing this method.
|
||||
*
|
||||
* \see widgetContext()
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
virtual void setWidgetContext( const QgsProcessingParameterWidgetContext &context );
|
||||
|
||||
/**
|
||||
* Returns the context in which the Processing definition widget is shown, e.g., the
|
||||
* parent model algorithm, a linked map canvas, and other relevant information which allows the widget
|
||||
* to fine-tune its behavior.
|
||||
*
|
||||
* \see setWidgetContext()
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
const QgsProcessingParameterWidgetContext &widgetContext() const;
|
||||
|
||||
/**
|
||||
* Registers a Processing context \a generator class that will be used to retrieve
|
||||
* a Processing context for the widget when required.
|
||||
*
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
|
||||
private:
|
||||
|
||||
QgsProcessingContextGenerator *mContextGenerator = nullptr;
|
||||
QgsProcessingParameterWidgetContext mWidgetContext;
|
||||
};
|
||||
|
||||
|
||||
@ -117,6 +157,14 @@ class GUI_EXPORT QgsProcessingParameterDefinitionWidget: public QWidget
|
||||
*/
|
||||
QgsProcessingParameterDefinition *createParameter( const QString &name = QString() ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Registers a Processing context \a generator class that will be used to retrieve
|
||||
* a Processing context for the widget when required.
|
||||
*
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
|
||||
private:
|
||||
|
||||
QString mType;
|
||||
@ -203,6 +251,14 @@ class GUI_EXPORT QgsProcessingParameterDefinitionDialog: public QDialog
|
||||
*/
|
||||
void switchToCommentTab();
|
||||
|
||||
/**
|
||||
* Registers a Processing context \a generator class that will be used to retrieve
|
||||
* a Processing context for the widget when required.
|
||||
*
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
void registerProcessingContextGenerator( QgsProcessingContextGenerator *generator );
|
||||
|
||||
public slots:
|
||||
void accept() override;
|
||||
|
||||
|
@ -1841,18 +1841,13 @@ 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();
|
||||
if ( mModel )
|
||||
{
|
||||
QgsExpressionContext expressionContext = createExpressionContext( context, algorithm );
|
||||
mDefaultLineEdit->setExpressionContext( expressionContext );
|
||||
}
|
||||
mDefaultLineEdit->registerExpressionContextGenerator( this );
|
||||
|
||||
if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
|
||||
mDefaultLineEdit->setExpression( QgsProcessingParameters::parameterAsExpression( expParam, expParam->defaultValueForGui(), context ) );
|
||||
vlayout->addWidget( mDefaultLineEdit );
|
||||
@ -1866,14 +1861,13 @@ QgsProcessingExpressionParameterDefinitionWidget::QgsProcessingExpressionParamet
|
||||
if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
|
||||
initialParent = expParam->parentLayerParameterName();
|
||||
|
||||
|
||||
if ( mModel )
|
||||
if ( QgsProcessingModelAlgorithm *model = widgetContext.model() )
|
||||
{
|
||||
// populate combo box with other model input choices
|
||||
const QMap<QString, QgsProcessingModelParameter> components = mModel->parameterComponents();
|
||||
const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
|
||||
for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
|
||||
{
|
||||
if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( mModel->parameterDefinition( it.value().parameterName() ) ) )
|
||||
if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( model->parameterDefinition( it.value().parameterName() ) ) )
|
||||
{
|
||||
mParentLayerComboBox-> addItem( definition->description(), definition->name() );
|
||||
if ( !initialParent.isEmpty() && initialParent == definition->name() )
|
||||
@ -1881,7 +1875,7 @@ QgsProcessingExpressionParameterDefinitionWidget::QgsProcessingExpressionParamet
|
||||
mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
|
||||
}
|
||||
}
|
||||
else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( mModel->parameterDefinition( it.value().parameterName() ) ) )
|
||||
else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( model->parameterDefinition( it.value().parameterName() ) ) )
|
||||
{
|
||||
mParentLayerComboBox-> addItem( definition->description(), definition->name() );
|
||||
if ( !initialParent.isEmpty() && initialParent == definition->name() )
|
||||
@ -1907,46 +1901,9 @@ 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 )
|
||||
{
|
||||
|
@ -66,8 +66,6 @@ class QgsProcessingMapLayerComboBox;
|
||||
class QgsRasterBandComboBox;
|
||||
class QgsProcessingLayerOutputDestinationWidget;
|
||||
class QgsCheckableComboBox;
|
||||
class QgsProcessingModelAlgorithm;
|
||||
class QgsExpressionContext;
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
@ -635,13 +633,11 @@ 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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -132,13 +132,6 @@ 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:
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user