001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Dimension; 007import java.awt.GridBagLayout; 008import java.awt.event.ActionEvent; 009import java.io.IOException; 010import java.net.MalformedURLException; 011 012import javax.swing.Action; 013import javax.swing.ImageIcon; 014import javax.swing.JComboBox; 015import javax.swing.JOptionPane; 016import javax.swing.JPanel; 017import javax.swing.JScrollPane; 018 019import org.openstreetmap.josm.Main; 020import org.openstreetmap.josm.data.imagery.ImageryInfo; 021import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType; 022import org.openstreetmap.josm.gui.ExtendedDialog; 023import org.openstreetmap.josm.gui.actionsupport.AlignImageryPanel; 024import org.openstreetmap.josm.gui.layer.ImageryLayer; 025import org.openstreetmap.josm.gui.preferences.imagery.WMSLayerTree; 026import org.openstreetmap.josm.io.imagery.WMSImagery; 027import org.openstreetmap.josm.tools.GBC; 028import org.openstreetmap.josm.tools.ImageProvider; 029 030public class AddImageryLayerAction extends JosmAction implements AdaptableAction { 031 032 private static final int MAX_ICON_SIZE = 24; 033 private final ImageryInfo info; 034 035 public AddImageryLayerAction(ImageryInfo info) { 036 super(info.getMenuName(), /* ICON */"imagery_menu", tr("Add imagery layer {0}",info.getName()), null, false, false); 037 putValue("toolbar", "imagery_" + info.getToolbarName()); 038 this.info = info; 039 installAdapters(); 040 041 // change toolbar icon from if specified 042 try { 043 if (info.getIcon() != null) { 044 ImageIcon i = new ImageProvider(info.getIcon()).setOptional(true). 045 setMaxHeight(MAX_ICON_SIZE).setMaxWidth(MAX_ICON_SIZE).get(); 046 if (i != null) { 047 putValue(Action.SMALL_ICON, i); 048 } 049 } 050 } catch (Exception ex) { 051 throw new RuntimeException(ex.getMessage(), ex); 052 } 053 } 054 055 @Override 056 public void actionPerformed(ActionEvent e) { 057 if (!isEnabled()) return; 058 try { 059 final ImageryInfo infoToAdd = ImageryType.WMS_ENDPOINT.equals(info.getImageryType()) 060 ? getWMSLayerInfo() : info; 061 if (infoToAdd != null) { 062 Main.main.addLayer(ImageryLayer.create(infoToAdd)); 063 AlignImageryPanel.addNagPanelIfNeeded(); 064 } 065 } catch (IllegalArgumentException ex) { 066 if (ex.getMessage() == null || ex.getMessage().isEmpty()) { 067 throw ex; 068 } else { 069 JOptionPane.showMessageDialog(Main.parent, 070 ex.getMessage(), tr("Error"), 071 JOptionPane.ERROR_MESSAGE); 072 } 073 } 074 } 075 076 protected ImageryInfo getWMSLayerInfo() { 077 try { 078 assert (ImageryType.WMS_ENDPOINT.equals(info.getImageryType())); 079 final WMSImagery wms = new WMSImagery(); 080 wms.attemptGetCapabilities(info.getUrl()); 081 082 final WMSLayerTree tree = new WMSLayerTree(); 083 tree.updateTree(wms); 084 final JComboBox formats = new JComboBox(wms.getFormats().toArray()); 085 formats.setToolTipText(tr("Select image format for WMS layer")); 086 087 if (1 != new ExtendedDialog(Main.parent, tr("Select WMS layers"), new String[]{tr("Add layers"), tr("Cancel")}) {{ 088 final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree()); 089 scrollPane.setPreferredSize(new Dimension(400, 400)); 090 final JPanel panel = new JPanel(new GridBagLayout()); 091 panel.add(scrollPane, GBC.eol().fill()); 092 panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL)); 093 setContent(panel); 094 }}.showDialog().getValue()) { 095 return null; 096 } 097 098 final String url = wms.buildGetMapUrl( 099 tree.getSelectedLayers(), (String) formats.getSelectedItem()); 100 return new ImageryInfo(info.getName(), url, "wms", info.getEulaAcceptanceRequired(), info.getCookies()); 101 } // exception handling from AddWMSLayerPanel.java 102 catch (MalformedURLException ex) { 103 JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."), 104 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 105 } catch (IOException ex) { 106 JOptionPane.showMessageDialog(Main.parent, tr("Could not retrieve WMS layer list."), 107 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 108 } catch (WMSImagery.WMSGetCapabilitiesException ex) { 109 JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMS layer list."), 110 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 111 Main.error("Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData()); 112 } 113 return null; 114 } 115 116 protected boolean isLayerAlreadyPresent() { 117 if (Main.isDisplayingMapView()) { 118 for (ImageryLayer layer : Main.map.mapView.getLayersOfType(ImageryLayer.class)) { 119 if (info.equals(layer.getInfo())) { 120 return true; 121 } 122 } 123 } 124 return false; 125 } 126 127 @Override 128 protected void updateEnabledState() { 129 // never enable blacklisted entries. Do not add same imagery layer twice (fix #2519) 130 if (info.isBlacklisted() /*|| isLayerAlreadyPresent()*/) { // FIXME check disabled to allow several instances with different settings (see #7981) 131 setEnabled(false); 132 } else if (info.getImageryType() == ImageryType.TMS || info.getImageryType() == ImageryType.BING || info.getImageryType() == ImageryType.SCANEX) { 133 setEnabled(true); 134 } else if (Main.isDisplayingMapView() && !Main.map.mapView.getAllLayers().isEmpty()) { 135 setEnabled(true); 136 } else { 137 setEnabled(false); 138 } 139 } 140}