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

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

Refactor Imagery preferences settings panels to allow future reuse

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