//------------------------------------------------------------------------------ // Copyright (c) 2005, 2006 IBM Corporation and others. // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html // // Contributors: // IBM Corporation - initial implementation //------------------------------------------------------------------------------ package org.eclipse.epf.authoring.gef.edit; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.FreeformLayer; import org.eclipse.draw2d.FreeformLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.MarginBorder; import org.eclipse.draw2d.PolylineConnection; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.emf.ecore.EObject; import org.eclipse.epf.authoring.gef.commands.ChangeBoundsCommand; import org.eclipse.epf.authoring.gef.edit.policies.DiagramLayoutEditPolicy; import org.eclipse.epf.authoring.ui.AuthoringUIPlugin; import org.eclipse.epf.diagram.model.Diagram; import org.eclipse.epf.diagram.model.Link; import org.eclipse.epf.diagram.model.Node; import org.eclipse.epf.diagram.model.NodeContainer; import org.eclipse.epf.library.edit.util.TngUtil; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.editpolicies.RootComponentEditPolicy; /** * Provides EditPart for Diagram. Handles the basic layout mechanism * if the children location is not set in the diagram. * * @author Phong Nguyen Le * @author skannoor * @since 1.0 */ public class DiagramEditPart extends NodeContainerEditPart { Point cachedPoint = new Point(-1, -1); protected boolean debug; private boolean markDirty = false; static int cachedWidth = 10; static int cachedHeight = 10; public DiagramEditPart(Diagram model) { super(model); debug = AuthoringUIPlugin.getDefault().isDebugging(); } protected IFigure createFigure() { Figure f = new FreeformLayer() { protected void layout() { if (hasMisplacedChildren()) { resetChildrenLocations(); } super.layout(); } }; f.setBorder(new MarginBorder(20)); f.setLayoutManager(new FreeformLayout()); return f; } protected void resetChildrenLocations() { int y = 10; final int spacing = 40; int occupied = 0; int xelements = 0; int x = 10; boolean locked = TngUtil.isLocked((EObject)((Diagram)getModel()).getObject()); for (Iterator iter = getChildren().iterator(); iter.hasNext();) { Object child = iter.next(); if (child instanceof GraphicalEditPart) { GraphicalEditPart part = (GraphicalEditPart) child; int width = part.getRoot().getViewer().getControl().getBounds().width; if (part.getModel() instanceof Node) { Node node = (Node) part.getModel(); Point p = node.getLocation().getCopy(); if (p == null || p.x == -1) { if (x + part.getFigure().getPreferredSize().width > width) { y = cachedPoint.y + cachedHeight + spacing; xelements = 0; x = 10; cachedPoint.x = -1; occupied = 0; } if (cachedPoint.x != -1) { x = cachedPoint.x + cachedWidth + spacing; } ++xelements; if (p == null) { p = new Point(-1, -1); } p.x = x; p.y = y; //node.setLocation(p); //On opening a AD diagram, editor should be marked dirty. //If diagram is not saved, cannot be browsed. Forcing to save the diagram once. if (!locked && ((Diagram) getModel()).isNew() && !((Diagram) getModel()).isReadOnly() && markDirty) { ChangeBoundsCommand cbc = new ChangeBoundsCommand(node, p, part.getFigure() .getPreferredSize().width); getViewer().getEditDomain().getCommandStack() .execute(cbc); } else { // If Plugin is Locked: Do auto-layout and donot // save to model. node.setLocation(p); } cachedPoint = p; cachedWidth = part.getFigure().getPreferredSize().width; cachedHeight = part.getFigure().getPreferredSize().height; if (debug) { System.out .println("Point : " + new Point(x, y).toString()); //$NON-NLS-1$ System.out .println("Cached : width: " + cachedWidth + " Height : " + cachedHeight); //$NON-NLS-1$ //$NON-NLS-2$ } occupied += x; } } } } } protected boolean hasMisplacedChildren() { for (Iterator iter = getChildren().iterator(); iter.hasNext();) { Object child = iter.next(); if (child instanceof EditPart) { Object model = ((EditPart) child).getModel(); if (model instanceof Node) { Node node = (Node) model; Point p = node.getLocation(); if (p == null || p.x == -1){ return true; } } } } return false; } protected void createEditPolicies() { installEditPolicy(EditPolicy.COMPONENT_ROLE, new RootComponentEditPolicy()); installEditPolicy(EditPolicy.CONTAINER_ROLE, new DiagramLayoutEditPolicy()); } /** * @see org.eclipse.epf.authoring.gef.edit.NodeContainerEditPart#addPartToEdit(Collection, * Object) */ protected void addPartToEdit(Collection partsToEdit, Object node) { if (node instanceof NodeContainer) { NodeContainerEditPart editPart = (NodeContainerEditPart) findChildByModel(node); for (Iterator iter = ((NodeContainer) node).getNodes().iterator(); iter .hasNext();) { editPart.addPartToEdit(partsToEdit, iter.next()); } } else { super.addPartToEdit(partsToEdit, node); } } /** * Moves complete diagram children to given delta. * @param int (X-axis delta) * @param int (Y-axis delta) * */ public void moveFigure(int moveX, int moveY) { for (Iterator iter = this.getChildren().iterator(); iter.hasNext();) { Object child = iter.next(); if (child instanceof GraphicalEditPart) { GraphicalEditPart part = (GraphicalEditPart) child; Rectangle bounds = part.getFigure().getBounds(); Rectangle r = new Rectangle(new Point(bounds.x + moveX, bounds.y + moveY), bounds.getSize()); // also need to move the bend points List list = part.getSourceConnections(); for (Iterator itor = list.iterator(); itor.hasNext();) { LinkEditPart linkpart = (LinkEditPart) itor.next(); Link link = (Link) linkpart.getModel(); if (link.getBendpoints().size() > 0) { PointList plist = ((PolylineConnection) linkpart .getFigure()).getPoints(); List points = new ArrayList(); for (int i = 1; i < plist.size() - 1; i++) { Point p = plist.getPoint(i); p = p.translate(new Point(moveX, moveY)); org.eclipse.draw2d.AbsoluteBendpoint bp = new org.eclipse.draw2d.AbsoluteBendpoint( p); points.add(bp); } linkpart.getConnectionFigure().setRoutingConstraint( points); } } this.setLayoutConstraint(part, part.getFigure(), r); } else { // System.out.println("Part not moved: " + child); //$NON-NLS-1$ } } } /** * On opening a diagram, editor should be marked dirty. * Invoker of DiagramEditPart should explicitly set the flag to mark editor dirty * or not. Withou handling this will cause browsing perspective in consistent. * For defect: https://bugs.eclipse.org/bugs/show_bug.cgi?id=156029 */ public void markDirty(boolean markDirty){ this.markDirty = markDirty; } }