Refactor doc material loading to OpenRocketDocument
This commit is contained in:
parent
65116fcb58
commit
0d5952cfa3
@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import info.openrocket.core.file.wavefrontobj.export.OBJExportOptions;
|
import info.openrocket.core.file.wavefrontobj.export.OBJExportOptions;
|
||||||
|
import info.openrocket.core.material.Material;
|
||||||
import info.openrocket.core.preferences.ApplicationPreferences;
|
import info.openrocket.core.preferences.ApplicationPreferences;
|
||||||
import info.openrocket.core.preferences.DocumentPreferences;
|
import info.openrocket.core.preferences.DocumentPreferences;
|
||||||
import info.openrocket.core.rocketcomponent.*;
|
import info.openrocket.core.rocketcomponent.*;
|
||||||
@ -33,7 +34,7 @@ import info.openrocket.core.util.ArrayList;
|
|||||||
* - Simulation instances
|
* - Simulation instances
|
||||||
* - the stored file and file save information
|
* - the stored file and file save information
|
||||||
* - undo/redo information
|
* - undo/redo information
|
||||||
*
|
*
|
||||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||||
*/
|
*/
|
||||||
public class OpenRocketDocument implements ComponentChangeListener, StateChangeListener {
|
public class OpenRocketDocument implements ComponentChangeListener, StateChangeListener {
|
||||||
@ -46,65 +47,65 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
*/
|
*/
|
||||||
public static final int UNDO_LEVELS = 50;
|
public static final int UNDO_LEVELS = 50;
|
||||||
/**
|
/**
|
||||||
* The margin of the undo levels. After the number of undo levels exceeds
|
* The margin of the undo levels. After the number of undo levels exceeds
|
||||||
* UNDO_LEVELS by this amount the undo is purged to that length.
|
* UNDO_LEVELS by this amount the undo is purged to that length.
|
||||||
*/
|
*/
|
||||||
public static final int UNDO_MARGIN = 10;
|
public static final int UNDO_MARGIN = 10;
|
||||||
|
|
||||||
public static final String SIMULATION_NAME_PREFIX = "Simulation ";
|
public static final String SIMULATION_NAME_PREFIX = "Simulation ";
|
||||||
|
|
||||||
/** Whether an undo error has already been reported to the user */
|
/** Whether an undo error has already been reported to the user */
|
||||||
private static boolean undoErrorReported = false;
|
private static boolean undoErrorReported = false;
|
||||||
|
|
||||||
private final Rocket rocket;
|
private final Rocket rocket;
|
||||||
|
|
||||||
private final ArrayList<Simulation> simulations = new ArrayList<Simulation>();
|
private final ArrayList<Simulation> simulations = new ArrayList<Simulation>();
|
||||||
private final ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>();
|
private final ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>();
|
||||||
|
|
||||||
// The Photo Settings will be saved in the core module as a map of key values with corresponding content
|
// The Photo Settings will be saved in the core module as a map of key values with corresponding content
|
||||||
private Map<String, String> photoSettings = new HashMap<>();
|
private Map<String, String> photoSettings = new HashMap<>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The undo/redo variables and mechanism are documented in doc/undo-redo-flow.*
|
* The undo/redo variables and mechanism are documented in doc/undo-redo-flow.*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The undo history of the rocket. Whenever a new undo position is created while the
|
* The undo history of the rocket. Whenever a new undo position is created while the
|
||||||
* rocket is in "dirty" state, the rocket is copied here.
|
* rocket is in "dirty" state, the rocket is copied here.
|
||||||
*/
|
*/
|
||||||
private final LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
|
private final LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
|
||||||
private final LinkedList<String> undoDescription = new LinkedList<String>();
|
private final LinkedList<String> undoDescription = new LinkedList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The position in the undoHistory we are currently at. If modifications have been
|
* 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
|
* made to the rocket, the rocket is in "dirty" state and this points to the previous
|
||||||
* "clean" state.
|
* "clean" state.
|
||||||
*/
|
*/
|
||||||
private int undoPosition = -1; // Illegal position, init in constructor
|
private int undoPosition = -1; // Illegal position, init in constructor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of the next action that modifies this rocket.
|
* The description of the next action that modifies this rocket.
|
||||||
*/
|
*/
|
||||||
private String nextDescription = null;
|
private String nextDescription = null;
|
||||||
private String storedDescription = null;
|
private String storedDescription = null;
|
||||||
|
|
||||||
|
|
||||||
private final ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2);
|
private final ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2);
|
||||||
|
|
||||||
private File file = null;
|
private File file = null;
|
||||||
private int modID = -1;
|
private int modID = -1;
|
||||||
private int savedID = -1;
|
private int savedID = -1;
|
||||||
|
|
||||||
private final StorageOptions storageOptions = new StorageOptions();
|
private final StorageOptions storageOptions = new StorageOptions();
|
||||||
private final OBJExportOptions objOptions;
|
private final OBJExportOptions objOptions;
|
||||||
|
|
||||||
private final DecalRegistry decalRegistry = new DecalRegistry();
|
private final DecalRegistry decalRegistry = new DecalRegistry();
|
||||||
|
|
||||||
private final List<DocumentChangeListener> listeners = new ArrayList<DocumentChangeListener>();
|
private final List<DocumentChangeListener> listeners = new ArrayList<DocumentChangeListener>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main constructor, enable events in the rocket
|
* main constructor, enable events in the rocket
|
||||||
* and initializes the document
|
* and initializes the document
|
||||||
* @param rocket the rocket to be used in the document
|
* @param rocket the rocket to be used in the document
|
||||||
*/
|
*/
|
||||||
OpenRocketDocument(Rocket rocket) {
|
OpenRocketDocument(Rocket rocket) {
|
||||||
@ -113,7 +114,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
rocket.enableEvents();
|
rocket.enableEvents();
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initializes the document, clearing the undo cache and
|
* initializes the document, clearing the undo cache and
|
||||||
* setting itself as a listener for changes in the rocket
|
* setting itself as a listener for changes in the rocket
|
||||||
@ -122,7 +123,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
clearUndo();
|
clearUndo();
|
||||||
rocket.addComponentChangeListener(this);
|
rocket.addComponentChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds a customExpression into the list
|
* adds a customExpression into the list
|
||||||
* @param expression the expression to be added
|
* @param expression the expression to be added
|
||||||
@ -130,10 +131,10 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public void addCustomExpression(CustomExpression expression) {
|
public void addCustomExpression(CustomExpression expression) {
|
||||||
if (customExpressions.contains(expression)) {
|
if (customExpressions.contains(expression)) {
|
||||||
log.info(Markers.USER_MARKER, "Could not add custom expression " + expression.getName() + " to document as document already has a matching expression.");
|
log.info(Markers.USER_MARKER, "Could not add custom expression " + expression.getName() + " to document as document already has a matching expression.");
|
||||||
}
|
}
|
||||||
customExpressions.add(expression);
|
customExpressions.add(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes custom expression from the document
|
* Removes custom expression from the document
|
||||||
* @param expression
|
* @param expression
|
||||||
@ -141,44 +142,44 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public void removeCustomExpression(CustomExpression expression) {
|
public void removeCustomExpression(CustomExpression expression) {
|
||||||
customExpressions.remove(expression);
|
customExpressions.remove(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:LOW:this leaves the object custom expression exposed, is it supposed to be like that?
|
//TODO:LOW:this leaves the object custom expression exposed, is it supposed to be like that?
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<CustomExpression> getCustomExpressions() {
|
public List<CustomExpression> getCustomExpressions() {
|
||||||
return customExpressions;
|
return customExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns a set of all the flight data types defined or available in any way in the rocket document
|
* @returns a set of all the flight data types defined or available in any way in the rocket document
|
||||||
*/
|
*/
|
||||||
public Set<FlightDataType> getFlightDataTypes() {
|
public Set<FlightDataType> getFlightDataTypes() {
|
||||||
Set<FlightDataType> allTypes = new LinkedHashSet<FlightDataType>();
|
Set<FlightDataType> allTypes = new LinkedHashSet<FlightDataType>();
|
||||||
|
|
||||||
// built in
|
// built in
|
||||||
Collections.addAll(allTypes, FlightDataType.ALL_TYPES);
|
Collections.addAll(allTypes, FlightDataType.ALL_TYPES);
|
||||||
|
|
||||||
// custom expressions
|
// custom expressions
|
||||||
for (CustomExpression exp : customExpressions) {
|
for (CustomExpression exp : customExpressions) {
|
||||||
allTypes.add(exp.getType());
|
allTypes.add(exp.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulation listeners
|
// simulation listeners
|
||||||
for (Simulation sim : simulations) {
|
for (Simulation sim : simulations) {
|
||||||
for (SimulationExtension c : sim.getSimulationExtensions()) {
|
for (SimulationExtension c : sim.getSimulationExtensions()) {
|
||||||
allTypes.addAll(c.getFlightDataTypes());
|
allTypes.addAll(c.getFlightDataTypes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// imported data
|
// imported data
|
||||||
/// not implemented yet
|
/// not implemented yet
|
||||||
|
|
||||||
|
|
||||||
return allTypes;
|
return allTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the rocket in the document
|
* gets the rocket in the document
|
||||||
* @return the rocket in the document
|
* @return the rocket in the document
|
||||||
@ -186,7 +187,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public Rocket getRocket() {
|
public Rocket getRocket() {
|
||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the selected configuration from the rocket
|
* returns the selected configuration from the rocket
|
||||||
* @return selected configuration from the rocket
|
* @return selected configuration from the rocket
|
||||||
@ -194,7 +195,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public FlightConfiguration getSelectedConfiguration() {
|
public FlightConfiguration getSelectedConfiguration() {
|
||||||
return rocket.getSelectedConfiguration();
|
return rocket.getSelectedConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the File handler object for the document
|
* returns the File handler object for the document
|
||||||
* @return the File handler object for the document
|
* @return the File handler object for the document
|
||||||
@ -220,7 +221,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the file handler object for the document
|
* set the file handler object for the document
|
||||||
* @param file the new file handler object
|
* @param file the new file handler object
|
||||||
@ -228,7 +229,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public void setFile(File file) {
|
public void setFile(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns if the current rocket is saved
|
* returns if the current rocket is saved
|
||||||
* @return if the current rocket is saved
|
* @return if the current rocket is saved
|
||||||
@ -236,7 +237,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public boolean isSaved() {
|
public boolean isSaved() {
|
||||||
return rocket.getModID() + modID == savedID;
|
return rocket.getModID() + modID == savedID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the current rocket as saved, and none if false is given
|
* sets the current rocket as saved, and none if false is given
|
||||||
* @param saved if the current rocket or none will be set to save
|
* @param saved if the current rocket or none will be set to save
|
||||||
@ -247,7 +248,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
else
|
else
|
||||||
this.savedID = rocket.getModID() + modID;
|
this.savedID = rocket.getModID() + modID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the default storage options for this document.
|
* Retrieve the default storage options for this document.
|
||||||
*
|
*
|
||||||
@ -261,25 +262,25 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
return objOptions;
|
return objOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the decal list used in the document
|
* returns the decal list used in the document
|
||||||
* @return the decal list registered in the document
|
* @return the decal list registered in the document
|
||||||
*/
|
*/
|
||||||
public Collection<DecalImage> getDecalList() {
|
public Collection<DecalImage> getDecalList() {
|
||||||
|
|
||||||
return decalRegistry.getDecalList();
|
return decalRegistry.getDecalList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the number of times the given decal was used
|
* returns the number of times the given decal was used
|
||||||
* @param img the decal to be counted
|
* @param img the decal to be counted
|
||||||
* @return the number of times
|
* @return the number of times
|
||||||
*/
|
*/
|
||||||
public int countDecalUsage(DecalImage img) {
|
public int countDecalUsage(DecalImage img) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
Iterator<RocketComponent> it = rocket.iterator();
|
Iterator<RocketComponent> it = rocket.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
RocketComponent c = it.next();
|
RocketComponent c = it.next();
|
||||||
@ -290,7 +291,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: LOW: move this method to rocketComponent, Appearance and decal
|
//TODO: LOW: move this method to rocketComponent, Appearance and decal
|
||||||
//I see 3 layers of object accessed, seems unsafe
|
//I see 3 layers of object accessed, seems unsafe
|
||||||
/**
|
/**
|
||||||
@ -333,7 +334,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets a unique identification for the given decal
|
* gets a unique identification for the given decal
|
||||||
* @param img the decal to be made unique
|
* @param img the decal to be made unique
|
||||||
@ -345,7 +346,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return decalRegistry.makeUniqueImage(img);
|
return decalRegistry.makeUniqueImage(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the decal image from an attachment
|
* gets the decal image from an attachment
|
||||||
* @param a the attachment
|
* @param a the attachment
|
||||||
@ -354,7 +355,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public DecalImage getDecalImage(Attachment a) {
|
public DecalImage getDecalImage(Attachment a) {
|
||||||
return decalRegistry.getDecalImage(a);
|
return decalRegistry.getDecalImage(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets a list of simulations in the document
|
* gets a list of simulations in the document
|
||||||
* @return the simulations in the document
|
* @return the simulations in the document
|
||||||
@ -362,7 +363,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public List<Simulation> getSimulations() {
|
public List<Simulation> getSimulations() {
|
||||||
return simulations.clone();
|
return simulations.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the number of simulations in the document
|
* gets the number of simulations in the document
|
||||||
* @return the number of simulations in the document
|
* @return the number of simulations in the document
|
||||||
@ -370,7 +371,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public int getSimulationCount() {
|
public int getSimulationCount() {
|
||||||
return simulations.size();
|
return simulations.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the the Nth simulation from the document
|
* the the Nth simulation from the document
|
||||||
* @param n simulation index
|
* @param n simulation index
|
||||||
@ -379,7 +380,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public Simulation getSimulation(int n) {
|
public Simulation getSimulation(int n) {
|
||||||
return simulations.get(n);
|
return simulations.get(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the index of the given simulation
|
* gets the index of the given simulation
|
||||||
* @param simulation the simulation being searched
|
* @param simulation the simulation being searched
|
||||||
@ -388,7 +389,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public int getSimulationIndex(Simulation simulation) {
|
public int getSimulationIndex(Simulation simulation) {
|
||||||
return simulations.indexOf(simulation);
|
return simulations.indexOf(simulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds simulation into the document
|
* adds simulation into the document
|
||||||
* fires document change event
|
* fires document change event
|
||||||
@ -397,7 +398,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public void addSimulation(Simulation simulation) {
|
public void addSimulation(Simulation simulation) {
|
||||||
addSimulation(simulation, simulations.size());
|
addSimulation(simulation, simulations.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds the simulation to the Nth index, overwriting if there is already one
|
* adds the simulation to the Nth index, overwriting if there is already one
|
||||||
* fires change document event
|
* fires change document event
|
||||||
@ -412,7 +413,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes the specific simulation from the list
|
* removes the specific simulation from the list
|
||||||
* @param simulation the simulation to be removed
|
* @param simulation the simulation to be removed
|
||||||
@ -421,7 +422,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
simulations.remove(simulation);
|
simulations.remove(simulation);
|
||||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes the Nth simulation from the document
|
* removes the Nth simulation from the document
|
||||||
* fires document change event
|
* fires document change event
|
||||||
@ -433,7 +434,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||||
return simulation;
|
return simulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes the flight configuration and simulation with the specific id
|
* removes the flight configuration and simulation with the specific id
|
||||||
* @param configId
|
* @param configId
|
||||||
@ -458,13 +459,13 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a unique name suitable for the next simulation. The name begins
|
* 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
|
* with {@link #SIMULATION_NAME_PREFIX} and has a unique number larger than any
|
||||||
* previous simulation.
|
* previous simulation.
|
||||||
*
|
*
|
||||||
* @return the new name.
|
* @return the new name.
|
||||||
*/
|
*/
|
||||||
public String getNextSimulationName() {
|
public String getNextSimulationName() {
|
||||||
@ -482,39 +483,39 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return SIMULATION_NAME_PREFIX + (maxValue + 1);
|
return SIMULATION_NAME_PREFIX + (maxValue + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an undo point at this position. This method should be called *before* any
|
* Adds an undo point at this position. This method should be called *before* any
|
||||||
* action that is to be undoable. All actions after the call will be undone by a
|
* action that is to be undoable. All actions after the call will be undone by a
|
||||||
* single "Undo" action.
|
* single "Undo" action.
|
||||||
* <p>
|
* <p>
|
||||||
* The description should be a short, descriptive string of the actions that will
|
* The description should be a short, descriptive string of the actions that will
|
||||||
* follow. This is shown to the user e.g. in the Edit-menu, for example
|
* follow. This is shown to the user e.g. in the Edit-menu, for example
|
||||||
* "Undo (Modify body tube)". If the actions are not known (in general should not
|
* "Undo (Modify body tube)". If the actions are not known (in general should not
|
||||||
* be the case!) description may be null.
|
* be the case!) description may be null.
|
||||||
* <p>
|
* <p>
|
||||||
* If this method is called successively without any change events occurring between the
|
* If this method is called successively without any change events occurring between the
|
||||||
* calls, only the last call will have any effect.
|
* calls, only the last call will have any effect.
|
||||||
*
|
*
|
||||||
* @param description A short description of the following actions.
|
* @param description A short description of the following actions.
|
||||||
*/
|
*/
|
||||||
public void addUndoPosition(String description) {
|
public void addUndoPosition(String description) {
|
||||||
|
|
||||||
checkDescription(description);
|
checkDescription(description);
|
||||||
|
|
||||||
// Check whether modifications have been done since last call
|
// Check whether modifications have been done since last call
|
||||||
if(isCheckNoModification(description))
|
if(isCheckNoModification(description))
|
||||||
return;
|
return;
|
||||||
log.info("Adding undo position '" + description + "' to " + this + ", document is in unclean state");
|
log.info("Adding undo position '" + description + "' to " + this + ", document is in unclean state");
|
||||||
checkUndoPositionConsistency();
|
checkUndoPositionConsistency();
|
||||||
addStateToUndoHistory(description);
|
addStateToUndoHistory(description);
|
||||||
|
|
||||||
maintainMaximumUndoSize();
|
maintainMaximumUndoSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void maintainMaximumUndoSize() {
|
private void maintainMaximumUndoSize() {
|
||||||
if (undoHistory.size() > UNDO_LEVELS + UNDO_MARGIN && undoPosition > UNDO_MARGIN) {
|
if (undoHistory.size() > UNDO_LEVELS + UNDO_MARGIN && undoPosition > UNDO_MARGIN) {
|
||||||
@ -539,7 +540,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if there was or not modification, and logs
|
* checks if there was or not modification, and logs
|
||||||
*
|
*
|
||||||
* @param description the description to be used in the log
|
* @param description the description to be used in the log
|
||||||
* @return if there was or not modification
|
* @return if there was or not modification
|
||||||
*/
|
*/
|
||||||
@ -552,11 +553,11 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if the document already has a stored undo description
|
* checks if the document already has a stored undo description
|
||||||
* logs if it has
|
* logs if it has
|
||||||
*
|
*
|
||||||
* @param description undo description to be logged
|
* @param description undo description to be logged
|
||||||
*/
|
*/
|
||||||
private void checkDescription(String description) {
|
private void checkDescription(String description) {
|
||||||
@ -576,15 +577,15 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
}
|
}
|
||||||
removeRedoInfo();
|
removeRedoInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a time-limited undoable operation. After the operation {@link #stopUndo()}
|
* Start a time-limited undoable operation. After the operation {@link #stopUndo()}
|
||||||
* must be called, which will restore the previous undo description into effect.
|
* 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
|
* 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
|
* undo cannot be nested, and no other undo operations may be called between
|
||||||
* the start and stop calls.
|
* the start and stop calls.
|
||||||
*
|
*
|
||||||
* @param description Description of the following undoable operations.
|
* @param description Description of the following undoable operations.
|
||||||
*/
|
*/
|
||||||
public void startUndo(String description) {
|
public void startUndo(String description) {
|
||||||
@ -597,7 +598,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
addUndoPosition(description);
|
addUndoPosition(description);
|
||||||
storedDescription = store;
|
storedDescription = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End the previous time-limited undoable operation. This must be called after
|
* End the previous time-limited undoable operation. This must be called after
|
||||||
* {@link #startUndo(String)} has been called before any other undo operations are
|
* {@link #startUndo(String)} has been called before any other undo operations are
|
||||||
@ -610,8 +611,8 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
storedDescription = null;
|
storedDescription = null;
|
||||||
addUndoPosition(stored);
|
addUndoPosition(stored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the undo history.
|
* Clear the undo history.
|
||||||
*/
|
*/
|
||||||
@ -619,18 +620,18 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
//log.info("Clearing undo history of " + this);
|
//log.info("Clearing undo history of " + this);
|
||||||
undoHistory.clear();
|
undoHistory.clear();
|
||||||
undoDescription.clear();
|
undoDescription.clear();
|
||||||
|
|
||||||
undoHistory.add(rocket.copyWithOriginalID());
|
undoHistory.add(rocket.copyWithOriginalID());
|
||||||
undoDescription.add(null);
|
undoDescription.add(null);
|
||||||
undoPosition = 0;
|
undoPosition = 0;
|
||||||
|
|
||||||
fireUndoRedoChangeEvent();
|
fireUndoRedoChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentChanged(ComponentChangeEvent e) {
|
public void componentChanged(ComponentChangeEvent e) {
|
||||||
|
|
||||||
if (!e.isUndoChange()) {
|
if (!e.isUndoChange()) {
|
||||||
if (undoPosition < undoHistory.size() - 1) {
|
if (undoPosition < undoHistory.size() - 1) {
|
||||||
log.info("Rocket changed while in undo history, removing redo information for " + this +
|
log.info("Rocket changed while in undo history, removing redo information for " + this +
|
||||||
@ -640,7 +641,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
removeRedoInfo();
|
removeRedoInfo();
|
||||||
setLatestDescription();
|
setLatestDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
fireUndoRedoChangeEvent();
|
fireUndoRedoChangeEvent();
|
||||||
fireDocumentChangeEvent(new DocumentChangeEvent(e.getSource()));
|
fireDocumentChangeEvent(new DocumentChangeEvent(e.getSource()));
|
||||||
}
|
}
|
||||||
@ -667,8 +668,8 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
undoDescription.removeLast();
|
undoDescription.removeLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether undo action is available.
|
* Return whether undo action is available.
|
||||||
* @return <code>true</code> if undo can be performed
|
* @return <code>true</code> if undo can be performed
|
||||||
@ -676,10 +677,10 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public boolean isUndoAvailable() {
|
public boolean isUndoAvailable() {
|
||||||
if (undoPosition > 0)
|
if (undoPosition > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !isCleanState();
|
return !isCleanState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the description of what action would be undone if undo is called.
|
* Return the description of what action would be undone if undo is called.
|
||||||
* @return the description what would be undone, or <code>null</code> if description unavailable.
|
* @return the description what would be undone, or <code>null</code> if description unavailable.
|
||||||
@ -687,15 +688,15 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public String getUndoDescription() {
|
public String getUndoDescription() {
|
||||||
if (!isUndoAvailable())
|
if (!isUndoAvailable())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (isCleanState()) {
|
if (isCleanState()) {
|
||||||
return undoDescription.get(undoPosition - 1);
|
return undoDescription.get(undoPosition - 1);
|
||||||
} else {
|
} else {
|
||||||
return undoDescription.get(undoPosition);
|
return undoDescription.get(undoPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether redo action is available.
|
* Return whether redo action is available.
|
||||||
* @return <code>true</code> if redo can be performed
|
* @return <code>true</code> if redo can be performed
|
||||||
@ -703,7 +704,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public boolean isRedoAvailable() {
|
public boolean isRedoAvailable() {
|
||||||
return undoPosition < undoHistory.size() - 1;
|
return undoPosition < undoHistory.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the description of what action would be redone if redo is called.
|
* Return the description of what action would be redone if redo is called.
|
||||||
* @return the description of what would be redone, or <code>null</code> if description unavailable.
|
* @return the description of what would be redone, or <code>null</code> if description unavailable.
|
||||||
@ -711,11 +712,11 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public String getRedoDescription() {
|
public String getRedoDescription() {
|
||||||
if (!isRedoAvailable())
|
if (!isRedoAvailable())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return undoDescription.get(undoPosition);
|
return undoDescription.get(undoPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform undo operation on the rocket.
|
* Perform undo operation on the rocket.
|
||||||
*/
|
*/
|
||||||
@ -730,9 +731,9 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
if (storedDescription != null) {
|
if (storedDescription != null) {
|
||||||
logUndoError("undo() called with storedDescription=" + storedDescription);
|
logUndoError("undo() called with storedDescription=" + storedDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update history position
|
// Update history position
|
||||||
|
|
||||||
if (isCleanState()) {
|
if (isCleanState()) {
|
||||||
// We are in a clean state, simply move backwards in history
|
// We are in a clean state, simply move backwards in history
|
||||||
undoPosition--;
|
undoPosition--;
|
||||||
@ -744,13 +745,13 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
undoHistory.add(rocket.copyWithOriginalID());
|
undoHistory.add(rocket.copyWithOriginalID());
|
||||||
undoDescription.add(null);
|
undoDescription.add(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
rocket.checkComponentStructure();
|
rocket.checkComponentStructure();
|
||||||
rocket.loadFrom(undoHistory.get(undoPosition));
|
rocket.loadFrom(undoHistory.get(undoPosition));
|
||||||
rocket.checkComponentStructure();
|
rocket.checkComponentStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform redo operation on the rocket.
|
* Perform redo operation on the rocket.
|
||||||
*/
|
*/
|
||||||
@ -765,20 +766,20 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
if (storedDescription != null) {
|
if (storedDescription != null) {
|
||||||
logUndoError("redo() called with storedDescription=" + storedDescription);
|
logUndoError("redo() called with storedDescription=" + storedDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
undoPosition++;
|
undoPosition++;
|
||||||
|
|
||||||
rocket.loadFrom(undoHistory.get(undoPosition).copyWithOriginalID());
|
rocket.loadFrom(undoHistory.get(undoPosition).copyWithOriginalID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean isCleanState() {
|
private boolean isCleanState() {
|
||||||
return rocket.getModID() == undoHistory.get(undoPosition).getModID();
|
return rocket.getModID() == undoHistory.get(undoPosition).getModID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a non-fatal undo/redo error or inconsistency. Reports it to the user the first
|
* Log a non-fatal undo/redo error or inconsistency. Reports it to the user the first
|
||||||
* time it occurs, but not on subsequent times. Logs automatically the undo system state.
|
* time it occurs, but not on subsequent times. Logs automatically the undo system state.
|
||||||
*/
|
*/
|
||||||
private void logUndoError(String error) {
|
private void logUndoError(String error) {
|
||||||
@ -786,64 +787,64 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState() +
|
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState() +
|
||||||
" nextDescription=" + nextDescription + " storedDescription=" + storedDescription,
|
" nextDescription=" + nextDescription + " storedDescription=" + storedDescription,
|
||||||
new Throwable());
|
new Throwable());
|
||||||
|
|
||||||
if (!undoErrorReported) {
|
if (!undoErrorReported) {
|
||||||
undoErrorReported = true;
|
undoErrorReported = true;
|
||||||
Application.getExceptionHandler().handleErrorCondition("Undo/Redo error: " + error);
|
Application.getExceptionHandler().handleErrorCondition("Undo/Redo error: " + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a copy of this document. The rocket is copied with original ID's, the default
|
* Return a copy of this document. The rocket is copied with original ID's, the default
|
||||||
* motor configuration ID is maintained and the simulations are copied to the new rocket.
|
* motor configuration ID is maintained and the simulations are copied to the new rocket.
|
||||||
* No undo/redo information or file storage information is maintained.
|
* No undo/redo information or file storage information is maintained.
|
||||||
*
|
*
|
||||||
* This function is used from the Optimization routine to store alternatives of the same rocket.
|
* This function is used from the Optimization routine to store alternatives of the same rocket.
|
||||||
* For now we can assume that the copy returned does not have any of the attachment factories in place.
|
* For now we can assume that the copy returned does not have any of the attachment factories in place.
|
||||||
*
|
*
|
||||||
* @return a copy of this document.
|
* @return a copy of this document.
|
||||||
*/
|
*/
|
||||||
public OpenRocketDocument copy() {
|
public OpenRocketDocument copy() {
|
||||||
Rocket rocketCopy = rocket.copyWithOriginalID();
|
Rocket rocketCopy = rocket.copyWithOriginalID();
|
||||||
OpenRocketDocument documentCopy = OpenRocketDocumentFactory.createDocumentFromRocket(rocketCopy);
|
OpenRocketDocument documentCopy = OpenRocketDocumentFactory.createDocumentFromRocket(rocketCopy);
|
||||||
|
|
||||||
for (Simulation s : simulations) {
|
for (Simulation s : simulations) {
|
||||||
documentCopy.addSimulation(s.duplicateSimulation(rocketCopy));
|
documentCopy.addSimulation(s.duplicateSimulation(rocketCopy));
|
||||||
}
|
}
|
||||||
return documentCopy;
|
return documentCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////// Listeners
|
/////// Listeners
|
||||||
|
|
||||||
public void addUndoRedoListener(UndoRedoListener listener) {
|
public void addUndoRedoListener(UndoRedoListener listener) {
|
||||||
undoRedoListeners.add(listener);
|
undoRedoListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeUndoRedoListener(UndoRedoListener listener) {
|
public void removeUndoRedoListener(UndoRedoListener listener) {
|
||||||
undoRedoListeners.remove(listener);
|
undoRedoListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void fireUndoRedoChangeEvent() {
|
private void fireUndoRedoChangeEvent() {
|
||||||
UndoRedoListener[] array = undoRedoListeners.toArray(new UndoRedoListener[0]);
|
UndoRedoListener[] array = undoRedoListeners.toArray(new UndoRedoListener[0]);
|
||||||
for (UndoRedoListener l : array) {
|
for (UndoRedoListener l : array) {
|
||||||
l.setAllValues();
|
l.setAllValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDocumentChangeListener(DocumentChangeListener listener) {
|
public void addDocumentChangeListener(DocumentChangeListener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeDocumentChangeListener(DocumentChangeListener listener) {
|
public void removeDocumentChangeListener(DocumentChangeListener listener) {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
public void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
||||||
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
||||||
for (DocumentChangeListener l : array) {
|
for (DocumentChangeListener l : array) {
|
||||||
@ -857,16 +858,16 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
l.documentSaving(event);
|
l.documentSaving(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toSimulationDetail(){
|
public String toSimulationDetail(){
|
||||||
StringBuilder str = new StringBuilder();
|
StringBuilder str = new StringBuilder();
|
||||||
str.append(">> Dumping simulation list:\n");
|
str.append(">> Dumping simulation list:\n");
|
||||||
int simNum = 0;
|
int simNum = 0;
|
||||||
for( Simulation s : this.simulations ){
|
for( Simulation s : this.simulations ){
|
||||||
str.append(String.format(" [%d] %s (%s) \n", simNum, s.getName(), s.getId().toShortKey() ));
|
str.append(String.format(" [%d] %s (%s) \n", simNum, s.getName(), s.getId().toShortKey() ));
|
||||||
simNum++;
|
simNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str.toString();
|
return str.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -881,4 +882,21 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
|
|||||||
public DocumentPreferences getDocumentPreferences() {
|
public DocumentPreferences getDocumentPreferences() {
|
||||||
return docPrefs;
|
return docPrefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all materials that are user-defined and document materials to the document material database.
|
||||||
|
*/
|
||||||
|
public void reloadDocumentMaterials() {
|
||||||
|
for (RocketComponent c : getRocket()) {
|
||||||
|
List<Material> materials = c.getAllMaterials();
|
||||||
|
if (materials == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Material m : materials) {
|
||||||
|
if (m.isUserDefined() && m.isDocumentMaterial()) {
|
||||||
|
getDocumentPreferences().addMaterial(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -246,23 +246,6 @@ public class GeneralRocketLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load all materials that are user-defined and document materials to the document material database.
|
|
||||||
*/
|
|
||||||
private void loadMaterialsToDocument() {
|
|
||||||
for (RocketComponent c : doc.getRocket()) {
|
|
||||||
List<Material> materials = c.getAllMaterials();
|
|
||||||
if (materials == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (Material m : materials) {
|
|
||||||
if (m.isUserDefined() && m.isDocumentMaterial()) {
|
|
||||||
doc.getDocumentPreferences().addMaterial(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadUsing(RocketLoader loader, InputStream source, String fileName) throws RocketLoadException {
|
private void loadUsing(RocketLoader loader, InputStream source, String fileName) throws RocketLoadException {
|
||||||
warnings.clear();
|
warnings.clear();
|
||||||
DocumentLoadingContext context = new DocumentLoadingContext();
|
DocumentLoadingContext context = new DocumentLoadingContext();
|
||||||
@ -273,6 +256,6 @@ public class GeneralRocketLoader {
|
|||||||
warnings.addAll(loader.getWarnings());
|
warnings.addAll(loader.getWarnings());
|
||||||
|
|
||||||
// Check for custom materials that need to be added to the document material database
|
// Check for custom materials that need to be added to the document material database
|
||||||
loadMaterialsToDocument();
|
doc.reloadDocumentMaterials();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user