Ticket #5933: 5933_v3.patch

File 5933_v3.patch, 28.9 KB (added by simon04, 7 years ago)
  • src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java b/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
    index 3c63305..fe03b79 100644
    a b import java.awt.event.MouseListener; 
    1010import java.awt.font.TextAttribute;
    1111import java.util.Collection;
    1212import java.util.Collections;
    13 import java.util.Hashtable;
    1413import java.util.List;
    1514import java.util.Map;
    1615
    import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    2322import org.openstreetmap.josm.data.osm.Tag;
    2423import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
    2524import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    26 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Check;
    27 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Combo;
    2825import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
    29 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Text;
    3026import org.openstreetmap.josm.tools.GBC;
    3127
    3228public class PresetListPanel extends JPanel {
    public class PresetListPanel extends JPanel { 
    8177        public void mouseReleased(MouseEvent arg0) {}
    8278    }
    8379
    84     public void updatePresets(int nodes, int ways, int relations, int closedways, Map<String, Map<String, Integer>> valueCount, PresetHandler presetHandler) {
     80    public void updatePresets(final Collection<PresetType> types, final Map<String, String> tags, PresetHandler presetHandler) {
    8581
    8682        removeAll();
    87         int total = nodes+ways+relations+closedways;
    88         if(total == 0) {
     83        if (types.isEmpty()) {
    8984            setVisible(false);
    9085            return;
    9186        }
    9287
    93         for(TaggingPreset t : TaggingPresetPreference.taggingPresets) {
    94             if(
    95                     (       t.types == null
    96                             || (relations > 0 && t.types.contains(PresetType.RELATION))
    97                             || (nodes > 0 && t.types.contains(PresetType.NODE))
    98                             || (ways+closedways > 0 && t.types.contains(PresetType.WAY))
    99                             || (closedways > 0 && t.types.contains(PresetType.CLOSEDWAY))
    100                     )
    101                     && t.isShowable())
    102             {
    103                 int found = 0;
    104                 for(TaggingPreset.Item i : t.data) {
    105                     if(i instanceof TaggingPreset.Key) {
    106                         String val = ((TaggingPreset.Key)i).value;
    107                         String key = ((TaggingPreset.Key)i).key;
    108                         // we subtract 100 if not found and add 1 if found
    109                         found -= 100;
    110                         if(key == null || !valueCount.containsKey(key)) {
    111                             continue;
    112                         }
    113 
    114                         Map<String, Integer> v = valueCount.get(key);
    115                         if(v.size() == 1 && val != null && v.containsKey(val) && v.get(val) == total) {
    116                             found += 101;
    117                         }
    118                     } else {
    119                         String key = null;
    120                         if ((i instanceof Text) && ((Text)i).required) {
    121                             key = ((Text)i).key;
    122                         } else if ((i instanceof Combo) && ((Combo)i).required) {
    123                             key = ((Combo)i).key;
    124                         } else if ((i instanceof Check) && ((Check)i).required) {
    125                             key = ((Check)i).key;
    126                         }
    127                         if (key != null) {
    128                             if (valueCount.get(key) != null) {
    129                                 found += 1;
    130                             } else {
    131                                 found -= 100;
    132                             }
    133                         }
    134                     }
    135                 }
    136 
    137                 if(found <= 0) {
    138                     continue;
    139                 }
    140 
    141                 JLabel lbl = new JLabel(t.getName() + " …");
    142                 lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
    143                 lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
    144                 add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
     88        for (TaggingPreset t : TaggingPresetPreference.taggingPresets) {
     89            if (!t.matches(types, tags)) {
     90                continue;
    14591            }
     92
     93            JLabel lbl = new JLabel(t.getName() + " …");
     94            lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
     95            lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
     96            add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
    14697        }
    14798
    148         if(getComponentCount() > 0) {
     99        if (getComponentCount() > 0) {
    149100            setVisible(true);
    150101            // This ensures the presets are exactly as high as needed.
    151102            int height = getComponentCount() * getComponent(0).getHeight();
    public class PresetListPanel extends JPanel { 
    156107            setVisible(false);
    157108        }
    158109    }
    159 
    160110}
  • src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java b/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
    index 05a700e..5a9bca9 100644
    a b import java.util.Arrays; 
    3030import java.util.Collection;
    3131import java.util.Collections;
    3232import java.util.Comparator;
     33import java.util.EnumSet;
    3334import java.util.HashMap;
    3435import java.util.HashSet;
    3536import java.util.Iterator;
    import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask; 
    103104import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
    104105import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    105106import org.openstreetmap.josm.gui.tagging.TaggingPreset;
     107import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
    106108import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
    107109import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
    108110import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
    public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi 
    260262                Component c = super.getListCellRendererComponent(list, value,
    261263                        index, isSelected, cellHasFocus);
    262264                if (c instanceof JLabel) {
    263                     String str = null;
    264                     str=((AutoCompletionListItem) value).getValue();
    265                     if (valueCount.containsKey(objKey)){
    266                         Map<String, Integer> m=valueCount.get(objKey);
     265                    String str = ((AutoCompletionListItem) value).getValue();
     266                    if (valueCount.containsKey(objKey)) {
     267                        Map<String, Integer> m = valueCount.get(objKey);
    267268                        if (m.containsKey(str)) {
    268                             str+="("+m.get(str)+")";
    269                             c.setFont(c.getFont().deriveFont(Font.ITALIC+Font.BOLD));
     269                            str = tr("{0} ({1})", str, m.get(str));
     270                            c.setFont(c.getFont().deriveFont(Font.ITALIC + Font.BOLD));
    270271                        }
    271272                    }
    272                     ((JLabel)c).setText(str);
     273                    ((JLabel) c).setText(str);
    273274                }
    274275                return c;
    275276            }
    public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi 
    946947
    947948        // re-load property data
    948949        propertyData.setRowCount(0);
    949         int nodes = 0;
    950         int ways = 0;
    951         int relations = 0;
    952         int closedways = 0;
    953950
    954         Map<String, Integer> keyCount = new HashMap<String, Integer>();
     951        final Map<String, Integer> keyCount = new HashMap<String, Integer>();
     952        final Map<String, String> tags = new HashMap<String, String>();
    955953        valueCount.clear();
     954        EnumSet<PresetType> types = EnumSet.noneOf(TaggingPreset.PresetType.class);
    956955        for (OsmPrimitive osm : newSelection) {
    957             if(osm instanceof Node) {
    958                 ++nodes;
    959             } else if(osm instanceof Relation) {
    960                 ++relations;
    961             } else if(((Way)osm).isClosed()) {
    962                 ++closedways;
    963             } else {
    964                 ++ways;
    965             }
    966             for (String key: osm.keySet()) {
     956            types.add(PresetType.forPrimitive(osm));
     957            for (String key : osm.keySet()) {
    967958                String value = osm.get(key);
    968959                keyCount.put(key, keyCount.containsKey(key) ? keyCount.get(key) + 1 : 1);
    969960                if (valueCount.containsKey(key)) {
    970961                    Map<String, Integer> v = valueCount.get(key);
    971                     v.put(value, v.containsKey(value)? v.get(value) + 1 : 1 );
     962                    v.put(value, v.containsKey(value) ? v.get(value) + 1 : 1);
    972963                } else {
    973                     TreeMap<String,Integer> v = new TreeMap<String, Integer>();
     964                    TreeMap<String, Integer> v = new TreeMap<String, Integer>();
    974965                    v.put(value, 1);
    975966                    valueCount.put(key, v);
    976967                }
    977968            }
    978969        }
    979970        for (Entry<String, Map<String, Integer>> e : valueCount.entrySet()) {
    980             int count=0;
    981             for (Entry<String, Integer> e1: e.getValue().entrySet()) {
    982                 count+=e1.getValue();
     971            int count = 0;
     972            for (Entry<String, Integer> e1 : e.getValue().entrySet()) {
     973                count += e1.getValue();
    983974            }
    984975            if (count < newSelection.size()) {
    985                 e.getValue().put("", newSelection.size()-count);
     976                e.getValue().put("", newSelection.size() - count);
    986977            }
    987978            propertyData.addRow(new Object[]{e.getKey(), e.getValue()});
     979            tags.put(e.getKey(), e.getValue().size() == 1
     980                    ? e.getValue().keySet().iterator().next() : tr("<different>"));
    988981        }
    989982
    990983        membershipData.setRowCount(0);
    public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi 
    10251018            membershipData.addRow(new Object[]{r, roles.get(r)});
    10261019        }
    10271020
    1028         presets.updatePresets(nodes, ways, relations, closedways, valueCount, presetHandler);
     1021        presets.updatePresets(types, tags, presetHandler);
    10291022
    10301023        membershipTable.getTableHeader().setVisible(membershipData.getRowCount() > 0);
    10311024        membershipTable.setVisible(membershipData.getRowCount() > 0);
  • src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java

    diff --git a/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java b/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java
    index 55fc577..65fbc8e 100644
    a b import java.awt.BorderLayout; 
    55import java.awt.GridBagConstraints;
    66import java.awt.GridBagLayout;
    77import java.awt.Insets;
    8 import java.util.HashMap;
    9 import java.util.Map;
    10 import java.util.Map.Entry;
     8import java.util.EnumSet;
    119
    1210import javax.swing.BoxLayout;
    1311import javax.swing.JButton;
    public class TagEditorPanel extends JPanel { 
    180178    }
    181179
    182180    private void updatePresets() {
    183         Map<String, Map<String, Integer>> valuesCount = new HashMap<String, Map<String,Integer>>();
    184         for (Entry<String, String> entry: model.getTags().entrySet()) {
    185             Map<String, Integer> values = new HashMap<String, Integer>();
    186             values.put(entry.getValue(), 1);
    187             valuesCount.put(entry.getKey(), values);
    188         }
    189         presetListPanel.updatePresets(0, 0, 1, 0, valuesCount, presetHandler);
     181        presetListPanel.updatePresets(
     182                EnumSet.of(TaggingPreset.PresetType.RELATION),
     183                model.getTags(), presetHandler);
    190184        validate();
    191185    }
    192186}
  • src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java

    diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
    index 5d23549..bd40aac 100644
    a b public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    107107        public String getName() {
    108108            return name().toLowerCase();
    109109        }
     110
     111        public static PresetType forPrimitive(OsmPrimitive p) {
     112            return forPrimitiveType(p.getDisplayType());
     113        }
     114
     115        public static PresetType forPrimitiveType(org.openstreetmap.josm.data.osm.OsmPrimitiveType type) {
     116            switch (type) {
     117                case NODE:
     118                    return NODE;
     119                case WAY:
     120                    return WAY;
     121                case CLOSEDWAY:
     122                    return CLOSEDWAY;
     123                case RELATION:
     124                    return RELATION;
     125                default:
     126                    throw new IllegalArgumentException();
     127            }
     128        }
     129    }
     130
     131    /**
     132     * Enum denoting the way how a match (see {@link Item#matches}) is performed.
     133     */
     134    private enum MatchType {
     135
     136        /**
     137         * Neutral, i.e., o not consider this item for matching.
     138         */
     139        NONE("none"), /**
     140         * Positive if key matches, neutral otherwise.
     141         */
     142        KEY("key"),
     143        /**
     144         * Positive if key matches, negative otherwise.
     145         */
     146        KEY_REQUIRED("key!"),
     147        /**
     148         * Positive if key and value matches, negative otherwise.
     149         */
     150        KEY_VALUE("keyvalue");
     151        private final String value;
     152
     153        private MatchType(String value) {
     154            this.value = value;
     155        }
     156
     157        public String getValue() {
     158            return value;
     159        }
     160
     161        public static MatchType ofString(String type) {
     162            for (MatchType i : EnumSet.allOf(MatchType.class)) {
     163                if (i.getValue().equals(type)) {
     164                    return i;
     165                }
     166            }
     167            throw new IllegalArgumentException(type + " is not allowed");
     168        }
    110169    }
    111170
    112171    public static final int DIALOG_ANSWER_APPLY = 1;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    139198        boolean requestFocusInWindow() {
    140199            return false;
    141200        }
     201
     202        /**
     203         * Tests whether the tags match this item.
     204         * @param tags the tags of an {@link OsmPrimitive}
     205         * @return {@code true} if matches (positive), {@code null} if neutral, {@code false} if mismatches (negative).
     206         */
     207        abstract Boolean matches(Map<String, String> tags);
    142208    }
    143209
    144210    public static class Usage {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    244310        public String text;
    245311        public String locale_text;
    246312        public String text_context;
    247         public String default_;
     313        public String default_ = "";
    248314        public String originalValue;
    249315        public String use_last_as_default = "false";
    250         public boolean delete_if_empty = false;
    251         public boolean required = false;
     316        public String match = MatchType.NONE.getValue();
    252317
    253318        private JComponent value;
    254319
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    315380                    if (v.equals(originalValue) || (originalValue == null && v.length() == 0))
    316381                        return;
    317382
    318                     if (delete_if_empty && v.length() == 0) {
    319                         v = null;
    320                     }
    321383                    changedTags.add(new Tag(key, v));
    322384        }
    323385
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    325387        boolean requestFocusInWindow() {
    326388            return value.requestFocusInWindow();
    327389        }
     390
     391        @Override
     392        Boolean matches(Map<String, String> tags) {
     393            switch (MatchType.ofString(match)) {
     394                case NONE:
     395                    return null;
     396                case KEY:
     397                    return tags.containsKey(key) ? true : null;
     398                case KEY_REQUIRED:
     399                    return tags.containsKey(key);
     400                default:
     401                    throw new IllegalArgumentException("key_value matching not supported for <text>: " + text);
     402            }
     403        }
    328404    }
    329405
    330406    public static class Check extends Item {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    336412        public String value_on = OsmUtils.trueval;
    337413        public String value_off = OsmUtils.falseval;
    338414        public boolean default_ = false; // only used for tagless objects
    339         public boolean required = false;
     415        public String match = MatchType.NONE.getValue();
    340416
    341417        private QuadStateCheckBox check;
    342418        private QuadStateCheckBox.State initialState;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    410486                            null));
    411487        }
    412488        @Override boolean requestFocusInWindow() {return check.requestFocusInWindow();}
     489
     490        @Override
     491        Boolean matches(Map<String, String> tags) {
     492            switch (MatchType.ofString(match)) {
     493                case NONE:
     494                    return null;
     495                case KEY:
     496                    return tags.containsKey(key) ? true : null;
     497                case KEY_REQUIRED:
     498                    return tags.containsKey(key);
     499                case KEY_VALUE:
     500                    return value_off.equals(tags.get(key)) || value_on.equals(tags.get(key));
     501                default:
     502                    throw new IllegalStateException();
     503            }
     504        }
    413505    }
    414506
    415507    public static abstract class ComboMultiSelect extends Item {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    426518        public String locale_short_descriptions;
    427519        public String default_;
    428520        public String delimiter = ";";
    429         public boolean delete_if_empty = false;
    430521        public String use_last_as_default = "false";
    431         public boolean required = false;
     522        public String match = MatchType.NONE.getValue();
    432523
    433524        protected List<String> short_description_list;
    434525        protected JComponent component;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    439530        protected abstract Object getSelectedItem();
    440531        protected abstract void addToPanelAnchor(JPanel p, String def, String[] display_array);
    441532
     533        protected char getDelChar() {
     534            return delimiter.isEmpty() ? ';' : delimiter.charAt(0);
     535        }
     536
    442537        @Override
    443538        public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
    444539
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    446541            usage = determineTextUsage(sel, key);
    447542            String def = default_;
    448543
    449             char delChar = ';';
    450             if (!delimiter.isEmpty()) {
    451                 delChar = delimiter.charAt(0);
    452             }
     544            char delChar = getDelChar();
    453545
    454546            String[] value_array = splitEscaped(delChar, values);
    455547            String[] display_array;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    551643            } else if (value.equals(originalValue.toString()))
    552644                return;
    553645
    554             if (delete_if_empty && value.length() == 0) {
    555                 value = null;
    556             }
    557646            if (!"false".equals(use_last_as_default)) {
    558647                lastValue.put(key, value);
    559648            }
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    607696                }
    608697            };
    609698        }
     699
     700        @Override
     701        Boolean matches(Map<String, String> tags) {
     702            switch (MatchType.ofString(match)) {
     703                case NONE:
     704                    return null;
     705                case KEY:
     706                    return tags.containsKey(key) ? true : null;
     707                case KEY_REQUIRED:
     708                    return tags.containsKey(key);
     709                case KEY_VALUE:
     710                    return tags.containsKey(key)
     711                            && Arrays.asList(splitEscaped(getDelChar(), values)).contains(tags.get(key));
     712                default:
     713                    throw new IllegalStateException();
     714            }
     715        }
    610716    }
    611717
    612718    public static class Combo extends ComboMultiSelect {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    827933        @Override
    828934        public void addCommands(List<Tag> changedTags) {
    829935        }
     936
     937        @Override
     938        Boolean matches(Map<String, String> tags) {
     939            return null;
     940        }
    830941    }
    831942
    832943    public static class Link extends Item {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    861972        @Override
    862973        public void addCommands(List<Tag> changedTags) {
    863974        }
     975
     976        @Override
     977        Boolean matches(Map<String, String> tags) {
     978            return null;
     979        }
    864980    }
    865981
    866982    public static class Role {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    870986        public String text_context;
    871987        public String locale_text;
    872988
    873         public boolean required=false;
     989        public boolean required = false;
    874990        public long count = 0;
    875991
    876992        public void setType(String types) throws SAXException {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    9551071        @Override
    9561072        public void addCommands(List<Tag> changedTags) {
    9571073        }
     1074
     1075        @Override
     1076        Boolean matches(Map<String, String> tags) {
     1077            return null;
     1078        }
    9581079    }
    9591080
    9601081    public static class Optional extends Item {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    9711092        @Override
    9721093        public void addCommands(List<Tag> changedTags) {
    9731094        }
     1095
     1096        @Override
     1097        Boolean matches(Map<String, String> tags) {
     1098            return null;
     1099        }
    9741100    }
    9751101
    9761102    public static class Space extends Item {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    9841110        @Override
    9851111        public void addCommands(List<Tag> changedTags) {
    9861112        }
     1113
     1114        @Override
     1115        Boolean matches(Map<String, String> tags) {
     1116            return null;
     1117        }
    9871118    }
    9881119
    9891120    public static class Key extends Item {
    9901121
    9911122        public String key;
    9921123        public String value;
     1124        public String match = MatchType.KEY_VALUE.getValue();
    9931125
    9941126        @Override
    9951127        public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    10001132        public void addCommands(List<Tag> changedTags) {
    10011133            changedTags.add(new Tag(key, value));
    10021134        }
     1135
     1136        @Override
     1137        Boolean matches(Map<String, String> tags) {
     1138            switch (MatchType.ofString(match)) {
     1139                case NONE:
     1140                    return null;
     1141                case KEY:
     1142                    return tags.containsKey(key) ? true : null;
     1143                case KEY_REQUIRED:
     1144                    return tags.containsKey(key);
     1145                case KEY_VALUE:
     1146                    return value.equals(tags.get(key));
     1147                default:
     1148                    throw new IllegalStateException();
     1149            }
     1150        }
    10031151    }
    10041152
    10051153    /**
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange 
    14851633    public String toString() {
    14861634        return (types == null?"":types) + " " + name;
    14871635    }
     1636
     1637    public boolean matches(Collection<PresetType> t, Map<String, String> tags) {
     1638        if (!isShowable()) {
     1639            return false;
     1640        } else if (t != null && types != null && !types.containsAll(t)) {
     1641            return false;
     1642        }
     1643        boolean atLeastOnePositiveMatch = false;
     1644        for (Item item : data) {
     1645            Boolean m = item.matches(tags);
     1646            if (m != null && !m) {
     1647                return false;
     1648            } else if (m != null) {
     1649                atLeastOnePositiveMatch = true;
     1650            }
     1651        }
     1652        return atLeastOnePositiveMatch;
     1653    }
    14881654}
  • src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java

    diff --git a/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java b/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java
    index 6792206..c9e252a 100644
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.tools;
    33
    4 import java.util.ArrayList;
     4import java.util.EnumSet;
     5import java.util.LinkedList;
    56import java.util.List;
    67
    78import org.openstreetmap.josm.data.osm.OsmPrimitive;
    8 import org.openstreetmap.josm.data.osm.Way;
    99import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
    1010import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    11 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Check;
    12 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Combo;
    1311import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
    14 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Text;
    1512
    1613/**
    1714 * List of tagging presets with name templates, allows to find appropriate template based on existing primitive
    public class TaggingPresetNameTemplateList { 
    2623        }
    2724        return instance;
    2825    }
    29 
    30     private final List<TaggingPreset> presetsWithPattern = new ArrayList<TaggingPreset>();
     26    private final List<TaggingPreset> presetsWithPattern = new LinkedList<TaggingPreset>();
    3127
    3228    private TaggingPresetNameTemplateList() {
    3329        if (TaggingPresetPreference.taggingPresets != null) {
    34             for (TaggingPreset tp: TaggingPresetPreference.taggingPresets) {
     30            for (TaggingPreset tp : TaggingPresetPreference.taggingPresets) {
    3531                if (tp.nameTemplate != null) {
    3632                    presetsWithPattern.add(tp);
    3733                }
    public class TaggingPresetNameTemplateList { 
    4137
    4238    public TaggingPreset findPresetTemplate(OsmPrimitive primitive) {
    4339
    44         PresetType presetType;
    45         switch (primitive.getType()) {
    46         case NODE:
    47             presetType = PresetType.NODE;
    48             break;
    49         case WAY:
    50             if (((Way) primitive).isClosed()) {
    51                 presetType = PresetType.CLOSEDWAY;
    52             } else {
    53                 presetType = PresetType.WAY;
     40        for (TaggingPreset t : presetsWithPattern) {
     41            if (t.matches(EnumSet.of(PresetType.forPrimitive(primitive)), primitive.getKeys())) {
     42                return t;
    5443            }
    55             break;
    56         case RELATION:
    57             presetType = PresetType.RELATION;
    58             break;
    59         default:
    60             throw new AssertionError();
    6144        }
    62 
    63         for(TaggingPreset t : presetsWithPattern) {
    64 
    65 
    66             if (       t.types == null
    67                     || t.types.contains(presetType)
    68                     || (presetType == PresetType.CLOSEDWAY && t.types.contains(PresetType.WAY))) {
    69                 int found = 0;
    70 
    71                 if (t.nameTemplateFilter != null) {
    72                     if (t.nameTemplateFilter.match(primitive))
    73                         return t;
    74                     else {
    75                         continue;
    76                     }
    77                 }
    78 
    79                 for(TaggingPreset.Item i : t.data) {
    80                     if(i instanceof TaggingPreset.Key) {
    81                         String val = ((TaggingPreset.Key)i).value;
    82                         String key = ((TaggingPreset.Key)i).key;
    83                         // we subtract 100 if not found and add 1 if found
    84                         if (val != null && val.equals(primitive.get(key))) {
    85                             found+=1;
    86                         } else {
    87                             found-=100;
    88                         }
    89                     } else {
    90                         String key = null;
    91                         if ((i instanceof Text) && ((Text)i).required) {
    92                             key = ((Text)i).key;
    93                         } else if ((i instanceof Combo) && ((Combo)i).required) {
    94                             key = ((Combo)i).key;
    95                         } else if ((i instanceof Check) && ((Check)i).required) {
    96                             key = ((Check)i).key;
    97                         }
    98                         if (key != null) {
    99                             if (primitive.get(key) != null) {
    100                                 found += 1;
    101                             } else {
    102                                 found -= 100;
    103                             }
    104                         }
    105                     }
    106                 }
    107 
    108                 if(found > 0)
    109                     return t; // First matching preset wins
    110             }
    111         }
    112 
    11345        return null;
    114 
    11546    }
    116 
    117 
    11847}