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