1 /*
   2  * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.undo;
  27 
  28 import java.io.Serializable;
  29 import javax.swing.UIManager;
  30 
  31 /**
  32  * An abstract implementation of <code>UndoableEdit</code>,
  33  * implementing simple responses to all boolean methods in
  34  * that interface.
  35  *
  36  * @author Ray Ryan
  37  */
  38 public class AbstractUndoableEdit implements UndoableEdit, Serializable {
  39     private static final long serialVersionUID = 580150227676302096L;
  40 
  41     /**
  42      * String returned by <code>getUndoPresentationName</code>;
  43      * as of Java 2 platform v1.3.1 this field is no longer used. This value
  44      * is now localized and comes from the defaults table with key
  45      * <code>AbstractUndoableEdit.undoText</code>.
  46      *
  47      * @see javax.swing.UIDefaults
  48      */
  49     protected static final String UndoName = "Undo";
  50 
  51     /**
  52      * String returned by <code>getRedoPresentationName</code>;
  53      * as of Java 2 platform v1.3.1 this field is no longer used. This value
  54      * is now localized and comes from the defaults table with key
  55      * <code>AbstractUndoableEdit.redoText</code>.
  56      *
  57      * @see javax.swing.UIDefaults
  58      */
  59     protected static final String RedoName = "Redo";
  60 
  61     /**
  62      * Defaults to true; becomes false if this edit is undone, true
  63      * again if it is redone.
  64      */
  65     boolean hasBeenDone;
  66 
  67     /**
  68      * True if this edit has not received <code>die</code>; defaults
  69      * to <code>true</code>.
  70      */
  71     boolean alive;
  72 
  73     /**
  74      * Creates an <code>AbstractUndoableEdit</code> which defaults
  75      * <code>hasBeenDone</code> and <code>alive</code> to <code>true</code>.
  76      */
  77     public AbstractUndoableEdit() {
  78         super();
  79 
  80         hasBeenDone = true;
  81         alive = true;
  82     }
  83 
  84     /**
  85      * Sets <code>alive</code> to false. Note that this
  86      * is a one way operation; dead edits cannot be resurrected.
  87      * Sending <code>undo</code> or <code>redo</code> to
  88      * a dead edit results in an exception being thrown.
  89      *
  90      * <p>Typically an edit is killed when it is consolidated by
  91      * another edit's <code>addEdit</code> or <code>replaceEdit</code>
  92      * method, or when it is dequeued from an <code>UndoManager</code>.
  93      */
  94     public void die() {
  95         alive = false;
  96     }
  97 
  98     /**
  99      * Throws <code>CannotUndoException</code> if <code>canUndo</code>
 100      * returns <code>false</code>. Sets <code>hasBeenDone</code>
 101      * to <code>false</code>. Subclasses should override to undo the
 102      * operation represented by this edit. Override should begin with
 103      * a call to super.
 104      *
 105      * @exception CannotUndoException if <code>canUndo</code>
 106      *    returns <code>false</code>
 107      * @see     #canUndo
 108      */
 109     public void undo() throws CannotUndoException {
 110         if (!canUndo()) {
 111             throw new CannotUndoException();
 112         }
 113         hasBeenDone = false;
 114     }
 115 
 116     /**
 117      * Returns true if this edit is <code>alive</code>
 118      * and <code>hasBeenDone</code> is <code>true</code>.
 119      *
 120      * @return true if this edit is <code>alive</code>
 121      *    and <code>hasBeenDone</code> is <code>true</code>
 122      *
 123      * @see     #die
 124      * @see     #undo
 125      * @see     #redo
 126      */
 127     public boolean canUndo() {
 128         return alive && hasBeenDone;
 129     }
 130 
 131     /**
 132      * Throws <code>CannotRedoException</code> if <code>canRedo</code>
 133      * returns false. Sets <code>hasBeenDone</code> to <code>true</code>.
 134      * Subclasses should override to redo the operation represented by
 135      * this edit. Override should begin with a call to super.
 136      *
 137      * @exception CannotRedoException if <code>canRedo</code>
 138      *     returns <code>false</code>
 139      * @see     #canRedo
 140      */
 141     public void redo() throws CannotRedoException {
 142         if (!canRedo()) {
 143             throw new CannotRedoException();
 144         }
 145         hasBeenDone = true;
 146     }
 147 
 148     /**
 149      * Returns <code>true</code> if this edit is <code>alive</code>
 150      * and <code>hasBeenDone</code> is <code>false</code>.
 151      *
 152      * @return <code>true</code> if this edit is <code>alive</code>
 153      *   and <code>hasBeenDone</code> is <code>false</code>
 154      * @see     #die
 155      * @see     #undo
 156      * @see     #redo
 157      */
 158     public boolean canRedo() {
 159         return alive && !hasBeenDone;
 160     }
 161 
 162     /**
 163      * This default implementation returns false.
 164      *
 165      * @param anEdit the edit to be added
 166      * @return false
 167      *
 168      * @see UndoableEdit#addEdit
 169      */
 170     public boolean addEdit(UndoableEdit anEdit) {
 171         return false;
 172     }
 173 
 174     /**
 175      * This default implementation returns false.
 176      *
 177      * @param anEdit the edit to replace
 178      * @return false
 179      *
 180      * @see UndoableEdit#replaceEdit
 181      */
 182     public boolean replaceEdit(UndoableEdit anEdit) {
 183         return false;
 184     }
 185 
 186     /**
 187      * This default implementation returns true.
 188      *
 189      * @return true
 190      * @see UndoableEdit#isSignificant
 191      */
 192     public boolean isSignificant() {
 193         return true;
 194     }
 195 
 196     /**
 197      * This default implementation returns "". Used by
 198      * <code>getUndoPresentationName</code> and
 199      * <code>getRedoPresentationName</code> to
 200      * construct the strings they return. Subclasses should override to
 201      * return an appropriate description of the operation this edit
 202      * represents.
 203      *
 204      * @return the empty string ""
 205      *
 206      * @see     #getUndoPresentationName
 207      * @see     #getRedoPresentationName
 208      */
 209     public String getPresentationName() {
 210         return "";
 211     }
 212 
 213     /**
 214      * Retreives the value from the defaults table with key
 215      * <code>AbstractUndoableEdit.undoText</code> and returns
 216      * that value followed by a space, followed by
 217      * <code>getPresentationName</code>.
 218      * If <code>getPresentationName</code> returns "",
 219      * then the defaults value is returned alone.
 220      *
 221      * @return the value from the defaults table with key
 222      *    <code>AbstractUndoableEdit.undoText</code>, followed
 223      *    by a space, followed by <code>getPresentationName</code>
 224      *    unless <code>getPresentationName</code> is "" in which
 225      *    case, the defaults value is returned alone.
 226      * @see #getPresentationName
 227      */
 228     public String getUndoPresentationName() {
 229         String name = getPresentationName();
 230         if (!"".equals(name)) {
 231             name = UIManager.getString("AbstractUndoableEdit.undoText") +
 232                 " " + name;
 233         } else {
 234             name = UIManager.getString("AbstractUndoableEdit.undoText");
 235         }
 236 
 237         return name;
 238     }
 239 
 240     /**
 241      * Retreives the value from the defaults table with key
 242      * <code>AbstractUndoableEdit.redoText</code> and returns
 243      * that value followed by a space, followed by
 244      * <code>getPresentationName</code>.
 245      * If <code>getPresentationName</code> returns "",
 246      * then the defaults value is returned alone.
 247      *
 248      * @return the value from the defaults table with key
 249      *    <code>AbstractUndoableEdit.redoText</code>, followed
 250      *    by a space, followed by <code>getPresentationName</code>
 251      *    unless <code>getPresentationName</code> is "" in which
 252      *    case, the defaults value is returned alone.
 253      * @see #getPresentationName
 254      */
 255     public String getRedoPresentationName() {
 256         String name = getPresentationName();
 257         if (!"".equals(name)) {
 258             name = UIManager.getString("AbstractUndoableEdit.redoText") +
 259                 " " + name;
 260         } else {
 261             name = UIManager.getString("AbstractUndoableEdit.redoText");
 262         }
 263 
 264         return name;
 265     }
 266 
 267     /**
 268      * Returns a string that displays and identifies this
 269      * object's properties.
 270      *
 271      * @return a String representation of this object
 272      */
 273     public String toString()
 274     {
 275         return super.toString()
 276             + " hasBeenDone: " + hasBeenDone
 277             + " alive: " + alive;
 278     }
 279 }