001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.dialogs.properties;
003
004 import java.awt.Cursor;
005 import java.awt.Dimension;
006 import java.awt.Font;
007 import java.awt.GridBagLayout;
008 import java.awt.event.MouseEvent;
009 import java.awt.event.MouseListener;
010 import java.awt.font.TextAttribute;
011 import java.util.Collection;
012 import java.util.Collections;
013 import java.util.List;
014 import java.util.Map;
015
016 import javax.swing.Action;
017 import javax.swing.Icon;
018 import javax.swing.JLabel;
019 import javax.swing.JPanel;
020
021 import org.openstreetmap.josm.data.osm.OsmPrimitive;
022 import org.openstreetmap.josm.data.osm.Tag;
023 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
024 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
025 import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
026 import org.openstreetmap.josm.tools.GBC;
027
028 public class PresetListPanel extends JPanel {
029
030 public PresetListPanel() {
031 super(new GridBagLayout());
032 }
033
034 public interface PresetHandler {
035 Collection<OsmPrimitive> getSelection();
036 void updateTags(List<Tag> tags);
037 }
038
039 /**
040 * Small helper class that manages the highlighting of the label on hover as well as opening
041 * the corresponding preset when clicked
042 */
043 private static class PresetLabelML implements MouseListener {
044 final JLabel label;
045 final Font hover;
046 final Font normal;
047 final TaggingPreset tag;
048 final PresetHandler presetHandler;
049
050 PresetLabelML(JLabel lbl, TaggingPreset t, PresetHandler presetHandler) {
051 super();
052 label = lbl;
053 lbl.setCursor(new Cursor(Cursor.HAND_CURSOR));
054 normal = label.getFont();
055 hover = normal.deriveFont(Collections.singletonMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DOTTED));
056 tag = t;
057 this.presetHandler = presetHandler;
058 }
059 public void mouseClicked(MouseEvent arg0) {
060 Collection<OsmPrimitive> selection = tag.createSelection(presetHandler.getSelection());
061 if (selection == null || selection.isEmpty())
062 return;
063 int answer = tag.showDialog(selection, false);
064
065 if (answer == TaggingPreset.DIALOG_ANSWER_APPLY) {
066 presetHandler.updateTags(tag.getChangedTags());
067 }
068
069 }
070 public void mouseEntered(MouseEvent arg0) {
071 label.setFont(hover);
072 }
073 public void mouseExited(MouseEvent arg0) {
074 label.setFont(normal);
075 }
076 public void mousePressed(MouseEvent arg0) {}
077 public void mouseReleased(MouseEvent arg0) {}
078 }
079
080 public void updatePresets(final Collection<PresetType> types, final Map<String, String> tags, PresetHandler presetHandler) {
081
082 removeAll();
083 if (types.isEmpty()) {
084 setVisible(false);
085 return;
086 }
087
088 for (TaggingPreset t : TaggingPresetPreference.taggingPresets) {
089 if (!t.matches(types, tags, true)) {
090 continue;
091 }
092
093 JLabel lbl = new JLabel(t.getName() + " ???");
094 lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
095 lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
096 add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
097 }
098
099 if (getComponentCount() > 0) {
100 setVisible(true);
101 // This ensures the presets are exactly as high as needed.
102 int height = getComponentCount() * getComponent(0).getHeight();
103 Dimension size = new Dimension(getWidth(), height);
104 setMaximumSize(size);
105 setMinimumSize(size);
106 } else {
107 setVisible(false);
108 }
109 }
110 }