Ticket #22664: flexibilize-presets_v3.patch

File flexibilize-presets_v3.patch, 30.1 KB (added by anonymous, 22 months ago)
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java

     
    138138    public boolean preset_name_label;
    139139
    140140    /**
     141     * If menu items should be sorted
     142     */
     143    public String items_sort = "yes";
     144
     145    /**
    141146     * The types as preparsed collection.
    142147     */
    143148    public transient Set<TaggingPresetType> types;
     
    255260    }
    256261
    257262    /**
     263     * Called from the XML parser to set the sort option.
     264     * @param sort The sort value for the menu items.
     265     * @since 18619
     266     */
     267    public void setItems_sort(final String sort) {
     268        this.items_sort = sort;
     269    }
     270
     271    /**
    258272     * Called from the XML parser to set the icon.
    259273     * The loading task is performed in the background in order to speedup startup.
    260274     * @param iconName icon name
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetMenu.java

     
    120120     * Sorts the menu items using the translated item text
    121121     */
    122122    public void sortMenu() {
    123         TaggingPresetMenu.sortMenu(this.menu);
     123        TaggingPresetMenu.sortMenu(this.menu, TaggingPresets.SORT_MENU.get());
    124124    }
    125125
    126126    /**
    127127     * Sorts the menu items using the translated item text
    128128     * @param menu menu to sort
     129     * @param itemssort if menu should be sorted.
    129130     */
    130     public static void sortMenu(JMenu menu) {
     131    public static void sortMenu(JMenu menu, boolean itemssort) {
     132        Action a = menu.getAction();
     133
     134        boolean sort = itemssort;
     135
     136        if (a instanceof TaggingPreset) {
     137            sort = (sort && ((TaggingPreset) a).items_sort.equals("yes")) || ((TaggingPreset) a).items_sort.equals("always");
     138        }
     139
    131140        Component[] items = menu.getMenuComponents();
    132141        PresetTextComparator comp = new PresetTextComparator();
    133142        List<JMenuItem> sortarray = new ArrayList<>();
     
    135144        for (int i = 0; i < items.length; i++) {
    136145            Object item = items[i];
    137146            if (item instanceof JMenu) {
    138                 sortMenu((JMenu) item);
     147                sortMenu((JMenu) item, itemssort);
    139148            }
    140             if (item instanceof JMenuItem) {
    141                 sortarray.add((JMenuItem) item);
    142                 if (i == items.length-1) {
     149            if (sort) {
     150                if (item instanceof JMenuItem) {
     151                    sortarray.add((JMenuItem) item);
     152                    if (i == items.length-1) {
     153                        handleMenuItem(menu, comp, sortarray, lastSeparator);
     154                        sortarray = new ArrayList<>();
     155                        lastSeparator = 0;
     156                    }
     157                } else if (item instanceof JSeparator) {
    143158                    handleMenuItem(menu, comp, sortarray, lastSeparator);
    144159                    sortarray = new ArrayList<>();
    145                     lastSeparator = 0;
     160                    lastSeparator = i;
    146161                }
    147             } else if (item instanceof JSeparator) {
    148                 handleMenuItem(menu, comp, sortarray, lastSeparator);
    149                 sortarray = new ArrayList<>();
    150                 lastSeparator = i;
    151162            }
    152163        }
    153164    }
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReader.java

     
    3939import org.openstreetmap.josm.gui.tagging.presets.items.PresetListEntry;
    4040import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
    4141import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
     42import org.openstreetmap.josm.gui.tagging.presets.items.SelectGroup;
    4243import org.openstreetmap.josm.gui.tagging.presets.items.Space;
    4344import org.openstreetmap.josm.gui.tagging.presets.items.Text;
    4445import org.openstreetmap.josm.io.CachedFile;
     
    145146        parser.mapOnStart("roles", Roles.class);
    146147        parser.map("role", Role.class);
    147148        parser.mapBoth("checkgroup", CheckGroup.class);
     149        parser.mapBoth("selectgroup", SelectGroup.class);
    148150        parser.map("check", Check.class);
    149151        parser.map("combo", Combo.class);
    150152        parser.map("multiselect", MultiSelect.class);
     
    182184
    183185        /** to detect end of {@code <checkgroup>} */
    184186        CheckGroup lastcheckgroup = null;
     187        /** to detect end of {@code <selectgroup>} */
     188        SelectGroup lastselectgroup = null;
     189        int selectgroupcount = PresetListEntry.SELECT_GROUP_NONE;
    185190        /** to detect end of {@code <group>} */
    186191        TaggingPresetMenu lastmenu = null;
    187192        /** to detect end of reused {@code <group>} */
     
    302307                            all.getLast().data.add((TaggingPresetItem) o);
    303308                        }
    304309                    } else if (o instanceof PresetListEntry) {
    305                         listEntries.add((PresetListEntry) o);
     310                        PresetListEntry entry = (PresetListEntry) o;
     311
     312                        if(lastselectgroup != null) {
     313                            if(!lastselectgroup.exclusive) {
     314                                entry.select_group = selectgroupcount;
     315                            }
     316                            else {
     317                                entry.select_group = -selectgroupcount;
     318                            }
     319                        }
     320
     321                        listEntries.add(entry);
    306322                    } else if (o instanceof CheckGroup) {
    307323                        CheckGroup cg = (CheckGroup) o;
    308324                        if (cg == lastcheckgroup) {
     
    316332                        } else {
    317333                            lastcheckgroup = cg;
    318334                        }
     335                    } else if (o instanceof SelectGroup) {
     336                        SelectGroup sg = (SelectGroup) o;
     337                        if (sg == lastselectgroup) {
     338                            lastselectgroup = null;
     339                        } else {
     340                            lastselectgroup = sg;
     341                            selectgroupcount++;
     342                        }
    319343                    } else {
    320344                        if (!checks.isEmpty()) {
    321345                            all.getLast().data.addAll(checks);
     
    329353                        }
    330354                        listEntries.clear();
    331355                        lastrole = null;
     356                        selectgroupcount = PresetListEntry.SELECT_GROUP_NONE;
    332357                    }
    333358                } else
    334359                    throw new SAXException(tr("Preset sub element without parent"));
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java

     
    123123                }
    124124            }
    125125        }
    126         if (SORT_MENU.get()) {
    127             TaggingPresetMenu.sortMenu(presetsMenu);
    128         }
     126
     127        TaggingPresetMenu.sortMenu(presetsMenu, SORT_MENU.get());
     128
    129129        listeners.forEach(TaggingPresetListener::taggingPresetsModified);
    130130    }
    131131
  • src/org/openstreetmap/josm/gui/tagging/presets/items/Combo.java

     
    168168        combobox.setToolTipText(getKeyTooltipText());
    169169        combobox.applyComponentOrientation(OrientationAction.getValueOrientation(key));
    170170
    171         return true;
     171
     172        return isNeeded(usage);
    172173    }
    173174
     175
     176
    174177    /**
    175178     * Finds the PresetListEntry that matches value.
    176179     * <p>
  • src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java

     
    3535 * Abstract superclass for combo box and multi-select list types.
    3636 */
    3737public abstract class ComboMultiSelect extends KeyedItem {
    38 
     38    protected static final String VALUE_SORT_USER = "user";
    3939    /**
    4040     * A list of entries.
    4141     * The list has to be separated by commas (for the {@link Combo} box) or by the specified delimiter (for the {@link MultiSelect}).
     
    5353    /** Disabled internationalisation for value to avoid mistakes, see #11696 */
    5454    public boolean values_no_i18n; // NOSONAR
    5555    /** Whether to sort the values, defaults to true. */
    56     public boolean values_sort = true; // NOSONAR
     56    public String values_sort = String.valueOf(true); // NOSONAR
     57    /** Whether to show this combo in dialog only when it's needed.
     58     * It's needed when key doesn't exist or if current value is not in values */
     59    public boolean if_needed_only = false; // NOSONAR
    5760    /**
    5861     * A list of entries that is displayed to the user.
    5962     * Must be the same number and order of entries as {@link #values} and editable must be false or not specified.
     
    138141                // editor-ersatz of a readonly combobox. fixes #6157
    139142                l.setText(value.getListDisplay(width));
    140143            }
     144
    141145            if (value.getCount() > 0) {
    142146                l.setFont(l.getFont().deriveFont(Font.ITALIC + Font.BOLD));
    143147            }
     
    310314            addListEntry(e);
    311315        }
    312316
    313         if (values_sort && TaggingPresets.SORT_MENU.get()) {
     317        if (values_sort.equals(String.valueOf(true)) && TaggingPresets.SORT_MENU.get()) {
    314318            Collections.sort(presetListEntries, (a, b) -> AlphanumComparator.getInstance().compare(a.getDisplayValue(), b.getDisplayValue()));
    315319        }
    316320    }
     
    430434    public MatchType getDefaultMatch() {
    431435        return MatchType.NONE;
    432436    }
     437
     438    protected boolean isNeeded(Usage usage) {
     439        boolean result = !if_needed_only || usage.unused();
     440
     441        if (!result) {
     442            for (String v : usage.map.keySet()) {
     443                for (PresetListEntry p : presetListEntries) {
     444                    if (p.value.equals(v)) {
     445                        return false;
     446                    }
     447                }
     448            }
     449        }
     450
     451        return result;
     452    }
    433453}
  • src/org/openstreetmap/josm/gui/tagging/presets/items/Key.java

     
    77
    88import javax.swing.JPanel;
    99
     10import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1011import org.openstreetmap.josm.data.osm.Tag;
    1112import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
    1213
     
    1415 * Invisible type allowing to hardcode an OSM key/value from the preset definition.
    1516 */
    1617public class Key extends KeyedItem {
     18    private static final String VALUE_APPEND_ALWAYS = "always";
    1719
    1820    /** The hardcoded value for key */
    1921    public String value; // NOSONAR
    2022
     23    /** The hardcoded value for key appending existing value **/
     24    public String append_value;  // NOSONAR
     25
     26    /** The hardcoded delimiter to use for appending values **/
     27    public String delimiter = ";"; // NOSONAR
     28
     29    /** The hardcoded type of appending */
     30    public String append = null; // NOSONAR
     31
     32    /** The hardcoded prefix to use for setting value to empty key */
     33    public String prefix = null; // NOSONAR
     34
     35    private String useValue;
     36
    2137    @Override
    2238    public boolean addToPanel(JPanel p, TaggingPresetItemGuiSupport support) {
     39        if (prefix != null) {
     40            useValue = prefix + value;
     41        }
     42        else {
     43            useValue = value;
     44        }
     45
     46        // If append_value is present append also if append was not set
     47        if (append_value != null || append != null) {
     48            String toUse = append_value != null ? append_value : value;
     49
     50            Collection<OsmPrimitive> col = support.getSelected();
     51
     52            for (OsmPrimitive pr : col) {
     53                String currentValue = pr.get(key);
     54
     55                if (currentValue != null) {
     56                    useValue = currentValue;
     57
     58                    if ((append != null && append.equals(VALUE_APPEND_ALWAYS)) || !useValue.contains(toUse)) {
     59                        useValue += delimiter + toUse;
     60                    }
     61
     62                    break;
     63                }
     64            }
     65        }
     66
    2367        return false;
    2468    }
    2569
     
    3377     * @return the tag
    3478     */
    3579    public Tag asTag() {
    36         return new Tag(key, value);
     80        return new Tag(key, useValue != null ? useValue : value);
    3781    }
    3882
    3983    @Override
     
    4387
    4488    @Override
    4589    public Collection<String> getValues() {
    46         return Collections.singleton(value);
     90        return Collections.singleton(useValue != null ? useValue : value);
    4791    }
    4892
    4993    @Override
    5094    public String toString() {
    51         return "Key [key=" + key + ", value=" + value + ", text=" + text
    52                 + ", text_context=" + text_context + ", match=" + match
    53                 + ']';
     95        return "Key [key=" + key + ", value=" + value + ", value_append=" + append_value
     96                + ", text=" + text + ", text_context=" + text_context + ", match=" + match
     97                + ", delimiter=" + delimiter + ']';
    5498    }
    5599}
  • src/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelect.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
    46import java.awt.Dimension;
     7import java.awt.GridBagLayout;
    58import java.awt.Insets;
    69import java.awt.Rectangle;
    7 import java.util.stream.Collectors;
     10import java.awt.event.MouseAdapter;
     11import java.awt.event.MouseEvent;
     12import java.util.Collections;
     13import java.util.List;
     14import java.util.Objects;
    815
    916import javax.swing.DefaultListModel;
     17import javax.swing.DefaultListSelectionModel;
     18import javax.swing.JButton;
    1019import javax.swing.JLabel;
    1120import javax.swing.JList;
    1221import javax.swing.JPanel;
    1322import javax.swing.JScrollPane;
     23import javax.swing.ListModel;
     24import javax.swing.ListSelectionModel;
     25import javax.swing.event.ListSelectionEvent;
     26import javax.swing.event.ListSelectionListener;
    1427
    1528import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     29import org.openstreetmap.josm.gui.util.ReorderableTableModel;
    1630import org.openstreetmap.josm.gui.widgets.OrientationAction;
    1731import org.openstreetmap.josm.tools.GBC;
     32import org.openstreetmap.josm.tools.ImageProvider;
     33import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
    1834
    1935/**
    2036 * Multi-select list type.
    2137 */
    2238public class MultiSelect extends ComboMultiSelect {
    23 
    2439    /**
    2540     * Number of rows to display (positive integer, optional).
    2641     */
    2742    public short rows; // NOSONAR
    2843
    2944    /** The model for the JList */
    30     protected final DefaultListModel<PresetListEntry> model = new DefaultListModel<>();
     45    protected final PresetListModel model = new PresetListModel();
    3146    /** The swing component */
    3247    protected final JList<PresetListEntry> list = new JList<>(model);
    3348
     49    /**
     50     * Text that will be put in front of the resulting value.
     51     */
     52    public String prefix; // NOSONAR
     53
     54    /**
     55     * If the entries in the list should be selected with clicking only.
     56     */
     57    public boolean quick_select = false;
     58
     59    /**
     60     * Use selection model that selects/deselects values with single click.
     61     * @since 18619
     62     */
     63    public MultiSelect() {
     64        list.setSelectionModel(new SingleClickSelectionModel(list));
     65    }
     66
    3467    private void addEntry(PresetListEntry entry) {
     68        addEntry(entry, -1);
     69    }
     70
     71    private void addEntry(PresetListEntry entry, int presetCount) {
     72        if (prefix != null && entry.value.startsWith(prefix)) {
     73            entry.value = entry.value.substring(prefix.length());
     74        }
     75
    3576        if (!seenValues.containsKey(entry.value)) {
    36             model.addElement(entry);
    37             seenValues.put(entry.value, entry);
     77            boolean add = true;
     78
     79            for (int i = 0; i < model.size(); i++) {
     80                PresetListEntry test = model.get(i);
     81
     82                if (test.delimiter != null && entry.value.matches(".*\\\\{0}" + test.delimiter+".*")) {
     83                    add = false;
     84
     85                    String[] parts = entry.value.split(test.delimiter,-1);
     86
     87                    for (int j = 0; j < parts.length; j++) {
     88                        if (prefix != null && parts[j].startsWith(prefix)) {
     89                            parts[j] = parts[j].substring(prefix.length());
     90                        }
     91                        addEntry(new PresetListEntry(parts[j], this, j == 0 ? String.valueOf(delimiter) : test.delimiter), presetCount);
     92                    }
     93
     94                    break;
     95                }
     96            }
     97
     98            if (add) {
     99                if (presetCount == -1) {
     100                    model.addElement(entry);
     101                }
     102                else {
     103                    model.insertElementAt(entry, model.getSize() - presetCount);
     104                }
     105                seenValues.put(entry.value, entry);
     106            }
     107        }
     108    }
     109
     110    private void select(PresetListEntry entry) {
     111        for (int i = 0; i < model.getSize(); i++) {
     112            PresetListEntry test = model.get(i);
     113
     114            if (Objects.equals(test.value, entry.value)) {
     115                int[] indices = model.getSelectedIndices();
     116
     117                if (indices != null && indices.length > 0 && indices[indices.length - 1] > i) {
     118                    PresetListEntry removed = model.remove(i);
     119                    model.add(indices[indices.length-1], removed);
     120                    list.addSelectionInterval(indices[indices.length-1], indices[indices.length-1]);
     121                }
     122                else {
     123                    list.addSelectionInterval(i, i);
     124                }
     125
     126                if(usage != null && usage.map != null && !usage.map.containsKey(test.value)) {
     127                    usage.map.put(test.value, 1);
     128                }
     129
     130                break;
     131            }
     132            else if (test.delimiter != null && entry.value.matches(".*\\\\{0}" + test.delimiter+".*")) {
     133                for (String part : entry.value.split(test.delimiter, -1)) {
     134                    select(new PresetListEntry(part, this, test.delimiter));
     135                }
     136            }
    38137        }
    39138    }
    40139
     
    53152        // Add values from the preset.
    54153        presetListEntries.forEach(this::addEntry);
    55154
     155        int count = model.getSize();
     156
    56157        // Add all values used in the selected primitives. This also adds custom values and makes
    57158        // sure we won't lose them.
    58159        usage = usage.splitValues(String.valueOf(delimiter));
    59160        for (String value: usage.map.keySet()) {
    60             addEntry(new PresetListEntry(value, this));
     161            addEntry(new PresetListEntry(value, this), count);
    61162        }
    62163
    63164        // Select the values in the initial value.
    64165        if (!initialValue.isEmpty() && !DIFFERENT.equals(initialValue)) {
     166            if(prefix != null && initialValue.startsWith(prefix)) {
     167                initialValue = initialValue.substring(prefix.length());
     168            }
     169
    65170            for (String value : initialValue.split(String.valueOf(delimiter), -1)) {
    66171                PresetListEntry e = new PresetListEntry(value, this);
    67172                addEntry(e);
    68                 int i = model.indexOf(e);
    69                 list.addSelectionInterval(i, i);
     173                select(e);
    70174            }
    71175        }
     176        else if (default_ != null) {
     177            select(new PresetListEntry(default_, this));
     178        }
    72179
    73180        ComboMultiSelectListCellRenderer renderer = new ComboMultiSelectListCellRenderer(list, list.getCellRenderer(), 200, key);
    74181        list.setCellRenderer(renderer);
     
    89196                insets = sp.getInsets();
    90197                r.width += insets.left + insets.right;
    91198                r.height += insets.top + insets.bottom;
    92                 sp.setPreferredSize(new Dimension(r.width, r.height));
     199                sp.setPreferredSize(new Dimension(Math.max(r.width, sp.getPreferredSize().width), r.height));
    93200            }
    94201        }
    95         p.add(sp, GBC.eol().fill(GBC.HORIZONTAL)); // NOSONAR
     202
     203        if(values_sort.equals(VALUE_SORT_USER)) {
     204            final JButton up = new JButton(ImageProvider.get("dialogs", "up", ImageSizes.LARGEICON));
     205            up.setToolTipText(tr("Move the currently selected members up"));
     206            up.addActionListener(e -> {
     207                model.moveUp();
     208            });
     209            final JButton down = new JButton(ImageProvider.get("dialogs", "down", ImageSizes.LARGEICON));
     210            down.setToolTipText(tr("Move the currently selected members down"));
     211            down.addActionListener(e -> {
     212                model.moveDown();
     213            });
     214            up.setEnabled(model.canMoveUp());
     215            down.setEnabled(model.canMoveDown());
     216
     217            list.addListSelectionListener(new ListSelectionListener() {
     218                @Override
     219                public void valueChanged(ListSelectionEvent e) {
     220                    up.setEnabled(model.canMoveUp());
     221                    down.setEnabled(model.canMoveDown());
     222                }
     223            });
     224
     225            JPanel content = new JPanel(new GridBagLayout());
     226            content.add(sp, GBC.std(0,0).span(1, 4).fill());
     227            content.add(GBC.glue(0, 1), GBC.std(1, 0).fill(GBC.VERTICAL));
     228            content.add(up, GBC.std(1, 1));
     229            content.add(down, GBC.std(1, 2));
     230            content.add(GBC.glue(0, 1), GBC.std(1, 3).fill(GBC.VERTICAL));
     231
     232            p.add(content, GBC.eol().fill(GBC.HORIZONTAL)); // NOSONAR
     233        }
     234        else {
     235            p.add(sp, GBC.eol().fill(GBC.HORIZONTAL)); // NOSONAR
     236        }
    96237
    97238        list.addListSelectionListener(l -> support.fireItemValueModified(this, key, getSelectedItem().value));
    98239        list.setToolTipText(getKeyTooltipText());
     
    103244
    104245    @Override
    105246    protected PresetListEntry getSelectedItem() {
    106         return new PresetListEntry(list.getSelectedValuesList()
    107             .stream().map(e -> e.value).distinct().sorted().collect(Collectors.joining(String.valueOf(delimiter))), this);
     247         StringBuilder result = new StringBuilder();
     248         List<PresetListEntry> temp = list.getSelectedValuesList();
     249
     250         if (!temp.isEmpty()) {
     251             if (values_sort.equals(String.valueOf(true))) {
     252                 Collections.sort(temp);
     253             }
     254
     255             if (prefix != null) {
     256                 result.append(prefix);
     257             }
     258
     259             result.append(temp.get(0).value);
     260
     261             for (int i = 1; i < temp.size(); i++) {
     262                 if (result.indexOf(temp.get(i).value) == -1) {
     263                     result.append(temp.get(i).delimiter != null ? temp.get(i).delimiter : delimiter).append(temp.get(i).value);
     264                 }
     265             }
     266         }
     267
     268         return new PresetListEntry(result.toString(), this);
     269    }
     270
     271    private final class SingleClickSelectionModel extends DefaultListSelectionModel {
     272        private boolean mousePressed;
     273        private ListModel<PresetListEntry> model;
     274
     275        private SingleClickSelectionModel(JList<PresetListEntry> list) {
     276            this.model = list.getModel();
     277            list.addMouseListener(new MouseAdapter() {
     278                @Override
     279                public void mousePressed(MouseEvent e) {
     280                    mousePressed = true;
     281                }
     282                @Override
     283                public void mouseReleased(MouseEvent e) {
     284                    mousePressed = false;
     285                }
     286            });
     287        }
     288
     289        @Override
     290        public void addSelectionInterval(int index0, int index1) {
     291            removeSelectionForGroupAtIndex(index0);
     292            super.addSelectionInterval(index0, index1);
     293        }
     294
     295        private void removeSelectionForGroupAtIndex(int index) {
     296            if(!isSelectedIndex(index)) {
     297                int selectGroup = model.getElementAt(index).select_group;
     298
     299                for(int i = 0; i < model.getSize(); i++) {
     300                    if(isSelectedIndex(i) && (selectGroup < 0 || (model.getElementAt(i).select_group != PresetListEntry.SELECT_GROUP_NONE && model.getElementAt(i).select_group == selectGroup) || model.getElementAt(i).select_group < 0)) {
     301                        super.removeSelectionInterval(i, i);
     302                    }
     303                }
     304            }
     305        }
     306
     307        @Override
     308        public void setSelectionInterval(int index0, int index1) {
     309            if (quick_select && getSelectionMode() == MULTIPLE_INTERVAL_SELECTION) {
     310                if (!mousePressed) {
     311                    if (isSelectedIndex(index0)) {
     312                        super.removeSelectionInterval(index0, index1);
     313                    }
     314                    else {
     315                        removeSelectionForGroupAtIndex(index0);
     316                        super.addSelectionInterval(index0, index1);
     317                    }
     318                }
     319            }
     320            else {
     321                super.setSelectionInterval(index0, index1);
     322            }
     323        }
     324    }
     325
     326    private final class PresetListModel extends DefaultListModel<PresetListEntry> implements ReorderableTableModel<PresetListEntry> {
     327        @Override
     328        public PresetListEntry getValue(int index) {
     329            return get(index);
     330        }
     331
     332        @Override
     333        public PresetListEntry setValue(int index, PresetListEntry value) {
     334            return set(index, value);
     335        }
     336
     337        @Override
     338        public ListSelectionModel getSelectionModel() {
     339            return list.getSelectionModel();
     340        }
     341
     342        @Override
     343        public int getRowCount() {
     344            return size();
     345        }
    108346    }
    109347}
  • src/org/openstreetmap/josm/gui/tagging/presets/items/PresetListEntry.java

     
    2121 * {@link MultiSelect}.
    2222 */
    2323public class PresetListEntry implements Comparable<PresetListEntry> {
     24    /** Value for entries without a select group*/
     25    public static final int SELECT_GROUP_NONE = 0;
    2426    /** Used to display an entry matching several different values. */
    2527    protected static final PresetListEntry ENTRY_DIFFERENT = new PresetListEntry(KeyedItem.DIFFERENT, null);
    2628    /** Used to display an empty entry used to clear values. */
     
    4648    public String locale_display_value; // NOSONAR
    4749    /** The localized version of {@link #short_description}. */
    4850    public String locale_short_description; // NOSONAR
     51    /** The delimiter for separating this entry from the previous */
     52    public String delimiter; // NOSONAR
     53    /** The select group for multi select */
     54    public int select_group = SELECT_GROUP_NONE;
    4955
    5056    private String cachedDisplayValue;
    5157    private String cachedShortDescription;
    5258    private ImageIcon cachedIcon;
    5359
     60
    5461    /**
    5562     * Constructs a new {@code PresetListEntry}, uninitialized.
    5663     *
     
    6774     * @param cms the ComboMultiSelect
    6875     */
    6976    public PresetListEntry(String value, ComboMultiSelect cms) {
     77        this(value, cms, null);
     78    }
     79
     80    /**
     81     * Constructs a new {@code PresetListEntry}, initialized with a value and
     82     * {@link ComboMultiSelect} context and the delimiter for this entry.
     83     *
     84     * @param value value
     85     * @param cms the ComboMultiSelect
     86     * @param delimiter The character to use to separate this entry from the previous
     87     * @since 18619
     88     */
     89    public PresetListEntry(String value, ComboMultiSelect cms, String delimiter) {
    7090        this.value = value;
    7191        this.cms = cms;
     92        this.delimiter = delimiter;
    7293    }
    7394
    7495    /**
  • src/org/openstreetmap/josm/gui/tagging/presets/items/SelectGroup.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.tagging.presets.items;
     3
     4import java.util.List;
     5
     6import javax.swing.JPanel;
     7
     8import org.openstreetmap.josm.data.osm.Tag;
     9import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
     10import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11
     12/**
     13 * A group of {@link PresetListEntry}s.
     14 * @since 18637
     15 */
     16public class SelectGroup extends TaggingPresetItem {
     17    /** If items in this SelectGroup can only be selected when no item in the complete list is selected */
     18    public boolean exclusive = false;
     19
     20    @Override
     21    protected boolean addToPanel(JPanel p, TaggingPresetItemGuiSupport support) {
     22        // TODO Auto-generated method stub
     23        return false;
     24    }
     25
     26    @Override
     27    protected void addCommands(List<Tag> changedTags) {
     28        // TODO Auto-generated method stub
     29
     30    }
     31
     32}