1 | package org.openstreetmap.josm.data;
|
---|
2 |
|
---|
3 | import java.beans.PropertyChangeEvent;
|
---|
4 | import java.beans.PropertyChangeListener;
|
---|
5 | import java.io.File;
|
---|
6 | import java.io.FileReader;
|
---|
7 | import java.io.FileWriter;
|
---|
8 | import java.util.Collection;
|
---|
9 | import java.util.LinkedList;
|
---|
10 | import java.util.List;
|
---|
11 |
|
---|
12 | import javax.swing.UIManager;
|
---|
13 | import javax.swing.UIManager.LookAndFeelInfo;
|
---|
14 |
|
---|
15 | import org.jdom.Element;
|
---|
16 | import org.jdom.input.SAXBuilder;
|
---|
17 | import org.jdom.output.Format;
|
---|
18 | import org.jdom.output.XMLOutputter;
|
---|
19 | import org.openstreetmap.josm.data.projection.LatitudeLongitude;
|
---|
20 | import org.openstreetmap.josm.data.projection.Projection;
|
---|
21 | import org.openstreetmap.josm.data.projection.UTM;
|
---|
22 |
|
---|
23 |
|
---|
24 | /**
|
---|
25 | * This class holds all preferences for JOSM.
|
---|
26 | *
|
---|
27 | * @author imi
|
---|
28 | */
|
---|
29 | public class Preferences {
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * The look and feel. Classname of the look and feel class to use.
|
---|
33 | */
|
---|
34 | public LookAndFeelInfo laf = UIManager.getInstalledLookAndFeels()[0];
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * The convertor used to translate lat/lon points to screen points.
|
---|
38 | */
|
---|
39 | private Projection projection = new UTM();
|
---|
40 |
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Whether lines should be drawn between track points of raw gps data.
|
---|
44 | */
|
---|
45 | private boolean drawRawGpsLines = false;
|
---|
46 | /**
|
---|
47 | * Force the drawing of lines between raw gps points if there are no
|
---|
48 | * lines in the imported document.
|
---|
49 | */
|
---|
50 | private boolean forceRawGpsLines = false;
|
---|
51 | /**
|
---|
52 | * Whether nodes on the same place should be considered identical.
|
---|
53 | */
|
---|
54 | public boolean mergeNodes = true;
|
---|
55 |
|
---|
56 | /**
|
---|
57 | * Base URL to the osm data server
|
---|
58 | */
|
---|
59 | public String osmDataServer = "http://www.openstreetmap.org/api/0.1";
|
---|
60 | /**
|
---|
61 | * The username to the osm server
|
---|
62 | */
|
---|
63 | public String osmDataUsername = "";
|
---|
64 | /**
|
---|
65 | * The stored password or <code>null</code>, if the password should not be
|
---|
66 | * stored.
|
---|
67 | */
|
---|
68 | public String osmDataPassword = null;
|
---|
69 |
|
---|
70 | /**
|
---|
71 | * List of all available Projections.
|
---|
72 | */
|
---|
73 | public static final Projection[] allProjections = new Projection[]{
|
---|
74 | new UTM(),
|
---|
75 | new LatitudeLongitude()
|
---|
76 | };
|
---|
77 |
|
---|
78 | /**
|
---|
79 | * Return the location of the preferences file
|
---|
80 | */
|
---|
81 | public static String getPreferencesFile() {
|
---|
82 | return System.getProperty("user.home")+"/.josm-preferences";
|
---|
83 | }
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * Exception thrown in case of any loading/saving error (including parse errors).
|
---|
87 | * @author imi
|
---|
88 | */
|
---|
89 | public static class PreferencesException extends Exception {
|
---|
90 | public PreferencesException(String message, Throwable cause) {
|
---|
91 | super(message, cause);
|
---|
92 | }
|
---|
93 | }
|
---|
94 | /**
|
---|
95 | * Load from disk.
|
---|
96 | * @throws PreferencesException Any loading error (parse errors as well)
|
---|
97 | */
|
---|
98 | public void load() throws PreferencesException {
|
---|
99 | File file = new File(System.getProperty("user.home")+"/.josm-preferences");
|
---|
100 | Element root;
|
---|
101 | try {
|
---|
102 | root = new SAXBuilder().build(new FileReader(file)).getRootElement();
|
---|
103 |
|
---|
104 | // laf
|
---|
105 | String lafClassName = root.getChildText("laf");
|
---|
106 | for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels())
|
---|
107 | if (lafInfo.getClassName().equals(lafClassName)) {
|
---|
108 | laf = lafInfo;
|
---|
109 | break;
|
---|
110 | }
|
---|
111 | if (laf == null)
|
---|
112 | throw new PreferencesException("Look and Feel not found.", null);
|
---|
113 |
|
---|
114 | // projection
|
---|
115 | Class<?> projectionClass = Class.forName(root.getChildText("projection"));
|
---|
116 | projection = allProjections[0]; // defaults to UTM
|
---|
117 | for (Projection p : allProjections) {
|
---|
118 | if (p.getClass() == projectionClass) {
|
---|
119 | projection = p;
|
---|
120 | break;
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | Element osmServer = root.getChild("osm-server");
|
---|
125 | if (osmServer != null) {
|
---|
126 | osmDataServer = osmServer.getChildText("url");
|
---|
127 | osmDataUsername = osmServer.getChildText("username");
|
---|
128 | osmDataPassword = osmServer.getChildText("password");
|
---|
129 | }
|
---|
130 | mergeNodes = root.getChild("mergeNodes") != null;
|
---|
131 | drawRawGpsLines = root.getChild("drawRawGpsLines") != null;
|
---|
132 | } catch (Exception e) {
|
---|
133 | if (e instanceof PreferencesException)
|
---|
134 | throw (PreferencesException)e;
|
---|
135 | throw new PreferencesException("Could not load preferences", e);
|
---|
136 | }
|
---|
137 |
|
---|
138 | }
|
---|
139 | /**
|
---|
140 | * Save to disk.
|
---|
141 | * @throws PreferencesException Any saving error (exceeding disk space, etc..)
|
---|
142 | */
|
---|
143 | @SuppressWarnings("unchecked")
|
---|
144 | public void save() throws PreferencesException {
|
---|
145 | Element root = new Element("josm-settings");
|
---|
146 |
|
---|
147 | List children = root.getChildren();
|
---|
148 | children.add(new Element("laf").setText(laf.getClassName()));
|
---|
149 | children.add(new Element("projection").setText(getProjection().getClass().getName()));
|
---|
150 | if (mergeNodes)
|
---|
151 | children.add(new Element("mergeNodes"));
|
---|
152 | if (drawRawGpsLines)
|
---|
153 | children.add(new Element("drawRawGpsLines"));
|
---|
154 | Element osmServer = new Element("osm-server");
|
---|
155 | osmServer.getChildren().add(new Element("url").setText(osmDataServer));
|
---|
156 | osmServer.getChildren().add(new Element("username").setText(osmDataUsername));
|
---|
157 | osmServer.getChildren().add(new Element("password").setText(osmDataPassword));
|
---|
158 | children.add(osmServer);
|
---|
159 |
|
---|
160 | try {
|
---|
161 | final FileWriter file = new FileWriter(getPreferencesFile());
|
---|
162 | new XMLOutputter(Format.getPrettyFormat()).output(root, file);
|
---|
163 | file.close();
|
---|
164 | } catch (Exception e) {
|
---|
165 | throw new PreferencesException("Could not write preferences", e);
|
---|
166 | }
|
---|
167 | }
|
---|
168 |
|
---|
169 |
|
---|
170 | // projection change listener stuff
|
---|
171 |
|
---|
172 | /**
|
---|
173 | * The list of all listeners to projection changes.
|
---|
174 | */
|
---|
175 | private Collection<PropertyChangeListener> listener = new LinkedList<PropertyChangeListener>();
|
---|
176 | /**
|
---|
177 | * Add a listener of projection changes to the list of listeners.
|
---|
178 | * @param listener The listerner to add.
|
---|
179 | */
|
---|
180 | public void addPropertyChangeListener(PropertyChangeListener listener) {
|
---|
181 | if (listener != null)
|
---|
182 | this.listener.add(listener);
|
---|
183 | }
|
---|
184 | /**
|
---|
185 | * Remove the listener from the list.
|
---|
186 | */
|
---|
187 | public void removePropertyChangeListener(PropertyChangeListener listener) {
|
---|
188 | this.listener.remove(listener);
|
---|
189 | }
|
---|
190 | /**
|
---|
191 | * Fires a PropertyChangeEvent if the old value differs from the new value.
|
---|
192 | */
|
---|
193 | private <T> void firePropertyChanged(String name, T oldValue, T newValue) {
|
---|
194 | if (oldValue == newValue)
|
---|
195 | return;
|
---|
196 | PropertyChangeEvent evt = null;
|
---|
197 | for (PropertyChangeListener l : listener) {
|
---|
198 | if (evt == null)
|
---|
199 | evt = new PropertyChangeEvent(this, name, oldValue, newValue);
|
---|
200 | l.propertyChange(evt);
|
---|
201 | }
|
---|
202 | }
|
---|
203 |
|
---|
204 | // getter / setter
|
---|
205 |
|
---|
206 | /**
|
---|
207 | * Set the projection and fire an event to all ProjectionChangeListener
|
---|
208 | * @param projection The new Projection.
|
---|
209 | */
|
---|
210 | public void setProjection(Projection projection) {
|
---|
211 | Projection old = this.projection;
|
---|
212 | this.projection = projection;
|
---|
213 | firePropertyChanged("projection", old, projection);
|
---|
214 | }
|
---|
215 | /**
|
---|
216 | * Get the current projection.
|
---|
217 | * @return The current projection set.
|
---|
218 | */
|
---|
219 | public Projection getProjection() {
|
---|
220 | return projection;
|
---|
221 | }
|
---|
222 | public void setDrawRawGpsLines(boolean drawRawGpsLines) {
|
---|
223 | boolean old = this.drawRawGpsLines;
|
---|
224 | this.drawRawGpsLines = drawRawGpsLines;
|
---|
225 | firePropertyChanged("drawRawGpsLines", old, drawRawGpsLines);
|
---|
226 | }
|
---|
227 | public boolean isDrawRawGpsLines() {
|
---|
228 | return drawRawGpsLines;
|
---|
229 | }
|
---|
230 | public void setForceRawGpsLines(boolean forceRawGpsLines) {
|
---|
231 | boolean old = this.forceRawGpsLines;
|
---|
232 | this.forceRawGpsLines = forceRawGpsLines;
|
---|
233 | firePropertyChanged("forceRawGpsLines", old, forceRawGpsLines);
|
---|
234 | }
|
---|
235 | public boolean isForceRawGpsLines() {
|
---|
236 | return forceRawGpsLines;
|
---|
237 | }
|
---|
238 | }
|
---|