Changeset 19592 in josm for trunk


Ignore:
Timestamp:
2026-07-23T18:04:58+02:00 (3 days ago)
Author:
stoecker
Message:

fix #24482 - patch by tordanik - improve autofilters

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r19403 r19592  
    621621
    622622        MapFrame map = MainApplication.getMap();
    623         if (AutoFilterManager.getInstance().getCurrentAutoFilter() != null) {
     623        if (AutoFilterManager.getInstance().getCurrentCombinedFilter() != null) {
    624624            AutoFilterManager.getInstance().drawOSDText(tempG);
    625625        } else if (MainApplication.isDisplayingMapView() && map.filterDialog != null) {
  • trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterButton.java

    r19519 r19592  
    1515import org.openstreetmap.josm.actions.PreferencesAction;
    1616import org.openstreetmap.josm.data.preferences.NamedColorProperty;
    17 import org.openstreetmap.josm.gui.MainApplication;
    1817import org.openstreetmap.josm.gui.preferences.display.DrawingPreference;
    1918
     
    3635            @Override
    3736            public synchronized void actionPerformed(ActionEvent e) {
     37
    3838                AutoFilterManager afm = AutoFilterManager.getInstance();
    39                 if (filter.equals(afm.getCurrentAutoFilter())) {
    40                     afm.setCurrentAutoFilter(null);
    41                     MainApplication.getMap().filterDialog.getFilterModel().executeFilters(true);
     39
     40                if (afm.getCurrentAutoFilters().isEmpty()) {
     41                    afm.setCurrentAutoFilter(filter);
    4242                } else {
    43                     afm.setCurrentAutoFilter(filter);
     43                    if ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0
     44                            || (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) {
     45                        if (afm.getCurrentAutoFilters().contains(filter)) {
     46                            afm.removeCurrentAutoFilter(filter);
     47                        } else {
     48                            afm.addCurrentAutoFilter(filter);
     49                        }
     50                    } else {
     51                        if (afm.getCurrentAutoFilters().size() == 1 && afm.getCurrentAutoFilters().contains(filter)) {
     52                            afm.setCurrentAutoFilter(null);
     53                        } else {
     54                            afm.setCurrentAutoFilter(filter);
     55                        }
     56                    }
    4457                }
     58
    4559            }
    4660        });
     
    5569        if (getModel().isPressed()) {
    5670            g.setColor(PROP_COLOR.get().darker().darker());
    57         } else if (getModel().isRollover() || AutoFilterManager.getInstance().getCurrentAutoFilter() == filter) {
     71        } else if (getModel().isRollover() || AutoFilterManager.getInstance().getCurrentAutoFilters().contains(filter)) {
    5872            g.setColor(PROP_COLOR.get().darker());
    5973        } else {
  • trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java

    r19519 r19592  
    99import java.util.Collection;
    1010import java.util.Collections;
     11import java.util.HashMap;
    1112import java.util.List;
    1213import java.util.Map;
    1314import java.util.NavigableSet;
    1415import java.util.Objects;
    15 import java.util.TreeMap;
     16import java.util.OptionalInt;
    1617import java.util.TreeSet;
    17 import java.util.function.Consumer;
     18import java.util.stream.Collectors;
     19import java.util.stream.IntStream;
    1820
    1921import org.openstreetmap.josm.actions.mapmode.MapMode;
     
    6466
    6567    /**
    66      * Property to determines if the auto filter feature is enabled.
     68     * Property to determine if the auto filter feature is enabled.
    6769     */
    6870    public static final BooleanProperty PROP_AUTO_FILTER_ENABLED = new BooleanProperty("auto.filter.enabled", true);
    6971
    7072    /**
     73     * Property to determine if the auto filter feature completely hides elements instead of just disabling them.
     74     * Equivalent to {@link Filter#hiding}
     75     */
     76    public static final BooleanProperty PROP_AUTO_FILTER_HIDING = new BooleanProperty("auto.filter.hiding", false);
     77
     78
     79    /**
    7180     * Property to determine the current auto filter rule.
    7281     */
     
    8190     * The buttons currently displayed in map view.
    8291     */
    83     private final Map<Integer, AutoFilterButton> buttons = new TreeMap<>();
     92    private final Map<OptionalInt, AutoFilterButton> buttons = new HashMap<>();
    8493
    8594    /**
     
    104113
    105114    /**
    106      * The currently selected auto filter, if any.
    107      */
    108     private AutoFilter currentAutoFilter;
     115     * The currently selected auto filters, if any.
     116     * If more than one auto filter is active, elements will match if they match at least one of them.
     117     */
     118    private final List<AutoFilter> currentAutoFilters = new ArrayList<>();
    109119
    110120    /**
     
    134144            // Retrieve the values from current rule visible on screen
    135145            NavigableSet<Integer> values = getNumericValues();
    136             // Make sure current auto filter button remains visible even if no data is found, to allow user to disable it
    137             if (currentAutoFilter != null) {
    138                 values.add(currentAutoFilter.getFilter().value);
    139             }
    140             if (!values.equals(buttons.keySet())) {
     146            // Make sure current auto filter buttons remain visible even if no data is found, to allow user to disable them
     147            for (var currentAutoFilter : currentAutoFilters) {
     148                if (currentAutoFilter.getFilter().value != null) {
     149                    values.add(currentAutoFilter.getFilter().value);
     150                }
     151            }
     152            if (!values.equals(buttons.keySet().stream()
     153                    .filter(it -> it.isPresent() && it.getAsInt() != Integer.MIN_VALUE)
     154                    .map(OptionalInt::getAsInt).collect(Collectors.toSet()))) {
    141155                removeAllButtons();
    142156                addNewButtons(values);
     
    147161    static class CompiledFilter extends Filter implements MatchSupplier {
    148162        final AutoFilterRule rule;
    149         final int value;
    150 
    151         CompiledFilter(AutoFilterRule rule, int value) {
     163        final Integer value;
     164
     165        CompiledFilter(AutoFilterRule rule, Integer value, boolean hiding) {
    152166            this.rule = rule;
    153167            this.value = value;
     168            this.hiding = hiding;
    154169            this.enable = true;
    155170            this.inverted = true;
     
    174189                return false;
    175190            CompiledFilter other = (CompiledFilter) obj;
    176             return Objects.equals(rule, other.rule) && value == other.value;
     191            return Objects.equals(rule, other.rule) && Objects.equals(value, other.value);
     192        }
     193    }
     194
     195    /** The combination of multiple {@link CompiledFilter}s */
     196    static class CombinedFilter extends Filter implements MatchSupplier {
     197
     198        private final List<CompiledFilter> filters;
     199
     200        CombinedFilter(List<CompiledFilter> filters) {
     201
     202            if (filters == null || filters.isEmpty()) throw new IllegalArgumentException("no filters provided");
     203
     204            this.filters = filters;
     205
     206            boolean hiding = filters.get(0).hiding;
     207            String key = filters.get(0).rule.getKey();
     208            List<String> values = new ArrayList<>();
     209
     210            for (CompiledFilter filter : filters) {
     211                if (hiding != filter.hiding) throw new IllegalArgumentException("non-matching hiding properties");
     212                if (!Objects.equals(key, filter.rule.getKey())) throw new IllegalArgumentException("non-matching keys");
     213                values.add(filter.rule.formatValue(filter.value));
     214            }
     215
     216            this.hiding = hiding;
     217            this.enable = true;
     218            this.inverted = true;
     219            this.text = key + "~" + String.join("|", values);
     220
     221        }
     222
     223        @Override
     224        public SearchCompiler.Match get() {
     225            return new SearchCompiler.Match() {
     226                @Override
     227                public boolean match(OsmPrimitive osm) {
     228                    return filters.stream().anyMatch(filter -> filter.get().match(osm));
     229                }
     230            };
     231        }
     232
     233        @Override
     234        public int hashCode() {
     235            return 31 * super.hashCode() + Objects.hash(filters);
     236        }
     237
     238        @Override
     239        public boolean equals(Object obj) {
     240            if (this == obj)
     241                return true;
     242            if (!super.equals(obj) || getClass() != obj.getClass())
     243                return false;
     244            CombinedFilter other = (CombinedFilter) obj;
     245            return Objects.equals(filters, other.filters);
    177246        }
    178247    }
     
    180249    static class Match extends SearchCompiler.Match {
    181250        final AutoFilterRule rule;
    182         final int value;
    183 
    184         Match(AutoFilterRule rule, int value) {
     251        final Integer value;
     252
     253        Match(AutoFilterRule rule, Integer value) {
    185254            this.rule = rule;
    186255            this.value = value;
     
    189258        @Override
    190259        public boolean match(OsmPrimitive osm) {
    191             return rule.getTagValuesForPrimitive(osm).anyMatch(v -> v == value);
     260            IntStream values = rule.getTagValuesForPrimitive(osm, false);
     261            if (value != null) {
     262                return values.anyMatch(v -> v == value);
     263            } else {
     264                return values.findAny().isEmpty();
     265            }
    192266        }
    193267
     
    197271            if (o == null || getClass() != o.getClass()) return false;
    198272            Match match = (Match) o;
    199             return value == match.value &&
     273            return Objects.equals(value, match.value) &&
    200274                    Objects.equals(rule, match.rule);
    201275        }
     
    215289        final AutoFilterButton keyButton = AutoFilterButton.forOsmKey(enabledRule.getKey());
    216290        addButton(keyButton, Integer.MIN_VALUE, i++);
    217         for (final Integer value : values.descendingSet()) {
    218             CompiledFilter filter = new CompiledFilter(enabledRule, value);
     291        var valueList = new ArrayList<>(values.descendingSet());
     292        if (enabledRule.getNoValueFilter()) {
     293            valueList.add(null);
     294        }
     295        for (final Integer value : valueList) {
     296            CompiledFilter filter = new CompiledFilter(enabledRule, value, PROP_AUTO_FILTER_HIDING.get());
    219297            String label = enabledRule.formatValue(value);
    220298            AutoFilter autoFilter = new AutoFilter(label, filter.text, filter);
    221299            AutoFilterButton button = new AutoFilterButton(autoFilter);
    222             if (autoFilter.equals(currentAutoFilter)) {
     300            if (currentAutoFilters.contains(autoFilter)) {
    223301                button.getModel().setPressed(true);
    224302            }
     303            addButton(button, value, i++);
    225304            maxWidth = Math.max(maxWidth, button.getPreferredSize().width);
    226             addButton(button, value, i++);
    227305        }
    228306        for (AutoFilterButton b : buttons.values()) {
     
    232310    }
    233311
    234     private void addButton(AutoFilterButton button, int value, int i) {
     312    private void addButton(AutoFilterButton button, Integer value, int i) {
    235313        MapView mapView = MainApplication.getMap().mapView;
    236         buttons.put(value, button);
     314        buttons.put(value == null ? OptionalInt.empty() : OptionalInt.of(value), button);
    237315        mapView.add(button).setLocation(3, 60 + 22*i);
    238316    }
     
    253331        BBox bbox = MainApplication.getMap().mapView.getState().getViewArea().getLatLonBoundsBox().toBBox();
    254332        NavigableSet<Integer> values = new TreeSet<>();
    255         Consumer<OsmPrimitive> consumer = o -> enabledRule.getTagValuesForPrimitive(o).forEach(values::add);
    256         ds.searchNodes(bbox).forEach(consumer);
    257         ds.searchWays(bbox).forEach(consumer);
    258         ds.searchRelations(bbox).forEach(consumer);
     333        for (var primitiveList : List.of(ds.searchNodes(bbox), ds.searchWays(bbox), ds.searchRelations(bbox))) {
     334            // add all values that are directly mentioned
     335            primitiveList.forEach(o -> enabledRule.getTagValuesForPrimitive(o, true).forEach(values::add));
     336            // only add integer values from value ranges, not fractional values
     337            primitiveList.forEach(o -> enabledRule.getTagValuesForPrimitive(o, false)
     338                    .filter(v -> !enabledRule.formatValue(v).contains("."))
     339                    .forEach(values::add));
     340
     341        }
    259342        return values;
    260343    }
     
    268351    public void dataChanged(DataChangedEvent event) {
    269352        updateFiltersFull();
     353        updateButtons();
    270354    }
    271355
     
    314398
    315399    private synchronized void updateFiltersFull() {
    316         if (currentAutoFilter != null) {
     400        if (!currentAutoFilters.isEmpty()) {
    317401            model.executeFilters();
    318402        }
     
    320404
    321405    private synchronized void updateFiltersEvent(AbstractDatasetChangedEvent event, boolean affectedOnly) {
    322         if (currentAutoFilter != null) {
     406        if (!currentAutoFilters.isEmpty()) {
    323407            Collection<? extends OsmPrimitive> prims = event.getPrimitives();
    324408            model.executeFilters(affectedOnly ? FilterModel.getAffectedPrimitives(prims) : prims);
     
    383467
    384468    /**
    385      * Returns the currently selected auto filter, if any.
    386      * @return the currently selected auto filter, or null
    387      */
    388     public synchronized AutoFilter getCurrentAutoFilter() {
    389         return currentAutoFilter;
     469     * Returns the currently selected auto filters, if any.
     470     * @return the currently selected auto filters. Can be empty.
     471     */
     472    public synchronized List<AutoFilter> getCurrentAutoFilters() {
     473        return currentAutoFilters;
     474    }
     475
     476    /**
     477     * Returns a combination of all {@link #getCurrentAutoFilters()}, if any.
     478     * @return a single combined filter, or null
     479     */
     480    public Filter getCurrentCombinedFilter() {
     481        if (currentAutoFilters.isEmpty()) {
     482            return null;
     483        } else if (currentAutoFilters.size() == 1) {
     484            return currentAutoFilters.get(0).getFilter();
     485        } else {
     486            return new CombinedFilter(currentAutoFilters.stream().map(AutoFilter::getFilter).collect(Collectors.toList()));
     487        }
    390488    }
    391489
     
    395493     */
    396494    public synchronized void setCurrentAutoFilter(AutoFilter autoFilter) {
     495        currentAutoFilters.clear();
     496        if (autoFilter != null) {
     497            currentAutoFilters.add(autoFilter);
     498        }
     499        updateModelFilters();
     500    }
     501
     502    public synchronized void addCurrentAutoFilter(AutoFilter autoFilter) {
     503        if (!currentAutoFilters.contains(autoFilter)) {
     504            currentAutoFilters.add(autoFilter);
     505            updateModelFilters();
     506        }
     507    }
     508
     509    public synchronized void removeCurrentAutoFilter(AutoFilter autoFilter) {
     510        if (currentAutoFilters.contains(autoFilter)) {
     511            currentAutoFilters.removeIf(it -> Objects.equals(it, autoFilter));
     512            updateModelFilters();
     513        }
     514    }
     515
     516    private synchronized void updateModelFilters() {
    397517        model.clearFilters();
    398         currentAutoFilter = autoFilter;
    399         if (autoFilter != null) {
    400             model.addFilter(autoFilter.getFilter());
     518        if (currentAutoFilters.isEmpty()) {
     519            if (MainApplication.getMap() != null) {
     520                MainApplication.getMap().filterDialog.getFilterModel().executeFilters(true);
     521            }
     522        } else {
     523            model.addFilter(getCurrentCombinedFilter());
    401524            model.executeFilters();
    402             if (model.isChanged()) {
    403                 OsmDataLayer dataLayer = MainApplication.getLayerManager().getActiveDataLayer();
    404                 if (dataLayer != null) {
    405                     dataLayer.invalidate();
    406                 }
     525            // update the data layer (necessary even if model.isChanged() == false to update the OSDText)
     526            OsmDataLayer dataLayer = MainApplication.getLayerManager().getActiveDataLayer();
     527            if (dataLayer != null) {
     528                dataLayer.invalidate();
    407529            }
    408530        }
     
    414536     */
    415537    public synchronized void drawOSDText(Graphics2D g) {
     538        String filterText = Objects.requireNonNull(getCurrentCombinedFilter()).text;
     539        String lengthLimitedFilterText = filterText.length() > 18 ? filterText.substring(0, 18) + "…" : filterText;
    416540        model.drawOSDText(g, lblOSD,
    417             tr("<h2>Filter active: {0}</h2>", currentAutoFilter.getFilter().text),
     541            tr("<h2>Filter active: {0}</h2>", lengthLimitedFilterText),
    418542            tr("</p><p>Click again on filter button to see all objects.</p></html>"));
    419543    }
     
    438562                resetCurrentAutoFilter();
    439563            }
    440         } else if (e.getKey().equals(PROP_AUTO_FILTER_RULE.getKey())) {
     564        } else if (e.getKey().equals(PROP_AUTO_FILTER_RULE.getKey())
     565                || e.getKey().equals(PROP_AUTO_FILTER_HIDING.getKey())) {
    441566            enableAutoFilterRule(PROP_AUTO_FILTER_RULE.get());
    442567            resetCurrentAutoFilter();
  • trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java

    r19519 r19592  
    44import java.text.DecimalFormat;
    55import java.util.Arrays;
     6import java.util.HashSet;
     7import java.util.List;
    68import java.util.Locale;
    79import java.util.Objects;
    810import java.util.Optional;
     11import java.util.Set;
    912import java.util.function.Function;
    1013import java.util.function.IntFunction;
     
    1316import java.util.regex.Pattern;
    1417import java.util.stream.IntStream;
     18import java.util.stream.Stream;
    1519
    1620import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    1822import org.openstreetmap.josm.data.preferences.BooleanProperty;
    1923import org.openstreetmap.josm.tools.Logging;
     24
     25import static java.util.stream.Collectors.toList;
    2026
    2127/**
     
    4349    private IntFunction<String> valueFormatter = Integer::toString;
    4450
     51    private boolean noValueFilter = false;
     52
     53    /** The union of {@link #key} and the keys provided by {@link #setExtraKeys(List)}. */
     54    private List<String> allKeys;
     55
    4556    /**
    4657     * Constructs a new {@code AutoFilterRule}.
     
    5162        this.key = key;
    5263        this.minZoomLevel = minZoomLevel;
     64        this.allKeys = List.of(key);
    5365    }
    5466
     
    6779    public int getMinZoomLevel() {
    6880        return minZoomLevel;
     81    }
     82
     83    /**
     84     * Returns true if there should be a filter button for OSM primitives which have no value for the key.
     85     * @since xxx
     86     */
     87    public boolean getNoValueFilter() {
     88        return noValueFilter;
    6989    }
    7090
     
    7393     * @param value the numeric value to format
    7494     * @return the formatted value
    75      */
    76     public String formatValue(int value) {
    77         return valueFormatter.apply(value);
     95     * @since xxx
     96     */
     97    public String formatValue(Integer value) {
     98        return value == null ? "∅" : valueFormatter.apply(value);
    7899    }
    79100
     
    113134
    114135    /**
     136     * Adds a filter button for OSM primitives which have no value for the key.
     137     */
     138    public AutoFilterRule enableNoValueFilter() {
     139        this.noValueFilter = true;
     140        return this;
     141    }
     142
     143    /**
     144     * Sets extra OSM keys on which the rule applies in addition to the primary key ({@link #getKey()}).
     145     * This allows a filter to look at the values of more than one key at the same time.
     146     * @param extraKeys the list of extra keys, may be empty
     147     * @return {@code this}
     148     * @throws NullPointerException if {@code extraKeys} is null
     149     * @since xxx
     150     */
     151    public AutoFilterRule setExtraKeys(List<String> extraKeys) {
     152        Objects.requireNonNull(extraKeys);
     153        this.allKeys = Stream.concat(Stream.of(key), extraKeys.stream()).collect(toList());
     154        return this;
     155    }
     156
     157    /**
    115158     * Returns the numeric values for the given OSM primitive
    116      * @param osm the primitive
     159     *
     160     * @param osm              the primitive
     161     * @param directValuesOnly whether "inner" values from ranges (such as 6 and 7 for 5-8) should be omitted
    117162     * @return a stream of numeric values
    118      */
    119     public IntStream getTagValuesForPrimitive(OsmPrimitive osm) {
     163     * @since xxx
     164     */
     165    public IntStream getTagValuesForPrimitive(OsmPrimitive osm, boolean directValuesOnly) {
     166        if (osm.isDeleted()) return IntStream.empty();
     167        if (allKeys.size() == 1) {
     168            IntStream values = getTagValuesForPrimitive(osm, key, directValuesOnly);
     169            if (values != null) return values;
     170        } else {
     171            Set<Integer> allValues = new HashSet<>();
     172            for (String k : allKeys) {
     173                IntStream values = getTagValuesForPrimitive(osm, k, directValuesOnly);
     174                if (values != null) {
     175                    values.forEach(allValues::add);
     176                }
     177            }
     178            if (!allValues.isEmpty()) return allValues.stream().mapToInt(it -> it).sorted();
     179        }
     180        return Boolean.TRUE.equals(PROP_AUTO_FILTER_DEFAULTS.get()) ? defaultValueSupplier.apply(osm) : IntStream.empty();
     181    }
     182
     183    private IntStream getTagValuesForPrimitive(OsmPrimitive osm, String key, boolean directValuesOnly) {
    120184        String value = osm.get(key);
    121185        if (value != null) {
     
    126190                    int a = valueExtractor.applyAsInt(m.group(1));
    127191                    int b = valueExtractor.applyAsInt(m.group(2));
    128                     return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
     192                    if (directValuesOnly && a != b) {
     193                        return IntStream.of(a, b).sorted();
     194                    } else {
     195                        return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
     196                    }
    129197                } else {
    130198                    try {
     
    137205            });
    138206        }
    139         return Boolean.TRUE.equals(PROP_AUTO_FILTER_DEFAULTS.get()) ? defaultValueSupplier.apply(osm) : IntStream.empty();
     207        return null;
    140208    }
    141209
     
    157225                    .setDefaultValueSupplier(AutoFilterRule::defaultLayer),
    158226            new AutoFilterRule("level", 17)
     227                .setExtraKeys(List.of("repeat_on"))
     228                .enableNoValueFilter()
    159229                // #17109, support values like 0.5 or 1.5 - level values are multiplied by 2 when parsing, values are divided by 2 for formatting
    160230                .setValueExtractor(s -> (int) (Double.parseDouble(s) * 2.))
  • trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java

    r18556 r19592  
    9999     */
    100100    public void executeFilters(boolean force) {
    101         if (AutoFilterManager.getInstance().getCurrentAutoFilter() == null && (force || model.hasFilters())) {
     101        if (AutoFilterManager.getInstance().getCurrentCombinedFilter() == null && (force || model.hasFilters())) {
    102102            model.executeFilters();
    103103            updateMap();
     
    112112     */
    113113    public void executeFilters(Collection<? extends OsmPrimitive> primitives, boolean force) {
    114         if (AutoFilterManager.getInstance().getCurrentAutoFilter() == null && (force || model.hasFilters())) {
     114        if (AutoFilterManager.getInstance().getCurrentCombinedFilter() == null && (force || model.hasFilters())) {
    115115            model.executeFilters(primitives);
    116116            updateMap();
  • trunk/src/org/openstreetmap/josm/gui/preferences/display/DrawingPreference.java

    r18416 r19592  
    5757    private final JCheckBox discardableKeys = new JCheckBox(tr("Display discardable keys"));
    5858    private final JCheckBox autoFilters = new JCheckBox(tr("Use auto filters"));
     59    private final JCheckBox autoFiltersHiding = new JCheckBox(tr("Hide auto-filtered elements"));
     60
    5961    private final JLabel lblRule = new JLabel(tr("Rule"));
    6062    private final JosmComboBox<AutoFilterRule> autoFilterRules = new JosmComboBox<>(
     
    150152            lblRule.setEnabled(autoFilters.isSelected());
    151153            autoFilterRules.setEnabled(autoFilters.isSelected());
     154            autoFiltersHiding.setEnabled(autoFilters.isSelected());
    152155        });
    153156        autoFilterRules.setToolTipText("Rule defining which tag will provide automatic filters, below a certain zoom level");
    154157        autoFilterRules.setSelectedItem(AutoFilterManager.getInstance().getAutoFilterRule(AutoFilterManager.PROP_AUTO_FILTER_RULE.get()));
     158        autoFiltersHiding.setToolTipText(
     159            tr("Completely hide elements which do not match the automatic filter instead of merely disabling them"));
     160        autoFiltersHiding.setSelected(AutoFilterManager.PROP_AUTO_FILTER_HIDING.get());
    155161
    156162        JLabel performanceLabel = new JLabel(tr("Options that affect drawing performance"));
     
    184190        panel.add(lblRule, GBC.std().insets(40, 0, 0, 0));
    185191        panel.add(autoFilterRules, GBC.eop().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0));
     192        panel.add(autoFiltersHiding, GBC.eop().insets(40, 0, 0, 0));
    186193
    187194        ExpertToggleAction.addVisibilitySwitcher(performanceLabel);
     
    214221        Config.getPref().putBoolean("display.discardable-keys", discardableKeys.isSelected());
    215222        AutoFilterManager.PROP_AUTO_FILTER_ENABLED.put(autoFilters.isSelected());
     223        AutoFilterManager.PROP_AUTO_FILTER_HIDING.put(autoFiltersHiding.isSelected());
    216224        AutoFilterManager.PROP_AUTO_FILTER_RULE.put(((AutoFilterRule) autoFilterRules.getSelectedItem()).getKey());
    217225        int vn = Config.getPref().getInt("mappaint.node.virtual-size", 8);
  • trunk/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterRuleTest.java

    r19519 r19592  
    2323class AutoFilterRuleTest {
    2424    /**
    25      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive}.
     25     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive, boolean)}.
    2626     */
    2727    @Test
     
    3737        assertTagValuesForPrimitive(level, "way level=10;12-13", 20, 24, 25, 26);
    3838        assertTagValuesForPrimitive(level, "way level=0;0.5;1;1.5;2;2.5;3", 0, 1, 2, 3, 4, 5, 6);
     39        assertTagValuesForPrimitive(level, "node level=0 repeat_on=1;2", 0, 2, 4);
     40        assertTagValuesForPrimitive(level, "way level=4 repeat_on=4;5 layer=1", 8, 10);
    3941        assertEquals("0 0.5 1 1.5 2 2.5 3",
    4042                IntStream.of(0, 1, 2, 3, 4, 5, 6).mapToObj(level::formatValue).collect(Collectors.joining(" ")));
     
    4244
    4345    /**
    44      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive} to deal with {@code %} of key {@code incline}.
     46     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive, boolean)} to deal with {@code %} of key {@code incline}.
    4547     */
    4648    @Test
     
    5355
    5456    /**
    55      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive} provides sensible defaults, see #17496.
     57     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive, boolean)} provides sensible defaults, see #17496.
    5658     */
    5759    @Test
     
    7072    private void assertTagValuesForPrimitive(AutoFilterRule rule, String assertion, int... expected) {
    7173        final OsmPrimitive primitive = OsmUtils.createPrimitive(assertion);
    72         final int[] actual = rule.getTagValuesForPrimitive(primitive).toArray();
     74        final int[] actual = rule.getTagValuesForPrimitive(primitive, false).toArray();
    7375        assertArrayEquals(expected, actual);
    7476    }
Note: See TracChangeset for help on using the changeset viewer.