001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    import static org.openstreetmap.josm.tools.I18n.trc;
006    
007    import java.awt.Component;
008    import java.awt.event.ActionEvent;
009    import java.util.List;
010    
011    import javax.swing.Action;
012    import javax.swing.JComponent;
013    import javax.swing.JMenu;
014    import javax.swing.JMenuItem;
015    import javax.swing.JPopupMenu;
016    import javax.swing.MenuElement;
017    
018    import org.openstreetmap.josm.Main;
019    import org.openstreetmap.josm.actions.AddImageryLayerAction;
020    import org.openstreetmap.josm.actions.JosmAction;
021    import org.openstreetmap.josm.actions.Map_Rectifier_WMSmenuAction;
022    import org.openstreetmap.josm.data.imagery.ImageryInfo;
023    import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
024    import org.openstreetmap.josm.gui.layer.ImageryLayer;
025    import org.openstreetmap.josm.gui.layer.Layer;
026    import org.openstreetmap.josm.tools.ImageProvider;
027    
028    public class ImageryMenu extends JMenu implements MapView.LayerChangeListener {
029        private Action offsetAction = new JosmAction(
030                tr("Imagery offset"), "mapmode/adjustimg", tr("Adjust imagery offset"), null, false, false) {
031            {
032                putValue("toolbar", "imagery-offset");
033                Main.toolbar.register(this);
034            }
035            @Override
036            public void actionPerformed(ActionEvent e) {
037                List<ImageryLayer> layers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
038                if (layers.isEmpty()) {
039                    setEnabled(false);
040                    return;
041                }
042                Component source = null;
043                if (e.getSource() instanceof Component) {
044                    source = (Component)e.getSource();
045                }
046                JPopupMenu popup = new JPopupMenu();
047                if (layers.size() == 1) {
048                    JComponent c = layers.get(0).getOffsetMenuItem(popup);
049                    if (c instanceof JMenuItem) {
050                        ((JMenuItem) c).getAction().actionPerformed(e);
051                    } else {
052                        if (source == null) return;
053                        popup.show(source, source.getWidth()/2, source.getHeight()/2);
054                    }
055                    return;
056                }
057                if (source == null) return;
058                for (ImageryLayer layer : layers) {
059                    JMenuItem layerMenu = layer.getOffsetMenuItem();
060                    layerMenu.setText(layer.getName());
061                    layerMenu.setIcon(layer.getIcon());
062                    popup.add(layerMenu);
063                }
064                popup.show(source, source.getWidth()/2, source.getHeight()/2);
065            }
066        };
067        private JMenuItem singleOffset = new JMenuItem(offsetAction);
068        private JMenuItem offsetMenuItem = singleOffset;
069        private Map_Rectifier_WMSmenuAction rectaction = new Map_Rectifier_WMSmenuAction();
070        private int offsPos;
071    
072        public ImageryMenu() {
073            super(tr("Imagery"));
074            MapView.addLayerChangeListener(this);
075        }
076    
077        public void refreshImageryMenu() {
078            removeAll();
079    
080            // for each configured ImageryInfo, add a menu entry.
081            for (final ImageryInfo u : ImageryLayerInfo.instance.getLayers()) {
082                add(new AddImageryLayerAction(u));
083            }
084            addSeparator();
085            add(new JMenuItem(rectaction));
086    
087            addSeparator();
088            offsPos = getMenuComponentCount();
089            add(offsetMenuItem);
090        }
091    
092        private JMenuItem getNewOffsetMenu(){
093            if (Main.map == null || Main.map.mapView == null) {
094                offsetAction.setEnabled(false);
095                return singleOffset;
096            }
097            List<ImageryLayer> layers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
098            if (layers.isEmpty()) {
099                offsetAction.setEnabled(false);
100                return singleOffset;
101            }
102            offsetAction.setEnabled(true);
103            JMenu newMenu = new JMenu(trc("layer","Offset")) {
104                // Hack to prevent ToolbarPreference from tracing this menu
105                // TODO: Modify ToolbarPreference to not to trace such dynamic submenus?
106                @Override
107                public MenuElement[] getSubElements() {
108                    return new MenuElement[0];
109                }
110            };
111            newMenu.setIcon(ImageProvider.get("mapmode", "adjustimg"));
112            newMenu.setAction(offsetAction);
113            if (layers.size() == 1)
114                return (JMenuItem)layers.get(0).getOffsetMenuItem(newMenu);
115            for (ImageryLayer layer : layers) {
116                JMenuItem layerMenu = layer.getOffsetMenuItem();
117                layerMenu.setText(layer.getName());
118                layerMenu.setIcon(layer.getIcon());
119                newMenu.add(layerMenu);
120            }
121            return newMenu;
122        }
123    
124        public void refreshOffsetMenu() {
125            JMenuItem newItem = getNewOffsetMenu();
126            remove(offsetMenuItem);
127            add(newItem, offsPos);
128            offsetMenuItem = newItem;
129        }
130    
131        @Override
132        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
133        }
134    
135        @Override
136        public void layerAdded(Layer newLayer) {
137            if (newLayer instanceof ImageryLayer) {
138                refreshOffsetMenu();
139            }
140        }
141    
142        @Override
143        public void layerRemoved(Layer oldLayer) {
144            if (oldLayer instanceof ImageryLayer) {
145                refreshOffsetMenu();
146            }
147        }
148    }