37#include <QApplication>
38#include <QGraphicsSceneHoverEvent>
45#include <QSvgRenderer>
47#include "moc_qgsmodelcomponentgraphicitem.cpp"
49using namespace Qt::StringLiterals;
53QgsModelComponentGraphicItem::QgsModelComponentGraphicItem( QgsProcessingModelComponent *component, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
54 : QGraphicsObject( parent )
55 , mComponent( component )
58 setAcceptHoverEvents(
true );
59 setFlag( QGraphicsItem::ItemIsSelectable,
true );
60 setFlag( QGraphicsItem::ItemSendsGeometryChanges,
true );
61 setZValue( QgsModelGraphicsScene::ZValues::ModelComponent );
63 mFont.setPixelSize( 12 );
67 QPainter painter( &editPicture );
68 svg.render( &painter );
70 mEditButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, editPicture, QPointF( 0, 0 ) );
71 connect( mEditButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::editComponent );
74 QPicture deletePicture;
75 painter.begin( &deletePicture );
76 svg2.render( &painter );
78 mDeleteButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, deletePicture, QPointF( 0, 0 ) );
79 connect( mDeleteButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::deleteComponent );
81 updateButtonPositions();
84QgsModelComponentGraphicItem::Flags QgsModelComponentGraphicItem::flags()
const
86 return QgsModelComponentGraphicItem::Flags();
89QgsModelComponentGraphicItem::~QgsModelComponentGraphicItem() =
default;
91QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
93 return mComponent.get();
96const QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
const
98 return mComponent.get();
101QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
106const QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
const
111QgsModelGraphicsView *QgsModelComponentGraphicItem::view()
113 if ( scene()->views().isEmpty() )
116 return qobject_cast<QgsModelGraphicsView *>( scene()->views().first() );
119QFont QgsModelComponentGraphicItem::font()
const
124void QgsModelComponentGraphicItem::setFont(
const QFont &font )
130void QgsModelComponentGraphicItem::moveComponentBy( qreal dx, qreal dy )
132 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
133 mComponent->setPosition( pos() );
135 emit aboutToChange( tr(
"Move %1" ).arg( mComponent->description() ) );
136 updateStoredComponentPosition( pos(), mComponent->size() );
139 emit sizePositionChanged();
140 emit updateArrowPaths();
143void QgsModelComponentGraphicItem::previewItemMove( qreal dx, qreal dy )
145 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
146 emit updateArrowPaths();
149void QgsModelComponentGraphicItem::setItemRect( QRectF rect )
151 rect = rect.normalized();
153 if ( rect.width() < MIN_COMPONENT_WIDTH )
154 rect.setWidth( MIN_COMPONENT_WIDTH );
155 if ( rect.height() < MIN_COMPONENT_HEIGHT )
156 rect.setHeight( MIN_COMPONENT_HEIGHT );
158 setPos( rect.center() );
159 prepareGeometryChange();
161 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
163 mComponent->setPosition( pos() );
164 mComponent->setSize( rect.size() );
165 updateStoredComponentPosition( pos(), mComponent->size() );
167 updateButtonPositions();
170 emit updateArrowPaths();
171 emit sizePositionChanged();
174QRectF QgsModelComponentGraphicItem::previewItemRectChange( QRectF rect )
176 rect = rect.normalized();
178 if ( rect.width() < MIN_COMPONENT_WIDTH )
179 rect.setWidth( MIN_COMPONENT_WIDTH );
180 if ( rect.height() < MIN_COMPONENT_HEIGHT )
181 rect.setHeight( MIN_COMPONENT_HEIGHT );
183 setPos( rect.center() );
184 prepareGeometryChange();
186 mTempSize = rect.size();
188 updateButtonPositions();
189 emit updateArrowPaths();
194void QgsModelComponentGraphicItem::finalizePreviewedItemRectChange( QRectF )
196 mComponent->setPosition( pos() );
197 prepareGeometryChange();
198 mComponent->setSize( mTempSize );
199 mTempSize = QSizeF();
201 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
202 updateStoredComponentPosition( pos(), mComponent->size() );
204 updateButtonPositions();
208 emit sizePositionChanged();
209 emit updateArrowPaths();
214 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
215 updateToolTip( mapFromScene( event->
modelPoint() ) );
220 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
221 updateToolTip( mapFromScene( event->
modelPoint() ) );
226 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
228 setToolTip( QString() );
233 emit repaintArrows();
240 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
244void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
246 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
250void QgsModelComponentGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent *event )
252 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
253 updateToolTip( event->pos() );
256void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
258 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
259 updateToolTip( event->pos() );
262void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
264 modelHoverLeaveEvent(
nullptr );
267QVariant QgsModelComponentGraphicItem::itemChange( QGraphicsItem::GraphicsItemChange change,
const QVariant &value )
271 case QGraphicsItem::ItemSelectedChange:
273 emit repaintArrows();
277 case QGraphicsItem::ItemSceneChange:
282 if ( linkPointCount( Qt::TopEdge ) )
284 mExpandTopButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::TopEdge ), QPointF( 0, 0 ) );
285 connect( mExpandTopButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [
this](
bool folded ) { fold( Qt::TopEdge, folded ); } );
287 for (
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
289 mInSockets.append(
new QgsModelDesignerSocketGraphicItem(
this, mComponent.get(), idx, QPointF( 0, 0 ), Qt::TopEdge ) );
292 if ( linkPointCount( Qt::BottomEdge ) )
294 mExpandBottomButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::BottomEdge ), QPointF( 0, 0 ) );
295 connect( mExpandBottomButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [
this](
bool folded ) { fold( Qt::BottomEdge, folded ); } );
297 for (
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
299 mOutSockets.append(
new QgsModelDesignerSocketGraphicItem(
this, mComponent.get(), idx, QPointF( 0, 0 ), Qt::BottomEdge ) );
303 updateButtonPositions();
312 return QGraphicsObject::itemChange( change, value );
315QRectF QgsModelComponentGraphicItem::boundingRect()
const
317 const QFontMetricsF fm( mFont );
318 const int linksAbove = linkPointCount( Qt::TopEdge );
319 const int linksBelow = linkPointCount( Qt::BottomEdge );
321 const double hUp = linksAbove == 0 ? 0 : fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::TopEdge ) ? 0 : linksAbove ) + 2 );
322 const double hDown = linksBelow == 0 ? 0 : fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::BottomEdge ) ? 0 : linksBelow ) + 2 );
324 double outlineSize = 0;
325 if ( outlineColor().isValid() )
327 outlineSize = RECT_OUTLINE_SIZE + 0.5;
331 -( itemSize().width() ) / 2 - RECT_PEN_SIZE - outlineSize,
332 -( itemSize().height() ) / 2 - hUp - RECT_PEN_SIZE - outlineSize,
333 itemSize().width() + 2 * RECT_PEN_SIZE + outlineSize * 2,
334 itemSize().height() + hDown + hUp + 2 * RECT_PEN_SIZE + outlineSize * 2
338bool QgsModelComponentGraphicItem::contains(
const QPointF &point )
const
340 const QRectF paintingBounds = boundingRect();
341 if ( point.x() < paintingBounds.left() + RECT_PEN_SIZE )
343 if ( point.x() > paintingBounds.right() - RECT_PEN_SIZE )
345 if ( point.y() < paintingBounds.top() + RECT_PEN_SIZE )
347 if ( point.y() > paintingBounds.bottom() - RECT_PEN_SIZE )
353void QgsModelComponentGraphicItem::paintBackground( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
355 const QRectF rect = itemRect();
358 if ( mComponent->color().isValid() )
360 color = mComponent->color();
364 color = color.darker( 110 );
367 color = color.darker( 105 );
373 stroke = color.darker( 110 );
377 color = fillColor( state() );
378 stroke = strokeColor( state() );
381 paintOutline( painter, option, widget );
383 QPen strokePen = QPen( stroke, 0 );
384 strokePen.setStyle( strokeStyle( state() ) );
385 painter->setPen( strokePen );
386 painter->setBrush( QBrush( color, Qt::SolidPattern ) );
387 painter->drawRect( rect );
390void QgsModelComponentGraphicItem::paintOutline( QPainter *painter,
const QStyleOptionGraphicsItem *, QWidget * )
392 const QColor outline = outlineColor();
393 if ( outline.isValid() )
396 const bool wasAntiAliased = painter->testRenderHint( QPainter::RenderHint::Antialiasing );
397 painter->setRenderHint( QPainter::RenderHint::Antialiasing );
398 QPen strokePen = QPen( outline, RECT_OUTLINE_SIZE );
399 strokePen.setJoinStyle( Qt::MiterJoin );
400 strokePen.setStyle( strokeStyle( state() ) );
401 painter->setPen( strokePen );
402 painter->setBrush( Qt::NoBrush );
403 const QRectF rect = itemRect();
404 painter->drawRect( rect );
405 painter->setRenderHint( QPainter::RenderHint::Antialiasing, wasAntiAliased );
409void QgsModelComponentGraphicItem::paint( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
411 paintBackground( painter, option, widget );
413 const QRectF rect = itemRect();
415 if ( mComponent->color().isValid() )
417 QColor color = mComponent->color();
421 color = color.darker( 110 );
424 color = color.darker( 105 );
430 foreColor = color.lightness() > 150 ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 );
434 foreColor = textColor( state() );
436 painter->setFont( font() );
437 painter->setPen( QPen( foreColor ) );
441 const QSizeF componentSize = itemSize();
443 const QFontMetricsF fm( font() );
444 double h = fm.ascent();
445 QPointF pt( -componentSize.width() / 2 + 25, componentSize.height() / 2.0 - h + 1 );
447 if ( iconPicture().isNull() && iconPixmap().isNull() )
449 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 );
451 painter->drawText( labelRect, Qt::TextWordWrap | titleAlignment(), text );
455 const QRectF labelRect = QRectF( rect.left() + 21 + TEXT_MARGIN, rect.top() + TEXT_MARGIN, rect.width() - 2 * TEXT_MARGIN - mButtonSize.width() - BUTTON_MARGIN - 21, rect.height() - 2 * TEXT_MARGIN );
457 painter->drawText( labelRect, Qt::TextWordWrap | Qt::AlignVCenter, text );
460 painter->setPen( QPen( QApplication::palette().color( QPalette::Text ) ) );
462 if ( linkPointCount( Qt::TopEdge ) )
464 h = -( fm.height() * 1.2 );
465 h = h - componentSize.height() / 2.0 + 5;
466 pt = QPointF( -componentSize.width() / 2 + SOCKET_MARGIN, h );
467 painter->drawText( pt, QObject::tr(
"In" ) );
469 if ( !mComponent->linksCollapsed( Qt::TopEdge ) )
471 for (
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
473 text = linkPointText( Qt::TopEdge, idx );
474 h = -( fm.height() * 1.2 ) * ( i + 1 );
475 h = h - componentSize.height() / 2.0 + 5;
476 pt = QPointF( -componentSize.width() / 2 + SOCKET_MARGIN + 10, h );
477 painter->drawText( pt, text );
482 if ( linkPointCount( Qt::BottomEdge ) )
484 h = fm.height() * 1.1;
485 h = h + componentSize.height() / 2.0;
486 const double w = fm.boundingRect(
"Out" ).width();
487 pt = QPointF( componentSize.width() / 2 - SOCKET_MARGIN - w, h );
488 painter->drawText( pt, QObject::tr(
"Out" ) );
489 if ( !mComponent->linksCollapsed( Qt::BottomEdge ) )
491 for (
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
493 text = linkPointText( Qt::BottomEdge, idx );
494 h = fm.height() * 1.2 * ( idx + 2 );
495 h = h + componentSize.height() / 2.0;
496 double w = fm.boundingRect( text ).width();
498 const double x = componentSize.width() / 2.0 - w - SOCKET_MARGIN - 10;
500 painter->drawText( QPointF( x, h ), text );
505 const QPixmap px = iconPixmap();
508 painter->drawPixmap( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), px );
512 const QPicture pic = iconPicture();
515 painter->drawPicture( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), pic );
520QRectF QgsModelComponentGraphicItem::itemRect(
bool storedRect )
const
524 return QRectF( mComponent->position().x() - ( mComponent->size().width() ) / 2.0, mComponent->position().y() - ( mComponent->size().height() ) / 2.0, mComponent->size().width(), mComponent->size().height() );
527 return QRectF( -( itemSize().width() ) / 2.0, -( itemSize().height() ) / 2.0, itemSize().width(), itemSize().height() );
530QString QgsModelComponentGraphicItem::truncatedTextForItem(
const QString &text )
const
532 const QFontMetricsF fm( mFont );
533 double width = fm.boundingRect( text ).width();
534 if ( width < itemSize().width() - SOCKET_MARGIN - mButtonSize.width() )
538 t = t.left( t.length() - 3 ) + QChar( 0x2026 );
539 width = fm.boundingRect( t ).width();
540 while ( width > itemSize().width() - SOCKET_MARGIN - mButtonSize.width() )
542 if ( t.length() < 5 )
545 t = t.left( t.length() - 4 ) + QChar( 0x2026 );
546 width = fm.boundingRect( t ).width();
551Qt::PenStyle QgsModelComponentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
553 return Qt::SolidLine;
556Qt::Alignment QgsModelComponentGraphicItem::titleAlignment()
const
558 return Qt::AlignLeft;
561QPicture QgsModelComponentGraphicItem::iconPicture()
const
566QPixmap QgsModelComponentGraphicItem::iconPixmap()
const
572void QgsModelComponentGraphicItem::updateButtonPositions()
574 mEditButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN, itemSize().height() / 2.0 - mButtonSize.height() / 2.0 - BUTTON_MARGIN ) );
575 mDeleteButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN, mButtonSize.height() / 2.0 - itemSize().height() / 2.0 + BUTTON_MARGIN ) );
577 if ( mExpandBottomButton )
579 const QPointF pt = linkPoint( Qt::BottomEdge, -1,
false );
580 mExpandBottomButton->setPosition( QPointF( 0, pt.y() ) );
582 bool collapsed = mComponent->linksCollapsed( Qt::BottomEdge );
583 for ( QgsModelDesignerSocketGraphicItem *socket : std::as_const( mOutSockets ) )
585 const QPointF pt = linkPoint( Qt::BottomEdge, socket->index(),
false );
586 socket->setPosition( pt );
587 socket->setVisible( !collapsed );
592 if ( mExpandTopButton )
594 const QPointF pt = linkPoint( Qt::TopEdge, -1,
true );
595 mExpandTopButton->setPosition( QPointF( 0, pt.y() ) );
597 bool collapsed = mComponent->linksCollapsed( Qt::TopEdge );
598 for ( QgsModelDesignerSocketGraphicItem *socket : std::as_const( mInSockets ) )
600 const QPointF pt = linkPoint( Qt::TopEdge, socket->index(),
true );
601 socket->setPosition( pt );
602 socket->setVisible( !collapsed );
608QSizeF QgsModelComponentGraphicItem::itemSize()
const
610 return !mTempSize.isValid() ? mComponent->size() : mTempSize;
613void QgsModelComponentGraphicItem::updateToolTip(
const QPointF &pos )
615 const bool prevHoverStatus = mIsHovering;
616 if ( itemRect().contains( pos ) )
618 setToolTip( mLabel );
623 setToolTip( QString() );
626 if ( mIsHovering != prevHoverStatus )
629 emit repaintArrows();
633void QgsModelComponentGraphicItem::fold( Qt::Edge edge,
bool folded )
635 emit aboutToChange( !folded ? tr(
"Expand Item" ) : tr(
"Collapse Item" ) );
636 mComponent->setLinksCollapsed( edge, folded );
640 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast<QgsProcessingModelChildAlgorithm *
>( mComponent.get() ) )
642 mModel->childAlgorithm( child->childId() ).setLinksCollapsed( edge, folded );
644 else if ( QgsProcessingModelParameter *param =
dynamic_cast<QgsProcessingModelParameter *
>( mComponent.get() ) )
646 mModel->parameterComponent( param->parameterName() ).setLinksCollapsed( edge, folded );
648 else if ( QgsProcessingModelOutput *output =
dynamic_cast<QgsProcessingModelOutput *
>( mComponent.get() ) )
650 mModel->childAlgorithm( output->childId() ).modelOutput( output->name() ).setLinksCollapsed( edge, folded );
653 updateButtonPositions();
654 prepareGeometryChange();
655 emit updateArrowPaths();
660QString QgsModelComponentGraphicItem::label()
const
665void QgsModelComponentGraphicItem::setLabel(
const QString &label )
671QgsModelComponentGraphicItem::State QgsModelComponentGraphicItem::state()
const
675 else if ( mIsHovering )
681int QgsModelComponentGraphicItem::linkPointCount( Qt::Edge )
const
686QString QgsModelComponentGraphicItem::linkPointText( Qt::Edge,
int )
const
691QPointF QgsModelComponentGraphicItem::linkPoint( Qt::Edge edge,
int index,
bool incoming )
const
697 if ( linkPointCount( Qt::BottomEdge ) )
699 const int pointIndex = !mComponent->linksCollapsed( Qt::BottomEdge ) ? index : -1;
700 const QFontMetricsF fm( mFont );
701 const double h = fm.height() * 1.2 * ( pointIndex + 1 ) + fm.height() / 2.0;
702 const double y = h + itemSize().height() / 2.0 + 6.4;
704 if ( !mComponent->linksCollapsed( Qt::BottomEdge ) )
708 x = itemSize().width() / 2 - SOCKET_MARGIN;
712 const QString text = truncatedTextForItem( linkPointText( Qt::BottomEdge, index ) );
713 const double w = fm.boundingRect( text ).width();
714 x = itemSize().width() / 2 - SOCKET_MARGIN - w - 14;
721 x = itemSize().width() / 2 - 17;
729 return QPointF( x, y );
736 if ( linkPointCount( Qt::TopEdge ) )
738 double offsetX = SOCKET_MARGIN;
739 int paramIndex = index;
740 if ( mComponent->linksCollapsed( Qt::TopEdge ) )
745 const QFontMetricsF fm( mFont );
746 const double h = -( fm.height() * 1.2 ) * ( paramIndex + 2 ) - fm.height() / 2.0 + 8;
747 const double y = h - itemSize().height() / 2.0;
748 const double x = -itemSize().width() / 2 + offsetX;
749 return QPointF( x, y );
761QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint( QgsModelComponentGraphicItem *other, Qt::Edge &edge )
const
764 const QgsRectangle otherRect( other->itemRect().translated( other->pos() ) );
766 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
767 const double distLeft = otherRect.distance(
QgsPointXY( leftPoint ) );
769 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
770 const double distRight = otherRect.distance(
QgsPointXY( rightPoint ) );
772 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
773 const double distTop = otherRect.distance(
QgsPointXY( topPoint ) );
775 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
776 const double distBottom = otherRect.distance(
QgsPointXY( bottomPoint ) );
778 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
783 else if ( distRight <= distTop && distRight <= distBottom )
785 edge = Qt::RightEdge;
788 else if ( distBottom <= distTop )
790 edge = Qt::BottomEdge;
800QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint(
const QPointF &point, Qt::Edge &edge )
const
804 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
805 const double distLeft = otherPt.distance(
QgsPointXY( leftPoint ) );
807 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
808 const double distRight = otherPt.distance(
QgsPointXY( rightPoint ) );
810 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
811 const double distTop = otherPt.distance(
QgsPointXY( topPoint ) );
813 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
814 const double distBottom = otherPt.distance(
QgsPointXY( bottomPoint ) );
816 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
821 else if ( distRight <= distTop && distRight <= distBottom )
823 edge = Qt::RightEdge;
826 else if ( distBottom <= distTop )
828 edge = Qt::BottomEdge;
838QgsModelDesignerSocketGraphicItem *QgsModelComponentGraphicItem::outSocketAt(
int index )
const
840 if ( index < 0 || index >= mOutSockets.size() )
844 return mOutSockets.at( index );
847QList<QgsModelArrowItem *> QgsModelComponentGraphicItem::incomingArrows()
849 const QList<QGraphicsItem *> allItems = scene()->items();
850 QList<QgsModelArrowItem *> arrows;
851 for ( QGraphicsItem *item : allItems )
853 if (
auto arrowItem =
dynamic_cast< QgsModelArrowItem *
>( item ) )
855 if ( arrowItem->endItem() ==
this )
864QList<QgsModelArrowItem *> QgsModelComponentGraphicItem::outgoingArrows()
866 const QList<QGraphicsItem *> allItems = scene()->items();
867 QList<QgsModelArrowItem *> arrows;
868 for ( QGraphicsItem *item : allItems )
870 if (
auto arrowItem =
dynamic_cast< QgsModelArrowItem *
>( item ) )
872 if ( arrowItem->startItem() ==
this )
883 mWidgetContextGenerator = generator;
888 if ( mWidgetContextGenerator )
890 return mWidgetContextGenerator->createWidgetContext();
895QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
896 : QgsModelComponentGraphicItem( parameter, model, parent )
899 QPainter painter( &mPicture );
900 svg.render( &painter );
904 setLabel( parameterDefinition->description() );
906 setLabel( QObject::tr(
"Error (%1)" ).arg( parameter->parameterName() ) );
909void QgsModelParameterGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
911 QMenu *popupmenu =
new QMenu( event->widget() );
912 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
913 connect( removeAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::deleteComponent );
914 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
915 connect( editAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComponent );
916 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
917 connect( editCommentAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComment );
919 popupmenu->exec( event->screenPos() );
922QColor QgsModelParameterGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
924 QColor
c( 238, 242, 131 );
940QColor QgsModelParameterGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
945 return QColor( 116, 113, 68 );
948 return QColor( 234, 226, 118 );
953QColor QgsModelParameterGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
958QPicture QgsModelParameterGraphicItem::iconPicture()
const
963int QgsModelParameterGraphicItem::linkPointCount( Qt::Edge edge )
const
978QString QgsModelParameterGraphicItem::linkPointText( Qt::Edge,
int index )
const
985 if (
const QgsProcessingModelParameter *parameter =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
987 QString text = this->model()->parameterDefinition( parameter->parameterName() )->type();
992 const QVariant paramValue = paramDef->defaultValue();
994 if ( paramValue.isValid() )
996 text +=
": " + paramDef->userFriendlyString( paramValue );
999 return truncatedTextForItem( text );
1005QColor QgsModelParameterGraphicItem::linkColor( Qt::Edge ,
int index )
const
1009 return FALLBACK_COLOR;
1012 if (
const QgsProcessingModelParameter *parameter =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
1016 return parameterDefinition->modelColor();
1020 return FALLBACK_COLOR;
1023QString QgsModelParameterGraphicItem::applyEdit(
1024 std::unique_ptr< QgsProcessingParameterDefinition > newParameter,
const QString &oldDescription,
const QString &oldName,
const QString &comment,
const QColor &commentColor
1027 QgsProcessingModelParameter *paramComponent =
dynamic_cast< QgsProcessingModelParameter *
>( component() );
1028 if ( !paramComponent )
1031 const QString undoCommandId = u
"param:%1"_s.arg( paramComponent->parameterName() );
1032 emit aboutToChange( tr(
"Edit %1" ).arg( newParameter->description() ), undoCommandId );
1034 model()->removeModelParameter( paramComponent->parameterName() );
1036 if ( newParameter->description() != oldDescription )
1040 QString name = newParameter->name();
1041 const QString baseName = name;
1043 while ( model()->parameterDefinition( name ) )
1045 name = u
"%1%2"_s.arg( baseName ).arg( i );
1049 newParameter->setName( name );
1050 model()->changeParameterName( oldName, newParameter->name() );
1053 paramComponent->setParameterName( newParameter->name() );
1054 paramComponent->setDescription( newParameter->name() );
1055 paramComponent->comment()->setDescription( comment );
1056 paramComponent->comment()->setColor( commentColor );
1058 const QString description = newParameter->description();
1059 const QString name = newParameter->name();
1060 model()->addModelParameter( newParameter.release(), *paramComponent );
1061 setLabel( description );
1062 emit requestModelRepaint();
1068void QgsModelParameterGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1070 if ( QgsProcessingModelParameter *param =
dynamic_cast<QgsProcessingModelParameter *
>( component() ) )
1072 model()->parameterComponent( param->parameterName() ).setPosition( pos );
1073 model()->parameterComponent( param->parameterName() ).setSize( size );
1077bool QgsModelParameterGraphicItem::canDeleteComponent()
1079 if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( component() ) )
1081 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
1085 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
1097void QgsModelParameterGraphicItem::editComponent()
1102void QgsModelParameterGraphicItem::editComment()
1107void QgsModelParameterGraphicItem::deleteComponent()
1109 if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( component() ) )
1111 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
1113 QMessageBox::warning(
1115 QObject::tr(
"Could not remove input" ),
1117 "Algorithms depend on the selected input.\n"
1118 "Remove them before trying to remove it."
1122 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
1124 QMessageBox::warning(
1126 QObject::tr(
"Could not remove input" ),
1128 "Other inputs depend on the selected input.\n"
1129 "Remove them before trying to remove it."
1135 emit aboutToChange( tr(
"Delete Input %1" ).arg( param->description() ) );
1136 model()->removeModelParameter( param->parameterName() );
1138 emit requestModelRepaint();
1143void QgsModelParameterGraphicItem::edit(
bool editComment )
1145 const QgsProcessingModelParameter *paramComponent =
dynamic_cast< const QgsProcessingModelParameter *
>( component() );
1146 if ( !paramComponent )
1150 if ( !existingParam )
1153 const QString oldName = existingParam->
name();
1154 const QString oldDescription = existingParam->
description();
1156 const QString comment = paramComponent->comment()->description();
1157 const QColor commentColor = paramComponent->comment()->color();
1164 dlg.setComments( comment );
1165 dlg.setCommentColor( commentColor );
1173 dlg.switchToCommentTab();
1178 std::unique_ptr< QgsProcessingParameterDefinition > newParam( dlg.createParameter( existingParam->
name() ) );
1181 const QString safeName = QgsProcessingModelAlgorithm::safeName( newParam->description() ).toLower();
1182 newParam->setName( safeName );
1184 applyEdit( std::move( newParam ), oldDescription, oldName, dlg.comments(), dlg.commentColor() );
1190QgsModelChildAlgorithmGraphicItem::QgsModelChildAlgorithmGraphicItem( QgsProcessingModelChildAlgorithm *child, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1191 : QgsModelComponentGraphicItem( child, model, parent )
1193 if ( child->algorithm() && !child->algorithm()->svgIconPath().isEmpty() )
1195 QSvgRenderer svg( child->algorithm()->svgIconPath() );
1196 const QSizeF size = svg.defaultSize();
1197 QPainter painter( &mPicture );
1198 painter.scale( 16.0 / size.width(), 16.0 / size.width() );
1199 svg.render( &painter );
1202 else if ( child->algorithm() )
1204 mPixmap = child->algorithm()->icon().pixmap( 15, 15 );
1207 setLabel( child->description() );
1210 mIsValid = model->validateChildAlgorithm( child->childId(), issues );
1213void QgsModelChildAlgorithmGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1215 QMenu *popupmenu =
new QMenu( event->widget() );
1219 QAction *runSelectedStepsAction = popupmenu->addAction( QObject::tr(
"Run Selected Steps…" ) );
1221 connect( runSelectedStepsAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::runSelected );
1224 QAction *runFromHereAction = popupmenu->addAction( QObject::tr(
"Run from Here…" ) );
1226 connect( runFromHereAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::runFromHere );
1228 popupmenu->addSeparator();
1230 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1231 connect( removeAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deleteComponent );
1232 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1233 connect( editAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::editComponent );
1234 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
1235 connect( editCommentAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::editComment );
1236 popupmenu->addSeparator();
1238 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1240 if ( !child->isActive() )
1242 QAction *activateAction = popupmenu->addAction( QObject::tr(
"Activate" ) );
1243 connect( activateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::activateAlgorithm );
1247 QAction *deactivateAction = popupmenu->addAction( QObject::tr(
"Deactivate" ) );
1248 connect( deactivateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm );
1254 const QList<const QgsProcessingParameterDefinition *> outputParams =
algorithm->destinationParameterDefinitions();
1255 if ( !outputParams.isEmpty() )
1257 popupmenu->addSeparator();
1258 QAction *viewOutputLayersAction = popupmenu->addAction( QObject::tr(
"View Output Layers" ) );
1260 connect( viewOutputLayersAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::showPreviousResults );
1262 switch ( mResults.executionStatus() )
1266 viewOutputLayersAction->setEnabled(
false );
1275 QAction *viewLogAction = popupmenu->addAction( QObject::tr(
"View Log…" ) );
1276 connect( viewLogAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::showLog );
1278 switch ( mResults.executionStatus() )
1281 viewLogAction->setEnabled(
false );
1290 popupmenu->exec( event->screenPos() );
1293QColor QgsModelChildAlgorithmGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1298 c = QColor( 255, 255, 255 );
1300 c = QColor( 208, 0, 0 );
1305 c =
c.darker( 110 );
1308 c =
c.darker( 105 );
1317QColor QgsModelChildAlgorithmGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1322 return mIsValid ? QColor( 50, 50, 50 ) : QColor( 80, 0, 0 );
1325 return mIsValid ? Qt::gray : QColor( 134, 0, 0 );
1330QColor QgsModelChildAlgorithmGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1332 return mIsValid ? ( qgis::down_cast<const QgsProcessingModelChildAlgorithm *>( component() )->isActive() ? Qt::black : Qt::gray ) : QColor( 255, 255, 255 );
1335QColor QgsModelChildAlgorithmGraphicItem::outlineColor()
const
1339 return QColor( 150, 150, 0 );
1342 switch ( mResults.executionStatus() )
1347 return QColor( 150, 150, 150 );
1351 return QColor( 55, 160, 55 );
1353 return QColor( 208, 0, 0 );
1358QPixmap QgsModelChildAlgorithmGraphicItem::iconPixmap()
const
1363QPicture QgsModelChildAlgorithmGraphicItem::iconPicture()
const
1368int QgsModelChildAlgorithmGraphicItem::linkPointCount( Qt::Edge edge )
const
1370 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1372 if ( !child->algorithm() )
1377 case Qt::BottomEdge:
1378 return child->algorithm()->outputDefinitions().size();
1383 std::remove_if( params.begin(), params.end(), [](
const QgsProcessingParameterDefinition *param ) { return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination(); } ),
1386 return params.size();
1397QColor QgsModelComponentGraphicItem::linkColor( Qt::Edge edge,
int index )
const
1399 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1401 if ( !child->algorithm() )
1403 return FALLBACK_COLOR;
1408 case Qt::BottomEdge:
1410 if ( index <= child->
algorithm()->outputDefinitions().size() - 1 )
1412 return child->algorithm()->outputDefinitions().at( index )->modelColor();
1414 return FALLBACK_COLOR;
1420 if ( index <= params.size() - 1 )
1422 return params.at( index )->modelColor();
1425 return FALLBACK_COLOR;
1434 return FALLBACK_COLOR;
1437QString QgsModelChildAlgorithmGraphicItem::linkPointText( Qt::Edge edge,
int index )
const
1442 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1444 if ( !child->algorithm() )
1449 case Qt::BottomEdge:
1451 if ( index >= child->algorithm()->outputDefinitions().length() )
1460 return truncatedTextForItem( title );
1467 std::remove_if( params.begin(), params.end(), [](
const QgsProcessingParameterDefinition *param ) { return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination(); } ),
1471 if ( index >= params.length() )
1479 QString name = param->
name();
1481 QgsProcessingModelChildParameterSources paramSources = child->parameterSources().value( name );
1482 QString parameterValueAsString;
1484 if ( !paramSources.empty() )
1486 QgsProcessingModelChildParameterSource firstParameterSource = paramSources[0];
1488 switch ( firstParameterSource.source() )
1491 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) ) );
1495 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.expression() );
1500 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.expressionText() );
1505 parameterValueAsString = u
": <%1>"_s.arg( firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) ) );
1510 const QString friendlyName = firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) );
1511 parameterValueAsString = friendlyName.isEmpty() ? u
":"_s : u
": <%1>"_s.arg( friendlyName );
1516 const QVariant paramValue = paramSources[0].staticValue();
1519 title += parameterValueAsString;
1522 return truncatedTextForItem( title );
1533void QgsModelChildAlgorithmGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1535 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast<QgsProcessingModelChildAlgorithm *
>( component() ) )
1537 model()->childAlgorithm( child->childId() ).setPosition( pos );
1538 model()->childAlgorithm( child->childId() ).setSize( size );
1542bool QgsModelChildAlgorithmGraphicItem::canDeleteComponent()
1544 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1546 return model()->dependentChildAlgorithms( child->childId() ).empty();
1553 if ( mResults == results )
1557 const QList< QgsModelArrowItem * > arrows = outgoingArrows();
1560 for ( QgsModelArrowItem *arrow : arrows )
1562 arrow->setShowBadge(
false );
1567 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1571 const QVariantMap outputs = results.
outputs();
1572 for (
auto it = outputs.constBegin(); it != outputs.constEnd(); ++it )
1579 const int index = indexForOutput( it.key() );
1582 for ( QgsModelArrowItem *arrow : arrows )
1584 if ( arrow->startIndex() == index && arrow->startEdge() == Qt::BottomEdge )
1586 arrow->setShowBadge(
true );
1587 arrow->badgeItem()->setValue( it.value() );
1599 emit updateArrowPaths();
1602void QgsModelChildAlgorithmGraphicItem::setSourceFeatureCount(
const QString ¶meterName,
long long featureCount )
1604 const int index = indexForInput( parameterName );
1608 const QList< QgsModelArrowItem * > arrows = incomingArrows();
1609 for ( QgsModelArrowItem *arrow : arrows )
1611 if ( arrow->endIndex() == index && arrow->endEdge() == Qt::TopEdge )
1613 arrow->setShowBadge(
true );
1614 arrow->badgeItem()->setValue( featureCount );
1619void QgsModelChildAlgorithmGraphicItem::setSinkFeatureCount(
const QString &outputName,
long long featureCount )
1621 const int index = indexForOutput( outputName );
1625 const QList< QgsModelArrowItem * > arrows = outgoingArrows();
1626 for ( QgsModelArrowItem *arrow : arrows )
1628 if ( arrow->startIndex() == index && arrow->startEdge() == Qt::BottomEdge )
1630 arrow->setShowBadge(
true );
1631 arrow->badgeItem()->setValue( featureCount );
1636void QgsModelChildAlgorithmGraphicItem::setProgress(
double progress )
1638 if ( mProgress == progress )
1641 mProgress = progress;
1645void QgsModelChildAlgorithmGraphicItem::setStarted()
1651void QgsModelChildAlgorithmGraphicItem::setOutdated()
1657int QgsModelChildAlgorithmGraphicItem::indexForInput(
const QString ¶meterName )
const
1659 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1669int QgsModelChildAlgorithmGraphicItem::indexForOutput(
const QString &output )
const
1671 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1681void QgsModelChildAlgorithmGraphicItem::editComponent()
1686void QgsModelChildAlgorithmGraphicItem::editComment()
1691void QgsModelChildAlgorithmGraphicItem::applyEdit(
const QgsProcessingModelChildAlgorithm &
algorithm )
1693 const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() );
1697 QgsProcessingModelChildAlgorithm newAlgorithm =
algorithm;
1698 newAlgorithm.setChildId( child->childId() );
1699 newAlgorithm.copyNonDefinitionPropertiesFromModel( model() );
1700 if ( newAlgorithm.toVariant() == child->toVariant() )
1706 const QString undoCommandId = u
"alg:%1"_s.arg( child->childId() );
1707 emit aboutToChange( tr(
"Edit %1" ).arg( newAlgorithm.description() ), undoCommandId );
1708 model()->setChildAlgorithm( newAlgorithm );
1709 emit requestModelRepaint();
1713void QgsModelChildAlgorithmGraphicItem::paintBackground( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
1715 if ( mProgress < 0 )
1717 QgsModelComponentGraphicItem::paintBackground( painter, option, widget );
1721 paintOutline( painter, option, widget );
1723 const QRectF rect = itemRect();
1726 if ( component()->color().isValid() )
1728 color = component()->color();
1732 color = color.darker( 110 );
1735 color = color.darker( 105 );
1741 stroke = color.darker( 110 );
1745 color = fillColor( state() );
1746 stroke = strokeColor( state() );
1749 QPen strokePen = QPen( stroke, 0 );
1750 strokePen.setStyle( strokeStyle( state() ) );
1751 painter->setPen( strokePen );
1753 const QColor colorLeft = color.darker( 120 );
1754 QColor colorRight = color;
1756 constexpr double fadeSize = 5;
1757 const double fadeSizeProportionRect = fadeSize / rect.width();
1759 if ( mProgress < 98 )
1761 QLinearGradient gradient( rect.topLeft(), rect.topRight() );
1762 gradient.setColorAt( 0.0, colorLeft );
1763 gradient.setColorAt( std::max( 0.0, mProgress / 100 - fadeSizeProportionRect / 2 ), colorLeft );
1764 gradient.setColorAt( std::min( 1.0, mProgress / 100 + fadeSizeProportionRect / 2 ), colorRight );
1765 gradient.setColorAt( 1.0, colorRight );
1767 painter->setBrush( QBrush( gradient ) );
1771 painter->setBrush( QBrush( colorLeft ) );
1773 painter->drawRect( rect );
1776void QgsModelChildAlgorithmGraphicItem::deleteComponent()
1778 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1780 emit aboutToChange( tr(
"Remove %1" ).arg( child->algorithm() ? child->algorithm()->displayName() : tr(
"Algorithm" ) ) );
1781 if ( !model()->removeChildAlgorithm( child->childId() ) )
1783 QMessageBox::warning(
1785 QObject::tr(
"Could not remove algorithm" ),
1787 "Other algorithms depend on the selected one.\n"
1788 "Remove them before trying to remove it."
1795 emit requestModelRepaint();
1800void QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm()
1802 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1804 model()->deactivateChildAlgorithm( child->childId() );
1805 emit requestModelRepaint();
1809void QgsModelChildAlgorithmGraphicItem::activateAlgorithm()
1811 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1813 if ( model()->activateChildAlgorithm( child->childId() ) )
1815 emit requestModelRepaint();
1819 QMessageBox::warning(
1821 QObject::tr(
"Could not activate algorithm" ),
1823 "The selected algorithm depends on other currently non-active algorithms.\n"
1824 "Activate them them before trying to activate it.."
1831void QgsModelChildAlgorithmGraphicItem::edit(
bool editComment )
1833 const QgsProcessingModelChildAlgorithm *child =
dynamic_cast< const QgsProcessingModelChildAlgorithm *
>( component() );
1843 dlg.setModal(
true );
1844 dlg.setComments( child->comment()->description() );
1845 dlg.setCommentColor( child->comment()->color() );
1846 dlg.setWidgetContext( widgetContext );
1849 dlg.switchToCommentTab();
1854 std::unique_ptr< QgsProcessingModelChildAlgorithm > alg = dlg.createAlgorithm();
1858 emit rebuildConfigurationDockWidget();
1864QgsModelOutputGraphicItem::QgsModelOutputGraphicItem( QgsProcessingModelOutput *output, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1865 : QgsModelComponentGraphicItem( output, model, parent )
1868 QPainter painter( &mPicture );
1869 svg.render( &painter );
1871 setLabel( output->description() );
1874QColor QgsModelOutputGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1876 QColor
c( 172, 196, 114 );
1880 c =
c.darker( 110 );
1883 c =
c.darker( 105 );
1892QColor QgsModelOutputGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1897 return QColor( 42, 65, 42 );
1900 return QColor( 90, 140, 90 );
1905QColor QgsModelOutputGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1910QPicture QgsModelOutputGraphicItem::iconPicture()
const
1915void QgsModelOutputGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1917 if ( QgsProcessingModelOutput *output =
dynamic_cast<QgsProcessingModelOutput *
>( component() ) )
1919 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setPosition( pos );
1920 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setSize( size );
1924bool QgsModelOutputGraphicItem::canDeleteComponent()
1926 if (
dynamic_cast<const QgsProcessingModelOutput *
>( component() ) )
1933void QgsModelOutputGraphicItem::deleteComponent()
1935 if (
const QgsProcessingModelOutput *output =
dynamic_cast<const QgsProcessingModelOutput *
>( component() ) )
1937 emit aboutToChange( tr(
"Delete Output %1" ).arg( output->description() ) );
1938 model()->childAlgorithm( output->childId() ).removeModelOutput( output->name() );
1939 model()->updateDestinationParameters();
1941 emit requestModelRepaint();
1950QgsModelGroupBoxGraphicItem::QgsModelGroupBoxGraphicItem( QgsProcessingModelGroupBox *box, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1951 : QgsModelComponentGraphicItem( box, model, parent )
1953 setZValue( QgsModelGraphicsScene::ZValues::GroupBox );
1954 setLabel( box->description() );
1958 f.setPixelSize( 14 );
1962void QgsModelGroupBoxGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1964 QMenu *popupmenu =
new QMenu( event->widget() );
1965 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1966 connect( removeAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::deleteComponent );
1967 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1968 connect( editAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::editComponent );
1969 popupmenu->exec( event->screenPos() );
1972QgsModelGroupBoxGraphicItem::~QgsModelGroupBoxGraphicItem() =
default;
1974QColor QgsModelGroupBoxGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1976 QColor
c( 230, 230, 230 );
1980 c =
c.darker( 110 );
1983 c =
c.darker( 105 );
1992QColor QgsModelGroupBoxGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1997 return QColor( 50, 50, 50 );
2000 return QColor( 150, 150, 150 );
2005QColor QgsModelGroupBoxGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
2007 return QColor( 100, 100, 100 );
2010Qt::PenStyle QgsModelGroupBoxGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
2015Qt::Alignment QgsModelGroupBoxGraphicItem::titleAlignment()
const
2017 return Qt::AlignHCenter;
2020void QgsModelGroupBoxGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
2022 if ( QgsProcessingModelGroupBox *box =
dynamic_cast<QgsProcessingModelGroupBox *
>( component() ) )
2024 box->setPosition( pos );
2025 box->setSize( size );
2026 model()->addGroupBox( *box );
2030bool QgsModelGroupBoxGraphicItem::canDeleteComponent()
2032 if (
dynamic_cast<QgsProcessingModelGroupBox *
>( component() ) )
2039void QgsModelGroupBoxGraphicItem::applyEdit(
const QgsProcessingModelGroupBox &groupBox )
2041 QgsProcessingModelGroupBox newGroupBox = groupBox;
2042 const QList<QgsProcessingModelGroupBox> existingGroupBoxes = model()->groupBoxes();
2043 for (
const QgsProcessingModelGroupBox &existingGroupBox : existingGroupBoxes )
2045 if ( existingGroupBox.uuid() == newGroupBox.uuid() )
2048 newGroupBox.setPosition( existingGroupBox.position() );
2049 newGroupBox.setSize( existingGroupBox.size() );
2053 const QString commandId = u
"groupbox:%1"_s.arg( newGroupBox.uuid() );
2054 emit aboutToChange( tr(
"Edit Group Box" ), commandId );
2056 model()->addGroupBox( newGroupBox );
2058 emit requestModelRepaint();
2061void QgsModelGroupBoxGraphicItem::deleteComponent()
2063 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast<const QgsProcessingModelGroupBox *
>( component() ) )
2065 emit aboutToChange( tr(
"Delete Group Box" ) );
2066 model()->removeGroupBox( box->uuid() );
2068 emit requestModelRepaint();
2072void QgsModelGroupBoxGraphicItem::editComponent()
2074 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast<const QgsProcessingModelGroupBox *
>( component() ) )
2080 applyEdit( dlg.groupBox() );
2089QgsModelCommentGraphicItem::QgsModelCommentGraphicItem( QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
2090 : QgsModelComponentGraphicItem( comment, model, parent )
2091 , mParentComponent( parentItem->component()->clone() )
2092 , mParentItem( parentItem )
2094 setLabel( comment->description() );
2097 f.setPixelSize( 9 );
2101void QgsModelCommentGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
2103 QMenu *popupmenu =
new QMenu( event->widget() );
2104 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
2105 connect( removeAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::deleteComponent );
2106 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
2107 connect( editAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::editComponent );
2108 popupmenu->exec( event->screenPos() );
2111QgsModelCommentGraphicItem::~QgsModelCommentGraphicItem() =
default;
2113QColor QgsModelCommentGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
2115 QColor
c( 230, 230, 230 );
2119 c =
c.darker( 110 );
2122 c =
c.darker( 105 );
2131QColor QgsModelCommentGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
2136 return QColor( 50, 50, 50 );
2139 return QColor( 150, 150, 150 );
2144QColor QgsModelCommentGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
2146 return QColor( 100, 100, 100 );
2149Qt::PenStyle QgsModelCommentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
2154void QgsModelCommentGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
2156 if ( QgsProcessingModelComment *comment = modelComponent() )
2158 comment->setPosition( pos );
2159 comment->setSize( size );
2163bool QgsModelCommentGraphicItem::canDeleteComponent()
2165 if ( modelComponent() )
2172void QgsModelCommentGraphicItem::deleteComponent()
2174 if ( QgsProcessingModelComment *comment = modelComponent() )
2176 emit aboutToChange( tr(
"Delete Comment" ) );
2177 comment->setDescription( QString() );
2179 emit requestModelRepaint();
2183void QgsModelCommentGraphicItem::editComponent()
2187 mParentItem->editComment();
2191QgsProcessingModelComment *QgsModelCommentGraphicItem::modelComponent()
2193 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( mParentComponent.get() ) )
2195 return model()->childAlgorithm( child->childId() ).comment();
2197 else if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( mParentComponent.get() ) )
2199 return model()->parameterComponent( param->parameterName() ).comment();
2201 else if (
const QgsProcessingModelOutput *output =
dynamic_cast<const QgsProcessingModelOutput *
>( mParentComponent.get() ) )
2203 return model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).comment();
2208QgsModelComponentGraphicItem *QgsModelCommentGraphicItem::parentComponentItem()
const
@ Success
Child was successfully executed.
@ NotExecuted
Child has not been executed.
@ Failed
Child encountered an error while executing.
@ Warning
Warning message.
@ ExpressionText
Parameter value is taken from a text with expressions, evaluated just before the algorithm runs.
@ ModelOutput
Parameter value is linked to an output parameter for the model.
@ ChildOutput
Parameter value is taken from an output generated by a child algorithm.
@ ModelParameter
Parameter value is taken from a parent model parameter.
@ StaticValue
Parameter value is a static value.
@ Expression
Parameter value is taken from an expression, evaluated just before the algorithm runs.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
A dialog which allows users to specify the properties of a model group box.
A mouse event which is the result of a user interaction with a QgsModelGraphicsView.
QPointF modelPoint() const
Returns the event point location in model coordinates.
Abstract base class for processing algorithms.
virtual QgsProcessingContext * processingContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return a Proc...
Contains information about the context in which a processing algorithm is executed.
Encapsulates the results of running a child algorithm within a model.
QVariantMap outputs() const
Returns the outputs generated by the child algorithm.
Qgis::ProcessingModelChildAlgorithmExecutionStatus executionStatus() const
Returns the status of executing the child algorithm.
A dialog for configuring parameter settings and comments for a child algorithm in a Processing model.
Base class for the definition of processing outputs.
QString description() const
Returns the description for the output.
A dialog which allows users to specify the properties of a Processing parameter.
Base class for the definition of processing parameters.
virtual QString userFriendlyString(const QVariant &value) const
Returns a user-friendly string representation of the provided parameter value.
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.
void setModelChildAlgorithmId(const QString &id)
Sets the child algorithm id within 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...
static int parameterDefinitionIndex(const QgsProcessingAlgorithm *algorithm, const QString &name)
Returns the index of the parameter with matching name for a specified algorithm.
static int outputDefinitionIndex(const QgsProcessingAlgorithm *algorithm, const QString &name)
Returns the index of the output matching name for a specified algorithm.
An interface for objects which can create Processing widget contexts.
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 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
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
#define Q_NOWARN_DEPRECATED_POP
#define BUILTIN_UNREACHABLE
#define Q_NOWARN_DEPRECATED_PUSH
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.