2424import java .awt .Color ;
2525import java .awt .Font ;
2626import java .awt .SystemColor ;
27- import java .io .*;
28- import java .util .*;
2927
3028import processing .app .ui .Toolkit ;
3129import processing .core .*;
30+ import processing .utils .PreferencesException ;
3231
3332
3433/**
4746 * such things, we could start using the Java Preferences API. But wow, that
4847 * sounds like a lot of work. Not unlike writing this paragraph.
4948 */
50- public class Preferences {
51- // had to rename the defaults file because people were editing it
52- static final String DEFAULTS_FILE = "defaults.txt" ; //$NON-NLS-1$
53- static final String PREFS_FILE = "preferences.txt" ; //$NON-NLS-1$
49+ public class Preferences extends processing .utils .Preferences {
5450
55- static Map <String , String > defaults ;
56- static Map <String , String > table = new HashMap <>();
57- static File preferencesFile ;
58- private static boolean initialized = false ;
59-
60-
61- // /** @return true if the sketchbook file did not exist */
62- // static public boolean init() {
6351 static public void init () {
64- initialized = true ;
65- // start by loading the defaults, in case something
66- // important was deleted from the user prefs
52+ processing .utils .Preferences .initialized = true ;
53+
6754 try {
68- // Name changed for 2.1b2 to avoid problems with users modifying or
69- // replacing the file after doing a search for "preferences.txt".
70- load (Base .getLibStream (DEFAULTS_FILE ));
71- } catch (Exception e ) {
72- Messages .showError (null , "Could not read default settings.\n " +
73- "You'll need to reinstall Processing." , e );
55+ // start by loading the defaults, in case something
56+ // important was deleted from the user prefs
57+ loadDefaults ();
58+ } catch (PreferencesException e ) {
59+ Messages .showError (e .getTitle (), e .getMessage (), e );
7460 }
7561
76- // Clone the defaults, then override any them with the user's preferences.
77- // This ensures that any new/added preference will be present.
78- defaults = new HashMap <>(table );
79-
8062 // other things that have to be set explicitly for the defaults
8163 setColor ("run.window.bgcolor" , SystemColor .control ); //$NON-NLS-1$
8264
@@ -86,21 +68,15 @@ static public void init() {
8668 }
8769
8870 // next load user preferences file
89- preferencesFile = Base .getSettingsFile (PREFS_FILE );
90- boolean firstRun = !preferencesFile .exists ();
91- if (!firstRun ) {
92- try {
93- load (new FileInputStream (preferencesFile ));
94-
95- } catch (Exception ex ) {
96- Messages .showError ("Error reading preferences" ,
97- "Error reading the preferences file. " +
98- "Please delete (or move)\n " +
99- preferencesFile .getAbsolutePath () +
100- " and restart Processing." , ex );
101- }
71+ Preferences .setPreferencesFolder (Base .getSettingsFolder ());
72+ try {
73+ loadPreferences ();
74+ } catch (PreferencesException e ) {
75+ Messages .showError (e .getTitle (), e .getMessage (), e );
10276 }
10377
78+ boolean firstRun = !getPreferencesFile ().exists ();
79+
10480 if (checkSketchbookPref () || firstRun ) {
10581// if (firstRun) {
10682 // create a new preferences file if none exists
@@ -129,14 +105,6 @@ static public void init() {
129105 }
130106
131107
132- /**
133- * For testing, pretend to load preferences without a real file.
134- */
135- static public void skipInit () {
136- initialized = true ;
137- }
138-
139-
140108 static void handleProxy (String protocol , String hostProp , String portProp ) {
141109 String proxyHost = get ("proxy." + protocol + ".host" );
142110 String proxyPort = get ("proxy." + protocol + ".port" );
@@ -149,185 +117,15 @@ static void handleProxy(String protocol, String hostProp, String portProp) {
149117 }
150118
151119
152- static public String getPreferencesPath () {
153- return preferencesFile .getAbsolutePath ();
154- }
155-
156-
157- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
158-
159-
160- /**
161- * Load a set of key/value pairs from a UTF-8 encoded file into 'table'.
162- * For 3.0a6, this removes any platform-specific extensions from keys, so
163- * that we don't have platform-specific entries in a user's preferences.txt
164- * file, which would require all prefs to be changed twice, or risk being
165- * overwritten by the unchanged platform-specific version on reload.
166- */
167- static public void load (InputStream input ) throws IOException {
168- HashMap <String , String > platformSpecific = new HashMap <>();
169-
170- String [] lines = PApplet .loadStrings (input ); // Reads as UTF-8
171- for (String line : lines ) {
172- if ((line .length () == 0 ) ||
173- (line .charAt (0 ) == '#' )) continue ;
174-
175- // this won't properly handle = signs being in the text
176- int equals = line .indexOf ('=' );
177- if (equals != -1 ) {
178- String key = line .substring (0 , equals ).trim ();
179- String value = line .substring (equals + 1 ).trim ();
180- if (!isPlatformSpecific (key , value , platformSpecific )) {
181- table .put (key , value );
182- }
183- }
184- }
185- // Now override the keys with any platform-specific defaults we've found.
186- for (String key : platformSpecific .keySet ()) {
187- table .put (key , platformSpecific .get (key ));
188- }
189- }
190-
191-
192- /**
193- * @param key original key (may include platform extension)
194- * @param value the value that goes with the key
195- * @param specific where to put the key/value pairs for *this* platform
196- * @return true if a platform-specific key
197- */
198- static protected boolean isPlatformSpecific (String key , String value ,
199- Map <String , String > specific ) {
200- for (String platform : PConstants .platformNames ) {
201- String ext = "." + platform ;
202- if (key .endsWith (ext )) {
203- String thisPlatform = PConstants .platformNames [PApplet .platform ];
204- if (platform .equals (thisPlatform )) {
205- key = key .substring (0 , key .lastIndexOf (ext ));
206- // store this for later overrides
207- specific .put (key , value );
208- //} else {
209- // ignore platform-specific defaults for other platforms,
210- // but return 'true' because it needn't be added to the big list
211- }
212- return true ;
213- }
214- }
215- return false ;
216- }
217-
218-
219- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
220-
221-
222- static public void save () {
223- // On startup, this is null, but ignore it. It's trying to update the
224- // prefs for the open sketch before Preferences.init() has been called.
225- if (preferencesFile != null ) {
226- try {
227- File dir = preferencesFile .getParentFile ();
228- File preferencesTemp = File .createTempFile ("preferences" , ".txt" , dir );
229- if (!preferencesTemp .setWritable (true , false )) {
230- throw new IOException ("Could not set " + preferencesTemp + " writable" );
231- }
232-
233- // Fix for 0163 to properly use Unicode when writing preferences.txt
234- PrintWriter writer = PApplet .createWriter (preferencesTemp );
235-
236- String [] keyList = table .keySet ().toArray (new String [0 ]);
237- // Sorting is really helpful for debugging, diffing, and finding keys
238- keyList = PApplet .sort (keyList );
239- for (String key : keyList ) {
240- writer .println (key + "=" + table .get (key )); //$NON-NLS-1$
241- }
242- writer .flush ();
243- writer .close ();
244-
245- // Rename preferences.txt to preferences.old
246- File oldPreferences = new File (dir , "preferences.old" );
247- if (oldPreferences .exists ()) {
248- if (!oldPreferences .delete ()) {
249- throw new IOException ("Could not delete preferences.old" );
250- }
251- }
252- if (preferencesFile .exists () &&
253- !preferencesFile .renameTo (oldPreferences )) {
254- throw new IOException ("Could not replace preferences.old" );
255- }
256- // Make the temporary file into the real preferences
257- if (!preferencesTemp .renameTo (preferencesFile )) {
258- throw new IOException ("Could not move preferences file into place" );
259- }
260-
261- } catch (IOException e ) {
262- Messages .showWarning ("Preferences" ,
263- "Could not save the Preferences file." , e );
264- }
265- }
266- }
267-
268-
269- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
270-
271-
272- // all the information from preferences.txt
273-
274- static public String get (String attribute /*, String defaultValue */ ) {
275- if (!initialized ) {
276- throw new RuntimeException (
277- "Tried reading preferences prior to initialization."
278- );
279- }
280- return table .get (attribute );
281- }
282-
283-
284- static public String getDefault (String attribute ) {
285- return defaults .get (attribute );
286- }
287-
288-
289- static public void set (String attribute , String value ) {
290- table .put (attribute , value );
291- }
292-
293-
294- static public void unset (String attribute ) {
295- table .remove (attribute );
296- }
297-
298-
299- static public boolean getBoolean (String attribute ) {
300- String value = get (attribute ); //, null);
301- return Boolean .parseBoolean (value );
302-
303- /*
304- supposedly not needed, because anything besides 'true'
305- (ignoring case) will just be false.. so if malformed -> false
306- if (value == null) return defaultValue;
307-
120+ static public void save (){
308121 try {
309- return (new Boolean(value)).booleanValue ();
310- } catch (NumberFormatException e ) {
311- System.err.println("expecting an integer: " + attribute + " = " + value );
122+ processing . utils . Preferences . save ();
123+ } catch (PreferencesException e ) {
124+ Messages . showWarning ( e . getTitle (), e . getMessage (), e );
312125 }
313- return defaultValue;
314- */
315- }
316-
317-
318- static public void setBoolean (String attribute , boolean value ) {
319- set (attribute , value ? "true" : "false" ); //$NON-NLS-1$ //$NON-NLS-2$
320- }
321-
322-
323- static public int getInteger (String attribute /*, int defaultValue*/ ) {
324- return Integer .parseInt (get (attribute ));
325126 }
326127
327-
328- static public void setInteger (String key , int value ) {
329- set (key , String .valueOf (value ));
330- }
128+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
331129
332130
333131 static public Color getColor (String name ) {
@@ -358,41 +156,4 @@ static public Font getFont(String familyAttr, String sizeAttr, int style) {
358156 return new Font (fontFamily , style , fontSize );
359157 }
360158
361-
362- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
363-
364-
365- /**
366- * Check for a 4.0 sketchbook location, and if none exists,
367- * try to grab it from the 3.0 sketchbook location.
368- * @return true if a location was found and the pref didn't exist
369- */
370- static protected boolean checkSketchbookPref () {
371- // If a 4.0 sketchbook location has never been inited
372- if (getSketchbookPath () == null ) {
373- String threePath = get ("sketchbook.path.three" ); //$NON-NLS-1$
374- // If they've run the 3.0 version, start with that location
375- if (threePath != null ) {
376- setSketchbookPath (threePath );
377- return true ; // save the sketchbook right away
378- }
379- // Otherwise it'll be null, and reset properly by Base
380- }
381- return false ;
382- }
383-
384-
385- static public String getOldSketchbookPath () {
386- return get ("sketchbook.path.three" ); //$NON-NLS-1$
387- }
388-
389-
390- static public String getSketchbookPath () {
391- return get ("sketchbook.path.four" ); //$NON-NLS-1$
392- }
393-
394-
395- static protected void setSketchbookPath (String path ) {
396- set ("sketchbook.path.four" , path ); //$NON-NLS-1$
397- }
398159}
0 commit comments