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