1. /*
  2. * @(#)CompoundEdit.java 1.16 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.undo;
  8. import java.util.*;
  9. /**
  10. * A concrete subclass of AbstractUndoableEdit, used to assemble little
  11. * UndoableEdits into great big ones.
  12. *
  13. * @version 1.16 11/29/01
  14. * @author Ray Ryan
  15. */
  16. public class CompoundEdit extends AbstractUndoableEdit {
  17. /**
  18. * True iff this edit has never received end()
  19. */
  20. boolean inProgress;
  21. /**
  22. * The collection of UndoableEdits undone/redone en masse by this
  23. * CompoundEdit
  24. */
  25. protected Vector edits;
  26. public CompoundEdit() {
  27. super();
  28. inProgress = true;
  29. edits = new Vector();
  30. }
  31. /**
  32. * Sends undo() to all contained UndoableEdits in the reverse of
  33. * the order in which they were added.
  34. */
  35. public void undo() throws CannotUndoException {
  36. super.undo();
  37. int i = edits.size();
  38. while (i-- > 0) {
  39. UndoableEdit e = (UndoableEdit)edits.elementAt(i);
  40. e.undo();
  41. }
  42. }
  43. /**
  44. * Sends redo() to all contained UndoableEdits in the order in
  45. * which they were added.
  46. */
  47. public void redo() throws CannotRedoException {
  48. super.redo();
  49. Enumeration cursor = edits.elements();
  50. while (cursor.hasMoreElements()) {
  51. ((UndoableEdit)cursor.nextElement()).redo();
  52. }
  53. }
  54. /**
  55. * Returns the last UndoableEdit in edits, or null if edits is
  56. * empty
  57. */
  58. protected UndoableEdit lastEdit() {
  59. int count = edits.size();
  60. if (count > 0)
  61. return (UndoableEdit)edits.elementAt(count-1);
  62. else
  63. return null;
  64. }
  65. /**
  66. * Send die to each subedit, in the reverse of the order that they
  67. * were added
  68. */
  69. public void die() {
  70. int size = edits.size();
  71. for (int i = size-1; i >= 0; i--)
  72. {
  73. UndoableEdit e = (UndoableEdit)edits.elementAt(i);
  74. // System.out.println("CompoundEdit(" + i + "): Discarding " +
  75. // e.getUndoPresentationName());
  76. e.die();
  77. }
  78. super.die();
  79. }
  80. /**
  81. * If this edit is inProgress, accepts anEdit and returns
  82. * true.
  83. *
  84. * <p>The last edit added to this CompoundEdit is given a
  85. * chance to addEdit(anEdit). If it refuses (returns false), anEdit is
  86. * given a chance to replaceEdit the last edit. If anEdit returns
  87. * false here, it is added to edits.</p>
  88. */
  89. public boolean addEdit(UndoableEdit anEdit) {
  90. if (!inProgress) {
  91. return false;
  92. } else {
  93. UndoableEdit last = lastEdit();
  94. // If this is the first subedit received, just add it.
  95. // Otherwise, give the last one a chance to absorb the new
  96. // one. If it won't, give the new one a chance to absorb
  97. // the last one.
  98. if (last == null) {
  99. edits.addElement(anEdit);
  100. }
  101. else if (!last.addEdit(anEdit)) {
  102. if (anEdit.replaceEdit(last)) {
  103. edits.removeElementAt(edits.size()-1);
  104. }
  105. edits.addElement(anEdit);
  106. }
  107. return true;
  108. }
  109. }
  110. /**
  111. * Sets inProgress to false.
  112. *
  113. * @see #canUndo
  114. * @see #canRedo
  115. */
  116. public void end() {
  117. inProgress = false;
  118. }
  119. /**
  120. * Returns false if isInProgress or if super does.
  121. *
  122. * @see #isInProgress
  123. */
  124. public boolean canUndo() {
  125. return !isInProgress() && super.canUndo();
  126. }
  127. /**
  128. * Returns false if isInProgress or if super does.
  129. *
  130. * @see #isInProgress
  131. */
  132. public boolean canRedo() {
  133. return !isInProgress() && super.canRedo();
  134. }
  135. /**
  136. * Returns true if this edit is in progress--that is, it has not
  137. * received end. This generally means that edits are still being
  138. * added to it.
  139. *
  140. * @see #end
  141. */
  142. public boolean isInProgress() {
  143. return inProgress;
  144. }
  145. /**
  146. * Returns true if any of the UndoableEdits in edits do. Returns
  147. * false if they all return false.
  148. */
  149. public boolean isSignificant() {
  150. Enumeration cursor = edits.elements();
  151. while (cursor.hasMoreElements()) {
  152. if (((UndoableEdit)cursor.nextElement()).isSignificant()) {
  153. return true;
  154. }
  155. }
  156. return false;
  157. }
  158. /**
  159. * Returns getPresentationName from the last UndoableEdit added to
  160. * edits. If edits is empty, calls super.
  161. */
  162. public String getPresentationName() {
  163. UndoableEdit last = lastEdit();
  164. if (last != null) {
  165. return last.getPresentationName();
  166. } else {
  167. return super.getPresentationName();
  168. }
  169. }
  170. /**
  171. * Returns getUndoPresentationName from the last UndoableEdit
  172. * added to edits. If edits is empty, calls super.
  173. */
  174. public String getUndoPresentationName() {
  175. UndoableEdit last = lastEdit();
  176. if (last != null) {
  177. return last.getUndoPresentationName();
  178. } else {
  179. return super.getUndoPresentationName();
  180. }
  181. }
  182. /**
  183. * Returns getRedoPresentationName from the last UndoableEdit
  184. * added to edits. If edits is empty, calls super.
  185. */
  186. public String getRedoPresentationName() {
  187. UndoableEdit last = lastEdit();
  188. if (last != null) {
  189. return last.getRedoPresentationName();
  190. } else {
  191. return super.getRedoPresentationName();
  192. }
  193. }
  194. /**
  195. * Returns a string that displays and identifies this
  196. * object's properties.
  197. *
  198. * @return a String representation of this object
  199. */
  200. public String toString()
  201. {
  202. return super.toString()
  203. + " inProgress: " + inProgress
  204. + " edits: " + edits;
  205. }
  206. }