/******************************************************************************* * Copyright (c) 2010 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package org.eclipse.nebula.visualization.internal.xygraph.undo; import java.util.ArrayList; import java.util.List; /** * The operation manager will help to manage the undoable and redoable * operations. * * @author Xihui Chen * */ public class OperationsManager { private SizeLimitedStack<IUndoableCommand> undoStack; private SizeLimitedStack<IUndoableCommand> redoStack; private List<IOperationsManagerListener> listeners; /** * Constructor. */ public OperationsManager() { undoStack = new SizeLimitedStack<IUndoableCommand>(30); redoStack = new SizeLimitedStack<IUndoableCommand>(30); listeners = new ArrayList<IOperationsManagerListener>(); } /** * Execute a command and push it to undo stack. * * @param command * the command to be executed. */ public void addCommand(IUndoableCommand command) { undoStack.push(command); redoStack.clear(); fireOperationsHistoryChanged(); } /** * Undo the command. Restore the state of the target to the previous state * before this command has been executed. * * @param command */ public void undoCommand(IUndoableCommand command) { IUndoableCommand temp; do { temp = undoStack.pop(); temp.undo(); redoStack.push(temp); } while (temp != command); fireOperationsHistoryChanged(); } /** * Re-do the command. Restore the state of the target to the state after * this command has been executed. * * @param command */ public void redoCommand(IUndoableCommand command) { IUndoableCommand temp; do { temp = redoStack.pop(); temp.redo(); undoStack.push(temp); } while (temp != command); fireOperationsHistoryChanged(); } /** * undo the last command. Do nothing if there is no last command. */ public void undo() { if (undoStack.size() > 0) undoCommand(undoStack.peek()); } /** * redo the last undone command. Do nothing if there is no last undone * command. */ public void redo() { if (redoStack.size() > 0) redoCommand(redoStack.peek()); } /** * @return the undo commands array. The first element is the oldest commands * and the last element is the latest commands. */ public Object[] getUndoCommands() { return undoStack.toArray(); } /** * @return the redo commands array. The first element is the oldest commands * and the last element is the latest commands. */ public Object[] getRedoCommands() { return redoStack.toArray(); } public void addListener(IOperationsManagerListener listener) { listeners.add(listener); } public boolean removeListener(IOperationsManagerListener listener) { return listeners.remove(listener); } private void fireOperationsHistoryChanged() { for (IOperationsManagerListener listener : listeners) listener.operationsHistoryChanged(this); } public int getUndoCommandsSize() { return undoStack.size(); } public int getRedoCommandsSize() { return redoStack.size(); } }