import java.awt.Point;
import java.awt.Toolkit;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import net.sf.openrocket.database.Databases;
import net.sf.openrocket.document.Simulation;
+import net.sf.openrocket.gui.main.ExceptionHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.BodyComponent;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.RK4Simulator;
import net.sf.openrocket.simulation.SimulationConditions;
import net.sf.openrocket.unit.UnitGroup;
- private static final String VERSION = "0.9.0";
+ private static final String BUILD_VERSION;
+ private static final String BUILD_SOURCE;
+ public static final String DEFAULT_BUILD_SOURCE = "default";
+
+ static {
+ try {
+ InputStream is = ClassLoader.getSystemResourceAsStream("build.properties");
+ if (is == null) {
+ throw new MissingResourceException(
+ "build.properties not found, distribution built wrong" +
+ " path:"+System.getProperty("java.class.path"),
+ "build.properties", "build.version");
+ }
+
+ Properties props = new Properties();
+ props.load(is);
+ is.close();
+
+ BUILD_VERSION = props.getProperty("build.version");
+ if (BUILD_VERSION == null) {
+ throw new MissingResourceException(
+ "build.version not found in property file",
+ "build.properties", "build.version");
+ }
+
+ BUILD_SOURCE = props.getProperty("build.source");
+
+ } catch (IOException e) {
+ throw new MissingResourceException(
+ "Error reading build.properties",
+ "build.properties", "build.version");
+ }
+ }
public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition";
public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation";
+ // Preferences related to data export
+ public static final String EXPORT_FIELD_SEPARATOR = "ExportFieldSeparator";
+ public static final String EXPORT_SIMULATION_COMMENT = "ExportSimulationComment";
+ public static final String EXPORT_FIELD_NAME_COMMENT = "ExportFieldDescriptionComment";
+ public static final String EXPORT_EVENT_COMMENTS = "ExportEventComments";
+ public static final String EXPORT_COMMENT_CHARACTER = "ExportCommentCharacter";
+
+ public static final String PLOT_SHOW_POINTS = "ShowPlotPoints";
/**
* Node to this application's preferences.
+ * @deprecated Use the static methods instead.
*/
+ @Deprecated
public static final Preferences NODE;
+ private static final Preferences PREFNODE;
static {
throw new RuntimeException("Unable to clear preference node",e);
}
}
- NODE = root.node(NODENAME);
+ PREFNODE = root.node(NODENAME);
+ NODE = PREFNODE;
}
private static final Material DEFAULT_LINE_MATERIAL =
- Databases.findMaterial(Material.Type.LINE, "Elastic cord (round 2mm, 1/16 in)", 0.0018);
+ Databases.findMaterial(Material.Type.LINE, "Elastic cord (round 2mm, 1/16 in)",
+ 0.0018, false);
private static final Material DEFAULT_SURFACE_MATERIAL =
- Databases.findMaterial(Material.Type.SURFACE, "Ripstop nylon", 0.067);
+ Databases.findMaterial(Material.Type.SURFACE, "Ripstop nylon", 0.067, false);
private static final Material DEFAULT_BULK_MATERIAL =
- Databases.findMaterial(Material.Type.BULK, "Cardboard", 680);
+ Databases.findMaterial(Material.Type.BULK, "Cardboard", 680, false);
//////////////////////
public static String getVersion() {
- return VERSION;
+ return BUILD_VERSION;
+ }
+
+
+ public static String getBuildSource() {
+ return BUILD_SOURCE;
+ }
+
+
+ public static String getUniqueID() {
+ String id = PREFNODE.get("id", null);
+ if (id == null) {
+ id = UniqueID.generateHashedID();
+ PREFNODE.put("id", id);
+ }
+ return id;
}
public static void storeVersion() {
- NODE.put("OpenRocketVersion", getVersion());
+ PREFNODE.put("OpenRocketVersion", getVersion());
}
* @return The preference value.
*/
public static int getChoise(String key, int max, int def) {
- int v = NODE.getInt(key, def);
+ int v = PREFNODE.getInt(key, def);
if ((v<0) || (v>max))
return def;
return v;
* @param value the value to store.
*/
public static void putChoise(String key, int value) {
- NODE.putInt(key, value);
+ PREFNODE.putInt(key, value);
storeVersion();
}
public static String getString(String key, String def) {
- return NODE.get(key, def);
+ return PREFNODE.get(key, def);
}
public static void putString(String key, String value) {
- NODE.put(key, value);
+ PREFNODE.put(key, value);
storeVersion();
}
+
+ public static boolean getBoolean(String key, boolean def) {
+ return PREFNODE.getBoolean(key, def);
+ }
+
+ public static void putBoolean(String key, boolean value) {
+ PREFNODE.putBoolean(key, value);
+ storeVersion();
+ }
//////////////////
public static File getDefaultDirectory() {
- String file = NODE.get("defaultDirectory", null);
+ String file = PREFNODE.get("defaultDirectory", null);
if (file == null)
return null;
return new File(file);
} else {
d = dir.getAbsolutePath();
}
- NODE.put("defaultDirectory", d);
+ PREFNODE.put("defaultDirectory", d);
storeVersion();
}
* @return the DPI setting to use.
*/
public static double getDPI() {
- int dpi = NODE.getInt("DPI", 0); // Tenths of a dpi
+ int dpi = PREFNODE.getInt("DPI", 0); // Tenths of a dpi
if (dpi < 10) {
dpi = Toolkit.getDefaultToolkit().getScreenResolution()*10;
String material = get("componentMaterials", componentClass, null);
if (material != null) {
try {
- Material m = Material.fromStorableString(material);
+ Material m = Material.fromStorableString(material, false);
if (m.getType() == type)
return m;
} catch (IllegalArgumentException ignore) { }
public static Point getWindowPosition(Class<?> c) {
int x, y;
- String pref = NODE.node("windows").get("position." + c.getCanonicalName(), null);
+ String pref = PREFNODE.node("windows").get("position." + c.getCanonicalName(), null);
if (pref == null)
return null;
}
public static void setWindowPosition(Class<?> c, Point p) {
- NODE.node("windows").put("position." + c.getCanonicalName(), "" + p.x + "," + p.y);
+ PREFNODE.node("windows").put("position." + c.getCanonicalName(), "" + p.x + "," + p.y);
storeVersion();
}
public static Dimension getWindowSize(Class<?> c) {
int x, y;
- String pref = NODE.node("windows").get("size." + c.getCanonicalName(), null);
+ String pref = PREFNODE.node("windows").get("size." + c.getCanonicalName(), null);
if (pref == null)
return null;
}
public static void setWindowSize(Class<?> c, Dimension d) {
- NODE.node("windows").put("size." + c.getCanonicalName(), "" + d.width + "," + d.height);
+ PREFNODE.node("windows").put("size." + c.getCanonicalName(), "" + d.width + "," + d.height);
storeVersion();
}
//// Background flight data computation
public static boolean computeFlightInBackground() {
- return NODE.getBoolean("backgroundFlight", true);
+ return PREFNODE.getBoolean("backgroundFlight", true);
}
public static Simulation getBackgroundSimulation(Rocket rocket) {
+ ///////// Export variables
+
+ public static boolean isExportSelected(FlightDataBranch.Type type) {
+ Preferences prefs = PREFNODE.node("exports");
+ return prefs.getBoolean(type.getName(), false);
+ }
+
+ public static void setExportSelected(FlightDataBranch.Type type, boolean selected) {
+ Preferences prefs = PREFNODE.node("exports");
+ prefs.putBoolean(type.getName(), selected);
+ }
+
+
///////// Default unit storage
public static void loadDefaultUnits() {
- Preferences prefs = NODE.node("units");
+ Preferences prefs = PREFNODE.node("units");
try {
for (String key: prefs.keys()) {
}
} catch (BackingStoreException e) {
- System.err.println("BackingStoreException:");
- e.printStackTrace();
+ ExceptionHandler.handleErrorCondition(e);
}
}
public static void storeDefaultUnits() {
- Preferences prefs = NODE.node("units");
+ Preferences prefs = PREFNODE.node("units");
for (String key: UnitGroup.UNITS.keySet()) {
UnitGroup group = UnitGroup.UNITS.get(key);
+ //// Material storage
+
+
+ /**
+ * Add a user-defined material to the preferences. The preferences are
+ * first checked for an existing material matching the provided one using
+ * {@link Material#equals(Object)}.
+ *
+ * @param m the material to add.
+ */
+ public static void addUserMaterial(Material m) {
+ Preferences prefs = PREFNODE.node("userMaterials");
+
+
+ // Check whether material already exists
+ if (getUserMaterials().contains(m)) {
+ return;
+ }
+
+ // Add material using next free key (key is not used when loading)
+ String mat = m.toStorableString();
+ for (int i = 0; ; i++) {
+ String key = "material" + i;
+ if (prefs.get(key, null) == null) {
+ prefs.put(key, mat);
+ return;
+ }
+ }
+ }
+
+
+ /**
+ * Remove a user-defined material from the preferences. The matching is performed
+ * using {@link Material#equals(Object)}.
+ *
+ * @param m the material to remove.
+ */
+ public static void removeUserMaterial(Material m) {
+ Preferences prefs = PREFNODE.node("userMaterials");
+
+ try {
+
+ // Iterate through materials and remove all keys with a matching material
+ for (String key: prefs.keys()) {
+ String value = prefs.get(key, null);
+ try {
+
+ Material existing = Material.fromStorableString(value, true);
+ if (existing.equals(m)) {
+ prefs.remove(key);
+ }
+
+ } catch (IllegalArgumentException ignore) { }
+
+ }
+
+ } catch (BackingStoreException e) {
+ throw new IllegalStateException("Cannot read preferences!", e);
+ }
+ }
+
+
+ /**
+ * Return a set of all user-defined materials in the preferences. The materials
+ * are created marked as user-defined.
+ *
+ * @return a set of all user-defined materials.
+ */
+ public static Set<Material> getUserMaterials() {
+ Preferences prefs = PREFNODE.node("userMaterials");
+
+ HashSet<Material> materials = new HashSet<Material>();
+ try {
+
+ for (String key: prefs.keys()) {
+ String value = prefs.get(key, null);
+ try {
+
+ Material m = Material.fromStorableString(value, true);
+ materials.add(m);
+
+ } catch (IllegalArgumentException e) {
+ System.err.println("Illegal material string " + value);
+ }
+
+ }
+
+ } catch (BackingStoreException e) {
+ throw new IllegalStateException("Cannot read preferences!", e);
+ }
+
+ return materials;
+ }
+
+
//// Helper methods
private static String get(String directory,
// Search preferences
Class<?> c = componentClass;
- Preferences prefs = NODE.node(directory);
+ Preferences prefs = PREFNODE.node(directory);
while (c!=null && RocketComponent.class.isAssignableFrom(c)) {
String value = prefs.get(c.getSimpleName(), null);
if (value != null)
private static void set(String directory, Class<? extends RocketComponent> componentClass,
String value) {
- Preferences prefs = NODE.node(directory);
+ Preferences prefs = PREFNODE.node(directory);
if (value == null)
prefs.remove(componentClass.getSimpleName());
else