Ignore:
Timestamp:
2021-10-07T13:07:57+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #21408 - Fixes vanishing icons, and scrollpane size if icons have different sizes. Also disables multiselect if the selected primitives have different values (patch by marcello)

Location:
trunk/src/org/openstreetmap/josm/gui/tagging/presets
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItemGuiSupport.java

    r18254 r18257  
    3131
    3232    /** whether to fire events or not */
    33     private boolean enabled = false;
     33    private boolean enabled;
    3434
    3535    /**
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/Combo.java

    r18254 r18257  
    1313import java.util.Arrays;
    1414import java.util.Comparator;
    15 import java.util.TreeMap;
    1615
    1716import javax.swing.AbstractAction;
     
    8988        initializeLocaleText(null);
    9089        usage = determineTextUsage(support.getSelected(), key);
    91         seenValues = new TreeMap<>();
     90        seenValues.clear();
    9291        // get the standard values from the preset definition
    9392        initListEntries();
    9493
    9594        // init the model
    96         dropDownModel = new AutoCompComboBoxModel<PresetListEntry>(Comparator.naturalOrder());
     95        dropDownModel = new AutoCompComboBoxModel<>(Comparator.<PresetListEntry>naturalOrder());
    9796
    9897        if (!usage.hasUniqueValue() && !usage.unused()) {
     
    125124        combobox.setEditable(editable);
    126125
    127         autoCompModel = new AutoCompComboBoxModel<AutoCompletionItem>(Comparator.naturalOrder());
     126        autoCompModel = new AutoCompComboBoxModel<>(Comparator.<AutoCompletionItem>naturalOrder());
    128127        getAllForKeys(Arrays.asList(key)).forEach(autoCompModel::addElement);
    129128        getDisplayValues().forEach(s -> autoCompModel.addElement(new AutoCompletionItem(s, AutoCompletionPriority.IS_IN_STANDARD)));
     
    155154        }
    156155
    157         String valueToSelect = getInitialValue(default_);
     156        String valueToSelect = getInitialValue(usage);
    158157        if (valueToSelect != null) {
    159158            PresetListEntry selItem = find(valueToSelect);
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java

    r18254 r18257  
    55
    66import java.awt.Component;
     7import java.awt.Font;
    78import java.lang.reflect.Method;
    89import java.lang.reflect.Modifier;
     
    9192    protected final List<PresetListEntry> presetListEntries = new ArrayList<>();
    9293    /** Helps avoid duplicate list entries */
    93     protected Map<String, PresetListEntry> seenValues = new TreeMap<>();
     94    protected final Map<String, PresetListEntry> seenValues = new TreeMap<>();
    9495    protected Usage usage;
    9596    /** Used to see if the user edited the value. May be null. */
     
    131132
    132133            JLabel l = (JLabel) renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     134            l.setComponentOrientation(component.getComponentOrientation());
    133135            if (index != -1) {
    134136                // index -1 is set when measuring the size of the cell and when painting the
     
    136138                l.setText(value.getListDisplay(width));
    137139            }
     140            if (value.getCount() > 0) {
     141                l.setFont(l.getFont().deriveFont(Font.ITALIC + Font.BOLD));
     142            }
     143            l.setIcon(value.getIcon());
    138144            l.setToolTipText(value.getToolTipText(key));
    139             l.setIcon(value.getIcon());
    140145            return l;
    141146        }
     
    221226    }
    222227
    223     private List<String> getValuesFromCode(String values_from) {
     228    private List<String> getValuesFromCode(String valuesFrom) {
    224229        // get the values from a Java function
    225         String[] classMethod = values_from.split("#", -1);
     230        String[] classMethod = valuesFrom.split("#", -1);
    226231        if (classMethod.length == 2) {
    227232            try {
     
    315320     * The initial value is the value shown in the control when the preset dialogs opens.
    316321     *
    317      * @param def The default value
     322     * @param usage The key Usage
    318323     * @return The initial value to use.
    319324     */
    320     protected String getInitialValue(String def) {
     325    protected String getInitialValue(Usage usage) {
    321326        String initialValue = null;
     327        originalValue = null;
    322328
    323329        if (usage.hasUniqueValue()) {
    324330            // all selected primitives have the same not empty value for this key
    325331            initialValue = usage.getFirst();
     332            originalValue = initialValue;
    326333        } else if (!usage.unused()) {
    327334            // at least one primitive has a value for this key (but not all have the same one)
    328335            initialValue = DIFFERENT;
     336            originalValue = initialValue;
    329337        } else if (PROP_FILL_DEFAULT.get() || isForceUseLastAsDefault()) {
    330338            // at this point no primitive had any value for this key
     
    336344        } else if (!usage.hadKeys()) {
    337345            // use the default only on objects with no keys at all
    338             initialValue = def;
    339         }
    340         originalValue = initialValue;
     346            initialValue = default_;
     347        }
    341348        return initialValue;
    342349    }
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/KeyedItem.java

    r18254 r18257  
    107107        private boolean hadKeys;
    108108        private boolean hadEmpty;
     109        private int selectedCount;
    109110
    110111        /**
     
    139140        public boolean hadKeys() {
    140141            return hadKeys;
     142        }
     143
     144        /**
     145         * Returns the number of primitives selected.
     146         * @return the number of primitives selected.
     147         */
     148        public int getSelectedCount() {
     149            return selectedCount;
     150        }
     151
     152        /**
     153         * Splits multiple values and adds their usage counts as single value.
     154         * <p>
     155         * A value of {@code regional;pizza} will increment the count of {@code regional} and of
     156         * {@code pizza}.
     157         * @param delimiter The delimiter used for splitting.
     158         * @return A new usage object with the new counts.
     159         */
     160        public Usage splitValues(String delimiter) {
     161            Usage usage = new Usage();
     162            usage.hadEmpty = hadEmpty;
     163            usage.hadKeys = hadKeys;
     164            usage.selectedCount = selectedCount;
     165            map.forEach((value, count) -> {
     166                for (String v : value.split(String.valueOf(delimiter), -1)) {
     167                    usage.map.merge(v, count, Integer::sum);
     168                }
     169            });
     170            return usage;
    141171        }
    142172    }
     
    150180    public static Usage determineTextUsage(Collection<OsmPrimitive> sel, String key) {
    151181        Usage returnValue = new Usage();
     182        returnValue.selectedCount = sel.size();
    152183        for (OsmPrimitive s : sel) {
    153184            String v = s.get(key);
     
    166197    protected static Usage determineBooleanUsage(Collection<OsmPrimitive> sel, String key) {
    167198        Usage returnValue = new Usage();
     199        returnValue.selectedCount = sel.size();
    168200        for (OsmPrimitive s : sel) {
    169201            String booleanValue = OsmUtils.getNamedOsmBoolean(s.get(key));
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelect.java

    r18254 r18257  
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import java.util.TreeMap;
     4import java.awt.Dimension;
     5import java.awt.Insets;
     6import java.awt.Rectangle;
    57import java.util.stream.Collectors;
    68
     
    4143        initializeLocaleText(null);
    4244        usage = determineTextUsage(support.getSelected(), key);
    43         seenValues = new TreeMap<>();
     45        seenValues.clear();
    4446        initListEntries();
    4547
    4648        model.clear();
    47         if (!usage.hasUniqueValue() && !usage.unused()) {
    48             addEntry(PresetListEntry.ENTRY_DIFFERENT);
     49        // disable if the selected primitives have different values
     50        list.setEnabled(usage.hasUniqueValue() || usage.unused());
     51        String initialValue = getInitialValue(usage);
     52
     53        // Add values from the preset.
     54        presetListEntries.forEach(this::addEntry);
     55
     56        // Add all values used in the selected primitives. This also adds custom values and makes
     57        // sure we won't lose them.
     58        usage = usage.splitValues(String.valueOf(delimiter));
     59        for (String value: usage.map.keySet()) {
     60            addEntry(new PresetListEntry(value, this));
    4961        }
    5062
    51         String initialValue = getInitialValue(default_);
    52         if (initialValue != null) {
    53             // add all values already present to the list, otherwise we would remove all
    54             // custom entries unknown to the preset
     63        // Select the values in the initial value.
     64        if (initialValue != null && !DIFFERENT.equals(initialValue)) {
    5565            for (String value : initialValue.split(String.valueOf(delimiter), -1)) {
    5666                PresetListEntry e = new PresetListEntry(value, this);
     
    6171        }
    6272
    63         presetListEntries.forEach(this::addEntry);
    64 
    6573        ComboMultiSelectListCellRenderer renderer = new ComboMultiSelectListCellRenderer(list, list.getCellRenderer(), 200, key);
    6674        list.setCellRenderer(renderer);
     75        JLabel label = addLabel(p);
     76        label.setLabelFor(list);
     77        JScrollPane sp = new JScrollPane(list);
    6778
    6879        if (rows > 0) {
    6980            list.setVisibleRowCount(rows);
     81            // setVisibleRowCount() only works when all cells have the same height, but sometimes we
     82            // have icons of different sizes. Calculate the size of the first {@code rows} entries
     83            // and size the scrollpane accordingly.
     84            Rectangle r = list.getCellBounds(0, Math.min(rows, model.size() - 1));
     85            Insets insets = list.getInsets();
     86            r.width += insets.left + insets.right;
     87            r.height += insets.top + insets.bottom;
     88            insets = sp.getInsets();
     89            r.width += insets.left + insets.right;
     90            r.height += insets.top + insets.bottom;
     91            sp.setPreferredSize(new Dimension(r.width, r.height));
    7092        }
    71         JLabel label = addLabel(p);
    72         p.add(new JScrollPane(list), GBC.eol().fill(GBC.HORIZONTAL)); // NOSONAR
    73         label.setLabelFor(list);
     93        p.add(sp, GBC.eol().fill(GBC.HORIZONTAL)); // NOSONAR
    7494
    7595        list.addListSelectionListener(l -> support.fireItemValueModified(this, key, getSelectedItem().value));
     
    83103    protected PresetListEntry getSelectedItem() {
    84104        return new PresetListEntry(list.getSelectedValuesList()
    85             .stream().map(e -> e.value).collect(Collectors.joining(String.valueOf(delimiter))), this);
     105            .stream().map(e -> e.value).distinct().sorted().collect(Collectors.joining(String.valueOf(delimiter))), this);
    86106    }
    87107}
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/PresetListEntry.java

    r18254 r18257  
    4848    public String locale_short_description; // NOSONAR
    4949
    50     private String cachedDisplayValue = null;
    51     private String cachedShortDescription = null;
    52     private ImageIcon cachedIcon = null;
     50    private String cachedDisplayValue;
     51    private String cachedShortDescription;
     52    private ImageIcon cachedIcon;
    5353
    5454    /**
     
    8383    public String getListDisplay(int width) {
    8484        String displayValue = getDisplayValue();
    85         Integer count = cms == null ? null : cms.usage.map.get(value);
     85        Integer count = getCount();
    8686
    87         if (count != null) {
    88             displayValue = String.format("%s (%d)", displayValue, count);
     87        if (count > 0 && cms.usage.getSelectedCount() > 1) {
     88            displayValue = tr("{0} ({1})", displayValue, count);
    8989        }
    9090
     
    184184    }
    185185
     186    /**
     187     * Returns how many selected primitives had this value set.
     188     * @return see above
     189     */
     190    public int getCount() {
     191        Integer count = cms == null ? null : cms.usage.map.get(value);
     192        return count == null ? 0 : count;
     193    }
     194
    186195    @Override
    187196    public int compareTo(PresetListEntry o) {
Note: See TracChangeset for help on using the changeset viewer.