| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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 API and implementation |
| *******************************************************************************/ |
| package org.eclipse.gef.examples.logicdesigner.model.commands; |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.eclipse.draw2d.geometry.Rectangle; |
| |
| import org.eclipse.gef.commands.Command; |
| |
| import org.eclipse.gef.examples.logicdesigner.LogicMessages; |
| import org.eclipse.gef.examples.logicdesigner.model.AndGate; |
| import org.eclipse.gef.examples.logicdesigner.model.Circuit; |
| import org.eclipse.gef.examples.logicdesigner.model.GroundOutput; |
| import org.eclipse.gef.examples.logicdesigner.model.LED; |
| import org.eclipse.gef.examples.logicdesigner.model.LiveOutput; |
| import org.eclipse.gef.examples.logicdesigner.model.LogicDiagram; |
| import org.eclipse.gef.examples.logicdesigner.model.LogicFlowContainer; |
| import org.eclipse.gef.examples.logicdesigner.model.LogicGuide; |
| import org.eclipse.gef.examples.logicdesigner.model.LogicLabel; |
| import org.eclipse.gef.examples.logicdesigner.model.LogicSubpart; |
| import org.eclipse.gef.examples.logicdesigner.model.OrGate; |
| import org.eclipse.gef.examples.logicdesigner.model.Wire; |
| import org.eclipse.gef.examples.logicdesigner.model.WireBendpoint; |
| import org.eclipse.gef.examples.logicdesigner.model.XORGate; |
| |
| public class CloneCommand extends Command { |
| |
| private List parts, newTopLevelParts, newConnections; |
| private LogicDiagram parent; |
| private Map bounds, indices, connectionPartMap; |
| private ChangeGuideCommand vGuideCommand, hGuideCommand; |
| private LogicGuide hGuide, vGuide; |
| private int hAlignment, vAlignment; |
| |
| public CloneCommand() { |
| super(LogicMessages.CloneCommand_Label); |
| parts = new LinkedList(); |
| } |
| |
| public void addPart(LogicSubpart part, Rectangle newBounds) { |
| parts.add(part); |
| if (bounds == null) { |
| bounds = new HashMap(); |
| } |
| bounds.put(part, newBounds); |
| } |
| |
| public void addPart(LogicSubpart part, int index) { |
| parts.add(part); |
| if (indices == null) { |
| indices = new HashMap(); |
| } |
| indices.put(part, new Integer(index)); |
| } |
| |
| protected void clonePart(LogicSubpart oldPart, LogicDiagram newParent, |
| Rectangle newBounds, List newConnections, Map connectionPartMap, |
| int index) { |
| LogicSubpart newPart = null; |
| |
| if (oldPart instanceof AndGate) { |
| newPart = new AndGate(); |
| } else if (oldPart instanceof Circuit) { |
| newPart = new Circuit(); |
| } else if (oldPart instanceof GroundOutput) { |
| newPart = new GroundOutput(); |
| } else if (oldPart instanceof LED) { |
| newPart = new LED(); |
| newPart.setPropertyValue(LED.P_VALUE, |
| oldPart.getPropertyValue(LED.P_VALUE)); |
| } else if (oldPart instanceof LiveOutput) { |
| newPart = new LiveOutput(); |
| } else if (oldPart instanceof LogicLabel) { |
| newPart = new LogicLabel(); |
| ((LogicLabel) newPart).setLabelContents(((LogicLabel) oldPart) |
| .getLabelContents()); |
| } else if (oldPart instanceof OrGate) { |
| newPart = new OrGate(); |
| } else if (oldPart instanceof LogicFlowContainer) { |
| newPart = new LogicFlowContainer(); |
| } else if (oldPart instanceof XORGate) { |
| newPart = new XORGate(); |
| } |
| |
| if (oldPart instanceof LogicDiagram) { |
| Iterator i = ((LogicDiagram) oldPart).getChildren().iterator(); |
| while (i.hasNext()) { |
| // for children they will not need new bounds |
| clonePart((LogicSubpart) i.next(), (LogicDiagram) newPart, |
| null, newConnections, connectionPartMap, -1); |
| } |
| } |
| |
| Iterator i = oldPart.getTargetConnections().iterator(); |
| while (i.hasNext()) { |
| Wire connection = (Wire) i.next(); |
| Wire newConnection = new Wire(); |
| newConnection.setValue(connection.getValue()); |
| newConnection.setTarget(newPart); |
| newConnection.setTargetTerminal(connection.getTargetTerminal()); |
| newConnection.setSourceTerminal(connection.getSourceTerminal()); |
| newConnection.setSource(connection.getSource()); |
| |
| Iterator b = connection.getBendpoints().iterator(); |
| Vector newBendPoints = new Vector(); |
| |
| while (b.hasNext()) { |
| WireBendpoint bendPoint = (WireBendpoint) b.next(); |
| WireBendpoint newBendPoint = new WireBendpoint(); |
| newBendPoint.setRelativeDimensions( |
| bendPoint.getFirstRelativeDimension(), |
| bendPoint.getSecondRelativeDimension()); |
| newBendPoint.setWeight(bendPoint.getWeight()); |
| newBendPoints.add(newBendPoint); |
| } |
| |
| newConnection.setBendpoints(newBendPoints); |
| newConnections.add(newConnection); |
| } |
| |
| if (index < 0) { |
| newParent.addChild(newPart); |
| } else { |
| newParent.addChild(newPart, index); |
| } |
| |
| newPart.setSize(oldPart.getSize()); |
| |
| if (newBounds != null) { |
| newPart.setLocation(newBounds.getTopLeft()); |
| } else { |
| newPart.setLocation(oldPart.getLocation()); |
| } |
| |
| // keep track of the new parts so we can delete them in undo |
| // keep track of the oldpart -> newpart map so that we can properly |
| // attach |
| // all connections. |
| if (newParent == parent) |
| newTopLevelParts.add(newPart); |
| connectionPartMap.put(oldPart, newPart); |
| } |
| |
| public void execute() { |
| connectionPartMap = new HashMap(); |
| newConnections = new LinkedList(); |
| newTopLevelParts = new LinkedList(); |
| |
| Iterator i = parts.iterator(); |
| |
| LogicSubpart part = null; |
| while (i.hasNext()) { |
| part = (LogicSubpart) i.next(); |
| if (bounds != null && bounds.containsKey(part)) { |
| clonePart(part, parent, (Rectangle) bounds.get(part), |
| newConnections, connectionPartMap, -1); |
| } else if (indices != null && indices.containsKey(part)) { |
| clonePart(part, parent, null, newConnections, |
| connectionPartMap, |
| ((Integer) indices.get(part)).intValue()); |
| } else { |
| clonePart(part, parent, null, newConnections, |
| connectionPartMap, -1); |
| } |
| } |
| |
| // go through and set the source of each connection to the proper |
| // source. |
| Iterator c = newConnections.iterator(); |
| |
| while (c.hasNext()) { |
| Wire conn = (Wire) c.next(); |
| LogicSubpart source = conn.getSource(); |
| if (connectionPartMap.containsKey(source)) { |
| conn.setSource((LogicSubpart) connectionPartMap.get(source)); |
| conn.attachSource(); |
| conn.attachTarget(); |
| } |
| } |
| |
| if (hGuide != null) { |
| hGuideCommand = new ChangeGuideCommand( |
| (LogicSubpart) connectionPartMap.get(parts.get(0)), true); |
| hGuideCommand.setNewGuide(hGuide, hAlignment); |
| hGuideCommand.execute(); |
| } |
| |
| if (vGuide != null) { |
| vGuideCommand = new ChangeGuideCommand( |
| (LogicSubpart) connectionPartMap.get(parts.get(0)), false); |
| vGuideCommand.setNewGuide(vGuide, vAlignment); |
| vGuideCommand.execute(); |
| } |
| } |
| |
| public void setParent(LogicDiagram parent) { |
| this.parent = parent; |
| } |
| |
| public void redo() { |
| for (Iterator iter = newTopLevelParts.iterator(); iter.hasNext();) |
| parent.addChild((LogicSubpart) iter.next()); |
| for (Iterator iter = newConnections.iterator(); iter.hasNext();) { |
| Wire conn = (Wire) iter.next(); |
| LogicSubpart source = conn.getSource(); |
| if (connectionPartMap.containsKey(source)) { |
| conn.setSource((LogicSubpart) connectionPartMap.get(source)); |
| conn.attachSource(); |
| conn.attachTarget(); |
| } |
| } |
| if (hGuideCommand != null) |
| hGuideCommand.redo(); |
| if (vGuideCommand != null) |
| vGuideCommand.redo(); |
| } |
| |
| public void setGuide(LogicGuide guide, int alignment, boolean isHorizontal) { |
| if (isHorizontal) { |
| hGuide = guide; |
| hAlignment = alignment; |
| } else { |
| vGuide = guide; |
| vAlignment = alignment; |
| } |
| } |
| |
| public void undo() { |
| if (hGuideCommand != null) |
| hGuideCommand.undo(); |
| if (vGuideCommand != null) |
| vGuideCommand.undo(); |
| for (Iterator iter = newTopLevelParts.iterator(); iter.hasNext();) |
| parent.removeChild((LogicSubpart) iter.next()); |
| } |
| |
| } |