/*******************************************************************************
* 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();
}
}