001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.properties;
003
004import java.awt.Dimension;
005import java.awt.GridBagLayout;
006import java.awt.event.MouseAdapter;
007import java.awt.event.MouseEvent;
008import java.util.Collection;
009import java.util.Map;
010
011import javax.swing.JLabel;
012import javax.swing.JPanel;
013
014import org.openstreetmap.josm.data.osm.DataSet;
015import org.openstreetmap.josm.data.osm.OsmPrimitive;
016import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
017import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetHandler;
018import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetLabel;
019import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType;
020import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
021import org.openstreetmap.josm.tools.GBC;
022
023/**
024 * A list of matching presets for a set of tags.
025 */
026public class PresetListPanel extends JPanel {
027
028    static final class LabelMouseAdapter extends MouseAdapter {
029        private final TaggingPreset t;
030        private final TaggingPresetHandler presetHandler;
031
032        LabelMouseAdapter(TaggingPreset t, TaggingPresetHandler presetHandler) {
033            this.t = t;
034            this.presetHandler = presetHandler;
035        }
036
037        @Override
038        public void mouseClicked(MouseEvent e) {
039            Collection<OsmPrimitive> selection = t.createSelection(presetHandler.getSelection());
040            if (selection.isEmpty())
041                return;
042            int answer = t.showDialog(selection, false);
043            DataSet ds = selection.iterator().next().getDataSet();
044            boolean locked = ds != null && ds.isLocked();
045
046            if (answer == TaggingPreset.DIALOG_ANSWER_APPLY && !locked) {
047                presetHandler.updateTags(t.getChangedTags());
048            }
049        }
050    }
051
052    /**
053     * Constructs a new {@code PresetListPanel}.
054     */
055    public PresetListPanel() {
056        super(new GridBagLayout());
057    }
058
059    /**
060     * Updates the preset list based on the {@code tags} and {@code types},
061     * and associates an interaction with (matching) presets via {@code presetHandler}.
062     * @param types collection of tagging presets types
063     * @param tags collection of tags
064     * @param presetHandler tagging preset handler
065     */
066    public void updatePresets(final Collection<TaggingPresetType> types, final Map<String, String> tags,
067            final TaggingPresetHandler presetHandler) {
068
069        removeAll();
070        if (types.isEmpty()) {
071            setVisible(false);
072            return;
073        }
074
075        for (final TaggingPreset t : TaggingPresets.getMatchingPresets(types, tags, true)) {
076            final JLabel lbl = new TaggingPresetLabel(t);
077            lbl.addMouseListener(new LabelMouseAdapter(t, presetHandler));
078            add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
079        }
080
081        if (getComponentCount() > 0) {
082            setVisible(true);
083            // This ensures the presets are exactly as high as needed.
084            int height = getComponentCount() * getComponent(0).getHeight();
085            Dimension size = new Dimension(getWidth(), height);
086            setMaximumSize(size);
087            setMinimumSize(size);
088        } else {
089            setVisible(false);
090        }
091    }
092}