package org.eclipse.uml2.diagram.sequence.edit.policies; import java.util.Collections; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartListener; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.NodeListener; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.editpolicies.AbstractEditPolicy; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart; import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest; import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.uml2.diagram.sequence.edit.parts.InteractionEditPart; import org.eclipse.uml2.diagram.sequence.internal.layout.manage.SdLayoutAsInnerLayout; public class InteractionNestedLayoutEditPolicy extends AbstractEditPolicy { private SdLayoutAsInnerLayout mySdLayout; private EditPartTracker myEditPartTracker; @Override public void activate() { reinitSDLayout(); try { InteractionNestedLayoutRequest req = new InteractionNestedLayoutRequest(); //req.setRepeatSessionsCount(2); getHostImpl().getDiagramEditDomain().getDiagramCommandStack().execute(getCommand(req)); } catch (RuntimeException e){ e.printStackTrace(); throw e; } } private void reinitSDLayout(){ myEditPartTracker = new EditPartTracker(); mySdLayout = new SdLayoutAsInnerLayout(getHostImpl()); getHost().addEditPartListener(myEditPartTracker); setupNodesTree(getHostImpl()); setupLinksTree(getHostImpl()); } private void setupNodesTree(EditPart treeRoot){ for (Object next : treeRoot.getChildren()){ EditPart nextEP = (EditPart)next; addToLayout(nextEP); nextEP.addEditPartListener(myEditPartTracker); if (nextEP instanceof NodeEditPart){ ((NodeEditPart)nextEP).addNodeListener(myEditPartTracker); } setupNodesTree(nextEP); } } private void setupLinksTree(EditPart treeRoot){ for (Object next : treeRoot.getChildren()){ if (next instanceof NodeEditPart){ NodeEditPart nextEP = (NodeEditPart)next; for (Object nextLink : nextEP.getSourceConnections()){ if (nextLink instanceof ConnectionEditPart){ addToLayout((ConnectionEditPart)nextLink); } } } setupLinksTree((EditPart)next); } } @Override public void deactivate() { mySdLayout = null; getHost().removeEditPartListener(myEditPartTracker); } @Override public boolean understandsRequest(Request req) { if (req instanceof ArrangeRequest){ return true; //temporary to allow execution from "Arrange Selected" } return req instanceof InteractionNestedLayoutRequest; } @Override public Command getCommand(Request request) { if (request instanceof ArrangeRequest){ return getNestedLayoutCommand(new InteractionNestedLayoutRequest()); } if (request instanceof InteractionNestedLayoutRequest){ return getNestedLayoutCommand((InteractionNestedLayoutRequest)request); } return null; } protected Command getNestedLayoutCommand(final InteractionNestedLayoutRequest request){ AbstractTransactionalCommand result = new AbstractTransactionalCommand(getHostImpl().getEditingDomain(), "Layouting", Collections.singletonList(WorkspaceSynchronizer.getFile(getHostImpl().getNotationView().eResource()))){ @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { if (request.isTotalLayout()){ mySdLayout = null; reinitSDLayout(); } for (IAdaptable nextViewAdapter : request.getViewAdapters()){ View view = (View) nextViewAdapter.getAdapter(View.class); if (view == null){ System.err.println("There are no View adapters in: " + nextViewAdapter); continue; } EditPart nextEditPart = (EditPart) getHost().getViewer().getEditPartRegistry().get(view); if (nextEditPart == null){ System.err.println("There are no EditPart registered for view: " + view); continue; } addToLayout(nextEditPart); } for (IGraphicalEditPart nextReshaped : request.getReshapedElements()){ mySdLayout.elementReshaped(nextReshaped); } for (int i = 0; i < request.getSessionsCount(); i++){ mySdLayout.performLayout(); } return CommandResult.newOKCommandResult(); } }; return new ICommandProxy(result); } private InteractionEditPart getHostImpl(){ return (InteractionEditPart) getHost(); } private void addToLayout(EditPart editPart){ if (editPart instanceof ITextAwareEditPart){ return; } //System.err.println("Adding to layout: " + editPart); if (editPart instanceof ConnectionEditPart){ mySdLayout.linkAdded((ConnectionEditPart)editPart); return; } if (editPart instanceof GraphicalEditPart){ mySdLayout.nodeAdded((GraphicalEditPart)editPart); } } private void removeFromLayout(EditPart editPart){ if (editPart instanceof ITextAwareEditPart){ return; } if (editPart instanceof ConnectionEditPart){ mySdLayout.linkRemoved((ConnectionEditPart)editPart); return; } if (editPart instanceof GraphicalEditPart){ mySdLayout.nodeRemoved((GraphicalEditPart)editPart); } } private class EditPartTracker extends EditPartListener.Stub implements NodeListener { public void childAdded(EditPart child, int index) { addToLayout(child); child.addEditPartListener(this); if (child instanceof NodeEditPart){ ((NodeEditPart)child).addNodeListener(this); for (Object next : ((NodeEditPart)child).getSourceConnections()){ org.eclipse.gef.ConnectionEditPart nextLink = (org.eclipse.gef.ConnectionEditPart)next; //if (nextLink.getTarget() != null){ addToLayout(nextLink); //} } } setupNodesTree(child); } @Override public void removingChild(EditPart child, int index) { child.removeEditPartListener(this); if (child instanceof NodeEditPart){ ((NodeEditPart)child).removeNodeListener(this); } removeFromLayout(child); } public void removingSourceConnection(org.eclipse.gef.ConnectionEditPart connection, int index) { removeFromLayout(connection); } public void removingTargetConnection(org.eclipse.gef.ConnectionEditPart connection, int index) { // TODO Auto-generated method stub } public void sourceConnectionAdded(org.eclipse.gef.ConnectionEditPart connection, int index) { addToLayout(connection); } public void targetConnectionAdded(org.eclipse.gef.ConnectionEditPart connection, int index) { // } } }