Changeset 14892 in josm


Ignore:
Timestamp:
2019-03-17T16:06:34+01:00 (5 years ago)
Author:
GerdP
Message:

see #17412: Improve re-selection of tree element when the tree is rebuild

  • If an item for a TestError was selected and the new tree contains a similar entry select this new entry. This works also when the entry is at very different position in the tree.
  • If multiple edit layers have validation results, don't try to use the selection of one layer when switching to another and don't try to expand the same rows.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java

    r14878 r14892  
    151151     */
    152152    public void buildTree() {
     153        buildTree(true);
     154    }
     155    /**
     156     * Builds the errors tree
     157     * @param expandAgain if true, try to expand the same rows as before
     158     */
     159    public void buildTree(boolean expandAgain) {
    153160        if (resetScheduled)
    154161            return;
     
    164171        int selRow = selPath == null ? -1 : getRowForPath(selPath);
    165172
    166         // Remember the currently expanded rows
    167         Set<Object> oldExpandedRows = new HashSet<>();
    168         Enumeration<TreePath> expanded = getExpandedDescendants(new TreePath(getRoot()));
    169         if (expanded != null) {
    170             while (expanded.hasMoreElements()) {
    171                 TreePath path = expanded.nextElement();
    172                 DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
    173                 Object userObject = node.getUserObject();
    174                 if (userObject instanceof Severity) {
    175                     oldExpandedRows.add(userObject);
    176                 } else if (userObject instanceof String) {
    177                     String msg = (String) userObject;
    178                     int index = msg.lastIndexOf(" (");
    179                     if (index > 0) {
    180                         msg = msg.substring(0, index);
     173            // Remember the currently expanded rows
     174            Set<Object> oldExpandedRows = new HashSet<>();
     175            if (expandAgain) {
     176                Enumeration<TreePath> expanded = getExpandedDescendants(new TreePath(getRoot()));
     177                if (expanded != null) {
     178                    while (expanded.hasMoreElements()) {
     179                        TreePath path = expanded.nextElement();
     180                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
     181                        Object userObject = node.getUserObject();
     182                        if (userObject instanceof Severity) {
     183                            oldExpandedRows.add(userObject);
     184                        } else if (userObject instanceof String) {
     185                            String msg = (String) userObject;
     186                            int index = msg.lastIndexOf(" (");
     187                            if (index > 0) {
     188                                msg = msg.substring(0, index);
     189                            }
     190                            oldExpandedRows.add(msg);
     191                        }
    181192                    }
    182                     oldExpandedRows.add(msg);
    183                 }
    184             }
    185         }
     193                }
     194            }
    186195
    187196        Predicate<TestError> filterToUse = e -> !e.isIgnored();
     
    276285        }
    277286
    278         if (selRow >= 0 && selRow < getRowCount()) {
     287        if (selPath != null) {
     288            DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent();
     289            Object userObject = node.getUserObject();
     290            if (userObject instanceof TestError && ((TestError) userObject).isIgnored()) {
     291                // don't try to find ignored error
     292                selPath = null;
     293            }
     294        }
     295        if (selPath != null) {
     296            // try to reselect previously selected row. May not work if tree structure changed too much.
     297            DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent();
     298            Object searchObject = node.getUserObject();
     299            String msg = null;
     300            if (searchObject instanceof String) {
     301                msg = (String) searchObject;
     302                int index = msg.lastIndexOf(" (");
     303                if (index > 0) {
     304                    msg = msg.substring(0, index);
     305                }
     306            }
     307            String searchString = msg;
     308            visitTreeNodes(getRoot(), n -> {
     309                boolean found = false;
     310                final Object userInfo = n.getUserObject();
     311                if (searchObject instanceof TestError && userInfo instanceof TestError) {
     312                    TestError e1 = (TestError) searchObject;
     313                    TestError e2 = (TestError) userInfo;
     314                    found |= e1.getCode() == e2.getCode() && e1.getMessage().equals(e2.getMessage())
     315                            && e1.getPrimitives().size() == e2.getPrimitives().size()
     316                            && e1.getPrimitives().containsAll(e2.getPrimitives());
     317                } else if (searchObject instanceof String && userInfo instanceof String) {
     318                    found |= ((String) userInfo).startsWith(searchString);
     319                } else if (searchObject instanceof Severity) {
     320                    found |= searchObject.equals(userInfo);
     321                }
     322
     323                if (found) {
     324                    TreePath path = new TreePath(n.getPath());
     325                    setSelectionPath(path);
     326                    scrollPathToVisible(path);
     327                }
     328            });
     329        }
     330        if (selRow >= 0 && selRow < getRowCount() && getSelectionCount() == 0) {
     331            // fall back: if we cannot find the previously selected entry, select the row by position
    279332            setSelectionRow(selRow);
    280333            scrollRowToVisible(selRow);
     
    328381     */
    329382    public final void setErrorList(List<TestError> errors) {
     383        if (errors != null && errors == this.errors)
     384            return;
    330385        this.errors = errors != null ? errors : new ArrayList<>();
    331386        sortErrors();
    332387        if (isVisible()) {
    333             buildTree();
     388            //TODO: If list is changed because another layer was activated it would be good to store/restore
     389            // the expanded / selected paths.
     390            clearSelection();
     391            buildTree(false);
    334392        }
    335393    }
     
    368426        final List<TreePath> paths = new ArrayList<>();
    369427        walkAndSelectRelatedErrors(new TreePath(getRoot()), new HashSet<>(primitives)::contains, paths);
    370         getSelectionModel().clearSelection();
    371         getSelectionModel().setSelectionPaths(paths.toArray(new TreePath[0]));
     428        clearSelection();
     429        setSelectionPaths(paths.toArray(new TreePath[0]));
    372430        // make sure that first path is visible
    373431        if (!paths.isEmpty()) {
Note: See TracChangeset for help on using the changeset viewer.