QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsmodelgraphicsscene.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmodelgraphicsscene.cpp
3  ----------------------------------
4  Date : March 2020
5  Copyright : (C) 2020 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsmodelgraphicsscene.h"
17 #include "qgsprocessingmodelchildparametersource.h"
18 #include "qgsprocessingmodelalgorithm.h"
20 #include "qgsmodelarrowitem.h"
21 #include "qgsprocessingmodelgroupbox.h"
22 #include "qgsmessagebar.h"
23 #include "qgsmessagebaritem.h"
24 #include "qgsmessageviewer.h"
25 #include <QGraphicsSceneMouseEvent>
26 #include <QPushButton>
27 
29 
30 QgsModelGraphicsScene::QgsModelGraphicsScene( QObject *parent )
31  : QGraphicsScene( parent )
32 {
33  setItemIndexMethod( QGraphicsScene::NoIndex );
34 }
35 
36 QgsProcessingModelAlgorithm *QgsModelGraphicsScene::model()
37 {
38  return mModel;
39 }
40 
41 void QgsModelGraphicsScene::setModel( QgsProcessingModelAlgorithm *model )
42 {
43  mModel = model;
44 }
45 
46 void QgsModelGraphicsScene::setFlag( QgsModelGraphicsScene::Flag flag, bool on )
47 {
48  if ( on )
49  mFlags |= flag;
50  else
51  mFlags &= ~flag;
52 }
53 
54 void QgsModelGraphicsScene::mousePressEvent( QGraphicsSceneMouseEvent *event )
55 {
56  if ( event->button() != Qt::LeftButton )
57  return;
58  QGraphicsScene::mousePressEvent( event );
59 }
60 
61 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createParameterGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelParameter *param ) const
62 {
63  return new QgsModelParameterGraphicItem( param, model, nullptr );
64 }
65 
66 QgsModelChildAlgorithmGraphicItem *QgsModelGraphicsScene::createChildAlgGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelChildAlgorithm *child ) const
67 {
68  return new QgsModelChildAlgorithmGraphicItem( child, model, nullptr );
69 }
70 
71 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createOutputGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelOutput *output ) const
72 {
73  return new QgsModelOutputGraphicItem( output, model, nullptr );
74 }
75 
76 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createCommentGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem ) const
77 {
78  return new QgsModelCommentGraphicItem( comment, parentItem, model, nullptr );
79 }
80 
81 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createGroupBoxGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelGroupBox *box ) const
82 {
83  return new QgsModelGroupBoxGraphicItem( box, model, nullptr );
84 }
85 
86 void QgsModelGraphicsScene::createItems( QgsProcessingModelAlgorithm *model, QgsProcessingContext &context )
87 {
88  // model group boxes
89  const QList<QgsProcessingModelGroupBox> boxes = model->groupBoxes();
90  mGroupBoxItems.clear();
91  for ( const QgsProcessingModelGroupBox &box : boxes )
92  {
93  QgsModelComponentGraphicItem *item = createGroupBoxGraphicItem( model, box.clone() );
94  addItem( item );
95  item->setPos( box.position().x(), box.position().y() );
96  mGroupBoxItems.insert( box.uuid(), item );
97  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
98  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
99  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
100  }
101 
102  // model input parameters
103  const QMap<QString, QgsProcessingModelParameter> params = model->parameterComponents();
104  for ( auto it = params.constBegin(); it != params.constEnd(); ++it )
105  {
106  QgsModelComponentGraphicItem *item = createParameterGraphicItem( model, it.value().clone() );
107  addItem( item );
108  item->setPos( it.value().position().x(), it.value().position().y() );
109  mParameterItems.insert( it.value().parameterName(), item );
110  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
111  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
112  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
113 
114  addCommentItemForComponent( model, it.value(), item );
115  }
116 
117  // input dependency arrows
118  for ( auto it = params.constBegin(); it != params.constEnd(); ++it )
119  {
120  const QgsProcessingParameterDefinition *parameterDef = model->parameterDefinition( it.key() );
121  const QStringList parameterLinks = parameterDef->dependsOnOtherParameters();
122  for ( const QString &otherName : parameterLinks )
123  {
124  if ( mParameterItems.contains( it.key() ) && mParameterItems.contains( otherName ) )
125  {
126  std::unique_ptr< QgsModelArrowItem > arrow = qgis::make_unique< QgsModelArrowItem >( mParameterItems.value( otherName ), QgsModelArrowItem::Marker::Circle, mParameterItems.value( it.key() ), QgsModelArrowItem::Marker::ArrowHead );
127  arrow->setPenStyle( Qt::DotLine );
128  addItem( arrow.release() );
129  }
130  }
131  }
132 
133  // child algorithms
134  const QMap<QString, QgsProcessingModelChildAlgorithm> childAlgs = model->childAlgorithms();
135  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
136  {
137  QgsModelChildAlgorithmGraphicItem *item = createChildAlgGraphicItem( model, it.value().clone() );
138  addItem( item );
139  item->setPos( it.value().position().x(), it.value().position().y() );
140  item->setResults( mChildResults.value( it.value().childId() ).toMap() );
141  item->setInputs( mChildInputs.value( it.value().childId() ).toMap() );
142  mChildAlgorithmItems.insert( it.value().childId(), item );
143  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
144  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
145  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
146 
147  addCommentItemForComponent( model, it.value(), item );
148  }
149 
150  // arrows linking child algorithms
151  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
152  {
153  int topIdx = 0;
154  int bottomIdx = 0;
155  if ( !it.value().algorithm() )
156  continue;
157 
158  const QgsProcessingParameterDefinitions parameters = it.value().algorithm()->parameterDefinitions();
159  for ( const QgsProcessingParameterDefinition *parameter : parameters )
160  {
161  if ( !( parameter->flags() & QgsProcessingParameterDefinition::FlagHidden ) )
162  {
163  QList< QgsProcessingModelChildParameterSource > sources;
164  if ( it.value().parameterSources().contains( parameter->name() ) )
165  sources = it.value().parameterSources()[parameter->name()];
166  for ( const QgsProcessingModelChildParameterSource &source : sources )
167  {
168  const QList< LinkSource > sourceItems = linkSourcesForParameterValue( model, QVariant::fromValue( source ), it.value().childId(), context );
169  for ( const LinkSource &link : sourceItems )
170  {
171  if ( !link.item )
172  continue;
173  QgsModelArrowItem *arrow = nullptr;
174  if ( link.linkIndex == -1 )
175  arrow = new QgsModelArrowItem( link.item, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), parameter->isDestination() ? Qt::BottomEdge : Qt::TopEdge, parameter->isDestination() ? bottomIdx : topIdx, QgsModelArrowItem::Marker::Circle );
176  else
177  arrow = new QgsModelArrowItem( link.item, link.edge, link.linkIndex, true, QgsModelArrowItem::Marker::Circle,
178  mChildAlgorithmItems.value( it.value().childId() ),
179  parameter->isDestination() ? Qt::BottomEdge : Qt::TopEdge,
180  parameter->isDestination() ? bottomIdx : topIdx,
181  true,
182  QgsModelArrowItem::Marker::Circle );
183  addItem( arrow );
184  }
185  }
186  if ( parameter->isDestination() )
187  bottomIdx++;
188  else
189  topIdx++;
190  }
191  }
192  const QList< QgsProcessingModelChildDependency > dependencies = it.value().dependencies();
193  for ( const QgsProcessingModelChildDependency &depend : dependencies )
194  {
195  if ( depend.conditionalBranch.isEmpty() || !model->childAlgorithm( depend.childId ).algorithm() )
196  {
197  addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
198  }
199  else
200  {
201  // find branch link point
202  const QgsProcessingOutputDefinitions outputs = model->childAlgorithm( depend.childId ).algorithm()->outputDefinitions();
203  int i = 0;
204  bool found = false;
205  for ( const QgsProcessingOutputDefinition *output : outputs )
206  {
207  if ( output->name() == depend.conditionalBranch )
208  {
209  found = true;
210  break;
211  }
212  i++;
213  }
214  if ( found )
215  addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), Qt::BottomEdge, i, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
216  }
217  }
218  }
219 
220  // and finally the model outputs
221  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
222  {
223  const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
224  QMap< QString, QgsModelComponentGraphicItem * > outputItems;
225 
226  for ( auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
227  {
228  QgsModelComponentGraphicItem *item = createOutputGraphicItem( model, outputIt.value().clone() );
229  addItem( item );
230  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
231  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
232  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
233 
234  QPointF pos = outputIt.value().position();
235  int idx = -1;
236  int i = 0;
237  // find the actual index of the linked output from the child algorithm it comes from
238  if ( it.value().algorithm() )
239  {
240  const QgsProcessingOutputDefinitions sourceChildAlgOutputs = it.value().algorithm()->outputDefinitions();
241  for ( const QgsProcessingOutputDefinition *childAlgOutput : sourceChildAlgOutputs )
242  {
243  if ( childAlgOutput->name() == outputIt.value().childOutputName() )
244  {
245  idx = i;
246  break;
247  }
248  i++;
249  }
250  }
251 
252  item->setPos( pos );
253  outputItems.insert( outputIt.key(), item );
254  addItem( new QgsModelArrowItem( mChildAlgorithmItems[it.value().childId()], Qt::BottomEdge, idx, QgsModelArrowItem::Marker::Circle, item, QgsModelArrowItem::Marker::Circle ) );
255 
256  addCommentItemForComponent( model, outputIt.value(), item );
257  }
258  mOutputItems.insert( it.value().childId(), outputItems );
259  }
260 }
261 
262 QList<QgsModelComponentGraphicItem *> QgsModelGraphicsScene::selectedComponentItems()
263 {
264  QList<QgsModelComponentGraphicItem *> componentItemList;
265 
266  const QList<QGraphicsItem *> graphicsItemList = selectedItems();
267  for ( QGraphicsItem *item : graphicsItemList )
268  {
269  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
270  {
271  componentItemList.push_back( componentItem );
272  }
273  }
274 
275  return componentItemList;
276 }
277 
278 QgsModelComponentGraphicItem *QgsModelGraphicsScene::componentItemAt( QPointF position ) const
279 {
280  //get a list of items which intersect the specified position, in descending z order
281  const QList<QGraphicsItem *> itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );
282 
283  for ( QGraphicsItem *graphicsItem : itemList )
284  {
285  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( graphicsItem ) )
286  {
287  return componentItem;
288  }
289  }
290  return nullptr;
291 }
292 
293 QgsModelComponentGraphicItem *QgsModelGraphicsScene::groupBoxItem( const QString &uuid )
294 {
295  return mGroupBoxItems.value( uuid );
296 }
297 
298 void QgsModelGraphicsScene::selectAll()
299 {
300  //select all items in scene
301  QgsModelComponentGraphicItem *focusedItem = nullptr;
302  const QList<QGraphicsItem *> itemList = items();
303  for ( QGraphicsItem *graphicsItem : itemList )
304  {
305  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( graphicsItem ) )
306  {
307  componentItem->setSelected( true );
308  if ( !focusedItem )
309  focusedItem = componentItem;
310  }
311  }
312  emit selectedItemChanged( focusedItem );
313 }
314 
315 void QgsModelGraphicsScene::deselectAll()
316 {
317  //we can't use QGraphicsScene::clearSelection, as that emits no signals
318  //and we don't know which items are being deselected
319  //instead, do the clear selection manually...
320  const QList<QGraphicsItem *> selectedItemList = selectedItems();
321  for ( QGraphicsItem *item : selectedItemList )
322  {
323  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
324  {
325  componentItem->setSelected( false );
326  }
327  }
328  emit selectedItemChanged( nullptr );
329 }
330 
331 void QgsModelGraphicsScene::setSelectedItem( QgsModelComponentGraphicItem *item )
332 {
333  whileBlocking( this )->deselectAll();
334  if ( item )
335  {
336  item->setSelected( true );
337  }
338  emit selectedItemChanged( item );
339 }
340 
341 void QgsModelGraphicsScene::setChildAlgorithmResults( const QVariantMap &results )
342 {
343  mChildResults = results;
344 
345  for ( auto it = mChildResults.constBegin(); it != mChildResults.constEnd(); ++it )
346  {
347  if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
348  {
349  item->setResults( it.value().toMap() );
350  }
351  }
352 }
353 
354 void QgsModelGraphicsScene::setChildAlgorithmInputs( const QVariantMap &inputs )
355 {
356  mChildInputs = inputs;
357 
358  for ( auto it = mChildInputs.constBegin(); it != mChildInputs.constEnd(); ++it )
359  {
360  if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
361  {
362  item->setInputs( it.value().toMap() );
363  }
364  }
365 }
366 
367 QList<QgsModelGraphicsScene::LinkSource> QgsModelGraphicsScene::linkSourcesForParameterValue( QgsProcessingModelAlgorithm *model, const QVariant &value, const QString &childId, QgsProcessingContext &context ) const
368 {
369  QList<QgsModelGraphicsScene::LinkSource> res;
370  if ( value.type() == QVariant::List )
371  {
372  const QVariantList list = value.toList();
373  for ( const QVariant &v : list )
374  res.append( linkSourcesForParameterValue( model, v, childId, context ) );
375  }
376  else if ( value.type() == QVariant::StringList )
377  {
378  const QStringList list = value.toStringList();
379  for ( const QString &v : list )
380  res.append( linkSourcesForParameterValue( model, v, childId, context ) );
381  }
382  else if ( value.canConvert< QgsProcessingModelChildParameterSource >() )
383  {
384  const QgsProcessingModelChildParameterSource source = value.value< QgsProcessingModelChildParameterSource >();
385  switch ( source.source() )
386  {
387  case QgsProcessingModelChildParameterSource::ModelParameter:
388  {
389  LinkSource l;
390  l.item = mParameterItems.value( source.parameterName() );
391  res.append( l );
392  break;
393  }
394  case QgsProcessingModelChildParameterSource::ChildOutput:
395  {
396  if ( !model->childAlgorithm( source.outputChildId() ).algorithm() )
397  break;
398 
399  const QgsProcessingOutputDefinitions outputs = model->childAlgorithm( source.outputChildId() ).algorithm()->outputDefinitions();
400  int i = 0;
401  for ( const QgsProcessingOutputDefinition *output : outputs )
402  {
403  if ( output->name() == source.outputName() )
404  break;
405  i++;
406  }
407  if ( mChildAlgorithmItems.contains( source.outputChildId() ) )
408  {
409  LinkSource l;
410  l.item = mChildAlgorithmItems.value( source.outputChildId() );
411  l.edge = Qt::BottomEdge;
412  l.linkIndex = i;
413  res.append( l );
414  }
415 
416  break;
417  }
418 
419  case QgsProcessingModelChildParameterSource::Expression:
420  {
421  const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = model->variablesForChildAlgorithm( childId, context );
422  QgsExpression exp( source.expression() );
423  const QSet<QString> vars = exp.referencedVariables();
424  for ( const QString &v : vars )
425  {
426  if ( variables.contains( v ) )
427  {
428  res.append( linkSourcesForParameterValue( model, QVariant::fromValue( variables.value( v ).source ), childId, context ) );
429  }
430  }
431  break;
432  }
433 
434  case QgsProcessingModelChildParameterSource::StaticValue:
435  case QgsProcessingModelChildParameterSource::ExpressionText:
436  case QgsProcessingModelChildParameterSource::ModelOutput:
437  break;
438  }
439  }
440  return res;
441 }
442 
443 void QgsModelGraphicsScene::addCommentItemForComponent( QgsProcessingModelAlgorithm *model, const QgsProcessingModelComponent &component, QgsModelComponentGraphicItem *parentItem )
444 {
445  if ( mFlags & FlagHideComments || !component.comment() || component.comment()->description().isEmpty() )
446  return;
447 
448  QgsModelComponentGraphicItem *commentItem = createCommentGraphicItem( model, component.comment()->clone(), parentItem );
449  commentItem->setPos( component.comment()->position().x(), component.comment()->position().y() );
450  addItem( commentItem );
451  connect( commentItem, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
452  connect( commentItem, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
453  connect( commentItem, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
454 
455  std::unique_ptr< QgsModelArrowItem > arrow = qgis::make_unique< QgsModelArrowItem >( parentItem, QgsModelArrowItem::Circle, commentItem, QgsModelArrowItem::Circle );
456  arrow->setPenStyle( Qt::DotLine );
457  addItem( arrow.release() );
458 }
459 
460 QgsMessageBar *QgsModelGraphicsScene::messageBar() const
461 {
462  return mMessageBar;
463 }
464 
465 void QgsModelGraphicsScene::setMessageBar( QgsMessageBar *messageBar )
466 {
467  mMessageBar = messageBar;
468 }
469 
470 void QgsModelGraphicsScene::showWarning( const QString &shortMessage, const QString &title, const QString &longMessage, Qgis::MessageLevel level )
471 {
472  QgsMessageBarItem *messageWidget = mMessageBar->createMessage( QString(), shortMessage );
473  QPushButton *detailsButton = new QPushButton( tr( "Details" ) );
474  connect( detailsButton, &QPushButton::clicked, detailsButton, [ = ]
475  {
476  QgsMessageViewer *dialog = new QgsMessageViewer( detailsButton );
477  dialog->setTitle( title );
478  dialog->setMessage( longMessage, QgsMessageOutput::MessageHtml );
479  dialog->showMessage();
480  } );
481  messageWidget->layout()->addWidget( detailsButton );
482  mMessageBar->clearWidgets();
483  mMessageBar->pushWidget( messageWidget, level, 0 );
484 }
485 
487 
qgsmessagebaritem.h
algorithm
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
QgsProcessingParameterDefinition
Base class for the definition of processing parameters.
Definition: qgsprocessingparameters.h:331
QgsProcessingParameterDefinitions
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.
Definition: qgsprocessingparameters.h:761
qgsmodelarrowitem.h
QgsProcessingAlgorithm::outputDefinitions
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
Definition: qgsprocessingalgorithm.h:306
QgsProcessingOutputDefinition
Base class for the definition of processing outputs.
Definition: qgsprocessingoutputs.h:42
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsMessageBarItem
Represents an item shown within a QgsMessageBar widget.
Definition: qgsmessagebaritem.h:39
qgsmessageviewer.h
QgsMessageBar
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
qgsmessagebar.h
qgsmodelcomponentgraphicitem.h
qgsmodelgraphicsscene.h
Qgis::MessageLevel
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:89
QgsProcessingParameterDefinition::FlagHidden
@ FlagHidden
Parameter is hidden and should not be shown to users.
Definition: qgsprocessingparameters.h:424
QgsMessageOutput::MessageHtml
@ MessageHtml
Definition: qgsmessageoutput.h:47
QgsProcessingOutputDefinitions
QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefinitions
List of processing parameters.
Definition: qgsprocessingoutputs.h:143
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsProcessingParameterDefinition::dependsOnOtherParameters
virtual QStringList dependsOnOtherParameters() const
Returns a list of other parameter names on which this parameter is dependent (e.g.
Definition: qgsprocessingparameters.h:602