Ticket #17268: clear_ignored_errors_v19.patch
File clear_ignored_errors_v19.patch, 18.2 KB (added by , 5 years ago) |
---|
-
src/org/openstreetmap/josm/data/preferences/sources/ValidatorPrefHelper.java
44 44 /** The preferences for ignored severity other */ 45 45 public static final BooleanProperty PREF_OTHER = new BooleanProperty(PREFIX + ".other", false); 46 46 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 47 56 /** 48 57 * The preferences key for enabling the permanent filtering 49 58 * of the displayed errors in the tree regarding the current selection … … 50 59 */ 51 60 public static final String PREF_FILTER_BY_SELECTION = PREFIX + ".selectionFilter"; 52 61 53 /**54 * Constructs a new {@code PresetPrefHelper}.55 */56 62 public ValidatorPrefHelper() { 57 63 super(MapCSSTagChecker.ENTRIES_PREF_KEY, SourceType.TAGCHECKER_RULE); 58 64 } -
src/org/openstreetmap/josm/data/validation/OsmValidator.java
7 7 import java.io.File; 8 8 import java.io.FileNotFoundException; 9 9 import java.io.IOException; 10 import java.io.PrintWriter;11 10 import java.nio.charset.StandardCharsets; 12 11 import java.nio.file.Files; 13 12 import java.nio.file.Path; … … 88 87 /** Grid detail, multiplier of east,north values for valuable cell sizing */ 89 88 private static double griddetail; 90 89 91 private static final Collection<String> ignoredErrors = new TreeSet<>(); 92 90 private static final HashMap<String, String> ignoredErrors = new HashMap<>(); 93 91 /** 94 92 * All registered tests 95 93 */ … … 204 202 private static void loadIgnoredErrors() { 205 203 ignoredErrors.clear(); 206 204 if (ValidatorPrefHelper.PREF_USE_IGNORE.get()) { 205 Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST).forEach(map -> { 206 ignoredErrors.putAll(map); 207 }); 207 208 Path path = Paths.get(getValidatorDir()).resolve("ignorederrors"); 208 209 try { 209 210 if (path.toFile().exists()) { 210 211 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); 212 220 } catch (FileNotFoundException e) { 213 221 Logging.debug(Logging.getErrorMessage(e)); 214 222 } catch (IOException e) { … … 228 236 * @see TestError#getIgnoreSubGroup() 229 237 */ 230 238 public static void addIgnoredError(String s) { 231 ignoredErrors.add(s);239 addIgnoredError(s, ""); 232 240 } 233 241 234 242 /** 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 /** 235 254 * Check if a error should be ignored 236 255 * @param s The ignore group / sub group name 237 256 * @return <code>true</code> to ignore that error 238 257 */ 239 258 public static boolean hasIgnoredError(String s) { 240 return ignoredErrors.contains (s);259 return ignoredErrors.containsKey(s); 241 260 } 242 261 243 262 /** 244 * Saves the names of the ignored errors to a file 263 * Get the list of all ignored errors 264 * @return The <code>Collection<String></code> of errors that are ignored 245 265 */ 266 public static HashMap<String, String> getIgnoredErrors() { 267 return ignoredErrors; 268 } 269 270 /** 271 * Reset the error list by deleting {@code validator.ignorelist} 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 {@code validator.ignorelist.bak} to 282 * {@code validator.ignorelist} 283 */ 284 public static void restoreErrorList() { 285 saveIgnoredErrors(); 286 List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP); 287 backupErrorList(); 288 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, tlist); 289 OsmValidator.initialize(); 290 } 291 292 private static void backupErrorList() { 293 List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, null); 294 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP, tlist); 295 } 296 297 /** 298 * Saves the names of the ignored errors to a preference 299 */ 246 300 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); 301 List<Map<String, String>> list = new ArrayList<>(); 302 list.add(ignoredErrors); 303 int i = 0; 304 while (i < list.size()) { 305 if (list.get(i) == null || list.get(i).isEmpty()) { 306 list.remove(i); 307 continue; 250 308 } 251 } catch (IOException e) { 252 Logging.error(e); 309 i++; 253 310 } 311 if (list.isEmpty()) list = null; 312 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, list); 254 313 } 255 314 256 315 /** -
src/org/openstreetmap/josm/gui/dialogs/ValidatorListManagementDialog.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.dialogs; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.GridBagLayout; 7 import java.awt.event.ActionEvent; 8 import java.util.HashMap; 9 import java.util.List; 10 import java.util.Locale; 11 12 import javax.swing.ImageIcon; 13 import javax.swing.JOptionPane; 14 import javax.swing.JPanel; 15 import javax.swing.JScrollPane; 16 import javax.swing.JTable; 17 import javax.swing.table.TableModel; 18 19 import org.openstreetmap.josm.actions.ValidateAction; 20 import org.openstreetmap.josm.data.validation.OsmValidator; 21 import org.openstreetmap.josm.data.validation.TestError; 22 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 23 import org.openstreetmap.josm.gui.ExtendedDialog; 24 import org.openstreetmap.josm.gui.MainApplication; 25 import org.openstreetmap.josm.gui.MapFrame; 26 import org.openstreetmap.josm.gui.util.GuiHelper; 27 import org.openstreetmap.josm.tools.GBC; 28 import org.openstreetmap.josm.tools.ImageProvider; 29 import org.openstreetmap.josm.tools.Logging; 30 31 32 /** 33 * A management window for the validator's ignorelist 34 * @author Taylor Smock 35 * @since xxx 36 */ 37 public class ValidatorListManagementDialog extends ExtendedDialog { 38 enum BUTTONS { 39 OK(0, tr("OK"), new ImageProvider("ok")), 40 CLEAR(1, tr("Clear"), new ImageProvider("dialogs", "fix")), 41 RESTORE(2, tr("Restore"), new ImageProvider("copy")), 42 CANCEL(3, tr("Cancel"), new ImageProvider("cancel")); 43 44 private int index; 45 private String name; 46 private ImageIcon icon; 47 48 BUTTONS(int index, String name, ImageProvider image) { 49 this.index = index; 50 this.name = name; 51 this.icon = image.getResource().getImageIcon(); 52 } 53 54 public ImageIcon getImageIcon() { 55 return icon; 56 } 57 58 public int getIndex() { 59 return index; 60 } 61 62 public String getName() { 63 return name; 64 } 65 } 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 JTable ignoreErrors; 78 79 private final String type; 80 81 /** 82 * Create a new {@link ValidatorListManagementDialog} 83 * @param type The type of list to create (first letter may or may not be 84 * capitalized, it is put into all lowercase after building the title) 85 */ 86 public ValidatorListManagementDialog(String type) { 87 super(MainApplication.getMainFrame(), tr("Validator {0} List Management", type), BUTTON_TEXTS, false); 88 this.type = type.toLowerCase(Locale.ENGLISH); 89 setButtonIcons(BUTTON_IMAGES); 90 91 ignoreErrors = buildList(); 92 JScrollPane scroll = GuiHelper.embedInVerticalScrollPane(ignoreErrors); 93 94 panel.add(scroll, GBC.eol().fill(GBC.BOTH).anchor(GBC.CENTER)); 95 setContent(panel); 96 setDefaultButton(1); 97 setupDialog(); 98 showDialog(); 99 } 100 101 @Override 102 public void buttonAction(int buttonIndex, ActionEvent evt) { 103 // Currently OK/Cancel buttons do nothing 104 final int answer; 105 if (buttonIndex == BUTTONS.RESTORE.getIndex()) { 106 dispose(); 107 answer = rerunValidatorPrompt(); 108 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 109 OsmValidator.restoreErrorList(); 110 } 111 } else if (buttonIndex == BUTTONS.CLEAR.getIndex()) { 112 dispose(); 113 answer = rerunValidatorPrompt(); 114 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 115 OsmValidator.resetErrorList(); 116 } 117 } else if (buttonIndex == BUTTONS.OK.getIndex()) { 118 dispose(); 119 answer = rerunValidatorPrompt(); 120 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 121 TableModel model = ignoreErrors.getModel(); 122 if (model.getColumnCount() != 2) { 123 Logging.error("We only expect two columns for ignoreErrors.getModel(): actual = {0}", 124 model.getColumnCount()); 125 } 126 OsmValidator.resetErrorList(); 127 for (int i = 0; i < model.getRowCount(); i++) { 128 OsmValidator.addIgnoredError((String) model.getValueAt(i, 0), 129 (String) model.getValueAt(i, 1)); 130 } 131 OsmValidator.saveIgnoredErrors(); 132 OsmValidator.initialize(); 133 } 134 } else { 135 super.buttonAction(buttonIndex, evt); 136 } 137 } 138 139 /** 140 * Build a JTextArea with a list 141 * @return <type>list as a JTextArea 142 */ 143 public JTable buildList() { 144 HashMap<String, String> map; 145 if ("ignore".equals(type)) { 146 map = OsmValidator.getIgnoredErrors(); 147 if (map.isEmpty()) { 148 OsmValidator.initialize(); 149 map = OsmValidator.getIgnoredErrors(); 150 } 151 } else { 152 Logging.error(tr("Cannot understand the following type: {0}", type)); 153 return null; 154 } 155 156 String[][] content = new String[map.size()][2]; 157 int i = 0; 158 for (String key : map.keySet()) { 159 String value = map.get(key); 160 content[i][0] = key; 161 if (value != null && !value.isEmpty()) { 162 content[i][1] = value; 163 } else { 164 content[i][1] = ""; 165 } 166 i++; 167 // This is needed, since otherwise there may be a NPE 168 if (i >= map.size()) break; 169 } 170 171 String[] header = new String[] {tr("Errors"), tr("Description") }; 172 return new JTable(content, header); 173 } 174 175 /** 176 * Prompt to rerun the validator when the ignore list changes 177 * @return {@code JOptionPane.YES_OPTION}, {@code JOptionPane.NO_OPTION}, 178 * or {@code JOptionPane.CANCEL_OPTION} 179 */ 180 public int rerunValidatorPrompt() { 181 MapFrame map = MainApplication.getMap(); 182 List<TestError> errors = map.validatorDialog.tree.getErrors(); 183 ValidateAction validateAction = ValidatorDialog.validateAction; 184 if (!validateAction.isEnabled() || errors == null || errors.isEmpty()) return JOptionPane.NO_OPTION; 185 final int answer = ConditionalOptionPaneUtil.showOptionDialog( 186 "rerun_validation_when_ignorelist_changed", 187 MainApplication.getMainFrame(), 188 tr("{0}Should the validation be rerun?{1}", "<hmtl><h3>", "</h3></html>"), 189 tr("Ignored error filter changed"), 190 JOptionPane.YES_NO_CANCEL_OPTION, 191 JOptionPane.QUESTION_MESSAGE, 192 null, 193 null); 194 if (answer == JOptionPane.YES_OPTION) { 195 validateAction.doValidate(true); 196 } 197 return answer; 198 } 199 } -
src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java
63 63 import org.openstreetmap.josm.tools.ImageProvider; 64 64 import org.openstreetmap.josm.tools.InputMapUtils; 65 65 import org.openstreetmap.josm.tools.JosmRuntimeException; 66 import org.openstreetmap.josm.tools.Pair; 66 67 import org.openstreetmap.josm.tools.Shortcut; 67 68 import org.xml.sax.SAXException; 68 69 … … 85 86 private final SideButton fixButton; 86 87 /** The ignore button */ 87 88 private final SideButton ignoreButton; 89 /** The reset ignorelist button */ 90 private final SideButton ignorelistManagement; 88 91 /** The select button */ 89 92 private final SideButton selectButton; 90 93 /** The lookup button */ … … 174 177 }); 175 178 ignoreButton.setEnabled(false); 176 179 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 ValidatorListManagementDialog dialog = new ValidatorListManagementDialog("Ignore"); 195 if (dialog.getValue() == 1) { 196 // TODO save 197 } 198 } 199 }); 200 buttons.add(ignorelistManagement); 177 201 } else { 178 202 ignoreButton = null; 203 ignorelistManagement = null; 179 204 } 205 180 206 createLayout(tree, true, buttons); 181 207 } 182 208 … … 245 271 246 272 Object mainNodeInfo = node.getUserObject(); 247 273 if (!(mainNodeInfo instanceof TestError)) { 248 Set< String> state = new HashSet<>();274 Set<Pair<String, String>> state = new HashSet<>(); 249 275 // ask if the whole set should be ignored 250 276 if (asked == JOptionPane.DEFAULT_OPTION) { 251 277 String[] a = new String[] {tr("Whole group"), tr("Single elements"), tr("Nothing")}; … … 257 283 ValidatorTreePanel.visitTestErrors(node, err -> { 258 284 err.setIgnored(true); 259 285 changed.set(true); 260 state.add(n ode.getDepth() == 1 ? err.getIgnoreSubGroup() : err.getIgnoreGroup());286 state.add(new Pair<>(node.getDepth() == 1 ? err.getIgnoreSubGroup() : err.getIgnoreGroup(), err.getMessage())); 261 287 }, processedNodes); 262 for ( Strings : state) {263 OsmValidator.addIgnoredError(s );288 for (Pair<String, String> s : state) { 289 OsmValidator.addIgnoredError(s.a, s.b); 264 290 } 265 291 continue; 266 292 } else if (asked == JOptionPane.CANCEL_OPTION || asked == JOptionPane.CLOSED_OPTION) { … … 271 297 ValidatorTreePanel.visitTestErrors(node, error -> { 272 298 String state = error.getIgnoreState(); 273 299 if (state != null) { 274 OsmValidator.addIgnoredError(state );300 OsmValidator.addIgnoredError(state, error.getMessage()); 275 301 } 276 302 changed.set(true); 277 303 error.setIgnored(true); … … 287 313 /** 288 314 * Sets the selection of the map to the current selected items. 289 315 */ 290 @SuppressWarnings("unchecked")291 316 private void setSelectedItems() { 292 317 DataSet ds = MainApplication.getLayerManager().getActiveDataSet(); 293 318 if (tree == null || ds == null)