Skip to content

Commit

Permalink
Add a pure virtual clone method to processing parameter definitions
Browse files Browse the repository at this point in the history
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.
52 changes: 52 additions & 0 deletions python/core/processing/qgsprocessingparameters.sip
Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
4 changes: 4 additions & 0 deletions python/plugins/processing/algs/gdal/buildvrt.py
Expand Up @@ -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'

Expand Down
4 changes: 4 additions & 0 deletions python/plugins/processing/algs/qgis/Aggregate.py
Expand Up @@ -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'

Expand Down
12 changes: 5 additions & 7 deletions python/plugins/processing/algs/qgis/FieldsMapper.py
Expand Up @@ -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

Expand All @@ -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'

Expand Down
4 changes: 4 additions & 0 deletions python/plugins/processing/algs/qgis/Heatmap.py
Expand Up @@ -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,
Expand Down
26 changes: 15 additions & 11 deletions src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -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() );
}
}
}
Expand Down Expand Up @@ -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 );
}
Expand All @@ -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();
Expand Down

0 comments on commit 37b899f

Please sign in to comment.