source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java

Last change on this file was 17998, checked in by Don-vip, 3 years ago

fix #20950 - UnsupportedOperationException when right-clicking on an MVT Layer in non-expert mode (patch by taylor.smock)

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static java.util.Collections.emptyList;
5import static java.util.stream.Collectors.toCollection;
6import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
7import static org.openstreetmap.josm.tools.I18n.tr;
8
9import java.awt.Component;
10import java.awt.Dimension;
11import java.awt.event.ActionEvent;
12import java.util.ArrayList;
13import java.util.List;
14import java.util.stream.Stream;
15
16import javax.swing.AbstractAction;
17import javax.swing.Action;
18import javax.swing.JMenuItem;
19import javax.swing.JOptionPane;
20import javax.swing.JPopupMenu;
21
22import org.openstreetmap.josm.gui.ExtendedDialog;
23import org.openstreetmap.josm.gui.MainApplication;
24import org.openstreetmap.josm.gui.layer.Layer;
25import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
26import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction;
27import org.openstreetmap.josm.gui.layer.Layer.SeparatorLayerAction;
28import org.openstreetmap.josm.tools.ImageProvider;
29
30/**
31 * Popup menu handler for the layer list.
32 */
33public class LayerListPopup extends JPopupMenu {
34
35 /**
36 * An action that displays the layer information.
37 * @see Layer#getInfoComponent()
38 */
39 public static final class InfoAction extends AbstractAction {
40 private final transient Layer layer;
41
42 /**
43 * Constructs a new {@code InfoAction} for the given layer.
44 * @param layer The layer
45 */
46 public InfoAction(Layer layer) {
47 super(tr("Info"));
48 new ImageProvider("info").getResource().attachImageIcon(this, true);
49 putValue("help", ht("/Action/LayerInfo"));
50 this.layer = layer;
51 }
52
53 @Override
54 public void actionPerformed(ActionEvent e) {
55 Object object = layer.getInfoComponent();
56 if (object instanceof Component) {
57 ExtendedDialog ed = new ExtendedDialog(
58 MainApplication.getMainFrame(), tr("Information about layer"),
59 tr("OK"));
60 ed.setButtonIcons("ok");
61 ed.setIcon(JOptionPane.INFORMATION_MESSAGE);
62 ed.setContent((Component) object);
63 ed.setResizable(layer.isInfoResizable());
64 ed.setMinimumSize(new Dimension(270, 170));
65 ed.showDialog();
66 } else {
67 JOptionPane.showMessageDialog(
68 MainApplication.getMainFrame(), object,
69 tr("Information about layer"),
70 JOptionPane.INFORMATION_MESSAGE
71 );
72 }
73 }
74 }
75
76 /**
77 * Constructs a new {@code LayerListPopup}.
78 * @param selectedLayers list of selected layers
79 */
80 public LayerListPopup(List<Layer> selectedLayers) {
81
82 List<Action> actions;
83 if (selectedLayers.size() == 1) {
84 Action[] entries = selectedLayers.get(0).getMenuEntries();
85 // Since we may add to the array later, we cannot use Arrays.asList -- it prohibits the use of `add` or `remove`.
86 actions = entries != null ? Stream.of(entries).collect(toCollection(ArrayList::new)) : emptyList();
87 } else {
88 // Very simple algorithm - first selected layer has actions order as in getMenuEntries, actions from other layers go to the end
89 actions = new ArrayList<>();
90 boolean separatorAdded = true;
91 for (Action a: selectedLayers.get(0).getMenuEntries()) {
92 if (!separatorAdded && a instanceof SeparatorLayerAction) {
93 separatorAdded = true;
94 actions.add(a);
95 } else if (a instanceof LayerAction && ((LayerAction) a).supportLayers(selectedLayers)) {
96 separatorAdded = false;
97 if (a instanceof MultiLayerAction)
98 a = ((MultiLayerAction) a).getMultiLayerAction(selectedLayers);
99 actions.add(a);
100 }
101 }
102 // This will usually add no action, because if some action support all selected layers then it was probably used also in first layer
103 for (int i = 1; i < selectedLayers.size(); i++) {
104 separatorAdded = false;
105 for (Action a: selectedLayers.get(i).getMenuEntries()) {
106 if (a instanceof LayerAction && !(a instanceof MultiLayerAction)
107 && ((LayerAction) a).supportLayers(selectedLayers) && !actions.contains(a)) {
108 if (!separatorAdded) {
109 separatorAdded = true;
110 actions.add(SeparatorLayerAction.INSTANCE);
111 }
112 actions.add(a);
113 }
114 }
115 }
116 }
117 if (!actions.isEmpty() && actions.get(actions.size() - 1) instanceof SeparatorLayerAction) {
118 actions.remove(actions.size() - 1);
119 }
120 for (Action a : actions) {
121 if (a instanceof LayerAction) {
122 add(((LayerAction) a).createMenuComponent());
123 } else {
124 add(new JMenuItem(a));
125 }
126 }
127 }
128}
Note: See TracBrowser for help on using the repository browser.