Ticket #17268: clear_ignored_errors_v16.patch

File clear_ignored_errors_v16.patch, 16.1 KB (added by taylor.smock, 5 years ago)

Change to a pop-up window that asks for "OK", "Reset", "Clear", and "Cancel". The ignorelist can be directly modified in this pane, and the method to add errors is now overloaded with the option to add a description.

  • src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java

     
    8585    private final SideButton fixButton;
    8686    /** The ignore button */
    8787    private final SideButton ignoreButton;
     88    /** The reset ignorelist button */
     89    private final SideButton ignorelistManagement;
    8890    /** The select button */
    8991    private final SideButton selectButton;
    9092    /** The lookup button */
     
    174176            });
    175177            ignoreButton.setEnabled(false);
    176178            buttons.add(ignoreButton);
     179
     180            if (!ValidatorPrefHelper.PREF_IGNORELIST_KEEP_BACKUP.get()) {
     181                // Clear the backup ignore list
     182                Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP, null);
     183            }
     184            ignorelistManagement = new SideButton(new AbstractAction() {
     185                {
     186                    putValue(NAME, tr("Manage Ignore"));
     187                    putValue(SHORT_DESCRIPTION, tr("Manage the ignore list"));
     188                    new ImageProvider("dialogs", "fix").getResource().attachImageIcon(this, true);
     189                }
     190
     191                @Override
     192                public void actionPerformed(ActionEvent e) {
     193                    IgnoreListManagementDialog dialog = new IgnoreListManagementDialog();
     194                    if (dialog.getValue() == 1) {
     195                        // TODO save
     196                    }
     197                }
     198            });
     199            buttons.add(ignorelistManagement);
    177200        } else {
    178201            ignoreButton = null;
     202            ignorelistManagement = null;
    179203        }
     204
    180205        createLayout(tree, true, buttons);
    181206    }
    182207
     
    287312    /**
    288313     * Sets the selection of the map to the current selected items.
    289314     */
    290     @SuppressWarnings("unchecked")
    291315    private void setSelectedItems() {
    292316        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
    293317        if (tree == null || ds == null)
  • 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("dialogs", "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).isBlank()) {
     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.isBlank()) {
     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/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/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    }