package net.sf.openrocket.document;
-import java.awt.event.ActionEvent;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-
import net.sf.openrocket.document.events.DocumentChangeEvent;
import net.sf.openrocket.document.events.DocumentChangeListener;
import net.sf.openrocket.document.events.SimulationChangeEvent;
-import net.sf.openrocket.gui.util.Icons;
-import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.logging.TraceException;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
-import net.sf.openrocket.util.BugException;
/**
* Class describing an entire OpenRocket document, including a rocket and
*/
public class OpenRocketDocument implements ComponentChangeListener {
private static final LogHelper log = Application.getLogger();
- private static final Translator trans = Application.getTranslator();
/**
* The minimum number of undo levels that are stored.
/** Whether an undo error has already been reported to the user */
private static boolean undoErrorReported = false;
-
-
private final Rocket rocket;
private final Configuration configuration;
*/
private LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
private LinkedList<String> undoDescription = new LinkedList<String>();
-
+
/**
* The position in the undoHistory we are currently at. If modifications have been
* made to the rocket, the rocket is in "dirty" state and this points to the previous
private String storedDescription = null;
+ private ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2);
+
private File file = null;
private int savedID = -1;
private final List<DocumentChangeListener> listeners =
new ArrayList<DocumentChangeListener>();
- /* These must be initialized after undo history is set up. */
- private final UndoRedoAction undoAction;
- private final UndoRedoAction redoAction;
-
-
public OpenRocketDocument(Rocket rocket) {
this(rocket.getDefaultConfiguration());
}
clearUndo();
- undoAction = new UndoRedoAction(UndoRedoAction.UNDO);
- redoAction = new UndoRedoAction(UndoRedoAction.REDO);
-
rocket.addComponentChangeListener(this);
}
}
- public Action getUndoAction() {
- return undoAction;
- }
-
-
- public Action getRedoAction() {
- return redoAction;
- }
-
-
/**
* Clear the undo history.
*/
undoHistory.add(rocket.copyWithOriginalID());
undoDescription.add(null);
undoPosition = 0;
-
- if (undoAction != null)
- undoAction.setAllValues();
- if (redoAction != null)
- redoAction.setAllValues();
+
+ fireUndoRedoChangeEvent();
}
undoDescription.set(undoPosition, nextDescription);
}
- undoAction.setAllValues();
- redoAction.setAllValues();
+ fireUndoRedoChangeEvent();
}
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
if (!isUndoAvailable()) {
logUndoError("Undo not available");
- undoAction.setAllValues();
- redoAction.setAllValues();
+ fireUndoRedoChangeEvent();
return;
}
if (storedDescription != null) {
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
if (!isRedoAvailable()) {
logUndoError("Redo not available");
- undoAction.setAllValues();
- redoAction.setAllValues();
+ fireUndoRedoChangeEvent();
return;
}
if (storedDescription != null) {
/////// Listeners
+ public void addUndoRedoListener( UndoRedoListener listener ) {
+ undoRedoListeners.add(listener);
+ }
+
+ public void removeUndoRedoListener( UndoRedoListener listener ) {
+ undoRedoListeners.remove(listener);
+ }
+
+ private void fireUndoRedoChangeEvent() {
+ UndoRedoListener[] array = undoRedoListeners.toArray(new UndoRedoListener[0]);
+ for (UndoRedoListener l : array) {
+ l.setAllValues();
+ }
+
+ }
+
public void addDocumentChangeListener(DocumentChangeListener listener) {
listeners.add(listener);
}
- /**
- * Inner class to implement undo/redo actions.
- */
- private class UndoRedoAction extends AbstractAction {
- public static final int UNDO = 1;
- public static final int REDO = 2;
-
- private final int type;
-
- // Sole constructor
- public UndoRedoAction(int type) {
- if (type != UNDO && type != REDO) {
- throw new IllegalArgumentException("Unknown type = " + type);
- }
- this.type = type;
- setAllValues();
- }
-
-
- // Actual action to make
- @Override
- public void actionPerformed(ActionEvent e) {
- switch (type) {
- case UNDO:
- log.user("Performing undo, event=" + e);
- undo();
- break;
-
- case REDO:
- log.user("Performing redo, event=" + e);
- redo();
- break;
- }
- }
-
-
- // Set all the values correctly (name and enabled/disabled status)
- public void setAllValues() {
- String name, desc;
- boolean actionEnabled;
-
- switch (type) {
- case UNDO:
- //// Undo
- name = trans.get("OpenRocketDocument.Undo");
- desc = getUndoDescription();
- actionEnabled = isUndoAvailable();
- this.putValue(SMALL_ICON, Icons.EDIT_UNDO);
- break;
-
- case REDO:
- ////Redo
- name = trans.get("OpenRocketDocument.Redo");
- desc = getRedoDescription();
- actionEnabled = isRedoAvailable();
- this.putValue(SMALL_ICON, Icons.EDIT_REDO);
- break;
-
- default:
- throw new BugException("illegal type=" + type);
- }
-
- if (desc != null)
- name = name + " (" + desc + ")";
-
- putValue(NAME, name);
- setEnabled(actionEnabled);
- }
- }
}
--- /dev/null
+package net.sf.openrocket.gui.main;\r
+\r
+import java.awt.event.ActionEvent;\r
+\r
+import javax.swing.AbstractAction;\r
+\r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.document.UndoRedoListener;\r
+import net.sf.openrocket.gui.util.Icons;\r
+import net.sf.openrocket.l10n.Translator;\r
+import net.sf.openrocket.logging.LogHelper;\r
+import net.sf.openrocket.startup.Application;\r
+import net.sf.openrocket.util.BugException;\r
+\r
+/**\r
+ * Inner class to implement undo/redo actions.\r
+ */\r
+public class UndoRedoAction extends AbstractAction implements UndoRedoListener {\r
+ \r
+ // Use Factory mechanism because we want to register the new instance as an\r
+ // UndoRedoListener.\r
+ public static UndoRedoAction newUndoAction( OpenRocketDocument document ) {\r
+ UndoRedoAction undo = new UndoRedoAction( UNDO, document );\r
+ document.addUndoRedoListener(undo);\r
+ return undo;\r
+ }\r
+\r
+ public static UndoRedoAction newRedoAction( OpenRocketDocument document ) {\r
+ UndoRedoAction redo = new UndoRedoAction( REDO, document );\r
+ document.addUndoRedoListener(redo);\r
+ return redo;\r
+ }\r
+\r
+ private static final LogHelper log = Application.getLogger();\r
+ private static final Translator trans = Application.getTranslator();\r
+\r
+ private static final int UNDO = 1;\r
+ private static final int REDO = 2;\r
+ \r
+ private final int type;\r
+ \r
+ private final OpenRocketDocument document;\r
+ \r
+ // Sole constructor\r
+ private UndoRedoAction(int type, OpenRocketDocument document) {\r
+ this.document = document;\r
+ if (type != UNDO && type != REDO) {\r
+ throw new IllegalArgumentException("Unknown type = " + type);\r
+ }\r
+ this.type = type;\r
+ setAllValues();\r
+ }\r
+ \r
+ \r
+ // Actual action to make\r
+ @Override\r
+ public void actionPerformed(ActionEvent e) {\r
+ switch (type) {\r
+ case UNDO:\r
+ log.user("Performing undo, event=" + e);\r
+ document.undo();\r
+ break;\r
+ \r
+ case REDO:\r
+ log.user("Performing redo, event=" + e);\r
+ document.redo();\r
+ break;\r
+ }\r
+ }\r
+ \r
+ \r
+ // Set all the values correctly (name and enabled/disabled status)\r
+ public void setAllValues() {\r
+ String name, desc;\r
+ boolean actionEnabled;\r
+ \r
+ switch (type) {\r
+ case UNDO:\r
+ //// Undo\r
+ name = trans.get("OpenRocketDocument.Undo");\r
+ desc = document.getUndoDescription();\r
+ actionEnabled = document.isUndoAvailable();\r
+ this.putValue(SMALL_ICON, Icons.EDIT_UNDO);\r
+ break;\r
+ \r
+ case REDO:\r
+ ////Redo\r
+ name = trans.get("OpenRocketDocument.Redo");\r
+ desc = document.getRedoDescription();\r
+ actionEnabled = document.isRedoAvailable();\r
+ this.putValue(SMALL_ICON, Icons.EDIT_REDO);\r
+ break;\r
+ \r
+ default:\r
+ throw new BugException("illegal type=" + type);\r
+ }\r
+ \r
+ if (desc != null)\r
+ name = name + " (" + desc + ")";\r
+ \r
+ putValue(NAME, name);\r
+ setEnabled(actionEnabled);\r
+ }\r
+}\r