32#include <QSvgRenderer>
35#include <QGraphicsSceneHoverEvent>
36#include <QApplication>
43QgsModelComponentGraphicItem::QgsModelComponentGraphicItem( QgsProcessingModelComponent *component, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
44 : QGraphicsObject( parent )
45 , mComponent( component )
48 setAcceptHoverEvents(
true );
49 setFlag( QGraphicsItem::ItemIsSelectable,
true );
50 setFlag( QGraphicsItem::ItemSendsGeometryChanges,
true );
51 setZValue( QgsModelGraphicsScene::ZValues::ModelComponent );
53 mFont.setPixelSize( 12 );
57 QPainter painter( &editPicture );
58 svg.render( &painter );
60 mEditButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, editPicture, QPointF( 0, 0 ) );
61 connect( mEditButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::editComponent );
64 QPicture deletePicture;
65 painter.begin( &deletePicture );
66 svg2.render( &painter );
68 mDeleteButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, deletePicture, QPointF( 0, 0 ) );
69 connect( mDeleteButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::deleteComponent );
71 updateButtonPositions();
74QgsModelComponentGraphicItem::Flags QgsModelComponentGraphicItem::flags()
const
76 return QgsModelComponentGraphicItem::Flags();
79QgsModelComponentGraphicItem::~QgsModelComponentGraphicItem() =
default;
81QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
83 return mComponent.get();
86const QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
const
88 return mComponent.get();
91QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
96QgsModelGraphicsView *QgsModelComponentGraphicItem::view()
98 if ( scene()->views().isEmpty() )
101 return qobject_cast< QgsModelGraphicsView * >( scene()->views().first() );
104QFont QgsModelComponentGraphicItem::font()
const
109void QgsModelComponentGraphicItem::setFont(
const QFont &font )
115void QgsModelComponentGraphicItem::moveComponentBy( qreal dx, qreal dy )
117 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
118 mComponent->setPosition( pos() );
120 emit aboutToChange( tr(
"Move %1" ).arg( mComponent->description() ) );
121 updateStoredComponentPosition( pos(), mComponent->size() );
124 emit sizePositionChanged();
125 emit updateArrowPaths();
128void QgsModelComponentGraphicItem::previewItemMove( qreal dx, qreal dy )
130 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
131 emit updateArrowPaths();
134void QgsModelComponentGraphicItem::setItemRect( QRectF rect )
136 rect = rect.normalized();
138 if ( rect.width() < MIN_COMPONENT_WIDTH )
139 rect.setWidth( MIN_COMPONENT_WIDTH );
140 if ( rect.height() < MIN_COMPONENT_HEIGHT )
141 rect.setHeight( MIN_COMPONENT_HEIGHT );
143 setPos( rect.center() );
144 prepareGeometryChange();
146 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
148 mComponent->setPosition( pos() );
149 mComponent->setSize( rect.size() );
150 updateStoredComponentPosition( pos(), mComponent->size() );
152 updateButtonPositions();
155 emit updateArrowPaths();
156 emit sizePositionChanged();
159QRectF QgsModelComponentGraphicItem::previewItemRectChange( QRectF rect )
161 rect = rect.normalized();
163 if ( rect.width() < MIN_COMPONENT_WIDTH )
164 rect.setWidth( MIN_COMPONENT_WIDTH );
165 if ( rect.height() < MIN_COMPONENT_HEIGHT )
166 rect.setHeight( MIN_COMPONENT_HEIGHT );
168 setPos( rect.center() );
169 prepareGeometryChange();
171 mTempSize = rect.size();
173 updateButtonPositions();
174 emit updateArrowPaths();
179void QgsModelComponentGraphicItem::finalizePreviewedItemRectChange( QRectF )
181 mComponent->setPosition( pos() );
182 prepareGeometryChange();
183 mComponent->setSize( mTempSize );
184 mTempSize = QSizeF();
186 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
187 updateStoredComponentPosition( pos(), mComponent->size() );
189 updateButtonPositions();
193 emit sizePositionChanged();
194 emit updateArrowPaths();
199 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
200 updateToolTip( mapFromScene( event->
modelPoint() ) );
205 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
206 updateToolTip( mapFromScene( event->
modelPoint() ) );
211 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
213 setToolTip( QString() );
218 emit repaintArrows();
225 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
229void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
231 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
235void QgsModelComponentGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent *event )
237 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
238 updateToolTip( event->pos() );
241void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
243 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
244 updateToolTip( event->pos() );
247void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
249 modelHoverLeaveEvent(
nullptr );
252QVariant QgsModelComponentGraphicItem::itemChange( QGraphicsItem::GraphicsItemChange change,
const QVariant &value )
256 case QGraphicsItem::ItemSelectedChange:
258 emit repaintArrows();
262 case QGraphicsItem::ItemSceneChange:
267 if ( linkPointCount( Qt::TopEdge ) )
269 mExpandTopButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::TopEdge ), QPointF( 0, 0 ) );
270 connect( mExpandTopButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [ = ](
bool folded ) { fold( Qt::TopEdge, folded ); } );
272 if ( linkPointCount( Qt::BottomEdge ) )
274 mExpandBottomButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::BottomEdge ), QPointF( 0, 0 ) );
275 connect( mExpandBottomButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [ = ](
bool folded ) { fold( Qt::BottomEdge, folded ); } );
278 updateButtonPositions();
287 return QGraphicsObject::itemChange( change, value );
290QRectF QgsModelComponentGraphicItem::boundingRect()
const
292 const QFontMetricsF fm( mFont );
293 const int linksAbove = linkPointCount( Qt::TopEdge );
294 const int linksBelow = linkPointCount( Qt::BottomEdge );
296 const double hUp = linksAbove == 0 ? 0 :
297 fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::TopEdge ) ? 0 : linksAbove ) + 2 );
298 const double hDown = linksBelow == 0 ? 0 :
299 fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::BottomEdge ) ? 0 : linksBelow ) + 2 );
300 return QRectF( -( itemSize().width() ) / 2 - RECT_PEN_SIZE,
301 -( itemSize().height() ) / 2 - hUp - RECT_PEN_SIZE,
302 itemSize().width() + 2 * RECT_PEN_SIZE,
303 itemSize().height() + hDown + hUp + 2 * RECT_PEN_SIZE );
306bool QgsModelComponentGraphicItem::contains(
const QPointF &point )
const
308 const QRectF paintingBounds = boundingRect();
309 if ( point.x() < paintingBounds.left() + RECT_PEN_SIZE )
311 if ( point.x() > paintingBounds.right() - RECT_PEN_SIZE )
313 if ( point.y() < paintingBounds.top() + RECT_PEN_SIZE )
315 if ( point.y() > paintingBounds.bottom() - RECT_PEN_SIZE )
321void QgsModelComponentGraphicItem::paint( QPainter *painter,
const QStyleOptionGraphicsItem *, QWidget * )
323 const QRectF rect = itemRect();
327 if ( mComponent->color().isValid() )
329 color = mComponent->color();
333 color = color.darker( 110 );
336 color = color.darker( 105 );
342 stroke = color.darker( 110 );
343 foreColor = color.lightness() > 150 ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 );
347 color = fillColor( state() );
348 stroke = strokeColor( state() );
349 foreColor = textColor( state() );
352 QPen strokePen = QPen( stroke, 0 ) ;
353 strokePen.setStyle( strokeStyle( state() ) );
354 painter->setPen( strokePen );
355 painter->setBrush( QBrush( color, Qt::SolidPattern ) );
356 painter->drawRect( rect );
357 painter->setFont( font() );
358 painter->setPen( QPen( foreColor ) );
362 const QSizeF componentSize = itemSize();
364 const QFontMetricsF fm( font() );
365 double h = fm.ascent();
366 QPointF pt( -componentSize.width() / 2 + 25, componentSize.height() / 2.0 - h + 1 );
368 if ( iconPicture().isNull() && iconPixmap().isNull() )
370 const QRectF labelRect = QRectF( rect.left() + TEXT_MARGIN, rect.top() + TEXT_MARGIN, rect.width() - 2 * TEXT_MARGIN - mButtonSize.width() - BUTTON_MARGIN, rect.height() - 2 * TEXT_MARGIN );
372 painter->drawText( labelRect, Qt::TextWordWrap | titleAlignment(), text );
376 const QRectF labelRect = QRectF( rect.left() + 21 + TEXT_MARGIN, rect.top() + TEXT_MARGIN,
377 rect.width() - 2 * TEXT_MARGIN - mButtonSize.width() - BUTTON_MARGIN - 21, rect.height() - 2 * TEXT_MARGIN );
379 painter->drawText( labelRect, Qt::TextWordWrap | Qt::AlignVCenter, text );
382 painter->setPen( QPen( QApplication::palette().color( QPalette::Text ) ) );
384 if ( linkPointCount( Qt::TopEdge ) || linkPointCount( Qt::BottomEdge ) )
386 h = -( fm.height() * 1.2 );
387 h = h - componentSize.height() / 2.0 + 5;
388 pt = QPointF( -componentSize.width() / 2 + 25, h );
389 painter->drawText( pt, QObject::tr(
"In" ) );
391 if ( !mComponent->linksCollapsed( Qt::TopEdge ) )
393 for (
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
395 text = linkPointText( Qt::TopEdge, idx );
396 h = -( fm.height() * 1.2 ) * ( i + 1 );
397 h = h - componentSize.height() / 2.0 + 5;
398 pt = QPointF( -componentSize.width() / 2 + 33, h );
399 painter->drawText( pt, text );
404 h = fm.height() * 1.1;
405 h = h + componentSize.height() / 2.0;
406 pt = QPointF( -componentSize.width() / 2 + 25, h );
407 painter->drawText( pt, QObject::tr(
"Out" ) );
408 if ( !mComponent->linksCollapsed( Qt::BottomEdge ) )
410 for (
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
412 text = linkPointText( Qt::BottomEdge, idx );
413 h = fm.height() * 1.2 * ( idx + 2 );
414 h = h + componentSize.height() / 2.0;
415 pt = QPointF( -componentSize.width() / 2 + 33, h );
416 painter->drawText( pt, text );
421 const QPixmap px = iconPixmap();
424 painter->drawPixmap( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), px );
428 const QPicture pic = iconPicture();
431 painter->drawPicture( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), pic );
436QRectF QgsModelComponentGraphicItem::itemRect(
bool storedRect )
const
440 return QRectF( mComponent->position().x() - ( mComponent->size().width() ) / 2.0,
441 mComponent->position().y() - ( mComponent->size().height() ) / 2.0,
442 mComponent->size().width(),
443 mComponent->size().height() );
446 return QRectF( -( itemSize().width() ) / 2.0,
447 -( itemSize().height() ) / 2.0,
449 itemSize().height() );
452QString QgsModelComponentGraphicItem::truncatedTextForItem(
const QString &text )
const
454 const QFontMetricsF fm( mFont );
455 double width = fm.boundingRect( text ).width();
456 if ( width < itemSize().width() - 25 - mButtonSize.width() )
460 t = t.left( t.length() - 3 ) + QChar( 0x2026 );
461 width = fm.boundingRect( t ).width();
462 while ( width > itemSize().width() - 25 - mButtonSize.width() )
464 if ( t.length() < 5 )
467 t = t.left( t.length() - 4 ) + QChar( 0x2026 );
468 width = fm.boundingRect( t ).width();
473Qt::PenStyle QgsModelComponentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
475 return Qt::SolidLine;
478Qt::Alignment QgsModelComponentGraphicItem::titleAlignment()
const
480 return Qt::AlignLeft;
483QPicture QgsModelComponentGraphicItem::iconPicture()
const
488QPixmap QgsModelComponentGraphicItem::iconPixmap()
const
493void QgsModelComponentGraphicItem::updateButtonPositions()
495 mEditButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN,
496 itemSize().height() / 2.0 - mButtonSize.height() / 2.0 - BUTTON_MARGIN ) );
497 mDeleteButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN,
498 mButtonSize.height() / 2.0 - itemSize().height() / 2.0 + BUTTON_MARGIN ) );
500 if ( mExpandTopButton )
502 const QPointF pt = linkPoint( Qt::TopEdge, -1,
true );
503 mExpandTopButton->setPosition( QPointF( 0, pt.y() ) );
505 if ( mExpandBottomButton )
507 const QPointF pt = linkPoint( Qt::BottomEdge, -1,
false );
508 mExpandBottomButton->setPosition( QPointF( 0, pt.y() ) );
512QSizeF QgsModelComponentGraphicItem::itemSize()
const
514 return !mTempSize.isValid() ? mComponent->size() : mTempSize;
517void QgsModelComponentGraphicItem::updateToolTip(
const QPointF &pos )
519 const bool prevHoverStatus = mIsHovering;
520 if ( itemRect().contains( pos ) )
522 setToolTip( mLabel );
527 setToolTip( QString() );
530 if ( mIsHovering != prevHoverStatus )
533 emit repaintArrows();
537void QgsModelComponentGraphicItem::fold( Qt::Edge edge,
bool folded )
539 emit aboutToChange( !folded ? tr(
"Expand Item" ) : tr(
"Collapse Item" ) );
540 mComponent->setLinksCollapsed( edge, folded );
544 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast< QgsProcessingModelChildAlgorithm *
>( mComponent.get() ) )
545 mModel->childAlgorithm( child->childId() ).setLinksCollapsed( edge, folded );
546 else if ( QgsProcessingModelParameter *param =
dynamic_cast< QgsProcessingModelParameter *
>( mComponent.get() ) )
547 mModel->parameterComponent( param->parameterName() ).setLinksCollapsed( edge, folded );
548 else if ( QgsProcessingModelOutput *output =
dynamic_cast< QgsProcessingModelOutput *
>( mComponent.get() ) )
549 mModel->childAlgorithm( output->childId() ).modelOutput( output->name() ).setLinksCollapsed( edge, folded );
551 prepareGeometryChange();
552 emit updateArrowPaths();
557QString QgsModelComponentGraphicItem::label()
const
562void QgsModelComponentGraphicItem::setLabel(
const QString &label )
568QgsModelComponentGraphicItem::State QgsModelComponentGraphicItem::state()
const
572 else if ( mIsHovering )
578int QgsModelComponentGraphicItem::linkPointCount( Qt::Edge )
const
583QString QgsModelComponentGraphicItem::linkPointText( Qt::Edge,
int )
const
588QPointF QgsModelComponentGraphicItem::linkPoint( Qt::Edge edge,
int index,
bool incoming )
const
594 if ( linkPointCount( Qt::BottomEdge ) )
597 if ( mComponent->linksCollapsed( Qt::BottomEdge ) )
601 const int pointIndex = !mComponent->linksCollapsed( Qt::BottomEdge ) ? index : -1;
602 const QString text = truncatedTextForItem( linkPointText( Qt::BottomEdge, index ) );
603 const QFontMetricsF fm( mFont );
604 const double w = fm.boundingRect( text ).width();
605 const double h = fm.height() * 1.2 * ( pointIndex + 1 ) + fm.height() / 2.0;
606 const double y = h + itemSize().height() / 2.0 + 5;
607 const double x = !mComponent->linksCollapsed( Qt::BottomEdge ) ? ( -itemSize().width() / 2 + 33 + w + 5 ) : 10;
608 return QPointF( incoming ? -itemSize().width() / 2 + offsetX
617 if ( linkPointCount( Qt::TopEdge ) )
620 int paramIndex = index;
621 if ( mComponent->linksCollapsed( Qt::TopEdge ) )
626 const QFontMetricsF fm( mFont );
627 const QString text = truncatedTextForItem( linkPointText( Qt::TopEdge, index ) );
628 const double w = fm.boundingRect( text ).width();
629 double h = -( fm.height() * 1.2 ) * ( paramIndex + 2 ) - fm.height() / 2.0 + 8;
630 h = h - itemSize().height() / 2.0;
631 return QPointF( incoming ? -itemSize().width() / 2 + offsetX
632 : ( !mComponent->linksCollapsed( Qt::TopEdge ) ? ( -itemSize().width() / 2 + 33 + w + 5 ) : 10 ),
645QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint( QgsModelComponentGraphicItem *other, Qt::Edge &edge )
const
648 const QgsRectangle otherRect( other->itemRect().translated( other->pos() ) );
650 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
651 const double distLeft = otherRect.distance(
QgsPointXY( leftPoint ) );
653 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
654 const double distRight = otherRect.distance(
QgsPointXY( rightPoint ) );
656 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
657 const double distTop = otherRect.distance(
QgsPointXY( topPoint ) );
659 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
660 const double distBottom = otherRect.distance(
QgsPointXY( bottomPoint ) );
662 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
667 else if ( distRight <= distTop && distRight <= distBottom )
669 edge = Qt::RightEdge;
672 else if ( distBottom <= distTop )
674 edge = Qt::BottomEdge;
684QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint(
const QPointF &point, Qt::Edge &edge )
const
688 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
689 const double distLeft = otherPt.distance(
QgsPointXY( leftPoint ) );
691 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
692 const double distRight = otherPt.distance(
QgsPointXY( rightPoint ) );
694 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
695 const double distTop = otherPt.distance(
QgsPointXY( topPoint ) );
697 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
698 const double distBottom = otherPt.distance(
QgsPointXY( bottomPoint ) );
700 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
705 else if ( distRight <= distTop && distRight <= distBottom )
707 edge = Qt::RightEdge;
710 else if ( distBottom <= distTop )
712 edge = Qt::BottomEdge;
722QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
723 : QgsModelComponentGraphicItem( parameter, model, parent )
726 QPainter painter( &mPicture );
727 svg.render( &painter );
731 setLabel( paramDef->description() );
733 setLabel( QObject::tr(
"Error (%1)" ).arg( parameter->parameterName() ) );
736void QgsModelParameterGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
738 QMenu *popupmenu =
new QMenu( event->widget() );
739 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
740 connect( removeAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::deleteComponent );
741 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
742 connect( editAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComponent );
743 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
744 connect( editCommentAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComment );
746 popupmenu->exec( event->screenPos() );
749QColor QgsModelParameterGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
751 QColor
c( 238, 242, 131 );
767QColor QgsModelParameterGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
772 return QColor( 116, 113, 68 );
775 return QColor( 234, 226, 118 );
780QColor QgsModelParameterGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
785QPicture QgsModelParameterGraphicItem::iconPicture()
const
790void QgsModelParameterGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
792 if ( QgsProcessingModelParameter *param =
dynamic_cast< QgsProcessingModelParameter *
>( component() ) )
794 model()->parameterComponent( param->parameterName() ).setPosition( pos );
795 model()->parameterComponent( param->parameterName() ).setSize( size );
799bool QgsModelParameterGraphicItem::canDeleteComponent()
801 if (
const QgsProcessingModelParameter *param =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
803 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
807 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
819void QgsModelParameterGraphicItem::deleteComponent()
821 if (
const QgsProcessingModelParameter *param =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
823 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
825 QMessageBox::warning(
nullptr, QObject::tr(
"Could not remove input" ),
826 QObject::tr(
"Algorithms depend on the selected input.\n"
827 "Remove them before trying to remove it." ) );
829 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
831 QMessageBox::warning(
nullptr, QObject::tr(
"Could not remove input" ),
832 QObject::tr(
"Other inputs depend on the selected input.\n"
833 "Remove them before trying to remove it." ) );
837 emit aboutToChange( tr(
"Delete Input %1" ).arg( param->description() ) );
838 model()->removeModelParameter( param->parameterName() );
840 emit requestModelRepaint();
847QgsModelChildAlgorithmGraphicItem::QgsModelChildAlgorithmGraphicItem( QgsProcessingModelChildAlgorithm *child, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
848 : QgsModelComponentGraphicItem( child, model, parent )
850 if ( child->algorithm() && !child->algorithm()->svgIconPath().isEmpty() )
852 QSvgRenderer svg( child->algorithm()->svgIconPath() );
853 const QSizeF size = svg.defaultSize();
854 QPainter painter( &mPicture );
855 painter.scale( 16.0 / size.width(), 16.0 / size.width() );
856 svg.render( &painter );
859 else if ( child->algorithm() )
861 mPixmap = child->algorithm()->icon().pixmap( 15, 15 );
864 setLabel( child->description() );
867 mIsValid = model->validateChildAlgorithm( child->childId(), issues );
870void QgsModelChildAlgorithmGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
872 QMenu *popupmenu =
new QMenu( event->widget() );
873 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
874 connect( removeAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deleteComponent );
875 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
876 connect( editAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::editComponent );
877 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
878 connect( editCommentAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComment );
879 popupmenu->addSeparator();
881 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
883 if ( !child->isActive() )
885 QAction *activateAction = popupmenu->addAction( QObject::tr(
"Activate" ) );
886 connect( activateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::activateAlgorithm );
890 QAction *deactivateAction = popupmenu->addAction( QObject::tr(
"Deactivate" ) );
891 connect( deactivateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm );
895 popupmenu->exec( event->screenPos() );
898QColor QgsModelChildAlgorithmGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
903 c = QColor( 255, 255, 255 );
905 c = QColor( 208, 0, 0 );
922QColor QgsModelChildAlgorithmGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
927 return mIsValid ? QColor( 50, 50, 50 ) : QColor( 80, 0, 0 );
930 return mIsValid ? Qt::gray : QColor( 134, 0, 0 );
935QColor QgsModelChildAlgorithmGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
937 return mIsValid ? ( qgis::down_cast< const QgsProcessingModelChildAlgorithm * >( component() )->isActive() ? Qt::black : Qt::gray ) : QColor( 255, 255, 255 );
940QPixmap QgsModelChildAlgorithmGraphicItem::iconPixmap()
const
945QPicture QgsModelChildAlgorithmGraphicItem::iconPicture()
const
950int QgsModelChildAlgorithmGraphicItem::linkPointCount( Qt::Edge edge )
const
952 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
954 if ( !child->algorithm() )
960 return child->algorithm()->outputDefinitions().size();
966 return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination();
968 return params.size();
979QString QgsModelChildAlgorithmGraphicItem::linkPointText( Qt::Edge edge,
int index )
const
984 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
986 if ( !child->algorithm() )
993 if ( index >= child->algorithm()->outputDefinitions().length() )
997 tr(
"Cannot link output for child: %1" ).arg( child->algorithm()->name() ),
1004 if ( mResults.contains( output->
name() ) )
1006 title += QStringLiteral(
": %1" ).arg( mResults.value( output->
name() ).toString() );
1008 return truncatedTextForItem( title );
1016 return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination();
1017 } ), params.end() );
1019 if ( index >= params.length() )
1023 tr(
"Cannot link source for child: %1" ).arg( child->algorithm()->name() ),
1028 QString title = params.at( index )->description();
1029 if ( !mInputs.value( params.at( index )->name() ).toString().isEmpty() )
1030 title += QStringLiteral(
": %1" ).arg( mInputs.value( params.at( index )->name() ).toString() );
1031 return truncatedTextForItem( title );
1042void QgsModelChildAlgorithmGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1044 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast< QgsProcessingModelChildAlgorithm *
>( component() ) )
1046 model()->childAlgorithm( child->childId() ).setPosition( pos );
1047 model()->childAlgorithm( child->childId() ).setSize( size );
1051bool QgsModelChildAlgorithmGraphicItem::canDeleteComponent()
1053 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
1055 return model()->dependentChildAlgorithms( child->childId() ).empty();
1060void QgsModelChildAlgorithmGraphicItem::setResults(
const QVariantMap &results )
1062 if ( mResults == results )
1067 emit updateArrowPaths();
1070void QgsModelChildAlgorithmGraphicItem::setInputs(
const QVariantMap &inputs )
1072 if ( mInputs == inputs )
1077 emit updateArrowPaths();
1080void QgsModelChildAlgorithmGraphicItem::deleteComponent()
1082 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
1084 emit aboutToChange( tr(
"Remove %1" ).arg( child->algorithm() ? child->algorithm()->displayName() : tr(
"Algorithm" ) ) );
1085 if ( !model()->removeChildAlgorithm( child->childId() ) )
1087 QMessageBox::warning(
nullptr, QObject::tr(
"Could not remove algorithm" ),
1088 QObject::tr(
"Other algorithms depend on the selected one.\n"
1089 "Remove them before trying to remove it." ) );
1094 emit requestModelRepaint();
1099void QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm()
1101 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
1103 model()->deactivateChildAlgorithm( child->childId() );
1104 emit requestModelRepaint();
1108void QgsModelChildAlgorithmGraphicItem::activateAlgorithm()
1110 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() ) )
1112 if ( model()->activateChildAlgorithm( child->childId() ) )
1114 emit requestModelRepaint();
1118 QMessageBox::warning(
nullptr, QObject::tr(
"Could not activate algorithm" ),
1119 QObject::tr(
"The selected algorithm depends on other currently non-active algorithms.\n"
1120 "Activate them them before trying to activate it.." ) );
1126QgsModelOutputGraphicItem::QgsModelOutputGraphicItem( QgsProcessingModelOutput *output, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1127 : QgsModelComponentGraphicItem( output, model, parent )
1130 QPainter painter( &mPicture );
1131 svg.render( &painter );
1133 setLabel( output->description() );
1136QColor QgsModelOutputGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1138 QColor
c( 172, 196, 114 );
1142 c =
c.darker( 110 );
1145 c =
c.darker( 105 );
1154QColor QgsModelOutputGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1159 return QColor( 42, 65, 42 );
1162 return QColor( 90, 140, 90 );
1167QColor QgsModelOutputGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1172QPicture QgsModelOutputGraphicItem::iconPicture()
const
1177void QgsModelOutputGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1179 if ( QgsProcessingModelOutput *output =
dynamic_cast< QgsProcessingModelOutput *
>( component() ) )
1181 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setPosition( pos );
1182 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setSize( size );
1186bool QgsModelOutputGraphicItem::canDeleteComponent()
1188 if (
dynamic_cast< const QgsProcessingModelOutput *
>( component() ) )
1195void QgsModelOutputGraphicItem::deleteComponent()
1197 if (
const QgsProcessingModelOutput *output =
dynamic_cast< const QgsProcessingModelOutput *
>( component() ) )
1199 emit aboutToChange( tr(
"Delete Output %1" ).arg( output->description() ) );
1200 model()->childAlgorithm( output->childId() ).removeModelOutput( output->name() );
1201 model()->updateDestinationParameters();
1203 emit requestModelRepaint();
1212QgsModelGroupBoxGraphicItem::QgsModelGroupBoxGraphicItem( QgsProcessingModelGroupBox *box, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1213 : QgsModelComponentGraphicItem( box, model, parent )
1215 setZValue( QgsModelGraphicsScene::ZValues::GroupBox );
1216 setLabel( box->description() );
1220 f.setPixelSize( 14 );
1224void QgsModelGroupBoxGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1226 QMenu *popupmenu =
new QMenu( event->widget() );
1227 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1228 connect( removeAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::deleteComponent );
1229 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1230 connect( editAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::editComponent );
1231 popupmenu->exec( event->screenPos() );
1234QgsModelGroupBoxGraphicItem::~QgsModelGroupBoxGraphicItem() =
default;
1236QColor QgsModelGroupBoxGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1238 QColor
c( 230, 230, 230 );
1242 c =
c.darker( 110 );
1245 c =
c.darker( 105 );
1254QColor QgsModelGroupBoxGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1259 return QColor( 50, 50, 50 );
1262 return QColor( 150, 150, 150 );
1267QColor QgsModelGroupBoxGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1269 return QColor( 100, 100, 100 );
1272Qt::PenStyle QgsModelGroupBoxGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
1277Qt::Alignment QgsModelGroupBoxGraphicItem::titleAlignment()
const
1279 return Qt::AlignHCenter;
1282void QgsModelGroupBoxGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1284 if ( QgsProcessingModelGroupBox *box =
dynamic_cast< QgsProcessingModelGroupBox *
>( component() ) )
1286 box->setPosition( pos );
1287 box->setSize( size );
1288 model()->addGroupBox( *box );
1292bool QgsModelGroupBoxGraphicItem::canDeleteComponent()
1294 if (
dynamic_cast< QgsProcessingModelGroupBox *
>( component() ) )
1301void QgsModelGroupBoxGraphicItem::deleteComponent()
1303 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast< const QgsProcessingModelGroupBox *
>( component() ) )
1305 emit aboutToChange( tr(
"Delete Group Box" ) );
1306 model()->removeGroupBox( box->uuid() );
1308 emit requestModelRepaint();
1312void QgsModelGroupBoxGraphicItem::editComponent()
1314 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast< const QgsProcessingModelGroupBox *
>( component() ) )
1320 emit aboutToChange( tr(
"Edit Group Box" ) );
1321 model()->addGroupBox( dlg.groupBox() );
1323 emit requestModelRepaint();
1332QgsModelCommentGraphicItem::QgsModelCommentGraphicItem( QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1333 : QgsModelComponentGraphicItem( comment, model, parent )
1334 , mParentComponent( parentItem->component()->clone() )
1335 , mParentItem( parentItem )
1337 setLabel( comment->description() );
1340 f.setPixelSize( 9 );
1344void QgsModelCommentGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1346 QMenu *popupmenu =
new QMenu( event->widget() );
1347 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1348 connect( removeAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::deleteComponent );
1349 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1350 connect( editAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::editComponent );
1351 popupmenu->exec( event->screenPos() );
1354QgsModelCommentGraphicItem::~QgsModelCommentGraphicItem() =
default;
1356QColor QgsModelCommentGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1358 QColor
c( 230, 230, 230 );
1362 c =
c.darker( 110 );
1365 c =
c.darker( 105 );
1374QColor QgsModelCommentGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1379 return QColor( 50, 50, 50 );
1382 return QColor( 150, 150, 150 );
1387QColor QgsModelCommentGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1389 return QColor( 100, 100, 100 );
1392Qt::PenStyle QgsModelCommentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
1397void QgsModelCommentGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1399 if ( QgsProcessingModelComment *comment = modelComponent() )
1401 comment->setPosition( pos );
1402 comment->setSize( size );
1406bool QgsModelCommentGraphicItem::canDeleteComponent()
1408 if ( modelComponent() )
1415void QgsModelCommentGraphicItem::deleteComponent()
1417 if ( QgsProcessingModelComment *comment = modelComponent() )
1419 emit aboutToChange( tr(
"Delete Comment" ) );
1420 comment->setDescription( QString() );
1422 emit requestModelRepaint();
1426void QgsModelCommentGraphicItem::editComponent()
1430 mParentItem->editComment();
1434QgsProcessingModelComment *QgsModelCommentGraphicItem::modelComponent()
1436 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( mParentComponent.get() ) )
1438 return model()->childAlgorithm( child->childId() ).comment();
1440 else if (
const QgsProcessingModelParameter *param =
dynamic_cast< const QgsProcessingModelParameter *
>( mParentComponent.get() ) )
1442 return model()->parameterComponent( param->parameterName() ).comment();
1444 else if (
const QgsProcessingModelOutput *output =
dynamic_cast< const QgsProcessingModelOutput *
>( mParentComponent.get() ) )
1446 return model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).comment();
1451QgsModelComponentGraphicItem *QgsModelCommentGraphicItem::parentComponentItem()
const
@ Warning
Warning message.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A widget which allow users to specify the properties of a model group box.
A QgsModelViewMouseEvent is the result of a user interaction with the mouse on a QgsModelGraphicsView...
QPointF modelPoint() const
Returns the event point location in model coordinates.
A class to represent a 2D point.
Base class for the definition of processing outputs.
QString name() const
Returns the name of the output.
QString description() const
Returns the description for the output.
Base class for the definition of processing parameters.
A rectangle specified with double values.
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 c
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.