Bug 174085 - Connection is deactivated after moving
Summary: Connection is deactivated after moving
Status: RESOLVED FIXED
Alias: None
Product: GEF
Classification: Tools
Component: GEF-Legacy GEF (MVC) (show other bugs)
Version: 3.2.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3.0 (Europa) M7   Edit
Assignee: Cherie Revells CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2007-02-13 15:24 EST by Luiz Scheinkman CLA
Modified: 2008-09-18 13:29 EDT (History)
2 users (show)

See Also:


Attachments
Attempted fix. (1.46 KB, patch)
2007-04-13 11:30 EDT, Cherie Revells CLA
ahunter.eclipse: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Luiz Scheinkman CLA 2007-02-13 15:24:32 EST
Build ID: Build id: M20060921-0945

Steps To Reproduce:
When an existing connection is reconnected to another node, 
the source node deactivates the connection after it's been moved.
This causes the connection's tooltip to disappear.


More information:
org.eclipse.gef.editparts.AbstractGraphicalEditPart#deactivate()

is not checking if it owns the connection before deactivating it.

// Proposed fix for org.eclipse.gef.editparts.AbstractGraphicalEditPart#deactivate()

    public void deactivate() {
        List l = getSourceConnections();
        ConnectionEditPart connection ;
        for (int i = 0; i < l.size(); i++) {
            connection = (ConnectionEditPart)l.get(i);
            if (connection.getSource() == this) {
                connection.deactivate();
            }
        }
        super.deactivate();
    }
Comment 1 Randy Hudson CLA 2007-02-14 16:52:38 EST
This usually indicates a problem in the model's commands, the notification order or in responding to that notification. For most models' connections, the source node is detached before it is attached to a new source node. If the model doesn't enforce this for free, the command should try to. Similarly, a part/node is generally removed from it's parent before it is added to another parent.
Comment 2 Luiz Scheinkman CLA 2007-02-14 20:11:28 EST
(In reply to comment #1)
> This usually indicates a problem in the model's commands, the notification
> order or in responding to that notification. For most models' connections, the
> source node is detached before it is attached to a new source node. If the
> model doesn't enforce this for free, the command should try to. Similarly, a
> part/node is generally removed from it's parent before it is added to another
> parent.
> 

This is correct. 

My model is being changed from outside the editor, without notifications, and later on, the editor calls "getGraphicalViewer().getContents().refresh()", which in turn calls "refreshChildren()". At this point, if my edit part was moved from  one parent edit part to another parent edit part the connections would be deactivated because of the order of the edit parts.

My assumption was that i could manipulated the model from outside the editor and later refresh its contents from the updated model.
Comment 3 Cherie Revells CLA 2007-03-29 09:59:15 EDT
I am having the same issue, but my scenario is different.  I am trying to implement grouping functionality in GMF.  I have two shapes on the diagram with a connection between them.  I have an action that will group the shapes.  My group command basically creates a group model element and reparents the shapes' model elements to belong to the group.  The group command does nothing with connections.  After I group two shapes with a connection between them, the connection is not active.  Here is what is happening...
- A group command is executed.
- The diagram editpart's refreshChildren() method is called.
- It sees that it has a new group child so it creates a new GroupEditPart.
---> This in turns creates new editparts for the two shapes that have been grouped.  In the refreshSourceConnections() method of the source shape, it does createOrFindConnection() and finds the existing editpart for the connection (that is referenced from the previous shape that was a child on the diagram).  It activates this connection.
- The diagram editpart's refreshChildren() method then removes the editparts no longer on the diagram.  Thus, it removes the previous shapes (that are now in the group) and deactivates them, which consequently deactivates the connection editpart that is being reused.
RESULT: The connection editpart is left in a deactivated state.
Comment 4 Cherie Revells CLA 2007-03-29 10:14:24 EDT
I should have read Randy's response a little more closely first.  If my group command removes the children model elements from the diagram first before adding the group to the diagram everything seems to work.  Randy, if you believe this is all working as it should, can we close this bugzilla?
Comment 5 Cherie Revells CLA 2007-03-29 11:51:32 EDT
My change of removing the children from the diagram first does not work afterall.  I still had Luiz's fix for AbstractGraphicalEditPart#deactivate() in my code.
Comment 6 Randy Hudson CLA 2007-03-29 16:19:09 EDT
> - A group command is executed.
> - The diagram editpart's refreshChildren() method is called.
Most likely because of the removal of the grouped children
> - It sees that it has a new group child so it creates a new GroupEditPart.
Because refreshChildren() catches all changes and maybe not just the change related to the first notification you receive. 

A couple of changes might fix the problem.

GEF Clients:
- don't call refreshChildren(), call add and remove child as appropriate.

GEF changes:
- AbstractConnectionEditPart setSource/Target: if the source is currently set, remove the conection from the source first.
AND/OR:
- refreshChildren() - process deletions before additions.
Comment 7 Cherie Revells CLA 2007-04-13 11:30:22 EDT
Created attachment 63767 [details]
Attempted fix.
Comment 8 Cherie Revells CLA 2007-04-13 11:35:57 EDT
Randy, can you take a look at my patch?  I have modified AbstractGraphicalEditPart.addTarget/SourceConnection to remove the connection from the previous source/target.

I first tried overriding AbstractConnectionEditPart setSource/Target to remove the connection from the source/target first.  The problem here is that in the case where I am passing in null because the source/target shape is being deleted, I don't want to remove it from the source/target otherwise the connection will be left hanging.  I thought a better place to do this was in AbstractGraphicalEditPart.

Mohammed and I discussed processing deletions before additions in refreshChildren(), but we thought this situation could still arise if the parent of the shape being added and the shapes being removed (which causes deactivation of the connection) were not in the same parent.
Comment 9 Randy Hudson CLA 2007-04-18 11:05:25 EDT
Released to HEAD
Comment 10 Anthony Hunter CLA 2007-04-19 15:07:11 EDT
Forgot to assign to Cherie
Comment 11 Anthony Hunter CLA 2007-04-19 15:08:05 EDT
In GEF Build I20070419