source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java@ 6104

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

see #8902 - Small performance enhancements / coding style (patch by shinigami):

  • while -> foreach
  • for -> for each

plus:

  • cleanup of FileDrop class to make it more integrated into JOSM core + remove warnings
  • Property svn:eol-style set to native
File size: 33.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.imagery;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Color;
8import java.awt.Component;
9import java.awt.Dimension;
10import java.awt.FlowLayout;
11import java.awt.Font;
12import java.awt.GridBagConstraints;
13import java.awt.GridBagLayout;
14import java.awt.event.ActionEvent;
15import java.awt.event.ActionListener;
16import java.awt.event.MouseEvent;
17import java.io.IOException;
18import java.net.MalformedURLException;
19import java.net.URL;
20import java.util.ArrayList;
21import java.util.HashMap;
22import java.util.HashSet;
23import java.util.List;
24import java.util.Map;
25import java.util.Set;
26
27import javax.swing.AbstractAction;
28import javax.swing.BorderFactory;
29import javax.swing.Box;
30import javax.swing.JButton;
31import javax.swing.JLabel;
32import javax.swing.JOptionPane;
33import javax.swing.JPanel;
34import javax.swing.JScrollPane;
35import javax.swing.JSeparator;
36import javax.swing.JTabbedPane;
37import javax.swing.JTable;
38import javax.swing.JToolBar;
39import javax.swing.event.ListSelectionEvent;
40import javax.swing.event.ListSelectionListener;
41import javax.swing.event.TableModelEvent;
42import javax.swing.event.TableModelListener;
43import javax.swing.table.DefaultTableCellRenderer;
44import javax.swing.table.DefaultTableModel;
45import javax.swing.table.TableColumnModel;
46
47import org.openstreetmap.gui.jmapviewer.Coordinate;
48import org.openstreetmap.gui.jmapviewer.JMapViewer;
49import org.openstreetmap.gui.jmapviewer.MapPolygonImpl;
50import org.openstreetmap.gui.jmapviewer.MapRectangleImpl;
51import org.openstreetmap.gui.jmapviewer.interfaces.MapPolygon;
52import org.openstreetmap.gui.jmapviewer.interfaces.MapRectangle;
53import org.openstreetmap.josm.Main;
54import org.openstreetmap.josm.data.imagery.ImageryInfo;
55import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
56import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
57import org.openstreetmap.josm.data.imagery.OffsetBookmark;
58import org.openstreetmap.josm.data.imagery.Shape;
59import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
60import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
61import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
62import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
63import org.openstreetmap.josm.gui.widgets.JosmEditorPane;
64import org.openstreetmap.josm.tools.GBC;
65import org.openstreetmap.josm.tools.ImageProvider;
66import org.openstreetmap.josm.tools.LanguageInfo;
67
68public class ImageryPreference extends DefaultTabPreferenceSetting {
69 public static class Factory implements PreferenceSettingFactory {
70 @Override
71 public PreferenceSetting createPreferenceSetting() {
72 return new ImageryPreference();
73 }
74 }
75
76 private ImageryPreference() {
77 super("imagery", tr("Imagery Preferences"), tr("Modify list of imagery layers displayed in the Imagery menu"), false, new JTabbedPane());
78 }
79
80 private ImageryProvidersPanel imageryProviders;
81 private ImageryLayerInfo layerInfo;
82
83 private CommonSettingsPanel commonSettings;
84 private WMSSettingsPanel wmsSettings;
85 private TMSSettingsPanel tmsSettings;
86
87 private void addSettingsSection(final JPanel p, String name, JPanel section) {
88 addSettingsSection(p, name, section, GBC.eol());
89 }
90
91 private void addSettingsSection(final JPanel p, String name, JPanel section, GBC gbc) {
92 final JLabel lbl = new JLabel(name);
93 lbl.setFont(lbl.getFont().deriveFont(Font.BOLD));
94 p.add(lbl,GBC.std());
95 p.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0));
96 p.add(section, gbc.insets(20,5,0,10));
97 }
98
99 private Component buildSettingsPanel(final PreferenceTabbedPane gui) {
100 final JPanel p = new JPanel(new GridBagLayout());
101 p.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
102
103 addSettingsSection(p, tr("Common Settings"), commonSettings = new CommonSettingsPanel());
104 addSettingsSection(p, tr("WMS Settings"), wmsSettings = new WMSSettingsPanel(),
105 GBC.eol().fill(GBC.HORIZONTAL));
106 addSettingsSection(p, tr("TMS Settings"), tmsSettings = new TMSSettingsPanel(),
107 GBC.eol().fill(GBC.HORIZONTAL));
108
109 p.add(new JPanel(),GBC.eol().fill(GBC.BOTH));
110 return new JScrollPane(p);
111 }
112
113 @Override
114 public void addGui(final PreferenceTabbedPane gui) {
115 JPanel p = gui.createPreferenceTab(this);
116 JTabbedPane pane = getTabPane();
117 layerInfo = new ImageryLayerInfo(ImageryLayerInfo.instance);
118 imageryProviders = new ImageryProvidersPanel(gui, layerInfo);
119 pane.addTab(tr("Imagery providers"), imageryProviders);
120 pane.addTab(tr("Settings"), buildSettingsPanel(gui));
121 pane.addTab(tr("Offset bookmarks"), new OffsetBookmarksPanel(gui));
122 loadSettings();
123 p.add(pane,GBC.std().fill(GBC.BOTH));
124 }
125
126 public ImageryProvidersPanel getProvidersPanel() {
127 return imageryProviders;
128 }
129
130 private void loadSettings() {
131 commonSettings.loadSettings();
132 wmsSettings.loadSettings();
133 tmsSettings.loadSettings();
134 }
135
136 @Override
137 public boolean ok() {
138 layerInfo.save();
139 ImageryLayerInfo.instance.clear();
140 ImageryLayerInfo.instance.load();
141 Main.main.menu.imageryMenu.refreshOffsetMenu();
142 OffsetBookmark.saveBookmarks();
143
144 boolean commonRestartRequired = commonSettings.saveSettings();
145 boolean wmsRestartRequired = wmsSettings.saveSettings();
146 boolean tmsRestartRequired = tmsSettings.saveSettings();
147
148 return commonRestartRequired || wmsRestartRequired || tmsRestartRequired;
149 }
150
151 /**
152 * Updates a server URL in the preferences dialog. Used by plugins.
153 *
154 * @param server
155 * The server name
156 * @param url
157 * The server URL
158 */
159 public void setServerUrl(String server, String url) {
160 for (int i = 0; i < imageryProviders.activeModel.getRowCount(); i++) {
161 if (server.equals(imageryProviders.activeModel.getValueAt(i, 0).toString())) {
162 imageryProviders.activeModel.setValueAt(url, i, 1);
163 return;
164 }
165 }
166 imageryProviders.activeModel.addRow(new String[] { server, url });
167 }
168
169 /**
170 * Gets a server URL in the preferences dialog. Used by plugins.
171 *
172 * @param server
173 * The server name
174 * @return The server URL
175 */
176 public String getServerUrl(String server) {
177 for (int i = 0; i < imageryProviders.activeModel.getRowCount(); i++) {
178 if (server.equals(imageryProviders.activeModel.getValueAt(i, 0).toString()))
179 return imageryProviders.activeModel.getValueAt(i, 1).toString();
180 }
181 return null;
182 }
183
184 public static class ImageryProvidersPanel extends JPanel {
185 // Public JTables and JMapViewer
186 public final JTable activeTable;
187 public final JTable defaultTable;
188 public final JMapViewer defaultMap;
189
190 // Public models
191 public final ImageryLayerTableModel activeModel;
192 public final ImageryDefaultLayerTableModel defaultModel;
193
194 // Public JToolbars
195 public final JToolBar activeToolbar;
196 public final JToolBar middleToolbar;
197 public final JToolBar defaultToolbar;
198
199 // Private members
200 private final PreferenceTabbedPane gui;
201 private final ImageryLayerInfo layerInfo;
202
203 private static class ImageryTableCellRenderer extends DefaultTableCellRenderer {
204
205 private List<ImageryInfo> layers;
206
207 public ImageryTableCellRenderer(List<ImageryInfo> layers) {
208 this.layers = layers;
209 }
210
211 @Override
212 public Component getTableCellRendererComponent(JTable table, Object value, boolean
213 isSelected, boolean hasFocus, int row, int column) {
214 JLabel label = (JLabel) super.getTableCellRendererComponent(
215 table, value, isSelected, hasFocus, row, column);
216 label.setBackground(Main.pref.getUIColor("Table.background"));
217 if (isSelected) {
218 label.setForeground(Main.pref.getUIColor("Table.foreground"));
219 }
220 if (value != null) { // Fix #8159
221 String t = value.toString();
222 for (ImageryInfo l : layers) {
223 if (l.getExtendedUrl().equals(t)) {
224 label.setBackground(Main.pref.getColor(
225 marktr("Imagery Background: Default"),
226 new Color(200,255,200)));
227 break;
228 }
229 }
230 }
231 return label;
232 }
233 }
234
235 public ImageryProvidersPanel(final PreferenceTabbedPane gui, ImageryLayerInfo layerInfoArg) {
236 super(new GridBagLayout());
237 this.gui = gui;
238 this.layerInfo = layerInfoArg;
239 this.activeModel = new ImageryLayerTableModel();
240
241 activeTable = new JTable(activeModel) {
242 @Override
243 public String getToolTipText(MouseEvent e) {
244 java.awt.Point p = e.getPoint();
245 return activeModel.getValueAt(rowAtPoint(p), columnAtPoint(p)).toString();
246 }
247 };
248
249 defaultModel = new ImageryDefaultLayerTableModel();
250 defaultTable = new JTable(defaultModel) {
251 @Override
252 public String getToolTipText(MouseEvent e) {
253 java.awt.Point p = e.getPoint();
254 return (String) defaultModel.getValueAt(rowAtPoint(p), columnAtPoint(p));
255 }
256 };
257
258 defaultModel.addTableModelListener(
259 new TableModelListener() {
260 @Override
261 public void tableChanged(TableModelEvent e) {
262 activeTable.repaint();
263 }
264 }
265 );
266
267 activeModel.addTableModelListener(
268 new TableModelListener() {
269 @Override
270 public void tableChanged(TableModelEvent e) {
271 defaultTable.repaint();
272 }
273 }
274 );
275
276 TableColumnModel mod = defaultTable.getColumnModel();
277 mod.getColumn(2).setPreferredWidth(800);
278 mod.getColumn(2).setCellRenderer(new ImageryTableCellRenderer(layerInfo.getLayers()));
279 mod.getColumn(1).setPreferredWidth(400);
280 mod.getColumn(0).setPreferredWidth(50);
281
282 mod = activeTable.getColumnModel();
283 mod.getColumn(1).setPreferredWidth(800);
284 mod.getColumn(1).setCellRenderer(new ImageryTableCellRenderer(layerInfo.getDefaultLayers()));
285 mod.getColumn(0).setPreferredWidth(200);
286
287 RemoveEntryAction remove = new RemoveEntryAction();
288 activeTable.getSelectionModel().addListSelectionListener(remove);
289
290 add(new JLabel(tr("Available default entries:")), GBC.eol().insets(5, 5, 0, 0));
291 // Add default item list
292 JScrollPane scrolldef = new JScrollPane(defaultTable);
293 scrolldef.setPreferredSize(new Dimension(200, 200));
294 add(scrolldef, GBC.std().insets(0, 5, 0, 0).fill(GridBagConstraints.BOTH).weight(1.0, 0.6).insets(5, 0, 0, 0));
295
296 // Add default item map
297 defaultMap = new JMapViewer();
298 defaultMap.setZoomContolsVisible(false);
299 defaultMap.setMinimumSize(new Dimension(100, 200));
300 add(defaultMap, GBC.std().insets(5, 5, 0, 0).fill(GridBagConstraints.BOTH).weight(0.33, 0.6).insets(5, 0, 0, 0));
301
302 defaultTable.getSelectionModel().addListSelectionListener(new DefListSelectionListener());
303
304 defaultToolbar = new JToolBar(JToolBar.VERTICAL);
305 defaultToolbar.setFloatable(false);
306 defaultToolbar.setBorderPainted(false);
307 defaultToolbar.setOpaque(false);
308 defaultToolbar.add(new ReloadAction());
309 add(defaultToolbar, GBC.eol().anchor(GBC.SOUTH).insets(0, 0, 5, 0));
310
311 ActivateAction activate = new ActivateAction();
312 defaultTable.getSelectionModel().addListSelectionListener(activate);
313 JButton btnActivate = new JButton(activate);
314
315 middleToolbar = new JToolBar(JToolBar.HORIZONTAL);
316 middleToolbar.setFloatable(false);
317 middleToolbar.setBorderPainted(false);
318 middleToolbar.setOpaque(false);
319 middleToolbar.add(btnActivate);
320 add(middleToolbar, GBC.eol().anchor(GBC.CENTER).insets(5, 15, 5, 0));
321
322 add(Box.createHorizontalGlue(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
323
324 add(new JLabel(tr("Selected entries:")), GBC.eol().insets(5, 0, 0, 0));
325 JScrollPane scroll = new JScrollPane(activeTable);
326 add(scroll, GBC.std().fill(GridBagConstraints.BOTH).span(GridBagConstraints.RELATIVE).weight(1.0, 0.4).insets(5, 0, 0, 5));
327 scroll.setPreferredSize(new Dimension(200, 200));
328
329 activeToolbar = new JToolBar(JToolBar.VERTICAL);
330 activeToolbar.setFloatable(false);
331 activeToolbar.setBorderPainted(false);
332 activeToolbar.setOpaque(false);
333 activeToolbar.add(new NewEntryAction(ImageryInfo.ImageryType.WMS));
334 activeToolbar.add(new NewEntryAction(ImageryInfo.ImageryType.TMS));
335 //activeToolbar.add(edit); TODO
336 activeToolbar.add(remove);
337 add(activeToolbar, GBC.eol().anchor(GBC.NORTH).insets(0, 0, 5, 5));
338
339 }
340
341 // Listener of default providers list selection
342 private final class DefListSelectionListener implements ListSelectionListener {
343 // The current drawn rectangles and polygons
344 private final Map<Integer, MapRectangle> mapRectangles;
345 private final Map<Integer, List<MapPolygon>> mapPolygons;
346
347 private DefListSelectionListener() {
348 this.mapRectangles = new HashMap<Integer, MapRectangle>();
349 this.mapPolygons = new HashMap<Integer, List<MapPolygon>>();
350 }
351
352 @Override
353 public void valueChanged(ListSelectionEvent e) {
354 // First index is set to -1 when the list is refreshed, so discard all map rectangles and polygons
355 if (e.getFirstIndex() == -1) {
356 defaultMap.removeAllMapRectangles();
357 defaultMap.removeAllMapPolygons();
358 mapRectangles.clear();
359 mapPolygons.clear();
360 // Only process complete (final) selection events
361 } else if (!e.getValueIsAdjusting()) {
362 for (int i = e.getFirstIndex(); i<=e.getLastIndex(); i++) {
363 updateBoundsAndShapes(i);
364 }
365 // If needed, adjust map to show all map rectangles and polygons
366 if (!mapRectangles.isEmpty() || !mapPolygons.isEmpty()) {
367 defaultMap.setDisplayToFitMapElements(false, true, true);
368 defaultMap.zoomOut();
369 }
370 }
371 }
372
373 private void updateBoundsAndShapes(int i) {
374 ImageryBounds bounds = defaultModel.getRow(i).getBounds();
375 if (bounds != null) {
376 List<Shape> shapes = bounds.getShapes();
377 if (shapes != null && !shapes.isEmpty()) {
378 if (defaultTable.getSelectionModel().isSelectedIndex(i)) {
379 if (!mapPolygons.containsKey(i)) {
380 List<MapPolygon> list = new ArrayList<MapPolygon>();
381 mapPolygons.put(i, list);
382 // Add new map polygons
383 for (Shape shape : shapes) {
384 MapPolygon polygon = new MapPolygonImpl(shape.getPoints());
385 list.add(polygon);
386 defaultMap.addMapPolygon(polygon);
387 }
388 }
389 } else if (mapPolygons.containsKey(i)) {
390 // Remove previously drawn map polygons
391 for (MapPolygon polygon : mapPolygons.get(i)) {
392 defaultMap.removeMapPolygon(polygon);
393 }
394 mapPolygons.remove(i);
395 }
396 // Only display bounds when no polygons (shapes) are defined for this provider
397 } else {
398 if (defaultTable.getSelectionModel().isSelectedIndex(i)) {
399 if (!mapRectangles.containsKey(i)) {
400 // Add new map rectangle
401 Coordinate topLeft = new Coordinate(bounds.getMax().lat(), bounds.getMin().lon());
402 Coordinate bottomRight = new Coordinate(bounds.getMin().lat(), bounds.getMax().lon());
403 MapRectangle rectangle = new MapRectangleImpl(topLeft, bottomRight);
404 mapRectangles.put(i, rectangle);
405 defaultMap.addMapRectangle(rectangle);
406 }
407 } else if (mapRectangles.containsKey(i)) {
408 // Remove previously drawn map rectangle
409 defaultMap.removeMapRectangle(mapRectangles.get(i));
410 mapRectangles.remove(i);
411 }
412 }
413 }
414 }
415 }
416
417 private class NewEntryAction extends AbstractAction {
418
419 private final ImageryInfo.ImageryType type;
420
421 public NewEntryAction(ImageryInfo.ImageryType type) {
422 putValue(NAME, type.toString());
423 putValue(SHORT_DESCRIPTION, tr("Add a new {0} entry by entering the URL", type.toString()));
424 putValue(SMALL_ICON, ImageProvider.get("dialogs",
425 "add" + (ImageryInfo.ImageryType.WMS.equals(type) ? "_wms" : ImageryInfo.ImageryType.TMS.equals(type) ? "_tms" : "")));
426 this.type = type;
427 }
428
429 @Override
430 public void actionPerformed(ActionEvent evt) {
431 final AddImageryPanel p;
432 if (ImageryInfo.ImageryType.WMS.equals(type)) {
433 p = new AddWMSLayerPanel();
434 } else if (ImageryInfo.ImageryType.TMS.equals(type)) {
435 p = new AddTMSLayerPanel();
436 } else {
437 throw new IllegalStateException("Type " + type + " not supported");
438 }
439
440 final AddImageryDialog addDialog = new AddImageryDialog(gui, p);
441 addDialog.showDialog();
442
443 if (addDialog.getValue() == 1) {
444 try {
445 activeModel.addRow(p.getImageryInfo());
446 } catch (IllegalArgumentException ex) {
447 if (ex.getMessage() == null || ex.getMessage().isEmpty())
448 throw ex;
449 else {
450 JOptionPane.showMessageDialog(Main.parent,
451 ex.getMessage(), tr("Error"),
452 JOptionPane.ERROR_MESSAGE);
453 }
454 }
455 }
456 }
457 }
458
459 private class RemoveEntryAction extends AbstractAction implements ListSelectionListener {
460
461 public RemoveEntryAction() {
462 putValue(NAME, tr("Remove"));
463 putValue(SHORT_DESCRIPTION, tr("Remove entry"));
464 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
465 updateEnabledState();
466 }
467
468 protected void updateEnabledState() {
469 setEnabled(activeTable.getSelectedRowCount() > 0);
470 }
471
472 @Override
473 public void valueChanged(ListSelectionEvent e) {
474 updateEnabledState();
475 }
476
477 @Override
478 public void actionPerformed(ActionEvent e) {
479 Integer i;
480 while ((i = activeTable.getSelectedRow()) != -1) {
481 activeModel.removeRow(i);
482 }
483 }
484 }
485
486 private class ActivateAction extends AbstractAction implements ListSelectionListener {
487 public ActivateAction() {
488 putValue(NAME, tr("Activate"));
489 putValue(SHORT_DESCRIPTION, tr("copy selected defaults"));
490 putValue(SMALL_ICON, ImageProvider.get("preferences", "activate-down"));
491 }
492
493 protected void updateEnabledState() {
494 setEnabled(defaultTable.getSelectedRowCount() > 0);
495 }
496
497 @Override
498 public void valueChanged(ListSelectionEvent e) {
499 updateEnabledState();
500 }
501
502 @Override
503 public void actionPerformed(ActionEvent e) {
504 int[] lines = defaultTable.getSelectedRows();
505 if (lines.length == 0) {
506 JOptionPane.showMessageDialog(
507 gui,
508 tr("Please select at least one row to copy."),
509 tr("Information"),
510 JOptionPane.INFORMATION_MESSAGE);
511 return;
512 }
513
514 Set<String> acceptedEulas = new HashSet<String>();
515
516 outer:
517 for (int line : lines) {
518 ImageryInfo info = defaultModel.getRow(line);
519
520 // Check if an entry with exactly the same values already
521 // exists
522 for (int j = 0; j < activeModel.getRowCount(); j++) {
523 if (info.equalsBaseValues(activeModel.getRow(j))) {
524 // Select the already existing row so the user has
525 // some feedback in case an entry exists
526 activeTable.getSelectionModel().setSelectionInterval(j, j);
527 activeTable.scrollRectToVisible(activeTable.getCellRect(j, 0, true));
528 continue outer;
529 }
530 }
531
532 String eulaURL = info.getEulaAcceptanceRequired();
533 // If set and not already accepted, ask for EULA acceptance
534 if (eulaURL != null && !acceptedEulas.contains(eulaURL)) {
535 if (confirmEulaAcceptance(gui, eulaURL)) {
536 acceptedEulas.add(eulaURL);
537 } else {
538 continue outer;
539 }
540 }
541
542 activeModel.addRow(new ImageryInfo(info));
543 int lastLine = activeModel.getRowCount() - 1;
544 activeTable.getSelectionModel().setSelectionInterval(lastLine, lastLine);
545 activeTable.scrollRectToVisible(activeTable.getCellRect(lastLine, 0, true));
546 }
547 }
548 }
549
550 private class ReloadAction extends AbstractAction {
551 public ReloadAction() {
552 putValue(SHORT_DESCRIPTION, tr("reload defaults"));
553 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
554 }
555
556 @Override
557 public void actionPerformed(ActionEvent evt) {
558 layerInfo.loadDefaults(true);
559 defaultModel.fireTableDataChanged();
560 }
561 }
562
563 /**
564 * The table model for imagery layer list
565 */
566 public class ImageryLayerTableModel extends DefaultTableModel {
567 public ImageryLayerTableModel() {
568 setColumnIdentifiers(new String[] { tr("Menu Name"), tr("Imagery URL")});
569 }
570
571 public ImageryInfo getRow(int row) {
572 return layerInfo.getLayers().get(row);
573 }
574
575 public void addRow(ImageryInfo i) {
576 layerInfo.add(i);
577 int p = getRowCount() - 1;
578 fireTableRowsInserted(p, p);
579 }
580
581 @Override
582 public void removeRow(int i) {
583 layerInfo.remove(getRow(i));
584 fireTableRowsDeleted(i, i);
585 }
586
587 @Override
588 public int getRowCount() {
589 return layerInfo.getLayers().size();
590 }
591
592 @Override
593 public Object getValueAt(int row, int column) {
594 ImageryInfo info = layerInfo.getLayers().get(row);
595 switch (column) {
596 case 0:
597 return info.getName();
598 case 1:
599 return info.getExtendedUrl();
600 default:
601 throw new ArrayIndexOutOfBoundsException();
602 }
603 }
604
605 @Override
606 public void setValueAt(Object o, int row, int column) {
607 if (layerInfo.getLayers().size() <= row) return;
608 ImageryInfo info = layerInfo.getLayers().get(row);
609 switch (column) {
610 case 0:
611 info.setName((String) o);
612 break;
613 case 1:
614 info.setExtendedUrl((String)o);
615 break;
616 default:
617 throw new ArrayIndexOutOfBoundsException();
618 }
619 }
620
621 @Override
622 public boolean isCellEditable(int row, int column) {
623 return true;
624 }
625 }
626
627 /**
628 * The table model for the default imagery layer list
629 */
630 public class ImageryDefaultLayerTableModel extends DefaultTableModel {
631 public ImageryDefaultLayerTableModel() {
632 setColumnIdentifiers(new String[]{"", tr("Menu Name (Default)"), tr("Imagery URL (Default)")});
633 }
634
635 public ImageryInfo getRow(int row) {
636 return layerInfo.getDefaultLayers().get(row);
637 }
638
639 @Override
640 public int getRowCount() {
641 return layerInfo.getDefaultLayers().size();
642 }
643
644 @Override
645 public Object getValueAt(int row, int column) {
646 ImageryInfo info = layerInfo.getDefaultLayers().get(row);
647 switch (column) {
648 case 0:
649 return info.getCountryCode();
650 case 1:
651 return info.getName();
652 case 2:
653 return info.getExtendedUrl();
654 }
655 return null;
656 }
657
658 @Override
659 public boolean isCellEditable(int row, int column) {
660 return false;
661 }
662 }
663
664 private boolean confirmEulaAcceptance(PreferenceTabbedPane gui, String eulaUrl) {
665 URL url = null;
666 try {
667 url = new URL(eulaUrl.replaceAll("\\{lang\\}", LanguageInfo.getWikiLanguagePrefix()));
668 JosmEditorPane htmlPane = null;
669 try {
670 htmlPane = new JosmEditorPane(url);
671 } catch (IOException e1) {
672 // give a second chance with a default Locale 'en'
673 try {
674 url = new URL(eulaUrl.replaceAll("\\{lang\\}", ""));
675 htmlPane = new JosmEditorPane(url);
676 } catch (IOException e2) {
677 JOptionPane.showMessageDialog(gui ,tr("EULA license URL not available: {0}", eulaUrl));
678 return false;
679 }
680 }
681 Box box = Box.createVerticalBox();
682 htmlPane.setEditable(false);
683 JScrollPane scrollPane = new JScrollPane(htmlPane);
684 scrollPane.setPreferredSize(new Dimension(400, 400));
685 box.add(scrollPane);
686 int option = JOptionPane.showConfirmDialog(Main.parent, box, tr("Please abort if you are not sure"), JOptionPane.YES_NO_OPTION,
687 JOptionPane.WARNING_MESSAGE);
688 if (option == JOptionPane.YES_OPTION)
689 return true;
690 } catch (MalformedURLException e2) {
691 JOptionPane.showMessageDialog(gui ,tr("Malformed URL for the EULA licence: {0}", eulaUrl));
692 }
693 return false;
694 }
695 }
696
697 static class OffsetBookmarksPanel extends JPanel {
698 List<OffsetBookmark> bookmarks = OffsetBookmark.allBookmarks;
699 OffsetsBookmarksModel model = new OffsetsBookmarksModel();
700
701 public OffsetBookmarksPanel(final PreferenceTabbedPane gui) {
702 super(new GridBagLayout());
703 final JTable list = new JTable(model) {
704 @Override
705 public String getToolTipText(MouseEvent e) {
706 java.awt.Point p = e.getPoint();
707 return model.getValueAt(rowAtPoint(p), columnAtPoint(p)).toString();
708 }
709 };
710 JScrollPane scroll = new JScrollPane(list);
711 add(scroll, GBC.eol().fill(GridBagConstraints.BOTH));
712 scroll.setPreferredSize(new Dimension(200, 200));
713
714 TableColumnModel mod = list.getColumnModel();
715 mod.getColumn(0).setPreferredWidth(150);
716 mod.getColumn(1).setPreferredWidth(200);
717 mod.getColumn(2).setPreferredWidth(300);
718 mod.getColumn(3).setPreferredWidth(150);
719 mod.getColumn(4).setPreferredWidth(150);
720
721 JPanel buttonPanel = new JPanel(new FlowLayout());
722
723 JButton add = new JButton(tr("Add"));
724 buttonPanel.add(add, GBC.std().insets(0, 5, 0, 0));
725 add.addActionListener(new ActionListener() {
726 @Override
727 public void actionPerformed(ActionEvent e) {
728 OffsetBookmark b = new OffsetBookmark(Main.getProjection().toCode(),"","",0,0);
729 model.addRow(b);
730 }
731 });
732
733 JButton delete = new JButton(tr("Delete"));
734 buttonPanel.add(delete, GBC.std().insets(0, 5, 0, 0));
735 delete.addActionListener(new ActionListener() {
736 @Override
737 public void actionPerformed(ActionEvent e) {
738 if (list.getSelectedRow() == -1) {
739 JOptionPane.showMessageDialog(gui, tr("Please select the row to delete."));
740 } else {
741 Integer i;
742 while ((i = list.getSelectedRow()) != -1) {
743 model.removeRow(i);
744 }
745 }
746 }
747 });
748
749 add(buttonPanel,GBC.eol());
750 }
751
752 /**
753 * The table model for imagery offsets list
754 */
755 class OffsetsBookmarksModel extends DefaultTableModel {
756 public OffsetsBookmarksModel() {
757 setColumnIdentifiers(new String[] { tr("Projection"), tr("Layer"), tr("Name"), tr("Easting"), tr("Northing"),});
758 }
759
760 public OffsetBookmark getRow(int row) {
761 return bookmarks.get(row);
762 }
763
764 public void addRow(OffsetBookmark i) {
765 bookmarks.add(i);
766 int p = getRowCount() - 1;
767 fireTableRowsInserted(p, p);
768 }
769
770 @Override
771 public void removeRow(int i) {
772 bookmarks.remove(getRow(i));
773 fireTableRowsDeleted(i, i);
774 }
775
776 @Override
777 public int getRowCount() {
778 return bookmarks.size();
779 }
780
781 @Override
782 public Object getValueAt(int row, int column) {
783 OffsetBookmark info = bookmarks.get(row);
784 switch (column) {
785 case 0:
786 if (info.projectionCode == null) return "";
787 return info.projectionCode.toString();
788 case 1:
789 return info.layerName;
790 case 2:
791 return info.name;
792 case 3:
793 return info.dx;
794 case 4:
795 return info.dy;
796 default:
797 throw new ArrayIndexOutOfBoundsException();
798 }
799 }
800
801 @Override
802 public void setValueAt(Object o, int row, int column) {
803 OffsetBookmark info = bookmarks.get(row);
804 switch (column) {
805 case 1:
806 info.layerName = o.toString();
807 break;
808 case 2:
809 info.name = o.toString();
810 break;
811 case 3:
812 info.dx = Double.parseDouble((String) o);
813 break;
814 case 4:
815 info.dy = Double.parseDouble((String) o);
816 break;
817 default:
818 throw new ArrayIndexOutOfBoundsException();
819 }
820 }
821
822 @Override
823 public boolean isCellEditable(int row, int column) {
824 return column >= 1;
825 }
826 }
827 }
828
829 public static void initialize() {
830 ImageryLayerInfo.instance.clear();
831 ImageryLayerInfo.instance.loadDefaults(false);
832 ImageryLayerInfo.instance.load();
833 OffsetBookmark.loadBookmarks();
834 Main.main.menu.imageryMenu.refreshImageryMenu();
835 Main.main.menu.imageryMenu.refreshOffsetMenu();
836 }
837}
Note: See TracBrowser for help on using the repository browser.