// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea // Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ package graphtea.plugins.commonplugin.undo; import graphtea.extensions.io.GraphSaveObject; import graphtea.graph.graph.GraphModel; import graphtea.platform.core.AbstractAction; import graphtea.platform.core.BlackBoard; import graphtea.platform.core.Listener; import graphtea.plugins.main.GraphData; import graphtea.ui.UIUtils; import java.util.HashMap; import java.util.Stack; public class UndoAction extends AbstractAction { public static final String UNDO_EVENT = UIUtils.getUIEventKey("Undo Action"); public static final String REDO_EVENT = UIUtils.getUIEventKey("Redo Action"); private HashMap<GraphModel, Stack<GraphSaveObject>> undoers = new HashMap<>(); private HashMap<GraphModel, Stack<GraphSaveObject>> redoers = new HashMap<>(); public void pushUndo(GraphModel g) { if (g == null) return; GraphSaveObject gso = new GraphSaveObject(g); redoers.put(g, new Stack<>()); //reset redo for this graph if(undoers.get(g) == null || undoers.get(g).size() == 0) { undoers.put(g, new Stack<>()); undoers.get(g).push(gso); return; } // just add the point if it is not on the top if (!gso.equals(undoers.get(g).peek())) { // System.out.println("new undo point: " + gso); undoers.get(g).push(gso); } // boolean isContained = false; // for(GraphSaveObject tmp : undoers.get(g)) { // byte[] b1 = GraphSaveObject.getBytesOfGraphSaveObject(tmp); // byte[] b2 = GraphSaveObject.getBytesOfGraphSaveObject(gso); // if (Arrays.equals(b1, b2)) { // isContained = true; // break; // } // } // if(!isContained) { // System.out.println("undo point" + gso); // undoers.get(g).push(gso); // } } public GraphSaveObject popUndo(GraphModel label) { if(undoers.get(label)== null) return null; if(undoers.get(label).size()==0) return null; GraphSaveObject temp = undoers.get(label).pop(); redoers.putIfAbsent(label, new Stack<>()); redoers.get(label).push(temp); return temp; } public GraphSaveObject popRedo(GraphModel label) { if(redoers.get(label)== null) return null; if(redoers.get(label).size()==0) return null; GraphSaveObject temp = redoers.get(label).pop(); if(undoers.get(label)!= null) undoers.get(label).push(temp); return temp; } public UndoAction(BlackBoard bb) { super(bb); listen4Event(UNDO_EVENT); listen4Event(REDO_EVENT); final GraphData gd = new GraphData(bb); bb.addListener("undo point", new Listener<GraphModel>() { public void keyChanged(String key, GraphModel value) { GraphModel g = gd.getGraph(); if (g != null) pushUndo(g); } }); } public void performAction(String eventName, Object value) { if (eventName.equals(UNDO_EVENT)) undo(); else redo(); } public void undo() { GraphData gd = new GraphData(blackboard); GraphModel cur = gd.getGraph(); // System.out.println("UNDO #: " + undoers.get(cur).size()); GraphSaveObject gso = popUndo(cur); if(gso == null) return; // System.out.println("GSO: " + gso.vs.size()); cur.clear(); gso.insertIntoGraph(cur); gd.getGraphRenderer().repaintGraph(); } public void redo() { GraphData gd = new GraphData(blackboard); GraphModel cur = gd.getGraph(); GraphSaveObject gso = popRedo(cur); if (gso == null) return; cur.clear(); gso.insertIntoGraph(cur); } public boolean trackUndos() { // System.out.println("Undo's undo track"); return false; } }