123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- package holeg.ui.controller;
- import com.google.gson.*;
- import holeg.model.*;
- import holeg.ui.controller.SaveController.EDGETYPE;
- import holeg.ui.controller.SaveController.GRAPHTYPE;
- import holeg.ui.controller.SaveController.NUMTYPE;
- import holeg.ui.controller.SaveController.TYPE;
- import holeg.ui.model.GuiSettings;
- import holeg.ui.model.Model;
- import holeg.utility.math.vector.Vec2f;
- import holeg.utility.math.vector.Vec2i;
- import java.awt.*;
- import java.awt.datatransfer.*;
- 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 NodeController uppC;
- private Clipboard clipboard;
- private HashMap<Integer, Integer> objIDMap;
- private HashMap<Integer, Integer> eleIDMap;
- private String sav;
- private Point point;
- private SimulationManager simManager;
- ClipboardController(Model model, SaveController store, LoadController load, CanvasController cvs,
- NodeController uppC, SimulationManager simManager) {
- this.model = model;
- this.store = store;
- this.load = load;
- this.cvsC = cvs;
- this.uppC = uppC;
- this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- this.simManager = simManager;
- }
- /**
- * Copy marked Objects into Clipboard in Json Format
- */
- public void copy(GroupNode upperNode) {
- JsonObject file = new JsonObject();
- ArrayDeque<AbstractCanvasObject> queue = new ArrayDeque<>();
- AbstractCanvasObject u = null;
- store.initNumeration();
- file.add("SAV", new JsonPrimitive((upperNode == null ? "CVS" : "" + upperNode.getId())));
- Vec2i pos = uppC.calculatePos(GuiSettings.getSelectedObjects());
- file.add("CENTER", GuiSettings.gson.toJsonTree(pos, Vec2i.class));
- for (AbstractCanvasObject abs : GuiSettings.getSelectedObjects()) {
- queue.add(abs);
- }
- while (!queue.isEmpty()) {
- u = queue.pop();
- String key = "CVSOBJECT" + store.getNumerator(NUMTYPE.OBJECT);
- file.add(key, GuiSettings.gson.toJsonTree(u, AbstractCanvasObject.class));
- edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new ArrayList<>());
- if (u instanceof HolonObject)
- store.elementsToJson(TYPE.CANVAS, file, u);
- if (u instanceof HolonSwitch sw)
- if (sw.getGraphPoints().size() != 0)
- store.unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
- if (u instanceof GroupNode groupnode) {
- for (AbstractCanvasObject adjacent : groupnode.getObjectsInThisLayer().toList()) {
- queue.add(adjacent);
- }
- }
- }
- if (upperNode == null)
- edgeToJson(EDGETYPE.LAYER, file, 0, model.getEdgesOnCanvas());
- StringSelection selection = new StringSelection(GuiSettings.gson.toJson(file));
- clipboard.setContents(selection, selection);
- }
- /**
- * Paste the Copied JsonTree into Canvas
- */
- void paste(GroupNode 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 (JsonParser.parseString(str).isJsonObject())
- json = (JsonObject) JsonParser.parseString(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, AbstractCanvasObject> objDispatch = new HashMap<>();
- HashMap<Integer, HolonElement> eleDispatch = new HashMap<>();
- GuiSettings.getSelectedObjects().clear();
- objIDMap = new HashMap<>();
- eleIDMap = new HashMap<>();
- sav = json.get("SAV").getAsString();
- Vec2i old = GuiSettings.gson.getAdapter(Vec2i.class).fromJsonTree(json.get("CENTER"));
- point = new Point(old.getX() - p.x, old.getY() - p.y);
- forwardObjects(keys, json, objDispatch, eleDispatch, upperNode);
- // for selecting Cps
- getObjectsInDepth();
- forwardEdges(edges, json, objDispatch, upperNode);
- this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
- }
- /**
- * Cuts the marked Objects out of Canvas and saves them into the Clipboard
- */
- void cut(GroupNode upperNode) {
- copy(upperNode);
- for (AbstractCanvasObject abs : GuiSettings.getSelectedObjects()) {
- if (upperNode == null)
- cvsC.deleteObjectOnCanvas(abs);
- else
- uppC.deleteObjectInGroupNode(abs, upperNode);
- if (abs instanceof GroupNode groupnode)
- cvsC.deleteAllObjectsInGroupNode(groupnode);
- }
- GuiSettings.getSelectedObjects().clear();
- this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
- }
- private void forwardEdges(List<String> keys, JsonObject json, HashMap<Integer, AbstractCanvasObject> objDispatch,
- GroupNode 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, AbstractCanvasObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch, GroupNode 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, AbstractCanvasObject> objDispatch,
- GroupNode upperNode) {
- AbstractCanvasObject temp = GuiSettings.gson.fromJson(jsonElement.getAsJsonObject(), AbstractCanvasObject.class);
- temp.initForReflection();
- objIDMapper(temp);
- updatePosition(temp, upperNode);
- // if its stored before on the canvas just put it there
- if (upperNode == null)
- cvsC.addObject(temp, false);
- else
- uppC.addObjectInGroupNode(temp, upperNode, false);
- // mark the Pasted Objects
- GuiSettings.getSelectedObjects().add(temp);
- objDispatch.put(temp.getId(), temp);
- }
- private void loadCanvasElements(JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch) {
- JsonObject object = jsonElement.getAsJsonObject();
- HolonElement ele = GuiSettings.gson.fromJson(object.get("properties"), HolonElement.class);
- load.initElements(ele);
- eleIDMapper(ele);
- // id which Object it was stored before
- int stored = objIDMap.get(object.get("ID").getAsInt());
- // lookup that object
- HolonObject obj = (HolonObject) objDispatch.get(stored);
- // add it
- obj.add(ele);
- // store element also inside a table
- eleDispatch.put(ele.getId(), ele);
- }
- private void loadUnitGraph(GRAPHTYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
- HashMap<Integer, HolonElement> eleDispatch) {
- JsonObject object = jsonElement.getAsJsonObject();
- List<String> keys = load.getKeys(object);
- String p;
- int mid;
- int sav = 0;
- LinkedList<Vec2f> graphpointTEST = new LinkedList<>();
- for (String k : keys) {
- if (!k.equals("ID")) {
- p = object.get(k).getAsString();
- mid = p.indexOf(':');
- float x1 = Float.parseFloat(p.substring(0, mid));
- float y1 = Float.parseFloat(p.substring(mid + 1, p.length()));
- graphpointTEST.add(new Vec2f(x1, y1));
- } 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(graphpointTEST);
- sw.sampleGraph();
- break;
- case ELEMENT:
- break;
- case TESTELEMENT:
- sav = eleIDMap.get(sav);
- HolonElement ele1 = eleDispatch.get(sav);
- ele1.setGraphPoints(graphpointTEST);
- ele1.sampleGraph();
- break;
- default:
- break;
- }
- }
- /**
- * loads an edge from json
- */
- private void loadEdge(EDGETYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
- GroupNode upperNode) {
- JsonObject object = jsonElement.getAsJsonObject();
- Edge temp = GuiSettings.gson.fromJson(object.get("properties"), Edge.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())));
- switch (type) {
- case LAYER:
- // if in canvas add it into the canvas but delete connection before
- model.getEdgesOnCanvas().add(temp);
- break;
- case CONNECTION:
- break;
- default:
- break;
- }
- }
- /**
- * Modified Method from LoadController. Slightly different
- */
- private void edgeToJson(EDGETYPE type, JsonObject file, int id, List<Edge> arr) {
- String k = null;
- boolean b = false;
- JsonObject temp = new JsonObject();
- for (Edge edge : arr) {
- if (GuiSettings.getClipboardObjects().contains(edge.getA())
- && GuiSettings.getClipboardObjects().contains(edge.getB())) {
- // add properties and only the ids from a and b
- temp.add("properties", GuiSettings.gson.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;
- }
- temp.add("connection", new JsonPrimitive(b));
- file.add(k, GuiSettings.gson.toJsonTree(temp));
- temp = new JsonObject();
- }
- }
- }
- /**
- * Adds all Objects in Depth into Clipboardobjects preemptive when objects are selected
- */
- void getObjectsInDepth() {
- GuiSettings.getClipboardObjects().clear();
- for (AbstractCanvasObject obj : GuiSettings.getSelectedObjects()) {
- GuiSettings.getClipboardObjects().add(obj);
- if (obj instanceof GroupNode groupnode) {
- groupnode.getAllObjectsRecursive().forEach(object -> GuiSettings.getClipboardObjects().add(object));
- }
- }
- }
- /**
- * Map the Copied Object ID into a new One
- */
- private void objIDMapper(AbstractCanvasObject temp) {
- int id = temp.getId();
- // 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();
- // oldID -> currentID
- eleIDMap.put(id, temp.getId());
- }
- private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) {
- int x = temp.getPosition().getX() - point.x;
- int y = temp.getPosition().getY() - point.y;
- if (y < 0)
- y = 0 + GuiSettings.getPictureScaleDiv2() + 1;
- if (upperNode != null) {
- if (x < GuiSettings.getPictureScaleDiv2() + 1)
- x = GuiSettings.getPictureScaleDiv2() + 1;
- } else if (x < 0)
- x = 0 + GuiSettings.getPictureScaleDiv2() + 1;
- if (x > GuiSettings.canvasSize.getX())
- x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1;
- if (y > GuiSettings.canvasSize.getY())
- y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1;
- temp.setPosition(new Vec2i(x, y));
- }
- }
|