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.Component;
008import java.awt.Dimension;
009import java.awt.event.ActionEvent;
010import java.util.ArrayList;
011import java.util.Arrays;
012import java.util.List;
013
014import javax.swing.AbstractAction;
015import javax.swing.Action;
016import javax.swing.JMenuItem;
017import javax.swing.JOptionPane;
018import javax.swing.JPopupMenu;
019
020import org.openstreetmap.josm.Main;
021import org.openstreetmap.josm.gui.ExtendedDialog;
022import org.openstreetmap.josm.gui.layer.Layer;
023import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
024import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction;
025import org.openstreetmap.josm.gui.layer.Layer.SeparatorLayerAction;
026import org.openstreetmap.josm.tools.ImageProvider;
027
028/**
029 * Popup menu handler for the layer list.
030 */
031public class LayerListPopup extends JPopupMenu {
032
033    public static final class InfoAction extends AbstractAction {
034        private final Layer layer;
035
036        /**
037         * Constructs a new {@code InfoAction} for the given layer.
038         * @param layer The layer
039         */
040        public InfoAction(Layer layer) {
041            super(tr("Info"), ImageProvider.get("info"));
042            putValue("help", ht("/Action/LayerInfo"));
043            this.layer = layer;
044        }
045
046        @Override
047        public void actionPerformed(ActionEvent e) {
048            Object object = layer.getInfoComponent();
049            if (object instanceof Component) {
050                ExtendedDialog ed = new ExtendedDialog(
051                        Main.parent, tr("Information about layer"),
052                        new String[] {tr("OK")});
053                ed.setButtonIcons(new String[] {"ok"});
054                ed.setIcon(JOptionPane.INFORMATION_MESSAGE);
055                ed.setContent((Component) object);
056                ed.setResizable(layer.isInfoResizable());
057                ed.setMinimumSize(new Dimension(270, 170));
058                ed.showDialog();
059            } else {
060                JOptionPane.showMessageDialog(
061                        Main.parent, object,
062                        tr("Information about layer"),
063                        JOptionPane.INFORMATION_MESSAGE
064                        );
065            }
066        }
067    }
068
069    public LayerListPopup(List<Layer> selectedLayers, final Layer layer) {
070
071        List<Action> actions;
072        if (selectedLayers.size() == 1) {
073            actions = Arrays.asList(selectedLayers.get(0).getMenuEntries());
074        } else {
075            // Very simple algorithm - first selected layer has actions order as in getMenuEntries, actions from other layers go to the end
076            actions = new ArrayList<>();
077            boolean separatorAdded = true;
078            for (Action a: selectedLayers.get(0).getMenuEntries()) {
079                if (!separatorAdded && a instanceof SeparatorLayerAction) {
080                    separatorAdded = true;
081                    actions.add(a);
082                } else if (a instanceof LayerAction && ((LayerAction)a).supportLayers(selectedLayers)) {
083                    separatorAdded = false;
084                    if(a instanceof MultiLayerAction)
085                        a = ((MultiLayerAction)a).getMultiLayerAction(selectedLayers);
086                    actions.add(a);
087                }
088            }
089            // This will usually add no action, because if some action support all selected layers then it was probably used also in first layer
090            for (int i=1; i<selectedLayers.size(); i++) {
091                separatorAdded = false;
092                for (Action a: selectedLayers.get(i).getMenuEntries()) {
093                    if (a instanceof LayerAction && !(a instanceof MultiLayerAction)
094                    && ((LayerAction)a).supportLayers(selectedLayers) && !actions.contains(a)) {
095                        if (!separatorAdded) {
096                            separatorAdded = true;
097                            actions.add(SeparatorLayerAction.INSTANCE);
098                        }
099                        actions.add(a);
100                    }
101                }
102            }
103        }
104        if (!actions.isEmpty() && actions.get(actions.size() - 1) instanceof SeparatorLayerAction) {
105            actions.remove(actions.size() - 1);
106        }
107        for (Action a : actions) {
108            if (a instanceof LayerAction) {
109                add (((LayerAction) a).createMenuComponent());
110            } else {
111                add(new JMenuItem(a));
112            }
113        }
114    }
115}