]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.ui/src/org/simantics/ui/tester/UndoPropertyTester.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / tester / UndoPropertyTester.java
1 /*******************************************************************************
2  * Copyright (c) 2011 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.ui.tester;
13
14 import org.eclipse.core.expressions.PropertyTester;
15 import org.eclipse.swt.widgets.Display;
16 import org.eclipse.ui.PlatformUI;
17 import org.eclipse.ui.contexts.IContextActivation;
18 import org.eclipse.ui.contexts.IContextService;
19 import org.simantics.DatabaseJob;
20 import org.simantics.Simantics;
21 import org.simantics.db.Session;
22 import org.simantics.db.UndoContext;
23 import org.simantics.db.exception.DatabaseException;
24 import org.simantics.db.management.ISessionContext;
25 import org.simantics.db.service.UndoRedoSupport;
26 import org.simantics.ui.SimanticsUI;
27 import org.simantics.utils.ui.ErrorLogger;
28 import org.simantics.utils.ui.SWTUtils;
29
30 /**
31  * An eclipse property tester for org.simantics.db database undo/redoability.
32  * 
33  * @author Kalle Kondelin
34  */
35 public class UndoPropertyTester extends PropertyTester implements UndoRedoSupport.ChangeListener {
36
37     private static final String PROP_CAN_REDO = "canRedo";
38
39     private static final String PROP_CAN_UNDO = "canUndo";
40
41     private static final String SIMANTICS_UNDO_CONTEXT = "org.simantics.ui.undoContext";
42
43     public static final boolean DEBUG = false;
44
45     public static final String UNDO_ENABLED = "org.simantics.undo.enabled";
46     
47     UndoRedoSupport undoSupport = null;
48     IContextActivation activation = null;
49     public UndoPropertyTester() {
50         if (DEBUG)
51             System.out.println("UndoPropertyTester: " + this);
52     }
53     @Override
54     public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
55         if (DEBUG)
56             System.out.println("UndoPropertyTester: receiver=" + receiver);
57         
58         String undoEnabled = System.getProperty(UNDO_ENABLED);
59         if(undoEnabled != null && "false".equals(undoEnabled))
60             return false;
61         
62         if (property.matches(PROP_CAN_UNDO))
63             return canUndo();
64         else if (property.matches(PROP_CAN_REDO))
65             return canRedo();
66         else
67             return false;
68     }
69     private boolean canUndo() {
70         ISessionContext ctx = Simantics.getSessionContext();
71         if (ctx == null) {
72             if (DEBUG)
73                 System.out.println("UndoPropertyTester: no can do undo.");
74             return false;
75         }
76         try {
77             Session s = ctx.peekSession();
78             if (null == s) {
79                 if (DEBUG)
80                     System.out.println("UndoPropertyTester: session is null, no can do undo.");
81                 return false;
82             }
83             if (DatabaseJob.inProgress())
84                 return true;
85             if (null == undoSupport) {
86                 undoSupport = s.getService(UndoRedoSupport.class);
87                 undoSupport.subscribe(this);
88             }
89             UndoContext uc = undoSupport.getUndoContext(s);
90             if (uc == null)
91                 return false;
92             boolean ret = !uc.getAll().isEmpty();
93             if (DEBUG)
94                 System.out.println("UndoPropertyTester: " + (ret ? "" : "no ")+ "can do undo.");
95             return ret;
96         } catch (Exception e) {
97             ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);
98             if (DEBUG)
99                 System.out.println("UndoPropertyTester: no can do undo");
100             return false;
101         }
102     }
103     private boolean canRedo() {
104         ISessionContext ctx = Simantics.getSessionContext();
105         if (ctx == null) {
106             if (DEBUG)
107                 System.out.println("UndoPropertyTester: no can do redo.");
108             return false;
109         }
110         try {
111             Session s = ctx.peekSession();
112             if (null == s) {
113                 if (DEBUG)
114                     System.out.println("UndoPropertyTester: session is null, no can do redo.");
115                 return false;
116             }
117             if (DatabaseJob.inProgress())
118                 return true;
119             if (null == undoSupport) {
120                 undoSupport = s.getService(UndoRedoSupport.class);
121                 undoSupport.subscribe(this);
122             }
123             UndoContext uc = undoSupport.getUndoContext(s);
124             if (uc == null)
125                 return false;
126             boolean ret = !uc.getRedoList().isEmpty();
127             if (DEBUG)
128                 System.out.println("UndoPropertyTester: " + (ret ? "" : "no ")+ "can do redo.");
129             return ret;
130         } catch (Exception e) {
131             ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);
132             if (DEBUG)
133                 System.out.println("UndoPropertyTester: no can do redo.");
134             return false;
135         }
136     }
137     @Override
138     public void onChanged() {
139         if (DEBUG)
140             System.out.println("UndoPropertyTester: on change.");
141         Display display = PlatformUI.getWorkbench().getDisplay();
142         SWTUtils.asyncExec(display, new Runnable() {
143             @Override
144             public void run() {
145                 handleChange();
146             }
147         });
148     }
149     private int oldUndo = 0;
150     private int oldRedo = 0;
151     private void handleChange() {
152         int newUndo = oldUndo;
153         int newRedo = oldRedo;
154         try {
155             ISessionContext ctx = SimanticsUI.getSessionContext();
156             if (DEBUG)
157                 System.out.println("UndoPropertyTester: handle change, ctx=" + ctx);
158             if (ctx == null)
159                 return;
160             Session session = ctx.peekSession();
161             if (DEBUG)
162                 System.out.println("UndoPropertyTester: handle change, session=" + session);
163             if (session == null)
164                 return;
165             UndoContext uc = undoSupport.getUndoContext(session);
166             if (uc == null)
167                 return;
168             newUndo = uc.getAll().size();
169             newRedo = uc.getRedoList().size();
170             if (DEBUG) {
171                 System.out.println("on undo change: " + oldUndo + "->" + newUndo);
172                 System.out.println("on redo change: " + oldRedo + "->" + newRedo);
173             }
174             boolean undoOn = oldUndo == 0 && newUndo == 1;
175             boolean undoOff = oldUndo > 0 && newUndo == 0;
176             boolean redoOn = oldRedo == 0 && newRedo == 1;
177             boolean redoOff = oldRedo > 0 && newRedo == 0;
178             if (undoOn || undoOff || redoOn || redoOff)
179                 toggleContext();
180         } catch (DatabaseException e) {
181             ErrorLogger.getDefault().logError("Undo/Redo support failed.", e);
182         }
183         oldUndo = newUndo;
184         oldRedo = newRedo;
185     }
186     private void toggleContext() {
187         IContextService contextService = (IContextService)PlatformUI.getWorkbench().getService(IContextService.class);
188         if (null != activation) {
189             if (DEBUG)
190                 System.out.println("UndoPropertyTester: deactivate.");
191             try {
192                 contextService.deactivateContext(activation);
193             } catch (Throwable t) {
194                 ErrorLogger.getDefault().logError("Undo/Redo support failed.", t);
195             }
196             activation = null;
197             if (DEBUG)
198                 System.out.println("UndoPropertyTester: deactivated.");
199         } else {
200             if (DEBUG)
201                 System.out.println("UndoPropertyTester: activate.");
202             try {
203                 activation = contextService.activateContext(SIMANTICS_UNDO_CONTEXT);
204             } catch (Throwable t) {
205                 ErrorLogger.getDefault().logError("Undo/Redo support failed.", t);
206                 activation = null;
207             }
208             if (DEBUG)
209                 System.out.println("UndoPropertyTester: activated=" + activation);
210         }
211     }
212 }