Community
Participate
Working Groups
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(); }
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.
(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.
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.
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?
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.
> - 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.
Created attachment 63767 [details] Attempted fix.
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.
Released to HEAD
Forgot to assign to Cherie
In GEF Build I20070419