source: josm/src/org/openstreetmap/josm/Main.java@ 103

Last change on this file since 103 was 103, checked in by imi, 18 years ago
  • fixed unicode compatibility
  • added Layer menu which mirrors the layer list context menu
  • added "convert to data layer" for all gps layers
  • removed raw gpx import and 0.2 osm-file import
  • removed dependency to JDOM
File size: 11.9 KB
Line 
1package org.openstreetmap.josm;
2
3import java.awt.BorderLayout;
4import java.awt.Component;
5import java.awt.Dimension;
6import java.awt.Rectangle;
7import java.awt.Toolkit;
8import java.io.File;
9import java.io.IOException;
10import java.net.URI;
11import java.net.URISyntaxException;
12import java.util.Collection;
13import java.util.Map;
14import java.util.StringTokenizer;
15import java.util.concurrent.Executor;
16import java.util.concurrent.Executors;
17import java.util.regex.Matcher;
18import java.util.regex.Pattern;
19
20import javax.swing.Action;
21import javax.swing.JMenu;
22import javax.swing.JMenuBar;
23import javax.swing.JOptionPane;
24import javax.swing.JPanel;
25import javax.swing.JSeparator;
26import javax.swing.JToolBar;
27import javax.swing.UIManager;
28
29import org.openstreetmap.josm.actions.AboutAction;
30import org.openstreetmap.josm.actions.DownloadAction;
31import org.openstreetmap.josm.actions.ExitAction;
32import org.openstreetmap.josm.actions.GpxExportAction;
33import org.openstreetmap.josm.actions.OpenAction;
34import org.openstreetmap.josm.actions.PreferencesAction;
35import org.openstreetmap.josm.actions.RedoAction;
36import org.openstreetmap.josm.actions.SaveAction;
37import org.openstreetmap.josm.actions.UndoAction;
38import org.openstreetmap.josm.actions.UploadAction;
39import org.openstreetmap.josm.actions.mapmode.MapMode;
40import org.openstreetmap.josm.data.Bounds;
41import org.openstreetmap.josm.data.Preferences;
42import org.openstreetmap.josm.data.osm.DataSet;
43import org.openstreetmap.josm.data.projection.Epsg4326;
44import org.openstreetmap.josm.data.projection.Projection;
45import org.openstreetmap.josm.gui.MapFrame;
46import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
47import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
48import org.openstreetmap.josm.gui.layer.Layer;
49import org.openstreetmap.josm.gui.layer.OsmDataLayer;
50import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
51import org.openstreetmap.josm.tools.ImageProvider;
52
53abstract public class Main {
54 /**
55 * Global parent component for all dialogs and message boxes
56 */
57 public static Component parent;
58 /**
59 * Global application window. Use this as JOPtionPane-parent to center on application.
60 */
61 public static Main main;
62 /**
63 * The worker thread slave. This is for executing all long and intensive
64 * calculations. The executed runnables are guaranteed to be executed seperatly
65 * and sequenciel.
66 */
67 public final static Executor worker = Executors.newSingleThreadExecutor();
68 /**
69 * Global application preferences
70 */
71 public static Preferences pref = new Preferences();
72 /**
73 * The global dataset.
74 */
75 public static DataSet ds = new DataSet();
76 /**
77 * The projection method used.
78 */
79 public static Projection proj;
80 /**
81 * The MapFrame. Use setMapFrame to set or clear it.
82 */
83 public static MapFrame map;
84
85 /**
86 * Set or clear (if passed <code>null</code>) the map.
87 */
88 public final void setMapFrame(final MapFrame map) {
89 Main.map = map;
90 panel.setVisible(false);
91 panel.removeAll();
92 if (map != null) {
93 map.fillPanel(panel);
94 panel.setVisible(true);
95 map.mapView.addLayerChangeListener(new LayerChangeListener(){
96 public void activeLayerChange(final Layer oldLayer, final Layer newLayer) {
97 setLayerMenu(newLayer.getMenuEntries());
98 }
99 public void layerAdded(final Layer newLayer) {
100 if (newLayer instanceof OsmDataLayer)
101 Main.main.editLayer().listenerCommands.add(redoUndoListener);
102 }
103 public void layerRemoved(final Layer oldLayer) {
104 if (oldLayer instanceof OsmDataLayer)
105 Main.main.editLayer().listenerCommands.add(redoUndoListener);
106 if (map.mapView.getAllLayers().isEmpty())
107 setLayerMenu(null);
108 }
109 });
110 if (map.mapView.editLayer != null)
111 map.mapView.editLayer.listenerCommands.add(redoUndoListener);
112 }
113 redoUndoListener.commandChanged(0,0);
114 }
115
116 /**
117 * Set the layer menu (changed when active layer changes).
118 */
119 public final void setLayerMenu(Component[] entries) {
120 if (entries == null || entries.length == 0)
121 layerMenu.setVisible(false);
122 else {
123 layerMenu.removeAll();
124 for (Component c : entries)
125 layerMenu.add(c);
126 layerMenu.setVisible(true);
127 }
128 }
129
130 /**
131 * Remove the specified layer from the map. If it is the last layer, remove the map as well.
132 */
133 public final void removeLayer(final Layer layer) {
134 map.mapView.removeLayer(layer);
135 if (layer instanceof OsmDataLayer)
136 ds = new DataSet();
137 if (map.mapView.getAllLayers().isEmpty())
138 setMapFrame(null);
139 }
140 public Main() {
141 main = this;
142 contentPane.add(panel, BorderLayout.CENTER);
143
144 final Action uploadAction = new UploadAction();
145 final Action saveAction = new SaveAction();
146 final Action gpxExportAction = new GpxExportAction(null);
147 final Action exitAction = new ExitAction();
148 final Action preferencesAction = new PreferencesAction();
149 final Action aboutAction = new AboutAction();
150
151 final JMenu fileMenu = new JMenu("Files");
152 fileMenu.setMnemonic('F');
153 fileMenu.add(openAction);
154 fileMenu.add(saveAction);
155 fileMenu.add(gpxExportAction);
156 fileMenu.addSeparator();
157 fileMenu.add(exitAction);
158 mainMenu.add(fileMenu);
159
160
161 final JMenu connectionMenu = new JMenu("Connection");
162 connectionMenu.setMnemonic('C');
163 connectionMenu.add(downloadAction);
164 connectionMenu.add(uploadAction);
165 mainMenu.add(connectionMenu);
166
167 layerMenu = new JMenu("Layer");
168 layerMenu.setMnemonic('L');
169 mainMenu.add(layerMenu);
170 layerMenu.setVisible(false);
171
172 final JMenu editMenu = new JMenu("Edit");
173 editMenu.setMnemonic('E');
174 editMenu.add(undoAction);
175 editMenu.add(redoAction);
176 editMenu.addSeparator();
177 editMenu.add(preferencesAction);
178 mainMenu.add(editMenu);
179
180 mainMenu.add(new JSeparator());
181 final JMenu helpMenu = new JMenu("Help");
182 helpMenu.setMnemonic('H');
183 helpMenu.add(aboutAction);
184 mainMenu.add(helpMenu);
185
186 // creating toolbar
187 final JToolBar toolBar = new JToolBar();
188 toolBar.setFloatable(false);
189 toolBar.add(downloadAction);
190 toolBar.add(uploadAction);
191 toolBar.addSeparator();
192 toolBar.add(openAction);
193 toolBar.add(saveAction);
194 toolBar.add(gpxExportAction);
195 toolBar.addSeparator();
196 toolBar.add(undoAction);
197 toolBar.add(redoAction);
198 toolBar.addSeparator();
199 toolBar.add(preferencesAction);
200 contentPane.add(toolBar, BorderLayout.NORTH);
201
202 contentPane.updateUI();
203 }
204 /**
205 * Add a new layer to the map. If no map exist, create one.
206 */
207 public final void addLayer(final Layer layer) {
208 if (map == null) {
209 final MapFrame mapFrame = new MapFrame();
210 setMapFrame(mapFrame);
211 mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction());
212 mapFrame.setVisible(true);
213 mapFrame.setVisibleDialogs();
214 }
215 map.mapView.addLayer(layer);
216 }
217 /**
218 * @return The edit osm layer. If none exist, it will be created.
219 */
220 public final OsmDataLayer editLayer() {
221 if (map == null || map.mapView.editLayer == null)
222 addLayer(new OsmDataLayer(ds, "unnamed", false));
223 return map.mapView.editLayer;
224 }
225
226
227
228
229 /**
230 * Use this to register shortcuts to
231 */
232 public static final JPanel contentPane = new JPanel(new BorderLayout());
233
234
235 ////////////////////////////////////////////////////////////////////////////////////////
236 // Implementation part
237 ////////////////////////////////////////////////////////////////////////////////////////
238
239
240 private static JPanel panel = new JPanel(new BorderLayout());
241
242 protected final JMenuBar mainMenu = new JMenuBar();
243 protected static Rectangle bounds;
244
245 private final UndoAction undoAction = new UndoAction();
246 private final RedoAction redoAction = new RedoAction();
247 private final OpenAction openAction = new OpenAction();
248 private final DownloadAction downloadAction = new DownloadAction();
249
250 private final CommandQueueListener redoUndoListener = new CommandQueueListener(){
251 public void commandChanged(final int queueSize, final int redoSize) {
252 undoAction.setEnabled(queueSize > 0);
253 redoAction.setEnabled(redoSize > 0);
254 }
255 };
256 private JMenu layerMenu;
257
258 /**
259 * Should be called before the main constructor to setup some parameter stuff
260 * @param args The parsed argument list.
261 */
262 public static void preConstructorInit(Map<String, Collection<String>> args) {
263 // load preferences
264 String errMsg = null;
265 try {
266 if (args.containsKey("reset-preferences")) {
267 Main.pref.resetToDefault();
268 } else
269 Main.pref.load();
270 } catch (final IOException e1) {
271 e1.printStackTrace();
272 errMsg = "Preferences could not be loaded. Write default preference file to '"+pref.getPreferencesDir()+"preferences'.";
273 Main.pref.resetToDefault();
274 }
275 if (errMsg != null)
276 JOptionPane.showMessageDialog(null, errMsg);
277
278 try {
279 Main.proj = (Projection)Class.forName(Main.pref.get("projection")).newInstance();
280 } catch (final Exception e) {
281 e.printStackTrace();
282 JOptionPane.showMessageDialog(null, "The projection could not be read from preferences. Using EPSG:4263.");
283 Main.proj = new Epsg4326();
284 }
285
286 try {
287 UIManager.setLookAndFeel(Main.pref.get("laf"));
288 contentPane.updateUI();
289 panel.updateUI();
290 } catch (final Exception e) {
291 e.printStackTrace();
292 }
293 UIManager.put("OptionPane.okIcon", ImageProvider.get("ok"));
294 UIManager.put("OptionPane.yesIcon", UIManager.get("OptionPane.okIcon"));
295 UIManager.put("OptionPane.cancelIcon", ImageProvider.get("cancel"));
296 UIManager.put("OptionPane.noIcon", UIManager.get("OptionPane.cancelIcon"));
297
298 Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
299 if (args.containsKey("geometry")) {
300 String geometry = args.get("geometry").iterator().next();
301 final Matcher m = Pattern.compile("(\\d+)x(\\d+)(([+-])(\\d+)([+-])(\\d+))?").matcher(geometry);
302 if (m.matches()) {
303 int w = Integer.valueOf(m.group(1));
304 int h = Integer.valueOf(m.group(2));
305 int x = 0, y = 0;
306 if (m.group(3) != null) {
307 x = Integer.valueOf(m.group(5));
308 y = Integer.valueOf(m.group(7));
309 if (m.group(4).equals("-"))
310 x = screenDimension.width - x - w;
311 if (m.group(6).equals("-"))
312 y = screenDimension.height - y - h;
313 }
314 bounds = new Rectangle(x,y,w,h);
315 } else
316 System.out.println("Ignoring malformed geometry: "+geometry);
317 }
318 if (bounds == null)
319 bounds = !args.containsKey("no-fullscreen") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
320 }
321
322 public void postConstructorProcessCmdLine(Map<String, Collection<String>> args) {
323 if (args.containsKey("download"))
324 for (String s : args.get("download"))
325 downloadFromParamString(false, s);
326 if (args.containsKey("downloadgps"))
327 for (String s : args.get("downloadgps"))
328 downloadFromParamString(true, s);
329 if (args.containsKey("selection"))
330 for (String s : args.get("selection"))
331 SelectionListDialog.search(s, SelectionListDialog.SearchMode.add);
332 }
333
334 private static void downloadFromParamString(final boolean rawGps, String s) {
335 if (s.startsWith("http:")) {
336 final Bounds b = DownloadAction.osmurl2bounds(s);
337 if (b == null)
338 JOptionPane.showMessageDialog(Main.parent, "Ignoring malformed url: '"+s+"'");
339 else
340 main.downloadAction.download(false, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
341 return;
342 }
343
344 if (s.startsWith("file:")) {
345 try {
346 main.openAction.openFile(new File(new URI(s)));
347 } catch (URISyntaxException e) {
348 JOptionPane.showMessageDialog(Main.parent, "Ignoring malformed file url: '"+s+"'");
349 }
350 return;
351 }
352
353 final StringTokenizer st = new StringTokenizer(s, ",");
354 if (st.countTokens() == 4) {
355 try {
356 main.downloadAction.download(rawGps, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
357 return;
358 } catch (final NumberFormatException e) {
359 }
360 }
361
362 main.openAction.openFile(new File(s));
363 }
364}
Note: See TracBrowser for help on using the repository browser.