17 #include "qgsprocessingmodelchildparametersource.h"
18 #include "qgsprocessingmodelalgorithm.h"
21 #include "qgsprocessingmodelgroupbox.h"
25 #include <QGraphicsSceneMouseEvent>
26 #include <QPushButton>
30 QgsModelGraphicsScene::QgsModelGraphicsScene( QObject *parent )
31 : QGraphicsScene( parent )
33 setItemIndexMethod( QGraphicsScene::NoIndex );
36 QgsProcessingModelAlgorithm *QgsModelGraphicsScene::model()
41 void QgsModelGraphicsScene::setModel( QgsProcessingModelAlgorithm *model )
46 void QgsModelGraphicsScene::setFlag( QgsModelGraphicsScene::Flag flag,
bool on )
54 void QgsModelGraphicsScene::mousePressEvent( QGraphicsSceneMouseEvent *event )
56 if ( event->button() != Qt::LeftButton )
58 QGraphicsScene::mousePressEvent( event );
61 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createParameterGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelParameter *param )
const
63 return new QgsModelParameterGraphicItem( param, model,
nullptr );
66 QgsModelChildAlgorithmGraphicItem *QgsModelGraphicsScene::createChildAlgGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelChildAlgorithm *child )
const
68 return new QgsModelChildAlgorithmGraphicItem( child, model,
nullptr );
71 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createOutputGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelOutput *output )
const
73 return new QgsModelOutputGraphicItem( output, model,
nullptr );
76 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createCommentGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem )
const
78 return new QgsModelCommentGraphicItem( comment, parentItem, model,
nullptr );
81 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createGroupBoxGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelGroupBox *box )
const
83 return new QgsModelGroupBoxGraphicItem( box, model,
nullptr );
86 void QgsModelGraphicsScene::createItems( QgsProcessingModelAlgorithm *model,
QgsProcessingContext &context )
89 const QList<QgsProcessingModelGroupBox> boxes = model->groupBoxes();
90 mGroupBoxItems.clear();
91 for (
const QgsProcessingModelGroupBox &box : boxes )
93 QgsModelComponentGraphicItem *item = createGroupBoxGraphicItem( model, box.clone() );
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 );
103 const QMap<QString, QgsProcessingModelParameter> params = model->parameterComponents();
104 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
106 QgsModelComponentGraphicItem *item = createParameterGraphicItem( model, it.value().clone() );
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 );
114 addCommentItemForComponent( model, it.value(), item );
118 for (
auto it = params.constBegin(); it != params.constEnd(); ++it )
122 for (
const QString &otherName : parameterLinks )
124 if ( mParameterItems.contains( it.key() ) && mParameterItems.contains( otherName ) )
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() );
134 const QMap<QString, QgsProcessingModelChildAlgorithm> childAlgs = model->childAlgorithms();
135 for (
auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
137 QgsModelChildAlgorithmGraphicItem *item = createChildAlgGraphicItem( model, it.value().clone() );
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 );
147 addCommentItemForComponent( model, it.value(), item );
151 for (
auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
155 if ( !it.value().algorithm() )
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 )
168 const QList< LinkSource > sourceItems = linkSourcesForParameterValue( model, QVariant::fromValue( source ), it.value().childId(), context );
169 for (
const LinkSource &link : sourceItems )
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 );
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,
182 QgsModelArrowItem::Marker::Circle );
186 if ( parameter->isDestination() )
192 const QList< QgsProcessingModelChildDependency > dependencies = it.value().dependencies();
193 for (
const QgsProcessingModelChildDependency &depend : dependencies )
195 if ( depend.conditionalBranch.isEmpty() || !model->childAlgorithm( depend.childId ).algorithm() )
197 addItem(
new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
207 if ( output->name() == depend.conditionalBranch )
215 addItem(
new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), Qt::BottomEdge, i, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
221 for (
auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
223 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
224 QMap< QString, QgsModelComponentGraphicItem * > outputItems;
226 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
228 QgsModelComponentGraphicItem *item = createOutputGraphicItem( model, outputIt.value().clone() );
230 connect( item, &QgsModelComponentGraphicItem::requestModelRepaint,
this, &QgsModelGraphicsScene::rebuildRequired );
231 connect( item, &QgsModelComponentGraphicItem::changed,
this, &QgsModelGraphicsScene::componentChanged );
232 connect( item, &QgsModelComponentGraphicItem::aboutToChange,
this, &QgsModelGraphicsScene::componentAboutToChange );
234 QPointF pos = outputIt.value().position();
238 if ( it.value().algorithm() )
243 if ( childAlgOutput->name() == outputIt.value().childOutputName() )
253 outputItems.insert( outputIt.key(), item );
254 addItem(
new QgsModelArrowItem( mChildAlgorithmItems[it.value().childId()], Qt::BottomEdge, idx, QgsModelArrowItem::Marker::Circle, item, QgsModelArrowItem::Marker::Circle ) );
256 addCommentItemForComponent( model, outputIt.value(), item );
258 mOutputItems.insert( it.value().childId(), outputItems );
262 QList<QgsModelComponentGraphicItem *> QgsModelGraphicsScene::selectedComponentItems()
264 QList<QgsModelComponentGraphicItem *> componentItemList;
266 const QList<QGraphicsItem *> graphicsItemList = selectedItems();
267 for ( QGraphicsItem *item : graphicsItemList )
269 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( item ) )
271 componentItemList.push_back( componentItem );
275 return componentItemList;
278 QgsModelComponentGraphicItem *QgsModelGraphicsScene::componentItemAt( QPointF position )
const
281 const QList<QGraphicsItem *> itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );
283 for ( QGraphicsItem *graphicsItem : itemList )
285 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( graphicsItem ) )
287 return componentItem;
293 QgsModelComponentGraphicItem *QgsModelGraphicsScene::groupBoxItem(
const QString &uuid )
295 return mGroupBoxItems.value( uuid );
298 void QgsModelGraphicsScene::selectAll()
301 QgsModelComponentGraphicItem *focusedItem =
nullptr;
302 const QList<QGraphicsItem *> itemList = items();
303 for ( QGraphicsItem *graphicsItem : itemList )
305 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( graphicsItem ) )
307 componentItem->setSelected(
true );
309 focusedItem = componentItem;
312 emit selectedItemChanged( focusedItem );
315 void QgsModelGraphicsScene::deselectAll()
320 const QList<QGraphicsItem *> selectedItemList = selectedItems();
321 for ( QGraphicsItem *item : selectedItemList )
323 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( item ) )
325 componentItem->setSelected(
false );
328 emit selectedItemChanged(
nullptr );
331 void QgsModelGraphicsScene::setSelectedItem( QgsModelComponentGraphicItem *item )
336 item->setSelected(
true );
338 emit selectedItemChanged( item );
341 void QgsModelGraphicsScene::setChildAlgorithmResults(
const QVariantMap &results )
343 mChildResults = results;
345 for (
auto it = mChildResults.constBegin(); it != mChildResults.constEnd(); ++it )
347 if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
349 item->setResults( it.value().toMap() );
354 void QgsModelGraphicsScene::setChildAlgorithmInputs(
const QVariantMap &inputs )
356 mChildInputs = inputs;
358 for (
auto it = mChildInputs.constBegin(); it != mChildInputs.constEnd(); ++it )
360 if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
362 item->setInputs( it.value().toMap() );
367 QList<QgsModelGraphicsScene::LinkSource> QgsModelGraphicsScene::linkSourcesForParameterValue( QgsProcessingModelAlgorithm *model,
const QVariant &value,
const QString &childId,
QgsProcessingContext &context )
const
369 QList<QgsModelGraphicsScene::LinkSource> res;
370 if ( value.type() == QVariant::List )
372 const QVariantList list = value.toList();
373 for (
const QVariant &v : list )
374 res.append( linkSourcesForParameterValue( model, v, childId, context ) );
376 else if ( value.type() == QVariant::StringList )
378 const QStringList list = value.toStringList();
379 for (
const QString &v : list )
380 res.append( linkSourcesForParameterValue( model, v, childId, context ) );
382 else if ( value.canConvert< QgsProcessingModelChildParameterSource >() )
384 const QgsProcessingModelChildParameterSource source = value.value< QgsProcessingModelChildParameterSource >();
385 switch ( source.source() )
387 case QgsProcessingModelChildParameterSource::ModelParameter:
390 l.item = mParameterItems.value( source.parameterName() );
394 case QgsProcessingModelChildParameterSource::ChildOutput:
396 if ( !model->childAlgorithm( source.outputChildId() ).algorithm() )
403 if ( output->name() == source.outputName() )
407 if ( mChildAlgorithmItems.contains( source.outputChildId() ) )
410 l.item = mChildAlgorithmItems.value( source.outputChildId() );
411 l.edge = Qt::BottomEdge;
419 case QgsProcessingModelChildParameterSource::Expression:
421 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = model->variablesForChildAlgorithm( childId, context );
423 const QSet<QString> vars = exp.referencedVariables();
424 for (
const QString &v : vars )
426 if ( variables.contains( v ) )
428 res.append( linkSourcesForParameterValue( model, QVariant::fromValue( variables.value( v ).source ), childId, context ) );
434 case QgsProcessingModelChildParameterSource::StaticValue:
435 case QgsProcessingModelChildParameterSource::ExpressionText:
436 case QgsProcessingModelChildParameterSource::ModelOutput:
443 void QgsModelGraphicsScene::addCommentItemForComponent( QgsProcessingModelAlgorithm *model,
const QgsProcessingModelComponent &component, QgsModelComponentGraphicItem *parentItem )
445 if ( mFlags & FlagHideComments || !component.comment() || component.comment()->description().isEmpty() )
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 );
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() );
465 void QgsModelGraphicsScene::setMessageBar(
QgsMessageBar *messageBar )
467 mMessageBar = messageBar;
470 void QgsModelGraphicsScene::showWarning(
const QString &shortMessage,
const QString &title,
const QString &longMessage,
Qgis::MessageLevel level )
472 QgsMessageBarItem *messageWidget = mMessageBar->createMessage( QString(), shortMessage );
473 QPushButton *detailsButton =
new QPushButton( tr(
"Details" ) );
474 connect( detailsButton, &QPushButton::clicked, detailsButton, [ = ]
476 QgsMessageViewer *dialog =
new QgsMessageViewer( detailsButton );
477 dialog->setTitle( title );
479 dialog->showMessage();
481 messageWidget->layout()->addWidget( detailsButton );
482 mMessageBar->clearWidgets();
483 mMessageBar->pushWidget( messageWidget, level, 0 );