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}