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

Last change on this file since 3826 was 3826, checked in by framm, 13 years ago

Add a "blacklisted" property to imagery layers; set this property from a
compiled-in list of regular expressions; disable blacklisted entries in
the Imagery menu.

  • Property svn:eol-style set to native
File size: 33.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trc;
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.List;
21import java.util.Locale;
22
23import javax.swing.AbstractAction;
24import javax.swing.BorderFactory;
25import javax.swing.Box;
26import javax.swing.JButton;
27import javax.swing.JCheckBox;
28import javax.swing.JColorChooser;
29import javax.swing.JComboBox;
30import javax.swing.JEditorPane;
31import javax.swing.JLabel;
32import javax.swing.JOptionPane;
33import javax.swing.JPanel;
34import javax.swing.JScrollPane;
35import javax.swing.JSeparator;
36import javax.swing.JSlider;
37import javax.swing.JSpinner;
38import javax.swing.JTabbedPane;
39import javax.swing.JTable;
40import javax.swing.JTextField;
41import javax.swing.JToolBar;
42import javax.swing.SpinnerNumberModel;
43import javax.swing.event.ListSelectionEvent;
44import javax.swing.event.ListSelectionListener;
45import javax.swing.table.DefaultTableModel;
46import javax.swing.table.TableColumnModel;
47
48import org.openstreetmap.josm.Main;
49import org.openstreetmap.josm.data.imagery.ImageryInfo;
50import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
51import org.openstreetmap.josm.data.imagery.OffsetBookmark;
52import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
53import org.openstreetmap.josm.gui.layer.ImageryLayer;
54import org.openstreetmap.josm.gui.layer.TMSLayer;
55import org.openstreetmap.josm.gui.layer.WMSLayer;
56import org.openstreetmap.josm.io.imagery.HTMLGrabber;
57import org.openstreetmap.josm.tools.ColorHelper;
58import org.openstreetmap.josm.tools.GBC;
59import org.openstreetmap.josm.tools.ImageProvider;
60
61public class ImageryPreference implements PreferenceSetting {
62 public static class Factory implements PreferenceSettingFactory {
63 @Override
64 public PreferenceSetting createPreferenceSetting() {
65 return new ImageryPreference();
66 }
67 }
68 ImageryProvidersPanel imageryProviders;
69
70 static ImagerySettingsMigration settingsMigration;
71
72 // Common settings
73 private Color colFadeColor;
74 private JButton btnFadeColor;
75 private JSlider fadeAmount = new JSlider(0, 100);
76 private JComboBox sharpen;
77
78 // WMS Settings
79 private JComboBox browser;
80 JCheckBox overlapCheckBox;
81 JSpinner spinEast;
82 JSpinner spinNorth;
83 JSpinner spinSimConn;
84
85 //TMS settings controls
86 private JCheckBox autozoomActive = new JCheckBox();
87 private JCheckBox autoloadTiles = new JCheckBox();
88 private JSpinner minZoomLvl;
89 private JSpinner maxZoomLvl;
90 private JCheckBox addToSlippyMapChosser = new JCheckBox();
91 private JTextField tilecacheDir = new JTextField();
92
93 private JPanel buildCommonSettingsPanel(final PreferenceTabbedPane gui) {
94 final JPanel p = new JPanel(new GridBagLayout());
95
96 this.colFadeColor = ImageryLayer.getFadeColor();
97 this.btnFadeColor = new JButton();
98
99 this.btnFadeColor.addActionListener(new ActionListener() {
100 @Override
101 public void actionPerformed(ActionEvent e) {
102 JColorChooser chooser = new JColorChooser(colFadeColor);
103 int answer = JOptionPane.showConfirmDialog(
104 gui, chooser,
105 tr("Choose a color for {0}", tr("imagery fade")),
106 JOptionPane.OK_CANCEL_OPTION,
107 JOptionPane.PLAIN_MESSAGE);
108 if (answer == JOptionPane.OK_OPTION) {
109 colFadeColor = chooser.getColor();
110 btnFadeColor.setBackground(colFadeColor);
111 btnFadeColor.setText(ColorHelper.color2html(colFadeColor));
112 }
113 }
114 });
115
116 p.add(new JLabel(tr("Fade Color: ")), GBC.std());
117 p.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
118 p.add(this.btnFadeColor, GBC.eol().fill(GBC.HORIZONTAL));
119
120 p.add(new JLabel(tr("Fade amount: ")), GBC.std());
121 p.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
122 p.add(this.fadeAmount, GBC.eol().fill(GBC.HORIZONTAL));
123
124 this.sharpen = new JComboBox(new String[] {
125 tr("None"),
126 tr("Soft"),
127 tr("Strong")});
128 p.add(new JLabel(tr("Sharpen (requires layer re-add): ")));
129 p.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
130 p.add(this.sharpen, GBC.eol().fill(GBC.HORIZONTAL));
131
132 if (settingsMigration != null) {
133 final JButton btnSettingsMigration = new JButton(tr("WMSPlugin/SlippyMap settings migration"));
134 btnSettingsMigration.addActionListener(new ActionListener() {
135 @Override
136 public void actionPerformed(ActionEvent e) {
137 if (settingsMigration == null) return;
138 settingsMigration.settingsMigrationDialog(gui);
139 loadSettings();
140 imageryProviders.model.fireTableDataChanged();
141 if (!settingsMigration.hasConflicts()) {
142 btnSettingsMigration.setEnabled(false);
143 settingsMigration = null;
144 }
145 }
146 });
147 p.add(btnSettingsMigration,GBC.eol().insets(0,5,0,5));
148 }
149 return p;
150 }
151
152 private JPanel buildWMSSettingsPanel() {
153 final JPanel p = new JPanel(new GridBagLayout());
154 browser = new JComboBox(new String[] {
155 "webkit-image {0}",
156 "gnome-web-photo --mode=photo --format=png {0} /dev/stdout",
157 "gnome-web-photo-fixed {0}",
158 "webkit-image-gtk {0}"});
159 browser.setEditable(true);
160 p.add(new JLabel(tr("Downloader:")), GBC.eol().fill(GBC.HORIZONTAL));
161 p.add(browser);
162
163 // Overlap
164 p.add(Box.createHorizontalGlue(), GBC.eol().fill(GBC.HORIZONTAL));
165
166 overlapCheckBox = new JCheckBox(tr("Overlap tiles"));
167 JLabel labelEast = new JLabel(tr("% of east:"));
168 JLabel labelNorth = new JLabel(tr("% of north:"));
169 spinEast = new JSpinner(new SpinnerNumberModel(WMSLayer.PROP_OVERLAP_EAST.get(), 1, 50, 1));
170 spinNorth = new JSpinner(new SpinnerNumberModel(WMSLayer.PROP_OVERLAP_NORTH.get(), 1, 50, 1));
171
172 JPanel overlapPanel = new JPanel(new FlowLayout());
173 overlapPanel.add(overlapCheckBox);
174 overlapPanel.add(labelEast);
175 overlapPanel.add(spinEast);
176 overlapPanel.add(labelNorth);
177 overlapPanel.add(spinNorth);
178
179 p.add(overlapPanel);
180
181 // Simultaneous connections
182 p.add(Box.createHorizontalGlue(), GBC.eol().fill(GBC.HORIZONTAL));
183 JLabel labelSimConn = new JLabel(tr("Simultaneous connections"));
184 spinSimConn = new JSpinner(new SpinnerNumberModel(WMSLayer.PROP_SIMULTANEOUS_CONNECTIONS.get(), 1, 30, 1));
185 JPanel overlapPanelSimConn = new JPanel(new FlowLayout(FlowLayout.LEFT));
186 overlapPanelSimConn.add(labelSimConn);
187 overlapPanelSimConn.add(spinSimConn);
188 p.add(overlapPanelSimConn, GBC.eol().fill(GBC.HORIZONTAL));
189
190 return p;
191 }
192
193 private JPanel buildTMSSettingsPanel() {
194 JPanel tmsTab = new JPanel(new GridBagLayout());
195
196 minZoomLvl = new JSpinner(new SpinnerNumberModel(TMSLayer.DEFAULT_MIN_ZOOM, TMSLayer.MIN_ZOOM, TMSLayer.MAX_ZOOM, 1));
197 maxZoomLvl = new JSpinner(new SpinnerNumberModel(TMSLayer.DEFAULT_MAX_ZOOM, TMSLayer.MIN_ZOOM, TMSLayer.MAX_ZOOM, 1));
198
199 tmsTab.add(new JLabel(tr("Auto zoom by default: ")), GBC.std());
200 tmsTab.add(GBC.glue(5, 0), GBC.std());
201 tmsTab.add(autozoomActive, GBC.eol().fill(GBC.HORIZONTAL));
202
203 tmsTab.add(new JLabel(tr("Autoload tiles by default: ")), GBC.std());
204 tmsTab.add(GBC.glue(5, 0), GBC.std());
205 tmsTab.add(autoloadTiles, GBC.eol().fill(GBC.HORIZONTAL));
206
207 tmsTab.add(new JLabel(tr("Min zoom lvl: ")), GBC.std());
208 tmsTab.add(GBC.glue(5, 0), GBC.std());
209 tmsTab.add(this.minZoomLvl, GBC.eol());
210
211 tmsTab.add(new JLabel(tr("Max zoom lvl: ")), GBC.std());
212 tmsTab.add(GBC.glue(5, 0), GBC.std());
213 tmsTab.add(this.maxZoomLvl, GBC.eol());
214
215 tmsTab.add(new JLabel(tr("Add to slippymap chooser: ")), GBC.std());
216 tmsTab.add(GBC.glue(5, 0), GBC.std());
217 tmsTab.add(addToSlippyMapChosser, GBC.eol().fill(GBC.HORIZONTAL));
218
219 tmsTab.add(new JLabel(tr("Tile cache directory: ")), GBC.std());
220 tmsTab.add(GBC.glue(5, 0), GBC.std());
221 tmsTab.add(tilecacheDir, GBC.eol().fill(GBC.HORIZONTAL));
222
223 return tmsTab;
224 }
225
226 private void addSettingsSection(final JPanel p, String name, JPanel section) {
227 addSettingsSection(p, name, section, GBC.eol());
228 }
229 private void addSettingsSection(final JPanel p, String name, JPanel section, GBC gbc) {
230 final JLabel lbl = new JLabel(name);
231 lbl.setFont(lbl.getFont().deriveFont(Font.BOLD));
232 p.add(lbl,GBC.std());
233 p.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0));
234 p.add(section, gbc.insets(20,5,0,10));
235 }
236
237 private Component buildSettingsPanel(final PreferenceTabbedPane gui) {
238 final JPanel p = new JPanel(new GridBagLayout());
239 p.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
240
241 addSettingsSection(p, tr("Common Settings"), buildCommonSettingsPanel(gui));
242 addSettingsSection(p, tr("WMS Settings"), buildWMSSettingsPanel());
243 addSettingsSection(p, tr("TMS Settings"), buildTMSSettingsPanel(),
244 GBC.eol().fill(GBC.HORIZONTAL));
245
246 p.add(new JPanel(),GBC.eol().fill(GBC.BOTH));
247 return new JScrollPane(p);
248 }
249
250 @Override
251 public void addGui(final PreferenceTabbedPane gui) {
252 JPanel p = gui.createPreferenceTab("imagery", tr("Imagery Preferences"), tr("Modify list of imagery layers displayed in the Imagery menu"));
253 JTabbedPane pane = new JTabbedPane();
254 imageryProviders = new ImageryProvidersPanel(gui, ImageryLayerInfo.instance);
255 pane.add(imageryProviders);
256 pane.add(buildSettingsPanel(gui));
257 pane.add(new OffsetBookmarksPanel(gui));
258 loadSettings();
259 pane.setTitleAt(0, tr("Imagery providers"));
260 pane.setTitleAt(1, tr("Settings"));
261 pane.setTitleAt(2, tr("Offset bookmarks"));
262 p.add(pane,GBC.std().fill(GBC.BOTH));
263 }
264
265 private void loadSettings() {
266 // Common settings
267 this.btnFadeColor.setBackground(colFadeColor);
268 this.btnFadeColor.setText(ColorHelper.color2html(colFadeColor));
269 this.fadeAmount.setValue(ImageryLayer.PROP_FADE_AMOUNT.get());
270 this.sharpen.setSelectedIndex(Math.max(0, Math.min(2, ImageryLayer.PROP_SHARPEN_LEVEL.get())));
271
272 // WMS Settings
273 this.browser.setSelectedItem(HTMLGrabber.PROP_BROWSER.get());
274 this.overlapCheckBox.setSelected(WMSLayer.PROP_OVERLAP.get());
275 this.spinEast.setValue(WMSLayer.PROP_OVERLAP_EAST.get());
276 this.spinNorth.setValue(WMSLayer.PROP_OVERLAP_NORTH.get());
277 this.spinSimConn.setValue(WMSLayer.PROP_SIMULTANEOUS_CONNECTIONS.get());
278
279 // TMS Settings
280 this.autozoomActive.setSelected(TMSLayer.PROP_DEFAULT_AUTOZOOM.get());
281 this.autoloadTiles.setSelected(TMSLayer.PROP_DEFAULT_AUTOLOAD.get());
282 this.addToSlippyMapChosser.setSelected(TMSLayer.PROP_ADD_TO_SLIPPYMAP_CHOOSER.get());
283 this.maxZoomLvl.setValue(TMSLayer.getMaxZoomLvl(null));
284 this.minZoomLvl.setValue(TMSLayer.getMinZoomLvl(null));
285 this.tilecacheDir.setText(TMSLayer.PROP_TILECACHE_DIR.get());
286 }
287
288 @Override
289 public boolean ok() {
290 boolean restartRequired = false;
291 ImageryLayerInfo.instance.save();
292 Main.main.menu.imageryMenu.refreshImageryMenu();
293 Main.main.menu.imageryMenu.refreshOffsetMenu();
294 OffsetBookmark.saveBookmarks();
295
296 WMSLayer.PROP_OVERLAP.put(overlapCheckBox.getModel().isSelected());
297 WMSLayer.PROP_OVERLAP_EAST.put((Integer) spinEast.getModel().getValue());
298 WMSLayer.PROP_OVERLAP_NORTH.put((Integer) spinNorth.getModel().getValue());
299 WMSLayer.PROP_SIMULTANEOUS_CONNECTIONS.put((Integer) spinSimConn.getModel().getValue());
300
301 HTMLGrabber.PROP_BROWSER.put(browser.getEditor().getItem().toString());
302
303 if (TMSLayer.PROP_ADD_TO_SLIPPYMAP_CHOOSER.get() != this.addToSlippyMapChosser.isSelected()) {
304 restartRequired = true;
305 }
306 TMSLayer.PROP_ADD_TO_SLIPPYMAP_CHOOSER.put(this.addToSlippyMapChosser.isSelected());
307 TMSLayer.PROP_DEFAULT_AUTOZOOM.put(this.autozoomActive.isSelected());
308 TMSLayer.PROP_DEFAULT_AUTOLOAD.put(this.autoloadTiles.isSelected());
309 TMSLayer.setMaxZoomLvl((Integer)this.maxZoomLvl.getValue());
310 TMSLayer.setMinZoomLvl((Integer)this.minZoomLvl.getValue());
311 TMSLayer.PROP_TILECACHE_DIR.put(this.tilecacheDir.getText());
312
313 ImageryLayer.PROP_FADE_AMOUNT.put(this.fadeAmount.getValue());
314 ImageryLayer.setFadeColor(this.colFadeColor);
315 ImageryLayer.PROP_SHARPEN_LEVEL.put(sharpen.getSelectedIndex());
316
317 return restartRequired;
318 }
319
320
321 /**
322 * Updates a server URL in the preferences dialog. Used by plugins.
323 *
324 * @param server
325 * The server name
326 * @param url
327 * The server URL
328 */
329 public void setServerUrl(String server, String url) {
330 for (int i = 0; i < imageryProviders.model.getRowCount(); i++) {
331 if (server.equals(imageryProviders.model.getValueAt(i, 0).toString())) {
332 imageryProviders.model.setValueAt(url, i, 1);
333 return;
334 }
335 }
336 imageryProviders.model.addRow(new String[] { server, url });
337 }
338
339 /**
340 * Gets a server URL in the preferences dialog. Used by plugins.
341 *
342 * @param server
343 * The server name
344 * @return The server URL
345 */
346 public String getServerUrl(String server) {
347 for (int i = 0; i < imageryProviders.model.getRowCount(); i++) {
348 if (server.equals(imageryProviders.model.getValueAt(i, 0).toString()))
349 return imageryProviders.model.getValueAt(i, 1).toString();
350 }
351 return null;
352 }
353
354 static class ImageryProvidersPanel extends JPanel {
355 final ImageryLayerTableModel model;
356 final ImageryDefaultLayerTableModel modeldef;
357 private final ImageryLayerInfo layerInfo;
358 private JTable listActive;
359 final JTable listdef;
360 final PreferenceTabbedPane gui;
361
362 public ImageryProvidersPanel(final PreferenceTabbedPane gui, ImageryLayerInfo layerInfo) {
363 super(new GridBagLayout());
364 this.gui = gui;
365 this.layerInfo = layerInfo;
366 this.model = new ImageryLayerTableModel();
367
368 listActive = new JTable(model) {
369 @Override
370 public String getToolTipText(MouseEvent e) {
371 java.awt.Point p = e.getPoint();
372 return model.getValueAt(rowAtPoint(p), columnAtPoint(p)).toString();
373 }
374 };
375
376 modeldef = new ImageryDefaultLayerTableModel();
377 listdef = new JTable(modeldef) {
378 @Override
379 public String getToolTipText(MouseEvent e) {
380 java.awt.Point p = e.getPoint();
381 return (String) modeldef.getValueAt(rowAtPoint(p), columnAtPoint(p));
382 }
383 };
384
385 TableColumnModel mod = listdef.getColumnModel();
386 mod.getColumn(1).setPreferredWidth(800);
387 mod.getColumn(0).setPreferredWidth(200);
388 mod = listActive.getColumnModel();
389 mod.getColumn(2).setPreferredWidth(50);
390 mod.getColumn(1).setPreferredWidth(800);
391 mod.getColumn(0).setPreferredWidth(200);
392
393 RemoveEntryAction remove = new RemoveEntryAction();
394 listActive.getSelectionModel().addListSelectionListener(remove);
395
396 add(new JLabel(tr("Available default entries:")), GBC.eol().insets(5, 5, 0, 0));
397 // Add default item list
398 JScrollPane scrolldef = new JScrollPane(listdef);
399 scrolldef.setPreferredSize(new Dimension(200, 200));
400 add(scrolldef, GBC.std().insets(0, 5, 0, 0).fill(GridBagConstraints.BOTH).weight(1.0, 0.6).insets(5, 0, 0, 0));
401
402 JToolBar tb = new JToolBar(JToolBar.VERTICAL);
403 tb.setFloatable(false);
404 tb.setBorderPainted(false);
405 tb.setOpaque(false);
406 tb.add(new ReloadAction());
407 add(tb, GBC.eol().anchor(GBC.SOUTH).insets(0, 0, 5, 0));
408
409 ActivateAction activate = new ActivateAction();
410 listdef.getSelectionModel().addListSelectionListener(activate);
411 JButton btnActivate = new JButton(activate);
412
413 JToolBar tb2 = new JToolBar(JToolBar.VERTICAL);
414 tb2.setFloatable(false);
415 tb2.setBorderPainted(false);
416 tb2.setOpaque(false);
417 tb2.add(btnActivate);
418 add(tb2, GBC.eol().anchor(GBC.CENTER).insets(5, 15, 5, 0));
419
420 add(Box.createHorizontalGlue(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
421
422 add(new JLabel(tr("Selected entries:")), GBC.eol().insets(5, 0, 0, 0));
423 JScrollPane scroll = new JScrollPane(listActive);
424 add(scroll, GBC.std().fill(GridBagConstraints.BOTH).weight(1.0, 0.4).insets(5, 0, 0, 5));
425 scroll.setPreferredSize(new Dimension(200, 200));
426
427 JToolBar sideButtonTB = new JToolBar(JToolBar.VERTICAL);
428 sideButtonTB.setFloatable(false);
429 sideButtonTB.setBorderPainted(false);
430 sideButtonTB.setOpaque(false);
431 sideButtonTB.add(new NewEntryAction());
432 //sideButtonTB.add(edit); TODO
433 sideButtonTB.add(remove);
434 add(sideButtonTB, GBC.eol().anchor(GBC.NORTH).insets(0, 0, 5, 5));
435
436 }
437
438 class NewEntryAction extends AbstractAction {
439 public NewEntryAction() {
440 putValue(NAME, tr("New"));
441 putValue(SHORT_DESCRIPTION, tr("add a new wms/tms entry by entering the url"));
442 putValue(SMALL_ICON, ImageProvider.get("dialogs", "add"));
443 }
444
445 public void actionPerformed(ActionEvent evt) {
446 AddWMSLayerPanel p = new AddWMSLayerPanel();
447 int answer = JOptionPane.showConfirmDialog(
448 gui, p,
449 tr("Add Imagery URL"),
450 JOptionPane.OK_CANCEL_OPTION);
451 if (answer == JOptionPane.OK_OPTION) {
452 model.addRow(new ImageryInfo(p.getUrlName(), p.getUrl()));
453 }
454 }
455 }
456
457 class RemoveEntryAction extends AbstractAction implements ListSelectionListener {
458
459 public RemoveEntryAction() {
460 putValue(NAME, tr("Remove"));
461 putValue(SHORT_DESCRIPTION, tr("remove entry"));
462 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
463 updateEnabledState();
464 }
465
466 protected void updateEnabledState() {
467 setEnabled(listActive.getSelectedRowCount() > 0);
468 }
469
470 @Override
471 public void valueChanged(ListSelectionEvent e) {
472 updateEnabledState();
473 }
474
475 @Override
476 public void actionPerformed(ActionEvent e) {
477 Integer i;
478 while ((i = listActive.getSelectedRow()) != -1) {
479 model.removeRow(i);
480 }
481 }
482 }
483
484 class ActivateAction extends AbstractAction implements ListSelectionListener {
485 public ActivateAction() {
486 putValue(NAME, tr("Activate"));
487 putValue(SHORT_DESCRIPTION, tr("copy selected defaults"));
488 putValue(SMALL_ICON, ImageProvider.get("preferences", "activate-down"));
489 }
490
491 protected void updateEnabledState() {
492 setEnabled(listdef.getSelectedRowCount() > 0);
493 }
494
495 @Override
496 public void valueChanged(ListSelectionEvent e) {
497 updateEnabledState();
498 }
499
500 @Override
501 public void actionPerformed(ActionEvent e) {
502 int[] lines = listdef.getSelectedRows();
503 if (lines.length == 0) {
504 JOptionPane.showMessageDialog(
505 gui,
506 tr("Please select at least one row to copy."),
507 tr("Information"),
508 JOptionPane.INFORMATION_MESSAGE);
509 return;
510 }
511
512 outer: for (int i = 0; i < lines.length; i++) {
513 ImageryInfo info = modeldef.getRow(lines[i]);
514
515 // Check if an entry with exactly the same values already
516 // exists
517 for (int j = 0; j < model.getRowCount(); j++) {
518 if (info.equalsBaseValues(model.getRow(j))) {
519 // Select the already existing row so the user has
520 // some feedback in case an entry exists
521 listActive.getSelectionModel().setSelectionInterval(j, j);
522 listActive.scrollRectToVisible(listActive.getCellRect(j, 0, true));
523 continue outer;
524 }
525 }
526
527 if (info.eulaAcceptanceRequired != null) {
528 if (!confirmEulaAcceptance(gui, info.eulaAcceptanceRequired)) {
529 continue outer;
530 }
531 }
532
533 model.addRow(new ImageryInfo(info));
534 int lastLine = model.getRowCount() - 1;
535 listActive.getSelectionModel().setSelectionInterval(lastLine, lastLine);
536 listActive.scrollRectToVisible(listActive.getCellRect(lastLine, 0, true));
537 }
538 }
539 }
540
541 class ReloadAction extends AbstractAction {
542 public ReloadAction() {
543 putValue(SHORT_DESCRIPTION, tr("reload defaults"));
544 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
545 }
546
547 public void actionPerformed(ActionEvent evt) {
548 layerInfo.load();
549 modeldef.fireTableDataChanged();
550 }
551 }
552
553 /**
554 * The table model for imagery layer list
555 */
556 class ImageryLayerTableModel extends DefaultTableModel {
557 public ImageryLayerTableModel() {
558 setColumnIdentifiers(new String[] { tr("Menu Name"), tr("Imagery URL"), trc("layer", "Zoom") });
559 }
560
561 public ImageryInfo getRow(int row) {
562 return layerInfo.getLayers().get(row);
563 }
564
565 public void addRow(ImageryInfo i) {
566 layerInfo.add(i);
567 int p = getRowCount() - 1;
568 fireTableRowsInserted(p, p);
569 }
570
571 @Override
572 public void removeRow(int i) {
573 layerInfo.remove(getRow(i));
574 fireTableRowsDeleted(i, i);
575 }
576
577 @Override
578 public int getRowCount() {
579 return layerInfo.getLayers().size();
580 }
581
582 @Override
583 public Object getValueAt(int row, int column) {
584 ImageryInfo info = layerInfo.getLayers().get(row);
585 switch (column) {
586 case 0:
587 return info.getName();
588 case 1:
589 return info.getFullUrl();
590 case 2:
591 return (info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.HTML) ?
592 (info.getPixelPerDegree() == 0.0 ? "" : info.getPixelPerDegree()) :
593 (info.getMaxZoom() == 0 ? "" : info.getMaxZoom());
594 default:
595 throw new ArrayIndexOutOfBoundsException();
596 }
597 }
598
599 @Override
600 public void setValueAt(Object o, int row, int column) {
601 ImageryInfo info = layerInfo.getLayers().get(row);
602 switch (column) {
603 case 0:
604 info.setName((String) o);
605 break;
606 case 1:
607 info.setUrl((String)o);
608 break;
609 case 2:
610 info.setPixelPerDegree(0);
611 info.setMaxZoom(0);
612 try {
613 if(info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.HTML) {
614 info.setPixelPerDegree(Double.parseDouble((String) o));
615 } else {
616 info.setMaxZoom(Integer.parseInt((String) o));
617 }
618 } catch (NumberFormatException e) {
619 }
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 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.getName();
655 case 1:
656 return info.getFullUrl();
657 }
658 return null;
659 }
660
661 @Override
662 public boolean isCellEditable(int row, int column) {
663 return false;
664 }
665 }
666
667 private boolean confirmEulaAcceptance(PreferenceTabbedPane gui, String eulaUrl) {
668 URL url = null;
669 try {
670 url = new URL(eulaUrl.replaceAll("\\{lang\\}", Locale.getDefault().toString()));
671 JEditorPane htmlPane = null;
672 try {
673 htmlPane = new JEditorPane(url);
674 } catch (IOException e1) {
675 // give a second chance with a default Locale 'en'
676 try {
677 url = new URL(eulaUrl.replaceAll("\\{lang\\}", "en"));
678 htmlPane = new JEditorPane(url);
679 } catch (IOException e2) {
680 JOptionPane.showMessageDialog(gui ,tr("EULA license URL not available: {0}", eulaUrl));
681 return false;
682 }
683 }
684 Box box = Box.createVerticalBox();
685 htmlPane.setEditable(false);
686 JScrollPane scrollPane = new JScrollPane(htmlPane);
687 scrollPane.setPreferredSize(new Dimension(400, 400));
688 box.add(scrollPane);
689 int option = JOptionPane.showConfirmDialog(Main.parent, box, tr("Please abort if you are not sure"), JOptionPane.YES_NO_OPTION,
690 JOptionPane.WARNING_MESSAGE);
691 if (option == JOptionPane.YES_OPTION)
692 return true;
693 } catch (MalformedURLException e2) {
694 JOptionPane.showMessageDialog(gui ,tr("Malformed URL for the EULA licence: {0}", eulaUrl));
695 }
696 return false;
697 }
698 }
699
700 static class OffsetBookmarksPanel extends JPanel {
701 List<OffsetBookmark> bookmarks = OffsetBookmark.allBookmarks;
702 OffsetsBookmarksModel model = new OffsetsBookmarksModel();
703
704 public OffsetBookmarksPanel(final PreferenceTabbedPane gui) {
705 super(new GridBagLayout());
706 final JTable list = new JTable(model) {
707 @Override
708 public String getToolTipText(MouseEvent e) {
709 java.awt.Point p = e.getPoint();
710 return model.getValueAt(rowAtPoint(p), columnAtPoint(p)).toString();
711 }
712 };
713 JScrollPane scroll = new JScrollPane(list);
714 add(scroll, GBC.eol().fill(GridBagConstraints.BOTH));
715 scroll.setPreferredSize(new Dimension(200, 200));
716
717 TableColumnModel mod = list.getColumnModel();
718 mod.getColumn(0).setPreferredWidth(150);
719 mod.getColumn(1).setPreferredWidth(200);
720 mod.getColumn(2).setPreferredWidth(300);
721 mod.getColumn(3).setPreferredWidth(150);
722 mod.getColumn(4).setPreferredWidth(150);
723
724 JPanel buttonPanel = new JPanel(new FlowLayout());
725
726 JButton add = new JButton(tr("Add"));
727 buttonPanel.add(add, GBC.std().insets(0, 5, 0, 0));
728 add.addActionListener(new ActionListener() {
729 @Override
730 public void actionPerformed(ActionEvent e) {
731 OffsetBookmark b = new OffsetBookmark(Main.proj,"","",0,0);
732 model.addRow(b);
733 }
734 });
735
736 JButton delete = new JButton(tr("Delete"));
737 buttonPanel.add(delete, GBC.std().insets(0, 5, 0, 0));
738 delete.addActionListener(new ActionListener() {
739 @Override
740 public void actionPerformed(ActionEvent e) {
741 if (list.getSelectedRow() == -1) {
742 JOptionPane.showMessageDialog(gui, tr("Please select the row to delete."));
743 } else {
744 Integer i;
745 while ((i = list.getSelectedRow()) != -1) {
746 model.removeRow(i);
747 }
748 }
749 }
750 });
751
752 add(buttonPanel,GBC.eol());
753 }
754
755 /**
756 * The table model for imagery offsets list
757 */
758 class OffsetsBookmarksModel extends DefaultTableModel {
759 public OffsetsBookmarksModel() {
760 setColumnIdentifiers(new String[] { tr("Projection"), tr("Layer"), tr("Name"), tr("Easting"), tr("Northing"),});
761 }
762
763 public OffsetBookmark getRow(int row) {
764 return bookmarks.get(row);
765 }
766
767 public void addRow(OffsetBookmark i) {
768 bookmarks.add(i);
769 int p = getRowCount() - 1;
770 fireTableRowsInserted(p, p);
771 }
772
773 @Override
774 public void removeRow(int i) {
775 bookmarks.remove(getRow(i));
776 fireTableRowsDeleted(i, i);
777 }
778
779 @Override
780 public int getRowCount() {
781 return bookmarks.size();
782 }
783
784 @Override
785 public Object getValueAt(int row, int column) {
786 OffsetBookmark info = bookmarks.get(row);
787 switch (column) {
788 case 0:
789 if (info.proj == null) return "";
790 return info.proj.toString();
791 case 1:
792 return info.layerName;
793 case 2:
794 return info.name;
795 case 3:
796 return info.dx;
797 case 4:
798 return info.dy;
799 default:
800 throw new ArrayIndexOutOfBoundsException();
801 }
802 }
803
804 @Override
805 public void setValueAt(Object o, int row, int column) {
806 OffsetBookmark info = bookmarks.get(row);
807 switch (column) {
808 case 1:
809 info.layerName = o.toString();
810 break;
811 case 2:
812 info.name = o.toString();
813 break;
814 case 3:
815 info.dx = Double.parseDouble((String) o);
816 break;
817 case 4:
818 info.dy = Double.parseDouble((String) o);
819 break;
820 default:
821 throw new ArrayIndexOutOfBoundsException();
822 }
823 }
824
825 @Override
826 public boolean isCellEditable(int row, int column) {
827 return column >= 1;
828 }
829 }
830 }
831
832 public static void initialize() {
833 settingsMigration = new ImagerySettingsMigration();
834 settingsMigration.migrateSettings();
835 if (!settingsMigration.hasConflicts()) {
836 settingsMigration = null;
837 }
838 ImageryLayerInfo.instance.load();
839 OffsetBookmark.loadBookmarks();
840 Main.main.menu.imageryMenu.refreshImageryMenu();
841 Main.main.menu.imageryMenu.refreshOffsetMenu();
842 }
843}
Note: See TracBrowser for help on using the repository browser.