1 11 12 package org.eclipse.ui.internal.ide.undo; 13 14 import org.eclipse.core.commands.ExecutionException; 15 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation; 16 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation2; 17 import org.eclipse.core.commands.operations.IOperationHistory; 18 import org.eclipse.core.commands.operations.IOperationHistoryListener; 19 import org.eclipse.core.commands.operations.IUndoableOperation; 20 import org.eclipse.core.commands.operations.OperationHistoryEvent; 21 import org.eclipse.core.resources.IResourceChangeEvent; 22 import org.eclipse.core.resources.IResourceChangeListener; 23 import org.eclipse.core.resources.ResourcesPlugin; 24 import org.eclipse.core.runtime.IStatus; 25 import org.eclipse.core.runtime.Status; 26 import org.eclipse.ui.PlatformUI; 27 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; 28 import org.eclipse.ui.internal.ide.Policy; 29 30 39 public class WorkspaceUndoMonitor { 40 41 44 private static WorkspaceUndoMonitor instance; 45 46 49 private static int CHANGE_THRESHHOLD = 10; 50 51 54 private static String DEBUG_PREFIX = "Workspace Undo Monitor: "; 56 61 public static WorkspaceUndoMonitor getInstance() { 62 if (instance == null) { 63 instance = new WorkspaceUndoMonitor(); 64 } 65 return instance; 66 } 67 68 72 private int numChanges = 0; 73 74 78 private IUndoableOperation operationInProgress = null; 79 80 84 private IResourceChangeListener resourceListener; 85 86 90 private IOperationHistoryListener historyListener; 91 92 95 private WorkspaceUndoMonitor() { 96 if (Policy.DEBUG_UNDOMONITOR) { 97 System.out.println(DEBUG_PREFIX + "Installing listeners"); } 99 resourceListener = getResourceChangeListener(); 100 ResourcesPlugin.getWorkspace().addResourceChangeListener( 101 resourceListener); 102 103 historyListener = getOperationHistoryListener(); 104 getOperationHistory().addOperationHistoryListener(historyListener); 105 106 } 107 108 113 private IResourceChangeListener getResourceChangeListener() { 114 return new IResourceChangeListener() { 115 120 public void resourceChanged(IResourceChangeEvent event) { 121 if (operationInProgress != null) { 124 return; 125 } 126 if (event.getType() == IResourceChangeEvent.POST_CHANGE 127 || event.getType() == IResourceChangeEvent.POST_BUILD) { 128 incrementChangeCount(); 131 if (numChanges >= CHANGE_THRESHHOLD) { 132 checkOperationHistory(); 133 } 134 } 135 } 136 }; 137 } 138 139 144 private IOperationHistoryListener getOperationHistoryListener() { 145 return new IOperationHistoryListener() { 146 147 152 public void historyNotification(OperationHistoryEvent event) { 153 if (!event.getOperation().hasContext( 156 WorkspaceUndoUtil.getWorkspaceUndoContext())) { 157 return; 158 } 159 switch (event.getEventType()) { 160 case OperationHistoryEvent.ABOUT_TO_EXECUTE: 161 case OperationHistoryEvent.ABOUT_TO_UNDO: 162 case OperationHistoryEvent.ABOUT_TO_REDO: 163 operationInProgress = event.getOperation(); 164 break; 165 case OperationHistoryEvent.DONE: 166 case OperationHistoryEvent.UNDONE: 167 case OperationHistoryEvent.REDONE: 168 resetChangeCount(); 169 operationInProgress = null; 170 break; 171 case OperationHistoryEvent.OPERATION_NOT_OK: 172 operationInProgress = null; 173 break; 174 } 175 } 176 177 }; 178 } 179 180 183 public void shutdown() { 184 if (Policy.DEBUG_UNDOMONITOR) { 185 System.out.println(DEBUG_PREFIX + "Shutting Down"); } 187 188 if (resourceListener != null) { 189 ResourcesPlugin.getWorkspace().removeResourceChangeListener( 190 resourceListener); 191 } 192 if (historyListener != null) { 193 getOperationHistory().removeOperationHistoryListener( 194 historyListener); 195 } 196 } 197 198 201 private IOperationHistory getOperationHistory() { 202 return PlatformUI.getWorkbench().getOperationSupport() 203 .getOperationHistory(); 204 } 205 206 209 private void checkOperationHistory() { 210 if (Policy.DEBUG_UNDOMONITOR) { 211 System.out.println(DEBUG_PREFIX + "Checking Operation History..."); } 213 IUndoableOperation currentOp = getOperationHistory().getUndoOperation( 214 WorkspaceUndoUtil.getWorkspaceUndoContext()); 215 if (currentOp == null) { 217 resetChangeCount(); 218 return; 219 } 220 if (!currentOp.canUndo()) { 222 flushWorkspaceHistory(currentOp); 223 return; 224 } 225 if (currentOp instanceof IAdvancedUndoableOperation 230 && currentOp instanceof IAdvancedUndoableOperation2) { 231 ((IAdvancedUndoableOperation2) currentOp).setQuietCompute(true); 232 IStatus status; 233 try { 234 status = ((IAdvancedUndoableOperation) currentOp) 235 .computeUndoableStatus(null); 236 } catch (ExecutionException e) { 237 status = Status.OK_STATUS; 243 } 244 ((IAdvancedUndoableOperation2) currentOp).setQuietCompute(false); 245 if (status.getSeverity() == IStatus.ERROR) { 246 flushWorkspaceHistory(currentOp); 247 } 248 } 249 resetChangeCount(); 250 } 251 252 255 private void flushWorkspaceHistory(IUndoableOperation op) { 256 if (Policy.DEBUG_UNDOMONITOR) { 257 System.out.println(DEBUG_PREFIX 258 + "Flushing undo history due to " + op); } 260 getOperationHistory().dispose( 261 WorkspaceUndoUtil.getWorkspaceUndoContext(), true, true, false); 262 } 263 264 267 private void resetChangeCount() { 268 numChanges = 0; 269 if (Policy.DEBUG_UNDOMONITOR) { 270 System.out.println(DEBUG_PREFIX + "Resetting change count to 0"); } 272 } 273 274 277 private void incrementChangeCount() { 278 numChanges++; 279 if (Policy.DEBUG_UNDOMONITOR) { 280 System.out 281 .println(DEBUG_PREFIX 282 + "Incrementing workspace change count. Count = " + numChanges); } 284 } 285 } 286 | Popular Tags |