Compare commits

...

2 Commits

13 changed files with 138 additions and 64 deletions

View File

@ -5,7 +5,7 @@ QgsModelGraphicsView.PasteModeCursor = QgsModelGraphicsView.PasteMode.PasteModeC
QgsModelGraphicsView.PasteModeCenter = QgsModelGraphicsView.PasteMode.PasteModeCenter QgsModelGraphicsView.PasteModeCenter = QgsModelGraphicsView.PasteMode.PasteModeCenter
QgsModelGraphicsView.PasteModeInPlace = QgsModelGraphicsView.PasteMode.PasteModeInPlace QgsModelGraphicsView.PasteModeInPlace = QgsModelGraphicsView.PasteMode.PasteModeInPlace
try: try:
QgsModelGraphicsView.__attribute_docs__ = {'algorithmDropped': 'Emitted when an algorithm is dropped onto the view.\n', 'inputDropped': 'Emitted when an input parameter is dropped onto the view.\n', 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the\nactive item and should have its properties displayed in any designer\nwindows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted, but is\nstill in a perfectly valid state.\n', 'macroCommandStarted': 'Emitted when a macro command containing a group of interactions is\nstarted in the view.\n', 'macroCommandEnded': 'Emitted when a macro command containing a group of interactions in the\nview has ended.\n', 'commandBegun': 'Emitted when an undo command is started in the view.\n', 'commandEnded': 'Emitted when an undo command in the view has ended.\n', 'deleteSelectedItems': 'Emitted when the selected items should be deleted;\n'} QgsModelGraphicsView.__attribute_docs__ = {'algorithmDropped': 'Emitted when an algorithm is dropped onto the view.\n', 'inputDropped': 'Emitted when an input parameter is dropped onto the view.\n', 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the\nactive item and should have its properties displayed in any designer\nwindows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted, but is\nstill in a perfectly valid state.\n', 'macroCommandStarted': 'Emitted when a macro command containing a group of interactions is\nstarted in the view.\n', 'macroCommandEnded': 'Emitted when a macro command containing a group of interactions in the\nview has ended.\n', 'commandBegun': 'Emitted when an undo command is started in the view.\n', 'commandEnded': 'Emitted when an undo command in the view has ended.\n', 'commandAborted': 'Emitted when an undo command in the view was aborted.\n', 'deleteSelectedItems': 'Emitted when the selected items should be deleted;\n'}
QgsModelGraphicsView.__overridden_methods__ = ['dragEnterEvent', 'dropEvent', 'dragMoveEvent', 'wheelEvent', 'mousePressEvent', 'mouseReleaseEvent', 'mouseMoveEvent', 'mouseDoubleClickEvent', 'keyPressEvent', 'keyReleaseEvent'] QgsModelGraphicsView.__overridden_methods__ = ['dragEnterEvent', 'dropEvent', 'dragMoveEvent', 'wheelEvent', 'mousePressEvent', 'mouseReleaseEvent', 'mouseMoveEvent', 'mouseDoubleClickEvent', 'keyPressEvent', 'keyReleaseEvent']
QgsModelGraphicsView.__signal_arguments__ = {'algorithmDropped': ['algorithmId: str', 'pos: QPointF'], 'inputDropped': ['inputId: str', 'pos: QPointF'], 'itemFocused': ['item: QgsModelComponentGraphicItem'], 'macroCommandStarted': ['text: str'], 'commandBegun': ['text: str']} QgsModelGraphicsView.__signal_arguments__ = {'algorithmDropped': ['algorithmId: str', 'pos: QPointF'], 'inputDropped': ['inputId: str', 'pos: QPointF'], 'itemFocused': ['item: QgsModelComponentGraphicItem'], 'macroCommandStarted': ['text: str'], 'commandBegun': ['text: str']}
QgsModelGraphicsView.__group__ = ['processing', 'models'] QgsModelGraphicsView.__group__ = ['processing', 'models']

View File

@ -44,6 +44,12 @@ made to the model.
%Docstring %Docstring
Ends the current undo command. This should be called after changes are Ends the current undo command. This should be called after changes are
made to the model. made to the model.
%End
void abortUndoCommand();
%Docstring
Aborts pending undo command, tunring last call to beginUndoCommand
obsolete
%End %End
QgsProcessingModelAlgorithm *model(); QgsProcessingModelAlgorithm *model();

View File

@ -90,6 +90,11 @@ Starts a single undo command
Ends a single undo command Ends a single undo command
%End %End
void abortCommand();
%Docstring
Aborts pending undo command
%End
enum ClipboardOperation /BaseType=IntEnum/ enum ClipboardOperation /BaseType=IntEnum/
{ {
@ -184,6 +189,11 @@ Emitted when an undo command is started in the view.
void commandEnded(); void commandEnded();
%Docstring %Docstring
Emitted when an undo command in the view has ended. Emitted when an undo command in the view has ended.
%End
void commandAborted();
%Docstring
Emitted when an undo command in the view was aborted.
%End %End
void deleteSelectedItems(); void deleteSelectedItems();

View File

@ -1,6 +1,6 @@
# The following has been generated automatically from src/gui/processing/models/qgsmodelgraphicsview.h # The following has been generated automatically from src/gui/processing/models/qgsmodelgraphicsview.h
try: try:
QgsModelGraphicsView.__attribute_docs__ = {'algorithmDropped': 'Emitted when an algorithm is dropped onto the view.\n', 'inputDropped': 'Emitted when an input parameter is dropped onto the view.\n', 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the\nactive item and should have its properties displayed in any designer\nwindows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted, but is\nstill in a perfectly valid state.\n', 'macroCommandStarted': 'Emitted when a macro command containing a group of interactions is\nstarted in the view.\n', 'macroCommandEnded': 'Emitted when a macro command containing a group of interactions in the\nview has ended.\n', 'commandBegun': 'Emitted when an undo command is started in the view.\n', 'commandEnded': 'Emitted when an undo command in the view has ended.\n', 'deleteSelectedItems': 'Emitted when the selected items should be deleted;\n'} QgsModelGraphicsView.__attribute_docs__ = {'algorithmDropped': 'Emitted when an algorithm is dropped onto the view.\n', 'inputDropped': 'Emitted when an input parameter is dropped onto the view.\n', 'itemFocused': 'Emitted when an ``item`` is "focused" in the view, i.e. it becomes the\nactive item and should have its properties displayed in any designer\nwindows.\n', 'willBeDeleted': 'Emitted in the destructor when the view is about to be deleted, but is\nstill in a perfectly valid state.\n', 'macroCommandStarted': 'Emitted when a macro command containing a group of interactions is\nstarted in the view.\n', 'macroCommandEnded': 'Emitted when a macro command containing a group of interactions in the\nview has ended.\n', 'commandBegun': 'Emitted when an undo command is started in the view.\n', 'commandEnded': 'Emitted when an undo command in the view has ended.\n', 'commandAborted': 'Emitted when an undo command in the view was aborted.\n', 'deleteSelectedItems': 'Emitted when the selected items should be deleted;\n'}
QgsModelGraphicsView.__overridden_methods__ = ['dragEnterEvent', 'dropEvent', 'dragMoveEvent', 'wheelEvent', 'mousePressEvent', 'mouseReleaseEvent', 'mouseMoveEvent', 'mouseDoubleClickEvent', 'keyPressEvent', 'keyReleaseEvent'] QgsModelGraphicsView.__overridden_methods__ = ['dragEnterEvent', 'dropEvent', 'dragMoveEvent', 'wheelEvent', 'mousePressEvent', 'mouseReleaseEvent', 'mouseMoveEvent', 'mouseDoubleClickEvent', 'keyPressEvent', 'keyReleaseEvent']
QgsModelGraphicsView.__signal_arguments__ = {'algorithmDropped': ['algorithmId: str', 'pos: QPointF'], 'inputDropped': ['inputId: str', 'pos: QPointF'], 'itemFocused': ['item: QgsModelComponentGraphicItem'], 'macroCommandStarted': ['text: str'], 'commandBegun': ['text: str']} QgsModelGraphicsView.__signal_arguments__ = {'algorithmDropped': ['algorithmId: str', 'pos: QPointF'], 'inputDropped': ['inputId: str', 'pos: QPointF'], 'itemFocused': ['item: QgsModelComponentGraphicItem'], 'macroCommandStarted': ['text: str'], 'commandBegun': ['text: str']}
QgsModelGraphicsView.__group__ = ['processing', 'models'] QgsModelGraphicsView.__group__ = ['processing', 'models']

View File

@ -44,6 +44,12 @@ made to the model.
%Docstring %Docstring
Ends the current undo command. This should be called after changes are Ends the current undo command. This should be called after changes are
made to the model. made to the model.
%End
void abortUndoCommand();
%Docstring
Aborts pending undo command, tunring last call to beginUndoCommand
obsolete
%End %End
QgsProcessingModelAlgorithm *model(); QgsProcessingModelAlgorithm *model();

View File

@ -90,6 +90,11 @@ Starts a single undo command
Ends a single undo command Ends a single undo command
%End %End
void abortCommand();
%Docstring
Aborts pending undo command
%End
enum ClipboardOperation enum ClipboardOperation
{ {
@ -184,6 +189,11 @@ Emitted when an undo command is started in the view.
void commandEnded(); void commandEnded();
%Docstring %Docstring
Emitted when an undo command in the view has ended. Emitted when an undo command in the view has ended.
%End
void commandAborted();
%Docstring
Emitted when an undo command in the view was aborted.
%End %End
void deleteSelectedItems(); void deleteSelectedItems();

View File

@ -345,6 +345,9 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags
connect( mView, &QgsModelGraphicsView::commandEnded, this, [this] { connect( mView, &QgsModelGraphicsView::commandEnded, this, [this] {
endUndoCommand(); endUndoCommand();
} ); } );
connect( mView, &QgsModelGraphicsView::commandAborted, this, [this] {
abortUndoCommand();
} );
connect( mView, &QgsModelGraphicsView::deleteSelectedItems, this, [this] { connect( mView, &QgsModelGraphicsView::deleteSelectedItems, this, [this] {
deleteSelected(); deleteSelected();
} ); } );
@ -429,6 +432,12 @@ void QgsModelDesignerDialog::endUndoCommand()
setDirty( true ); setDirty( true );
} }
void QgsModelDesignerDialog::abortUndoCommand()
{
if ( mActiveCommand )
mActiveCommand->setObsolete( true );
}
QgsProcessingModelAlgorithm *QgsModelDesignerDialog::model() QgsProcessingModelAlgorithm *QgsModelDesignerDialog::model()
{ {
return mModel.get(); return mModel.get();

View File

@ -72,6 +72,11 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
*/ */
void endUndoCommand(); void endUndoCommand();
/**
* Aborts pending undo command, tunring last call to beginUndoCommand obsolete
*/
void abortUndoCommand();
/** /**
* Returns the model shown in the dialog. * Returns the model shown in the dialog.
*/ */

View File

@ -473,6 +473,11 @@ void QgsModelGraphicsView::endCommand()
emit commandEnded(); emit commandEnded();
} }
void QgsModelGraphicsView::abortCommand()
{
emit commandAborted();
}
void QgsModelGraphicsView::snapSelected() void QgsModelGraphicsView::snapSelected()
{ {
QgsModelGraphicsScene *s = modelScene(); QgsModelGraphicsScene *s = modelScene();

View File

@ -119,6 +119,11 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
*/ */
void endCommand(); void endCommand();
/**
* Aborts pending undo command
*/
void abortCommand();
//! Clipboard operations //! Clipboard operations
enum ClipboardOperation enum ClipboardOperation
@ -212,6 +217,11 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
*/ */
void commandEnded(); void commandEnded();
/**
* Emitted when an undo command in the view was aborted.
*/
void commandAborted();
/** /**
* Emitted when the selected items should be deleted; * Emitted when the selected items should be deleted;
*/ */

View File

@ -23,7 +23,9 @@
#include "qgsmodelviewmouseevent.h" #include "qgsmodelviewmouseevent.h"
#include "qgsmodelviewtoolselect.h" #include "qgsmodelviewtoolselect.h"
#include "qgsmodelgraphicsview.h" #include "qgsmodelgraphicsview.h"
#include <QScrollBar> #include "qgsmodelviewrubberband.h"
#include "qgsmodelgraphicitem.h"
QgsModelViewToolLink::QgsModelViewToolLink( QgsModelGraphicsView *view ) QgsModelViewToolLink::QgsModelViewToolLink( QgsModelGraphicsView *view )
: QgsModelViewTool( view, tr( "Link Tool" ) ) : QgsModelViewTool( view, tr( "Link Tool" ) )
@ -40,22 +42,21 @@ void QgsModelViewToolLink::modelMoveEvent( QgsModelViewMouseEvent *event )
mBezierRubberBand->update( event->modelPoint(), Qt::KeyboardModifiers() ); mBezierRubberBand->update( event->modelPoint(), Qt::KeyboardModifiers() );
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate // we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate
QList<QGraphicsItem *> items = scene()->items( event->modelPoint() ); const QList<QGraphicsItem *> items = scene()->items( event->modelPoint() );
QgsModelDesignerSocketGraphicItem *socket = nullptr; QgsModelDesignerSocketGraphicItem *socket = nullptr;
for ( QGraphicsItem *item : items ) for ( QGraphicsItem *item : items )
{ {
if ( ( socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item ) ) socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item );
&& ( mFromSocket != socket && mFromSocket->edge() != socket->edge() ) ) if ( !socket || mFromSocket == socket || mFromSocket->edge() == socket->edge() || mFromSocket->component() == socket->component() )
{ continue;
// snap // snap
socket->modelHoverEnterEvent( event ); socket->modelHoverEnterEvent( event );
QPointF rubberEndPos = socket->mapToScene( socket->position() ); const QPointF rubberEndPos = socket->mapToScene( socket->position() );
mBezierRubberBand->update( rubberEndPos, Qt::KeyboardModifiers() ); mBezierRubberBand->update( rubberEndPos, Qt::KeyboardModifiers() );
break; break;
} }
}
if ( mLastHoveredSocket && socket != mLastHoveredSocket ) if ( mLastHoveredSocket && socket != mLastHoveredSocket )
{ {
@ -85,7 +86,7 @@ void QgsModelViewToolLink::modelReleaseEvent( QgsModelViewMouseEvent *event )
view()->setTool( mPreviousViewTool ); view()->setTool( mPreviousViewTool );
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate // we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate
QList<QGraphicsItem *> items = scene()->items( event->modelPoint() ); const QList<QGraphicsItem *> items = scene()->items( event->modelPoint() );
mToSocket = nullptr; mToSocket = nullptr;
@ -93,6 +94,10 @@ void QgsModelViewToolLink::modelReleaseEvent( QgsModelViewMouseEvent *event )
{ {
if ( QgsModelDesignerSocketGraphicItem *socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item ) ) if ( QgsModelDesignerSocketGraphicItem *socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item ) )
{ {
// Skip if sockets are both input or both output or both from the same algorithm
if ( mFromSocket->edge() == socket->edge() || mFromSocket->component() == socket->component() )
continue;
mToSocket = socket; mToSocket = socket;
break; break;
} }
@ -101,21 +106,12 @@ void QgsModelViewToolLink::modelReleaseEvent( QgsModelViewMouseEvent *event )
// Do nothing if cursor didn't land on another socket // Do nothing if cursor didn't land on another socket
if ( !mToSocket ) if ( !mToSocket )
{ {
// but it might have been an unlink, so we properly end the command
view()->endCommand();
return; return;
} }
// and we abort any pending unlink command to not litter the undo buffer
// Do nothing if from socket and to socket are both input or both output view()->abortCommand();
if ( mFromSocket->edge() == mToSocket->edge() )
{
return;
}
view()->beginCommand( tr( "Edit link" ) );
QList<QgsProcessingModelChildParameterSource> sources;
QgsProcessingModelComponent *componentFrom = nullptr;
QgsProcessingModelChildAlgorithm *childTo = nullptr;
/** /**
* Reorder input and output socket * Reorder input and output socket
@ -130,26 +126,32 @@ void QgsModelViewToolLink::modelReleaseEvent( QgsModelViewMouseEvent *event )
std::swap( mFromSocket, mToSocket ); std::swap( mFromSocket, mToSocket );
} }
componentFrom = mFromSocket->component(); QgsProcessingModelComponent *outputComponent = mFromSocket->component();
childTo = dynamic_cast<QgsProcessingModelChildAlgorithm *>( mToSocket->component() ); QgsProcessingModelChildAlgorithm *inputChildAlgorithm = dynamic_cast<QgsProcessingModelChildAlgorithm *>( mToSocket->component() );
if ( !inputChildAlgorithm )
const QgsProcessingParameterDefinition *toParam = childTo->algorithm()->parameterDefinitions().at( mToSocket->index() );
QgsProcessingModelChildParameterSource source;
if ( QgsProcessingModelChildAlgorithm *childFrom = dynamic_cast<QgsProcessingModelChildAlgorithm *>( componentFrom ) )
{ {
QString outputName = childFrom->algorithm()->outputDefinitions().at( mFromSocket->index() )->name(); // Should not happen, but checking is cheap!
source = QgsProcessingModelChildParameterSource::fromChildOutput( childFrom->childId(), outputName ); QgsDebugError( QStringLiteral( "Input is not a QgsProcessingModelChildAlgorithm" ) );
} return;
else if ( QgsProcessingModelParameter *paramFrom = dynamic_cast<QgsProcessingModelParameter *>( componentFrom ) )
{
source = QgsProcessingModelChildParameterSource::fromModelParameter( paramFrom->parameterName() );
} }
QList<QgsProcessingModelChildParameterSource> compatibleParamSources = scene()->model()->availableSourcesForChild( childTo->childId(), toParam ); QgsProcessingModelChildParameterSource newInputParamSource;
QString outParamDescription;
if ( const QgsProcessingModelChildAlgorithm *outputChildAlgorithm = dynamic_cast<QgsProcessingModelChildAlgorithm *>( outputComponent ) )
{
const QString outParamName = outputChildAlgorithm->algorithm()->outputDefinitions().at( mFromSocket->index() )->name();
newInputParamSource = QgsProcessingModelChildParameterSource::fromChildOutput( outputChildAlgorithm->childId(), outParamName );
outParamDescription = outputChildAlgorithm->algorithm()->outputDefinitions().at( mFromSocket->index() )->description();
}
else if ( const QgsProcessingModelParameter *paramFrom = dynamic_cast<QgsProcessingModelParameter *>( outputComponent ) )
{
newInputParamSource = QgsProcessingModelChildParameterSource::fromModelParameter( paramFrom->parameterName() );
outParamDescription = paramFrom->description();
}
if ( !compatibleParamSources.contains( source ) ) const QgsProcessingParameterDefinition *inputParam = inputChildAlgorithm->algorithm()->parameterDefinitions().at( mToSocket->index() );
const QList<QgsProcessingModelChildParameterSource> compatibleInputParamSources = scene()->model()->availableSourcesForChild( inputChildAlgorithm->childId(), inputParam );
if ( !compatibleInputParamSources.contains( newInputParamSource ) )
{ {
//Type are incomatible //Type are incomatible
const QString title = tr( "Sockets cannot be connected" ); const QString title = tr( "Sockets cannot be connected" );
@ -158,12 +160,12 @@ void QgsModelViewToolLink::modelReleaseEvent( QgsModelViewMouseEvent *event )
return; return;
} }
sources << source; view()->beginCommand( tr( "Link %1: %2 to %3: %4" ).arg( outputComponent->description(), outParamDescription, inputChildAlgorithm->description(), inputParam->description() ) );
childTo->addParameterSources( toParam->name(), sources );
inputChildAlgorithm->addParameterSources( inputParam->name(), { newInputParamSource } );
//We need to pass the update child algorithm to the model //We need to pass the update child algorithm to the model
scene()->model()->setChildAlgorithm( *childTo ); scene()->model()->setChildAlgorithm( *inputChildAlgorithm );
view()->endCommand(); view()->endCommand();
// Redraw // Redraw
@ -184,7 +186,7 @@ void QgsModelViewToolLink::activate()
mPreviousViewTool = tool; mPreviousViewTool = tool;
} }
QPointF rubberStartPos = mFromSocket->mapToScene( mFromSocket->position() ); const QPointF rubberStartPos = mFromSocket->mapToScene( mFromSocket->position() );
mBezierRubberBand->start( rubberStartPos, Qt::KeyboardModifiers() ); mBezierRubberBand->start( rubberStartPos, Qt::KeyboardModifiers() );
QgsModelViewTool::activate(); QgsModelViewTool::activate();
@ -200,28 +202,37 @@ void QgsModelViewToolLink::setFromSocket( QgsModelDesignerSocketGraphicItem *soc
{ {
mFromSocket = socket; mFromSocket = socket;
// If it's an input socket and it's already connected, we want 'From' to be the output at the other end of the connection
if ( mFromSocket->isInput() ) if ( mFromSocket->isInput() )
{ {
QgsProcessingModelChildAlgorithm *childFrom = dynamic_cast<QgsProcessingModelChildAlgorithm *>( mFromSocket->component() ); QgsProcessingModelChildAlgorithm *childFrom = dynamic_cast<QgsProcessingModelChildAlgorithm *>( mFromSocket->component() );
const QgsProcessingParameterDefinition *param = childFrom->algorithm()->parameterDefinitions().at( mFromSocket->index() ); const QgsProcessingParameterDefinition *param = childFrom->algorithm()->parameterDefinitions().at( mFromSocket->index() );
const QList<QgsProcessingModelChildParameterSource> currentSources = childFrom->parameterSources().value( param->name() );
auto currentSources = childFrom->parameterSources().value( param->name() ); for ( const QgsProcessingModelChildParameterSource &source : currentSources )
QgsProcessingModelChildParameterSource oldSource;
for ( const QgsProcessingModelChildParameterSource &source : std::as_const( currentSources ) )
{ {
// Was not connected, nothing to do
if ( source.outputChildId().isEmpty() )
break;
switch ( source.source() ) switch ( source.source() )
{ {
case Qgis::ProcessingModelChildParameterSource::ModelParameter: case Qgis::ProcessingModelChildParameterSource::ModelParameter:
case Qgis::ProcessingModelChildParameterSource::ChildOutput: case Qgis::ProcessingModelChildParameterSource::ChildOutput:
{ {
oldSource = source; view()->beginCommand( tr( "Unlink %1: %2", "Unlink Algorithm: Input" ).arg( childFrom->description(), param->description() ) );
view()->beginCommand( tr( "Edit link" ) );
//reset to default value // reset to default value. Layers/feature sources default to an empty model parameter
QList<QgsProcessingModelChildParameterSource> newSources; QList<QgsProcessingModelChildParameterSource> newSources;
if ( param->type() == QgsProcessingParameterFeatureSource::typeName() || param->type() == QgsProcessingParameterMapLayer::typeName() || param->type() == QgsProcessingParameterMeshLayer::typeName() || param->type() == QgsProcessingParameterPointCloudLayer::typeName() || param->type() == QgsProcessingParameterRasterLayer::typeName() || param->type() == QgsProcessingParameterVectorLayer::typeName() )
{
newSources << QgsProcessingModelChildParameterSource::fromModelParameter( QString() );
}
else
{
// Other parameters default to static value
newSources << QgsProcessingModelChildParameterSource::fromStaticValue( param->defaultValue() ); newSources << QgsProcessingModelChildParameterSource::fromStaticValue( param->defaultValue() );
}
childFrom->addParameterSources( param->name(), newSources ); childFrom->addParameterSources( param->name(), newSources );
//We need to pass the update child algorithm to the model //We need to pass the update child algorithm to the model
@ -232,9 +243,9 @@ void QgsModelViewToolLink::setFromSocket( QgsModelDesignerSocketGraphicItem *soc
//Get socket from initial source alg / source parameter //Get socket from initial source alg / source parameter
QgsModelComponentGraphicItem *item = nullptr; QgsModelComponentGraphicItem *item = nullptr;
int socketIndex = -1; int socketIndex = -1;
if ( oldSource.source() == Qgis::ProcessingModelChildParameterSource::ChildOutput ) if ( source.source() == Qgis::ProcessingModelChildParameterSource::ChildOutput )
{ {
item = scene()->childAlgorithmItem( oldSource.outputChildId() ); item = scene()->childAlgorithmItem( source.outputChildId() );
auto algSource = dynamic_cast<QgsProcessingModelChildAlgorithm *>( item->component() ); auto algSource = dynamic_cast<QgsProcessingModelChildAlgorithm *>( item->component() );
if ( !algSource ) if ( !algSource )
{ {
@ -243,7 +254,7 @@ void QgsModelViewToolLink::setFromSocket( QgsModelDesignerSocketGraphicItem *soc
} }
socketIndex = QgsProcessingUtils::outputDefinitionIndex( algSource->algorithm(), source.outputName() ); socketIndex = QgsProcessingUtils::outputDefinitionIndex( algSource->algorithm(), source.outputName() );
} }
else if ( oldSource.source() == Qgis::ProcessingModelChildParameterSource::ModelParameter ) else if ( source.source() == Qgis::ProcessingModelChildParameterSource::ModelParameter )
{ {
item = scene()->parameterItem( source.parameterName() ); item = scene()->parameterItem( source.parameterName() );
socketIndex = 0; socketIndex = 0;

View File

@ -19,12 +19,14 @@
#include "qgis_sip.h" #include "qgis_sip.h"
#include "qgis_gui.h" #include "qgis_gui.h"
#include "qgsmodelviewtool.h" #include "qgsmodelviewtool.h"
#include "qgsmodelviewrubberband.h"
#include "qgsmodelgraphicitem.h"
#include <memory> #include <memory>
#define SIP_NO_FILE #define SIP_NO_FILE
class QgsModelViewBezierRubberBand;
class QgsModelDesignerSocketGraphicItem;
class QgsProcessingModelComponent;
/** /**
* \ingroup gui * \ingroup gui
* \brief Model designer view tool for linking socket together * \brief Model designer view tool for linking socket together

View File

@ -124,7 +124,7 @@ void QgsModelViewToolSelect::modelPressEvent( QgsModelViewMouseEvent *event )
{ {
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate events // we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate events
// to multiple items // to multiple items
QList<QGraphicsItem *> items = scene()->items( event->modelPoint() ); const QList<QGraphicsItem *> items = scene()->items( event->modelPoint() );
for ( QGraphicsItem *item : items ) for ( QGraphicsItem *item : items )
{ {
if ( QgsModelDesignerSocketGraphicItem *socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item ) ) if ( QgsModelDesignerSocketGraphicItem *socket = dynamic_cast<QgsModelDesignerSocketGraphicItem *>( item ) )