/** * Perform the undo. All validity checks have already occurred. * * @param monitor * @param operation */ private IStatus doUndo(IProgressMonitor monitor, IAdaptable info, IUndoableOperation operation) throws ExecutionException { IStatus status = getUndoApproval(operation, info); if (status.isOK()) { notifyAboutToUndo(operation); try { status = operation.undo(monitor, info); } catch (OperationCanceledException e) { status = Status.CANCEL_STATUS; } catch (ExecutionException e) { notifyNotOK(operation); if (DEBUG_OPERATION_HISTORY_UNEXPECTED) { Tracing.printTrace( "OPERATIONHISTORY", //$NON-NLS-1$ "ExecutionException while undoing " + operation); // $NON-NLS-1$ } throw e; } catch (Exception e) { notifyNotOK(operation); if (DEBUG_OPERATION_HISTORY_UNEXPECTED) { Tracing.printTrace( "OPERATIONHISTORY", //$NON-NLS-1$ "Exception while undoing " + operation); // $NON-NLS-1$ } throw new ExecutionException( "While undoing the operation, an exception occurred", e); // $NON-NLS-1$ } } // if successful, the operation is removed from the undo history and // placed in the redo history. if (status.isOK()) { boolean addedToRedo = true; synchronized (undoRedoHistoryLock) { undoList.remove(operation); if (checkRedoLimit(operation)) { redoList.add(operation); } else { addedToRedo = false; } } // dispose the operation since we could not add it to the // stack and will no longer have a reference to it. if (!addedToRedo) { operation.dispose(); } // notification occurs after the undo and redo histories are // adjusted notifyUndone(operation); } else { notifyNotOK(operation, status); } return status; }