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 );
187 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 ) );
206 if ( output->name() == depend.conditionalBranch )
210 addItem(
new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), Qt::BottomEdge, i, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
216 for (
auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
218 const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
219 QMap< QString, QgsModelComponentGraphicItem * > outputItems;
221 for (
auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
223 QgsModelComponentGraphicItem *item = createOutputGraphicItem( model, outputIt.value().clone() );
225 connect( item, &QgsModelComponentGraphicItem::requestModelRepaint,
this, &QgsModelGraphicsScene::rebuildRequired );
226 connect( item, &QgsModelComponentGraphicItem::changed,
this, &QgsModelGraphicsScene::componentChanged );
227 connect( item, &QgsModelComponentGraphicItem::aboutToChange,
this, &QgsModelGraphicsScene::componentAboutToChange );
229 QPointF pos = outputIt.value().position();
233 if ( it.value().algorithm() )
238 if ( childAlgOutput->name() == outputIt.value().childOutputName() )
248 outputItems.insert( outputIt.key(), item );
249 addItem(
new QgsModelArrowItem( mChildAlgorithmItems[it.value().childId()], Qt::BottomEdge, idx, QgsModelArrowItem::Marker::Circle, item, QgsModelArrowItem::Marker::Circle ) );
251 addCommentItemForComponent( model, outputIt.value(), item );
253 mOutputItems.insert( it.value().childId(), outputItems );
257 QList<QgsModelComponentGraphicItem *> QgsModelGraphicsScene::selectedComponentItems()
259 QList<QgsModelComponentGraphicItem *> componentItemList;
261 const QList<QGraphicsItem *> graphicsItemList = selectedItems();
262 for ( QGraphicsItem *item : graphicsItemList )
264 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( item ) )
266 componentItemList.push_back( componentItem );
270 return componentItemList;
273 QgsModelComponentGraphicItem *QgsModelGraphicsScene::componentItemAt( QPointF position )
const
276 const QList<QGraphicsItem *> itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );
278 for ( QGraphicsItem *graphicsItem : itemList )
280 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( graphicsItem ) )
282 return componentItem;
288 QgsModelComponentGraphicItem *QgsModelGraphicsScene::groupBoxItem(
const QString &uuid )
290 return mGroupBoxItems.value( uuid );
293 void QgsModelGraphicsScene::selectAll()
296 QgsModelComponentGraphicItem *focusedItem =
nullptr;
297 const QList<QGraphicsItem *> itemList = items();
298 for ( QGraphicsItem *graphicsItem : itemList )
300 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( graphicsItem ) )
302 componentItem->setSelected(
true );
304 focusedItem = componentItem;
307 emit selectedItemChanged( focusedItem );
310 void QgsModelGraphicsScene::deselectAll()
315 const QList<QGraphicsItem *> selectedItemList = selectedItems();
316 for ( QGraphicsItem *item : selectedItemList )
318 if ( QgsModelComponentGraphicItem *componentItem =
dynamic_cast<QgsModelComponentGraphicItem *
>( item ) )
320 componentItem->setSelected(
false );
323 emit selectedItemChanged(
nullptr );
326 void QgsModelGraphicsScene::setSelectedItem( QgsModelComponentGraphicItem *item )
331 item->setSelected(
true );
333 emit selectedItemChanged( item );
336 void QgsModelGraphicsScene::setChildAlgorithmResults(
const QVariantMap &results )
338 mChildResults = results;
340 for (
auto it = mChildResults.constBegin(); it != mChildResults.constEnd(); ++it )
342 if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
344 item->setResults( it.value().toMap() );
349 void QgsModelGraphicsScene::setChildAlgorithmInputs(
const QVariantMap &inputs )
351 mChildInputs = inputs;
353 for (
auto it = mChildInputs.constBegin(); it != mChildInputs.constEnd(); ++it )
355 if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
357 item->setInputs( it.value().toMap() );
362 QList<QgsModelGraphicsScene::LinkSource> QgsModelGraphicsScene::linkSourcesForParameterValue( QgsProcessingModelAlgorithm *model,
const QVariant &value,
const QString &childId,
QgsProcessingContext &context )
const
364 QList<QgsModelGraphicsScene::LinkSource> res;
365 if ( value.type() == QVariant::List )
367 const QVariantList list = value.toList();
368 for (
const QVariant &v : list )
369 res.append( linkSourcesForParameterValue( model, v, childId, context ) );
371 else if ( value.type() == QVariant::StringList )
373 const QStringList list = value.toStringList();
374 for (
const QString &v : list )
375 res.append( linkSourcesForParameterValue( model, v, childId, context ) );
377 else if ( value.canConvert< QgsProcessingModelChildParameterSource >() )
379 const QgsProcessingModelChildParameterSource source = value.value< QgsProcessingModelChildParameterSource >();
380 switch ( source.source() )
382 case QgsProcessingModelChildParameterSource::ModelParameter:
385 l.item = mParameterItems.value( source.parameterName() );
389 case QgsProcessingModelChildParameterSource::ChildOutput:
391 if ( !model->childAlgorithm( source.outputChildId() ).algorithm() )
398 if ( output->name() == source.outputName() )
402 if ( mChildAlgorithmItems.contains( source.outputChildId() ) )
405 l.item = mChildAlgorithmItems.value( source.outputChildId() );
406 l.edge = Qt::BottomEdge;
414 case QgsProcessingModelChildParameterSource::Expression:
416 const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = model->variablesForChildAlgorithm( childId, context );
418 const QSet<QString> vars = exp.referencedVariables();
419 for (
const QString &v : vars )
421 if ( variables.contains( v ) )
423 res.append( linkSourcesForParameterValue( model, QVariant::fromValue( variables.value( v ).source ), childId, context ) );
429 case QgsProcessingModelChildParameterSource::StaticValue:
430 case QgsProcessingModelChildParameterSource::ExpressionText:
431 case QgsProcessingModelChildParameterSource::ModelOutput:
438 void QgsModelGraphicsScene::addCommentItemForComponent( QgsProcessingModelAlgorithm *model,
const QgsProcessingModelComponent &component, QgsModelComponentGraphicItem *parentItem )
440 if ( mFlags & FlagHideComments || !component.comment() || component.comment()->description().isEmpty() )
443 QgsModelComponentGraphicItem *commentItem = createCommentGraphicItem( model, component.comment()->clone(), parentItem );
444 commentItem->setPos( component.comment()->position().x(), component.comment()->position().y() );
445 addItem( commentItem );
446 connect( commentItem, &QgsModelComponentGraphicItem::requestModelRepaint,
this, &QgsModelGraphicsScene::rebuildRequired );
447 connect( commentItem, &QgsModelComponentGraphicItem::changed,
this, &QgsModelGraphicsScene::componentChanged );
448 connect( commentItem, &QgsModelComponentGraphicItem::aboutToChange,
this, &QgsModelGraphicsScene::componentAboutToChange );
450 std::unique_ptr< QgsModelArrowItem > arrow = qgis::make_unique< QgsModelArrowItem >( parentItem, QgsModelArrowItem::Circle, commentItem, QgsModelArrowItem::Circle );
451 arrow->setPenStyle( Qt::DotLine );
452 addItem( arrow.release() );
460 void QgsModelGraphicsScene::setMessageBar(
QgsMessageBar *messageBar )
462 mMessageBar = messageBar;
465 void QgsModelGraphicsScene::showWarning(
const QString &shortMessage,
const QString &title,
const QString &longMessage,
Qgis::MessageLevel level )
467 QgsMessageBarItem *messageWidget = mMessageBar->createMessage( QString(), shortMessage );
468 QPushButton *detailsButton =
new QPushButton( tr(
"Details" ) );
469 connect( detailsButton, &QPushButton::clicked, detailsButton, [ = ]
471 QgsMessageViewer *dialog =
new QgsMessageViewer( detailsButton );
472 dialog->setTitle( title );
474 dialog->showMessage();
476 messageWidget->layout()->addWidget( detailsButton );
477 mMessageBar->clearWidgets();
478 mMessageBar->pushWidget( messageWidget, level, 0 );