modulecommandstack.java

来自「一个eclipse插件源代码。用于web开发」· Java 代码 · 共 266 行

JAVA
266
字号
/*
 * $Header: /home/cvs/WEBPUMP2.0/WebPumpIDE_Src/WebPumpIDE/src/com/webpump/ui/gefmodule/ModuleCommandStack.java,v 1.1.1.1 2004/07/01 09:07:46 wang_j Exp $
 * $Revision: 1.1.1.1 $
 * $Date: 2004/07/01 09:07:46 $
 *
 * ====================================================================
 *
 * The NanJing HopeRun(IT-FOREST) Software License, Version 2.0.0
 *
 * Copyright 2003-2004 by NanJing HopeRun(IT-FOREST) Information System Co., Ltd, CHINA and
 *                        IT Forest Corporation
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * HopeRun(IT-FOREST) Information System Co., Ltd, CHINA and IT Forest Corporation.
 * You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into with
 * HopeRun(IT-FOREST) Information System Co., Ltd, CHINA and IT Forest Corporation.
 */
package com.webpump.ui.gefmodule;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import java.util.Stack;

import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;

import com.webpump.ui.gefmodule.command.ConnectionCommand;
import com.webpump.ui.gefmodule.command.CreateCommand;

/**
 * Class for ModuleCommandStack
 * 
 * @author shi_l
 * @version 2.0.0 2004-5-30
 */
public class ModuleCommandStack extends CommandStack {

	/**undo limit*/
	private int undoLimit = 0;

	/**save location*/
	private int saveLocation = 0;

	/**stack of the undo*/
	private Stack undo = new Stack();

	/**stack of the redo*/
	private Stack redo = new Stack();

	/**
	 * the list of {@link CommandStackListener}s
	 */
	protected List listeners = new ArrayList();

	/**
	 * Constructs a command stack. By default, there is no undo limit.
	 */
	public ModuleCommandStack() {
	}

	/**
	 * Adds the specified listener. Multiple adds will result in multiple notifications.
	 * @param listener the listener
	 */
	public void addCommandStackListener(CommandStackListener listener) {
		listeners.add(listener);
	}

	/**
	 * @return <code>true</code> if it is appropriate to call {@link #redo()}.
	 */
	public boolean canRedo() {
		return !redo.isEmpty();
	}

	/**
	 * @return <code>true</code> if {@link #undo()} can be called
	 */
	public boolean canUndo() {
		if (undo.size() == 0)
			return false;
		return ((Command) undo.lastElement()).canUndo();
	}

	/**
	 * Executes the specified Command if it is executable. Flushes the redo stack.
	 * @param command the Command to execute
	 */
	public void execute(Command command) {
		if (command == null || !command.canExecute())
			return;
		flushRedo();
		if (command instanceof CreateCommand) {
			if (((CreateCommand) command).executeCreate() == false) {
				return;
			}
		} else if (
			command instanceof ConnectionCommand
				&& ((ConnectionCommand) command).getSource() != null
				&& ((ConnectionCommand) command).getTarget() != null) {
			if (((ConnectionCommand) command).executeCreate() == false) {
				return;
			}
		} else {
			command.execute();
		}
		if (getUndoLimit() > 0) {
			while (undo.size() >= getUndoLimit()) {
				undo.remove(0);
				if (saveLocation > -1)
					saveLocation--;
			}
		}
		if (saveLocation > undo.size())
			saveLocation = -1;
		//The save point was somewhere in the redo stack
		undo.push(command);
		notifyListeners();
	}

	/**
	 * This will <code>dispose()</code> all the commands in both the undo and redo stack. Both
	 * stacks will be empty afterwards.
	 */
	public void dispose() {
		flushUndo();
		flushRedo();
	}

	/**
	 * Flushes the entire stack and resets the save location to zero. This method might be
	 * called when performing "revert to saved".
	 */
	public void flush() {
		flushRedo();
		flushUndo();
		saveLocation = 0;
		notifyListeners();
	}

	private void flushRedo() {
		while (!redo.isEmpty())
			 ((Command) redo.pop()).dispose();
	}

	private void flushUndo() {
		while (!undo.isEmpty())
			 ((Command) undo.pop()).dispose();
	}

	/**
	 * @return an array containing all commands in the order they were executed
	 */
	public Object[] getCommands() {
		List commands = new ArrayList(undo);
		for (int i = redo.size() - 1; i >= 0; i--) {
			commands.add(redo.get(i));
		}
		return commands.toArray();
	}

	/**
	 * Peeks at the top of the <i>redo</i> stack. This is useful for describing to the User
	 * what will be redone. The returned <code>Command</code> has a label describing it.
	 * @return the top of the <i>redo</i> stack, which may be <code>null</code>
	 */
	public Command getRedoCommand() {
		return redo.isEmpty() ? null : (Command) redo.peek();
	}

	/**
	 * Peeks at the top of the <i>undo</i> stack. This is useful for describing to the User
	 * what will be undone. The returned <code>Command</code> has a label describing it.
	 * @return the top of the <i>undo</i> stack, which may be <code>null</code>
	 */
	public Command getUndoCommand() {
		return undo.isEmpty() ? null : (Command) undo.peek();
	}

	/**
	 * Returns the undo limit. The undo limit is the maximum number of atomic operations that
	 * the User can undo. <code>-1</code> is used to indicate no limit.
	 * @return the undo limit
	 */
	public int getUndoLimit() {
		return undoLimit;
	}

	/**
	 * Returns true if the stack is dirty. The stack is dirty whenever the last executed or
	 * redone command is different than the command that was at the top of the undo stack when
	 * {@link #markSaveLocation()} was last called. 
	 * @return <code>true</code> if the stack is dirty
	 */
	public boolean isDirty() {
		return undo.size() != saveLocation;
	}

	/**
	 * Marks the last executed or redone Command as the point at which the changes were saved.
	 * Calculation of {@link #isDirty()} will be based on this checkpoint.
	 */
	public void markSaveLocation() {
		saveLocation = undo.size();
		notifyListeners();
	}

	/**
	 * Sends notification to all {@link CommandStackListener}s.
	 */
	protected void notifyListeners() {
		EventObject event = new EventObject(this);
		for (int i = 0; i < listeners.size(); i++)
			 ((CommandStackListener) listeners.get(i)).commandStackChanged(event);
	}

	/**
	 * Calls redo on the Command at the top of the <i>redo</i> stack, and pushes that Command
	 * onto the <i>undo</i> stack. This method should only be called when {@link #canUndo()}
	 * returns <code>true</code>.
	 */
	public void redo() {
		//Assert.isTrue(canRedo())
		if (!canRedo())
			return;
		Command command = (Command) redo.pop();
		command.redo();
		undo.push(command);
		notifyListeners();
	}

	/**
	 * Removes the first occurance of the specified listener.
	 * @param listener the listener
	 */
	public void removeCommandStackListener(CommandStackListener listener) {
		listeners.remove(listener);
	}

	/**
	 * Sets the undo limit. The undo limit is the maximum number of atomic operations that the
	 * User can undo. <code>-1</code> is used to indicate no limit.
	 * @param undoLimit the undo limit
	 */
	public void setUndoLimit(int undoLimit) {
		this.undoLimit = undoLimit;
	}

	/**
	 * Undoes the most recently executed (or redone) Command. The Command is popped from the
	 * undo stack to and pushed onto the redo stack. This method should only be called when
	 * {@link #canUndo()} returns <code>true</code>.
	 */
	public void undo() {
		//Assert.isTrue(canUndo());
		Command command = (Command) undo.pop();
		command.undo();
		redo.push(command);
		notifyListeners();
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?