Add method to format processing output values as strings

This commit is contained in:
Nyall Dawson 2024-01-09 11:46:15 +10:00
parent 3e7d376953
commit b674a7c35d
5 changed files with 388 additions and 0 deletions

View File

@ -10,6 +10,8 @@
class QgsProcessingOutputDefinition
{
%Docstring(signature="appended")
@ -121,6 +123,19 @@ Returns ``True`` if the output was automatically created when adding a parameter
.. seealso:: :py:func:`setAutoCreated`
.. versionadded:: 3.14
%End
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
%Docstring
Returns a string version of the parameter output ``value`` (if possible).
:param value: value to convert
:param context: processing context
:return: - value converted to string
- ok: will be set to ``True`` if value could be represented as a string.
.. versionadded:: 3.36
%End
protected:
@ -159,6 +174,7 @@ Returns the type name for the output class.
virtual QString type() const;
};
class QgsProcessingOutputVectorLayer : QgsProcessingOutputDefinition
@ -284,6 +300,9 @@ Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputHtml : QgsProcessingOutputDefinition
@ -336,6 +355,9 @@ Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputNumber : QgsProcessingOutputDefinition
@ -361,6 +383,9 @@ Constructor for QgsProcessingOutputNumber.
Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputString : QgsProcessingOutputDefinition
@ -411,6 +436,8 @@ Constructor for :py:class:`QgsProcessingOutputNumber`.
Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputFolder : QgsProcessingOutputDefinition

View File

@ -10,6 +10,8 @@
class QgsProcessingOutputDefinition
{
%Docstring(signature="appended")
@ -121,6 +123,19 @@ Returns ``True`` if the output was automatically created when adding a parameter
.. seealso:: :py:func:`setAutoCreated`
.. versionadded:: 3.14
%End
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
%Docstring
Returns a string version of the parameter output ``value`` (if possible).
:param value: value to convert
:param context: processing context
:return: - value converted to string
- ok: will be set to ``True`` if value could be represented as a string.
.. versionadded:: 3.36
%End
protected:
@ -159,6 +174,7 @@ Returns the type name for the output class.
virtual QString type() const;
};
class QgsProcessingOutputVectorLayer : QgsProcessingOutputDefinition
@ -284,6 +300,9 @@ Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputHtml : QgsProcessingOutputDefinition
@ -336,6 +355,9 @@ Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputNumber : QgsProcessingOutputDefinition
@ -361,6 +383,9 @@ Constructor for QgsProcessingOutputNumber.
Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputString : QgsProcessingOutputDefinition
@ -411,6 +436,8 @@ Constructor for :py:class:`QgsProcessingOutputNumber`.
Returns the type name for the output class.
%End
virtual QString type() const;
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const;
};
class QgsProcessingOutputFolder : QgsProcessingOutputDefinition

View File

@ -16,12 +16,30 @@
***************************************************************************/
#include "qgsprocessingoutputs.h"
#include "qgsvariantutils.h"
QgsProcessingOutputDefinition::QgsProcessingOutputDefinition( const QString &name, const QString &description )
: mName( name )
, mDescription( description )
{}
QString QgsProcessingOutputDefinition::valueAsString( const QVariant &value, QgsProcessingContext &, bool &ok ) const
{
if ( QgsVariantUtils::isNull( value ) )
{
ok = true;
return QObject::tr( "NULL" );
}
if ( value.type() == QVariant::String )
{
ok = true;
return value.toString();
}
ok = false;
return QString();
}
QgsProcessingOutputVectorLayer::QgsProcessingOutputVectorLayer( const QString &name, const QString &description, QgsProcessing::SourceType type )
: QgsProcessingOutputDefinition( name, description )
, mDataType( type )
@ -57,6 +75,24 @@ QgsProcessingOutputNumber::QgsProcessingOutputNumber( const QString &name, const
: QgsProcessingOutputDefinition( name, description )
{}
QString QgsProcessingOutputNumber::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
{
ok = false;
switch ( value.type() )
{
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
ok = true;
return value.toString();
default:
break;
}
return QgsProcessingOutputDefinition::valueAsString( value, context, ok );
}
QgsProcessingOutputString::QgsProcessingOutputString( const QString &name, const QString &description )
: QgsProcessingOutputDefinition( name, description )
{}
@ -65,6 +101,17 @@ QgsProcessingOutputBoolean::QgsProcessingOutputBoolean( const QString &name, con
: QgsProcessingOutputDefinition( name, description )
{}
QString QgsProcessingOutputBoolean::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
{
ok = false;
if ( value.type() == QVariant::Bool )
{
ok = true;
return value.toBool() ? QObject::tr( "True" ) : QObject::tr( "False" );
}
return QgsProcessingOutputDefinition::valueAsString( value, context, ok );
}
QgsProcessingOutputFolder::QgsProcessingOutputFolder( const QString &name, const QString &description )
: QgsProcessingOutputDefinition( name, description )
{}
@ -91,6 +138,37 @@ QString QgsProcessingOutputMultipleLayers::type() const
return typeName();
}
QString QgsProcessingOutputMultipleLayers::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
{
ok = false;
switch ( value.type() )
{
case QVariant::List:
{
ok = true;
const QVariantList list = value.toList();
QStringList layerNames;
for ( const QVariant &v : list )
{
layerNames << v.toString();
}
return layerNames.join( QStringLiteral( ", " ) );
}
case QVariant::StringList:
{
ok = true;
const QStringList list = value.toStringList();
return list.join( QStringLiteral( ", " ) );
}
default:
break;
}
return QgsProcessingOutputDefinition::valueAsString( value, context, ok );
}
QgsProcessingOutputConditionalBranch::QgsProcessingOutputConditionalBranch( const QString &name, const QString &description )
: QgsProcessingOutputDefinition( name, description )
{}
@ -105,3 +183,45 @@ QString QgsProcessingOutputVariant::type() const
{
return typeName();
}
QString QgsProcessingOutputVariant::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
{
ok = false;
switch ( value.type() )
{
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
ok = true;
return value.toString();
case QVariant::Bool:
ok = true;
return value.toBool() ? QObject::tr( "True" ) : QObject::tr( "False" );
case QVariant::List:
{
ok = true;
const QVariantList list = value.toList();
QStringList names;
for ( const QVariant &v : list )
{
names << v.toString();
}
return names.join( QStringLiteral( ", " ) );
}
case QVariant::StringList:
{
ok = true;
const QStringList list = value.toStringList();
return list.join( QStringLiteral( ", " ) );
}
default:
break;
}
return QgsProcessingOutputDefinition::valueAsString( value, context, ok );
}

View File

@ -21,6 +21,9 @@
#include "qgis_core.h"
#include "qgis.h"
#include "qgsprocessing.h"
class QgsProcessingContext;
//
// Output definitions
//
@ -132,6 +135,18 @@ class CORE_EXPORT QgsProcessingOutputDefinition
*/
bool autoCreated() const { return mAutoCreated; }
/**
* Returns a string version of the parameter output \a value (if possible).
*
* \param value value to convert
* \param context processing context
* \param ok will be set to TRUE if value could be represented as a string.
* \returns value converted to string
*
* \since QGIS 3.36
*/
virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const;
protected:
//! Output name
@ -171,6 +186,7 @@ class CORE_EXPORT QgsProcessingOutputMapLayer : public QgsProcessingOutputDefini
static QString typeName() { return QStringLiteral( "outputLayer" ); }
QString type() const override;
};
/**
@ -282,6 +298,8 @@ class CORE_EXPORT QgsProcessingOutputMultipleLayers : public QgsProcessingOutput
*/
static QString typeName() { return QStringLiteral( "outputMultilayer" ); }
QString type() const override;
QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const override;
};
/**
@ -327,6 +345,8 @@ class CORE_EXPORT QgsProcessingOutputVariant : public QgsProcessingOutputDefinit
*/
static QString typeName() { return QStringLiteral( "outputVariant" ); }
QString type() const override;
QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const override;
};
/**
@ -349,6 +369,8 @@ class CORE_EXPORT QgsProcessingOutputNumber : public QgsProcessingOutputDefiniti
*/
static QString typeName() { return QStringLiteral( "outputNumber" ); }
QString type() const override { return typeName(); }
QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const override;
};
/**
@ -393,6 +415,7 @@ class CORE_EXPORT QgsProcessingOutputBoolean : public QgsProcessingOutputDefinit
*/
static QString typeName() { return QStringLiteral( "outputBoolean" ); }
QString type() const override { return typeName(); }
QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const override;
};
/**

View File

@ -818,6 +818,7 @@ class TestQgsProcessing: public QgsTest
void formatHelp();
void preprocessParameters();
void guiDefaultParameterValues();
void testOutputs();
private:
@ -12782,5 +12783,195 @@ void TestQgsProcessing::guiDefaultParameterValues()
s.remove( QStringLiteral( "/Processing/DefaultGuiParam/testAlgorithm/testStringParameter" ) );
}
void TestQgsProcessing::testOutputs()
{
QgsProcessingContext context;
bool ok = false;
QgsProcessingOutputVectorLayer outputVectorLayer( QStringLiteral( "vl" ) );
QCOMPARE( outputVectorLayer.valueAsString( QStringLiteral( "/home/test/test.shp" ), context, ok ),
QStringLiteral( "/home/test/test.shp" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVectorLayer.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputRasterLayer outputRasterLayer( QStringLiteral( "rl" ) );
QCOMPARE( outputRasterLayer.valueAsString( QStringLiteral( "/home/test/test.tiff" ), context, ok ),
QStringLiteral( "/home/test/test.tiff" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputRasterLayer.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputPointCloudLayer outputPointCloudLayer( QStringLiteral( "pcl" ) );
QCOMPARE( outputPointCloudLayer.valueAsString( QStringLiteral( "/home/test/test.laz" ), context, ok ),
QStringLiteral( "/home/test/test.laz" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputPointCloudLayer.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputVectorTileLayer outputVectorTileLayer( QStringLiteral( "vtl" ) );
QCOMPARE( outputVectorTileLayer.valueAsString( QStringLiteral( "/home/test/test.mbtiles" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVectorTileLayer.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputMapLayer outputMapLayer( QStringLiteral( "ml" ) );
QCOMPARE( outputMapLayer.valueAsString( QStringLiteral( "/home/test/test.mbtiles" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputMapLayer.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputMultipleLayers outputMultipleLayers( QStringLiteral( "ml" ) );
QCOMPARE( outputMultipleLayers.valueAsString( QStringLiteral( "/home/test/test.mbtiles" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputMultipleLayers.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
QCOMPARE( outputMultipleLayers.valueAsString( QStringList() << QStringLiteral( "/home/test/test.mbtiles" )
<< QStringLiteral( "/home/test/test.shp" )
<< QStringLiteral( "/home/test/test.tif" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles, /home/test/test.shp, /home/test/test.tif" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputMultipleLayers.valueAsString( QVariantList() << QStringLiteral( "/home/test/test.mbtiles" )
<< QStringLiteral( "/home/test/test.shp" )
<< QStringLiteral( "/home/test/test.tif" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles, /home/test/test.shp, /home/test/test.tif" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputHtml outputHtml( QStringLiteral( "html" ) );
QCOMPARE( outputHtml.valueAsString( QStringLiteral( "/home/test/test.html" ), context, ok ),
QStringLiteral( "/home/test/test.html" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputHtml.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputFile outputFile( QStringLiteral( "file" ) );
QCOMPARE( outputFile.valueAsString( QStringLiteral( "/home/test/test.txt" ), context, ok ),
QStringLiteral( "/home/test/test.txt" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputFile.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputFolder outputFolder( QStringLiteral( "folder" ) );
QCOMPARE( outputFolder.valueAsString( QStringLiteral( "/home/test" ), context, ok ),
QStringLiteral( "/home/test" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputFolder.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputNumber outputNumber( QStringLiteral( "number" ) );
QCOMPARE( outputNumber.valueAsString( QStringLiteral( "xxx" ), context, ok ),
QStringLiteral( "xxx" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputNumber.valueAsString( 5, context, ok ),
QStringLiteral( "5" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputNumber.valueAsString( 5.5, context, ok ),
QStringLiteral( "5.5" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputNumber.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputString outputString( QStringLiteral( "string" ) );
QCOMPARE( outputString.valueAsString( QStringLiteral( "lalala" ), context, ok ),
QStringLiteral( "lalala" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputString.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputBoolean outputBoolean( QStringLiteral( "string" ) );
QCOMPARE( outputBoolean.valueAsString( QStringLiteral( "lalala" ), context, ok ),
QStringLiteral( "lalala" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputBoolean.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputBoolean.valueAsString( QVariant( true ), context, ok ),
QStringLiteral( "True" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputBoolean.valueAsString( QVariant( false ), context, ok ),
QStringLiteral( "False" ) );
QVERIFY( ok );
ok = false;
QgsProcessingOutputVariant outputVariant( QStringLiteral( "variant" ) );
QCOMPARE( outputVariant.valueAsString( QStringLiteral( "lalala" ), context, ok ),
QStringLiteral( "lalala" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( QVariant(), context, ok ),
QStringLiteral( "NULL" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( QVariant( true ), context, ok ),
QStringLiteral( "True" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( QVariant( false ), context, ok ),
QStringLiteral( "False" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( 5, context, ok ),
QStringLiteral( "5" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( 5.5, context, ok ),
QStringLiteral( "5.5" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( QStringList() << QStringLiteral( "/home/test/test.mbtiles" )
<< QStringLiteral( "/home/test/test.shp" )
<< QStringLiteral( "/home/test/test.tif" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles, /home/test/test.shp, /home/test/test.tif" ) );
QVERIFY( ok );
ok = false;
QCOMPARE( outputVariant.valueAsString( QVariantList() << QStringLiteral( "/home/test/test.mbtiles" )
<< QStringLiteral( "/home/test/test.shp" )
<< QStringLiteral( "/home/test/test.tif" ), context, ok ),
QStringLiteral( "/home/test/test.mbtiles, /home/test/test.shp, /home/test/test.tif" ) );
QVERIFY( ok );
ok = false;
}
QGSTEST_MAIN( TestQgsProcessing )
#include "testqgsprocessing.moc"