/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.gef.command; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.IFigure; import org.xmind.gef.Disposable; /** * @author Brian Sun */ public abstract class CommandStackBase extends Disposable implements ICommandStack { public static int DEFAULT_UNDO_LIMIT = 20; private List<ICommandStackListener> commandStackListeners = null; private List<ICommandStackListener> pendingCommandStackListeners = null; private List<ICommandStackListener> toBeRemovedCommandStackListeners = null; private boolean inTransaction = false; private int undoLimit; /** * @param undoLimit */ public CommandStackBase(int undoLimit) { this.undoLimit = undoLimit; } /** * */ public CommandStackBase() { this(DEFAULT_UNDO_LIMIT); } /** * @see org.xmind.gef.command.ICommandStack#addCSListener(org.xmind.gef.command.ICommandStackListener) */ public void addCSListener(ICommandStackListener listener) { if (inTransaction) { if (pendingCommandStackListeners == null) { pendingCommandStackListeners = new ArrayList<ICommandStackListener>(); } pendingCommandStackListeners.add(listener); } else { if (commandStackListeners == null) commandStackListeners = new ArrayList<ICommandStackListener>(); commandStackListeners.add(listener); } } /** * @see org.xmind.gef.command.ICommandStack#removeCSListener(org.xmind.gef.command.ICommandStackListener) */ public void removeCSListener(ICommandStackListener listener) { if (inTransaction) { if (toBeRemovedCommandStackListeners == null) toBeRemovedCommandStackListeners = new ArrayList<ICommandStackListener>(); toBeRemovedCommandStackListeners.add(listener); } else { if (commandStackListeners != null) { commandStackListeners.remove(listener); } } } protected void beginTransaction() { inTransaction = true; } protected void endTransaction(Command command, int preStatus) { inTransaction = false; if (pendingCommandStackListeners != null && commandStackListeners != null) { commandStackListeners.addAll(pendingCommandStackListeners); } if (toBeRemovedCommandStackListeners != null) { for (ICommandStackListener toBeRemovedListener : toBeRemovedCommandStackListeners) { if (commandStackListeners != null) commandStackListeners.remove(toBeRemovedListener); if (pendingCommandStackListeners != null) pendingCommandStackListeners.remove(toBeRemovedListener); } toBeRemovedCommandStackListeners.clear(); toBeRemovedCommandStackListeners = null; } if (pendingCommandStackListeners != null) { fireEvent(command, preStatus, pendingCommandStackListeners); pendingCommandStackListeners.clear(); pendingCommandStackListeners = null; } } private void fireEvent(Command command, int preStatus, List<ICommandStackListener> pendingCommandStackListeners) { for (Object listener : pendingCommandStackListeners.toArray()) { ((ICommandStackListener) listener).handleCommandStackEvent( new CommandStackEvent(this, command, preStatus)); } } protected void fireEvent(int status) { if (commandStackListeners == null) return; fireEvent(new CommandStackEvent(this, status)); } protected void fireEvent(Command cmd, int status) { if (commandStackListeners == null) return; fireEvent(new CommandStackEvent(this, cmd, status)); } protected void fireEvent(CommandStackEvent event) { if (commandStackListeners == null) return; for (Object listener : commandStackListeners.toArray()) { ((ICommandStackListener) listener).handleCommandStackEvent(event); } } /** * @see org.xmind.framework.Disposable#removeFromLayer(IFigure) */ @Override public void dispose() { if (commandStackListeners != null) { commandStackListeners.clear(); commandStackListeners = null; } clear(); super.dispose(); } /** * @see org.xmind.gef.command.ICommandStack#getUndoLimit() */ public int getUndoLimit() { return undoLimit; } /** * @see org.xmind.gef.command.ICommandStack#setUndoLimit(int) */ public void setUndoLimit(int undoLimit) { this.undoLimit = undoLimit; } /** * @see org.xmind.gef.command.ICommandStack#getRepeatLabel() * @deprecated */ public String getRepeatLabel() { return getUndoLabel(); } /** * @deprecated */ public boolean canRepeat() { return false; } /** * @deprecated */ public void repeat() { } public void markSaved() { } public boolean isDirty() { return canUndo(); } }