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

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

cleanup icons, mark undetected icons, set proper mimetype, delete unused icons, update geticons script

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