Ticket #17268: clear_ignored_errors_v17.patch

File clear_ignored_errors_v17.patch, 18.2 KB (added by GerdP, 7 years ago)

isBlank() -> isEmpty(), add description in ValidatorDialog

  • src/org/openstreetmap/josm/data/preferences/sources/ValidatorPrefHelper.java

     
    4444    /** The preferences for ignored severity other */
    4545    public static final BooleanProperty PREF_OTHER = new BooleanProperty(PREFIX + ".other", false);
    4646
     47    /** The preferences key for the ignorelist */
     48    public static final String PREF_IGNORELIST = PREFIX + ".ignorelist";
     49
     50    /** The preferences key for the ignorelist backup */
     51    public static final String PREF_IGNORELIST_BACKUP = PREFIX + ".ignorelist.bak";
     52
     53    /** The preferences key for whether or not the ignorelist backup should be cleared on start */
     54    public static final BooleanProperty PREF_IGNORELIST_KEEP_BACKUP = new BooleanProperty(PREFIX + ".ignorelist.bak.keep", false);
     55
    4756    /**
    4857     * The preferences key for enabling the permanent filtering
    4958     * of the displayed errors in the tree regarding the current selection
     
    5059     */
    5160    public static final String PREF_FILTER_BY_SELECTION = PREFIX + ".selectionFilter";
    5261
    53     /**
    54      * Constructs a new {@code PresetPrefHelper}.
    55      */
    5662    public ValidatorPrefHelper() {
    5763        super(MapCSSTagChecker.ENTRIES_PREF_KEY, SourceType.TAGCHECKER_RULE);
    5864    }
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

     
    77import java.io.File;
    88import java.io.FileNotFoundException;
    99import java.io.IOException;
    10 import java.io.PrintWriter;
    1110import java.nio.charset.StandardCharsets;
    1211import java.nio.file.Files;
    1312import java.nio.file.Path;
     
    8887    /** Grid detail, multiplier of east,north values for valuable cell sizing */
    8988    private static double griddetail;
    9089
    91     private static final Collection<String> ignoredErrors = new TreeSet<>();
    92 
     90    private static final HashMap<String, String> ignoredErrors = new HashMap<>();
    9391    /**
    9492     * All registered tests
    9593     */
     
    204202    private static void loadIgnoredErrors() {
    205203        ignoredErrors.clear();
    206204        if (ValidatorPrefHelper.PREF_USE_IGNORE.get()) {
     205            Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST).forEach(map -> {
     206                ignoredErrors.putAll(map);
     207            });
    207208            Path path = Paths.get(getValidatorDir()).resolve("ignorederrors");
    208209            try {
    209210                if (path.toFile().exists()) {
    210211                    try {
    211                         ignoredErrors.addAll(Files.readAllLines(path, StandardCharsets.UTF_8));
     212                        TreeSet<String> treeSet = new TreeSet<>();
     213                        treeSet.addAll(Files.readAllLines(path, StandardCharsets.UTF_8));
     214                        treeSet.forEach(ignore -> {
     215                            ignoredErrors.putIfAbsent(ignore, "");
     216                        });
     217
     218                        saveIgnoredErrors();
     219                        Files.deleteIfExists(path);
    212220                    } catch (FileNotFoundException e) {
    213221                        Logging.debug(Logging.getErrorMessage(e));
    214222                    } catch (IOException e) {
     
    228236     * @see TestError#getIgnoreSubGroup()
    229237     */
    230238    public static void addIgnoredError(String s) {
    231         ignoredErrors.add(s);
     239        addIgnoredError(s, "");
    232240    }
    233241
    234242    /**
     243     * Adds an ignored error
     244     * @param s The ignore group / sub group name
     245     * @param description What the error actually is
     246     * @see TestError#getIgnoreGroup()
     247     * @see TestError#getIgnoreSubGroup()
     248     */
     249    public static void addIgnoredError(String s, String description) {
     250        ignoredErrors.put(s, description);
     251    }
     252
     253    /**
    235254     * Check if a error should be ignored
    236255     * @param s The ignore group / sub group name
    237256     * @return <code>true</code> to ignore that error
    238257     */
    239258    public static boolean hasIgnoredError(String s) {
    240         return ignoredErrors.contains(s);
     259        return ignoredErrors.containsKey(s);
    241260    }
    242261
    243262    /**
    244      * Saves the names of the ignored errors to a file
     263     * Get the list of all ignored errors
     264     * @return The <code>Collection&ltString&gt</code> of errors that are ignored
    245265     */
     266    public static HashMap<String, String> getIgnoredErrors() {
     267        return ignoredErrors;
     268    }
     269
     270    /**
     271     * Reset the error list by deleting ignorederrors
     272     */
     273    public static void resetErrorList() {
     274        saveIgnoredErrors();
     275        backupErrorList();
     276        Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, null);
     277        OsmValidator.initialize();
     278    }
     279
     280    /**
     281     * Restore the error list by copying ignorederrors.bak to ignorederrors
     282     */
     283    public static void restoreErrorList() {
     284        saveIgnoredErrors();
     285        List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP);
     286        backupErrorList();
     287        Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, tlist);
     288        OsmValidator.initialize();
     289    }
     290
     291    private static void backupErrorList() {
     292        List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, null);
     293        Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP, tlist);
     294    }
     295
     296    /**
     297     * Saves the names of the ignored errors to a preference
     298     */
    246299    public static void saveIgnoredErrors() {
    247         try (PrintWriter out = new PrintWriter(new File(getValidatorDir(), "ignorederrors"), StandardCharsets.UTF_8.name())) {
    248             for (String e : ignoredErrors) {
    249                 out.println(e);
     300        List<Map<String, String>> list = new ArrayList<>();
     301        list.add(ignoredErrors);
     302        int i = 0;
     303        while (i < list.size()) {
     304            if (list.get(i) == null || list.get(i).isEmpty()) {
     305                list.remove(i);
     306                continue;
    250307            }
    251         } catch (IOException e) {
    252             Logging.error(e);
     308            i++;
    253309        }
     310        if (list.isEmpty()) list = null;
     311        Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, list);
    254312    }
    255313
    256314    /**
  • src/org/openstreetmap/josm/gui/dialogs/IgnoreListManagementDialog.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.dialogs;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.GridBagLayout;
     7import java.awt.event.ActionEvent;
     8import java.util.HashMap;
     9import java.util.List;
     10
     11import javax.swing.ImageIcon;
     12import javax.swing.JOptionPane;
     13import javax.swing.JPanel;
     14import javax.swing.JScrollPane;
     15import javax.swing.JTextArea;
     16
     17import org.openstreetmap.josm.actions.ValidateAction;
     18import org.openstreetmap.josm.data.validation.OsmValidator;
     19import org.openstreetmap.josm.data.validation.TestError;
     20import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
     21import org.openstreetmap.josm.gui.ExtendedDialog;
     22import org.openstreetmap.josm.gui.MainApplication;
     23import org.openstreetmap.josm.gui.MapFrame;
     24import org.openstreetmap.josm.gui.util.GuiHelper;
     25import org.openstreetmap.josm.tools.GBC;
     26import org.openstreetmap.josm.tools.ImageProvider;
     27import org.openstreetmap.josm.tools.Logging;
     28
     29
     30/**
     31 * A management window for the validator's ignorelist
     32 * @author Taylor Smock
     33 * @since xxx
     34 */
     35public class IgnoreListManagementDialog extends ExtendedDialog {
     36    enum BUTTONS {
     37        OK(0, tr("OK"), new ImageProvider("ok")),
     38        CLEAR(1, tr("Clear"), new ImageProvider("dialogs", "fix")),
     39        RESTORE(2, tr("Restore"), new ImageProvider("copy")),
     40        CANCEL(3, tr("Cancel"), new ImageProvider("cancel"));
     41
     42        private int index;
     43        private String name;
     44        private ImageIcon icon;
     45
     46        BUTTONS(int index, String name, ImageProvider image) {
     47            this.index = index;
     48            this.name = name;
     49            this.icon = image.getResource().getImageIcon();
     50        }
     51
     52        public ImageIcon getImageIcon() {
     53            return icon;
     54        }
     55
     56        public int getIndex() {
     57            return index;
     58        }
     59
     60        public String getName() {
     61            return name;
     62        }
     63    }
     64
     65    private static final String TITLE = tr("Ignore List Management");
     66
     67    private static final String[] BUTTON_TEXTS = {BUTTONS.OK.getName(), BUTTONS.CLEAR.getName(),
     68            BUTTONS.RESTORE.getName(), BUTTONS.CANCEL.getName()
     69    };
     70
     71    private static final ImageIcon[] BUTTON_IMAGES = {BUTTONS.OK.getImageIcon(), BUTTONS.CLEAR.getImageIcon(),
     72            BUTTONS.RESTORE.getImageIcon(), BUTTONS.CANCEL.getImageIcon()
     73    };
     74
     75    private final JPanel panel = new JPanel(new GridBagLayout());
     76
     77    private final JTextArea ignoreErrors;
     78
     79    private String initialText;
     80
     81    /**
     82     * Create a new {@link IgnoreListManagementDialog}
     83     */
     84    public IgnoreListManagementDialog() {
     85        super(MainApplication.getMainFrame(), TITLE, BUTTON_TEXTS, false);
     86        setButtonIcons(BUTTON_IMAGES);
     87
     88        ignoreErrors = buildIgnoreErrorList();
     89        JScrollPane scroll = GuiHelper.embedInVerticalScrollPane(ignoreErrors);
     90
     91        panel.add(scroll, GBC.eol().fill(GBC.BOTH).anchor(GBC.CENTER));
     92        setContent(panel);
     93        setDefaultButton(1);
     94        setupDialog();
     95        showDialog();
     96    }
     97
     98    @Override
     99    public void buttonAction(int buttonIndex, ActionEvent evt) {
     100        // Currently OK/Cancel buttons do nothing
     101        if (buttonIndex == BUTTONS.RESTORE.getIndex()) {
     102            dispose();
     103            final int answer = rerunValidatorPrompt();
     104            if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) {
     105                OsmValidator.restoreErrorList();
     106            }
     107        } else if (buttonIndex == BUTTONS.CLEAR.getIndex()) {
     108            dispose();
     109            final int answer = rerunValidatorPrompt();
     110            if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) {
     111                OsmValidator.resetErrorList();
     112            }
     113        } else if (buttonIndex == BUTTONS.OK.getIndex()) {
     114            dispose();
     115            String text = ignoreErrors.getText();
     116            if (!initialText.equals(text)) {
     117                String[] textArray = text.split(System.lineSeparator());
     118                Logging.debug(initialText);
     119                Logging.debug(text);
     120                final int answer = rerunValidatorPrompt();
     121                if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) {
     122                    HashMap<String, String> map = new HashMap<>();
     123                    map.putAll(OsmValidator.getIgnoredErrors());
     124                    OsmValidator.resetErrorList();
     125                    for (String line : textArray) {
     126                        if (line.equals("/* " + tr("There are no ignored errors") + " */")) continue;
     127                        String[] lineparts = line.split(" /\\* ");
     128                        if (lineparts.length == 1) {
     129                            OsmValidator.addIgnoredError(lineparts[0]);
     130                        } else if (lineparts.length == 2) {
     131                            OsmValidator.addIgnoredError(lineparts[0], lineparts[1].replace(" */", ""));
     132                        }
     133                    }
     134                }
     135            }
     136        } else {
     137            super.buttonAction(buttonIndex, evt);
     138        }
     139    }
     140
     141    /**
     142     * Build a JTextArea with the ignorelist
     143     * @return ignorelist as a JTextArea
     144     */
     145    public JTextArea buildIgnoreErrorList() {
     146        String displayText = "";
     147        HashMap<String, String> map = OsmValidator.getIgnoredErrors();
     148        if (map.isEmpty()) {
     149            OsmValidator.initialize();
     150            map = OsmValidator.getIgnoredErrors();
     151        }
     152        for (String key : map.keySet()) {
     153            String ignore = key;
     154            if (map.get(key) != null && !map.get(key).isEmpty()) {
     155                ignore += " /* " + map.get(key) + " */";
     156            }
     157            ignore += System.lineSeparator();
     158            Logging.debug(ignore);
     159            displayText += ignore;
     160        }
     161        JTextArea text = new JTextArea();
     162        if (displayText.isEmpty()) {
     163            displayText = "/* " + tr("There are no ignored errors") + " */";
     164        }
     165        text.setText(displayText);
     166        initialText = displayText;
     167        return text;
     168    }
     169
     170    /**
     171     * Prompt to rerun the validator when the ignore list changes
     172     * @return {@code JOptionPane.YES_OPTION}, {@code JOptionPane.NO_OPTION},
     173     *  or {@code JOptionPane.CANCEL_OPTION}
     174     */
     175    public int rerunValidatorPrompt() {
     176        MapFrame map = MainApplication.getMap();
     177        List<TestError> errors = map.validatorDialog.tree.getErrors();
     178        ValidateAction validateAction = ValidatorDialog.validateAction;
     179        if (!validateAction.isEnabled() || errors == null || errors.isEmpty()) return JOptionPane.NO_OPTION;
     180        final int answer = ConditionalOptionPaneUtil.showOptionDialog(
     181                "rerun_validation_when_ignorelist_changed",
     182                MainApplication.getMainFrame(),
     183                "<hmtl><h3>" + tr("Should the validation be rerun?") + "</h3></html>",
     184                tr("Ignored error filter changed"),
     185                JOptionPane.YES_NO_CANCEL_OPTION,
     186                JOptionPane.QUESTION_MESSAGE,
     187                null,
     188                null);
     189        if (answer == JOptionPane.YES_OPTION) {
     190            validateAction.doValidate(true);
     191        }
     192        return answer;
     193    }
     194}
  • src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java

     
    6363import org.openstreetmap.josm.tools.ImageProvider;
    6464import org.openstreetmap.josm.tools.InputMapUtils;
    6565import org.openstreetmap.josm.tools.JosmRuntimeException;
     66import org.openstreetmap.josm.tools.Pair;
    6667import org.openstreetmap.josm.tools.Shortcut;
    6768import org.xml.sax.SAXException;
    6869
     
    8586    private final SideButton fixButton;
    8687    /** The ignore button */
    8788    private final SideButton ignoreButton;
     89    /** The reset ignorelist button */
     90    private final SideButton ignorelistManagement;
    8891    /** The select button */
    8992    private final SideButton selectButton;
    9093    /** The lookup button */
     
    174177            });
    175178            ignoreButton.setEnabled(false);
    176179            buttons.add(ignoreButton);
     180
     181            if (!ValidatorPrefHelper.PREF_IGNORELIST_KEEP_BACKUP.get()) {
     182                // Clear the backup ignore list
     183                Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP, null);
     184            }
     185            ignorelistManagement = new SideButton(new AbstractAction() {
     186                {
     187                    putValue(NAME, tr("Manage Ignore"));
     188                    putValue(SHORT_DESCRIPTION, tr("Manage the ignore list"));
     189                    new ImageProvider("dialogs", "fix").getResource().attachImageIcon(this, true);
     190                }
     191
     192                @Override
     193                public void actionPerformed(ActionEvent e) {
     194                    IgnoreListManagementDialog dialog = new IgnoreListManagementDialog();
     195                    if (dialog.getValue() == 1) {
     196                        // TODO save
     197                    }
     198                }
     199            });
     200            buttons.add(ignorelistManagement);
    177201        } else {
    178202            ignoreButton = null;
     203            ignorelistManagement = null;
    179204        }
     205
    180206        createLayout(tree, true, buttons);
    181207    }
    182208
     
    245271
    246272            Object mainNodeInfo = node.getUserObject();
    247273            if (!(mainNodeInfo instanceof TestError)) {
    248                 Set<String> state = new HashSet<>();
     274                Set<Pair<String,String>> state = new HashSet<>();
    249275                // ask if the whole set should be ignored
    250276                if (asked == JOptionPane.DEFAULT_OPTION) {
    251277                    String[] a = new String[] {tr("Whole group"), tr("Single elements"), tr("Nothing")};
     
    257283                    ValidatorTreePanel.visitTestErrors(node, err -> {
    258284                        err.setIgnored(true);
    259285                        changed.set(true);
    260                         state.add(node.getDepth() == 1 ? err.getIgnoreSubGroup() : err.getIgnoreGroup());
     286                        state.add(new Pair<>(node.getDepth() == 1 ? err.getIgnoreSubGroup() : err.getIgnoreGroup(), err.getMessage()));
    261287                    }, processedNodes);
    262                     for (String s : state) {
    263                         OsmValidator.addIgnoredError(s);
     288                    for (Pair<String, String> s : state) {
     289                        OsmValidator.addIgnoredError(s.a, s.b);
    264290                    }
    265291                    continue;
    266292                } else if (asked == JOptionPane.CANCEL_OPTION || asked == JOptionPane.CLOSED_OPTION) {
     
    271297            ValidatorTreePanel.visitTestErrors(node, error -> {
    272298                String state = error.getIgnoreState();
    273299                if (state != null) {
    274                     OsmValidator.addIgnoredError(state);
     300                    OsmValidator.addIgnoredError(state, error.getMessage());
    275301                }
    276302                changed.set(true);
    277303                error.setIgnored(true);
     
    287313    /**
    288314     * Sets the selection of the map to the current selected items.
    289315     */
    290     @SuppressWarnings("unchecked")
    291316    private void setSelectedItems() {
    292317        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
    293318        if (tree == null || ds == null)