Skip to content
Permalink
Browse files
Add a pure virtual clone method to processing parameter definitions
And use it when we need to clone parameters (instead of more fragile
conversion to and from variants)

This fixes model loading which use algorithms which create python
subclasses of parameter definitions
  • Loading branch information
nyalldawson committed Aug 17, 2017
1 parent 251354e commit 37b899f
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 18 deletions.
@@ -213,6 +213,12 @@ class QgsProcessingParameterDefinition

virtual ~QgsProcessingParameterDefinition();

virtual QgsProcessingParameterDefinition *clone() const = 0 /Factory/;
%Docstring
Creates a clone of the parameter definition.
:rtype: QgsProcessingParameterDefinition
%End

virtual QString type() const = 0;
%Docstring
Unique parameter type name.
@@ -620,6 +626,8 @@ class QgsProcessingParameterBoolean : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;

@@ -656,6 +664,8 @@ class QgsProcessingParameterCrs : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -693,6 +703,8 @@ class QgsProcessingParameterMapLayer : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -730,6 +742,8 @@ class QgsProcessingParameterExtent : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -768,6 +782,8 @@ class QgsProcessingParameterPoint : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -809,6 +825,8 @@ class QgsProcessingParameterFile : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -879,6 +897,8 @@ class QgsProcessingParameterMatrix : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -967,6 +987,8 @@ class QgsProcessingParameterMultipleLayers : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1050,6 +1072,8 @@ class QgsProcessingParameterNumber : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1133,6 +1157,8 @@ class QgsProcessingParameterRange : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1188,6 +1214,8 @@ class QgsProcessingParameterRasterLayer : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1227,6 +1255,8 @@ class QgsProcessingParameterEnum : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1298,6 +1328,8 @@ class QgsProcessingParameterString : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;

@@ -1354,6 +1386,8 @@ class QgsProcessingParameterExpression : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;

@@ -1413,6 +1447,8 @@ class QgsProcessingParameterVectorLayer : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1479,6 +1515,8 @@ class QgsProcessingParameterField : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1565,6 +1603,8 @@ class QgsProcessingParameterFeatureSource : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1704,6 +1744,8 @@ class QgsProcessingParameterFeatureSink : QgsProcessingDestinationParameter
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1781,6 +1823,8 @@ class QgsProcessingParameterVectorDestination : QgsProcessingDestinationParamete
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1852,6 +1896,8 @@ class QgsProcessingParameterRasterDestination : QgsProcessingDestinationParamete
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1895,6 +1941,8 @@ class QgsProcessingParameterFileDestination : QgsProcessingDestinationParameter
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1958,6 +2006,8 @@ class QgsProcessingParameterFolderDestination : QgsProcessingDestinationParamete
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -1998,6 +2048,8 @@ class QgsProcessingParameterBand : QgsProcessingParameterDefinition
Returns the type name for the parameter class.
:rtype: str
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

@@ -63,6 +63,10 @@ class ParameterVrtDestination(QgsProcessingParameterRasterDestination):
def __init__(self, name, description):
super().__init__(name, description)

def clone(self):
copy = ParameterVrtDestination(self.name(), self.description())
return copy

def type(self):
return 'vrt_destination'

@@ -78,6 +78,10 @@ def __init__(self, name, description, parentLayerParameterName='INPUT'):
super().__init__(name, description)
self._parentLayerParameter = parentLayerParameterName

def clone(self):
copy = ParameterAggregates(self.name(), self.description(), self._parentLayerParameter)
return copy

def type(self):
return 'aggregates'

@@ -26,18 +26,12 @@
__revision__ = '$Format:%H$'

from qgis.core import (
QgsApplication,
QgsDistanceArea,
QgsExpression,
QgsFeature,
QgsFeatureSink,
QgsField,
QgsFields,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingUtils,
QgsProject,
)
QgsProcessingParameterDefinition)

from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm

@@ -59,6 +53,10 @@ def __init__(self, name, description, parentLayerParameterName='INPUT'):
super().__init__(name, description)
self._parentLayerParameter = parentLayerParameterName

def clone(self):
copy = ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
return copy

def type(self):
return 'fields_mapping'

@@ -116,6 +116,10 @@ def __init__(self, name='', description='', parent_layer=None, radius_param=None
self.radius_param = radius_param
self.radius_field_param = radius_field_param

def clone(self):
copy = ParameterHeatmapPixelSize(self.name(), self.description(), self.parent_layer, self.radius_param, self.radius_field_param, self.minimum(), self.maximum(), self.defaultValue((), self.flags() & QgsProcessingParameterDefinition.FlagOptional))
return copy

pixel_size_param = ParameterHeatmapPixelSize(self.PIXEL_SIZE,
self.tr('Output raster size'),
parent_layer=self.INPUT,
@@ -729,19 +729,19 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
if ( !source )
continue;

QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( source->toVariantMap() );
std::unique_ptr< QgsProcessingParameterDefinition > param( source->clone() );
param->setName( outputIt->childId() + ':' + outputIt->name() );
param->setDescription( outputIt->description() );
addParameter( param );

if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter *>( param ) )
if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter *>( param.get() ) )
{
QgsProcessingOutputDefinition *output = destParam->toOutputDefinition();
std::unique_ptr< QgsProcessingOutputDefinition > output( destParam->toOutputDefinition() );
if ( output )
{
addOutput( output );
addOutput( output.release() );
}
}
addParameter( param.release() );
}
}
}
@@ -793,8 +793,11 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
for ( ; childIt != childMap.constEnd(); ++childIt )
{
QgsProcessingModelChildAlgorithm child;
// we be leniant here - even if we couldn't load a parameter, don't interrupt the model loading
// otherwise models may become unusable (e.g. due to removed plugins providing algs/parameters)
// with no way for users to repair them
if ( !child.loadVariant( childIt.value() ) )
return false;
continue;

mChildAlgorithms.insert( child.childId(), child );
}
@@ -817,11 +820,12 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
{
QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( paramDefIt.value().toMap() );
if ( !param )
return false;

addParameter( param );
std::unique_ptr< QgsProcessingParameterDefinition > param( QgsProcessingParameters::parameterFromVariantMap( paramDefIt.value().toMap() ) );
// we be leniant here - even if we couldn't load a parameter, don't interrupt the model loading
// otherwise models may become unusable (e.g. due to removed plugins providing algs/parameters)
// with no way for users to repair them
if ( param )
addParameter( param.release() );
}

updateDestinationParameters();

0 comments on commit 37b899f

Please sign in to comment.