Updates for 0.9.5
[debian/openrocket] / src / net / sf / openrocket / document / OpenRocketDocument.java
index ae6c886c833c081c7cbbb3fa22de321bbadea171..83c4b0b7ebeba0c15f5860bafde4c75a161e07a8 100644 (file)
@@ -10,10 +10,14 @@ 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.rocketcomponent.ComponentChangeEvent;
 import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
 import net.sf.openrocket.rocketcomponent.Configuration;
 import net.sf.openrocket.rocketcomponent.Rocket;
+import net.sf.openrocket.util.BugException;
 import net.sf.openrocket.util.Icons;
 
 
@@ -29,6 +33,8 @@ public class OpenRocketDocument implements ComponentChangeListener {
        public static final int UNDO_MARGIN = 10;
 
        
+       public static final String SIMULATION_NAME_PREFIX = "Simulation ";
+       
        private final Rocket rocket;
        private final Configuration configuration;
 
@@ -40,6 +46,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
        private LinkedList<String> undoDescription = new LinkedList<String>();
        
        private String nextDescription = null;
+       private String storedDescription = null;
        
        
        private File file = null;
@@ -48,6 +55,9 @@ public class OpenRocketDocument implements ComponentChangeListener {
        private final StorageOptions storageOptions = new StorageOptions();
        
        
+       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;
@@ -62,16 +72,12 @@ public class OpenRocketDocument implements ComponentChangeListener {
                this.configuration = configuration;
                this.rocket = configuration.getRocket();
                
-               undoHistory.add(rocket.copy());
-               undoDescription.add(null);
-               undoPosition = 0;
+               clearUndo();
                
                undoAction = new UndoRedoAction(UndoRedoAction.UNDO);
                redoAction = new UndoRedoAction(UndoRedoAction.REDO);
                
                rocket.addComponentChangeListener(this);
-               
-               
        }
        
        
@@ -135,17 +141,43 @@ public class OpenRocketDocument implements ComponentChangeListener {
        }
        public void addSimulation(Simulation simulation) {
                simulations.add(simulation);
+               fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
        }
        public void addSimulation(Simulation simulation, int n) {
                simulations.add(n, simulation);
+               fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
        }
        public void removeSimulation(Simulation simulation) {
                simulations.remove(simulation);
+               fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
        }
        public Simulation removeSimulation(int n) {
-               return simulations.remove(n);
+               Simulation simulation = simulations.remove(n);
+               fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
+               return simulation;
        }
        
+       /**
+        * Return a unique name suitable for the next simulation.  The name begins
+        * with {@link #SIMULATION_NAME_PREFIX} and has a unique number larger than any
+        * previous simulation.
+        * 
+        * @return      the new name.
+        */
+       public String getNextSimulationName() {
+               // Generate unique name for the simulation
+               int maxValue = 0;
+               for (Simulation s: simulations) {
+                       String name = s.getName();
+                       if (name.startsWith(SIMULATION_NAME_PREFIX)) {
+                               try {
+                                       maxValue = Math.max(maxValue, 
+                                                       Integer.parseInt(name.substring(SIMULATION_NAME_PREFIX.length())));
+                               } catch (NumberFormatException ignore) { }
+                       }
+               }
+               return SIMULATION_NAME_PREFIX + (maxValue+1);
+       }
        
        
        /**
@@ -202,6 +234,31 @@ public class OpenRocketDocument implements ComponentChangeListener {
        }
 
        
+       /**
+        * Start a time-limited undoable operation.  After the operation {@link #stopUndo()}
+        * must be called, which will restore the previous undo description into effect.
+        * Only one level of start-stop undo descriptions is supported, i.e. start-stop
+        * undo cannot be nested, and no other undo operations may be called between
+        * the start and stop calls.
+        * 
+        * @param description   Description of the following undoable operations.
+        */
+       public void startUndo(String description) {
+               storedDescription = nextDescription;
+               addUndoPosition(description);
+       }
+       
+       /**
+        * End the previous time-limited undoable operation.  This must be called after
+        * {@link #startUndo(String)} has been called before any other undo operations are
+        * performed.
+        */
+       public void stopUndo() {
+               addUndoPosition(storedDescription);
+               storedDescription = null;
+       }
+       
+       
        public Action getUndoAction() {
                return undoAction;
        }
@@ -212,6 +269,24 @@ public class OpenRocketDocument implements ComponentChangeListener {
        }
        
        
+       /**
+        * Clear the undo history.
+        */
+       public void clearUndo() {
+               undoHistory.clear();
+               undoDescription.clear();
+               
+               undoHistory.add(rocket.copy());
+               undoDescription.add(null);
+               undoPosition = 0;
+               
+               if (undoAction != null)
+                       undoAction.setAllValues();
+               if (redoAction != null)
+                       redoAction.setAllValues();
+       }
+       
+       
        @Override
        public void componentChanged(ComponentChangeEvent e) {
                
@@ -301,6 +376,24 @@ public class OpenRocketDocument implements ComponentChangeListener {
        
        
        
+       ///////  Listeners
+       
+       public void addDocumentChangeListener(DocumentChangeListener listener) {
+               listeners.add(listener);
+       }
+       
+       public void removeDocumentChangeListener(DocumentChangeListener listener) {
+               listeners.remove(listener);
+       }
+       
+       protected void fireDocumentChangeEvent(DocumentChangeEvent event) {
+               DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
+               for (DocumentChangeListener l: array) {
+                       l.documentChanged(event);
+               }
+       }
+       
+       
        
        
        /**
@@ -357,7 +450,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
                                break;
                                
                        default:
-                               throw new RuntimeException("EEEK!");
+                               throw new BugException("illegal type="+type);
                        }
                        
                        if (desc != null)