package org.reprap; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.Properties; import java.util.Enumeration; import java.util.List; import java.util.ArrayList; import javax.media.j3d.Appearance; import javax.media.j3d.Material; import javax.vecmath.Color3f; import org.reprap.utilities.Debug; /** * A single centralised repository of the current preference settings. This also * implements (almost) a singleton for easy global access. If there are no current * preferences fallback distribution defaults are used. */ public class Preferences { private static String propsFile = "reprap.properties"; private static final String propsFolder = ".reprap"; private static final String propsFileDist = "reprap.properties.dist"; private static final String cannedDefault = "Canned_G_Codes"; private static final String prologueFile = "prologue.gcode"; private static final String epilogueFile = "epilogue.gcode"; private static Preferences globalPrefs = null; Properties fallbackPreferences; Properties mainPreferences; /* * This section deals with internal (i.e. not RepRap machine, but this code or * physics) precisions and accuracies */ // standard file names for the top and tail for G Code files public static final String prologue = "prologue.gcode"; public static final String epilogue = "epilogue.gcode"; private static final int grid = 100; // Click outline polygons to a... public static int grid() { return grid; } private static final double gridRes = 1.0/grid; // ...10 micron grid public static double gridRes() { return gridRes; } private static final double lessGridSquare = gridRes*gridRes*0.01; // Small squared size of a gridsquare public static double lessGridSquare() { return lessGridSquare; } private static final double tiny = 1.0e-12; // A small number public static double tiny() { return tiny; } private static final double swell = 1.01; // Quad tree swell factor public static double swell() { return swell; } private static final double machineResolution = 0.1; // RepRap step size in mm public static double machineResolution() { return machineResolution; } private static final double absoluteZero = -273; public static double absoluteZero() { return absoluteZero; } private static final double inToMM = 25.4; public static double inchesToMillimetres() { return inToMM; } private static final Color3f black = new Color3f(0, 0, 0); private static boolean displaySimulation = false; public static boolean simulate() { return displaySimulation; } public static void setSimulate(boolean s) { displaySimulation = s;} private static boolean subtractive = false; public static boolean Subtractive() { return subtractive; } public static void setSubtractive(boolean s) { subtractive = s;} private static boolean gCodeUseSerial = false; public static boolean GCodeUseSerial() { return gCodeUseSerial; } public static void setGCodeUseSerial(boolean s) { gCodeUseSerial = s;} private static String repRapMachine="GCodeRepRap"; public static String RepRapMachine() { return repRapMachine; } public static void setRepRapMachine(String s) { repRapMachine = s; } public static Appearance unselectedApp() { Color3f unselectedColour = null; try { unselectedColour = new Color3f((float)0.3, (float)0.3, (float)0.3); } catch (Exception ex) { ex.printStackTrace(); } Appearance unselectedApp = new Appearance(); unselectedApp.setMaterial(new Material(unselectedColour, black, unselectedColour, black, 0f)); return unselectedApp; } public static String getPropsFolderPath() { return System.getProperty("user.home") + File.separatorChar + propsFolder + File.separatorChar; } // Main preferences constructor public Preferences() throws IOException { fallbackPreferences = new Properties(); mainPreferences = new Properties(); URL fallbackUrl = ClassLoader.getSystemResource(propsFileDist); //Debug.a("++++ " + fallbackUrl.toString()); // Construct URL of user properties file String path = getPropsFolderPath() + propsFile; File mainFile = new File(path); URL mainUrl = mainFile.toURI().toURL(); if (fallbackUrl == null && !mainFile.exists()) //throw new IOException("Cannot load RepRap properties file or default "+propsFileDist); Debug.e("Cannot load RepRap properties file or default "+propsFileDist); if (fallbackUrl != null) fallbackPreferences.load(fallbackUrl.openStream()); if (mainFile.exists()) { mainPreferences.load(mainUrl.openStream()); if(fallbackUrl != null) comparePreferences(); } else { // If we don't have a local preferences file copy the default // file into it. mainPreferences.load(fallbackUrl.openStream()); save(true); } } /** * Compare the user's preferences with the distribution one and report any * different names. */ private void comparePreferences() { Enumeration<?> usersLot = mainPreferences.propertyNames(); Enumeration<?> distLot = fallbackPreferences.propertyNames(); String result = ""; int count = 0; boolean noDifference = true; while(usersLot.hasMoreElements()) { String next = (String)usersLot.nextElement(); if (!fallbackPreferences.containsKey(next)) { result += " " + next + "\n"; count++; } } if(count > 0) { result = "Your preferences file contains:\n" + result + "which "; if(count > 1) result += "are"; else result += "is"; result += " not in the distribution preferences file."; Debug.d(result); noDifference = false; } result = ""; count = 0; while(distLot.hasMoreElements()) { String next = (String)distLot.nextElement(); if (!mainPreferences.containsKey(next)) { result += " " + next + "\n"; count++; } } if(count > 0) { result = "The distribution preferences file contains:\n" + result + "which "; if(count > 1) result += "are"; else result += "is"; result += " not in your preferences file."; Debug.d(result); noDifference = false; } if(noDifference) Debug.d("The distribution preferences file and yours match. This is good."); } public void save(boolean startUp) throws FileNotFoundException, IOException { String savePath = getPropsFolderPath() + propsFile; //File f = new File(savePath + File.separatorChar + propsFile); File f = new File(savePath); if (!f.exists()) { // No properties file exists, so we will create one and try again // We'll put the properties file in the .reprap folder, // under the user's home folder. String canned = getPropsFolderPath() + loadString(cannedDefault) + File.separatorChar; File p = new File(canned); if (!p.isDirectory()) // Create .reprap folder and those under it if necessary p.mkdirs(); URL sourceUrl = ClassLoader.getSystemResource(prologueFile); File source = new File(sourceUrl.getFile()); File dest = new File(canned + prologueFile); org.reprap.utilities.RepRapUtils.copyFile(source, dest); sourceUrl = ClassLoader.getSystemResource(epilogueFile); source = new File(sourceUrl.getFile()); dest = new File(canned + epilogueFile); org.reprap.utilities.RepRapUtils.copyFile(source, dest); } OutputStream output = new FileOutputStream(f); mainPreferences.store(output, "RepRap machine parameters. See http://reprap.org/wiki/Java_Software_Preferences_File"); if(!startUp) org.reprap.Main.gui.getPrinter().refreshPreferences(); } public String loadString(String name) { if (mainPreferences.containsKey(name)) return mainPreferences.getProperty(name); if (fallbackPreferences.containsKey(name)) return fallbackPreferences.getProperty(name); Debug.e("RepRap preference: " + name + " not found in either preference file."); return null; } public int loadInt(String name) { String strVal = loadString(name); return Integer.parseInt(strVal); } public double loadDouble(String name) { String strVal = loadString(name); return Double.parseDouble(strVal); } public boolean loadBool(String name) { String strVal = loadString(name); if (strVal == null) return false; if (strVal.length() == 0) return false; if (strVal.compareToIgnoreCase("true") == 0) return true; return false; } public static boolean loadConfig(String configName) { propsFile = configName; try { globalPrefs = new Preferences(); return true; } catch(IOException e) { return false; } } synchronized private static void initIfNeeded() throws IOException { if (globalPrefs == null) globalPrefs = new Preferences(); } public static String loadGlobalString(String name) throws IOException { initIfNeeded(); return globalPrefs.loadString(name); } public static int loadGlobalInt(String name) throws IOException { initIfNeeded(); return globalPrefs.loadInt(name); } public static double loadGlobalDouble(String name) throws IOException { initIfNeeded(); return globalPrefs.loadDouble(name); } public static boolean loadGlobalBool(String name) throws IOException { initIfNeeded(); return globalPrefs.loadBool(name); } public static void saveGlobal() throws IOException { initIfNeeded(); globalPrefs.save(false); } public static Preferences getGlobalPreferences() throws IOException { initIfNeeded(); return globalPrefs; } public static String getDefaultPropsFile() { return propsFile; } /** * Set a new value * @param name * @param value * @throws IOException */ public static void setGlobalString(String name, String value) throws IOException { initIfNeeded(); //Debug.e("Setting global " + name + ":" + value); globalPrefs.setString(name, value); } public static void setGlobalBool(String name, boolean value) throws IOException { initIfNeeded(); globalPrefs.setString(name, value ? "true" : "false"); } /** * @param name * @param value */ private void setString(String name, String value) { //Debug.e("Setting " + name + ":" + value); mainPreferences.setProperty(name, value); } /** * @return an array of all the names of all the materials in extruders * @throws IOException */ public static String[] allMaterials() throws IOException { int extruderCount = globalPrefs.loadInt("NumberOfExtruders"); String[] result = new String[extruderCount]; for(int i = 0; i < extruderCount; i++) { String prefix = "Extruder" + i + "_"; result[i] = globalPrefs.loadString(prefix + "MaterialType(name)"); } return result; } public static String[] startsWith(String prefix) throws IOException { initIfNeeded(); Enumeration<?> allOfThem = globalPrefs.mainPreferences.propertyNames(); List<String> r = new ArrayList<String>(); while(allOfThem.hasMoreElements()) { String next = (String)allOfThem.nextElement(); if(next.startsWith(prefix)) r.add(next); } String[] result = new String[r.size()]; for(int i = 0; i < r.size(); i++) result[i] = (String)r.get(i); return result; } public static String[] notStartsWith(String prefix) throws IOException { initIfNeeded(); Enumeration<?> allOfThem = globalPrefs.mainPreferences.propertyNames(); List<String> r = new ArrayList<String>(); while(allOfThem.hasMoreElements()) { String next = (String)allOfThem.nextElement(); if(!next.startsWith(prefix)) r.add(next); } String[] result = new String[r.size()]; for(int i = 0; i < r.size(); i++) result[i] = (String)r.get(i); return result; } }