Skip to content

Commit 37b899f

Browse files
committed
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
1 parent 251354e commit 37b899f

File tree

8 files changed

+227
-18
lines changed

8 files changed

+227
-18
lines changed

python/core/processing/qgsprocessingparameters.sip

+52
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ class QgsProcessingParameterDefinition
213213

214214
virtual ~QgsProcessingParameterDefinition();
215215

216+
virtual QgsProcessingParameterDefinition *clone() const = 0 /Factory/;
217+
%Docstring
218+
Creates a clone of the parameter definition.
219+
:rtype: QgsProcessingParameterDefinition
220+
%End
221+
216222
virtual QString type() const = 0;
217223
%Docstring
218224
Unique parameter type name.
@@ -620,6 +626,8 @@ class QgsProcessingParameterBoolean : QgsProcessingParameterDefinition
620626
Returns the type name for the parameter class.
621627
:rtype: str
622628
%End
629+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
630+
623631
virtual QString type() const;
624632
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
625633

@@ -656,6 +664,8 @@ class QgsProcessingParameterCrs : QgsProcessingParameterDefinition
656664
Returns the type name for the parameter class.
657665
:rtype: str
658666
%End
667+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
668+
659669
virtual QString type() const;
660670
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
661671

@@ -693,6 +703,8 @@ class QgsProcessingParameterMapLayer : QgsProcessingParameterDefinition
693703
Returns the type name for the parameter class.
694704
:rtype: str
695705
%End
706+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
707+
696708
virtual QString type() const;
697709
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
698710

@@ -730,6 +742,8 @@ class QgsProcessingParameterExtent : QgsProcessingParameterDefinition
730742
Returns the type name for the parameter class.
731743
:rtype: str
732744
%End
745+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
746+
733747
virtual QString type() const;
734748
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
735749

@@ -768,6 +782,8 @@ class QgsProcessingParameterPoint : QgsProcessingParameterDefinition
768782
Returns the type name for the parameter class.
769783
:rtype: str
770784
%End
785+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
786+
771787
virtual QString type() const;
772788
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
773789

@@ -809,6 +825,8 @@ class QgsProcessingParameterFile : QgsProcessingParameterDefinition
809825
Returns the type name for the parameter class.
810826
:rtype: str
811827
%End
828+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
829+
812830
virtual QString type() const;
813831
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
814832

@@ -879,6 +897,8 @@ class QgsProcessingParameterMatrix : QgsProcessingParameterDefinition
879897
Returns the type name for the parameter class.
880898
:rtype: str
881899
%End
900+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
901+
882902
virtual QString type() const;
883903
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
884904

@@ -967,6 +987,8 @@ class QgsProcessingParameterMultipleLayers : QgsProcessingParameterDefinition
967987
Returns the type name for the parameter class.
968988
:rtype: str
969989
%End
990+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
991+
970992
virtual QString type() const;
971993
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
972994

@@ -1050,6 +1072,8 @@ class QgsProcessingParameterNumber : QgsProcessingParameterDefinition
10501072
Returns the type name for the parameter class.
10511073
:rtype: str
10521074
%End
1075+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1076+
10531077
virtual QString type() const;
10541078
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
10551079

@@ -1133,6 +1157,8 @@ class QgsProcessingParameterRange : QgsProcessingParameterDefinition
11331157
Returns the type name for the parameter class.
11341158
:rtype: str
11351159
%End
1160+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1161+
11361162
virtual QString type() const;
11371163
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
11381164

@@ -1188,6 +1214,8 @@ class QgsProcessingParameterRasterLayer : QgsProcessingParameterDefinition
11881214
Returns the type name for the parameter class.
11891215
:rtype: str
11901216
%End
1217+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1218+
11911219
virtual QString type() const;
11921220
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
11931221

@@ -1227,6 +1255,8 @@ class QgsProcessingParameterEnum : QgsProcessingParameterDefinition
12271255
Returns the type name for the parameter class.
12281256
:rtype: str
12291257
%End
1258+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1259+
12301260
virtual QString type() const;
12311261
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
12321262

@@ -1298,6 +1328,8 @@ class QgsProcessingParameterString : QgsProcessingParameterDefinition
12981328
Returns the type name for the parameter class.
12991329
:rtype: str
13001330
%End
1331+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1332+
13011333
virtual QString type() const;
13021334
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
13031335

@@ -1354,6 +1386,8 @@ class QgsProcessingParameterExpression : QgsProcessingParameterDefinition
13541386
Returns the type name for the parameter class.
13551387
:rtype: str
13561388
%End
1389+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1390+
13571391
virtual QString type() const;
13581392
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
13591393

@@ -1413,6 +1447,8 @@ class QgsProcessingParameterVectorLayer : QgsProcessingParameterDefinition
14131447
Returns the type name for the parameter class.
14141448
:rtype: str
14151449
%End
1450+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1451+
14161452
virtual QString type() const;
14171453
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
14181454

@@ -1479,6 +1515,8 @@ class QgsProcessingParameterField : QgsProcessingParameterDefinition
14791515
Returns the type name for the parameter class.
14801516
:rtype: str
14811517
%End
1518+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1519+
14821520
virtual QString type() const;
14831521
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
14841522

@@ -1565,6 +1603,8 @@ class QgsProcessingParameterFeatureSource : QgsProcessingParameterDefinition
15651603
Returns the type name for the parameter class.
15661604
:rtype: str
15671605
%End
1606+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1607+
15681608
virtual QString type() const;
15691609
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
15701610

@@ -1704,6 +1744,8 @@ class QgsProcessingParameterFeatureSink : QgsProcessingDestinationParameter
17041744
Returns the type name for the parameter class.
17051745
:rtype: str
17061746
%End
1747+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1748+
17071749
virtual QString type() const;
17081750
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
17091751

@@ -1781,6 +1823,8 @@ class QgsProcessingParameterVectorDestination : QgsProcessingDestinationParamete
17811823
Returns the type name for the parameter class.
17821824
:rtype: str
17831825
%End
1826+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1827+
17841828
virtual QString type() const;
17851829
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
17861830

@@ -1852,6 +1896,8 @@ class QgsProcessingParameterRasterDestination : QgsProcessingDestinationParamete
18521896
Returns the type name for the parameter class.
18531897
:rtype: str
18541898
%End
1899+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1900+
18551901
virtual QString type() const;
18561902
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
18571903

@@ -1895,6 +1941,8 @@ class QgsProcessingParameterFileDestination : QgsProcessingDestinationParameter
18951941
Returns the type name for the parameter class.
18961942
:rtype: str
18971943
%End
1944+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
1945+
18981946
virtual QString type() const;
18991947
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
19001948

@@ -1958,6 +2006,8 @@ class QgsProcessingParameterFolderDestination : QgsProcessingDestinationParamete
19582006
Returns the type name for the parameter class.
19592007
:rtype: str
19602008
%End
2009+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
2010+
19612011
virtual QString type() const;
19622012
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
19632013

@@ -1998,6 +2048,8 @@ class QgsProcessingParameterBand : QgsProcessingParameterDefinition
19982048
Returns the type name for the parameter class.
19992049
:rtype: str
20002050
%End
2051+
virtual QgsProcessingParameterDefinition *clone() const /Factory/;
2052+
20012053
virtual QString type() const;
20022054
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
20032055

python/plugins/processing/algs/gdal/buildvrt.py

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class ParameterVrtDestination(QgsProcessingParameterRasterDestination):
6363
def __init__(self, name, description):
6464
super().__init__(name, description)
6565

66+
def clone(self):
67+
copy = ParameterVrtDestination(self.name(), self.description())
68+
return copy
69+
6670
def type(self):
6771
return 'vrt_destination'
6872

python/plugins/processing/algs/qgis/Aggregate.py

+4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ def __init__(self, name, description, parentLayerParameterName='INPUT'):
7878
super().__init__(name, description)
7979
self._parentLayerParameter = parentLayerParameterName
8080

81+
def clone(self):
82+
copy = ParameterAggregates(self.name(), self.description(), self._parentLayerParameter)
83+
return copy
84+
8185
def type(self):
8286
return 'aggregates'
8387

python/plugins/processing/algs/qgis/FieldsMapper.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@
2626
__revision__ = '$Format:%H$'
2727

2828
from qgis.core import (
29-
QgsApplication,
3029
QgsDistanceArea,
3130
QgsExpression,
32-
QgsFeature,
33-
QgsFeatureSink,
3431
QgsField,
3532
QgsFields,
3633
QgsProcessingException,
37-
QgsProcessingParameterDefinition,
38-
QgsProcessingUtils,
39-
QgsProject,
40-
)
34+
QgsProcessingParameterDefinition)
4135

4236
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
4337

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

56+
def clone(self):
57+
copy = ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
58+
return copy
59+
6260
def type(self):
6361
return 'fields_mapping'
6462

python/plugins/processing/algs/qgis/Heatmap.py

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ def __init__(self, name='', description='', parent_layer=None, radius_param=None
116116
self.radius_param = radius_param
117117
self.radius_field_param = radius_field_param
118118

119+
def clone(self):
120+
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))
121+
return copy
122+
119123
pixel_size_param = ParameterHeatmapPixelSize(self.PIXEL_SIZE,
120124
self.tr('Output raster size'),
121125
parent_layer=self.INPUT,

src/core/processing/models/qgsprocessingmodelalgorithm.cpp

+15-11
Original file line numberDiff line numberDiff line change
@@ -729,19 +729,19 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
729729
if ( !source )
730730
continue;
731731

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

737-
if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter *>( param ) )
736+
if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter *>( param.get() ) )
738737
{
739-
QgsProcessingOutputDefinition *output = destParam->toOutputDefinition();
738+
std::unique_ptr< QgsProcessingOutputDefinition > output( destParam->toOutputDefinition() );
740739
if ( output )
741740
{
742-
addOutput( output );
741+
addOutput( output.release() );
743742
}
744743
}
744+
addParameter( param.release() );
745745
}
746746
}
747747
}
@@ -793,8 +793,11 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
793793
for ( ; childIt != childMap.constEnd(); ++childIt )
794794
{
795795
QgsProcessingModelChildAlgorithm child;
796+
// we be leniant here - even if we couldn't load a parameter, don't interrupt the model loading
797+
// otherwise models may become unusable (e.g. due to removed plugins providing algs/parameters)
798+
// with no way for users to repair them
796799
if ( !child.loadVariant( childIt.value() ) )
797-
return false;
800+
continue;
798801

799802
mChildAlgorithms.insert( child.childId(), child );
800803
}
@@ -817,11 +820,12 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
817820
QVariantMap::const_iterator paramDefIt = paramDefMap.constBegin();
818821
for ( ; paramDefIt != paramDefMap.constEnd(); ++paramDefIt )
819822
{
820-
QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( paramDefIt.value().toMap() );
821-
if ( !param )
822-
return false;
823-
824-
addParameter( param );
823+
std::unique_ptr< QgsProcessingParameterDefinition > param( QgsProcessingParameters::parameterFromVariantMap( paramDefIt.value().toMap() ) );
824+
// we be leniant here - even if we couldn't load a parameter, don't interrupt the model loading
825+
// otherwise models may become unusable (e.g. due to removed plugins providing algs/parameters)
826+
// with no way for users to repair them
827+
if ( param )
828+
addParameter( param.release() );
825829
}
826830

827831
updateDestinationParameters();

0 commit comments

Comments
 (0)