Frames | No Frames |
1: /* AbstractUndoableEdit.java -- 2: Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.undo; 40: 41: import java.io.Serializable; 42: 43: import javax.swing.UIManager; 44: 45: /** 46: * A default implementation of <code>UndoableEdit</code> that can be 47: * used as a base for implementing editing operations. 48: * 49: * @author Andrew Selkirk (aselkirk@sympatico.ca) 50: * @author Sascha Brawer (brawer@dandelis.ch) 51: */ 52: public class AbstractUndoableEdit 53: implements UndoableEdit, Serializable 54: { 55: /** 56: * The serialization ID. Verified using the <code>serialver</code> 57: * tool of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5, and Sun JDK 58: * 1.4.1_01 on GNU/Linux. 59: */ 60: static final long serialVersionUID = 580150227676302096L; 61: 62: 63: /** 64: * The constant string “Undo”, which was returned by 65: * {@link #getUndoPresentationName()} on early versions of the 66: * platform. However, this field has become obsolete with version 67: * 1.3.1. That method now retrieves a localized string from the 68: * {@link javax.swing.UIManager}, using the key 69: * <code>“AbstractUndoableEdit.undoText”</code>. 70: */ 71: protected static final String UndoName = "Undo"; 72: 73: 74: /** 75: * The constant string “Redo”, which was returned by 76: * {@link #getRedoPresentationName()} on early versions of the 77: * platform. However, this field has become obsolete with version 78: * 1.3.1. That method now retrieves a localized string from the 79: * {@link javax.swing.UIManager}, using the key 80: * <code>“AbstractUndoableEdit.redoText”</code>. 81: */ 82: protected static final String RedoName = "Redo"; 83: 84: 85: /** 86: * Indicates whether this editing action has been executed. A value 87: * of <code>true</code> means that the action was performed, or that 88: * a redo operation was successful. A value of <code>false</code> 89: * means that the action has not yet performed, or that an undo 90: * operation was successful. 91: */ 92: private boolean hasBeenDone; 93: 94: 95: /** 96: * Indicates whether this editing action is still alive. The value 97: * is set to <code>true</code> by the constructor, and to 98: * <code>false</code> by the {@link #die()} method. 99: */ 100: private boolean alive; 101: 102: 103: /** 104: * Constructs a new <code>AbstractUndoableEdit</code>. The initial 105: * state is that the editing action is alive, and 106: * <code>hasBeenDone</code> is <code>true</code>. 107: */ 108: public AbstractUndoableEdit() 109: { 110: // The API specification is not clear, but Mauve test code has 111: // determined that hasBeenDone is initially set to true. 112: alive = hasBeenDone = true; 113: } 114: 115: 116: /** 117: * Undoes this editing action. 118: * 119: * @throws CannotUndoException if {@link #canUndo()} returns 120: * <code>false</code>, for example because this action has already 121: * been undone. 122: * 123: * @see #canUndo() 124: * @see #redo() 125: */ 126: public void undo() 127: throws CannotUndoException 128: { 129: if (!canUndo()) 130: throw new CannotUndoException(); 131: hasBeenDone = false; 132: } 133: 134: 135: /** 136: * Determines whether it would be possible to undo this editing 137: * action. 138: * 139: * @return <code>true</code> to indicate that this action can be 140: * undone, <code>false</code> otherwise. 141: * 142: * @see #undo() 143: * @see #canRedo() 144: */ 145: public boolean canUndo() 146: { 147: return alive && hasBeenDone; 148: } 149: 150: 151: /** 152: * Redoes this editing action. 153: * 154: * @throws CannotRedoException if {@link #canRedo()} returns 155: * <code>false</code>, for example because this action has not 156: * yet been undone. 157: * 158: * @see #canRedo() 159: * @see #undo() 160: */ 161: public void redo() 162: throws CannotRedoException 163: { 164: if (!canRedo()) 165: throw new CannotRedoException(); 166: hasBeenDone = true; 167: } 168: 169: 170: /** 171: * Determines whether it would be possible to redo this editing 172: * action. 173: * 174: * @return <code>true</code> to indicate that this action can be 175: * redone, <code>false</code> otherwise. 176: * 177: * @see #redo() 178: * @see #canUndo() 179: */ 180: public boolean canRedo() 181: { 182: return alive && !hasBeenDone; 183: } 184: 185: 186: /** 187: * Informs this edit action that it will no longer be used. Some 188: * actions might use this information to release resources, for 189: * example open files. Called by {@link UndoManager} before this 190: * action is removed from the edit queue. 191: */ 192: public void die() 193: { 194: alive = false; 195: } 196: 197: 198: /** 199: * Incorporates another editing action into this one, thus forming a 200: * combined action. 201: * 202: * <p>The default implementation always returns <code>false</code>, 203: * indicating that the editing action could not be incorporated. 204: * 205: * @param edit the editing action to be incorporated. 206: */ 207: public boolean addEdit(UndoableEdit edit) 208: { 209: return false; 210: } 211: 212: 213: /** 214: * Incorporates another editing action into this one, thus forming a 215: * combined action that replaces the argument action. 216: * 217: * <p>The default implementation always returns <code>false</code>, 218: * indicating that the argument action should not be replaced. 219: * 220: * @param edit the editing action to be replaced. 221: */ 222: public boolean replaceEdit(UndoableEdit edit) 223: { 224: return false; 225: } 226: 227: 228: /** 229: * Determines whether this editing action is significant enough for 230: * being seperately undoable by the user. A typical significant 231: * action would be the resizing of an object. However, changing the 232: * selection in a text document would usually not be considered 233: * significant. 234: * 235: * <p>The default implementation returns <code>true</code>. 236: * 237: * @return <code>true</code> to indicate that the action is 238: * significant enough for being separately undoable, or 239: * <code>false</code> otherwise. 240: */ 241: public boolean isSignificant() 242: { 243: return true; 244: } 245: 246: 247: /** 248: * Returns a human-readable, localized name that describes this 249: * editing action and can be displayed to the user. 250: * 251: * <p>The default implementation returns an empty string. 252: */ 253: public String getPresentationName() 254: { 255: return ""; 256: } 257: 258: 259: /** 260: * Calculates a localized name for presenting the undo action to the 261: * user. 262: * 263: * <p>The default implementation returns the concatenation of the 264: * string “Undo” and the action name, which is 265: * determined by calling {@link #getPresentationName()}. 266: * 267: * <p>The string “Undo” is retrieved from the {@link 268: * javax.swing.UIManager}, using the key 269: * <code>“AbstractUndoableEdit.undoText”</code>. This 270: * allows the text to be localized. 271: */ 272: public String getUndoPresentationName() 273: { 274: String msg, pres; 275: 276: msg = UIManager.getString("AbstractUndoableEdit.undoText"); 277: if (msg == null) 278: msg = UndoName; 279: 280: pres = getPresentationName(); 281: if ((pres == null) || (pres.length() == 0)) 282: return msg; 283: else 284: return msg + ' ' + pres; 285: } 286: 287: 288: /** 289: * Calculates a localized name for presenting the redo action to the 290: * user. 291: * 292: * <p>The default implementation returns the concatenation of the 293: * string “Redo” and the action name, which is 294: * determined by calling {@link #getPresentationName()}. 295: * 296: * <p>The string “Redo” is retrieved from the {@link 297: * javax.swing.UIManager}, using the key 298: * <code>“AbstractUndoableEdit.redoText”</code>. This 299: * allows the text to be localized. 300: */ 301: public String getRedoPresentationName() 302: { 303: String msg, pres; 304: 305: msg = UIManager.getString("AbstractUndoableEdit.redoText"); 306: if (msg == null) 307: msg = RedoName; 308: 309: pres = getPresentationName(); 310: if ((pres == null) || (pres.length() == 0)) 311: return msg; 312: else 313: return msg + ' ' + pres; 314: } 315: 316: 317: public String toString() 318: { 319: return super.toString() 320: + " hasBeenDone: " + hasBeenDone 321: + " alive: " + alive; 322: } 323: }