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

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

fix #11271 - allow to skip plugin loading - patch by Bryce Nesbitt

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