source: josm/trunk/src/org/openstreetmap/josm/gui/MainApplication.java@ 5829

Last change on this file since 5829 was 5829, checked in by Don-vip, 11 years ago

fix javadoc + minor refactorization/code cleanup

  • Property svn:eol-style set to native
File size: 17.6 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Image;
8import java.awt.Toolkit;
9import java.awt.event.WindowAdapter;
10import java.awt.event.WindowEvent;
11import java.io.File;
12import java.net.Authenticator;
13import java.net.ProxySelector;
14import java.net.URL;
15import java.security.AllPermission;
16import java.security.CodeSource;
17import java.security.PermissionCollection;
18import java.security.Permissions;
19import java.security.Policy;
20import java.util.ArrayList;
21import java.util.Collection;
22import java.util.HashMap;
23import java.util.LinkedList;
24import java.util.List;
25import java.util.Map;
26
27import javax.swing.JFrame;
28import javax.swing.RepaintManager;
29import javax.swing.SwingUtilities;
30
31import gnu.getopt.Getopt;
32import gnu.getopt.LongOpt;
33
34import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
35import org.openstreetmap.josm.Main;
36import org.openstreetmap.josm.data.AutosaveTask;
37import org.openstreetmap.josm.data.CustomConfigurator;
38import org.openstreetmap.josm.data.Preferences;
39import org.openstreetmap.josm.data.Version;
40import org.openstreetmap.josm.gui.download.DownloadDialog;
41import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
42import org.openstreetmap.josm.gui.progress.ProgressMonitor;
43import org.openstreetmap.josm.gui.util.GuiHelper;
44import org.openstreetmap.josm.io.DefaultProxySelector;
45import org.openstreetmap.josm.io.auth.CredentialsManager;
46import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
47import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
48import org.openstreetmap.josm.plugins.PluginHandler;
49import org.openstreetmap.josm.plugins.PluginInformation;
50import org.openstreetmap.josm.tools.BugReportExceptionHandler;
51import org.openstreetmap.josm.tools.I18n;
52import org.openstreetmap.josm.tools.ImageProvider;
53
54/**
55 * Main window class application.
56 *
57 * @author imi
58 */
59public class MainApplication extends Main {
60 /**
61 * Allow subclassing (see JOSM.java)
62 */
63 public MainApplication() {}
64
65 /**
66 * Constructs a main frame, ready sized and operating. Does not display the frame.
67 * @param mainFrame The main JFrame of the application
68 */
69 public MainApplication(JFrame mainFrame) {
70 addListener();
71 mainFrame.setContentPane(contentPanePrivate);
72 mainFrame.setJMenuBar(menu);
73 geometry.applySafe(mainFrame);
74 LinkedList<Image> l = new LinkedList<Image>();
75 l.add(ImageProvider.get("logo_16x16x32").getImage());
76 l.add(ImageProvider.get("logo_16x16x8").getImage());
77 l.add(ImageProvider.get("logo_32x32x32").getImage());
78 l.add(ImageProvider.get("logo_32x32x8").getImage());
79 l.add(ImageProvider.get("logo_48x48x32").getImage());
80 l.add(ImageProvider.get("logo_48x48x8").getImage());
81 l.add(ImageProvider.get("logo").getImage());
82 mainFrame.setIconImages(l);
83 mainFrame.addWindowListener(new WindowAdapter(){
84 @Override public void windowClosing(final WindowEvent arg0) {
85 Main.exitJosm(true);
86 }
87 });
88 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
89 }
90
91 /**
92 * Displays help on the console
93 *
94 */
95 public static void showHelp() {
96 // TODO: put in a platformHook for system that have no console by default
97 System.out.println(tr("Java OpenStreetMap Editor")+" ["
98 +Version.getInstance().getAgentString()+"]\n\n"+
99 tr("usage")+":\n"+
100 "\tjava -jar josm.jar <options>...\n\n"+
101 tr("options")+":\n"+
102 "\t--help|-h "+tr("Show this help")+"\n"+
103 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
104 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
105 "\t[--download=]<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z)")+"\n"+
106 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
107 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw GPS")+"\n"+
108 "\t--downloadgps=<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z) as raw GPS")+"\n"+
109 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
110 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
111 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
112 "\t--load-preferences=<url-to-xml> "+tr("Changes preferences according to the XML file")+"\n\n"+
113 "\t--set=<key>=<value> "+tr("Set preference key to value")+"\n\n"+
114 "\t--language=<language> "+tr("Set the language")+"\n\n"+
115 "\t--version "+tr("Displays the JOSM version and exits")+"\n\n"+
116 tr("options provided as Java system properties")+":\n"+
117 "\t-Djosm.home="+tr("/PATH/TO/JOSM/FOLDER/ ")+tr("Change the folder for all user settings")+"\n\n"+
118 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
119 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
120 "\t-Xmx...m\n\n"+
121 tr("examples")+":\n"+
122 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
123 "\tjava -jar josm.jar http://www.openstreetmap.org/index.html?lat=43.2&lon=11.1&zoom=13\n"+
124 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
125 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
126 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
127 "\tjava -Xmx400m -jar josm.jar\n\n"+
128 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
129 tr("Make sure you load some data if you use --selection.")+"\n"
130 );
131 }
132
133 public enum Option {
134 HELP(false),
135 VERSION(false),
136 LANGUAGE(true),
137 RESET_PREFERENCES(false),
138 LOAD_PREFERENCES(true),
139 SET(true),
140 GEOMETRY(true),
141 NO_MAXIMIZE(false),
142 MAXIMIZE(false),
143 DOWNLOAD(true),
144 DOWNLOADGPS(true),
145 SELECTION(true);
146
147 private String name;
148 private boolean requiresArgument;
149
150 private Option(boolean requiresArgument) {
151 this.name = name().toLowerCase().replace("_", "-");
152 this.requiresArgument = requiresArgument;
153 }
154
155 public String getName() {
156 return name;
157 }
158
159 public boolean requiresArgument() {
160 return requiresArgument;
161 }
162
163 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
164 Map<Option, Collection<String>> res = new HashMap<Option, Collection<String>>();
165 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
166 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
167 if (o != null) {
168 res.put(o, e.getValue());
169 }
170 }
171 return res;
172 }
173 }
174
175 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
176
177 List<LongOpt> los = new ArrayList<LongOpt>();
178 for (Option o : Option.values()) {
179 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
180 }
181
182 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[0]));
183
184 Map<Option, Collection<String>> argMap = new HashMap<Option, Collection<String>>();
185
186 int c;
187 while ((c = g.getopt()) != -1 ) {
188 Option opt = null;
189 switch (c) {
190 case 'h':
191 opt = Option.HELP;
192 break;
193 case 'v':
194 opt = Option.VERSION;
195 break;
196 case 0:
197 opt = Option.values()[g.getLongind()];
198 break;
199 }
200 if (opt != null) {
201 Collection<String> values = argMap.get(opt);
202 if (values == null) {
203 values = new ArrayList<String>();
204 argMap.put(opt, values);
205 }
206 values.add(g.getOptarg());
207 } else
208 throw new IllegalArgumentException();
209 }
210 // positional arguments are a shortcut for the --download ... option
211 for (int i = g.getOptind(); i < args.length; ++i) {
212 Collection<String> values = argMap.get(Option.DOWNLOAD);
213 if (values == null) {
214 values = new ArrayList<String>();
215 argMap.put(Option.DOWNLOAD, values);
216 }
217 values.add(args[i]);
218 }
219
220 return argMap;
221 }
222
223 /**
224 * Main application Startup
225 * @param argArray Command-line arguments
226 */
227 public static void main(final String[] argArray) {
228 I18n.init();
229 Main.checkJava6();
230 Main.pref = new Preferences();
231
232 Policy.setPolicy(new Policy() {
233 // Permissions for plug-ins loaded when josm is started via webstart
234 private PermissionCollection pc;
235
236 {
237 pc = new Permissions();
238 pc.add(new AllPermission());
239 }
240
241 @Override
242 public void refresh() { }
243
244 @Override
245 public PermissionCollection getPermissions(CodeSource codesource) {
246 return pc;
247 }
248 });
249
250 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
251 // http://stuffthathappens.com/blog/2007/10/15/one-more-note-on-uncaught-exception-handlers/
252 System.setProperty("sun.awt.exception.handler", BugReportExceptionHandler.class.getName());
253
254 // initialize the platform hook, and
255 Main.determinePlatformHook();
256 // call the really early hook before we do anything else
257 Main.platform.preStartupHook();
258
259 // construct argument table
260 Map<Option, Collection<String>> args = null;
261 try {
262 args = buildCommandLineArgumentMap(argArray);
263 } catch (IllegalArgumentException e) {
264 System.exit(1);
265 }
266
267 if (args.containsKey(Option.VERSION)) {
268 System.out.println(Version.getInstance().getAgentString());
269 System.exit(0);
270 } //else {
271 // System.out.println(Version.getInstance().getReleaseAttributes());
272 //}
273
274 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
275
276 // Check if passed as parameter
277 if (args.containsKey(Option.LANGUAGE)) {
278 I18n.set(args.get(Option.LANGUAGE).iterator().next());
279 } else {
280 I18n.set(Main.pref.get("language", null));
281 }
282 Main.pref.updateSystemProperties();
283
284 final JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
285 Main.parent = mainFrame;
286
287 if (args.containsKey(Option.LOAD_PREFERENCES)) {
288 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
289 for (String i : args.get(Option.LOAD_PREFERENCES)) {
290 System.out.println("Reading preferences from " + i);
291 try {
292 URL url = new URL(i);
293 config.openAndReadXML(url.openStream());
294 } catch (Exception ex) {
295 throw new RuntimeException(ex);
296 }
297 }
298 }
299
300 if (args.containsKey(Option.SET)) {
301 for (String i : args.get(Option.SET)) {
302 String[] kv = i.split("=", 2);
303 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
304 }
305 }
306
307 DefaultAuthenticator.createInstance();
308 Authenticator.setDefault(DefaultAuthenticator.getInstance());
309 ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
310 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
311
312 // asking for help? show help and exit
313 if (args.containsKey(Option.HELP)) {
314 showHelp();
315 System.exit(0);
316 }
317
318 final SplashScreen splash = new SplashScreen();
319 final ProgressMonitor monitor = splash.getProgressMonitor();
320 monitor.beginTask(tr("Initializing"));
321 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
322 Main.setInitStatusListener(new InitStatusListener() {
323
324 @Override
325 public void updateStatus(String event) {
326 monitor.indeterminateSubTask(event);
327 }
328 });
329
330 List<PluginInformation> pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash,monitor.createSubTaskMonitor(1, false));
331 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
332 monitor.subTask(tr("Updating plugins"));
333 pluginsToLoad = PluginHandler.updatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
334 }
335
336 monitor.indeterminateSubTask(tr("Installing updated plugins"));
337 PluginHandler.installDownloadedPlugins(true);
338
339 monitor.indeterminateSubTask(tr("Loading early plugins"));
340 PluginHandler.loadEarlyPlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
341
342 monitor.indeterminateSubTask(tr("Setting defaults"));
343 preConstructorInit(args);
344
345 monitor.indeterminateSubTask(tr("Creating main GUI"));
346 final Main main = new MainApplication(mainFrame);
347
348 monitor.indeterminateSubTask(tr("Loading plugins"));
349 PluginHandler.loadLatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
350 toolbar.refreshToolbarControl();
351
352 GuiHelper.runInEDT(new Runnable() {
353 public void run() {
354 splash.setVisible(false);
355 splash.dispose();
356 mainFrame.setVisible(true);
357 }
358 });
359
360 Main.MasterWindowListener.setup();
361
362 boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized"));
363 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
364 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
365 // Main.debug("Main window maximized");
366 Main.windowState = JFrame.MAXIMIZED_BOTH;
367 mainFrame.setExtendedState(Main.windowState);
368 } else {
369 Main.debug("Main window: maximizing not supported");
370 }
371 } else {
372 // Main.debug("Main window not maximized");
373 }
374 if(main.menu.fullscreenToggleAction != null) {
375 main.menu.fullscreenToggleAction.initial();
376 }
377
378 final Map<Option, Collection<String>> args_final = args;
379
380 SwingUtilities.invokeLater(new Runnable() {
381 public void run() {
382 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
383 AutosaveTask autosaveTask = new AutosaveTask();
384 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
385 if (!unsavedLayerFiles.isEmpty()) {
386 ExtendedDialog dialog = new ExtendedDialog(
387 Main.parent,
388 tr("Unsaved osm data"),
389 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
390 );
391 dialog.setContent(
392 trn("JOSM found {0} unsaved osm data layer. ",
393 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
394 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
395 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
396 int selection = dialog.showDialog().getValue();
397 if (selection == 1) {
398 autosaveTask.recoverUnsavedLayers();
399 } else if (selection == 3) {
400 autosaveTask.dicardUnsavedLayers();
401 }
402 }
403 autosaveTask.schedule();
404 }
405
406 postConstructorProcessCmdLine(args_final);
407
408 DownloadDialog.autostartIfNeeded();
409 }
410 });
411
412 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
413 RemoteControl.start();
414 }
415
416 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
417 // Repaint manager is registered so late for a reason - there is lots of violation during startup process but they don't seem to break anything and are difficult to fix
418 System.out.println("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
419 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
420 }
421 }
422}
Note: See TracBrowser for help on using the repository browser.