001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.properties; 003 004import java.awt.Cursor; 005import java.awt.Dimension; 006import java.awt.Font; 007import java.awt.GridBagLayout; 008import java.awt.event.MouseEvent; 009import java.awt.event.MouseListener; 010import java.awt.font.TextAttribute; 011import java.util.Collection; 012import java.util.Collections; 013import java.util.List; 014import java.util.Map; 015 016import javax.swing.Action; 017import javax.swing.Icon; 018import javax.swing.JLabel; 019import javax.swing.JPanel; 020 021import org.openstreetmap.josm.data.osm.OsmPrimitive; 022import org.openstreetmap.josm.data.osm.Tag; 023import org.openstreetmap.josm.gui.tagging.TaggingPreset; 024import org.openstreetmap.josm.gui.tagging.TaggingPresetType; 025import org.openstreetmap.josm.tools.GBC; 026 027public class PresetListPanel extends JPanel { 028 029 public PresetListPanel() { 030 super(new GridBagLayout()); 031 } 032 033 public interface PresetHandler { 034 Collection<OsmPrimitive> getSelection(); 035 void updateTags(List<Tag> tags); 036 } 037 038 /** 039 * Small helper class that manages the highlighting of the label on hover as well as opening 040 * the corresponding preset when clicked 041 */ 042 private static class PresetLabelML implements MouseListener { 043 final JLabel label; 044 final Font hover; 045 final Font normal; 046 final TaggingPreset tag; 047 final PresetHandler presetHandler; 048 049 PresetLabelML(JLabel lbl, TaggingPreset t, PresetHandler presetHandler) { 050 super(); 051 label = lbl; 052 lbl.setCursor(new Cursor(Cursor.HAND_CURSOR)); 053 normal = label.getFont(); 054 hover = normal.deriveFont(Collections.singletonMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DOTTED)); 055 tag = t; 056 this.presetHandler = presetHandler; 057 } 058 @Override 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 @Override 071 public void mouseEntered(MouseEvent arg0) { 072 label.setFont(hover); 073 } 074 @Override 075 public void mouseExited(MouseEvent arg0) { 076 label.setFont(normal); 077 } 078 @Override 079 public void mousePressed(MouseEvent arg0) {} 080 @Override 081 public void mouseReleased(MouseEvent arg0) {} 082 } 083 084 public void updatePresets(final Collection<TaggingPresetType> types, final Map<String, String> tags, PresetHandler presetHandler) { 085 086 removeAll(); 087 if (types.isEmpty()) { 088 setVisible(false); 089 return; 090 } 091 092 for (TaggingPreset t : TaggingPreset.getMatchingPresets(types, tags, true)) { 093 JLabel lbl = new JLabel(t.getName() + " …"); 094 lbl.setIcon(t.getIcon()); 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}