Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #4798 from nyalldawson/intput_list
Convert model child algorithm parameter sources to a list
  • Loading branch information
nyalldawson committed Jun 30, 2017
2 parents bc4aae7 + 77588b9 commit 33c63d5
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 116 deletions.
106 changes: 106 additions & 0 deletions python/core/conversions.sip
Expand Up @@ -1198,6 +1198,112 @@ template<double, TYPE>
};


template<TYPE2>
%MappedType QMap<QString, QList<TYPE2> >
{
%TypeHeaderCode
#include <QMap>
#include <QList>
%End

%ConvertFromTypeCode
// Create the dictionary.
PyObject *d = PyDict_New();

if (!d)
return NULL;

const sipMappedType *qlist_type = sipFindMappedType("QList<TYPE2>");

// Set the dictionary elements.
QMap<QString, QList< TYPE2 > >::const_iterator i;

for (i = sipCpp->constBegin(); i != sipCpp->constEnd(); ++i)
{
QString *t1 = new QString(i.key());

PyObject *t1obj = sipConvertFromNewType(t1, sipType_QString, sipTransferObj);

QList< TYPE2 > *t2 = new QList< TYPE2 >( i.value() );

PyObject *t2obj = sipConvertFromMappedType(t2, qlist_type, sipTransferObj);

if (t1obj == NULL || t2obj == NULL || PyDict_SetItem(d, t1obj, t2obj) < 0)
{
Py_DECREF(d);

if (t1obj)
Py_DECREF(t1obj);

if (t2obj)
Py_DECREF(t2obj);
else
delete t2;

return NULL;
}

Py_DECREF(t1obj);
Py_DECREF(t2obj);
}

return d;
%End

%ConvertToTypeCode
PyObject *t1obj, *t2obj;
Py_ssize_t i = 0;


const sipMappedType *qlist_type = sipFindMappedType("QList<TYPE2>");


// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyDict_Check(sipPy))
return 0;

while (PyDict_Next(sipPy, &i, &t1obj, &t2obj))
{
if (!sipCanConvertToType(t1obj, sipType_QString, SIP_NOT_NONE))
return 0;
}

return 1;
}

QMap<QString, QList< TYPE2 > > *qm = new QMap<QString, QList< TYPE2 > >;

while (PyDict_Next(sipPy, &i, &t1obj, &t2obj))
{
int state;

QString *t1 = reinterpret_cast<QString *>(sipConvertToType(t1obj, sipType_QString, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));

QList<TYPE2> *t2 = reinterpret_cast< QList<TYPE2> * >(sipConvertToMappedType(t2obj, qlist_type, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));
if (*sipIsErr)
{
sipReleaseType(t2, sipType_TYPE2, state);
delete qm;
return 0;
}

if ( t2 )
qm->insert(*t1, *t2);
else
qm->insert(*t1, QList<TYPE2>() );

sipReleaseType(t1, sipType_QString, state);

sipReleaseType(t2, sipType_TYPE2, state);
}

*sipCppPtr = qm;

return sipGetState(sipTransferObj);
%End
};

template<double, TYPE2>
%MappedType QMultiMap<double, TYPE2>
Expand Down
23 changes: 12 additions & 11 deletions python/core/processing/qgsprocessingmodelalgorithm.sip
Expand Up @@ -161,6 +161,7 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm

};


class Component
{
%Docstring
Expand Down Expand Up @@ -415,30 +416,30 @@ Copies are protected to avoid slicing
:rtype: QgsProcessingAlgorithm
%End

QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > parameterSources() const;
QMap< QString, QList< QgsProcessingModelAlgorithm::ChildParameterSource > > parameterSources() const;
%Docstring
Returns a map of parameter sources. The keys are the child algorithm
parameter names, the values are the source for that parameter.
parameter names, the values are the sources for that parameter.
.. seealso:: setParameterSources()
.. seealso:: addParameterSource()
:rtype: QMap< str, QgsProcessingModelAlgorithm.ChildParameterSource >
.. seealso:: addParameterSources()
:rtype: QMap< str, QList< QgsProcessingModelAlgorithm.ChildParameterSource > >
%End

void setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > &sources );
void setParameterSources( const QMap< QString, QList< QgsProcessingModelAlgorithm::ChildParameterSource > > &sources );
%Docstring
Sets the map of parameter ``sources``. The keys are the child algorithm
parameter names, the values are the source for that parameter.
parameter names, the values are the sources for that parameter.
.. seealso:: parameterSources()
.. seealso:: addParameterSource()
.. seealso:: addParameterSources()
%End

void addParameterSource( const QString &name, const QgsProcessingModelAlgorithm::ChildParameterSource &source );
void addParameterSources( const QString &name, const QList< QgsProcessingModelAlgorithm::ChildParameterSource > &source );
%Docstring
Adds a parameter source. The ``name`` argument should match
one of the child algorithm's parameter names, and the ``source``
argument is used to set the source for that parameter.
one of the child algorithm's parameter names, and the ``sources``
argument is used to set the sources for that parameter.

Any existing parameter source with matching name will be replaced.
Any existing parameter sources with matching name will be replaced.
.. seealso:: parameterSources()
.. seealso:: setParameterSources()
%End
Expand Down
8 changes: 6 additions & 2 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Expand Up @@ -285,6 +285,8 @@ def setPreviousValues(self):
continue
if param.name() in alg.parameterSources():
value = alg.parameterSources()[param.name()]
if isinstance(value, list) and len(value) == 1:
value = value[0]
else:
value = param.defaultValue()

Expand Down Expand Up @@ -325,9 +327,11 @@ def createAlgorithm(self):
if val is None:
continue
elif isinstance(val, QgsProcessingModelAlgorithm.ChildParameterSource):
alg.addParameterSource(param.name(), val)
alg.addParameterSources(param.name(), [val])
elif isinstance(val, list):
alg.addParameterSources(param.name(), val)
else:
alg.addParameterSource(param.name(), QgsProcessingModelAlgorithm.ChildParameterSource.fromStaticValue(val))
alg.addParameterSources(param.name(), [QgsProcessingModelAlgorithm.ChildParameterSource.fromStaticValue(val)])

outputs = {}
for dest in self._alg.destinationParameterDefinitions():
Expand Down
21 changes: 11 additions & 10 deletions python/plugins/processing/modeler/ModelerScene.py
Expand Up @@ -109,17 +109,18 @@ def paintModel(self, model, controls=True):
for parameter in alg.algorithm().parameterDefinitions():
if not parameter.isDestination() and not parameter.flags() & QgsProcessingParameterDefinition.FlagHidden:
if parameter.name() in alg.parameterSources():
value = alg.parameterSources()[parameter.name()]
sources = alg.parameterSources()[parameter.name()]
else:
value = None
sourceItems = self.getItemsFromParamValue(value)
for sourceItem, sourceIdx in sourceItems:
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.childId()], idx)
sourceItem.addArrow(arrow)
self.algItems[alg.childId()].addArrow(arrow)
arrow.updatePath()
self.addItem(arrow)
idx += 1
sources = []
for source in sources:
sourceItems = self.getItemsFromParamValue(source)
for sourceItem, sourceIdx in sourceItems:
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.childId()], idx)
sourceItem.addArrow(arrow)
self.algItems[alg.childId()].addArrow(arrow)
arrow.updatePath()
self.addItem(arrow)
idx += 1
for depend in alg.dependencies():
arrow = ModelerArrowItem(self.algItems[depend], -1,
self.algItems[alg.childId()], -1)
Expand Down

0 comments on commit 33c63d5

Please sign in to comment.