--- /dev/null
+package org.simantics.ui.workbench.handler.e4;\r
+\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.contexts.IContextActivation;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.UndoContext;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.service.UndoRedoSupport;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.SWTUtils;\r
+\r
+public class UndoRedoTester {\r
+\r
+ private static final boolean DEBUG = false;\r
+ private static final String SIMANTICS_UNDO_CONTEXT = "org.simantics.ui.undoContext";\r
+ public static final String UNDO_ENABLED = "org.simantics.undo.enabled";\r
+ \r
+ private static UndoRedoSupport undoSupport = null;\r
+ private static UndoChangeListener changeListener = new UndoChangeListener();\r
+ private static IContextActivation activation = null;\r
+ \r
+ private static class UndoChangeListener implements UndoRedoSupport.ChangeListener {\r
+\r
+ private int oldUndo = 0;\r
+ private int oldRedo = 0;\r
+ \r
+ @Override\r
+ public void onChanged() {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: on change.");\r
+ Display display = PlatformUI.getWorkbench().getDisplay();\r
+ SWTUtils.asyncExec(display, new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ handleChange();\r
+ }\r
+ });\r
+ }\r
+ \r
+ private void handleChange() {\r
+ int newUndo = oldUndo;\r
+ int newRedo = oldRedo;\r
+ try {\r
+ ISessionContext ctx = SimanticsUI.getSessionContext();\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: handle change, ctx=" + ctx);\r
+ if (ctx == null)\r
+ return;\r
+ Session session = ctx.peekSession();\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: handle change, session=" + session);\r
+ if (session == null)\r
+ return;\r
+ UndoContext uc = undoSupport.getUndoContext(session);\r
+ if (uc == null)\r
+ return;\r
+ newUndo = uc.getAll().size();\r
+ newRedo = uc.getRedoList().size();\r
+ if (DEBUG) {\r
+ System.out.println("on undo change: " + oldUndo + "->" + newUndo);\r
+ System.out.println("on redo change: " + oldRedo + "->" + newRedo);\r
+ }\r
+ boolean undoOn = oldUndo == 0 && newUndo == 1;\r
+ boolean undoOff = oldUndo > 0 && newUndo == 0;\r
+ boolean redoOn = oldRedo == 0 && newRedo == 1;\r
+ boolean redoOff = oldRedo > 0 && newRedo == 0;\r
+ if (undoOn || undoOff || redoOn || redoOff)\r
+ toggleContext();\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);\r
+ }\r
+ oldUndo = newUndo;\r
+ oldRedo = newRedo;\r
+ }\r
+ private void toggleContext() {\r
+ IContextService contextService = (IContextService)PlatformUI.getWorkbench().getService(IContextService.class);\r
+ if (null != activation) {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: deactivate.");\r
+ try {\r
+ contextService.deactivateContext(activation);\r
+ } catch (Throwable t) {\r
+ ErrorLogger.getDefault().logError("Undo/Redo support failed.", t);\r
+ }\r
+ activation = null;\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: deactivated.");\r
+ } else {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: activate.");\r
+ try {\r
+ activation = contextService.activateContext(SIMANTICS_UNDO_CONTEXT);\r
+ } catch (Throwable t) {\r
+ ErrorLogger.getDefault().logError("Undo/Redo support failed.", t);\r
+ activation = null;\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: activated=" + activation);\r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ private UndoRedoTester() {\r
+ }\r
+ \r
+ public static boolean canUndo() {\r
+ String undoEnabled = System.getProperty(UNDO_ENABLED);\r
+ if(undoEnabled != null && "false".equals(undoEnabled))\r
+ return false;\r
+ \r
+ ISessionContext ctx = Simantics.getSessionContext();\r
+ if (ctx == null) {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: no can do undo.");\r
+ return false;\r
+ }\r
+ try {\r
+ Session s = ctx.peekSession();\r
+ if (null == s) {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: session is null, no can do undo.");\r
+ return false;\r
+ }\r
+ if (DatabaseJob.inProgress())\r
+ return true;\r
+ if (null == undoSupport) {\r
+ undoSupport = s.getService(UndoRedoSupport.class);\r
+ undoSupport.subscribe(changeListener);\r
+ }\r
+ UndoContext uc = undoSupport.getUndoContext(s);\r
+ if (uc == null)\r
+ return false;\r
+ boolean ret = !uc.getAll().isEmpty();\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: " + (ret ? "" : "no ")+ "can do undo.");\r
+ return ret;\r
+ } catch (Exception e) {\r
+ ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: no can do undo");\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ public static boolean canRedo() {\r
+ ISessionContext ctx = Simantics.getSessionContext();\r
+ if (ctx == null) {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: no can do redo.");\r
+ return false;\r
+ }\r
+ try {\r
+ Session s = ctx.peekSession();\r
+ if (null == s) {\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: session is null, no can do redo.");\r
+ return false;\r
+ }\r
+ if (DatabaseJob.inProgress())\r
+ return true;\r
+ if (null == undoSupport) {\r
+ undoSupport = s.getService(UndoRedoSupport.class);\r
+ undoSupport.subscribe(changeListener);\r
+ }\r
+ UndoContext uc = undoSupport.getUndoContext(s);\r
+ if (uc == null)\r
+ return false;\r
+ boolean ret = !uc.getRedoList().isEmpty();\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: " + (ret ? "" : "no ")+ "can do redo.");\r
+ return ret;\r
+ } catch (Exception e) {\r
+ ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);\r
+ if (DEBUG)\r
+ System.out.println("UndoPropertyTester: no can do redo.");\r
+ return false;\r
+ }\r
+ }\r
+\r
+}\r