execution on generated layers after the algorithm (or parent
model) completes
This commit adds an interface for layer post-processing handlers
for execution following a processing algorithm operation.
Post-processing of a layer will ONLY occur if that layer is set
to be loaded into a QGIS project on algorithm completion.
Algorithms that wish to set post-processing steps for generated
layers should implement this interface in a separate class
(NOT the algorithm class itself!) and implement a method
to handle the layer post-processing.
This method always runs in the main thread and can be used to
setup renderers, editor widgets, metadata, etc for the given layer.
Fixes#17961
in model child algorithms
Prior to this change if you edited an algorithm in a model and
tried to enter a preset string for certain parameter types, this
string would get silently discarded on closing the dialog. E.g.
with a dissolve algorithm it was not possible to have a fixed
field name within the model to dissolve by.
This was caused by WidgetWrapper.comboValue returning the customData
for these manually entered values in the parameters combo box,
yet manually entered values never have custom data.
To work around this we only return the custom data if its
set for the selected item - otherwise we return the text unchanged.
In order to handle the "[not set]" options, a new static custom
data value of WidgetWrapper.NOT_SET_OPTION is added to that
comboValue can detect this and return the appropriate None value.
if they are unique in the current project
Instead of always using the layer id, which is generally
gibberish and meaningless for users, instead prefer to use
the layer name as an input in the batch processing dialog. This
is done only if the name is unique within the current project's
loaded layers.
This change makes the dialog more user-friendly, but more importantly
it means that autofilling output values based on an input layer
parameter generates more meaningful automatic output file names.
Some filters are fast enough to return results that it's overkill
to run them in a background thread - add a flag to these filters
to allow them to run (blocking) in the main thread instead.
- add a clone() method to filters, and always search using the
clone instead of the original filter
- add a prepare() method to filters, which is always run in the
main thread and can be used to prepare the filter for safe
background execution (e.g. creating feature iterators in advance)
- don't use QtConcurrent to perform searches in background threads,
since it is not safe to use with QObjects
- instead manually create threads and ensure that cloned objects
are always moved to the thread that they will run in, to ensure
that they correctly have thread affinity with the thread in which
they are executed
This was a missing capability in the processing API - while algorithms
could declare multiple layer input parameters, there was no corresponding
multi-layer output. This meant that algorithms (such as Package Layers,
Vector Split) which create a set of layers which cannot be determined
in advance had no way to pass these generated layers on for further model
processing steps.
It's also useful for algorithms which operate on a specified folder,
processing all layers found there, and allowing these generated
outputs to be utilised in other model steps (e.g. packaging
all of them, merging them, etc)