001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.awt.event.ActionEvent;
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.List;
011
012import javax.swing.AbstractAction;
013import javax.swing.Action;
014import javax.swing.JMenuItem;
015import javax.swing.JOptionPane;
016import javax.swing.JPopupMenu;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.gui.layer.Layer;
020import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
021import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction;
022import org.openstreetmap.josm.gui.layer.Layer.SeparatorLayerAction;
023import org.openstreetmap.josm.tools.ImageProvider;
024
025/**
026 * Popup menu handler for the layer list.
027 */
028public class LayerListPopup extends JPopupMenu {
029
030    public final static class InfoAction extends AbstractAction {
031        private final Layer layer;
032        public InfoAction(Layer layer) {
033            super(tr("Info"), ImageProvider.get("info"));
034            putValue("help", ht("/Action/LayerInfo"));
035            this.layer = layer;
036        }
037        @Override
038        public void actionPerformed(ActionEvent e) {
039            JOptionPane.showMessageDialog(
040                    Main.parent,
041                    layer.getInfoComponent(),
042                    tr("Information about layer"),
043                    JOptionPane.INFORMATION_MESSAGE
044            );
045        }
046    }
047
048    public LayerListPopup(List<Layer> selectedLayers, final Layer layer) {
049
050        List<Action> actions;
051        if (selectedLayers.size() == 1) {
052            actions = Arrays.asList(selectedLayers.get(0).getMenuEntries());
053        } else {
054            // Very simple algorithm - first selected layer has actions order as in getMenuEntries, actions from other layers go to the end
055            actions = new ArrayList<Action>();
056            boolean separatorAdded = true;
057            for (Action a: selectedLayers.get(0).getMenuEntries()) {
058                if (!separatorAdded && a instanceof SeparatorLayerAction) {
059                    separatorAdded = true;
060                    actions.add(a);
061                } else if (a instanceof LayerAction && ((LayerAction)a).supportLayers(selectedLayers)) {
062                    separatorAdded = false;
063                    if(a instanceof MultiLayerAction)
064                        a = ((MultiLayerAction)a).getMultiLayerAction(selectedLayers);
065                    actions.add(a);
066                }
067            }
068            // This will usually add no action, because if some action support all selected layers then it was probably used also in first layer
069            for (int i=1; i<selectedLayers.size(); i++) {
070                separatorAdded = false;
071                for (Action a: selectedLayers.get(i).getMenuEntries()) {
072                    if (a instanceof LayerAction && !(a instanceof MultiLayerAction)
073                    && ((LayerAction)a).supportLayers(selectedLayers) && !actions.contains(a)) {
074                        if (!separatorAdded) {
075                            separatorAdded = true;
076                            actions.add(SeparatorLayerAction.INSTANCE);
077                        }
078                        actions.add(a);
079                    }
080                }
081            }
082        }
083        if (!actions.isEmpty() && actions.get(actions.size() - 1) instanceof SeparatorLayerAction) {
084            actions.remove(actions.size() - 1);
085        }
086        for (Action a : actions) {
087            if (a instanceof LayerAction) {
088                add (((LayerAction) a).createMenuComponent());
089            } else {
090                add(new JMenuItem(a));
091            }
092        }
093    }
094}