Skip to content

Commit 4ccd444

Browse files
arnaud-morvannyalldawson
authored andcommittedMay 14, 2018
[processing] Add default values in model for destination parameters
1 parent 8d5e5c9 commit 4ccd444

14 files changed

+225
-5
lines changed
 

‎python/core/processing/models/qgsprocessingmodelchildalgorithm.sip.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,17 @@ If child model outputs are altered by this method, :py:func:`QgsProcessingModelA
251251
must be called on the parent model.
252252

253253
.. seealso:: :py:func:`modelOutputs`
254+
%End
255+
256+
bool removeModelOutput( const QString &name );
257+
%Docstring
258+
Removes an existing output from the final model outputs.
259+
260+
QgsProcessingModelAlgorithm.updateDestinationParameters() must be called on the parent model.
261+
262+
.. seealso:: :py:func:`modelOutputs`
263+
264+
.. versionadded:: 3.2
254265
%End
255266

256267
QVariant toVariant() const;

‎python/core/processing/models/qgsprocessingmodeloutput.sip.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Represents a final output created by the model.
2323
%End
2424
public:
2525

26+
2627
QgsProcessingModelOutput( const QString &name = QString(), const QString &description = QString() );
2728
%Docstring
2829
Constructor for QgsProcessingModelOutput with the specified ``name`` and ``description``.
@@ -40,6 +41,24 @@ Returns the model output name.
4041
Sets the model output ``name``.
4142

4243
.. seealso:: :py:func:`name`
44+
%End
45+
46+
QVariant defaultValue() const;
47+
%Docstring
48+
Returns the default value for the model output parameter.
49+
50+
.. seealso:: :py:func:`setDefaultValue`
51+
52+
.. versionadded:: 3.2
53+
%End
54+
55+
void setDefaultValue( const QVariant &value );
56+
%Docstring
57+
Sets the default value for the model output.
58+
59+
.. seealso:: :py:func:`defaultValue`
60+
61+
.. versionadded:: 3.2
4362
%End
4463

4564
QString childId() const;

‎python/core/processing/qgsprocessingparameters.sip.in

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ to automatically load the resulting sink/layer after completing processing.
8585

8686
QVariantMap createOptions;
8787

88+
QVariant toVariant() const;
89+
%Docstring
90+
Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
91+
You can use QgsXmlUtils.writeVariant to save it to an XML document.
92+
93+
.. seealso:: :py:func:`loadVariant`
94+
%End
95+
96+
bool loadVariant( const QVariantMap &map );
97+
%Docstring
98+
Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
99+
You can use QgsXmlUtils.readVariant to load it from an XML document.
100+
101+
.. seealso:: :py:func:`toVariant`
102+
%End
88103

89104
operator QVariant() const;
90105

‎python/plugins/processing/gui/AlgorithmDialog.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ def getParameterValues(self):
111111
dest_project = QgsProject.instance()
112112

113113
value = self.mainWidget().outputWidgets[param.name()].getValue()
114+
if value == '':
115+
value = self.parameter.generateTemporaryDestination()
114116
if value and isinstance(value, QgsProcessingOutputLayerDefinition):
115117
value.destinationProject = dest_project
116118
if value:

‎python/plugins/processing/gui/DestinationSelectionPanel.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def __init__(self, parameter, alg):
8585
elif not isinstance(self.parameter, QgsProcessingParameterFolderDestination):
8686
self.leText.setPlaceholderText(self.SAVE_TO_TEMP_FILE)
8787

88+
self.setValue(self.parameter.defaultValue())
89+
8890
self.btnSelect.clicked.connect(self.selectOutput)
8991
self.leText.textEdited.connect(self.textChanged)
9092

@@ -285,8 +287,12 @@ def selectDirectory(self):
285287
self.skipOutputChanged.emit(False)
286288

287289
def setValue(self, value):
288-
if value == 'memory:':
290+
if value == 'memory:' or not value:
289291
self.saveToTemporary()
292+
elif isinstance(value, QgsProcessingOutputLayerDefinition):
293+
self.leText.setText(value.sink.staticValue())
294+
self.encoding = value.createOptions['fileEncoding']
295+
self.use_temporary = False
290296
else:
291297
self.leText.setText(value)
292298
self.use_temporary = False

‎python/plugins/processing/modeler/ModelerGraphicItem.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def __init__(self, element, model, controls, scene=None):
9292
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
9393
self.setZValue(1000)
9494

95-
if not isinstance(element, QgsProcessingModelOutput) and controls:
95+
if controls:
9696
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg'))
9797
picture = QPicture()
9898
painter = QPainter(picture)
@@ -224,6 +224,17 @@ def editElement(self):
224224
self.updateAlgorithm(alg)
225225
self.scene.dialog.repaintModel()
226226

227+
elif isinstance(self.element, QgsProcessingModelOutput):
228+
child_alg = self.model.childAlgorithm(self.element.childId())
229+
param_name = '{}:{}'.format(self.element.childId(), self.element.name())
230+
dlg = ModelerParameterDefinitionDialog(self.model,
231+
param=self.model.parameterDefinition(param_name))
232+
if dlg.exec_() and dlg.param is not None:
233+
model_output = child_alg.modelOutput(self.element.name())
234+
model_output.setDescription(dlg.param.description())
235+
model_output.setDefaultValue(dlg.param.defaultValue())
236+
self.model.updateDestinationParameters()
237+
227238
def updateAlgorithm(self, alg):
228239
existing_child = self.model.childAlgorithm(alg.childId())
229240
alg.setPosition(existing_child.position())
@@ -234,6 +245,8 @@ def updateAlgorithm(self, alg):
234245
alg.position() + QPointF(
235246
ModelerGraphicItem.BOX_WIDTH,
236247
(i + 1.5) * ModelerGraphicItem.BOX_HEIGHT))
248+
#if existing_child.modelOutput(out):
249+
# alg.modelOutput(out).setDefaultValue(existing_child.modelOutput(out).defaultValue())
237250
self.model.setChildAlgorithm(alg)
238251

239252
def removeElement(self):
@@ -258,6 +271,11 @@ def removeElement(self):
258271
else:
259272
self.scene.dialog.haschanged = True
260273
self.scene.dialog.repaintModel()
274+
elif isinstance(self.element, QgsProcessingModelOutput):
275+
self.model.childAlgorithm(self.element.childId()).removeModelOutput(self.element.name())
276+
self.model.updateDestinationParameters()
277+
self.scene.dialog.haschanged = True
278+
self.scene.dialog.repaintModel()
261279

262280
def getAdjustedText(self, text):
263281
font = QFont('Verdana', 8)

‎python/plugins/processing/modeler/ModelerParameterDefinitionDialog.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,15 @@
6363
QgsProcessingParameterVectorLayer,
6464
QgsProcessingParameterField,
6565
QgsProcessingParameterFeatureSource,
66-
QgsProcessingParameterBand
67-
)
68-
66+
QgsProcessingParameterBand,
67+
QgsProcessingDestinationParameter,
68+
QgsProcessingParameterFeatureSink,
69+
QgsProcessingParameterFileDestination,
70+
QgsProcessingParameterFolderDestination,
71+
QgsProcessingParameterRasterDestination,
72+
QgsProcessingParameterVectorDestination)
73+
74+
from processing.gui.DestinationSelectionPanel import DestinationSelectionPanel
6975
from processing.gui.enummodelerwidget import EnumModelerWidget
7076
from processing.gui.matrixmodelerwidget import MatrixModelerWidget
7177
from processing.core import parameters
@@ -293,6 +299,11 @@ def setupUi(self):
293299
self.widget.setFixedRows(self.param.hasFixedNumberRows())
294300
self.verticalLayout.addWidget(self.widget)
295301

302+
elif isinstance(self.param, QgsProcessingDestinationParameter):
303+
self.verticalLayout.addWidget(QLabel(self.tr('Default value')))
304+
self.defaultWidget = DestinationSelectionPanel(self.param, self.alg)
305+
self.verticalLayout.addWidget(self.defaultWidget)
306+
296307
self.verticalLayout.addSpacing(20)
297308
self.requiredCheck = QCheckBox()
298309
self.requiredCheck.setText(self.tr('Mandatory'))
@@ -425,6 +436,42 @@ def accept(self):
425436
elif (self.paramType == parameters.PARAMETER_MATRIX or
426437
isinstance(self.param, QgsProcessingParameterMatrix)):
427438
self.param = QgsProcessingParameterMatrix(name, description, hasFixedNumberRows=self.widget.fixedRows(), headers=self.widget.headers(), defaultValue=self.widget.value())
439+
440+
# Destination parameter
441+
elif (isinstance(self.param, QgsProcessingParameterFeatureSink)):
442+
self.param = QgsProcessingParameterFeatureSink(
443+
name=name,
444+
description=self.param.description(),
445+
type=self.param.dataType(),
446+
defaultValue=self.defaultWidget.getValue(),
447+
optional=self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
448+
elif (isinstance(self.param, QgsProcessingParameterFileDestination)):
449+
self.param = QgsProcessingParameterFileDestination(
450+
name=name,
451+
description=self.param.description(),
452+
fileFilter=self.param.fileFilter(),
453+
defaultValue=str(self.defaultWidget.getValue()),
454+
optional=self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
455+
elif (isinstance(self.param, QgsProcessingParameterFolderDestination)):
456+
self.param = QgsProcessingParameterFolderDestination(
457+
name=name,
458+
description=self.param.description(),
459+
defaultValue=str(self.defaultWidget.getValue()),
460+
optional=self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
461+
elif (isinstance(self.param, QgsProcessingParameterRasterDestination)):
462+
self.param = QgsProcessingParameterRasterDestination(
463+
name=name,
464+
description=self.param.description(),
465+
defaultValue=str(self.defaultWidget.getValue()),
466+
optional=self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
467+
elif (isinstance(self.param, QgsProcessingParameterVectorDestination)):
468+
self.param = QgsProcessingParameterVectorDestination(
469+
name=name,
470+
description=self.param.description(),
471+
type=self.param.dataType(),
472+
defaultValue=str(self.defaultWidget.getValue()),
473+
optional=self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
474+
428475
else:
429476
if self.paramType:
430477
typeId = self.paramType

‎src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
788788
param->setFlags( param->flags() & ~QgsProcessingParameterDefinition::FlagHidden );
789789
param->setName( outputIt->childId() + ':' + outputIt->name() );
790790
param->setDescription( outputIt->description() );
791+
param->setDefaultValue( outputIt->defaultValue() );
791792
addParameter( param.release() );
792793
}
793794
}

‎src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ void QgsProcessingModelChildAlgorithm::setModelOutputs( const QMap<QString, QgsP
7474
}
7575
}
7676

77+
bool QgsProcessingModelChildAlgorithm::removeModelOutput( const QString &name )
78+
{
79+
mModelOutputs.remove( name );
80+
return true;
81+
}
82+
7783
QVariant QgsProcessingModelChildAlgorithm::toVariant() const
7884
{
7985
QVariantMap map;

‎src/core/processing/models/qgsprocessingmodelchildalgorithm.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ class CORE_EXPORT QgsProcessingModelChildAlgorithm : public QgsProcessingModelCo
237237
*/
238238
void setModelOutputs( const QMap<QString, QgsProcessingModelOutput> &outputs );
239239

240+
/**
241+
* Removes an existing output from the final model outputs.
242+
*
243+
* QgsProcessingModelAlgorithm::updateDestinationParameters() must be called on the parent model.
244+
*
245+
* \see modelOutputs()
246+
* \since QGIS 3.2
247+
*/
248+
bool removeModelOutput( const QString &name );
249+
240250
/**
241251
* Saves this child to a QVariant.
242252
* \see loadVariant()

‎src/core/processing/models/qgsprocessingmodeloutput.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ QVariant QgsProcessingModelOutput::toVariant() const
2828
{
2929
QVariantMap map;
3030
map.insert( QStringLiteral( "name" ), mName );
31+
32+
if ( mDefaultValue.canConvert<QgsProcessingOutputLayerDefinition>() )
33+
{
34+
QVariantMap defaultMap = mDefaultValue.value<QgsProcessingOutputLayerDefinition>().toVariant().toMap();
35+
defaultMap.insert( QStringLiteral( "class" ), QStringLiteral( "QgsProcessingOutputLayerDefinition" ) );
36+
map.insert( QStringLiteral( "default_value" ), defaultMap );
37+
}
38+
else
39+
{
40+
map.insert( QStringLiteral( "default_value" ), mDefaultValue );
41+
}
42+
3143
map.insert( QStringLiteral( "child_id" ), mChildId );
3244
map.insert( QStringLiteral( "output_name" ), mOutputName );
3345
saveCommonProperties( map );
@@ -37,6 +49,27 @@ QVariant QgsProcessingModelOutput::toVariant() const
3749
bool QgsProcessingModelOutput::loadVariant( const QVariantMap &map )
3850
{
3951
mName = map.value( QStringLiteral( "name" ) ).toString();
52+
53+
QVariant defaultValue = map.value( QStringLiteral( "default_value" ) );
54+
if ( defaultValue.type() == QVariant::Map )
55+
{
56+
QVariantMap defaultMap = defaultValue.toMap();
57+
if ( defaultMap["class"] == "QgsProcessingOutputLayerDefinition" )
58+
{
59+
QgsProcessingOutputLayerDefinition value( "" );
60+
value.loadVariant( defaultMap );
61+
mDefaultValue = QVariant( value );
62+
}
63+
else
64+
{
65+
mDefaultValue = QVariant();
66+
}
67+
}
68+
else
69+
{
70+
mDefaultValue = map.value( QStringLiteral( "default_value" ) );
71+
}
72+
4073
mChildId = map.value( QStringLiteral( "child_id" ) ).toString();
4174
mOutputName = map.value( QStringLiteral( "output_name" ) ).toString();
4275
restoreCommonProperties( map );

‎src/core/processing/models/qgsprocessingmodeloutput.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgis_core.h"
2222
#include "qgis.h"
2323
#include "qgsprocessingmodelcomponent.h"
24+
#include "qgsprocessingparameters.h"
2425

2526
///@cond NOT_STABLE
2627

@@ -33,6 +34,11 @@ class CORE_EXPORT QgsProcessingModelOutput : public QgsProcessingModelComponent
3334
{
3435
public:
3536

37+
/*
38+
//! Output flags
39+
Q_DECLARE_FLAGS( Flags, QgsProcessingParameterDefinition::Flag )
40+
*/
41+
3642
/**
3743
* Constructor for QgsProcessingModelOutput with the specified \a name and \a description.
3844
*/
@@ -50,6 +56,20 @@ class CORE_EXPORT QgsProcessingModelOutput : public QgsProcessingModelComponent
5056
*/
5157
void setName( const QString &name ) { mName = name; }
5258

59+
/**
60+
* Returns the default value for the model output parameter.
61+
* \see setDefaultValue()
62+
* \since QGIS 3.2
63+
*/
64+
QVariant defaultValue() const { return mDefaultValue; }
65+
66+
/**
67+
* Sets the default value for the model output.
68+
* \see defaultValue()
69+
* \since QGIS 3.2
70+
*/
71+
void setDefaultValue( const QVariant &value ) { mDefaultValue = value; }
72+
5373
/**
5474
* Returns the child algorithm ID from which this output is generated.
5575
* \see setChildId()
@@ -89,6 +109,7 @@ class CORE_EXPORT QgsProcessingModelOutput : public QgsProcessingModelComponent
89109
private:
90110

91111
QString mName;
112+
QVariant mDefaultValue;
92113
QString mChildId;
93114
QString mOutputName;
94115
};

‎src/core/processing/qgsprocessingparameters.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
#include "qgsprocessingparametertype.h"
3030
#include <functional>
3131

32+
33+
QVariant QgsProcessingOutputLayerDefinition::toVariant() const
34+
{
35+
QVariantMap map;
36+
map.insert( QStringLiteral( "sink" ), sink.toVariant() );
37+
map.insert( QStringLiteral( "create_options" ), createOptions );
38+
return map;
39+
}
40+
41+
bool QgsProcessingOutputLayerDefinition::loadVariant( const QVariantMap &map )
42+
{
43+
sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
44+
createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
45+
return true;
46+
}
47+
3248
bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
3349
{
3450
QVariant val = parameters.value( name );

‎src/core/processing/qgsprocessingparameters.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ class CORE_EXPORT QgsProcessingOutputLayerDefinition
153153
*/
154154
QVariantMap createOptions;
155155

156+
/**
157+
* Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
158+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
159+
*
160+
* \see loadVariant()
161+
*/
162+
QVariant toVariant() const;
163+
164+
/**
165+
* Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
166+
* You can use QgsXmlUtils::readVariant to load it from an XML document.
167+
*
168+
* \see toVariant()
169+
*/
170+
bool loadVariant( const QVariantMap &map );
156171

157172
//! Allows direct construction of QVariants.
158173
operator QVariant() const

0 commit comments

Comments
 (0)
Please sign in to comment.