mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Move algorithm expression context generation to QgsProcessingAlgorithm
Fix error when selecting "from expression" in algorithm parameter dialog
This commit is contained in:
parent
607fed8c48
commit
39d20a4cb4
@ -228,6 +228,15 @@ class QgsProcessingAlgorithm
|
||||
:rtype: QWidget
|
||||
%End
|
||||
|
||||
QgsExpressionContext createExpressionContext( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context ) const;
|
||||
%Docstring
|
||||
Creates an expression context relating to the algorithm. This can be called by algorithms
|
||||
to create a new expression context ready for evaluating expressions within the algorithm.
|
||||
:rtype: QgsExpressionContext
|
||||
%End
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/ );
|
||||
|
||||
@ -866,6 +866,14 @@ class QgsExpressionContextUtils
|
||||
:rtype: QgsExpressionContext
|
||||
%End
|
||||
|
||||
static QgsExpressionContextScope *processingAlgorithmScope( const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new scope which contains variables and functions relating to a processing ``algorithm``,
|
||||
when used with the specified ``parameters`` and ``context``.
|
||||
For instance, algorithm name and parameter functions.
|
||||
:rtype: QgsExpressionContextScope
|
||||
%End
|
||||
|
||||
static void registerContextFunctions();
|
||||
%Docstring
|
||||
Registers all known core functions provided by QgsExpressionContextScope objects.
|
||||
|
||||
@ -36,12 +36,14 @@ from qgis.PyQt.QtGui import QCursor
|
||||
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
|
||||
from qgis.core import (QgsDataSourceUri,
|
||||
QgsCredentials,
|
||||
QgsExpression,
|
||||
QgsSettings,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingFeatureSinkDefinition)
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.core.outputs import OutputDirectory
|
||||
from processing.tools.dataobjects import createContext
|
||||
from processing.gui.PostgisTableSelector import PostgisTableSelector
|
||||
from processing.gui.ParameterGuiUtils import getFileFilter
|
||||
|
||||
@ -122,11 +124,13 @@ class DestinationSelectionPanel(BASE, WIDGET):
|
||||
popupMenu.exec_(QCursor.pos())
|
||||
|
||||
def showExpressionsBuilder(self):
|
||||
context = self.alg.createExpressionContext({}, createContext())
|
||||
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, 'generic',
|
||||
self.parameter.expressionContext(self.alg))
|
||||
context)
|
||||
dlg.setWindowTitle(self.tr('Expression based output'))
|
||||
if dlg.exec_() == QDialog.Accepted:
|
||||
self.leText.setText(dlg.expressionText())
|
||||
expression = QgsExpression(dlg.expressionText())
|
||||
self.leText.setText(expression.evaluate(context))
|
||||
|
||||
def saveToTemporary(self):
|
||||
self.leText.setText('')
|
||||
|
||||
11
resources/function_help/json/parameter
Normal file
11
resources/function_help/json/parameter
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "parameter",
|
||||
"type": "function",
|
||||
"description": "Returns the value of a processing algorithm input parameter.",
|
||||
"arguments": [
|
||||
{"arg":"name", "description":"name of the corresponding input parameter"}
|
||||
],
|
||||
"examples": [
|
||||
{ "expression":"parameter('BUFFER_SIZE')", "returns":"5.6"}
|
||||
]
|
||||
}
|
||||
@ -685,6 +685,9 @@ void QgsExpression::initVariableHelp()
|
||||
//cluster variables
|
||||
sVariableHelpTexts.insert( QStringLiteral( "cluster_color" ), QCoreApplication::translate( "cluster_color", "Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
|
||||
sVariableHelpTexts.insert( QStringLiteral( "cluster_size" ), QCoreApplication::translate( "cluster_size", "Number of symbols contained within a cluster." ) );
|
||||
|
||||
//processing variables
|
||||
sVariableHelpTexts.insert( QStringLiteral( "algorithm_id" ), QCoreApplication::translate( "algorithm_id", "Unique ID for algorithm." ) );
|
||||
}
|
||||
|
||||
QString QgsExpression::variableHelpText( const QString &variableName, bool showValue, const QVariant &value )
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "qgsprocessingparameters.h"
|
||||
#include "qgsprocessingoutputs.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsprocessingcontext.h"
|
||||
|
||||
QgsProcessingAlgorithm::~QgsProcessingAlgorithm()
|
||||
{
|
||||
@ -100,6 +101,22 @@ QWidget *QgsProcessingAlgorithm::createCustomParametersWidget( QWidget * ) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpressionContext QgsProcessingAlgorithm::createExpressionContext( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context ) const
|
||||
{
|
||||
// start with context's expression context
|
||||
QgsExpressionContext c = context.expressionContext();
|
||||
if ( c.scopeCount() == 0 )
|
||||
{
|
||||
//empty scope, populate with initial scopes
|
||||
c << QgsExpressionContextUtils::globalScope()
|
||||
<< QgsExpressionContextUtils::projectScope( context.project() );
|
||||
}
|
||||
|
||||
c << QgsExpressionContextUtils::processingAlgorithmScope( this, parameters, context );
|
||||
return c;
|
||||
}
|
||||
|
||||
bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *definition )
|
||||
{
|
||||
if ( !definition )
|
||||
|
||||
@ -229,6 +229,14 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
||||
*/
|
||||
virtual QWidget *createCustomParametersWidget( QWidget *parent = nullptr ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates an expression context relating to the algorithm. This can be called by algorithms
|
||||
* to create a new expression context ready for evaluating expressions within the algorithm.
|
||||
*/
|
||||
QgsExpressionContext createExpressionContext( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context ) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgsmaplayerlistutils.h"
|
||||
#include "qgsprocessingcontext.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDir>
|
||||
@ -707,6 +709,30 @@ class GetLayerVisibility : public QgsScopedExpressionFunction
|
||||
|
||||
};
|
||||
|
||||
class GetProcessingParameterValue : public QgsScopedExpressionFunction
|
||||
{
|
||||
public:
|
||||
GetProcessingParameterValue( const QVariantMap ¶ms )
|
||||
: QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
|
||||
, mParams( params )
|
||||
{}
|
||||
|
||||
QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression * ) override
|
||||
{
|
||||
return mParams.value( values.at( 0 ).toString() );
|
||||
}
|
||||
|
||||
QgsScopedExpressionFunction *clone() const override
|
||||
{
|
||||
return new GetProcessingParameterValue( mParams );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const QVariantMap mParams;
|
||||
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
QgsExpressionContextScope *QgsExpressionContextUtils::projectScope( const QgsProject *project )
|
||||
@ -1077,11 +1103,29 @@ QgsExpressionContext QgsExpressionContextUtils::createFeatureBasedContext( const
|
||||
return QgsExpressionContext() << scope;
|
||||
}
|
||||
|
||||
QgsExpressionContextScope *QgsExpressionContextUtils::processingAlgorithmScope( const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context )
|
||||
{
|
||||
// set aside for future use
|
||||
Q_UNUSED( context );
|
||||
|
||||
std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
|
||||
if ( !algorithm )
|
||||
return scope.release();
|
||||
|
||||
//add standard algorithm variables
|
||||
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
|
||||
|
||||
scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
|
||||
|
||||
return scope.release();
|
||||
}
|
||||
|
||||
void QgsExpressionContextUtils::registerContextFunctions()
|
||||
{
|
||||
QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
|
||||
QgsExpression::registerFunction( new GetComposerItemVariables( nullptr ) );
|
||||
QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>() ) );
|
||||
QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
|
||||
}
|
||||
|
||||
bool QgsScopedExpressionFunction::usesGeometry( const QgsExpressionNodeFunction *node ) const
|
||||
|
||||
@ -36,6 +36,8 @@ class QgsAtlasComposition;
|
||||
class QgsMapSettings;
|
||||
class QgsProject;
|
||||
class QgsSymbol;
|
||||
class QgsProcessingAlgorithm;
|
||||
class QgsProcessingContext;
|
||||
|
||||
/** \ingroup core
|
||||
* \class QgsScopedExpressionFunction
|
||||
@ -788,6 +790,13 @@ class CORE_EXPORT QgsExpressionContextUtils
|
||||
*/
|
||||
static QgsExpressionContext createFeatureBasedContext( const QgsFeature &feature, const QgsFields &fields );
|
||||
|
||||
/**
|
||||
* Creates a new scope which contains variables and functions relating to a processing \a algorithm,
|
||||
* when used with the specified \a parameters and \a context.
|
||||
* For instance, algorithm name and parameter functions.
|
||||
*/
|
||||
static QgsExpressionContextScope *processingAlgorithmScope( const QgsProcessingAlgorithm *algorithm, const QVariantMap ¶meters, QgsProcessingContext &context ) SIP_FACTORY;
|
||||
|
||||
/** Registers all known core functions provided by QgsExpressionContextScope objects.
|
||||
*/
|
||||
static void registerContextFunctions();
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "qgspoint.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsexpressioncontext.h"
|
||||
|
||||
class DummyAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
@ -219,6 +220,7 @@ class TestQgsProcessing: public QObject
|
||||
void combineLayerExtent();
|
||||
void processingFeatureSource();
|
||||
void processingFeatureSink();
|
||||
void algorithmScope();
|
||||
|
||||
private:
|
||||
|
||||
@ -2425,5 +2427,29 @@ void TestQgsProcessing::processingFeatureSink()
|
||||
QCOMPARE( layer2->crs().authid(), QStringLiteral( "EPSG:3113" ) );
|
||||
}
|
||||
|
||||
void TestQgsProcessing::algorithmScope()
|
||||
{
|
||||
QgsProcessingContext pc;
|
||||
|
||||
// no alg
|
||||
std::unique_ptr< QgsExpressionContextScope > scope( QgsExpressionContextUtils::processingAlgorithmScope( nullptr, QVariantMap(), pc ) );
|
||||
QVERIFY( scope.get() );
|
||||
|
||||
// with alg
|
||||
std::unique_ptr< QgsProcessingAlgorithm > alg( new DummyAlgorithm( "alg1" ) );
|
||||
QVariantMap params;
|
||||
params.insert( QStringLiteral( "a_param" ), 5 );
|
||||
scope.reset( QgsExpressionContextUtils::processingAlgorithmScope( alg.get(), params, pc ) );
|
||||
QVERIFY( scope.get() );
|
||||
QCOMPARE( scope->variable( QStringLiteral( "algorithm_id" ) ).toString(), alg->id() );
|
||||
|
||||
QgsExpressionContext context;
|
||||
context.appendScope( scope.release() );
|
||||
QgsExpression exp( "parameter('bad')" );
|
||||
QVERIFY( !exp.evaluate( &context ).isValid() );
|
||||
QgsExpression exp2( "parameter('a_param')" );
|
||||
QCOMPARE( exp2.evaluate( &context ).toInt(), 5 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsProcessing )
|
||||
#include "testqgsprocessing.moc"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user