Changeset 18556 in josm for trunk


Ignore:
Timestamp:
2022-09-08T22:51:20+02:00 (20 months ago)
Author:
taylor.smock
Message:

Fix #22333: Allow delete + move up/down actions in filter dialog to act on all selected filters (patch by Woazboat, modified)

This also adds build add/remove methods
in FilterModel and FilterTableModel.

Location:
trunk/src/org/openstreetmap/josm
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java

    • Property svn:eol-style set to native
    r16445 r18556  
    77import java.awt.Graphics2D;
    88import java.util.ArrayList;
     9import java.util.Arrays;
    910import java.util.Collection;
    1011import java.util.Collections;
     
    234235
    235236    /**
     237     * Adds new filters to the filter list.
     238     * @param newFilters The new filters
     239     * @return true (as specified by {@link Collection#add})
     240     * @since 18556
     241     */
     242    public boolean addFilters(Filter... newFilters) {
     243        boolean filtersChanged = filters.addAll(Arrays.asList(newFilters));
     244        updateFilterMatcher();
     245        return filtersChanged;
     246    }
     247
     248    /**
    236249     * Moves the filters in the given rows by a number of positions.
    237250     * @param delta negative or positive increment
     
    270283     * @param rowIndex The index of the filter to remove
    271284     * @return the filter previously at the specified position
     285     * @see #removeFilters(int...) for bulk removal
    272286     */
    273287    public Filter removeFilter(int rowIndex) {
    274288        Filter result = filters.remove(rowIndex);
     289        updateFilterMatcher();
     290        return result;
     291    }
     292
     293    /**
     294     * Removes the filters that are displayed in the given rows
     295     * @param rowIndexes The indexes of the filters to remove
     296     * @return the filters previously at the specified positions
     297     * @since 18556
     298     */
     299    public Collection<Filter> removeFilters(int... rowIndexes) {
     300        // Ensure that the indexes are sorted so we can go through them in reverse
     301        Arrays.sort(rowIndexes);
     302        List<Filter> result = new ArrayList<>(rowIndexes.length);
     303        for (int i = rowIndexes.length - 1; i >= 0; i--) {
     304            result.add(filters.remove(i));
     305        }
     306        // Reverse the list so that users can iterate through the filters in the order that they were in the model.
     307        Collections.reverse(result);
    275308        updateFilterMatcher();
    276309        return result;
  • trunk/src/org/openstreetmap/josm/gui/dialogs/FilterDialog.java

    r17188 r18556  
    176176        @Override
    177177        public void actionPerformed(ActionEvent e) {
    178             int index = filterModel.getSelectionModel().getMinSelectionIndex();
    179             if (index >= 0) {
    180                 filterModel.removeFilter(index);
    181             }
     178            filterModel.removeFilters(filterModel.getSelectedIndices());
    182179        }
    183180    }
     
    190187        @Override
    191188        public void actionPerformed(ActionEvent e) {
    192             int index = userTable.convertRowIndexToModel(userTable.getSelectionModel().getMinSelectionIndex());
    193             if (index >= 0 && filterModel.moveUp(index)) {
    194                 filterModel.getSelectionModel().setSelectionInterval(index-1, index-1);
    195             }
     189            filterModel.moveUp();
    196190        }
    197191
     
    209203        @Override
    210204        public void actionPerformed(ActionEvent e) {
    211             int index = userTable.convertRowIndexToModel(userTable.getSelectionModel().getMinSelectionIndex());
    212             if (index >= 0 && filterModel.moveDown(index)) {
    213                 filterModel.getSelectionModel().setSelectionInterval(index+1, index+1);
    214             }
     205            filterModel.moveDown();
    215206        }
    216207
  • trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java

    r15390 r18556  
    66
    77import java.awt.Graphics2D;
     8import java.util.Arrays;
    89import java.util.Collection;
    910import java.util.List;
     
    2122import org.openstreetmap.josm.gui.widgets.OSDLabel;
    2223import org.openstreetmap.josm.tools.Logging;
     24import org.openstreetmap.josm.tools.Utils;
    2325
    2426/**
     
    134136     * Adds a new filter to the filter list.
    135137     * @param filter The new filter
     138     * @see #addFilters(Filter...) for bulk addition
    136139     */
    137140    public void addFilter(Filter filter) {
    138141        if (model.addFilter(filter)) {
     142            savePrefs();
     143            updateFilters();
     144            int size = model.getFiltersCount();
     145            fireTableRowsInserted(size - 1, size - 1);
     146        }
     147    }
     148
     149    /**
     150     * Adds a new filter to the filter list.
     151     * @param filters The new filter
     152     * @since 18556
     153     */
     154    public void addFilters(Filter... filters) {
     155        if (model.addFilters(filters)) {
    139156            savePrefs();
    140157            updateFilters();
     
    166183     * Removes the filter that is displayed in the given row
    167184     * @param rowIndex The index of the filter to remove
     185     * @see #removeFilters(int...)
    168186     */
    169187    public void removeFilter(int rowIndex) {
    170         if (model.removeFilter(rowIndex) != null) {
     188        this.removeFilters(rowIndex);
     189    }
     190
     191    /**
     192     * Removes the filters that is displayed in the given rows
     193     * @param rowIndexes The indexes of the filters to remove
     194     * @since 18556
     195     */
     196    public void removeFilters(int... rowIndexes) {
     197        // Ensure that the indexes are sorted so we can go through
     198        // them in reverse
     199        Arrays.sort(rowIndexes);
     200        boolean modified = !model.removeFilters(rowIndexes).isEmpty();
     201        if (modified) {
    171202            savePrefs();
    172203            updateFilters();
    173             fireTableRowsDeleted(rowIndex, rowIndex);
     204            int[][] groupedRows = Utils.groupIntegers(rowIndexes);
     205            // Reverse to avoid having to deal with offsets in client code
     206            for (int i = groupedRows.length - 1; i >= 0; i--) {
     207                int[] rows = groupedRows[i];
     208                fireTableRowsDeleted(rows[0], rows[1]);
     209            }
    174210        }
    175211    }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

    r18439 r18556  
    308308        final ListSelectionModel selectionModel = getSelectionModel();
    309309        selectionModel.setValueIsAdjusting(true);
    310         for (int[] row : groupRows(selectedRows)) {
     310        for (int[] row : Utils.groupIntegers(selectedRows)) {
    311311            if (members.size() > row[0] - offset) {
    312312                // Remove (inclusive)
     
    318318        selectionModel.setValueIsAdjusting(false);
    319319        fireTableDataChanged();
    320     }
    321 
    322     /**
    323      * Group rows for use in changing selection intervals, to avoid many small calls on large selections
    324      * @param rows The rows to group
    325      * @return A list of grouped rows, [lower, higher] (inclusive)
    326      */
    327     private static List<int[]> groupRows(int... rows) {
    328         if (rows.length == 0) {
    329             return Collections.emptyList();
    330         }
    331         List<int[]> groups = new ArrayList<>();
    332         int[] current = {Integer.MIN_VALUE, Integer.MIN_VALUE};
    333         groups.add(current);
    334         for (int row : rows) {
    335             if (current[0] == Integer.MIN_VALUE) {
    336                 current[0] = row;
    337                 current[1] = row;
    338                 continue;
    339             }
    340             if (current[1] == row - 1) {
    341                 current[1] = row;
    342             } else {
    343                 current = new int[] {row, row};
    344                 groups.add(current);
    345             }
    346         }
    347         return Collections.unmodifiableList(groups);
    348320    }
    349321
     
    489461            final int tIdx = idx;
    490462            // Avoiding many addSelectionInterval calls is critical for performance.
    491             for (int[] row : groupRows(IntStream.of(originalSelection).map(i -> i < index ? i : i + tIdx - index).toArray())) {
     463            for (int[] row : Utils.groupIntegers(IntStream.of(originalSelection).map(i -> i < index ? i : i + tIdx - index).toArray())) {
    492464                model.addSelectionInterval(row[0], row[1]);
    493465            }
  • trunk/src/org/openstreetmap/josm/tools/Utils.java

    r18553 r18556  
    8282    private static final long MILLIS_OF_HOUR = TimeUnit.HOURS.toMillis(1);
    8383    private static final long MILLIS_OF_DAY = TimeUnit.DAYS.toMillis(1);
     84    private static final int[][] EMPTY_INT_INT_ARRAY = new int[0][];
    8485
    8586    /**
     
    13401341
    13411342        return Math.sqrt(standardDeviation / values.length);
     1343    }
     1344
     1345    /**
     1346     * Group a list of integers, mostly useful to avoid calling many selection change events
     1347     * for a logical interval.
     1348     * <br>
     1349     * Example: {@code groupIntegers(1, 2, 3, 5, 6, 7, 8, 9)} becomes {@code [[1, 3], [5, 9]]}
     1350     * @param integers The integers to group
     1351     * @return The integers grouped into logical blocks, [lower, higher] (inclusive)
     1352     * @since 18556
     1353     */
     1354    public static int[][] groupIntegers(int... integers) {
     1355        if (integers.length == 0) {
     1356            return EMPTY_INT_INT_ARRAY;
     1357        }
     1358        List<int[]> groups = new ArrayList<>();
     1359        int[] current = {Integer.MIN_VALUE, Integer.MIN_VALUE};
     1360        groups.add(current);
     1361        for (int row : integers) {
     1362            if (current[0] == Integer.MIN_VALUE) {
     1363                current[0] = row;
     1364                current[1] = row;
     1365                continue;
     1366            }
     1367            if (current[1] == row - 1) {
     1368                current[1] = row;
     1369            } else {
     1370                current = new int[] {row, row};
     1371                groups.add(current);
     1372            }
     1373        }
     1374        return groups.toArray(EMPTY_INT_INT_ARRAY);
    13421375    }
    13431376
Note: See TracChangeset for help on using the changeset viewer.