34#include <QApplication>
35#include <QGraphicsSceneHoverEvent>
42#include <QSvgRenderer>
44#include "moc_qgsmodelcomponentgraphicitem.cpp"
46using namespace Qt::StringLiterals;
50QgsModelComponentGraphicItem::QgsModelComponentGraphicItem( QgsProcessingModelComponent *component, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
51 : QGraphicsObject( parent )
52 , mComponent( component )
55 setAcceptHoverEvents(
true );
56 setFlag( QGraphicsItem::ItemIsSelectable,
true );
57 setFlag( QGraphicsItem::ItemSendsGeometryChanges,
true );
58 setZValue( QgsModelGraphicsScene::ZValues::ModelComponent );
60 mFont.setPixelSize( 12 );
64 QPainter painter( &editPicture );
65 svg.render( &painter );
67 mEditButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, editPicture, QPointF( 0, 0 ) );
68 connect( mEditButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::editComponent );
71 QPicture deletePicture;
72 painter.begin( &deletePicture );
73 svg2.render( &painter );
75 mDeleteButton =
new QgsModelDesignerFlatButtonGraphicItem(
this, deletePicture, QPointF( 0, 0 ) );
76 connect( mDeleteButton, &QgsModelDesignerFlatButtonGraphicItem::clicked,
this, &QgsModelComponentGraphicItem::deleteComponent );
78 updateButtonPositions();
81QgsModelComponentGraphicItem::Flags QgsModelComponentGraphicItem::flags()
const
83 return QgsModelComponentGraphicItem::Flags();
86QgsModelComponentGraphicItem::~QgsModelComponentGraphicItem() =
default;
88QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
90 return mComponent.get();
93const QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
const
95 return mComponent.get();
98QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
103const QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
const
108QgsModelGraphicsView *QgsModelComponentGraphicItem::view()
110 if ( scene()->views().isEmpty() )
113 return qobject_cast<QgsModelGraphicsView *>( scene()->views().first() );
116QFont QgsModelComponentGraphicItem::font()
const
121void QgsModelComponentGraphicItem::setFont(
const QFont &font )
127void QgsModelComponentGraphicItem::moveComponentBy( qreal dx, qreal dy )
129 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
130 mComponent->setPosition( pos() );
132 emit aboutToChange( tr(
"Move %1" ).arg( mComponent->description() ) );
133 updateStoredComponentPosition( pos(), mComponent->size() );
136 emit sizePositionChanged();
137 emit updateArrowPaths();
140void QgsModelComponentGraphicItem::previewItemMove( qreal dx, qreal dy )
142 setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
143 emit updateArrowPaths();
146void QgsModelComponentGraphicItem::setItemRect( QRectF rect )
148 rect = rect.normalized();
150 if ( rect.width() < MIN_COMPONENT_WIDTH )
151 rect.setWidth( MIN_COMPONENT_WIDTH );
152 if ( rect.height() < MIN_COMPONENT_HEIGHT )
153 rect.setHeight( MIN_COMPONENT_HEIGHT );
155 setPos( rect.center() );
156 prepareGeometryChange();
158 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
160 mComponent->setPosition( pos() );
161 mComponent->setSize( rect.size() );
162 updateStoredComponentPosition( pos(), mComponent->size() );
164 updateButtonPositions();
167 emit updateArrowPaths();
168 emit sizePositionChanged();
171QRectF QgsModelComponentGraphicItem::previewItemRectChange( QRectF rect )
173 rect = rect.normalized();
175 if ( rect.width() < MIN_COMPONENT_WIDTH )
176 rect.setWidth( MIN_COMPONENT_WIDTH );
177 if ( rect.height() < MIN_COMPONENT_HEIGHT )
178 rect.setHeight( MIN_COMPONENT_HEIGHT );
180 setPos( rect.center() );
181 prepareGeometryChange();
183 mTempSize = rect.size();
185 updateButtonPositions();
186 emit updateArrowPaths();
191void QgsModelComponentGraphicItem::finalizePreviewedItemRectChange( QRectF )
193 mComponent->setPosition( pos() );
194 prepareGeometryChange();
195 mComponent->setSize( mTempSize );
196 mTempSize = QSizeF();
198 emit aboutToChange( tr(
"Resize %1" ).arg( mComponent->description() ) );
199 updateStoredComponentPosition( pos(), mComponent->size() );
201 updateButtonPositions();
205 emit sizePositionChanged();
206 emit updateArrowPaths();
211 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
212 updateToolTip( mapFromScene( event->
modelPoint() ) );
217 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
218 updateToolTip( mapFromScene( event->
modelPoint() ) );
223 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
225 setToolTip( QString() );
230 emit repaintArrows();
237 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
241void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
243 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
247void QgsModelComponentGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent *event )
249 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
250 updateToolTip( event->pos() );
253void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
255 if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
256 updateToolTip( event->pos() );
259void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
261 modelHoverLeaveEvent(
nullptr );
264QVariant QgsModelComponentGraphicItem::itemChange( QGraphicsItem::GraphicsItemChange change,
const QVariant &value )
268 case QGraphicsItem::ItemSelectedChange:
270 emit repaintArrows();
274 case QGraphicsItem::ItemSceneChange:
279 if ( linkPointCount( Qt::TopEdge ) )
281 mExpandTopButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::TopEdge ), QPointF( 0, 0 ) );
282 connect( mExpandTopButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [
this](
bool folded ) { fold( Qt::TopEdge, folded ); } );
284 for (
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
286 mInSockets.append(
new QgsModelDesignerSocketGraphicItem(
this, mComponent.get(), idx, QPointF( 0, 0 ), Qt::TopEdge ) );
289 if ( linkPointCount( Qt::BottomEdge ) )
291 mExpandBottomButton =
new QgsModelDesignerFoldButtonGraphicItem(
this, mComponent->linksCollapsed( Qt::BottomEdge ), QPointF( 0, 0 ) );
292 connect( mExpandBottomButton, &QgsModelDesignerFoldButtonGraphicItem::folded,
this, [
this](
bool folded ) { fold( Qt::BottomEdge, folded ); } );
294 for (
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
296 mOutSockets.append(
new QgsModelDesignerSocketGraphicItem(
this, mComponent.get(), idx, QPointF( 0, 0 ), Qt::BottomEdge ) );
300 updateButtonPositions();
309 return QGraphicsObject::itemChange( change, value );
312QRectF QgsModelComponentGraphicItem::boundingRect()
const
314 const QFontMetricsF fm( mFont );
315 const int linksAbove = linkPointCount( Qt::TopEdge );
316 const int linksBelow = linkPointCount( Qt::BottomEdge );
318 const double hUp = linksAbove == 0 ? 0 : fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::TopEdge ) ? 0 : linksAbove ) + 2 );
319 const double hDown = linksBelow == 0 ? 0 : fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::BottomEdge ) ? 0 : linksBelow ) + 2 );
321 double outlineSize = 0;
322 if ( outlineColor().isValid() )
324 outlineSize = RECT_OUTLINE_SIZE + 0.5;
328 -( itemSize().width() ) / 2 - RECT_PEN_SIZE - outlineSize,
329 -( itemSize().height() ) / 2 - hUp - RECT_PEN_SIZE - outlineSize,
330 itemSize().width() + 2 * RECT_PEN_SIZE + outlineSize * 2,
331 itemSize().height() + hDown + hUp + 2 * RECT_PEN_SIZE + outlineSize * 2
335bool QgsModelComponentGraphicItem::contains(
const QPointF &point )
const
337 const QRectF paintingBounds = boundingRect();
338 if ( point.x() < paintingBounds.left() + RECT_PEN_SIZE )
340 if ( point.x() > paintingBounds.right() - RECT_PEN_SIZE )
342 if ( point.y() < paintingBounds.top() + RECT_PEN_SIZE )
344 if ( point.y() > paintingBounds.bottom() - RECT_PEN_SIZE )
350void QgsModelComponentGraphicItem::paintBackground( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
352 const QRectF rect = itemRect();
355 if ( mComponent->color().isValid() )
357 color = mComponent->color();
361 color = color.darker( 110 );
364 color = color.darker( 105 );
370 stroke = color.darker( 110 );
374 color = fillColor( state() );
375 stroke = strokeColor( state() );
378 paintOutline( painter, option, widget );
380 QPen strokePen = QPen( stroke, 0 );
381 strokePen.setStyle( strokeStyle( state() ) );
382 painter->setPen( strokePen );
383 painter->setBrush( QBrush( color, Qt::SolidPattern ) );
384 painter->drawRect( rect );
387void QgsModelComponentGraphicItem::paintOutline( QPainter *painter,
const QStyleOptionGraphicsItem *, QWidget * )
389 const QColor outline = outlineColor();
390 if ( outline.isValid() )
393 const bool wasAntiAliased = painter->testRenderHint( QPainter::RenderHint::Antialiasing );
394 painter->setRenderHint( QPainter::RenderHint::Antialiasing );
395 QPen strokePen = QPen( outline, RECT_OUTLINE_SIZE );
396 strokePen.setJoinStyle( Qt::MiterJoin );
397 strokePen.setStyle( strokeStyle( state() ) );
398 painter->setPen( strokePen );
399 painter->setBrush( Qt::NoBrush );
400 const QRectF rect = itemRect();
401 painter->drawRect( rect );
402 painter->setRenderHint( QPainter::RenderHint::Antialiasing, wasAntiAliased );
406void QgsModelComponentGraphicItem::paint( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
408 paintBackground( painter, option, widget );
410 const QRectF rect = itemRect();
412 if ( mComponent->color().isValid() )
414 QColor color = mComponent->color();
418 color = color.darker( 110 );
421 color = color.darker( 105 );
427 foreColor = color.lightness() > 150 ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 );
431 foreColor = textColor( state() );
433 painter->setFont( font() );
434 painter->setPen( QPen( foreColor ) );
438 const QSizeF componentSize = itemSize();
440 const QFontMetricsF fm( font() );
441 double h = fm.ascent();
442 QPointF pt( -componentSize.width() / 2 + 25, componentSize.height() / 2.0 - h + 1 );
444 if ( iconPicture().isNull() && iconPixmap().isNull() )
446 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 );
448 painter->drawText( labelRect, Qt::TextWordWrap | titleAlignment(), text );
452 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 );
454 painter->drawText( labelRect, Qt::TextWordWrap | Qt::AlignVCenter, text );
457 painter->setPen( QPen( QApplication::palette().color( QPalette::Text ) ) );
459 if ( linkPointCount( Qt::TopEdge ) )
461 h = -( fm.height() * 1.2 );
462 h = h - componentSize.height() / 2.0 + 5;
463 pt = QPointF( -componentSize.width() / 2 + 25, h );
464 painter->drawText( pt, QObject::tr(
"In" ) );
466 if ( !mComponent->linksCollapsed( Qt::TopEdge ) )
468 for (
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
470 text = linkPointText( Qt::TopEdge, idx );
471 h = -( fm.height() * 1.2 ) * ( i + 1 );
472 h = h - componentSize.height() / 2.0 + 5;
473 pt = QPointF( -componentSize.width() / 2 + 33, h );
474 painter->drawText( pt, text );
479 if ( linkPointCount( Qt::BottomEdge ) )
481 h = fm.height() * 1.1;
482 h = h + componentSize.height() / 2.0;
483 pt = QPointF( -componentSize.width() / 2 + 25, h );
484 painter->drawText( pt, QObject::tr(
"Out" ) );
485 if ( !mComponent->linksCollapsed( Qt::BottomEdge ) )
487 for (
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
489 text = linkPointText( Qt::BottomEdge, idx );
490 h = fm.height() * 1.2 * ( idx + 2 );
491 h = h + componentSize.height() / 2.0;
492 pt = QPointF( -componentSize.width() / 2 + 33, h );
493 painter->drawText( pt, text );
498 const QPixmap px = iconPixmap();
501 painter->drawPixmap( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), px );
505 const QPicture pic = iconPicture();
508 painter->drawPicture( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), pic );
513QRectF QgsModelComponentGraphicItem::itemRect(
bool storedRect )
const
517 return QRectF( mComponent->position().x() - ( mComponent->size().width() ) / 2.0, mComponent->position().y() - ( mComponent->size().height() ) / 2.0, mComponent->size().width(), mComponent->size().height() );
520 return QRectF( -( itemSize().width() ) / 2.0, -( itemSize().height() ) / 2.0, itemSize().width(), itemSize().height() );
523QString QgsModelComponentGraphicItem::truncatedTextForItem(
const QString &text )
const
525 const QFontMetricsF fm( mFont );
526 double width = fm.boundingRect( text ).width();
527 if ( width < itemSize().width() - 25 - mButtonSize.width() )
531 t = t.left( t.length() - 3 ) + QChar( 0x2026 );
532 width = fm.boundingRect( t ).width();
533 while ( width > itemSize().width() - 25 - mButtonSize.width() )
535 if ( t.length() < 5 )
538 t = t.left( t.length() - 4 ) + QChar( 0x2026 );
539 width = fm.boundingRect( t ).width();
544Qt::PenStyle QgsModelComponentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
546 return Qt::SolidLine;
549Qt::Alignment QgsModelComponentGraphicItem::titleAlignment()
const
551 return Qt::AlignLeft;
554QPicture QgsModelComponentGraphicItem::iconPicture()
const
559QPixmap QgsModelComponentGraphicItem::iconPixmap()
const
565void QgsModelComponentGraphicItem::updateButtonPositions()
567 mEditButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN, itemSize().height() / 2.0 - mButtonSize.height() / 2.0 - BUTTON_MARGIN ) );
568 mDeleteButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN, mButtonSize.height() / 2.0 - itemSize().height() / 2.0 + BUTTON_MARGIN ) );
570 if ( mExpandBottomButton )
572 const QPointF pt = linkPoint( Qt::BottomEdge, -1,
false );
573 mExpandBottomButton->setPosition( QPointF( 0, pt.y() ) );
575 bool collapsed = mComponent->linksCollapsed( Qt::BottomEdge );
576 for ( QgsModelDesignerSocketGraphicItem *socket : std::as_const( mOutSockets ) )
578 const QPointF pt = linkPoint( Qt::BottomEdge, socket->index(),
false );
579 socket->setPosition( pt );
580 socket->setVisible( !collapsed );
585 if ( mExpandTopButton )
587 const QPointF pt = linkPoint( Qt::TopEdge, -1,
true );
588 mExpandTopButton->setPosition( QPointF( 0, pt.y() ) );
590 bool collapsed = mComponent->linksCollapsed( Qt::TopEdge );
591 for ( QgsModelDesignerSocketGraphicItem *socket : std::as_const( mInSockets ) )
593 const QPointF pt = linkPoint( Qt::TopEdge, socket->index(),
true );
594 socket->setPosition( pt );
595 socket->setVisible( !collapsed );
601QSizeF QgsModelComponentGraphicItem::itemSize()
const
603 return !mTempSize.isValid() ? mComponent->size() : mTempSize;
606void QgsModelComponentGraphicItem::updateToolTip(
const QPointF &pos )
608 const bool prevHoverStatus = mIsHovering;
609 if ( itemRect().contains( pos ) )
611 setToolTip( mLabel );
616 setToolTip( QString() );
619 if ( mIsHovering != prevHoverStatus )
622 emit repaintArrows();
626void QgsModelComponentGraphicItem::fold( Qt::Edge edge,
bool folded )
628 emit aboutToChange( !folded ? tr(
"Expand Item" ) : tr(
"Collapse Item" ) );
629 mComponent->setLinksCollapsed( edge, folded );
633 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast<QgsProcessingModelChildAlgorithm *
>( mComponent.get() ) )
635 mModel->childAlgorithm( child->childId() ).setLinksCollapsed( edge, folded );
637 else if ( QgsProcessingModelParameter *param =
dynamic_cast<QgsProcessingModelParameter *
>( mComponent.get() ) )
639 mModel->parameterComponent( param->parameterName() ).setLinksCollapsed( edge, folded );
641 else if ( QgsProcessingModelOutput *output =
dynamic_cast<QgsProcessingModelOutput *
>( mComponent.get() ) )
643 mModel->childAlgorithm( output->childId() ).modelOutput( output->name() ).setLinksCollapsed( edge, folded );
646 updateButtonPositions();
647 prepareGeometryChange();
648 emit updateArrowPaths();
653QString QgsModelComponentGraphicItem::label()
const
658void QgsModelComponentGraphicItem::setLabel(
const QString &label )
664QgsModelComponentGraphicItem::State QgsModelComponentGraphicItem::state()
const
668 else if ( mIsHovering )
674int QgsModelComponentGraphicItem::linkPointCount( Qt::Edge )
const
679QString QgsModelComponentGraphicItem::linkPointText( Qt::Edge,
int )
const
684QPointF QgsModelComponentGraphicItem::linkPoint( Qt::Edge edge,
int index,
bool incoming )
const
690 if ( linkPointCount( Qt::BottomEdge ) )
693 if ( mComponent->linksCollapsed( Qt::BottomEdge ) )
697 const int pointIndex = !mComponent->linksCollapsed( Qt::BottomEdge ) ? index : -1;
698 const QString text = truncatedTextForItem( linkPointText( Qt::BottomEdge, index ) );
699 const QFontMetricsF fm( mFont );
700 const double w = fm.boundingRect( text ).width();
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;
703 const double x = !mComponent->linksCollapsed( Qt::BottomEdge ) ? ( -itemSize().width() / 2 + 33 + w + 10 ) : 10.4;
704 return QPointF( incoming ? -itemSize().width() / 2 + offsetX : x, y );
711 if ( linkPointCount( Qt::TopEdge ) )
714 int paramIndex = index;
715 if ( mComponent->linksCollapsed( Qt::TopEdge ) )
720 const QFontMetricsF fm( mFont );
721 const QString text = truncatedTextForItem( linkPointText( Qt::TopEdge, index ) );
722 const double w = fm.boundingRect( text ).width();
723 double h = -( fm.height() * 1.2 ) * ( paramIndex + 2 ) - fm.height() / 2.0 + 8;
724 h = h - itemSize().height() / 2.0;
725 return QPointF( incoming ? -itemSize().width() / 2 + offsetX : ( !mComponent->linksCollapsed( Qt::TopEdge ) ? ( -itemSize().width() / 2 + 33 + w + 5 ) : 10 ), h );
737QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint( QgsModelComponentGraphicItem *other, Qt::Edge &edge )
const
740 const QgsRectangle otherRect( other->itemRect().translated( other->pos() ) );
742 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
743 const double distLeft = otherRect.distance(
QgsPointXY( leftPoint ) );
745 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
746 const double distRight = otherRect.distance(
QgsPointXY( rightPoint ) );
748 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
749 const double distTop = otherRect.distance(
QgsPointXY( topPoint ) );
751 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
752 const double distBottom = otherRect.distance(
QgsPointXY( bottomPoint ) );
754 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
759 else if ( distRight <= distTop && distRight <= distBottom )
761 edge = Qt::RightEdge;
764 else if ( distBottom <= distTop )
766 edge = Qt::BottomEdge;
776QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint(
const QPointF &point, Qt::Edge &edge )
const
780 const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
781 const double distLeft = otherPt.distance(
QgsPointXY( leftPoint ) );
783 const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
784 const double distRight = otherPt.distance(
QgsPointXY( rightPoint ) );
786 const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
787 const double distTop = otherPt.distance(
QgsPointXY( topPoint ) );
789 const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
790 const double distBottom = otherPt.distance(
QgsPointXY( bottomPoint ) );
792 if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
797 else if ( distRight <= distTop && distRight <= distBottom )
799 edge = Qt::RightEdge;
802 else if ( distBottom <= distTop )
804 edge = Qt::BottomEdge;
814QgsModelDesignerSocketGraphicItem *QgsModelComponentGraphicItem::outSocketAt(
int index )
const
816 if ( index < 0 || index >= mOutSockets.size() )
820 return mOutSockets.at( index );
823QList<QgsModelArrowItem *> QgsModelComponentGraphicItem::incomingArrows()
825 const QList<QGraphicsItem *> allItems = scene()->items();
826 QList<QgsModelArrowItem *> arrows;
827 for ( QGraphicsItem *item : allItems )
829 if (
auto arrowItem =
dynamic_cast< QgsModelArrowItem *
>( item ) )
831 if ( arrowItem->endItem() ==
this )
840QList<QgsModelArrowItem *> QgsModelComponentGraphicItem::outgoingArrows()
842 const QList<QGraphicsItem *> allItems = scene()->items();
843 QList<QgsModelArrowItem *> arrows;
844 for ( QGraphicsItem *item : allItems )
846 if (
auto arrowItem =
dynamic_cast< QgsModelArrowItem *
>( item ) )
848 if ( arrowItem->startItem() ==
this )
859 mWidgetContextGenerator = generator;
864 if ( mWidgetContextGenerator )
866 return mWidgetContextGenerator->createWidgetContext();
871QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
872 : QgsModelComponentGraphicItem( parameter, model, parent )
875 QPainter painter( &mPicture );
876 svg.render( &painter );
880 setLabel( parameterDefinition->description() );
882 setLabel( QObject::tr(
"Error (%1)" ).arg( parameter->parameterName() ) );
885void QgsModelParameterGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
887 QMenu *popupmenu =
new QMenu( event->widget() );
888 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
889 connect( removeAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::deleteComponent );
890 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
891 connect( editAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComponent );
892 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
893 connect( editCommentAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComment );
895 popupmenu->exec( event->screenPos() );
898QColor QgsModelParameterGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
900 QColor
c( 238, 242, 131 );
916QColor QgsModelParameterGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
921 return QColor( 116, 113, 68 );
924 return QColor( 234, 226, 118 );
929QColor QgsModelParameterGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
934QPicture QgsModelParameterGraphicItem::iconPicture()
const
939int QgsModelParameterGraphicItem::linkPointCount( Qt::Edge edge )
const
954QString QgsModelParameterGraphicItem::linkPointText( Qt::Edge,
int index )
const
961 if (
const QgsProcessingModelParameter *parameter =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
963 QString text = this->model()->parameterDefinition( parameter->parameterName() )->type();
968 const QVariant paramValue = paramDef->defaultValue();
970 if ( paramValue.isValid() )
972 text +=
": " + paramDef->userFriendlyString( paramValue );
975 return truncatedTextForItem( text );
981QColor QgsModelParameterGraphicItem::linkColor( Qt::Edge ,
int index )
const
985 return FALLBACK_COLOR;
988 if (
const QgsProcessingModelParameter *parameter =
dynamic_cast< const QgsProcessingModelParameter *
>( component() ) )
992 return parameterDefinition->modelColor();
996 return FALLBACK_COLOR;
999void QgsModelParameterGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1001 if ( QgsProcessingModelParameter *param =
dynamic_cast<QgsProcessingModelParameter *
>( component() ) )
1003 model()->parameterComponent( param->parameterName() ).setPosition( pos );
1004 model()->parameterComponent( param->parameterName() ).setSize( size );
1008bool QgsModelParameterGraphicItem::canDeleteComponent()
1010 if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( component() ) )
1012 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
1016 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
1028void QgsModelParameterGraphicItem::deleteComponent()
1030 if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( component() ) )
1032 if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
1034 QMessageBox::warning(
1036 QObject::tr(
"Could not remove input" ),
1038 "Algorithms depend on the selected input.\n"
1039 "Remove them before trying to remove it."
1043 else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
1045 QMessageBox::warning(
1047 QObject::tr(
"Could not remove input" ),
1049 "Other inputs depend on the selected input.\n"
1050 "Remove them before trying to remove it."
1056 emit aboutToChange( tr(
"Delete Input %1" ).arg( param->description() ) );
1057 model()->removeModelParameter( param->parameterName() );
1059 emit requestModelRepaint();
1065QgsModelChildAlgorithmGraphicItem::QgsModelChildAlgorithmGraphicItem( QgsProcessingModelChildAlgorithm *child, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1066 : QgsModelComponentGraphicItem( child, model, parent )
1068 if ( child->algorithm() && !child->algorithm()->svgIconPath().isEmpty() )
1070 QSvgRenderer svg( child->algorithm()->svgIconPath() );
1071 const QSizeF size = svg.defaultSize();
1072 QPainter painter( &mPicture );
1073 painter.scale( 16.0 / size.width(), 16.0 / size.width() );
1074 svg.render( &painter );
1077 else if ( child->algorithm() )
1079 mPixmap = child->algorithm()->icon().pixmap( 15, 15 );
1082 setLabel( child->description() );
1085 mIsValid = model->validateChildAlgorithm( child->childId(), issues );
1088void QgsModelChildAlgorithmGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1090 QMenu *popupmenu =
new QMenu( event->widget() );
1094 QAction *runSelectedStepsAction = popupmenu->addAction( QObject::tr(
"Run Selected Steps…" ) );
1096 connect( runSelectedStepsAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::runSelected );
1099 QAction *runFromHereAction = popupmenu->addAction( QObject::tr(
"Run from Here…" ) );
1101 connect( runFromHereAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::runFromHere );
1103 popupmenu->addSeparator();
1105 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1106 connect( removeAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deleteComponent );
1107 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1108 connect( editAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::editComponent );
1109 QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr(
"Add Comment…" ) : QObject::tr(
"Edit Comment…" ) );
1110 connect( editCommentAction, &QAction::triggered,
this, &QgsModelParameterGraphicItem::editComment );
1111 popupmenu->addSeparator();
1113 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1115 if ( !child->isActive() )
1117 QAction *activateAction = popupmenu->addAction( QObject::tr(
"Activate" ) );
1118 connect( activateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::activateAlgorithm );
1122 QAction *deactivateAction = popupmenu->addAction( QObject::tr(
"Deactivate" ) );
1123 connect( deactivateAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm );
1129 const QList<const QgsProcessingParameterDefinition *> outputParams =
algorithm->destinationParameterDefinitions();
1130 if ( !outputParams.isEmpty() )
1132 popupmenu->addSeparator();
1133 QAction *viewOutputLayersAction = popupmenu->addAction( QObject::tr(
"View Output Layers" ) );
1135 connect( viewOutputLayersAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::showPreviousResults );
1137 switch ( mResults.executionStatus() )
1141 viewOutputLayersAction->setEnabled(
false );
1150 QAction *viewLogAction = popupmenu->addAction( QObject::tr(
"View Log…" ) );
1151 connect( viewLogAction, &QAction::triggered,
this, &QgsModelChildAlgorithmGraphicItem::showLog );
1153 switch ( mResults.executionStatus() )
1156 viewLogAction->setEnabled(
false );
1165 popupmenu->exec( event->screenPos() );
1168QColor QgsModelChildAlgorithmGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1173 c = QColor( 255, 255, 255 );
1175 c = QColor( 208, 0, 0 );
1180 c =
c.darker( 110 );
1183 c =
c.darker( 105 );
1192QColor QgsModelChildAlgorithmGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1197 return mIsValid ? QColor( 50, 50, 50 ) : QColor( 80, 0, 0 );
1200 return mIsValid ? Qt::gray : QColor( 134, 0, 0 );
1205QColor QgsModelChildAlgorithmGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1207 return mIsValid ? ( qgis::down_cast<const QgsProcessingModelChildAlgorithm *>( component() )->isActive() ? Qt::black : Qt::gray ) : QColor( 255, 255, 255 );
1210QColor QgsModelChildAlgorithmGraphicItem::outlineColor()
const
1214 return QColor( 150, 150, 0 );
1217 switch ( mResults.executionStatus() )
1222 return QColor( 150, 150, 150 );
1226 return QColor( 55, 160, 55 );
1228 return QColor( 208, 0, 0 );
1233QPixmap QgsModelChildAlgorithmGraphicItem::iconPixmap()
const
1238QPicture QgsModelChildAlgorithmGraphicItem::iconPicture()
const
1243int QgsModelChildAlgorithmGraphicItem::linkPointCount( Qt::Edge edge )
const
1245 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1247 if ( !child->algorithm() )
1252 case Qt::BottomEdge:
1253 return child->algorithm()->outputDefinitions().size();
1258 std::remove_if( params.begin(), params.end(), [](
const QgsProcessingParameterDefinition *param ) { return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination(); } ),
1261 return params.size();
1272QColor QgsModelComponentGraphicItem::linkColor( Qt::Edge edge,
int index )
const
1274 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1276 if ( !child->algorithm() )
1278 return FALLBACK_COLOR;
1283 case Qt::BottomEdge:
1285 if ( index <= child->
algorithm()->outputDefinitions().size() - 1 )
1287 return child->algorithm()->outputDefinitions().at( index )->modelColor();
1289 return FALLBACK_COLOR;
1295 if ( index <= params.size() - 1 )
1297 return params.at( index )->modelColor();
1300 return FALLBACK_COLOR;
1309 return FALLBACK_COLOR;
1312QString QgsModelChildAlgorithmGraphicItem::linkPointText( Qt::Edge edge,
int index )
const
1317 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1319 if ( !child->algorithm() )
1324 case Qt::BottomEdge:
1326 if ( index >= child->algorithm()->outputDefinitions().length() )
1335 return truncatedTextForItem( title );
1342 std::remove_if( params.begin(), params.end(), [](
const QgsProcessingParameterDefinition *param ) { return param->flags() & Qgis::ProcessingParameterFlag::Hidden || param->isDestination(); } ),
1346 if ( index >= params.length() )
1354 QString name = param->
name();
1356 QgsProcessingModelChildParameterSources paramSources = child->parameterSources().value( name );
1357 QString parameterValueAsString;
1359 if ( !paramSources.empty() )
1361 QgsProcessingModelChildParameterSource firstParameterSource = paramSources[0];
1363 switch ( firstParameterSource.source() )
1366 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) ) );
1370 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.expression() );
1375 parameterValueAsString = u
": %1"_s.arg( firstParameterSource.expressionText() );
1380 parameterValueAsString = u
": <%1>"_s.arg( firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) ) );
1385 const QString friendlyName = firstParameterSource.friendlyIdentifier(
const_cast<QgsProcessingModelAlgorithm *
>( model() ) );
1386 parameterValueAsString = friendlyName.isEmpty() ? u
":"_s : u
": <%1>"_s.arg( friendlyName );
1391 const QVariant paramValue = paramSources[0].staticValue();
1394 title += parameterValueAsString;
1397 return truncatedTextForItem( title );
1408void QgsModelChildAlgorithmGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1410 if ( QgsProcessingModelChildAlgorithm *child =
dynamic_cast<QgsProcessingModelChildAlgorithm *
>( component() ) )
1412 model()->childAlgorithm( child->childId() ).setPosition( pos );
1413 model()->childAlgorithm( child->childId() ).setSize( size );
1417bool QgsModelChildAlgorithmGraphicItem::canDeleteComponent()
1419 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1421 return model()->dependentChildAlgorithms( child->childId() ).empty();
1428 if ( mResults == results )
1432 const QList< QgsModelArrowItem * > arrows = outgoingArrows();
1435 for ( QgsModelArrowItem *arrow : arrows )
1437 arrow->setShowBadge(
false );
1442 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1446 const QVariantMap outputs = results.
outputs();
1447 for (
auto it = outputs.constBegin(); it != outputs.constEnd(); ++it )
1454 const int index = indexForOutput( it.key() );
1457 for ( QgsModelArrowItem *arrow : arrows )
1459 if ( arrow->startIndex() == index && arrow->startEdge() == Qt::BottomEdge )
1461 arrow->setShowBadge(
true );
1462 arrow->badgeItem()->setValue( it.value() );
1474 emit updateArrowPaths();
1477void QgsModelChildAlgorithmGraphicItem::setSourceFeatureCount(
const QString ¶meterName,
long long featureCount )
1479 const int index = indexForInput( parameterName );
1483 const QList< QgsModelArrowItem * > arrows = incomingArrows();
1484 for ( QgsModelArrowItem *arrow : arrows )
1486 if ( arrow->endIndex() == index && arrow->endEdge() == Qt::TopEdge )
1488 arrow->setShowBadge(
true );
1489 arrow->badgeItem()->setValue( featureCount );
1494void QgsModelChildAlgorithmGraphicItem::setSinkFeatureCount(
const QString &outputName,
long long featureCount )
1496 const int index = indexForOutput( outputName );
1500 const QList< QgsModelArrowItem * > arrows = outgoingArrows();
1501 for ( QgsModelArrowItem *arrow : arrows )
1503 if ( arrow->startIndex() == index && arrow->startEdge() == Qt::BottomEdge )
1505 arrow->setShowBadge(
true );
1506 arrow->badgeItem()->setValue( featureCount );
1511void QgsModelChildAlgorithmGraphicItem::setProgress(
double progress )
1513 if ( mProgress == progress )
1516 mProgress = progress;
1520void QgsModelChildAlgorithmGraphicItem::setStarted()
1526void QgsModelChildAlgorithmGraphicItem::setOutdated()
1532int QgsModelChildAlgorithmGraphicItem::indexForInput(
const QString ¶meterName )
const
1534 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1544int QgsModelChildAlgorithmGraphicItem::indexForOutput(
const QString &output )
const
1546 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1556void QgsModelChildAlgorithmGraphicItem::paintBackground( QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget )
1558 if ( mProgress < 0 )
1560 QgsModelComponentGraphicItem::paintBackground( painter, option, widget );
1564 paintOutline( painter, option, widget );
1566 const QRectF rect = itemRect();
1569 if ( component()->color().isValid() )
1571 color = component()->color();
1575 color = color.darker( 110 );
1578 color = color.darker( 105 );
1584 stroke = color.darker( 110 );
1588 color = fillColor( state() );
1589 stroke = strokeColor( state() );
1592 QPen strokePen = QPen( stroke, 0 );
1593 strokePen.setStyle( strokeStyle( state() ) );
1594 painter->setPen( strokePen );
1596 const QColor colorLeft = color.darker( 120 );
1597 QColor colorRight = color;
1599 constexpr double fadeSize = 5;
1600 const double fadeSizeProportionRect = fadeSize / rect.width();
1602 if ( mProgress < 98 )
1604 QLinearGradient gradient( rect.topLeft(), rect.topRight() );
1605 gradient.setColorAt( 0.0, colorLeft );
1606 gradient.setColorAt( std::max( 0.0, mProgress / 100 - fadeSizeProportionRect / 2 ), colorLeft );
1607 gradient.setColorAt( std::min( 1.0, mProgress / 100 + fadeSizeProportionRect / 2 ), colorRight );
1608 gradient.setColorAt( 1.0, colorRight );
1610 painter->setBrush( QBrush( gradient ) );
1614 painter->setBrush( QBrush( colorLeft ) );
1616 painter->drawRect( rect );
1619void QgsModelChildAlgorithmGraphicItem::deleteComponent()
1621 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1623 emit aboutToChange( tr(
"Remove %1" ).arg( child->algorithm() ? child->algorithm()->displayName() : tr(
"Algorithm" ) ) );
1624 if ( !model()->removeChildAlgorithm( child->childId() ) )
1626 QMessageBox::warning(
1628 QObject::tr(
"Could not remove algorithm" ),
1630 "Other algorithms depend on the selected one.\n"
1631 "Remove them before trying to remove it."
1638 emit requestModelRepaint();
1643void QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm()
1645 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1647 model()->deactivateChildAlgorithm( child->childId() );
1648 emit requestModelRepaint();
1652void QgsModelChildAlgorithmGraphicItem::activateAlgorithm()
1654 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( component() ) )
1656 if ( model()->activateChildAlgorithm( child->childId() ) )
1658 emit requestModelRepaint();
1662 QMessageBox::warning(
1664 QObject::tr(
"Could not activate algorithm" ),
1666 "The selected algorithm depends on other currently non-active algorithms.\n"
1667 "Activate them them before trying to activate it.."
1675QgsModelOutputGraphicItem::QgsModelOutputGraphicItem( QgsProcessingModelOutput *output, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1676 : QgsModelComponentGraphicItem( output, model, parent )
1679 QPainter painter( &mPicture );
1680 svg.render( &painter );
1682 setLabel( output->description() );
1685QColor QgsModelOutputGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1687 QColor
c( 172, 196, 114 );
1691 c =
c.darker( 110 );
1694 c =
c.darker( 105 );
1703QColor QgsModelOutputGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1708 return QColor( 42, 65, 42 );
1711 return QColor( 90, 140, 90 );
1716QColor QgsModelOutputGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1721QPicture QgsModelOutputGraphicItem::iconPicture()
const
1726void QgsModelOutputGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1728 if ( QgsProcessingModelOutput *output =
dynamic_cast<QgsProcessingModelOutput *
>( component() ) )
1730 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setPosition( pos );
1731 model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setSize( size );
1735bool QgsModelOutputGraphicItem::canDeleteComponent()
1737 if (
dynamic_cast<const QgsProcessingModelOutput *
>( component() ) )
1744void QgsModelOutputGraphicItem::deleteComponent()
1746 if (
const QgsProcessingModelOutput *output =
dynamic_cast<const QgsProcessingModelOutput *
>( component() ) )
1748 emit aboutToChange( tr(
"Delete Output %1" ).arg( output->description() ) );
1749 model()->childAlgorithm( output->childId() ).removeModelOutput( output->name() );
1750 model()->updateDestinationParameters();
1752 emit requestModelRepaint();
1761QgsModelGroupBoxGraphicItem::QgsModelGroupBoxGraphicItem( QgsProcessingModelGroupBox *box, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1762 : QgsModelComponentGraphicItem( box, model, parent )
1764 setZValue( QgsModelGraphicsScene::ZValues::GroupBox );
1765 setLabel( box->description() );
1769 f.setPixelSize( 14 );
1773void QgsModelGroupBoxGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1775 QMenu *popupmenu =
new QMenu( event->widget() );
1776 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1777 connect( removeAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::deleteComponent );
1778 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1779 connect( editAction, &QAction::triggered,
this, &QgsModelGroupBoxGraphicItem::editComponent );
1780 popupmenu->exec( event->screenPos() );
1783QgsModelGroupBoxGraphicItem::~QgsModelGroupBoxGraphicItem() =
default;
1785QColor QgsModelGroupBoxGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1787 QColor
c( 230, 230, 230 );
1791 c =
c.darker( 110 );
1794 c =
c.darker( 105 );
1803QColor QgsModelGroupBoxGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1808 return QColor( 50, 50, 50 );
1811 return QColor( 150, 150, 150 );
1816QColor QgsModelGroupBoxGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1818 return QColor( 100, 100, 100 );
1821Qt::PenStyle QgsModelGroupBoxGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
1826Qt::Alignment QgsModelGroupBoxGraphicItem::titleAlignment()
const
1828 return Qt::AlignHCenter;
1831void QgsModelGroupBoxGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1833 if ( QgsProcessingModelGroupBox *box =
dynamic_cast<QgsProcessingModelGroupBox *
>( component() ) )
1835 box->setPosition( pos );
1836 box->setSize( size );
1837 model()->addGroupBox( *box );
1841bool QgsModelGroupBoxGraphicItem::canDeleteComponent()
1843 if (
dynamic_cast<QgsProcessingModelGroupBox *
>( component() ) )
1850void QgsModelGroupBoxGraphicItem::applyEdit(
const QgsProcessingModelGroupBox &groupBox )
1852 QgsProcessingModelGroupBox newGroupBox = groupBox;
1853 const QList<QgsProcessingModelGroupBox> existingGroupBoxes = model()->groupBoxes();
1854 for (
const QgsProcessingModelGroupBox &existingGroupBox : existingGroupBoxes )
1856 if ( existingGroupBox.uuid() == newGroupBox.uuid() )
1859 newGroupBox.setPosition( existingGroupBox.position() );
1860 newGroupBox.setSize( existingGroupBox.size() );
1864 const QString commandId = u
"groupbox:%1"_s.arg( newGroupBox.uuid() );
1865 emit aboutToChange( tr(
"Edit Group Box" ), commandId );
1867 model()->addGroupBox( newGroupBox );
1869 emit requestModelRepaint();
1872void QgsModelGroupBoxGraphicItem::deleteComponent()
1874 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast<const QgsProcessingModelGroupBox *
>( component() ) )
1876 emit aboutToChange( tr(
"Delete Group Box" ) );
1877 model()->removeGroupBox( box->uuid() );
1879 emit requestModelRepaint();
1883void QgsModelGroupBoxGraphicItem::editComponent()
1885 if (
const QgsProcessingModelGroupBox *box =
dynamic_cast<const QgsProcessingModelGroupBox *
>( component() ) )
1891 applyEdit( dlg.groupBox() );
1900QgsModelCommentGraphicItem::QgsModelCommentGraphicItem( QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
1901 : QgsModelComponentGraphicItem( comment, model, parent )
1902 , mParentComponent( parentItem->component()->clone() )
1903 , mParentItem( parentItem )
1905 setLabel( comment->description() );
1908 f.setPixelSize( 9 );
1912void QgsModelCommentGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
1914 QMenu *popupmenu =
new QMenu( event->widget() );
1915 QAction *removeAction = popupmenu->addAction( QObject::tr(
"Remove" ) );
1916 connect( removeAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::deleteComponent );
1917 QAction *editAction = popupmenu->addAction( QObject::tr(
"Edit…" ) );
1918 connect( editAction, &QAction::triggered,
this, &QgsModelCommentGraphicItem::editComponent );
1919 popupmenu->exec( event->screenPos() );
1922QgsModelCommentGraphicItem::~QgsModelCommentGraphicItem() =
default;
1924QColor QgsModelCommentGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
const
1926 QColor
c( 230, 230, 230 );
1930 c =
c.darker( 110 );
1933 c =
c.darker( 105 );
1942QColor QgsModelCommentGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
const
1947 return QColor( 50, 50, 50 );
1950 return QColor( 150, 150, 150 );
1955QColor QgsModelCommentGraphicItem::textColor( QgsModelComponentGraphicItem::State )
const
1957 return QColor( 100, 100, 100 );
1960Qt::PenStyle QgsModelCommentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
const
1965void QgsModelCommentGraphicItem::updateStoredComponentPosition(
const QPointF &pos,
const QSizeF &size )
1967 if ( QgsProcessingModelComment *comment = modelComponent() )
1969 comment->setPosition( pos );
1970 comment->setSize( size );
1974bool QgsModelCommentGraphicItem::canDeleteComponent()
1976 if ( modelComponent() )
1983void QgsModelCommentGraphicItem::deleteComponent()
1985 if ( QgsProcessingModelComment *comment = modelComponent() )
1987 emit aboutToChange( tr(
"Delete Comment" ) );
1988 comment->setDescription( QString() );
1990 emit requestModelRepaint();
1994void QgsModelCommentGraphicItem::editComponent()
1998 mParentItem->editComment();
2002QgsProcessingModelComment *QgsModelCommentGraphicItem::modelComponent()
2004 if (
const QgsProcessingModelChildAlgorithm *child =
dynamic_cast<const QgsProcessingModelChildAlgorithm *
>( mParentComponent.get() ) )
2006 return model()->childAlgorithm( child->childId() ).comment();
2008 else if (
const QgsProcessingModelParameter *param =
dynamic_cast<const QgsProcessingModelParameter *
>( mParentComponent.get() ) )
2010 return model()->parameterComponent( param->parameterName() ).comment();
2012 else if (
const QgsProcessingModelOutput *output =
dynamic_cast<const QgsProcessingModelOutput *
>( mParentComponent.get() ) )
2014 return model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).comment();
2019QgsModelComponentGraphicItem *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.
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.
Base class for the definition of processing outputs.
QString description() const
Returns the description for the output.
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.
QString name() const
Returns the name of the parameter.
Contains settings which reflect the context in which a Processing parameter widget is shown.
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.