17 #include "qgsprocessingmodelcomponent.h" 
   18 #include "qgsprocessingmodelparameter.h" 
   19 #include "qgsprocessingmodelchildalgorithm.h" 
   20 #include "qgsprocessingmodeloutput.h" 
   21 #include "qgsprocessingmodelgroupbox.h" 
   25 #include "qgsprocessingmodelalgorithm.h" 
   31 #include <QSvgRenderer> 
   34 #include <QGraphicsSceneHoverEvent> 
   35 #include <QApplication> 
   37 #include <QMessageBox> 
   42 QgsModelComponentGraphicItem::QgsModelComponentGraphicItem( QgsProcessingModelComponent *component, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
   43   : QGraphicsObject( parent )
 
   44   , mComponent( component )
 
   47   setAcceptHoverEvents( 
true );
 
   48   setFlag( QGraphicsItem::ItemIsSelectable, 
true );
 
   49   setFlag( QGraphicsItem::ItemSendsGeometryChanges, 
true );
 
   50   setZValue( QgsModelGraphicsScene::ZValues::ModelComponent );
 
   52   mFont.setPixelSize( 12 );
 
   56   QPainter painter( &editPicture );
 
   57   svg.render( &painter );
 
   59   mEditButton = 
new QgsModelDesignerFlatButtonGraphicItem( 
this, editPicture, QPointF( 0, 0 ) );
 
   60   connect( mEditButton, &QgsModelDesignerFlatButtonGraphicItem::clicked, 
this, &QgsModelComponentGraphicItem::editComponent );
 
   63   QPicture deletePicture;
 
   64   painter.begin( &deletePicture );
 
   65   svg2.render( &painter );
 
   67   mDeleteButton = 
new QgsModelDesignerFlatButtonGraphicItem( 
this, deletePicture, QPointF( 0, 0 ) );
 
   68   connect( mDeleteButton, &QgsModelDesignerFlatButtonGraphicItem::clicked, 
this, &QgsModelComponentGraphicItem::deleteComponent );
 
   70   updateButtonPositions();
 
   73 QgsModelComponentGraphicItem::Flags QgsModelComponentGraphicItem::flags()
 const 
   75   return QgsModelComponentGraphicItem::Flags();
 
   78 QgsModelComponentGraphicItem::~QgsModelComponentGraphicItem() = 
default;
 
   80 QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
 
   82   return mComponent.get();
 
   85 const QgsProcessingModelComponent *QgsModelComponentGraphicItem::component()
 const 
   87   return mComponent.get();
 
   90 QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
 
   95 QgsModelGraphicsView *QgsModelComponentGraphicItem::view()
 
   97   if ( scene()->views().isEmpty() )
 
  100   return qobject_cast< QgsModelGraphicsView * >( scene()->views().first() );
 
  103 QFont QgsModelComponentGraphicItem::font()
 const 
  108 void QgsModelComponentGraphicItem::setFont( 
const QFont &font )
 
  114 void QgsModelComponentGraphicItem::moveComponentBy( qreal dx, qreal dy )
 
  116   setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
 
  117   mComponent->setPosition( pos() );
 
  119   emit aboutToChange( tr( 
"Move %1" ).arg( mComponent->description() ) );
 
  120   updateStoredComponentPosition( pos(), mComponent->size() );
 
  123   emit sizePositionChanged();
 
  124   emit updateArrowPaths();
 
  127 void QgsModelComponentGraphicItem::previewItemMove( qreal dx, qreal dy )
 
  129   setPos( mComponent->position().x() + dx, mComponent->position().y() + dy );
 
  130   emit updateArrowPaths();
 
  133 void QgsModelComponentGraphicItem::setItemRect( QRectF rect )
 
  135   rect = rect.normalized();
 
  137   if ( rect.width() < MIN_COMPONENT_WIDTH )
 
  138     rect.setWidth( MIN_COMPONENT_WIDTH );
 
  139   if ( rect.height() < MIN_COMPONENT_HEIGHT )
 
  140     rect.setHeight( MIN_COMPONENT_HEIGHT );
 
  142   setPos( rect.center() );
 
  143   prepareGeometryChange();
 
  145   emit aboutToChange( tr( 
"Resize %1" ).arg( mComponent->description() ) );
 
  147   mComponent->setPosition( pos() );
 
  148   mComponent->setSize( rect.size() );
 
  149   updateStoredComponentPosition( pos(), mComponent->size() );
 
  151   updateButtonPositions();
 
  154   emit updateArrowPaths();
 
  155   emit sizePositionChanged();
 
  158 QRectF QgsModelComponentGraphicItem::previewItemRectChange( QRectF rect )
 
  160   rect = rect.normalized();
 
  162   if ( rect.width() < MIN_COMPONENT_WIDTH )
 
  163     rect.setWidth( MIN_COMPONENT_WIDTH );
 
  164   if ( rect.height() < MIN_COMPONENT_HEIGHT )
 
  165     rect.setHeight( MIN_COMPONENT_HEIGHT );
 
  167   setPos( rect.center() );
 
  168   prepareGeometryChange();
 
  170   mTempSize = rect.size();
 
  172   updateButtonPositions();
 
  173   emit updateArrowPaths();
 
  178 void QgsModelComponentGraphicItem::finalizePreviewedItemRectChange( QRectF )
 
  180   mComponent->setPosition( pos() );
 
  181   prepareGeometryChange();
 
  182   mComponent->setSize( mTempSize );
 
  183   mTempSize = QSizeF();
 
  185   emit aboutToChange( tr( 
"Resize %1" ).arg( mComponent->description() ) );
 
  186   updateStoredComponentPosition( pos(), mComponent->size() );
 
  188   updateButtonPositions();
 
  192   emit sizePositionChanged();
 
  193   emit updateArrowPaths();
 
  198   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  199     updateToolTip( mapFromScene( event->
modelPoint() ) );
 
  204   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  205     updateToolTip( mapFromScene( event->
modelPoint() ) );
 
  210   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  212     setToolTip( QString() );
 
  217       emit repaintArrows();
 
  224   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  228 void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
 
  230   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  234 void QgsModelComponentGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent *event )
 
  236   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  237     updateToolTip( event->pos() );
 
  240 void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
 
  242   if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
 
  243     updateToolTip( event->pos() );
 
  246 void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
 
  248   modelHoverLeaveEvent( 
nullptr );
 
  251 QVariant QgsModelComponentGraphicItem::itemChange( QGraphicsItem::GraphicsItemChange change, 
const QVariant &value )
 
  255     case QGraphicsItem::ItemSelectedChange:
 
  257       emit repaintArrows();
 
  261     case QGraphicsItem::ItemSceneChange:
 
  266         if ( linkPointCount( Qt::TopEdge ) )
 
  268           mExpandTopButton = 
new QgsModelDesignerFoldButtonGraphicItem( 
this, mComponent->linksCollapsed( Qt::TopEdge ), QPointF( 0, 0 ) );
 
  269           connect( mExpandTopButton, &QgsModelDesignerFoldButtonGraphicItem::folded, 
this, [ = ]( 
bool folded ) { fold( Qt::TopEdge, folded ); } );
 
  271         if ( linkPointCount( Qt::BottomEdge ) )
 
  273           mExpandBottomButton = 
new QgsModelDesignerFoldButtonGraphicItem( 
this, mComponent->linksCollapsed( Qt::BottomEdge ), QPointF( 0, 0 ) );
 
  274           connect( mExpandBottomButton, &QgsModelDesignerFoldButtonGraphicItem::folded, 
this, [ = ]( 
bool folded ) { fold( Qt::BottomEdge, folded ); } );
 
  277         updateButtonPositions();
 
  286   return QGraphicsObject::itemChange( change, value );
 
  289 QRectF QgsModelComponentGraphicItem::boundingRect()
 const 
  291   QFontMetricsF fm( mFont );
 
  292   const int linksAbove = linkPointCount( Qt::TopEdge );
 
  293   const int linksBelow = linkPointCount( Qt::BottomEdge );
 
  295   const double hUp = linksAbove == 0 ? 0 :
 
  296                      fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::TopEdge ) ? 0 : linksAbove ) + 2 );
 
  297   const double hDown = linksBelow == 0 ? 0 :
 
  298                        fm.height() * 1.2 * ( ( mComponent->linksCollapsed( Qt::BottomEdge ) ? 0 : linksBelow ) + 2 );
 
  299   return QRectF( -( itemSize().width() ) / 2 - RECT_PEN_SIZE,
 
  300                  -( itemSize().height() ) / 2 - hUp - RECT_PEN_SIZE,
 
  301                  itemSize().width() + 2 * RECT_PEN_SIZE,
 
  302                  itemSize().height() + hDown + hUp + 2 * RECT_PEN_SIZE );
 
  305 bool QgsModelComponentGraphicItem::contains( 
const QPointF &point )
 const 
  307   QRectF paintingBounds = boundingRect();
 
  308   if ( point.x() < paintingBounds.left() + RECT_PEN_SIZE )
 
  310   if ( point.x() > paintingBounds.right() - RECT_PEN_SIZE )
 
  312   if ( point.y() < paintingBounds.top() + RECT_PEN_SIZE )
 
  314   if ( point.y() > paintingBounds.bottom() - RECT_PEN_SIZE )
 
  320 void QgsModelComponentGraphicItem::paint( QPainter *painter, 
const QStyleOptionGraphicsItem *, QWidget * )
 
  322   const QRectF rect = itemRect();
 
  326   if ( mComponent->color().isValid() )
 
  328     color = mComponent->color();
 
  332         color = color.darker( 110 );
 
  335         color = color.darker( 105 );
 
  341     stroke = color.darker( 110 );
 
  342     foreColor = color.lightness() > 150 ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 );
 
  346     color = fillColor( state() );
 
  347     stroke = strokeColor( state() );
 
  348     foreColor = textColor( state() );
 
  351   QPen strokePen = QPen( stroke, 0 ) ; 
 
  352   strokePen.setStyle( strokeStyle( state() ) );
 
  353   painter->setPen( strokePen );
 
  354   painter->setBrush( QBrush( color, Qt::SolidPattern ) );
 
  355   painter->drawRect( rect );
 
  356   painter->setFont( font() );
 
  357   painter->setPen( QPen( foreColor ) );
 
  361   const QSizeF componentSize = itemSize();
 
  363   QFontMetricsF fm( font() );
 
  364   double h = fm.ascent();
 
  365   QPointF pt( -componentSize.width() / 2 + 25, componentSize.height() / 2.0 - h + 1 );
 
  367   if ( iconPicture().isNull() && iconPixmap().isNull() )
 
  369     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 );
 
  371     painter->drawText( labelRect, Qt::TextWordWrap | titleAlignment(), text );
 
  375     QRectF labelRect = QRectF( rect.left() + 21 + TEXT_MARGIN, rect.top() + TEXT_MARGIN,
 
  376                                rect.width() - 2 * TEXT_MARGIN - mButtonSize.width() - BUTTON_MARGIN - 21, rect.height() - 2 * TEXT_MARGIN );
 
  378     painter->drawText( labelRect, Qt::TextWordWrap | Qt::AlignVCenter, text );
 
  381   painter->setPen( QPen( QApplication::palette().color( QPalette::WindowText ) ) );
 
  383   if ( linkPointCount( Qt::TopEdge ) || linkPointCount( Qt::BottomEdge ) )
 
  385     h = -( fm.height() * 1.2 );
 
  386     h = h - componentSize.height() / 2.0 + 5;
 
  387     pt = QPointF( -componentSize.width() / 2 + 25, h );
 
  388     painter->drawText( pt, QObject::tr( 
"In" ) );
 
  390     if ( !mComponent->linksCollapsed( Qt::TopEdge ) )
 
  392       for ( 
int idx = 0; idx < linkPointCount( Qt::TopEdge ); ++idx )
 
  394         text = linkPointText( Qt::TopEdge, idx );
 
  395         h = -( fm.height() * 1.2 ) * ( i + 1 );
 
  396         h = h - componentSize.height() / 2.0 + 5;
 
  397         pt = QPointF( -componentSize.width() / 2 + 33, h );
 
  398         painter->drawText( pt, text );
 
  403     h = fm.height() * 1.1;
 
  404     h = h + componentSize.height() / 2.0;
 
  405     pt = QPointF( -componentSize.width() / 2 + 25, h );
 
  406     painter->drawText( pt, QObject::tr( 
"Out" ) );
 
  407     if ( !mComponent->linksCollapsed( Qt::BottomEdge ) )
 
  409       for ( 
int idx = 0; idx < linkPointCount( Qt::BottomEdge ); ++idx )
 
  411         text = linkPointText( Qt::BottomEdge, idx );
 
  412         h = fm.height() * 1.2 * ( idx + 2 );
 
  413         h = h + componentSize.height() / 2.0;
 
  414         pt = QPointF( -componentSize.width() / 2 + 33, h );
 
  415         painter->drawText( pt, text );
 
  420   const QPixmap px = iconPixmap();
 
  423     painter->drawPixmap( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), px );
 
  427     const QPicture pic = iconPicture();
 
  430       painter->drawPicture( QPointF( -( componentSize.width() / 2.0 ) + 3, -8 ), pic );
 
  435 QRectF QgsModelComponentGraphicItem::itemRect( 
bool storedRect )
 const 
  439     return QRectF( mComponent->position().x() - ( mComponent->size().width() ) / 2.0,
 
  440                    mComponent->position().y()  - ( mComponent->size().height() ) / 2.0,
 
  441                    mComponent->size().width(),
 
  442                    mComponent->size().height() );
 
  445     return QRectF( -( itemSize().width() ) / 2.0,
 
  446                    -( itemSize().height() ) / 2.0,
 
  448                    itemSize().height() );
 
  451 QString QgsModelComponentGraphicItem::truncatedTextForItem( 
const QString &text )
 const 
  453   QFontMetricsF fm( mFont );
 
  454   double width = fm.boundingRect( text ).width();
 
  455   if ( width < itemSize().width() - 25 - mButtonSize.width() )
 
  459   t = t.left( t.length() - 3 ) + QChar( 0x2026 );
 
  460   width = fm.boundingRect( t ).width();
 
  461   while ( width > itemSize().width() - 25 - mButtonSize.width() )
 
  463     if ( t.length() < 5 )
 
  466     t = t.left( t.length() - 4 ) + QChar( 0x2026 );
 
  467     width = fm.boundingRect( t ).width();
 
  472 Qt::PenStyle QgsModelComponentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
 const 
  474   return Qt::SolidLine;
 
  477 Qt::Alignment QgsModelComponentGraphicItem::titleAlignment()
 const 
  479   return Qt::AlignLeft;
 
  482 QPicture QgsModelComponentGraphicItem::iconPicture()
 const 
  487 QPixmap QgsModelComponentGraphicItem::iconPixmap()
 const 
  492 void QgsModelComponentGraphicItem::updateButtonPositions()
 
  494   mEditButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN,
 
  495                                      itemSize().height() / 2.0 - mButtonSize.height() / 2.0 - BUTTON_MARGIN ) );
 
  496   mDeleteButton->setPosition( QPointF( itemSize().width() / 2.0 - mButtonSize.width() / 2.0 - BUTTON_MARGIN,
 
  497                                        mButtonSize.height() / 2.0 - itemSize().height() / 2.0 + BUTTON_MARGIN ) );
 
  499   if ( mExpandTopButton )
 
  501     QPointF pt = linkPoint( Qt::TopEdge, -1, 
true );
 
  502     mExpandTopButton->setPosition( QPointF( 0, pt.y() ) );
 
  504   if ( mExpandBottomButton )
 
  506     QPointF pt = linkPoint( Qt::BottomEdge, -1, 
false );
 
  507     mExpandBottomButton->setPosition( QPointF( 0, pt.y() ) );
 
  511 QSizeF QgsModelComponentGraphicItem::itemSize()
 const 
  513   return !mTempSize.isValid() ? mComponent->size() : mTempSize;
 
  516 void QgsModelComponentGraphicItem::updateToolTip( 
const QPointF &pos )
 
  518   const bool prevHoverStatus = mIsHovering;
 
  519   if ( itemRect().contains( pos ) )
 
  521     setToolTip( mLabel );
 
  526     setToolTip( QString() );
 
  529   if ( mIsHovering != prevHoverStatus )
 
  532     emit repaintArrows();
 
  536 void QgsModelComponentGraphicItem::fold( Qt::Edge edge, 
bool folded )
 
  538   emit aboutToChange( !folded ? tr( 
"Expand Item" ) : tr( 
"Collapse Item" ) );
 
  539   mComponent->setLinksCollapsed( edge, folded );
 
  543   if ( QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< QgsProcessingModelChildAlgorithm * 
>( mComponent.get() ) )
 
  544     mModel->childAlgorithm( child->childId() ).setLinksCollapsed( edge, folded );
 
  545   else if ( QgsProcessingModelParameter *param = 
dynamic_cast< QgsProcessingModelParameter * 
>( mComponent.get() ) )
 
  546     mModel->parameterComponent( param->parameterName() ).setLinksCollapsed( edge, folded );
 
  547   else if ( QgsProcessingModelOutput *output = 
dynamic_cast< QgsProcessingModelOutput * 
>( mComponent.get() ) )
 
  548     mModel->childAlgorithm( output->childId() ).modelOutput( output->name() ).setLinksCollapsed( edge, folded );
 
  550   prepareGeometryChange();
 
  551   emit updateArrowPaths();
 
  556 QString QgsModelComponentGraphicItem::label()
 const 
  561 void QgsModelComponentGraphicItem::setLabel( 
const QString &label )
 
  567 QgsModelComponentGraphicItem::State QgsModelComponentGraphicItem::state()
 const 
  571   else if ( mIsHovering )
 
  577 int QgsModelComponentGraphicItem::linkPointCount( Qt::Edge )
 const 
  582 QString QgsModelComponentGraphicItem::linkPointText( Qt::Edge, 
int )
 const 
  587 QPointF QgsModelComponentGraphicItem::linkPoint( Qt::Edge edge, 
int index, 
bool incoming )
 const 
  593       if ( linkPointCount( Qt::BottomEdge ) )
 
  596         if ( mComponent->linksCollapsed( Qt::BottomEdge ) )
 
  600         const int pointIndex = !mComponent->linksCollapsed( Qt::BottomEdge ) ? index : -1;
 
  601         const QString text = truncatedTextForItem( linkPointText( Qt::BottomEdge, index ) );
 
  602         QFontMetricsF fm( mFont );
 
  603         const double w = fm.boundingRect( text ).width();
 
  604         const double h = fm.height() * 1.2 * ( pointIndex + 1 ) + fm.height() / 2.0;
 
  605         const double y = h + itemSize().height() / 2.0 + 5;
 
  606         const double x = !mComponent->linksCollapsed( Qt::BottomEdge ) ? ( -itemSize().width() / 2 + 33 + w + 5 ) : 10;
 
  607         return QPointF( incoming ? -itemSize().width() / 2 + offsetX
 
  616       if ( linkPointCount( Qt::TopEdge ) )
 
  619         int paramIndex = index;
 
  620         if ( mComponent->linksCollapsed( Qt::TopEdge ) )
 
  625         QFontMetricsF fm( mFont );
 
  626         const QString text = truncatedTextForItem( linkPointText( Qt::TopEdge, index ) );
 
  627         const double w = fm.boundingRect( text ).width();
 
  628         double h = -( fm.height() * 1.2 ) * ( paramIndex + 2 ) - fm.height() / 2.0 + 8;
 
  629         h = h - itemSize().height() / 2.0;
 
  630         return QPointF( incoming ? -itemSize().width() / 2 + offsetX
 
  631                         : ( !mComponent->linksCollapsed( Qt::TopEdge ) ? ( -itemSize().width() / 2 + 33 + w + 5 ) : 10 ),
 
  644 QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint( QgsModelComponentGraphicItem *other, Qt::Edge &edge )
 const 
  647   const QgsRectangle otherRect( other->itemRect().translated( other->pos() ) );
 
  649   const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
 
  650   const double distLeft = otherRect.distance( 
QgsPointXY( leftPoint ) );
 
  652   const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
 
  653   const double distRight = otherRect.distance( 
QgsPointXY( rightPoint ) );
 
  655   const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
 
  656   const double distTop = otherRect.distance( 
QgsPointXY( topPoint ) );
 
  658   const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
 
  659   const double distBottom = otherRect.distance( 
QgsPointXY( bottomPoint ) );
 
  661   if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
 
  666   else if ( distRight <= distTop && distRight <= distBottom )
 
  668     edge = Qt::RightEdge;
 
  671   else if ( distBottom <= distTop )
 
  673     edge = Qt::BottomEdge;
 
  683 QPointF QgsModelComponentGraphicItem::calculateAutomaticLinkPoint( 
const QPointF &point, Qt::Edge &edge )
 const 
  687   const QPointF leftPoint = pos() + QPointF( -itemSize().width() / 2.0, 0 );
 
  688   const double distLeft = otherPt.distance( 
QgsPointXY( leftPoint ) );
 
  690   const QPointF rightPoint = pos() + QPointF( itemSize().width() / 2.0, 0 );
 
  691   const double distRight = otherPt.distance( 
QgsPointXY( rightPoint ) );
 
  693   const QPointF topPoint = pos() + QPointF( 0, -itemSize().height() / 2.0 );
 
  694   const double distTop = otherPt.distance( 
QgsPointXY( topPoint ) );
 
  696   const QPointF bottomPoint = pos() + QPointF( 0, itemSize().height() / 2.0 );
 
  697   const double distBottom = otherPt.distance( 
QgsPointXY( bottomPoint ) );
 
  699   if ( distLeft <= distRight && distLeft <= distTop && distLeft <= distBottom )
 
  704   else if ( distRight <= distTop && distRight <= distBottom )
 
  706     edge = Qt::RightEdge;
 
  709   else if ( distBottom <= distTop )
 
  711     edge = Qt::BottomEdge;
 
  721 QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
  722   : QgsModelComponentGraphicItem( parameter, model, parent )
 
  725   QPainter painter( &mPicture );
 
  726   svg.render( &painter );
 
  730     setLabel( paramDef->description() );
 
  732     setLabel( QObject::tr( 
"Error (%1)" ).arg( parameter->parameterName() ) );
 
  735 void QgsModelParameterGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
 
  737   QMenu *popupmenu = 
new QMenu( event->widget() );
 
  738   QAction *removeAction = popupmenu->addAction( QObject::tr( 
"Remove" ) );
 
  739   connect( removeAction, &QAction::triggered, 
this, &QgsModelParameterGraphicItem::deleteComponent );
 
  740   QAction *editAction = popupmenu->addAction( QObject::tr( 
"Edit…" ) );
 
  741   connect( editAction, &QAction::triggered, 
this, &QgsModelParameterGraphicItem::editComponent );
 
  742   QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr( 
"Add Comment…" ) : QObject::tr( 
"Edit Comment…" ) );
 
  743   connect( editCommentAction, &QAction::triggered, 
this, &QgsModelParameterGraphicItem::editComment );
 
  745   popupmenu->exec( event->screenPos() );
 
  748 QColor QgsModelParameterGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
 const 
  750   QColor 
c( 238, 242, 131 );
 
  766 QColor QgsModelParameterGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
 const 
  771       return QColor( 116, 113, 68 );
 
  774       return QColor( 234, 226, 118 );
 
  779 QColor QgsModelParameterGraphicItem::textColor( QgsModelComponentGraphicItem::State )
 const 
  784 QPicture QgsModelParameterGraphicItem::iconPicture()
 const 
  789 void QgsModelParameterGraphicItem::updateStoredComponentPosition( 
const QPointF &pos, 
const QSizeF &size )
 
  791   if ( QgsProcessingModelParameter *param = 
dynamic_cast< QgsProcessingModelParameter * 
>( component() ) )
 
  793     model()->parameterComponent( param->parameterName() ).setPosition( pos );
 
  794     model()->parameterComponent( param->parameterName() ).setSize( size );
 
  798 bool QgsModelParameterGraphicItem::canDeleteComponent()
 
  800   if ( 
const QgsProcessingModelParameter *param = 
dynamic_cast< const QgsProcessingModelParameter * 
>( component() ) )
 
  802     if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
 
  806     else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
 
  818 void QgsModelParameterGraphicItem::deleteComponent()
 
  820   if ( 
const QgsProcessingModelParameter *param = 
dynamic_cast< const QgsProcessingModelParameter * 
>( component() ) )
 
  822     if ( model()->childAlgorithmsDependOnParameter( param->parameterName() ) )
 
  824       QMessageBox::warning( 
nullptr, QObject::tr( 
"Could not remove input" ),
 
  825                             QObject::tr( 
"Algorithms depend on the selected input.\n" 
  826                                          "Remove them before trying to remove it." ) );
 
  828     else if ( model()->otherParametersDependOnParameter( param->parameterName() ) )
 
  830       QMessageBox::warning( 
nullptr, QObject::tr( 
"Could not remove input" ),
 
  831                             QObject::tr( 
"Other inputs depend on the selected input.\n" 
  832                                          "Remove them before trying to remove it." ) );
 
  836       emit aboutToChange( tr( 
"Delete Input %1" ).arg( param->description() ) );
 
  837       model()->removeModelParameter( param->parameterName() );
 
  839       emit requestModelRepaint();
 
  846 QgsModelChildAlgorithmGraphicItem::QgsModelChildAlgorithmGraphicItem( QgsProcessingModelChildAlgorithm *child, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
  847   : QgsModelComponentGraphicItem( child, model, parent )
 
  849   if ( child->algorithm() && !child->algorithm()->svgIconPath().isEmpty() )
 
  851     QSvgRenderer svg( child->algorithm()->svgIconPath() );
 
  852     const QSizeF size = svg.defaultSize();
 
  853     QPainter painter( &mPicture );
 
  854     painter.scale( 16.0 / size.width(), 16.0 / size.width() );
 
  855     svg.render( &painter );
 
  858   else if ( child->algorithm() )
 
  860     mPixmap = child->algorithm()->icon().pixmap( 15, 15 );
 
  863   setLabel( child->description() );
 
  866   mIsValid = model->validateChildAlgorithm( child->childId(), issues );
 
  869 void QgsModelChildAlgorithmGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
 
  871   QMenu *popupmenu = 
new QMenu( event->widget() );
 
  872   QAction *removeAction = popupmenu->addAction( QObject::tr( 
"Remove" ) );
 
  873   connect( removeAction, &QAction::triggered, 
this, &QgsModelChildAlgorithmGraphicItem::deleteComponent );
 
  874   QAction *editAction = popupmenu->addAction( QObject::tr( 
"Edit…" ) );
 
  875   connect( editAction, &QAction::triggered, 
this, &QgsModelChildAlgorithmGraphicItem::editComponent );
 
  876   QAction *editCommentAction = popupmenu->addAction( component()->comment()->description().isEmpty() ? QObject::tr( 
"Add Comment…" ) : QObject::tr( 
"Edit Comment…" ) );
 
  877   connect( editCommentAction, &QAction::triggered, 
this, &QgsModelParameterGraphicItem::editComment );
 
  878   popupmenu->addSeparator();
 
  880   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
  882     if ( !child->isActive() )
 
  884       QAction *activateAction = popupmenu->addAction( QObject::tr( 
"Activate" ) );
 
  885       connect( activateAction, &QAction::triggered, 
this, &QgsModelChildAlgorithmGraphicItem::activateAlgorithm );
 
  889       QAction *deactivateAction = popupmenu->addAction( QObject::tr( 
"Deactivate" ) );
 
  890       connect( deactivateAction, &QAction::triggered, 
this, &QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm );
 
  894   popupmenu->exec( event->screenPos() );
 
  897 QColor QgsModelChildAlgorithmGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
 const 
  902     c = QColor( 255, 255, 255 );
 
  904     c = QColor( 208, 0, 0 );
 
  921 QColor QgsModelChildAlgorithmGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
 const 
  926       return mIsValid ? QColor( 50, 50, 50 ) : QColor( 80, 0, 0 );
 
  929       return mIsValid ? Qt::gray : QColor( 134, 0, 0 );
 
  934 QColor QgsModelChildAlgorithmGraphicItem::textColor( QgsModelComponentGraphicItem::State )
 const 
  936   return mIsValid ? ( qgis::down_cast< const QgsProcessingModelChildAlgorithm * >( component() )->isActive() ? Qt::black : Qt::gray ) : QColor( 255, 255, 255 );
 
  939 QPixmap QgsModelChildAlgorithmGraphicItem::iconPixmap()
 const 
  944 QPicture QgsModelChildAlgorithmGraphicItem::iconPicture()
 const 
  949 int QgsModelChildAlgorithmGraphicItem::linkPointCount( Qt::Edge edge )
 const 
  951   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
  953     if ( !child->algorithm() )
 
  959         return child->algorithm()->outputDefinitions().size();
 
  965           return param->flags() & QgsProcessingParameterDefinition::FlagHidden || param->isDestination();
 
  967         return params.size();
 
  978 QString QgsModelChildAlgorithmGraphicItem::linkPointText( Qt::Edge edge, 
int index )
 const 
  983   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
  985     if ( !child->algorithm() )
 
  992         if ( index >= child->algorithm()->outputDefinitions().length() )
 
  996             tr( 
"Cannot link output for child: %1" ).arg( child->algorithm()->name() ),
 
  997             "QgsModelChildAlgorithmGraphicItem", Qgis::MessageLevel::Warning, 
true );
 
 1003         if ( mResults.contains( output->
name() ) )
 
 1005           title += QStringLiteral( 
": %1" ).arg( mResults.value( output->
name() ).toString() );
 
 1007         return truncatedTextForItem( title );
 
 1015           return param->flags() & QgsProcessingParameterDefinition::FlagHidden || param->isDestination();
 
 1016         } ), params.end() );
 
 1018         if ( index >= params.length() )
 
 1022             tr( 
"Cannot link source for child: %1" ).arg( child->algorithm()->name() ),
 
 1023             "QgsModelChildAlgorithmGraphicItem", Qgis::MessageLevel::Warning, 
true );
 
 1027         QString title = params.at( index )->description();
 
 1028         if ( !mInputs.value( params.at( index )->name() ).toString().isEmpty() )
 
 1029           title +=  QStringLiteral( 
": %1" ).arg( mInputs.value( params.at( index )->name() ).toString() );
 
 1030         return truncatedTextForItem( title );
 
 1041 void QgsModelChildAlgorithmGraphicItem::updateStoredComponentPosition( 
const QPointF &pos, 
const QSizeF &size )
 
 1043   if ( QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
 1045     model()->childAlgorithm( child->childId() ).setPosition( pos );
 
 1046     model()->childAlgorithm( child->childId() ).setSize( size );
 
 1050 bool QgsModelChildAlgorithmGraphicItem::canDeleteComponent()
 
 1052   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
 1054     return model()->dependentChildAlgorithms( child->childId() ).empty();
 
 1059 void QgsModelChildAlgorithmGraphicItem::setResults( 
const QVariantMap &results )
 
 1061   if ( mResults == results )
 
 1066   emit updateArrowPaths();
 
 1069 void QgsModelChildAlgorithmGraphicItem::setInputs( 
const QVariantMap &inputs )
 
 1071   if ( mInputs == inputs )
 
 1076   emit updateArrowPaths();
 
 1079 void QgsModelChildAlgorithmGraphicItem::deleteComponent()
 
 1081   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
 1083     emit aboutToChange( tr( 
"Remove %1" ).arg( child->algorithm() ? child->algorithm()->displayName() : tr( 
"Algorithm" ) ) );
 
 1084     if ( !model()->removeChildAlgorithm( child->childId() ) )
 
 1086       QMessageBox::warning( 
nullptr, QObject::tr( 
"Could not remove algorithm" ),
 
 1087                             QObject::tr( 
"Other algorithms depend on the selected one.\n" 
 1088                                          "Remove them before trying to remove it." ) );
 
 1093       emit requestModelRepaint();
 
 1098 void QgsModelChildAlgorithmGraphicItem::deactivateAlgorithm()
 
 1100   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
 1102     model()->deactivateChildAlgorithm( child->childId() );
 
 1103     emit requestModelRepaint();
 
 1107 void QgsModelChildAlgorithmGraphicItem::activateAlgorithm()
 
 1109   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( component() ) )
 
 1111     if ( model()->activateChildAlgorithm( child->childId() ) )
 
 1113       emit requestModelRepaint();
 
 1117       QMessageBox::warning( 
nullptr, QObject::tr( 
"Could not activate algorithm" ),
 
 1118                             QObject::tr( 
"The selected algorithm depends on other currently non-active algorithms.\n" 
 1119                                          "Activate them them before trying to activate it.." ) );
 
 1125 QgsModelOutputGraphicItem::QgsModelOutputGraphicItem( QgsProcessingModelOutput *output, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
 1126   : QgsModelComponentGraphicItem( output, model, parent )
 
 1129   QPainter painter( &mPicture );
 
 1130   svg.render( &painter );
 
 1132   setLabel( output->name() );
 
 1135 QColor QgsModelOutputGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
 const 
 1137   QColor 
c( 172, 196, 114 );
 
 1141       c = 
c.darker( 110 );
 
 1144       c = 
c.darker( 105 );
 
 1153 QColor QgsModelOutputGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
 const 
 1158       return QColor( 42, 65, 42 );
 
 1161       return QColor( 90, 140, 90 );
 
 1166 QColor QgsModelOutputGraphicItem::textColor( QgsModelComponentGraphicItem::State )
 const 
 1171 QPicture QgsModelOutputGraphicItem::iconPicture()
 const 
 1176 void QgsModelOutputGraphicItem::updateStoredComponentPosition( 
const QPointF &pos, 
const QSizeF &size )
 
 1178   if ( QgsProcessingModelOutput *output = 
dynamic_cast< QgsProcessingModelOutput * 
>( component() ) )
 
 1180     model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setPosition( pos );
 
 1181     model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).setSize( size );
 
 1185 bool QgsModelOutputGraphicItem::canDeleteComponent()
 
 1187   if ( 
dynamic_cast< const QgsProcessingModelOutput * 
>( component() ) )
 
 1194 void QgsModelOutputGraphicItem::deleteComponent()
 
 1196   if ( 
const QgsProcessingModelOutput *output = 
dynamic_cast< const QgsProcessingModelOutput * 
>( component() ) )
 
 1198     emit aboutToChange( tr( 
"Delete Output %1" ).arg( output->description() ) );
 
 1199     model()->childAlgorithm( output->childId() ).removeModelOutput( output->name() );
 
 1200     model()->updateDestinationParameters();
 
 1202     emit requestModelRepaint();
 
 1211 QgsModelGroupBoxGraphicItem::QgsModelGroupBoxGraphicItem( QgsProcessingModelGroupBox *box, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
 1212   : QgsModelComponentGraphicItem( box, model, parent )
 
 1214   setZValue( QgsModelGraphicsScene::ZValues::GroupBox );
 
 1215   setLabel( box->description() );
 
 1219   f.setPixelSize( 14 );
 
 1223 void QgsModelGroupBoxGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
 
 1225   QMenu *popupmenu = 
new QMenu( event->widget() );
 
 1226   QAction *removeAction = popupmenu->addAction( QObject::tr( 
"Remove" ) );
 
 1227   connect( removeAction, &QAction::triggered, 
this, &QgsModelGroupBoxGraphicItem::deleteComponent );
 
 1228   QAction *editAction = popupmenu->addAction( QObject::tr( 
"Edit…" ) );
 
 1229   connect( editAction, &QAction::triggered, 
this, &QgsModelGroupBoxGraphicItem::editComponent );
 
 1230   popupmenu->exec( event->screenPos() );
 
 1233 QgsModelGroupBoxGraphicItem::~QgsModelGroupBoxGraphicItem() = 
default;
 
 1235 QColor QgsModelGroupBoxGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
 const 
 1237   QColor 
c( 230, 230, 230 );
 
 1241       c = 
c.darker( 110 );
 
 1244       c = 
c.darker( 105 );
 
 1253 QColor QgsModelGroupBoxGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
 const 
 1258       return QColor( 50, 50, 50 );
 
 1261       return QColor( 150, 150, 150 );
 
 1266 QColor QgsModelGroupBoxGraphicItem::textColor( QgsModelComponentGraphicItem::State )
 const 
 1268   return QColor( 100, 100, 100 );
 
 1271 Qt::PenStyle QgsModelGroupBoxGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
 const 
 1276 Qt::Alignment QgsModelGroupBoxGraphicItem::titleAlignment()
 const 
 1278   return Qt::AlignHCenter;
 
 1281 void QgsModelGroupBoxGraphicItem::updateStoredComponentPosition( 
const QPointF &pos, 
const QSizeF &size )
 
 1283   if ( QgsProcessingModelGroupBox *box = 
dynamic_cast< QgsProcessingModelGroupBox * 
>( component() ) )
 
 1285     box->setPosition( pos );
 
 1286     box->setSize( size );
 
 1287     model()->addGroupBox( *box );
 
 1291 bool QgsModelGroupBoxGraphicItem::canDeleteComponent()
 
 1293   if ( 
dynamic_cast< QgsProcessingModelGroupBox * 
>( component() ) )
 
 1300 void QgsModelGroupBoxGraphicItem::deleteComponent()
 
 1302   if ( 
const QgsProcessingModelGroupBox *box = 
dynamic_cast< const QgsProcessingModelGroupBox * 
>( component() ) )
 
 1304     emit aboutToChange( tr( 
"Delete Group Box" ) );
 
 1305     model()->removeGroupBox( box->uuid() );
 
 1307     emit requestModelRepaint();
 
 1311 void QgsModelGroupBoxGraphicItem::editComponent()
 
 1313   if ( 
const QgsProcessingModelGroupBox *box = 
dynamic_cast< const QgsProcessingModelGroupBox * 
>( component() ) )
 
 1319       emit aboutToChange( tr( 
"Edit Group Box" ) );
 
 1320       model()->addGroupBox( dlg.groupBox() );
 
 1322       emit requestModelRepaint();
 
 1331 QgsModelCommentGraphicItem::QgsModelCommentGraphicItem( QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
 
 1332   : QgsModelComponentGraphicItem( comment, model, parent )
 
 1333   , mParentComponent( parentItem->component()->clone() )
 
 1334   , mParentItem( parentItem )
 
 1336   setLabel( comment->description() );
 
 1339   f.setPixelSize( 9 );
 
 1343 void QgsModelCommentGraphicItem::contextMenuEvent( QGraphicsSceneContextMenuEvent *event )
 
 1345   QMenu *popupmenu = 
new QMenu( event->widget() );
 
 1346   QAction *removeAction = popupmenu->addAction( QObject::tr( 
"Remove" ) );
 
 1347   connect( removeAction, &QAction::triggered, 
this, &QgsModelCommentGraphicItem::deleteComponent );
 
 1348   QAction *editAction = popupmenu->addAction( QObject::tr( 
"Edit…" ) );
 
 1349   connect( editAction, &QAction::triggered, 
this, &QgsModelCommentGraphicItem::editComponent );
 
 1350   popupmenu->exec( event->screenPos() );
 
 1353 QgsModelCommentGraphicItem::~QgsModelCommentGraphicItem() = 
default;
 
 1355 QColor QgsModelCommentGraphicItem::fillColor( QgsModelComponentGraphicItem::State state )
 const 
 1357   QColor 
c( 230, 230, 230 );
 
 1361       c = 
c.darker( 110 );
 
 1364       c = 
c.darker( 105 );
 
 1373 QColor QgsModelCommentGraphicItem::strokeColor( QgsModelComponentGraphicItem::State state )
 const 
 1378       return QColor( 50, 50, 50 );
 
 1381       return QColor( 150, 150, 150 );
 
 1386 QColor QgsModelCommentGraphicItem::textColor( QgsModelComponentGraphicItem::State )
 const 
 1388   return QColor( 100, 100, 100 );
 
 1391 Qt::PenStyle QgsModelCommentGraphicItem::strokeStyle( QgsModelComponentGraphicItem::State )
 const 
 1396 void QgsModelCommentGraphicItem::updateStoredComponentPosition( 
const QPointF &pos, 
const QSizeF &size )
 
 1398   if ( QgsProcessingModelComment *comment = modelComponent() )
 
 1400     comment->setPosition( pos );
 
 1401     comment->setSize( size );
 
 1405 bool QgsModelCommentGraphicItem::canDeleteComponent()
 
 1407   if ( modelComponent() )
 
 1414 void QgsModelCommentGraphicItem::deleteComponent()
 
 1416   if ( QgsProcessingModelComment *comment = modelComponent() )
 
 1418     emit aboutToChange( tr( 
"Delete Comment" ) );
 
 1419     comment->setDescription( QString() );
 
 1421     emit requestModelRepaint();
 
 1425 void QgsModelCommentGraphicItem::editComponent()
 
 1429     mParentItem->editComment();
 
 1433 QgsProcessingModelComment *QgsModelCommentGraphicItem::modelComponent()
 
 1435   if ( 
const QgsProcessingModelChildAlgorithm *child = 
dynamic_cast< const QgsProcessingModelChildAlgorithm * 
>( mParentComponent.get() ) )
 
 1437     return model()->childAlgorithm( child->childId() ).comment();
 
 1439   else if ( 
const QgsProcessingModelParameter *param = 
dynamic_cast< const QgsProcessingModelParameter * 
>( mParentComponent.get() ) )
 
 1441     return model()->parameterComponent( param->parameterName() ).comment();
 
 1443   else if ( 
const QgsProcessingModelOutput *output = 
dynamic_cast< const QgsProcessingModelOutput * 
>( mParentComponent.get() ) )
 
 1445     return model()->childAlgorithm( output->childId() ).modelOutput( output->name() ).comment();
 
 1450 QgsModelComponentGraphicItem *QgsModelCommentGraphicItem::parentComponentItem()
 const 
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A widget which allow users to specify the properties of a model group box.
A QgsModelViewMouseEvent is the result of a user interaction with the mouse on a QgsModelGraphicsView...
QPointF modelPoint() const
Returns the event point location in model coordinates.
A class to represent a 2D point.
Base class for the definition of processing outputs.
QString name() const
Returns the name of the output.
QString description() const
Returns the description for the output.
Base class for the definition of processing parameters.
A rectangle specified with double values.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.