blob: d823872753ead3cea85c5bf3bd6ab12e47ce2282 [file] [log] [blame]
/*******************************************************************************
* 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());
}
}