source: josm/trunk/src/org/openstreetmap/josm/data/Preferences.java@ 1082

Last change on this file since 1082 was 1082, checked in by framm, 15 years ago
  • some changes regarding the "hatched download area": now also works for areas where server returns no data; colour preference is now called "outside downloaded area", not "downloaded Area"; changing the colour now invalidates the prepared pattern so that restart is not required; pattern is now transparent (patch from Stephan Knauss) so WMS and other layers are visible below. Fixes #1762, #1754, partly #1756
  • Property svn:eol-style set to native
File size: 14.2 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data;
3
4import java.awt.Color;
5import java.io.BufferedReader;
6import java.io.File;
7import java.io.FileReader;
8import java.io.FileWriter;
9import java.io.IOException;
10import java.io.PrintWriter;
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collection;
14import java.util.LinkedList;
15import java.util.Map;
16import java.util.Properties;
17import java.util.SortedMap;
18import java.util.StringTokenizer;
19import java.util.TreeMap;
20import java.util.Map.Entry;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.gui.preferences.ProxyPreferences;
24import org.openstreetmap.josm.tools.ColorHelper;
25
26/**
27 * This class holds all preferences for JOSM.
28 *
29 * Other classes can register their beloved properties here. All properties will be
30 * saved upon set-access.
31 *
32 * @author imi
33 */
34public class Preferences {
35
36 /**
37 * Internal storage for the preferenced directory.
38 * Do not access this variable directly!
39 * @see #getPreferencesDirFile()
40 */
41 private File preferencesDirFile = null;
42
43 public static interface PreferenceChangedListener {
44 void preferenceChanged(String key, String newValue);
45 }
46
47 /**
48 * Class holding one bookmarkentry.
49 * @author imi
50 */
51 public static class Bookmark {
52 public String name;
53 public double[] latlon = new double[4]; // minlat, minlon, maxlat, maxlon
54 @Override public String toString() {
55 return name;
56 }
57 }
58
59 public final ArrayList<PreferenceChangedListener> listener = new ArrayList<PreferenceChangedListener>();
60
61 /**
62 * Map the property name to the property object.
63 */
64 protected final SortedMap<String, String> properties = new TreeMap<String, String>();
65 protected final SortedMap<String, String> defaults = new TreeMap<String, String>();
66
67 /**
68 * Override some values on read. This is intended to be used for technology previews
69 * where we want to temporarily modify things without changing the user's preferences
70 * file.
71 */
72 protected static final SortedMap<String, String> override = new TreeMap<String, String>();
73 static {
74 //override.put("osm-server.version", "0.5");
75 //override.put("osm-server.additional-versions", "");
76 //override.put("osm-server.url", "http://openstreetmap.gryph.de/api");
77 //override.put("plugins", null);
78 }
79
80 /**
81 * Return the location of the user defined preferences file
82 */
83 public String getPreferencesDir() {
84 final String path = getPreferencesDirFile().getPath();
85 if (path.endsWith(File.separator))
86 return path;
87 return path + File.separator;
88 }
89
90 public File getPreferencesDirFile() {
91 if (preferencesDirFile != null)
92 return preferencesDirFile;
93 String path;
94 path = System.getProperty("josm.home");
95 if (path != null) {
96 preferencesDirFile = new File(path);
97 } else {
98 path = System.getenv("APPDATA");
99 if (path != null) {
100 preferencesDirFile = new File(path, "JOSM");
101 } else {
102 preferencesDirFile = new File(System.getProperty("user.home"), ".josm");
103 }
104 }
105 return preferencesDirFile;
106 }
107
108 public File getPluginsDirFile() {
109 return new File(getPreferencesDirFile(), "plugins");
110 }
111
112 /**
113 * @return A list of all existing directories where resources could be stored.
114 */
115 public Collection<String> getAllPossiblePreferenceDirs() {
116 LinkedList<String> locations = new LinkedList<String>();
117 locations.add(Main.pref.getPreferencesDir());
118 String s;
119 if ((s = System.getenv("JOSM_RESOURCES")) != null) {
120 if (!s.endsWith(File.separator))
121 s = s + File.separator;
122 locations.add(s);
123 }
124 if ((s = System.getProperty("josm.resources")) != null) {
125 if (!s.endsWith(File.separator))
126 s = s + File.separator;
127 locations.add(s);
128 }
129 String appdata = System.getenv("APPDATA");
130 if (System.getenv("ALLUSERSPROFILE") != null && appdata != null
131 && appdata.lastIndexOf(File.separator) != -1) {
132 appdata = appdata.substring(appdata.lastIndexOf(File.separator));
133 locations.add(new File(new File(System.getenv("ALLUSERSPROFILE"),
134 appdata), "JOSM").getPath());
135 }
136 locations.add("/usr/local/share/josm/");
137 locations.add("/usr/local/lib/josm/");
138 locations.add("/usr/share/josm/");
139 locations.add("/usr/lib/josm/");
140 return locations;
141 }
142
143 synchronized public boolean hasKey(final String key) {
144 return override.containsKey(key) ? override.get(key) != null : properties.containsKey(key);
145 }
146
147 synchronized public String get(final String key) {
148 putDefault(key, null);
149 if (override.containsKey(key))
150 return override.get(key);
151 if (!properties.containsKey(key))
152 return "";
153 return properties.get(key);
154 }
155
156 synchronized public String get(final String key, final String def) {
157 putDefault(key, def);
158 if (override.containsKey(key))
159 return override.get(key);
160 final String prop = properties.get(key);
161 if (prop == null || prop.equals(""))
162 return def;
163 return prop;
164 }
165
166 synchronized public Map<String, String> getAllPrefix(final String prefix) {
167 final Map<String,String> all = new TreeMap<String,String>();
168 for (final Entry<String,String> e : properties.entrySet())
169 if (e.getKey().startsWith(prefix))
170 all.put(e.getKey(), e.getValue());
171 for (final Entry<String,String> e : override.entrySet())
172 if (e.getKey().startsWith(prefix))
173 if (e.getValue() == null)
174 all.remove(e.getKey());
175 else
176 all.put(e.getKey(), e.getValue());
177 return all;
178 }
179
180 synchronized public Map<String, String> getDefaults() {
181 return defaults;
182 }
183
184 synchronized public void putDefault(final String key, final String def) {
185 if(!defaults.containsKey(key) || defaults.get(key) == null)
186 defaults.put(key, def);
187 else if(def != null && !defaults.get(key).equals(def))
188 System.out.println("Defaults for " + key + " differ: " + def + " != " + defaults.get(key));
189 }
190
191 synchronized public boolean getBoolean(final String key) {
192 putDefault(key, null);
193 if (override.containsKey(key))
194 return override.get(key) == null ? false : Boolean.parseBoolean(override.get(key));
195 return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : false;
196 }
197
198 synchronized public boolean getBoolean(final String key, final boolean def) {
199 putDefault(key, Boolean.toString(def));
200 if (override.containsKey(key))
201 return override.get(key) == null ? def : Boolean.parseBoolean(override.get(key));
202 return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : def;
203 }
204
205 synchronized public void put(final String key, String value) {
206 String oldvalue = properties.get(key);
207 if(value != null && value.length() == 0)
208 value = null;
209 if(!((oldvalue == null && value == null) || (value != null
210 && oldvalue != null && oldvalue.equals(value))))
211 {
212 if (value == null)
213 properties.remove(key);
214 else
215 properties.put(key, value);
216 save();
217 firePreferenceChanged(key, value);
218 }
219 }
220
221 synchronized public void put(final String key, final boolean value) {
222 put(key, Boolean.toString(value));
223 }
224
225 private final void firePreferenceChanged(final String key, final String value) {
226 for (final PreferenceChangedListener l : listener)
227 l.preferenceChanged(key, value);
228 }
229
230 /**
231 * Called after every put. In case of a problem, do nothing but output the error
232 * in log.
233 */
234 public void save() {
235 try {
236 setSystemProperties();
237 final PrintWriter out = new PrintWriter(new FileWriter(getPreferencesDir() + "preferences"), false);
238 for (final Entry<String, String> e : properties.entrySet()) {
239 out.println(e.getKey() + "=" + e.getValue());
240 }
241 out.close();
242 } catch (final IOException e) {
243 e.printStackTrace();
244 // do not message anything, since this can be called from strange
245 // places.
246 }
247 }
248
249 public void load() throws IOException {
250 properties.clear();
251 final BufferedReader in = new BufferedReader(new FileReader(getPreferencesDir()+"preferences"));
252 int lineNumber = 0;
253 ArrayList<Integer> errLines = new ArrayList<Integer>();
254 for (String line = in.readLine(); line != null; line = in.readLine(), lineNumber++) {
255 final int i = line.indexOf('=');
256 if (i == -1 || i == 0) {
257 errLines.add(lineNumber);
258 continue;
259 }
260 properties.put(line.substring(0,i), line.substring(i+1));
261 }
262 if (!errLines.isEmpty()) {
263 throw new IOException("Malformed config file at lines " + errLines);
264 }
265 setSystemProperties();
266 }
267
268 public final void resetToDefault() {
269 properties.clear();
270 properties.put("projection", "org.openstreetmap.josm.data.projection.Epsg4326");
271 properties.put("draw.segment.direction", "true");
272 properties.put("draw.wireframe", "false");
273 properties.put("layerlist.visible", "true");
274 properties.put("propertiesdialog.visible", "true");
275 properties.put("selectionlist.visible", "true");
276 properties.put("commandstack.visible", "true");
277 properties.put("osm-server.url", "http://www.openstreetmap.org/api");
278 if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") == -1) {
279 properties.put("laf", "javax.swing.plaf.metal.MetalLookAndFeel");
280 } else {
281 properties.put("laf", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
282 }
283 save();
284 }
285
286 public Collection<Bookmark> loadBookmarks() throws IOException {
287 File bookmarkFile = new File(getPreferencesDir()+"bookmarks");
288 if (!bookmarkFile.exists())
289 bookmarkFile.createNewFile();
290 BufferedReader in = new BufferedReader(new FileReader(bookmarkFile));
291
292 Collection<Bookmark> bookmarks = new LinkedList<Bookmark>();
293 for (String line = in.readLine(); line != null; line = in.readLine()) {
294 StringTokenizer st = new StringTokenizer(line, ",");
295 if (st.countTokens() < 5)
296 continue;
297 Bookmark b = new Bookmark();
298 b.name = st.nextToken();
299 try {
300 for (int i = 0; i < b.latlon.length; ++i)
301 b.latlon[i] = Double.parseDouble(st.nextToken());
302 bookmarks.add(b);
303 } catch (NumberFormatException x) {
304 // line not parsed
305 }
306 }
307 in.close();
308 return bookmarks;
309 }
310
311 public void saveBookmarks(Collection<Bookmark> bookmarks) throws IOException {
312 File bookmarkFile = new File(Main.pref.getPreferencesDir()+"bookmarks");
313 if (!bookmarkFile.exists())
314 bookmarkFile.createNewFile();
315 PrintWriter out = new PrintWriter(new FileWriter(bookmarkFile));
316 for (Bookmark b : bookmarks) {
317 b.name = b.name.replace(',', '_');
318 out.print(b.name+",");
319 for (int i = 0; i < b.latlon.length; ++i)
320 out.print(b.latlon[i]+(i<b.latlon.length-1?",":""));
321 out.println();
322 }
323 out.close();
324 }
325
326 /**
327 * Convenience method for accessing colour preferences.
328 *
329 * @param colName name of the colour
330 * @param def default value
331 * @return a Color object for the configured colour, or the default value if none configured.
332 */
333 synchronized public Color getColor(String colName, Color def) {
334 String colStr = get("color."+colName);
335 if (colStr.equals("")) {
336 put("color."+colName, ColorHelper.color2html(def));
337 return def;
338 }
339 return ColorHelper.html2color(colStr);
340 }
341
342 // only for compatibility. Don't use any more.
343 @Deprecated
344 public static Color getPreferencesColor(String colName, Color def)
345 {
346 return Main.pref.getColor(colName, def);
347 }
348
349 /**
350 * Convenience method for accessing colour preferences.
351 *
352 * @param colName name of the colour
353 * @param specName name of the special colour settings
354 * @param def default value
355 * @return a Color object for the configured colour, or the default value if none configured.
356 */
357 synchronized public Color getColor(String colName, String specName, Color def) {
358 String colStr = get("color."+specName);
359 if(colStr.equals(""))
360 {
361 colStr = get("color."+colName);
362 if (colStr.equals("")) {
363 put("color."+colName, ColorHelper.color2html(def));
364 return def;
365 }
366 }
367 putDefault("color."+colName, ColorHelper.color2html(def));
368 return ColorHelper.html2color(colStr);
369 }
370
371 synchronized public void putColor(String colName, Color val) {
372 put("color."+colName, val != null ? ColorHelper.color2html(val) : null);
373 }
374
375 synchronized public int getInteger(String key, int def) {
376 putDefault(key, Integer.toString(def));
377 String v = get(key);
378 if(null == v)
379 return def;
380
381 try {
382 return Integer.parseInt(v);
383 } catch(NumberFormatException e) {
384 // fall out
385 }
386 return def;
387 }
388
389 synchronized public long getLong(String key, long def) {
390 putDefault(key, Long.toString(def));
391 String v = get(key);
392 if(null == v)
393 return def;
394
395 try {
396 return Long.parseLong(v);
397 } catch(NumberFormatException e) {
398 // fall out
399 }
400 return def;
401 }
402
403 synchronized public double getDouble(String key, double def) {
404 putDefault(key, Double.toString(def));
405 String v = get(key);
406 if(null == v)
407 return def;
408
409 try {
410 return Double.parseDouble(v);
411 } catch(NumberFormatException e) {
412 // fall out
413 }
414 return def;
415 }
416
417 synchronized public Collection<String> getCollection(String key, Collection<String> def) {
418 String s = get(key);
419 if(s != null && s.length() != 0)
420 {
421 /* handle old comma separated stuff - remove in future */
422 if(s.indexOf(',') >= 0)
423 return Arrays.asList(s.split(","));
424 /* handle space separated stuff - remove in future */
425 else if(s.indexOf(' ') >= 0)
426 return Arrays.asList(s.split(","));
427 else
428 return Arrays.asList(s.split(";"));
429 }
430 else if(def != null)
431 return def;
432 return null;
433 }
434 synchronized public void removeFromCollection(String key, String value) {
435 ArrayList<String> a = new ArrayList<String>(getCollection(key, null));
436 if(a != null)
437 {
438 a.remove(value);
439 putCollection(key, a);
440 }
441 }
442 synchronized public void putCollection(String key, Collection<String> val) {
443 String s = null;
444 if(val != null)
445 {
446 for(String a : val)
447 {
448 if(s != null)
449 s += ";" + a;
450 else
451 s = a;
452 }
453 }
454
455 put(key, s);
456 }
457
458 private void setSystemProperties() {
459 Properties sysProp = System.getProperties();
460 if (getBoolean(ProxyPreferences.PROXY_ENABLE)) {
461 sysProp.put("proxySet", "true");
462 sysProp.put("http.proxyHost", get(ProxyPreferences.PROXY_HOST));
463 sysProp.put("proxyPort", get(ProxyPreferences.PROXY_PORT));
464 if (!getBoolean(ProxyPreferences.PROXY_ANONYMOUS)) {
465 sysProp.put("proxyUser", get(ProxyPreferences.PROXY_USER));
466 sysProp.put("proxyPassword", get(ProxyPreferences.PROXY_PASS));
467 }
468 } else {
469 sysProp.put("proxySet", "false");
470 sysProp.remove("http.proxyHost");
471 sysProp.remove("proxyPort");
472 sysProp.remove("proxyUser");
473 sysProp.remove("proxyPassword");
474 }
475 System.setProperties(sysProp);
476 }
477}
Note: See TracBrowser for help on using the repository browser.