123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- package ui.controller;
- import classes.*;
- import com.google.gson.*;
- import ui.controller.SaveController.EDGETYPE;
- import ui.controller.SaveController.GRAPHTYPE;
- import ui.controller.SaveController.NUMTYPE;
- import ui.controller.SaveController.TYPE;
- import ui.model.Model;
- import java.awt.*;
- import java.awt.datatransfer.*;
- import java.awt.geom.Point2D;
- import java.io.IOException;
- import java.util.*;
- import java.util.List;
- import java.util.stream.Collectors;
- public class ClipboardController {
- private Model model;
- private SaveController store;
- private LoadController load;
- private CanvasController cvsC;
- private ObjectController objC;
- private NodeController uppC;
- private JsonParser parser;
- private Clipboard clipboard;
- private HashMap<Integer, Integer> objIDMap;
- private HashMap<Integer, Integer> eleIDMap;
- private String sav;
- private Point point;
- ClipboardController(Model model, SaveController store, LoadController load, CanvasController cvs,
- ObjectController obj, NodeController uppC, MultiPurposeController mp) {
- this.model = model;
- this.store = store;
- this.load = load;
- this.cvsC = cvs;
- this.objC = obj;
- this.uppC = uppC;
- this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- parser = new JsonParser();
- }
- /**
- * Copy marked Objects into Clipboard in Json Format
- */
- public void copy(CpsUpperNode upperNode) {
- JsonObject file = new JsonObject();
- ArrayDeque<AbstractCpsObject> queue = new ArrayDeque<>();
- AbstractCpsObject u = null;
- store.initNumeration();
- file.add("SAV", new JsonPrimitive((upperNode == null ? "CVS" : "" + upperNode.getId())));
- Position pos = uppC.calculatePos(model.getSelectedCpsObjects());
- file.add("CENTER", model.getGson().toJsonTree(pos, Position.class));
- for (AbstractCpsObject abs : model.getSelectedCpsObjects()) {
- queue.add(abs);
- }
- System.out.println("heiCopy");
- while (!queue.isEmpty()) {
- u = queue.pop();
- String key = "CVSOBJECT" + store.getNumerator(NUMTYPE.OBJECT);
- file.add(key, model.getGson().toJsonTree(u, AbstractCpsObject.class));
- edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), u.getConnections());
- if (u instanceof HolonObject)
- store.elementsToJson(TYPE.CANVAS, file, u);
- if (u instanceof HolonSwitch)
- if (((HolonSwitch) u).getGraphPoints().size() != 0)
- store.unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
- if (u instanceof CpsUpperNode) {
- for (AbstractCpsObject adjacent : ((CpsUpperNode) u).getNodes()) {
- queue.add(adjacent);
- }
- edgeToJson(EDGETYPE.NODE, file, u.getId(), ((CpsUpperNode) u).getNodeEdges());
- edgeToJson(EDGETYPE.OLD, file, u.getId(), ((CpsUpperNode) u).getOldEdges());
- }
- }
- if (upperNode == null)
- edgeToJson(EDGETYPE.LAYER, file, 0, model.getEdgesOnCanvas());
- else
- edgeToJson(EDGETYPE.LAYER, file, upperNode.getId(), upperNode.getNodeEdges());
- StringSelection selection = new StringSelection(model.getGson().toJson(file));
- clipboard.setContents(selection, selection);
- }
- /**
- * Paste the Copied JsonTree into Canvas
- */
- void paste(CpsUpperNode upperNode, Point p)
- throws UnsupportedFlavorException, IOException, JsonParseException {
- if (p == null)
- return;
- JsonObject json;
- Transferable content = clipboard.getContents(null);
- if (content != null && content.isDataFlavorSupported(DataFlavor.stringFlavor)
- && !content.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) {
- String str = (String) content.getTransferData(DataFlavor.stringFlavor);
- if (parser.parse(str).isJsonObject())
- json = (JsonObject) parser.parse(str);
- else
- throw new JsonParseException("Unknown Clipboard Information");
- } else
- return;
- List<String> keys = load.getKeys(json);
- List<String> edges = keys.stream().filter(key -> key.contains("EDGE"))
- .collect(Collectors.toCollection(ArrayList::new));
- HashMap<Integer, AbstractCpsObject> objDispatch = new HashMap<>();
- HashMap<Integer, HolonElement> eleDispatch = new HashMap<>();
- model.getSelectedCpsObjects().clear();
- objIDMap = new HashMap<>();
- eleIDMap = new HashMap<>();
- sav = json.get("SAV").getAsString();
- Position old = model.getGson().getAdapter(Position.class).fromJsonTree(json.get("CENTER"));
- point = new Point(old.x - p.x, old.y - p.y);
- forwardObjects(keys, json, objDispatch, eleDispatch, upperNode);
- // for selecting Cps
- getObjectsInDepth();
- forwardEdges(edges, json, objDispatch, upperNode);
- }
- /**
- * Cuts the marked Objects out of Canvas and saves them into the Clipboard
- */
- void cut(CpsUpperNode upperNode) {
- copy(upperNode);
- for (AbstractCpsObject abs : model.getSelectedCpsObjects()) {
- if (upperNode == null)
- cvsC.deleteObjectOnCanvas(abs);
- else
- uppC.deleteObjectInUpperNode(abs, upperNode);
- if (abs instanceof CpsUpperNode)
- cvsC.bfsNodeCleaner((CpsUpperNode) abs);
- }
- }
- private void forwardEdges(List<String> keys, JsonObject json, HashMap<Integer, AbstractCpsObject> objDispatch,
- CpsUpperNode upperNode) {
- List<String> conn = new ArrayList<>();
- for (String edge : keys) {
- if (edge.contains("LAYEREDGE"))
- loadEdge(EDGETYPE.LAYER, json.get(edge), objDispatch, upperNode);
- if (edge.contains("CONNEDGE"))
- conn.add(edge);
- if (edge.contains("NODEEDGE"))
- loadEdge(EDGETYPE.NODE, json.get(edge), objDispatch, null);
- if (edge.contains("OLDEDGE"))
- loadEdge(EDGETYPE.OLD, json.get(edge), objDispatch, null);
- }
- for (String edge : conn) {
- loadEdge(EDGETYPE.CONNECTION, json.get(edge), objDispatch, null);
- }
- }
- private void forwardObjects(List<String> keys, JsonObject json, HashMap<Integer, AbstractCpsObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch, CpsUpperNode upperNode) {
- for (String key : keys) {
- if (key.contains("CVSOBJECT"))
- loadCanvasObject(json.get(key), objDispatch, upperNode);
- if (key.contains("CVSELEMENT"))
- loadCanvasElements(json.get(key), objDispatch, eleDispatch);
- if (key.contains("SWUNITGRAPH"))
- loadUnitGraph(GRAPHTYPE.SWITCH, json.get(key), objDispatch, null);
- if (key.contains("ELEUNITGRAPH"))
- loadUnitGraph(GRAPHTYPE.ELEMENT, json.get(key), null, eleDispatch);
- if (key.contains("ELETESTUNITGRAPH"))
- loadUnitGraph(GRAPHTYPE.TESTELEMENT, json.get(key), null, eleDispatch);
- }
- }
- private void loadCanvasObject(JsonElement jsonElement, HashMap<Integer, AbstractCpsObject> objDispatch,
- CpsUpperNode upperNode) {
- AbstractCpsObject temp = model.getGson().fromJson(jsonElement.getAsJsonObject(), AbstractCpsObject.class);
- load.initObjects(temp);
- objIDMapper(temp);
- updatePosition(temp, upperNode);
- // if its stored before on the canvas just put it there
- if (temp.getSav().equals(sav)) {
- if (upperNode == null)
- cvsC.addObject(temp, false);
- else
- uppC.addObjectInUpperNode(temp, upperNode, false);
- // mark the Pasted Objects
- model.getSelectedCpsObjects().add(temp);
- } else {
- // else look up the table and put it into the right Uppernode
- CpsUpperNode temp2 = (CpsUpperNode) objDispatch.get(objIDMap.get(Integer.parseInt(temp.getSav())));
- if(temp2!=null)
- uppC.addObjectInUpperNode(temp, temp2, false);
- else{
- /**
- * if corresponding Uppernode doesn't exist:
- * Add it to the current Canvas/UpperNode
- */
- if (upperNode == null)
- cvsC.addObject(temp, false);
- else
- uppC.addObjectInUpperNode(temp, upperNode, false);
- }
- }
- objDispatch.put(temp.getId(), temp);
- }
- private void loadCanvasElements(JsonElement jsonElement, HashMap<Integer, AbstractCpsObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch) {
- JsonObject object = jsonElement.getAsJsonObject();
- HolonElement temp = model.getGson().fromJson(object.get("properties"), HolonElement.class);
- load.initElements(temp);
- eleIDMapper(temp);
- // id which Object it was stored before
- int stored = objIDMap.get(object.get("ID").getAsInt());
- // lookup that object
- HolonObject temp2 = (HolonObject) objDispatch.get(stored);
- // add it
- objC.addElement(temp2, temp);
- // store element also inside a table
- eleDispatch.put(temp.getId(), temp);
- }
- private void loadUnitGraph(GRAPHTYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCpsObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch) {
- JsonObject object = jsonElement.getAsJsonObject();
- List<String> keys = load.getKeys(object);
- String p;
- int mid, x, y;
- System.out.println("loadcontroller");
- LinkedList<Point> graphpoint = new LinkedList<>();
- int sav = 0;
- // foreach Point in the graph restore it
- for (String k : keys) {
- if (!k.equals("ID")) {
- p = object.get(k).getAsString();
- mid = p.indexOf(':');
- x = Integer.parseInt(p.substring(0, mid));
- y = Integer.parseInt(p.substring(mid + 1, p.length()));
- graphpoint.add(new Point(x, y));
- } else
- // else its an ID
- sav = object.get(k).getAsInt();
- }
- switch (type) {
- case SWITCH:
- sav = objIDMap.get(sav);
- HolonSwitch sw = (HolonSwitch) objDispatch.get(sav);
- sw.setGraphPoints(graphpoint);
- break;
- case ELEMENT:
- sav = eleIDMap.get(sav);
- HolonElement ele = eleDispatch.get(sav);
- ele.setGraphPoints(graphpoint);
- break;
- case TESTELEMENT:
- LinkedList<Point2D.Double> graphpointTEST = new LinkedList<>();
- for (String k : keys) {
- if (!k.equals("ID")) {
- p = object.get(k).getAsString();
- mid = p.indexOf(':');
- double x1 = Double.parseDouble(p.substring(0, mid));
- double y1 = Integer.parseInt(p.substring(mid + 1, p.length()));
- graphpointTEST.add(new Point2D.Double(x1, y1));
- } else
- // else its an ID
- sav = object.get(k).getAsInt();
- }
-
- sav = eleIDMap.get(sav);
- HolonElement ele1 = eleDispatch.get(sav);
- ele1.setTestGraphPoints(graphpointTEST);
- break;
- default:
- break;
- }
- }
- /**
- * loads an edge from json
- */
- private void loadEdge(EDGETYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCpsObject> objDispatch,
- CpsUpperNode upperNode) {
- JsonObject object = jsonElement.getAsJsonObject();
- CpsEdge temp = model.getGson().fromJson(object.get("properties"), CpsEdge.class);
- load.initCpsEdge(temp);
- // look for A and B inside the Table
- temp.setA(objDispatch.get(objIDMap.get(object.get("A").getAsInt())));
- temp.setB(objDispatch.get(objIDMap.get(object.get("B").getAsInt())));
- int sav;
- switch (type) {
- case LAYER:
- // if in canvas add it into the canvas but delete connection before
- (upperNode == null ? model.getEdgesOnCanvas() : upperNode.getNodeEdges()).add(temp);
- break;
- case CONNECTION:
- // if no duplicates in connection store them into the given A and B
- if (!uppC.lookforDuplicates(temp.getA(), temp.getB(), temp.getA().getConnections()))
- temp.getA().getConnections().add(temp);
- if (!uppC.lookforDuplicates(temp.getA(), temp.getB(), temp.getB().getConnections()))
- temp.getB().getConnections().add(temp);
- break;
- case NODE:
- // put it into given nodeofnode
- sav = objIDMap.get(object.get("ID").getAsInt());
- ((CpsUpperNode) objDispatch.get(sav)).getNodeEdges().add(temp);
- break;
- case OLD:
- // same as above
- sav = objIDMap.get(object.get("ID").getAsInt());
- ((CpsUpperNode) objDispatch.get(sav)).getOldEdges().add(temp);
- break;
- default:
- break;
- }
- if (object.get("connection").getAsBoolean() && !type.equals(EDGETYPE.CONNECTION)) {
- temp.getA().getConnections().add(temp);
- temp.getB().getConnections().add(temp);
- }
- }
- /**
- * Modified Method from LoadController. Slightly different
- */
- private void edgeToJson(EDGETYPE type, JsonObject file, int id, ArrayList<CpsEdge> arr) {
- String k = null;
- boolean b = false;
- JsonObject temp = new JsonObject();
- for (CpsEdge edge : arr) {
- if (model.getClipboradObjects().contains(edge.getA())
- && model.getClipboradObjects().contains(edge.getB())) {
- // add properties and only the ids from a and b
- temp.add("properties", model.getGson().toJsonTree(edge));
- temp.add("A", new JsonPrimitive(edge.getA().getId()));
- temp.add("B", new JsonPrimitive(edge.getB().getId()));
- // Key and occasionally the id of Uppernode
- switch (type) {
- case LAYER:
- temp.add("ID", new JsonPrimitive(id));
- k = "LAYEREDGE" + store.getNumerator(NUMTYPE.EDGE);
- break;
- case CONNECTION:
- k = "CONNEDGE" + store.getNumerator(NUMTYPE.CONNECTION);
- break;
- case NODE:
- temp.add("ID", new JsonPrimitive(id));
- k = "NODEEDGE" + store.getNumerator(NUMTYPE.NODEEDGE);
- break;
- case OLD:
- temp.add("ID", new JsonPrimitive(id));
- k = "OLDEDGE" + store.getNumerator(NUMTYPE.OLDEDGE);
- break;
- default:
- break;
- }
- // lookup if the CVS, NODE or OLDEDGE are also connections
- if (edge.getA().getConnections().contains(edge) && edge.getA().getConnections().contains(edge)
- && !type.equals(EDGETYPE.CONNECTION))
- b = true;
- temp.add("connection", new JsonPrimitive(b));
- file.add(k, model.getGson().toJsonTree(temp));
- temp = new JsonObject();
- }
- }
- }
- /**
- * Adds all Objects in Depth into Clipboardobjects preemptive when objects are selected
- */
- void getObjectsInDepth() {
- model.setClipboradObjects(new ArrayList<>());
- for (AbstractCpsObject obj : model.getSelectedCpsObjects()) {
- clipboadDepth(obj);
- }
- }
- /**
- * Get all Objects inside the Currentobject and add them into ClipboardObjects
- */
- private void clipboadDepth(AbstractCpsObject obj) {
- //modified backtracking Algorithm no True/False
- if (!(obj instanceof CpsUpperNode)) {
- model.getClipboradObjects().add(obj);
- } else {
- model.getClipboradObjects().add(obj);
- for (AbstractCpsObject abs : ((CpsUpperNode) obj).getNodes()) {
- clipboadDepth(abs);
- }
- }
- }
- /**
- * Map the Copied Object ID into a new One
- */
- private void objIDMapper(AbstractCpsObject temp) {
- int id = temp.getId();
- temp.setId(IdCounter.nextId());
- // oldID -> currentID
- objIDMap.put(id, temp.getId());
- }
- /**
- * Map the Copied Element ID into a new One
- */
- private void eleIDMapper(HolonElement temp) {
- int id = temp.getId();
- temp.setId(IdCounterElem.nextId());
- // oldID -> currentID
- eleIDMap.put(id, temp.getId());
- }
- private void updatePosition(AbstractCpsObject temp, CpsUpperNode upperNode) {
- int x = temp.getPosition().x - point.x;
- int y = temp.getPosition().y - point.y;
- if (y < 0)
- y = 0 + model.getScaleDiv2() + 1;
- if (upperNode != null) {
- if (x < upperNode.getLeftBorder() + model.getScaleDiv2() + 1)
- x = upperNode.getLeftBorder() + model.getScaleDiv2() + 1;
- } else if (x < 0)
- x = 0 + model.getScaleDiv2() + 1;
- if (x > model.getCanvasX())
- x = model.getCanvasX() - model.getScaleDiv2() - 1;
- if (y > model.getCanvasX())
- y = model.getCanvasY() - model.getScaleDiv2() - 1;
- temp.setPosition(new Position(x, y));
- }
- }
|