mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
[processing] Add new parameter type for print layout names
This commit is contained in:
parent
5ec43cfdc1
commit
dd49720863
@ -183,6 +183,8 @@ their acceptable ranges, defaults, etc.
|
||||
sipType = sipType_QgsProcessingParameterFolderDestination;
|
||||
else if ( sipCpp->type() == QgsProcessingParameterBand::typeName() )
|
||||
sipType = sipType_QgsProcessingParameterBand;
|
||||
else if ( sipCpp->type() == QgsProcessingParameterLayout::typeName() )
|
||||
sipType = sipType_QgsProcessingParameterLayout;
|
||||
else
|
||||
sipType = nullptr;
|
||||
%End
|
||||
@ -2747,6 +2749,49 @@ Sets whether multiple band selections are permitted.
|
||||
|
||||
};
|
||||
|
||||
class QgsProcessingParameterLayout : QgsProcessingParameterDefinition
|
||||
{
|
||||
%Docstring
|
||||
A print layout parameter, allowing users to select a print layout.
|
||||
|
||||
QgsProcessingParameterLayout should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsString()`
|
||||
This will return the name of the target print layout.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingparameters.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingParameterLayout( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
|
||||
bool optional = false );
|
||||
%Docstring
|
||||
Constructor for QgsProcessingParameterLayout.
|
||||
%End
|
||||
|
||||
static QString typeName();
|
||||
%Docstring
|
||||
Returns the type name for the parameter class.
|
||||
%End
|
||||
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
|
||||
|
||||
virtual QString type() const;
|
||||
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
|
||||
|
||||
virtual QString asScriptCode() const;
|
||||
|
||||
virtual QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const;
|
||||
|
||||
|
||||
static QgsProcessingParameterLayout *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new parameter using the definition from a script code.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1519,6 +1519,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromVariantM
|
||||
def.reset( new QgsProcessingParameterBand( name ) );
|
||||
else if ( type == QgsProcessingParameterMeshLayer::typeName() )
|
||||
def.reset( new QgsProcessingParameterMeshLayer( name ) );
|
||||
else if ( type == QgsProcessingParameterLayout::typeName() )
|
||||
def.reset( new QgsProcessingParameterLayout( name ) );
|
||||
else
|
||||
{
|
||||
QgsProcessingParameterType *paramType = QgsApplication::instance()->processingRegistry()->parameterType( type );
|
||||
@ -1603,6 +1605,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCo
|
||||
return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
|
||||
else if ( type == QStringLiteral( "mesh" ) )
|
||||
return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
|
||||
else if ( type == QStringLiteral( "layout" ) )
|
||||
return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -5198,3 +5202,73 @@ bool QgsProcessingParameterDistance::fromVariantMap( const QVariantMap &map )
|
||||
mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsProcessingParameterLayout
|
||||
//
|
||||
|
||||
QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
|
||||
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
|
||||
{}
|
||||
|
||||
QgsProcessingParameterDefinition *QgsProcessingParameterLayout::clone() const
|
||||
{
|
||||
return new QgsProcessingParameterLayout( *this );
|
||||
}
|
||||
|
||||
QString QgsProcessingParameterLayout::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
|
||||
{
|
||||
if ( !value.isValid() || value.isNull() )
|
||||
return QStringLiteral( "None" );
|
||||
|
||||
if ( value.canConvert<QgsProperty>() )
|
||||
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
|
||||
|
||||
QString s = value.toString();
|
||||
return QgsProcessingUtils::stringToPythonLiteral( s );
|
||||
}
|
||||
|
||||
QString QgsProcessingParameterLayout::asScriptCode() const
|
||||
{
|
||||
QString code = QStringLiteral( "##%1=" ).arg( mName );
|
||||
if ( mFlags & FlagOptional )
|
||||
code += QStringLiteral( "optional " );
|
||||
code += QStringLiteral( "layout " );
|
||||
|
||||
code += mDefault.toString();
|
||||
return code.trimmed();
|
||||
}
|
||||
|
||||
QString QgsProcessingParameterLayout::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
|
||||
{
|
||||
switch ( outputType )
|
||||
{
|
||||
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
|
||||
{
|
||||
QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', '%2'" ).arg( name(), description() );
|
||||
if ( mFlags & FlagOptional )
|
||||
code += QStringLiteral( ", optional=True" );
|
||||
QgsProcessingContext c;
|
||||
code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
|
||||
{
|
||||
QString def = definition;
|
||||
|
||||
if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
|
||||
def = def.mid( 1 );
|
||||
if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
|
||||
def.chop( 1 );
|
||||
|
||||
QVariant defaultValue = def;
|
||||
if ( def == QStringLiteral( "None" ) )
|
||||
defaultValue = QVariant();
|
||||
|
||||
return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
|
||||
}
|
||||
|
@ -258,6 +258,8 @@ class CORE_EXPORT QgsProcessingParameterDefinition
|
||||
sipType = sipType_QgsProcessingParameterFolderDestination;
|
||||
else if ( sipCpp->type() == QgsProcessingParameterBand::typeName() )
|
||||
sipType = sipType_QgsProcessingParameterBand;
|
||||
else if ( sipCpp->type() == QgsProcessingParameterLayout::typeName() )
|
||||
sipType = sipType_QgsProcessingParameterLayout;
|
||||
else
|
||||
sipType = nullptr;
|
||||
SIP_END
|
||||
@ -2582,6 +2584,43 @@ class CORE_EXPORT QgsProcessingParameterBand : public QgsProcessingParameterDefi
|
||||
bool mAllowMultiple = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class QgsProcessingParameterLayout
|
||||
* \ingroup core
|
||||
* A print layout parameter, allowing users to select a print layout.
|
||||
*
|
||||
* QgsProcessingParameterLayout should be evaluated by calling QgsProcessingAlgorithm::parameterAsString().
|
||||
* This will return the name of the target print layout.
|
||||
*
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
class CORE_EXPORT QgsProcessingParameterLayout : public QgsProcessingParameterDefinition
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsProcessingParameterLayout.
|
||||
*/
|
||||
QgsProcessingParameterLayout( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
|
||||
bool optional = false );
|
||||
|
||||
/**
|
||||
* Returns the type name for the parameter class.
|
||||
*/
|
||||
static QString typeName() { return QStringLiteral( "layout" ); }
|
||||
QgsProcessingParameterDefinition *clone() const override SIP_FACTORY;
|
||||
QString type() const override { return typeName(); }
|
||||
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
|
||||
QString asScriptCode() const override;
|
||||
QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const override;
|
||||
|
||||
/**
|
||||
* Creates a new parameter using the definition from a script code.
|
||||
*/
|
||||
static QgsProcessingParameterLayout *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;
|
||||
|
||||
};
|
||||
|
||||
// clazy:excludeall=qstring-allocations
|
||||
|
||||
#endif // QGSPROCESSINGPARAMETERS_H
|
||||
|
@ -1458,4 +1458,57 @@ class CORE_EXPORT QgsProcessingParameterTypeFeatureSink : public QgsProcessingPa
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A print layout parameter for Processing algorithms.
|
||||
*
|
||||
* \ingroup core
|
||||
* \note No Python bindings available. Get your copy from QgsApplication.processingRegistry().parameterType('layout')
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
class CORE_EXPORT QgsProcessingParameterTypeLayout : public QgsProcessingParameterType
|
||||
{
|
||||
QgsProcessingParameterDefinition *create( const QString &name ) const override SIP_FACTORY
|
||||
{
|
||||
return new QgsProcessingParameterLayout( name );
|
||||
}
|
||||
|
||||
QString description() const override
|
||||
{
|
||||
return QCoreApplication::translate( "Processing", "A print layout parameter." );
|
||||
}
|
||||
|
||||
QString name() const override
|
||||
{
|
||||
return QCoreApplication::translate( "Processing", "Print Layout" );
|
||||
}
|
||||
|
||||
QString id() const override
|
||||
{
|
||||
return QStringLiteral( "layout" );
|
||||
}
|
||||
|
||||
QString pythonImportString() const override
|
||||
{
|
||||
return QStringLiteral( "from qgis.core import QgsProcessingParameterLayout" );
|
||||
}
|
||||
|
||||
QString className() const override
|
||||
{
|
||||
return QStringLiteral( "QgsProcessingParameterLayout" );
|
||||
}
|
||||
|
||||
QStringList acceptedPythonTypes() const override
|
||||
{
|
||||
return QStringList() << QObject::tr( "str: name of print layout in current project" )
|
||||
<< QStringLiteral( "QgsProperty" );
|
||||
}
|
||||
|
||||
QStringList acceptedStringValues() const override
|
||||
{
|
||||
return QStringList() << QObject::tr( "Name of print layout in current project" );
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
#endif // QGSPROCESSINGPARAMETERTYPEIMPL_H
|
||||
|
@ -48,6 +48,7 @@ QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
|
||||
addParameterType( new QgsProcessingParameterTypeDistance() );
|
||||
addParameterType( new QgsProcessingParameterTypeBand() );
|
||||
addParameterType( new QgsProcessingParameterTypeFeatureSink() );
|
||||
addParameterType( new QgsProcessingParameterTypeLayout() );
|
||||
}
|
||||
|
||||
QgsProcessingRegistry::~QgsProcessingRegistry()
|
||||
|
@ -558,6 +558,7 @@ class TestQgsProcessing: public QObject
|
||||
void parameterFileOut();
|
||||
void parameterFolderOut();
|
||||
void parameterBand();
|
||||
void parameterLayout();
|
||||
void checkParamValues();
|
||||
void combineLayerExtent();
|
||||
void processingFeatureSource();
|
||||
@ -5810,6 +5811,122 @@ void TestQgsProcessing::parameterBand()
|
||||
QCOMPARE( fromCode->parentLayerParameterName(), def->parentLayerParameterName() );
|
||||
}
|
||||
|
||||
void TestQgsProcessing::parameterLayout()
|
||||
{
|
||||
QgsProcessingContext context;
|
||||
|
||||
// not optional!
|
||||
std::unique_ptr< QgsProcessingParameterLayout > def( new QgsProcessingParameterLayout( "non_optional", QString(), QString(), false ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( 1 ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( "test" ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( "" ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
|
||||
|
||||
// string
|
||||
QVariantMap params;
|
||||
params.insert( "non_optional", QString( "abcdef" ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsString( def.get(), params, context ), QString( "abcdef" ) );
|
||||
|
||||
QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) );
|
||||
QCOMPARE( def->valueAsPythonString( 5, context ), QStringLiteral( "'5'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc" ), context ), QStringLiteral( "'abc'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc\ndef" ), context ), QStringLiteral( "'abc\\ndef'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) );
|
||||
|
||||
QString pythonCode = def->asPythonString();
|
||||
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterLayout('non_optional', '', defaultValue=None)" ) );
|
||||
|
||||
QString code = def->asScriptCode();
|
||||
QCOMPARE( code, QStringLiteral( "##non_optional=layout" ) );
|
||||
std::unique_ptr< QgsProcessingParameterLayout > fromCode( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( code ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue(), def->defaultValue() );
|
||||
|
||||
QVariantMap map = def->toVariantMap();
|
||||
QgsProcessingParameterLayout fromMap( "x" );
|
||||
QVERIFY( fromMap.fromVariantMap( map ) );
|
||||
QCOMPARE( fromMap.name(), def->name() );
|
||||
QCOMPARE( fromMap.description(), def->description() );
|
||||
QCOMPARE( fromMap.flags(), def->flags() );
|
||||
QCOMPARE( fromMap.defaultValue(), def->defaultValue() );
|
||||
def.reset( dynamic_cast< QgsProcessingParameterLayout *>( QgsProcessingParameters::parameterFromVariantMap( map ) ) );
|
||||
QVERIFY( dynamic_cast< QgsProcessingParameterLayout *>( def.get() ) );
|
||||
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( QStringLiteral( "##non_optional=layout None" ) ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QVERIFY( !fromCode->defaultValue().isValid() );
|
||||
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( QStringLiteral( "##non_optional=layout it's mario" ) ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue().toString(), QStringLiteral( "it's mario" ) );
|
||||
|
||||
def->setDefaultValue( QStringLiteral( "it's mario" ) );
|
||||
pythonCode = def->asPythonString();
|
||||
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterLayout('non_optional', '', defaultValue='it\\'s mario')" ) );
|
||||
|
||||
code = def->asScriptCode();
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( code ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue(), def->defaultValue() );
|
||||
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( QStringLiteral( "##non_optional=layout 'my val'" ) ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue().toString(), QStringLiteral( "my val" ) );
|
||||
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( QStringLiteral( "##non_optional=layout \"my val\"" ) ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "non optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue().toString(), QStringLiteral( "my val" ) );
|
||||
|
||||
// optional
|
||||
def.reset( new QgsProcessingParameterLayout( "optional", QString(), QString( "default" ), true ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( 1 ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( "test" ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( "" ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );
|
||||
|
||||
params.insert( "optional", QVariant() );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsString( def.get(), params, context ), QString( "default" ) );
|
||||
params.insert( "optional", QString() ); //empty string should not result in default value
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsString( def.get(), params, context ), QString() );
|
||||
|
||||
pythonCode = def->asPythonString();
|
||||
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterLayout('optional', '', optional=True, defaultValue='default')" ) );
|
||||
code = def->asScriptCode();
|
||||
QCOMPARE( code, QStringLiteral( "##optional=optional layout default" ) );
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterLayout * >( QgsProcessingParameters::parameterFromScriptCode( code ) ) );
|
||||
QVERIFY( fromCode.get() );
|
||||
QCOMPARE( fromCode->name(), def->name() );
|
||||
QCOMPARE( fromCode->description(), QStringLiteral( "optional" ) );
|
||||
QCOMPARE( fromCode->flags(), def->flags() );
|
||||
QCOMPARE( fromCode->defaultValue(), def->defaultValue() );
|
||||
|
||||
// not optional, valid default!
|
||||
def.reset( new QgsProcessingParameterLayout( "non_optional", QString(), QString( "def" ), false ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( 1 ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( "test" ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( "" ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( QVariant() ) ); // should be valid, falls back to valid default
|
||||
}
|
||||
|
||||
void TestQgsProcessing::checkParamValues()
|
||||
{
|
||||
DummyAlgorithm a( "asd" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user