component config refactoring, localization fixes
[debian/openrocket] / src / net / sf / openrocket / util / Prefs.java
index 53d9ff262a965bd0c957911eacca00826f106f89..dfe05a1d4a3f864e75f6ba2f55552a1c9ce76ef8 100644 (file)
@@ -7,8 +7,12 @@ import java.awt.Toolkit;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.Properties;
@@ -16,9 +20,13 @@ import java.util.Set;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
 
+import net.sf.openrocket.arch.SystemInfo;
 import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.document.Simulation;
 import net.sf.openrocket.gui.main.ExceptionHandler;
+import net.sf.openrocket.gui.print.PrintSettings;
+import net.sf.openrocket.l10n.L10N;
+import net.sf.openrocket.l10n.Translator;
 import net.sf.openrocket.logging.LogHelper;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyComponent;
@@ -30,8 +38,8 @@ import net.sf.openrocket.rocketcomponent.RecoveryDevice;
 import net.sf.openrocket.rocketcomponent.Rocket;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.simulation.FlightDataType;
-import net.sf.openrocket.simulation.GUISimulationConditions;
 import net.sf.openrocket.simulation.RK4SimulationStepper;
+import net.sf.openrocket.simulation.SimulationOptions;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
@@ -39,6 +47,19 @@ import net.sf.openrocket.unit.UnitGroup;
 public class Prefs {
        private static final LogHelper log = Application.getLogger();
        
+       private static final String SPLIT_CHARACTER = "|";
+       
+
+       private static final List<Locale> SUPPORTED_LOCALES;
+       static {
+               List<Locale> list = new ArrayList<Locale>();
+               for (String lang : new String[] { "en", "de", "es", "fr" }) {
+                       list.add(new Locale(lang));
+               }
+               SUPPORTED_LOCALES = Collections.unmodifiableList(list);
+       }
+       
+
        /**
         * Whether to use the debug-node instead of the normal node.
         */
@@ -64,6 +85,7 @@ public class Prefs {
         */
        private static class BuildPropertyHolder {
                
+               public static final Properties PROPERTIES;
                public static final String BUILD_VERSION;
                public static final String BUILD_SOURCE;
                public static final boolean DEFAULT_CHECK_UPDATES;
@@ -78,11 +100,11 @@ public class Prefs {
                                                        "build.properties", "build.version");
                                }
                                
-                               Properties props = new Properties();
-                               props.load(is);
+                               PROPERTIES = new Properties();
+                               PROPERTIES.load(is);
                                is.close();
                                
-                               String version = props.getProperty("build.version");
+                               String version = PROPERTIES.getProperty("build.version");
                                if (version == null) {
                                        throw new MissingResourceException(
                                                        "build.version not found in property file",
@@ -90,14 +112,14 @@ public class Prefs {
                                }
                                BUILD_VERSION = version.trim();
                                
-                               BUILD_SOURCE = props.getProperty("build.source");
+                               BUILD_SOURCE = PROPERTIES.getProperty("build.source");
                                if (BUILD_SOURCE == null) {
                                        throw new MissingResourceException(
                                                        "build.source not found in property file",
                                                        "build.properties", "build.source");
                                }
                                
-                               String value = props.getProperty("build.checkupdates");
+                               String value = PROPERTIES.getProperty("build.checkupdates");
                                if (value != null)
                                        DEFAULT_CHECK_UPDATES = Boolean.parseBoolean(value);
                                else
@@ -113,7 +135,8 @@ public class Prefs {
        
        public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition";
        
-
+       public static final String USER_THRUST_CURVES_KEY = "UserThrustCurves";
+       
        public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation";
        
        // Preferences related to data export
@@ -190,13 +213,18 @@ public class Prefs {
         * Within a holder class so they will load only when needed.
         */
        private static class DefaultMaterialHolder {
+               private static final Translator trans = Application.getTranslator();
+               
+               //// Elastic cord (round 2mm, 1/16 in)
                private static final Material DEFAULT_LINE_MATERIAL =
-                               Databases.findMaterial(Material.Type.LINE, "Elastic cord (round 2mm, 1/16 in)",
+                               Databases.findMaterial(Material.Type.LINE, trans.get("Databases.materials.Elasticcordround2mm"),
                                                0.0018, false);
+               //// Ripstop nylon
                private static final Material DEFAULT_SURFACE_MATERIAL =
-                               Databases.findMaterial(Material.Type.SURFACE, "Ripstop nylon", 0.067, false);
+                               Databases.findMaterial(Material.Type.SURFACE, trans.get("Databases.materials.Ripstopnylon"), 0.067, false);
+               //// Cardboard
                private static final Material DEFAULT_BULK_MATERIAL =
-                               Databases.findMaterial(Material.Type.BULK, "Cardboard", 680, false);
+                               Databases.findMaterial(Material.Type.BULK, trans.get("Databases.materials.Cardboard"), 680, false);
        }
        
        //////////////////////
@@ -287,13 +315,58 @@ public class Prefs {
         * Set a string preference.
         * 
         * @param key           the preference key
-        * @param value         the value to set
+        * @param value         the value to set, or <code>null</code> to remove the key
         */
        public static void putString(String key, String value) {
+               if (value == null) {
+                       PREFNODE.remove(key);
+                       return;
+               }
                PREFNODE.put(key, value);
                storeVersion();
        }
        
+       
+       /**
+        * Retrieve an enum value from the user preferences.
+        * 
+        * @param <T>   the enum type
+        * @param key   the key
+        * @param def   the default value, cannot be null
+        * @return              the value in the preferences, or the default value
+        */
+       public static <T extends Enum<T>> T getEnum(String key, T def) {
+               if (def == null) {
+                       throw new BugException("Default value cannot be null");
+               }
+               
+               String value = getString(key, null);
+               if (value == null) {
+                       return def;
+               }
+               
+               try {
+                       return Enum.valueOf(def.getDeclaringClass(), value);
+               } catch (IllegalArgumentException e) {
+                       return def;
+               }
+       }
+       
+       /**
+        * Store an enum value to the user preferences.
+        * 
+        * @param key           the key
+        * @param value         the value to store, or null to remove the value
+        */
+       public static void putEnum(String key, Enum<?> value) {
+               if (value == null) {
+                       putString(key, null);
+               } else {
+                       putString(key, value.name());
+               }
+       }
+       
+       
        /**
         * Return a boolean preference.
         * 
@@ -331,7 +404,24 @@ public class Prefs {
        //////////////////
        
 
-
+       public static List<Locale> getSupportedLocales() {
+               return SUPPORTED_LOCALES;
+       }
+       
+       public static Locale getUserLocale() {
+               String locale = getString("locale", null);
+               return L10N.toLocale(locale);
+       }
+       
+       public static void setUserLocale(Locale l) {
+               if (l == null) {
+                       putString("locale", null);
+               } else {
+                       putString("locale", l.toString());
+               }
+       }
+       
+       
 
        public static boolean getCheckUpdates() {
                return PREFNODE.getBoolean(CHECK_UPDATES, BuildPropertyHolder.DEFAULT_CHECK_UPDATES);
@@ -361,12 +451,96 @@ public class Prefs {
        }
        
        
+       /**
+        * Return a list of files/directories to be loaded as custom thrust curves.
+        * <p>
+        * If this property has not been set, the directory "ThrustCurves" in the user
+        * application directory will be used.  The directory will be created if it does not
+        * exist.
+        * 
+        * @return      a list of files to load as thrust curves.
+        */
+       public static List<File> getUserThrustCurveFiles() {
+               List<File> list = new ArrayList<File>();
+               
+               String files = getString(USER_THRUST_CURVES_KEY, null);
+               if (files == null) {
+                       // Default to application directory
+                       File tcdir = getDefaultUserThrustCurveFile();
+                       if (!tcdir.isDirectory()) {
+                               tcdir.mkdirs();
+                       }
+                       list.add(tcdir);
+               } else {
+                       for (String file : files.split("\\" + SPLIT_CHARACTER)) {
+                               file = file.trim();
+                               if (file.length() > 0) {
+                                       list.add(new File(file));
+                               }
+                       }
+               }
+               
+               return list;
+       }
+       
+       public static File getDefaultUserThrustCurveFile() {
+               File appdir = SystemInfo.getUserApplicationDirectory();
+               File tcdir = new File(appdir, "ThrustCurves");
+               return tcdir;
+       }
+       
+       
+       /**
+        * Set the list of files/directories to be loaded as custom thrust curves.
+        * 
+        * @param files         the files to load, or <code>null</code> to reset to default value.
+        */
+       public static void setUserThrustCurveFiles(List<File> files) {
+               if (files == null) {
+                       putString(USER_THRUST_CURVES_KEY, null);
+                       return;
+               }
+               
+               String str = "";
+               
+               for (File file : files) {
+                       if (str.length() > 0) {
+                               str += SPLIT_CHARACTER;
+                       }
+                       str += file.getAbsolutePath();
+               }
+               putString(USER_THRUST_CURVES_KEY, str);
+       }
+       
+       
+
+
 
        public static Color getDefaultColor(Class<? extends RocketComponent> c) {
                String color = get("componentColors", c, DEFAULT_COLORS);
                if (color == null)
                        return Color.BLACK;
                
+               Color clr = parseColor(color);
+               if (clr != null) {
+                       return clr;
+               } else {
+                       return Color.BLACK;
+               }
+       }
+       
+       public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
+               if (color == null)
+                       return;
+               set("componentColors", c, stringifyColor(color));
+       }
+       
+       
+       private static Color parseColor(String color) {
+               if (color == null) {
+                       return null;
+               }
+               
                String[] rgb = color.split(",");
                if (rgb.length == 3) {
                        try {
@@ -377,17 +551,17 @@ public class Prefs {
                        } catch (NumberFormatException ignore) {
                        }
                }
-               
-               return Color.BLACK;
+               return null;
        }
        
-       public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
-               if (color == null)
-                       return;
+       
+       private static String stringifyColor(Color color) {
                String string = color.getRed() + "," + color.getGreen() + "," + color.getBlue();
-               set("componentColors", c, string);
+               return string;
        }
        
+       
+
        public static Color getMotorBorderColor() {
                // TODO: MEDIUM:  Motor color (settable?)
                return new Color(0, 0, 0, 200);
@@ -432,7 +606,7 @@ public class Prefs {
                if (dpi < 10)
                        dpi = 960;
                
-               return ((double) dpi) / 10.0;
+               return (dpi) / 10.0;
        }
        
        
@@ -482,7 +656,19 @@ public class Prefs {
        }
        
        
-
+       /**
+        * Return whether to use additional safety code checks.
+        */
+       public static boolean useSafetyChecks() {
+               // Currently default to false unless openrocket.debug.safetycheck is defined
+               String s = System.getProperty("openrocket.debug.safetycheck");
+               if (s != null && !(s.equalsIgnoreCase("false") || s.equalsIgnoreCase("off"))) {
+                       return true;
+               }
+               return false;
+       }
+       
+       
        public static Point getWindowPosition(Class<?> c) {
                int x, y;
                String pref = PREFNODE.node("windows").get("position." + c.getCanonicalName(), null);
@@ -529,11 +715,51 @@ public class Prefs {
                return new Dimension(x, y);
        }
        
+       
+       public static boolean isWindowMaximized(Class<?> c) {
+               String pref = PREFNODE.node("windows").get("size." + c.getCanonicalName(), null);
+               return "max".equals(pref);
+       }
+       
        public static void setWindowSize(Class<?> c, Dimension d) {
                PREFNODE.node("windows").put("size." + c.getCanonicalName(), "" + d.width + "," + d.height);
                storeVersion();
        }
        
+       public static void setWindowMaximized(Class<?> c) {
+               PREFNODE.node("windows").put("size." + c.getCanonicalName(), "max");
+               storeVersion();
+       }
+       
+       
+       ////  Printing
+       
+       public static PrintSettings getPrintSettings() {
+               PrintSettings settings = new PrintSettings();
+               Color c;
+               
+               c = parseColor(getString("print.template.fillColor", null));
+               if (c != null) {
+                       settings.setTemplateFillColor(c);
+               }
+               
+               c = parseColor(getString("print.template.borderColor", null));
+               if (c != null) {
+                       settings.setTemplateBorderColor(c);
+               }
+               
+               settings.setPaperSize(getEnum("print.paper.size", settings.getPaperSize()));
+               settings.setPaperOrientation(getEnum("print.paper.orientation", settings.getPaperOrientation()));
+               
+               return settings;
+       }
+       
+       public static void setPrintSettings(PrintSettings settings) {
+               putString("print.template.fillColor", stringifyColor(settings.getTemplateFillColor()));
+               putString("print.template.borderColor", stringifyColor(settings.getTemplateBorderColor()));
+               putEnum("print.paper.size", settings.getPaperSize());
+               putEnum("print.paper.orientation", settings.getPaperOrientation());
+       }
        
        ////  Background flight data computation
        
@@ -543,7 +769,7 @@ public class Prefs {
        
        public static Simulation getBackgroundSimulation(Rocket rocket) {
                Simulation s = new Simulation(rocket);
-               GUISimulationConditions cond = s.getConditions();
+               SimulationOptions cond = s.getOptions();
                
                cond.setTimeStep(RK4SimulationStepper.RECOMMENDED_TIME_STEP * 2);
                cond.setWindSpeedAverage(1.0);