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

Last change on this file since 8308 was 8298, checked in by stoecker, 9 years ago

see #8562 - text improvement

  • Property svn:eol-style set to native
File size: 29.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6import gnu.getopt.Getopt;
7import gnu.getopt.LongOpt;
8
9import java.awt.Dimension;
10import java.awt.Image;
11import java.awt.Toolkit;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.io.File;
15import java.io.IOException;
16import java.io.InputStream;
17import java.net.Authenticator;
18import java.net.InetAddress;
19import java.net.Inet6Address;
20import java.net.ProxySelector;
21import java.net.URL;
22import java.security.AllPermission;
23import java.security.CodeSource;
24import java.security.KeyStoreException;
25import java.security.NoSuchAlgorithmException;
26import java.security.PermissionCollection;
27import java.security.Permissions;
28import java.security.Policy;
29import java.security.cert.CertificateException;
30import java.util.ArrayList;
31import java.util.Arrays;
32import java.util.Collection;
33import java.util.HashMap;
34import java.util.LinkedList;
35import java.util.List;
36import java.util.Map;
37import java.util.Set;
38import java.util.TreeSet;
39
40import javax.swing.JFrame;
41import javax.swing.JOptionPane;
42import javax.swing.RepaintManager;
43import javax.swing.SwingUtilities;
44
45import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
46import org.openstreetmap.josm.Main;
47import org.openstreetmap.josm.actions.PreferencesAction;
48import org.openstreetmap.josm.data.AutosaveTask;
49import org.openstreetmap.josm.data.CustomConfigurator;
50import org.openstreetmap.josm.data.Version;
51import org.openstreetmap.josm.gui.download.DownloadDialog;
52import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
53import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
54import org.openstreetmap.josm.gui.progress.ProgressMonitor;
55import org.openstreetmap.josm.gui.util.GuiHelper;
56import org.openstreetmap.josm.io.DefaultProxySelector;
57import org.openstreetmap.josm.io.MessageNotifier;
58import org.openstreetmap.josm.io.OnlineResource;
59import org.openstreetmap.josm.io.auth.CredentialsManager;
60import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
61import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
62import org.openstreetmap.josm.plugins.PluginHandler;
63import org.openstreetmap.josm.plugins.PluginInformation;
64import org.openstreetmap.josm.tools.BugReportExceptionHandler;
65import org.openstreetmap.josm.tools.FontsManager;
66import org.openstreetmap.josm.tools.I18n;
67import org.openstreetmap.josm.tools.ImageProvider;
68import org.openstreetmap.josm.tools.OsmUrlToBounds;
69import org.openstreetmap.josm.tools.PlatformHookWindows;
70import org.openstreetmap.josm.tools.Utils;
71
72/**
73 * Main window class application.
74 *
75 * @author imi
76 */
77public class MainApplication extends Main {
78 /**
79 * Allow subclassing (see JOSM.java)
80 */
81 public MainApplication() {}
82
83 /**
84 * Constructs a main frame, ready sized and operating. Does not display the frame.
85 * @param mainFrame The main JFrame of the application
86 */
87 public MainApplication(JFrame mainFrame) {
88 addListener();
89 mainFrame.setContentPane(contentPanePrivate);
90 mainFrame.setJMenuBar(menu);
91 geometry.applySafe(mainFrame);
92 List<Image> l = new LinkedList<>();
93 l.add(ImageProvider.get("logo_16x16x32").getImage());
94 l.add(ImageProvider.get("logo_16x16x8").getImage());
95 l.add(ImageProvider.get("logo_32x32x32").getImage());
96 l.add(ImageProvider.get("logo_32x32x8").getImage());
97 l.add(ImageProvider.get("logo_48x48x32").getImage());
98 l.add(ImageProvider.get("logo_48x48x8").getImage());
99 l.add(ImageProvider.get("logo").getImage());
100 mainFrame.setIconImages(l);
101 mainFrame.addWindowListener(new WindowAdapter(){
102 @Override
103 public void windowClosing(final WindowEvent arg0) {
104 Main.exitJosm(true, 0);
105 }
106 });
107 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
108 }
109
110 /**
111 * Displays help on the console
112 * @since 2748
113 */
114 public static void showHelp() {
115 // TODO: put in a platformHook for system that have no console by default
116 System.out.println(tr("Java OpenStreetMap Editor")+" ["
117 +Version.getInstance().getAgentString()+"]\n\n"+
118 tr("usage")+":\n"+
119 "\tjava -jar josm.jar <options>...\n\n"+
120 tr("options")+":\n"+
121 "\t--help|-h "+tr("Show this help")+"\n"+
122 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
123 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
124 "\t[--download=]<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z)")+"\n"+
125 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
126 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw GPS")+"\n"+
127 "\t--downloadgps=<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z) as raw GPS")+"\n"+
128 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
129 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
130 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
131 "\t--load-preferences=<url-to-xml> "+tr("Changes preferences according to the XML file")+"\n\n"+
132 "\t--set=<key>=<value> "+tr("Set preference key to value")+"\n\n"+
133 "\t--language=<language> "+tr("Set the language")+"\n\n"+
134 "\t--version "+tr("Displays the JOSM version and exits")+"\n\n"+
135 "\t--debug "+tr("Print debugging messages to console")+"\n\n"+
136 "\t--skip-plugins "+tr("Skip loading plugins")+"\n\n"+
137 "\t--offline=<osm_api|josm_website|all> "+tr("Disable access to the given resource(s), separated by comma")+"\n\n"+
138 tr("options provided as Java system properties")+":\n"+
139 "\t-Djosm.pref=" +tr("/PATH/TO/JOSM/PREF ")+tr("Set the preferences directory")+"\n\n"+
140 "\t-Djosm.userdata="+tr("/PATH/TO/JOSM/USERDATA")+tr("Set the user data directory")+"\n\n"+
141 "\t-Djosm.cache=" +tr("/PATH/TO/JOSM/CACHE ")+tr("Set the cache directory")+"\n\n"+
142 "\t-Djosm.home=" +tr("/PATH/TO/JOSM/HOMEDIR ")+
143 tr("Relocate all 3 directories to homedir. Cache directory will be in homedir/cache")+"\n\n"+
144 tr("-Djosm.home has lower precedence, i.e. the specific setting overrides the general one")+"\n\n"+
145 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
146 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
147 "\t-Xmx...m\n\n"+
148 tr("examples")+":\n"+
149 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
150 "\tjava -jar josm.jar "+OsmUrlToBounds.getURL(43.2, 11.1, 13)+"\n"+
151 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
152 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
153 "\tjava -Djosm.pref=$XDG_CONFIG_HOME -Djosm.userdata=$XDG_DATA_HOME -Djosm.cache=$XDG_CACHE_HOME -jar josm.jar\n"+
154 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
155 "\tjava -Xmx1024m -jar josm.jar\n\n"+
156 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
157 tr("Make sure you load some data if you use --selection.")+"\n"
158 );
159 }
160
161 /**
162 * JOSM command line options.
163 * @see <a href="https://josm.openstreetmap.de/wiki/Help/CommandLineOptions">Help/CommandLineOptions</a>
164 * @since 5279
165 */
166 public enum Option {
167 /** --help|-h Show this help */
168 HELP(false),
169 /** --version Displays the JOSM version and exits */
170 VERSION(false),
171 /** --debug Print debugging messages to console */
172 DEBUG(false),
173 /** --trace Print detailed debugging messages to console */
174 TRACE(false),
175 /** --language=&lt;language&gt; Set the language */
176 LANGUAGE(true),
177 /** --reset-preferences Reset the preferences to default */
178 RESET_PREFERENCES(false),
179 /** --load-preferences=&lt;url-to-xml&gt; Changes preferences according to the XML file */
180 LOAD_PREFERENCES(true),
181 /** --set=&lt;key&gt;=&lt;value&gt; Set preference key to value */
182 SET(true),
183 /** --geometry=widthxheight(+|-)x(+|-)y Standard unix geometry argument */
184 GEOMETRY(true),
185 /** --no-maximize Do not launch in maximized mode */
186 NO_MAXIMIZE(false),
187 /** --maximize Launch in maximized mode */
188 MAXIMIZE(false),
189 /** --download=minlat,minlon,maxlat,maxlon Download the bounding box <br>
190 * --download=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) <br>
191 * --download=&lt;filename&gt; Open a file (any file type that can be opened with File/Open) */
192 DOWNLOAD(true),
193 /** --downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box as raw GPS <br>
194 * --downloadgps=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) as raw GPS */
195 DOWNLOADGPS(true),
196 /** --selection=&lt;searchstring&gt; Select with the given search */
197 SELECTION(true),
198 /** --offline=&lt;osm_api|josm_website|all&gt; Disable access to the given resource(s), delimited by comma */
199 OFFLINE(true),
200 /** --skip-plugins */
201 SKIP_PLUGINS(false),
202 ;
203
204 private String name;
205 private boolean requiresArgument;
206
207 private Option(boolean requiresArgument) {
208 this.name = name().toLowerCase().replace("_", "-");
209 this.requiresArgument = requiresArgument;
210 }
211
212 /**
213 * Replies the option name
214 * @return The option name, in lowercase
215 */
216 public String getName() {
217 return name;
218 }
219
220 /**
221 * Determines if this option requires an argument.
222 * @return {@code true} if this option requires an argument, {@code false} otherwise
223 */
224 public boolean requiresArgument() {
225 return requiresArgument;
226 }
227
228 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
229 Map<Option, Collection<String>> res = new HashMap<>();
230 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
231 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
232 if (o != null) {
233 res.put(o, e.getValue());
234 }
235 }
236 return res;
237 }
238 }
239
240 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
241
242 List<LongOpt> los = new ArrayList<>();
243 for (Option o : Option.values()) {
244 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
245 }
246
247 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[los.size()]));
248
249 Map<Option, Collection<String>> argMap = new HashMap<>();
250
251 int c;
252 while ((c = g.getopt()) != -1 ) {
253 Option opt = null;
254 switch (c) {
255 case 'h':
256 opt = Option.HELP;
257 break;
258 case 'v':
259 opt = Option.VERSION;
260 break;
261 case 0:
262 opt = Option.values()[g.getLongind()];
263 break;
264 }
265 if (opt != null) {
266 Collection<String> values = argMap.get(opt);
267 if (values == null) {
268 values = new ArrayList<>();
269 argMap.put(opt, values);
270 }
271 values.add(g.getOptarg());
272 } else
273 throw new IllegalArgumentException("Invalid option: "+c);
274 }
275 // positional arguments are a shortcut for the --download ... option
276 for (int i = g.getOptind(); i < args.length; ++i) {
277 Collection<String> values = argMap.get(Option.DOWNLOAD);
278 if (values == null) {
279 values = new ArrayList<>();
280 argMap.put(Option.DOWNLOAD, values);
281 }
282 values.add(args[i]);
283 }
284
285 return argMap;
286 }
287
288 /**
289 * Main application Startup
290 * @param argArray Command-line arguments
291 */
292 public static void main(final String[] argArray) {
293 I18n.init();
294 Main.checkJavaVersion();
295
296 // construct argument table
297 Map<Option, Collection<String>> args = null;
298 try {
299 args = buildCommandLineArgumentMap(argArray);
300 } catch (IllegalArgumentException e) {
301 System.exit(1);
302 return;
303 }
304
305 final boolean languageGiven = args.containsKey(Option.LANGUAGE);
306
307 if (languageGiven) {
308 I18n.set(args.get(Option.LANGUAGE).iterator().next());
309 }
310
311 initApplicationPreferences();
312
313 Policy.setPolicy(new Policy() {
314 // Permissions for plug-ins loaded when josm is started via webstart
315 private PermissionCollection pc;
316
317 {
318 pc = new Permissions();
319 pc.add(new AllPermission());
320 }
321
322 @Override
323 public void refresh() { }
324
325 @Override
326 public PermissionCollection getPermissions(CodeSource codesource) {
327 return pc;
328 }
329 });
330
331 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
332
333 // initialize the platform hook, and
334 Main.determinePlatformHook();
335 // call the really early hook before we do anything else
336 Main.platform.preStartupHook();
337
338 Main.commandLineArgs = Utils.copyArray(argArray);
339
340 if (args.containsKey(Option.VERSION)) {
341 System.out.println(Version.getInstance().getAgentString());
342 System.exit(0);
343 }
344
345 if (args.containsKey(Option.DEBUG) || args.containsKey(Option.TRACE)) {
346 // Enable JOSM debug level
347 logLevel = 4;
348 Main.info(tr("Printing debugging messages to console"));
349 }
350
351 Boolean skipLoadingPlugins = false;
352 if (args.containsKey(Option.SKIP_PLUGINS)) {
353 skipLoadingPlugins = true;
354 Main.info(tr("Plugin loading skipped"));
355 }
356
357 if (args.containsKey(Option.TRACE)) {
358 // Enable JOSM debug level
359 logLevel = 5;
360 // Enable debug in OAuth signpost via system preference, but only at trace level
361 Utils.updateSystemProperty("debug", "true");
362 Main.info(tr("Enabled detailed debug level (trace)"));
363 }
364
365 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
366
367 if (args.containsKey(Option.SET)) {
368 for (String i : args.get(Option.SET)) {
369 String[] kv = i.split("=", 2);
370 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
371 }
372 }
373
374 if (!languageGiven) {
375 I18n.set(Main.pref.get("language", null));
376 }
377 Main.pref.updateSystemProperties();
378
379 checkIPv6();
380
381 // asking for help? show help and exit
382 if (args.containsKey(Option.HELP)) {
383 showHelp();
384 System.exit(0);
385 }
386
387 processOffline(args);
388
389 Main.platform.afterPrefStartupHook();
390
391 FontsManager.initialize();
392
393 I18n.setupLanguageFonts();
394
395 final JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
396 Main.parent = mainFrame;
397
398 if (args.containsKey(Option.LOAD_PREFERENCES)) {
399 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
400 for (String i : args.get(Option.LOAD_PREFERENCES)) {
401 info("Reading preferences from " + i);
402 try (InputStream is = Utils.openURL(new URL(i))) {
403 config.openAndReadXML(is);
404 } catch (Exception ex) {
405 throw new RuntimeException(ex);
406 }
407 }
408 }
409
410 DefaultAuthenticator.createInstance();
411 Authenticator.setDefault(DefaultAuthenticator.getInstance());
412 DefaultProxySelector proxySelector = new DefaultProxySelector(ProxySelector.getDefault());
413 ProxySelector.setDefault(proxySelector);
414 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
415
416 final SplashScreen splash = new SplashScreen();
417 final ProgressMonitor monitor = splash.getProgressMonitor();
418 monitor.beginTask(tr("Initializing"));
419 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
420 Main.setInitStatusListener(new InitStatusListener() {
421
422 @Override
423 public void updateStatus(String event) {
424 monitor.indeterminateSubTask(event);
425 }
426 });
427
428 Collection<PluginInformation> pluginsToLoad = null;
429
430
431 if (!skipLoadingPlugins) {
432 pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash, monitor.createSubTaskMonitor(1, false));
433 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
434 monitor.subTask(tr("Updating plugins"));
435 pluginsToLoad = PluginHandler.updatePlugins(splash, null, monitor.createSubTaskMonitor(1, false), false);
436 }
437
438 monitor.indeterminateSubTask(tr("Installing updated plugins"));
439 PluginHandler.installDownloadedPlugins(true);
440
441 monitor.indeterminateSubTask(tr("Loading early plugins"));
442 PluginHandler.loadEarlyPlugins(splash, pluginsToLoad, monitor.createSubTaskMonitor(1, false));
443 }
444
445 monitor.indeterminateSubTask(tr("Setting defaults"));
446 preConstructorInit(args);
447
448 monitor.indeterminateSubTask(tr("Creating main GUI"));
449 final Main main = new MainApplication(mainFrame);
450
451 if (!skipLoadingPlugins) {
452 monitor.indeterminateSubTask(tr("Loading plugins"));
453 PluginHandler.loadLatePlugins(splash, pluginsToLoad, monitor.createSubTaskMonitor(1, false));
454 toolbar.refreshToolbarControl();
455 }
456
457 // Wait for splash disappearance (fix #9714)
458 GuiHelper.runInEDTAndWait(new Runnable() {
459 @Override
460 public void run() {
461 splash.setVisible(false);
462 splash.dispose();
463 mainFrame.setVisible(true);
464 main.gettingStarted.requestFocusInWindow();
465 }
466 });
467
468 Main.MasterWindowListener.setup();
469
470 boolean maximized = Main.pref.getBoolean("gui.maximized", false);
471 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
472 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
473 Main.windowState = JFrame.MAXIMIZED_BOTH;
474 mainFrame.setExtendedState(Main.windowState);
475 } else {
476 Main.debug("Main window: maximizing not supported");
477 }
478 }
479 if (main.menu.fullscreenToggleAction != null) {
480 main.menu.fullscreenToggleAction.initial();
481 }
482
483 SwingUtilities.invokeLater(new GuiFinalizationWorker(args, proxySelector));
484
485 if (Main.isPlatformWindows()) {
486 try {
487 // Check for insecure certificates to remove.
488 // This is Windows-dependant code but it can't go to preStartupHook (need i18n) neither startupHook (need to be called before remote control)
489 PlatformHookWindows.removeInsecureCertificates();
490 } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
491 error(e);
492 }
493 }
494
495 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
496 RemoteControl.start();
497 }
498
499 if (MessageNotifier.PROP_NOTIFIER_ENABLED.get()) {
500 MessageNotifier.start();
501 }
502
503 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
504 // 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
505 info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
506 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
507 }
508 }
509
510 private static void processOffline(Map<Option, Collection<String>> args) {
511 if (args.containsKey(Option.OFFLINE)) {
512 for (String s : args.get(Option.OFFLINE).iterator().next().split(",")) {
513 try {
514 Main.setOffline(OnlineResource.valueOf(s.toUpperCase()));
515 } catch (IllegalArgumentException e) {
516 Main.error(tr("''{0}'' is not a valid value for argument ''{1}''. Possible values are {2}, possibly delimited by commas.",
517 s.toUpperCase(), Option.OFFLINE.getName(), Arrays.toString(OnlineResource.values())));
518 System.exit(1);
519 return;
520 }
521 }
522 Set<OnlineResource> offline = Main.getOfflineResources();
523 if (!offline.isEmpty()) {
524 Main.warn(trn("JOSM is running in offline mode. This resource will not be available: {0}",
525 "JOSM is running in offline mode. These resources will not be available: {0}",
526 offline.size(), offline.size() == 1 ? offline.iterator().next() : Arrays.toString(offline.toArray())));
527 }
528 }
529 }
530
531 /**
532 * Check if IPv6 can be safely enabled and do so. Because this cannot be done after network activation,
533 * disabling or enabling IPV6 may only be done with next start.
534 */
535 private static void checkIPv6() {
536 if("auto".equals(Main.pref.get("prefer.ipv6", "auto"))) {
537 new Thread(new Runnable() { /* this may take some time (DNS, Connect) */
538 public void run() {
539 boolean hasv6 = false;
540 boolean wasv6 = Main.pref.getBoolean("validated.ipv6", false);
541 try {
542 /* Use the check result from last run of the software, as after the test, value
543 changes have no effect anymore */
544 if(wasv6) {
545 Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
546 }
547 for(InetAddress a : InetAddress.getAllByName("josm.openstreetmap.de")) {
548 if(a instanceof Inet6Address) {
549 if(a.isReachable(1000)) {
550 Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
551 if(!wasv6) {
552 Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
553 } else {
554 Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
555 }
556 hasv6 = true;
557 }
558 break; /* we're done */
559 }
560 }
561 } catch (Exception e) {
562 }
563 if(wasv6 && !hasv6) {
564 Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
565 }
566 Main.pref.put("validated.ipv6", hasv6);
567 }
568 }).start();
569 }
570 }
571
572 private static class GuiFinalizationWorker implements Runnable {
573
574 private final Map<Option, Collection<String>> args;
575 private final DefaultProxySelector proxySelector;
576
577 public GuiFinalizationWorker(Map<Option, Collection<String>> args, DefaultProxySelector proxySelector) {
578 this.args = args;
579 this.proxySelector = proxySelector;
580 }
581
582 @Override
583 public void run() {
584
585 // Handle proxy/network errors early to inform user he should change settings to be able to use JOSM correctly
586 if (!handleProxyErrors()) {
587 handleNetworkErrors();
588 }
589
590 // Restore autosave layers after crash and start autosave thread
591 handleAutosave();
592
593 // Handle command line instructions
594 postConstructorProcessCmdLine(args);
595
596 // Show download dialog if autostart is enabled
597 DownloadDialog.autostartIfNeeded();
598 }
599
600 private void handleAutosave() {
601 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
602 AutosaveTask autosaveTask = new AutosaveTask();
603 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
604 if (!unsavedLayerFiles.isEmpty()) {
605 ExtendedDialog dialog = new ExtendedDialog(
606 Main.parent,
607 tr("Unsaved osm data"),
608 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
609 );
610 dialog.setContent(
611 trn("JOSM found {0} unsaved osm data layer. ",
612 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
613 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
614 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
615 int selection = dialog.showDialog().getValue();
616 if (selection == 1) {
617 autosaveTask.recoverUnsavedLayers();
618 } else if (selection == 3) {
619 autosaveTask.discardUnsavedLayers();
620 }
621 }
622 autosaveTask.schedule();
623 }
624 }
625
626 private boolean handleNetworkOrProxyErrors(boolean hasErrors, String title, String message) {
627 if (hasErrors) {
628 ExtendedDialog ed = new ExtendedDialog(
629 Main.parent, title,
630 new String[]{tr("Change proxy settings"), tr("Cancel")});
631 ed.setButtonIcons(new String[]{"dialogs/settings", "cancel"}).setCancelButton(2);
632 ed.setMinimumSize(new Dimension(460, 260));
633 ed.setIcon(JOptionPane.WARNING_MESSAGE);
634 ed.setContent(message);
635
636 if (ed.showDialog().getValue() == 1) {
637 PreferencesAction.forPreferenceSubTab(null, null, ProxyPreference.class).run();
638 }
639 }
640 return hasErrors;
641 }
642
643 private boolean handleProxyErrors() {
644 return handleNetworkOrProxyErrors(proxySelector.hasErrors(), tr("Proxy errors occurred"),
645 tr("JOSM tried to access the following resources:<br>" +
646 "{0}" +
647 "but <b>failed</b> to do so, because of the following proxy errors:<br>" +
648 "{1}" +
649 "Would you like to change your proxy settings now?",
650 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorResources()),
651 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorMessages())
652 ));
653 }
654
655 private boolean handleNetworkErrors() {
656 boolean condition = !NETWORK_ERRORS.isEmpty();
657 if (condition) {
658 Set<String> errors = new TreeSet<>();
659 for (Throwable t : NETWORK_ERRORS.values()) {
660 errors.add(t.toString());
661 }
662 return handleNetworkOrProxyErrors(condition, tr("Network errors occurred"),
663 tr("JOSM tried to access the following resources:<br>" +
664 "{0}" +
665 "but <b>failed</b> to do so, because of the following network errors:<br>" +
666 "{1}" +
667 "It may be due to a missing proxy configuration.<br>" +
668 "Would you like to change your proxy settings now?",
669 Utils.joinAsHtmlUnorderedList(NETWORK_ERRORS.keySet()),
670 Utils.joinAsHtmlUnorderedList(errors)
671 ));
672 }
673 return false;
674 }
675 }
676}
Note: See TracBrowser for help on using the repository browser.