QGIS API Documentation 4.3.0-Master (0de80482b60)
Loading...
Searching...
No Matches
qgsprocessingguiregistry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingguiregistry.cpp
3 ---------------------
4 begin : April 2018
5 copyright : (C) 2018 by Matthias Kuhn
6 email : matthias@opengis.ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgis.h"
21#include "qgslogger.h"
45
46#include <QString>
47
48#include "moc_qgsprocessingguiregistry.cpp"
49
50using namespace Qt::StringLiterals;
51
53{
54 addAlgorithmConfigurationWidgetFactory( new QgsFilterAlgorithmConfigurationWidgetFactory() );
55 addAlgorithmConfigurationWidgetFactory( new QgsConditionalBranchAlgorithmConfigurationWidgetFactory() );
56
57 addParameterWidgetFactory( new QgsProcessingAlignRasterLayersWidgetWrapper() );
58 addParameterWidgetFactory( new QgsProcessingBooleanWidgetWrapper() );
59 addParameterWidgetFactory( new QgsProcessingCrsWidgetWrapper() );
60 addParameterWidgetFactory( new QgsProcessingStringWidgetWrapper() );
61 addParameterWidgetFactory( new QgsProcessingNumericWidgetWrapper() );
62 addParameterWidgetFactory( new QgsProcessingDistanceWidgetWrapper() );
63 addParameterWidgetFactory( new QgsProcessingAreaWidgetWrapper() );
64 addParameterWidgetFactory( new QgsProcessingVolumeWidgetWrapper() );
65 addParameterWidgetFactory( new QgsProcessingDurationWidgetWrapper() );
66 addParameterWidgetFactory( new QgsProcessingScaleWidgetWrapper() );
67 addParameterWidgetFactory( new QgsProcessingRangeWidgetWrapper() );
68 addParameterWidgetFactory( new QgsProcessingAuthConfigWidgetWrapper() );
69 addParameterWidgetFactory( new QgsProcessingMatrixWidgetWrapper() );
70 addParameterWidgetFactory( new QgsProcessingFileWidgetWrapper() );
71 addParameterWidgetFactory( new QgsProcessingExpressionWidgetWrapper() );
72 addParameterWidgetFactory( new QgsProcessingEnumWidgetWrapper() );
73 addParameterWidgetFactory( new QgsProcessingLayoutWidgetWrapper() );
74 addParameterWidgetFactory( new QgsProcessingLayoutItemWidgetWrapper() );
75 addParameterWidgetFactory( new QgsProcessingPointWidgetWrapper() );
76 addParameterWidgetFactory( new QgsProcessingGeometryWidgetWrapper() );
77 addParameterWidgetFactory( new QgsProcessingColorWidgetWrapper() );
78 addParameterWidgetFactory( new QgsProcessingCoordinateOperationWidgetWrapper() );
79 addParameterWidgetFactory( new QgsProcessingFieldWidgetWrapper() );
80 addParameterWidgetFactory( new QgsProcessingMapThemeWidgetWrapper() );
81 addParameterWidgetFactory( new QgsProcessingDateTimeWidgetWrapper() );
82 addParameterWidgetFactory( new QgsProcessingProviderConnectionWidgetWrapper() );
83 addParameterWidgetFactory( new QgsProcessingDatabaseSchemaWidgetWrapper() );
84 addParameterWidgetFactory( new QgsProcessingDatabaseTableWidgetWrapper() );
85 addParameterWidgetFactory( new QgsProcessingExtentWidgetWrapper() );
86 addParameterWidgetFactory( new QgsProcessingMapLayerWidgetWrapper() );
87 addParameterWidgetFactory( new QgsProcessingVectorLayerWidgetWrapper() );
88 addParameterWidgetFactory( new QgsProcessingFeatureSourceWidgetWrapper() );
89 addParameterWidgetFactory( new QgsProcessingRasterLayerWidgetWrapper() );
90 addParameterWidgetFactory( new QgsProcessingMeshLayerWidgetWrapper() );
91 addParameterWidgetFactory( new QgsProcessingBandWidgetWrapper() );
92 addParameterWidgetFactory( new QgsProcessingMultipleLayerWidgetWrapper() );
93 addParameterWidgetFactory( new QgsProcessingVectorTileWriterLayersWidgetWrapper() );
94 addParameterWidgetFactory( new QgsProcessingFeatureSinkWidgetWrapper() );
95 addParameterWidgetFactory( new QgsProcessingVectorDestinationWidgetWrapper() );
96 addParameterWidgetFactory( new QgsProcessingRasterDestinationWidgetWrapper() );
97 addParameterWidgetFactory( new QgsProcessingFileDestinationWidgetWrapper() );
98 addParameterWidgetFactory( new QgsProcessingFolderDestinationWidgetWrapper() );
99 addParameterWidgetFactory( new QgsProcessingFieldMapWidgetWrapper() );
100 addParameterWidgetFactory( new QgsProcessingAggregateWidgetWrapper() );
101 addParameterWidgetFactory( new QgsProcessingTinInputLayersWidgetWrapper() );
102 addParameterWidgetFactory( new QgsProcessingDxfLayersWidgetWrapper() );
103 addParameterWidgetFactory( new QgsProcessingMeshDatasetGroupsWidgetWrapper() );
104 addParameterWidgetFactory( new QgsProcessingMeshDatasetTimeWidgetWrapper() );
105 addParameterWidgetFactory( new QgsProcessingPointCloudLayerWidgetWrapper() );
106 addParameterWidgetFactory( new QgsProcessingAnnotationLayerWidgetWrapper() );
107 addParameterWidgetFactory( new QgsProcessingPointCloudDestinationWidgetWrapper() );
108 addParameterWidgetFactory( new QgsProcessingPointCloudAttributeWidgetWrapper() );
109 addParameterWidgetFactory( new QgsProcessingVectorTileDestinationWidgetWrapper() );
110 addParameterWidgetFactory( new QgsProcessingRasterOptionsWidgetWrapper() );
111 addParameterWidgetFactory( new QgsProcessingHeatmapPixelSizeWidgetWrapper() );
112 addParameterWidgetFactory( new QgsProcessingReliefColorsWidgetWrapper() );
113 addParameterWidgetFactory( new QgsProcessingExecuteSqlWidgetWrapper() );
114 addParameterWidgetFactory( new QgsProcessingInterpolationPixelSizeWidgetWrapper() );
115 addParameterWidgetFactory( new QgsProcessingInterpolationSourceWidgetWrapper() );
116
117 mModelConfigWidgetFactory = std::make_unique< QgsProcessingGuiInternalModelConfigWidgetFactory >();
118 registerModelConfigWidgetFactory( mModelConfigWidgetFactory.get() );
119}
120
122{
123 const QList<QgsProcessingAlgorithmConfigurationWidgetFactory *> factories = mAlgorithmConfigurationWidgetFactories;
124 for ( QgsProcessingAlgorithmConfigurationWidgetFactory *factory : factories )
126 const QMap<QString, QgsProcessingParameterWidgetFactoryInterface *> paramFactories = mParameterWidgetFactories;
127 for ( auto it = paramFactories.constBegin(); it != paramFactories.constEnd(); ++it )
128 removeParameterWidgetFactory( it.value() );
129
130 unregisterModelConfigWidgetFactory( mModelConfigWidgetFactory.get() );
131 mModelConfigWidgetFactory.reset();
132}
133
135{
136 mAlgorithmConfigurationWidgetFactories.append( factory );
137}
138
140{
141 mAlgorithmConfigurationWidgetFactories.removeAll( factory );
142 delete factory;
143}
144
146{
147 for ( const auto *factory : mAlgorithmConfigurationWidgetFactories )
148 {
149 if ( factory->canCreateFor( algorithm ) )
150 {
151 std::unique_ptr<QgsProcessingAlgorithmConfigurationWidget> widget( factory->create( algorithm ) );
152 if ( widget )
153 widget->setAlgorithm( algorithm );
154 return widget.release();
155 }
156 }
157
158 return nullptr;
159}
160
162{
163 if ( !factory )
164 return false;
165
166 if ( mParameterWidgetFactories.contains( factory->parameterType() ) )
167 {
168 QgsLogger::warning( u"Duplicate parameter factory for %1 registered"_s.arg( factory->parameterType() ) );
169 return false;
170 }
171
172 mParameterWidgetFactories.insert( factory->parameterType(), factory );
173 return true;
174}
175
177{
178 if ( !factory )
179 return;
180
181 mParameterWidgetFactories.remove( factory->parameterType() );
182 delete factory;
183}
184
186{
187 mModelConfigWidgetFactories << factory;
188}
189
191{
192 mModelConfigWidgetFactories.removeAll( factory );
193}
194
196{
197 if ( !parameter )
198 return nullptr;
199
200 const QVariantMap metadata = parameter->metadata();
201 const QString widgetType = metadata.value( u"widget_wrapper"_s ).toMap().value( u"widget_type"_s ).toString();
202 const QString parameterType = !widgetType.isEmpty() ? widgetType : parameter->type();
203 if ( !mParameterWidgetFactories.contains( parameterType ) )
204 return nullptr;
205
206 if ( QgsProcessingParameterWidgetFactoryInterface *factory = mParameterWidgetFactories.value( parameterType ) )
207 {
208 return factory->createWidgetWrapper( parameter, type );
209 }
210 return nullptr;
211}
212
214 QgsProcessingModelAlgorithm *model, const QString &childId, const QgsProcessingParameterDefinition *parameter, QgsProcessingContext &context
215)
216{
217 if ( !parameter )
218 return nullptr;
219
220 const QString parameterType = parameter->type();
221 auto it = mParameterWidgetFactories.constFind( parameterType );
222 if ( it == mParameterWidgetFactories.constEnd() )
223 return nullptr;
224
225 return it.value()->createModelerWidgetWrapper( model, childId, parameter, context );
226}
227
229 const QString &type, QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm
230)
231{
232 auto it = mParameterWidgetFactories.constFind( type );
233 if ( it == mParameterWidgetFactories.constEnd() )
234 return nullptr;
235
236 return it.value()->createParameterDefinitionWidget( context, widgetContext, definition, algorithm );
237}
238
240 QgsProcessingModelComponent *component, QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext
241) const
242{
243 for ( auto it = mModelConfigWidgetFactories.constBegin(); it != mModelConfigWidgetFactories.constEnd(); ++it )
244 {
245 // factory may have been deleted without deregistering, don't crash!
246 if ( !it->data() )
247 continue;
248
249 if ( it->data()->supportsComponent( component ) )
250 {
251 if ( QgsProcessingModelConfigWidget *widget = it->data()->createWidget( component, context, widgetContext ) )
252 return widget;
253 }
254 }
255 return nullptr;
256}
257
259{
260 mWidgetContextGenerator = generator;
261}
262
264{
265 if ( mWidgetContextGenerator )
266 {
267 return mWidgetContextGenerator->createWidgetContext();
268 }
270}
271
273bool QgsProcessingGuiInternalModelConfigWidgetFactory::supportsComponent( QgsProcessingModelComponent *component ) const
274{
275 if ( dynamic_cast< QgsProcessingModelGroupBox * >( component ) )
276 return true;
277
278 if ( dynamic_cast< QgsProcessingModelChildAlgorithm * >( component ) )
279 return true;
280
281 if ( dynamic_cast< QgsProcessingModelParameter * >( component ) )
282 return true;
283
284 if ( dynamic_cast< QgsProcessingModelOutput * >( component ) )
285 return true;
286
287 return false;
288}
289
290QgsProcessingModelConfigWidget *QgsProcessingGuiInternalModelConfigWidgetFactory::createWidget(
291 QgsProcessingModelComponent *component, QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext
292) const
293{
294 if ( QgsProcessingModelGroupBox *groupBox = dynamic_cast< QgsProcessingModelGroupBox * >( component ) )
295 {
296 QgsModelDesignerDialog *dialog = widgetContext.modelDesignerDialog();
297 const QString boxUuid = groupBox->uuid();
298
299 auto widget = new QgsModelGroupBoxDefinitionPanelWidget( *groupBox );
300 connect( widget, &QgsModelGroupBoxDefinitionPanelWidget::widgetChanged, this, [dialog, boxUuid, widget] {
301 QgsModelGraphicsScene *modelScene = dialog->modelScene();
302 QgsModelGroupBoxGraphicItem *graphicItem = dynamic_cast< QgsModelGroupBoxGraphicItem * >( modelScene->groupBoxItem( boxUuid ) );
303 if ( !graphicItem )
304 return; // should not happen
305
306 graphicItem->applyEdit( widget->groupBox() );
307 } );
308
309 return widget;
310 }
311 else if ( QgsProcessingModelChildAlgorithm *childAlg = dynamic_cast< QgsProcessingModelChildAlgorithm * >( component ) )
312 {
313 QgsModelDesignerDialog *dialog = widgetContext.modelDesignerDialog();
314 const QString childId = childAlg->childId();
315
316 std::unique_ptr< QgsProcessingAlgorithm > algorithm( childAlg->algorithm()->create() );
317 auto widget = new QgsProcessingModelerParametersWidget( algorithm.get(), widgetContext.model(), context, childId, childAlg->configuration(), nullptr );
318 widget->setComments( childAlg->comment()->description() );
319 widget->setCommentColor( childAlg->comment()->color() );
320
321 QgsProcessingParameterWidgetContext widgetContextCopy = widgetContext;
322 widgetContextCopy.setModelChildAlgorithmId( childId );
323 widget->setWidgetContext( widgetContextCopy );
324
325 connect( widget, &QgsProcessingModelConfigWidget::widgetChanged, this, [dialog, childId, widget] {
326 QgsModelGraphicsScene *modelScene = dialog->modelScene();
327 QgsModelChildAlgorithmGraphicItem *graphicItem = modelScene->childAlgorithmItem( childId );
328 if ( !graphicItem )
329 return; // should not happen
330
331 std::unique_ptr< QgsProcessingModelChildAlgorithm > updatedAlgorithm = widget->createAlgorithm();
332 if ( updatedAlgorithm )
333 {
334 graphicItem->applyEdit( *updatedAlgorithm );
335 }
336 } );
337
338 return widget;
339 }
340 else if ( QgsProcessingModelParameter *modelParam = dynamic_cast< QgsProcessingModelParameter * >( component ) )
341 {
342 QgsModelDesignerDialog *dialog = widgetContext.modelDesignerDialog();
343 QgsProcessingModelAlgorithm *model = widgetContext.model();
344
345 const QString componentName = modelParam->parameterName();
346 const QgsProcessingParameterDefinition *existingParam = model->parameterDefinition( componentName );
347 if ( !existingParam )
348 return nullptr;
349
350 const QString comment = modelParam->comment()->description();
351 const QColor commentColor = modelParam->comment()->color();
352 const QString oldName = existingParam->name();
353 const QString oldDescription = existingParam->description();
354
355 auto widget = new QgsProcessingParameterDefinitionPanelWidget( existingParam->type(), context, widgetContext, existingParam, model );
356 widget->setComments( comment );
357 widget->setCommentColor( commentColor );
358 if ( widgetContext.processingContextGenerator() )
359 {
360 widget->registerProcessingContextGenerator( widgetContext.processingContextGenerator() );
361 }
362
363 auto existingParamName = std::make_shared< QString >( existingParam->name() );
364
365 connect( widget, &QgsProcessingParameterDefinitionPanelWidget::widgetChanged, this, [dialog, componentName, oldDescription, oldName, existingParamName, widget] {
366 QgsModelGraphicsScene *modelScene = dialog->modelScene();
367 if ( !modelScene )
368 return;
369
370 QgsModelParameterGraphicItem *graphicItem = dynamic_cast< QgsModelParameterGraphicItem * >( modelScene->parameterItem( componentName ) );
371 if ( !graphicItem )
372 return; // should not happen
373
374 std::unique_ptr< QgsProcessingParameterDefinition > newParam( widget->createParameter( *existingParamName ) );
375 if ( !newParam )
376 return;
377
378 const QString comment = widget->comments();
379 const QColor commentColor = widget->commentColor();
380 *existingParamName = graphicItem->applyEdit( std::move( newParam ), oldDescription, oldName, comment, commentColor );
381 } );
382
383 return widget;
384 }
385 else if ( QgsProcessingModelOutput *modelOutput = dynamic_cast< QgsProcessingModelOutput * >( component ) )
386 {
387 QgsModelDesignerDialog *dialog = widgetContext.modelDesignerDialog();
388 QgsProcessingModelAlgorithm *model = widgetContext.model();
389
390 const QString childId = modelOutput->childId();
391 const QString childOutputName = modelOutput->childOutputName();
392
393 const QgsProcessingParameterDefinition *existingParam = model->modelParameterFromChildIdAndOutputName( childId, modelOutput->name() );
394 if ( !existingParam )
395 return nullptr;
396
397 const QString comment = modelOutput->comment()->description();
398 const QColor commentColor = modelOutput->comment()->color();
399
400 auto widget = new QgsProcessingParameterDefinitionPanelWidget( existingParam->type(), context, widgetContext, existingParam, model );
401 widget->setComments( comment );
402 widget->setCommentColor( commentColor );
403 if ( widgetContext.processingContextGenerator() )
404 {
405 widget->registerProcessingContextGenerator( widgetContext.processingContextGenerator() );
406 }
407
408 connect( widget, &QgsProcessingParameterDefinitionPanelWidget::widgetChanged, this, [dialog, childId, childOutputName, widget] {
409 QgsModelGraphicsScene *modelScene = dialog->modelScene();
410 if ( !modelScene )
411 return;
412
413 QgsModelOutputGraphicItem *graphicItem = dynamic_cast< QgsModelOutputGraphicItem * >( modelScene->outputItem( childId, childOutputName ) );
414 if ( !graphicItem )
415 return; // should not happen
416
417 std::unique_ptr< QgsProcessingParameterDefinition > newParam( widget->createParameter() );
418 if ( !newParam )
419 return;
420
421 graphicItem
422 ->applyEdit( newParam->description(), newParam->description(), newParam->defaultValue(), !newParam->flags().testFlag( Qgis::ProcessingParameterFlag::Optional ), widget->comments(), widget->commentColor() );
423 } );
424
425 return widget;
426 }
427
428 return nullptr;
429}
ProcessingMode
Types of modes which Processing widgets can be created for.
Definition qgis.h:3888
@ Optional
Parameter is optional.
Definition qgis.h:3984
A widget wrapper for Processing parameter value widgets.
static void warning(const QString &msg)
Goes to qWarning.
A widget which allows users to specify the properties of a model group box.
void widgetChanged()
Emitted when the widget state changes.
Abstract base class for widgets which allow users to specify the properties of a Processing parameter...
Interface base class for factories for algorithm configuration widgets.
A configuration widget for processing algorithms allows providing additional configuration options di...
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
void addAlgorithmConfigurationWidgetFactory(QgsProcessingAlgorithmConfigurationWidgetFactory *factory)
Add a new configuration widget factory for customized algorithm configuration widgets.
bool addParameterWidgetFactory(QgsProcessingParameterWidgetFactoryInterface *factory)
Adds a parameter widget factory to the registry, allowing widget creation for parameters of the match...
void removeAlgorithmConfigurationWidgetFactory(QgsProcessingAlgorithmConfigurationWidgetFactory *factory)
Remove a configuration widget factory for customized algorithm configuration widgets.
void registerModelConfigWidgetFactory(QgsProcessingModelConfigWidgetFactory *factory)
Register a new factory class for creating panel widgets that can be shown in the Processing model des...
void unregisterModelConfigWidgetFactory(QgsProcessingModelConfigWidgetFactory *factory)
Unregister a previously registered factory for creating panel widgets that can be shown in the Proces...
QgsProcessingAlgorithmConfigurationWidget * algorithmConfigurationWidget(const QgsProcessingAlgorithm *algorithm) const
Gets the configuration widget for an algorithm.
QgsAbstractProcessingParameterWidgetWrapper * createParameterWidgetWrapper(const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type)
Creates a new parameter widget wrapper for the given parameter.
void registerWidgetContextGenerator(QgsProcessingWidgetContextGenerator *generator)
Register a Processing widget context generator class that will be used to retrieve a widget context w...
QgsProcessingAbstractParameterDefinitionWidget * createParameterDefinitionWidget(const QString &type, QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition=nullptr, const QgsProcessingAlgorithm *algorithm=nullptr)
Creates a new parameter definition widget allowing for configuration of an instance of a specific par...
QgsProcessingModelerParameterWidget * createModelerParameterWidget(QgsProcessingModelAlgorithm *model, const QString &childId, const QgsProcessingParameterDefinition *parameter, QgsProcessingContext &context)
Creates a new modeler parameter widget for the given parameter.
void removeParameterWidgetFactory(QgsProcessingParameterWidgetFactoryInterface *factory)
Removes a parameter widget factory from the registry.
QgsProcessingModelConfigWidget * createModelConfigWidgetForComponent(QgsProcessingModelComponent *component, QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext) const
Creates a new widget for configuring a Processing model component.
QgsProcessingParameterWidgetContext createWidgetContext() override
Register a Processing widget context.
Factory class for creating panel widgets that can be shown in the Processing model designer dialog.
A panel widget that can be shown in the Processing model designer dialog for configuring part of the ...
A widget for customising the value of Processing algorithm parameters inside a Processing model.
A panel config widget combining parameter settings and comments for a child algorithm in a Processing...
A panel widget which allows users to specify the properties of a Processing parameter.
Base class for the definition of processing parameters.
QVariantMap metadata() const
Returns the parameter's freeform metadata.
QString description() const
Returns the description for the parameter.
virtual QString type() const =0
Unique parameter type name.
QString name() const
Returns the name of the parameter.
Contains settings which reflect the context in which a Processing parameter widget is shown.
QgsModelDesignerDialog * modelDesignerDialog() const
Returns the associated model designer dialog, if applicable.
void setModelChildAlgorithmId(const QString &id)
Sets the child algorithm id within the model which the parameter widget is associated with.
QgsProcessingModelAlgorithm * model() const
Returns the model which the parameter widget is associated with.
QgsProcessingContextGenerator * processingContextGenerator() const
Returns the Processing context generator class that will be used to retrieve a Processing context for...
An interface for Processing widget wrapper factories.
virtual QString parameterType() const =0
Returns the type string for the parameter type the factory is associated with.
An interface for objects which can create Processing widget contexts.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call