/[classpath]/classpath/javax/swing/undo/CompoundEdit.java
ViewVC logotype

Diff of /classpath/javax/swing/undo/CompoundEdit.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by mkoch, Sun Jun 8 12:14:56 2003 UTC revision 1.3 by brawer, Mon Nov 17 16:11:32 2003 UTC
# Line 1  Line 1 
1  /* AbstractTableModel.java --  /* CompoundEdit.java -- Combines multiple UndoableEdits.
2     Copyright (C) 2002 Free Software Foundation, Inc.     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 41  package javax.swing.undo; Line 41  package javax.swing.undo;
41  import java.util.Vector;  import java.util.Vector;
42    
43  /**  /**
44   * CompoundEdit   * An editing action that consists of multiple
45   * @author Andrew Selkirk   * <code>UndoableEdits</code>.
46     *
47     * <p>The use of a <code>CompoundEdit</code> is divided in two separate
48     * phases.
49     *
50     * <ol><li>In the first phase, the <code>CompoundEdit</code> is
51     * initialized.  After a new instance of <code>CompoundEdit</code> has
52     * been created, {@link #addEdit(UndoableEdit)} is called for each
53     * element of the compound.  To terminate the initialization phase,
54     * call {@link #end()}.</li>
55     *
56     * <li>In the second phase, the the <code>CompoundEdit</code> can be
57     * used, typically by invoking {@link #undo()} and {@link
58     * #redo()}.</li></ol>
59     *
60     * @author Andrew Selkirk (aselkirk@sympatico.ca)
61     * @author Sascha Brawer (brawer@dandelis.ch)
62   */   */
63  public class CompoundEdit extends AbstractUndoableEdit {  public class CompoundEdit
64      extends AbstractUndoableEdit
65          //-------------------------------------------------------------  {
66          // Variables --------------------------------------------------    /**
67          //-------------------------------------------------------------     * The <code>UndoableEdit</code>s being combined into a compound
68       * editing action.
69          /**     */
70           * The collection of UndoableEdits undone/redone en    protected Vector edits;
71           * masse by this CompoundEdit  
72           */  
73          protected       Vector  edits           = new Vector();    /**
74       * Indicates whether the creation of this CompoundEdit is still in
75          /**     * progress. Initially, the value of this flag is
76           * TODO     * <code>true</code>. The {@link #end()} method changes the flag to
77           */     * <code>false</code>.
78          private         boolean inProgress      = false;     */
79      private boolean inProgress;
80    
81          //-------------------------------------------------------------  
82          // Initialization ---------------------------------------------    /**
83          //-------------------------------------------------------------     * Constructs a new CompoundEdit.
84       */
85          /**    public CompoundEdit()
86           * Create new Compound Edit    {
87           */      edits = new Vector();
88          public CompoundEdit() {      inProgress = true;
89          } // CompoundEdit()    }
90      
91    
92          //-------------------------------------------------------------    /**
93          // Interface: UndoableEdit ------------------------------------     * Undoes all edits that are part of of this
94          //-------------------------------------------------------------     * <code>CompoundEdit</code>. The compound elements will receive the
95       * <code>undo</code> message in the reverse order of addition.
96          /**     *
97           * addEdit     * @throws CannotUndoException if {@link #canUndo()} returns
98           * @param anEdit TODO     * <code>false</code>. This can happen if {@link #end()} has not
99           * @returns TODO     * been called on this <code>CompoundEdit</code>, or if this edit
100           */     * has already been undone.
101          public boolean addEdit(UndoableEdit anEdit) {     *
102       * @see #canUndo()
103                  // Variables     * @see #redo()
104                  UndoableEdit    lastEdit;     */
105      public void undo()
106                  if (inProgress == true) {      throws CannotUndoException
107      {
108                          // Get Last Edit      // AbstractUndoableEdit.undo() will throw a CannotUndoException if
109                          lastEdit = lastEdit();      // canUndo returns false.
110        super.undo();
111                          // Check for null  
112                          if (lastEdit != null) {      for (int i = edits.size() - 1; i >= 0; i--)
113          ((UndoableEdit) edits.elementAt(i)).undo();
114                                  if (lastEdit.addEdit(anEdit) == false) {    }
115                                          if (lastEdit.replaceEdit(anEdit) == false) {  
116                                                  edits.add(anEdit);  
117                                          }    /**
118                                  }     * Redoes all edits that are part of of this
119       * <code>CompoundEdit</code>. The compound elements will receive the
120                          } // if: lastEdit     * <code>undo</code> message in the same order as they were added.
121       *
122                          return true;     * @throws CannotRedoException if {@link #canRedo()} returns
123       * <code>false</code>. This can happen if {@link #end()} has not
124                  } else {     * been called on this <code>CompoundEdit</code>, or if this edit
125                          return false;     * has already been redone.
126                  }     *
127          } // addEdit()     * @see #canRedo()
128       * @see #undo()
129          /**     */
130           * canRedo    public void redo()
131           * @returns TODO      throws CannotRedoException
132           */    {
133          public boolean canRedo() {      // AbstractUndoableEdit.redo() will throw a CannotRedoException if
134                  if (isInProgress() == true || super.canRedo() == false) {      // canRedo returns false.
135                          return false;      super.redo();
136                  }  
137                  return true;      for (int i = 0; i < edits.size(); i++)
138          } // canRedo()        ((UndoableEdit) edits.elementAt(i)).redo();
139      }
140          /**  
141           * canUndo    
142           * @returns TODO    /**
143           */     * Returns the the <code>UndoableEdit</code> that was last added to
144          public boolean canUndo() {     * this compound.
145                  if (isInProgress() == true || super.canUndo() == false) {     */
146                          return false;    protected UndoableEdit lastEdit()
147                  }    {
148                  return true;      if (edits.size() == 0)
149          } // canUndo()        return null;
150        else
151          /**        return (UndoableEdit) edits.elementAt(edits.size() - 1);
152           * die    }
153           */  
154          public void die() {  
155      /**
156                  // Variables     * Informs this edit action, and all compound edits, that they will
157                  int                             index;     * no longer be used. Some actions might use this information to
158                  UndoableEdit    current;     * release resources such as open files.  Called by {@link
159       * UndoManager} before this action is removed from the edit queue.
160                  // Loop through all contained UndoableEdits     *
161                  for (index = edits.size() - 1; index >= 0; index--) {     * <p>The compound elements will receive the
162                          current = (UndoableEdit) edits.elementAt(index);     * <code>die</code> message in the reverse order of addition.
163                          current.die();     */
164                  } // for: index    public void die()
165      {
166          } // die()      for (int i = edits.size() - 1; i >= 0; i--)
167          ((UndoableEdit) edits.elementAt(i)).die();
168          /**  
169           * end      super.die();
170           */    }
171          public void end() {  
172                  inProgress = false;  
173          } // end()    /**
174       * Incorporates another editing action into this one, thus forming a
175          /**     * combined edit.
176           * getPresentationName     *
177           * @returns TODO     * <p>If this edit&#x2019;s {@link #end()} method has been called
178           */     * before, <code>false</code> is returned immediately. Otherwise,
179          public String getPresentationName() {     * the {@linkplain #lastEdit() last added edit} is given the
180                  if (edits.size() == 0) {     * opportunity to {@linkplain UndoableEdit#addEdit(UndoableEdit)
181                          return super.getPresentationName();     * incorporate} <code>edit</code>.  If this fails, <code>edit</code>
182                  } else {     * is given the opportunity to {@linkplain
183                          return lastEdit().getPresentationName();     * UndoableEdit#replaceEdit(UndoableEdit) replace} the last added
184                  }     * edit.  If this fails as well, <code>edit</code> gets added as a
185          } // getPresentationName()     * new compound to {@link #edits}.
186       *
187          /**     * @param edit the editing action being added.
188           * getRedoPresentationName     *
189           * @returns TODO     * @return <code>true</code> if <code>edit</code> could somehow be
190           */     * incorporated; <code>false</code> if <code>edit</code> has not
191          public String getRedoPresentationName() {     * been incorporated because {@link #end()} was called before.
192                  if (edits.size() == 0) {     */
193                          return super.getRedoPresentationName();    public boolean addEdit(UndoableEdit edit)
194                  } else {    {
195                          return lastEdit().getRedoPresentationName();      UndoableEdit last;
196                  }  
197          } // getRedoPresentationName()      // If end has been called before, do nothing.
198        if (!inProgress)
199          /**        return false;
200           * getUndoPresentationName  
201           * @returns TODO      last = lastEdit();
202           */  
203          public String getUndoPresentationName() {      // If edit is the very first edit, just add it to the list.
204                  if (edits.size() == 0) {      if (last == null)
205                          return super.getUndoPresentationName();      {
206                  } else {        edits.add(edit);
207                          return lastEdit().getUndoPresentationName();        return true;
208                  }      }
209          } // getUndoPresentationName()  
210        // Try to incorporate edit into last.
211          /**      if (last.addEdit(edit))
212           * isInProgress        return true;
213           * @returns TODO  
214           */      // Try to replace last by edit.
215          public boolean isInProgress() {      if (edit.replaceEdit(last))
216                  return inProgress;      {
217          } // isInProgress()        edits.set(edits.size() - 1, edit);
218          return true;
219        }
220          /**  
221           * isSignigicant      // If everything else has failed, add edit to the list of compound
222           * @returns TODO      // edits.
223           */      edits.add(edit);
224          public boolean isSignificant() {      return true;
225      }
226                  // Variables  
227                  int                             index;  
228                  UndoableEdit    current;    /**
229       * Informs this <code>CompoundEdit</code> that its construction
230                  // Check each edit     * phase has been completed. After this method has been called,
231                  for (index = 0; index < edits.size(); index++) {     * {@link #undo()} and {@link #redo()} may be called, {@link
232                          current = (UndoableEdit) edits.elementAt(index);     * #isInProgress()} will return <code>false</code>, and all attempts
233                          if (current.isSignificant() == true) {     * to {@linkplain #addEdit(UndoableEdit) add further edits} will
234                                  return true;     * fail.
235                          }     */
236                  } // for: index    public void end()
237      {
238                  return false;      inProgress = false;
239      }
240          } // isSignificant()  
241    
242          /**    /**
243           * lastEdit     * Determines whether it would be possible to undo this editing
244           * @returns TODO     * action. The result will be <code>true</code> if {@link #end()}
245           */     * has been called on this <code>CompoundEdit</code>, {@link #die()}
246          protected UndoableEdit lastEdit() {     * has not yet been called, and the edit has not been undone
247                  if (edits.size() == 0) {     * already.
248                          return null;     *
249                  }     * @return <code>true</code> to indicate that this action can be
250                  return (UndoableEdit) edits.elementAt(edits.size() - 1);     * undone; <code>false</code> otherwise.
251          } // lastEdit()     *
252       * @see #undo()
253          /**     * @see #canRedo()
254           * redo     */
255           * @throws CannotRedoException TODO    public boolean canUndo()
256           */    {
257          public void redo() throws CannotRedoException {      return !inProgress && super.canUndo();
258      }
259                  // Variables  
260                  int                             index;  
261                  UndoableEdit    current;    /**
262       * Determines whether it would be possible to redo this editing
263                  // Loop through all contained UndoableEdits     * action. The result will be <code>true</code> if {@link #end()}
264                  for (index = 0; index < edits.size(); index++) {     * has been called on this <code>CompoundEdit</code>, {@link #die()}
265                          current = (UndoableEdit) edits.elementAt(index);     * has not yet been called, and the edit has not been redone
266                          current.redo();     * already.
267                  } // for: index     *
268       * @return <code>true</code> to indicate that this action can be
269          } // redo()     * redone; <code>false</code> otherwise.
270       *
271          /**     * @see #redo()
272           * String representation     * @see #canUndo()
273           * @returns String representation     */
274           */    public boolean canRedo()
275          public String toString() {    {
276                  return null; // TODO      return !inProgress && super.canRedo();
277          } // toString()    }
278    
279          /**  
280           * undo    /**
281           * @throws CannotUndoException TODO     * Determines whether the initial construction phase of this
282           */     * <code>CompoundEdit</code> is still in progress.  During this
283          public void undo() throws CannotUndoException {     * phase, edits {@linkplain #addEdit(UndoableEdit) may be
284       * added}. After initialization has been terminated by calling
285                  // Variables     * {@link #end()}, {@link #undo()} and {@link #redo()} can be used.
286                  int                             index;     *
287                  UndoableEdit    current;     * @return <code>true</code> if the initialization phase is still in
288       * progress; <code>false</code> if {@link #end()} has been called.
289                  // Loop through all contained UndoableEdits     *
290                  for (index = edits.size() - 1; index >= 0; index--) {     * @see #end()
291                          current = (UndoableEdit) edits.elementAt(index);     */
292                          current.undo();    public boolean isInProgress()
293                  } // for: index    {
294        return inProgress;
295          } // undo()    }
296    
297    
298  } // CompoundEdit    /**
299       * Determines whether this editing action is significant enough for
300       * being seperately undoable by the user. A typical significant
301       * action would be the resizing of an object. However, changing the
302       * selection in a text document would usually not be considered
303       * significant.
304       *
305       * <p>A <code>CompoundEdit</code> is significant if any of its
306       * elements are significant.
307       */
308      public boolean isSignificant()
309      {
310        for (int i = edits.size() - 1; i >= 0; i--)
311          if (((UndoableEdit) edits.elementAt(i)).isSignificant())
312            return true;
313    
314        return false;
315      }
316      
317    
318      /**
319       * Returns a human-readable, localized name that describes this
320       * editing action and can be displayed to the user.
321       *
322       * <p>The implementation delegates the call to the {@linkplain
323       * #lastEdit() last added edit action}. If no edit has been added
324       * yet, the inherited implementation will be invoked, which always
325       * returns an empty string.
326       */
327      public String getPresentationName()
328      {
329        UndoableEdit last;
330    
331        last = lastEdit();
332        if (last == null)
333          return super.getPresentationName();
334        else
335          return last.getPresentationName();
336      }
337    
338    
339      /**
340       * Calculates a localized message text for presenting the undo
341       * action to the user.
342       *
343       * <p>The implementation delegates the call to the {@linkplain
344       * #lastEdit() last added edit action}. If no edit has been added
345       * yet, the {@linkplain
346       * AbstractUndoableEdit#getUndoPresentationName() inherited
347       * implementation} will be invoked.
348       */
349      public String getUndoPresentationName()
350      {
351        UndoableEdit last;
352    
353        last = lastEdit();
354        if (last == null)
355          return super.getUndoPresentationName();
356        else
357          return last.getUndoPresentationName();
358      }
359    
360    
361      /**
362       * Calculates a localized message text for presenting the redo
363       * action to the user.
364       *
365       * <p>The implementation delegates the call to the {@linkplain
366       * #lastEdit() last added edit action}. If no edit has been added
367       * yet, the {@linkplain
368       * AbstractUndoableEdit#getRedoPresentationName() inherited
369       * implementation} will be invoked.
370       */
371      public String getRedoPresentationName()
372      {
373        UndoableEdit last;
374    
375        last = lastEdit();
376        if (last == null)
377          return super.getRedoPresentationName();
378        else
379          return last.getRedoPresentationName();
380      }
381      
382      
383      /**
384       * Calculates a string that may be useful for debugging.
385       */
386      public String toString()
387      {
388        return super.toString()
389          + " inProgress: " + inProgress
390          + " edits: " + edits;
391      }
392    }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26