Ticket #17268: clear_ignored_errors_v20.patch
| File clear_ignored_errors_v20.patch, 18.7 KB (added by , 7 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.Enumeration; 9 import java.util.HashMap; 10 import java.util.List; 11 import java.util.Locale; 12 import java.util.TreeMap; 13 14 import javax.swing.ImageIcon; 15 import javax.swing.JOptionPane; 16 import javax.swing.JPanel; 17 import javax.swing.JScrollPane; 18 import javax.swing.JTree; 19 import javax.swing.tree.DefaultMutableTreeNode; 20 import javax.swing.tree.TreeNode; 21 22 import org.openstreetmap.josm.actions.ValidateAction; 23 import org.openstreetmap.josm.data.validation.OsmValidator; 24 import org.openstreetmap.josm.data.validation.TestError; 25 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 26 import org.openstreetmap.josm.gui.ExtendedDialog; 27 import org.openstreetmap.josm.gui.MainApplication; 28 import org.openstreetmap.josm.gui.MapFrame; 29 import org.openstreetmap.josm.gui.util.GuiHelper; 30 import org.openstreetmap.josm.tools.GBC; 31 import org.openstreetmap.josm.tools.ImageProvider; 32 import org.openstreetmap.josm.tools.Logging; 33 34 35 /** 36 * A management window for the validator's ignorelist 37 * @author Taylor Smock 38 * @since xxx 39 */ 40 public class ValidatorListManagementDialog extends ExtendedDialog { 41 enum BUTTONS { 42 OK(0, tr("OK"), new ImageProvider("ok")), 43 CLEAR(1, tr("Clear All"), new ImageProvider("dialogs", "fix")), 44 RESTORE(2, tr("Restore"), new ImageProvider("copy")), 45 CANCEL(3, tr("Cancel"), new ImageProvider("cancel")); 46 47 private int index; 48 private String name; 49 private ImageIcon icon; 50 51 BUTTONS(int index, String name, ImageProvider image) { 52 this.index = index; 53 this.name = name; 54 this.icon = image.getResource().getImageIcon(); 55 } 56 57 public ImageIcon getImageIcon() { 58 return icon; 59 } 60 61 public int getIndex() { 62 return index; 63 } 64 65 public String getName() { 66 return name; 67 } 68 } 69 70 private static final String[] BUTTON_TEXTS = {BUTTONS.OK.getName(), BUTTONS.CLEAR.getName(), 71 BUTTONS.RESTORE.getName(), BUTTONS.CANCEL.getName() 72 }; 73 74 private static final ImageIcon[] BUTTON_IMAGES = {BUTTONS.OK.getImageIcon(), BUTTONS.CLEAR.getImageIcon(), 75 BUTTONS.RESTORE.getImageIcon(), BUTTONS.CANCEL.getImageIcon() 76 }; 77 78 private final JPanel panel = new JPanel(new GridBagLayout()); 79 80 private final JTree ignoreErrors; 81 82 private final String type; 83 84 /** 85 * Create a new {@link ValidatorListManagementDialog} 86 * @param type The type of list to create (first letter may or may not be 87 * capitalized, it is put into all lowercase after building the title) 88 */ 89 public ValidatorListManagementDialog(String type) { 90 super(MainApplication.getMainFrame(), tr("Validator {0} List Management", type), BUTTON_TEXTS, false); 91 this.type = type.toLowerCase(Locale.ENGLISH); 92 setButtonIcons(BUTTON_IMAGES); 93 94 ignoreErrors = buildList(); 95 JScrollPane scroll = GuiHelper.embedInVerticalScrollPane(ignoreErrors); 96 97 panel.add(scroll, GBC.eol().fill(GBC.BOTH).anchor(GBC.CENTER)); 98 setContent(panel); 99 setDefaultButton(1); 100 setupDialog(); 101 showDialog(); 102 } 103 104 @Override 105 public void buttonAction(int buttonIndex, ActionEvent evt) { 106 // Currently OK/Cancel buttons do nothing 107 final int answer; 108 if (buttonIndex == BUTTONS.RESTORE.getIndex()) { 109 dispose(); 110 answer = rerunValidatorPrompt(); 111 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 112 OsmValidator.restoreErrorList(); 113 } 114 } else if (buttonIndex == BUTTONS.CLEAR.getIndex()) { 115 dispose(); 116 answer = rerunValidatorPrompt(); 117 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 118 OsmValidator.resetErrorList(); 119 } 120 } else if (buttonIndex == BUTTONS.OK.getIndex()) { 121 dispose(); 122 } else { 123 super.buttonAction(buttonIndex, evt); 124 } 125 } 126 127 private DefaultMutableTreeNode inTree(DefaultMutableTreeNode root, String name) { 128 Enumeration<TreeNode> trunks = root.children(); 129 while (trunks.hasMoreElements()) { 130 TreeNode ttrunk = trunks.nextElement(); 131 if (ttrunk instanceof DefaultMutableTreeNode) { 132 DefaultMutableTreeNode trunk = (DefaultMutableTreeNode) ttrunk; 133 if (name.equals(trunk.getUserObject())) { 134 return trunk; 135 } 136 } 137 } 138 return new DefaultMutableTreeNode(name); 139 } 140 141 /** 142 * Build a JTree with a list 143 * @return <type>list as a {@code JTree} 144 */ 145 public JTree buildList() { 146 TreeMap<String, String> map = new TreeMap<>(); 147 if ("ignore".equals(type)) { 148 HashMap<String, String> tmap; 149 tmap = OsmValidator.getIgnoredErrors(); 150 if (tmap.isEmpty()) { 151 OsmValidator.initialize(); 152 tmap = OsmValidator.getIgnoredErrors(); 153 } 154 map.putAll(tmap); 155 } else { 156 Logging.error(tr("Cannot understand the following type: {0}", type)); 157 return null; 158 } 159 DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("{0} list", type)); 160 161 for (String key : map.keySet()) { 162 String value = map.get(key); 163 String[] osmobjects = key.split(":(r|w|n)_"); 164 DefaultMutableTreeNode trunk; 165 DefaultMutableTreeNode branch; 166 167 if (value != null && !value.isEmpty()) { 168 trunk = inTree(root, value); 169 branch = inTree(trunk, osmobjects[0]); 170 trunk.add(branch); 171 } else { 172 trunk = inTree(root, osmobjects[0]); 173 branch = trunk; 174 } 175 for (int i = 1; i < osmobjects.length; i++) { 176 String osmid = osmobjects[i]; 177 int index = key.indexOf(osmid); 178 char type = key.charAt(index - 2); 179 DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(type + "_" + osmid); 180 branch.add(leaf); 181 } 182 root.add(trunk); 183 } 184 JTree tree = new JTree(root); 185 tree.setRootVisible(false); 186 return tree; 187 } 188 189 /** 190 * Prompt to rerun the validator when the ignore list changes 191 * @return {@code JOptionPane.YES_OPTION}, {@code JOptionPane.NO_OPTION}, 192 * or {@code JOptionPane.CANCEL_OPTION} 193 */ 194 public int rerunValidatorPrompt() { 195 MapFrame map = MainApplication.getMap(); 196 List<TestError> errors = map.validatorDialog.tree.getErrors(); 197 ValidateAction validateAction = ValidatorDialog.validateAction; 198 if (!validateAction.isEnabled() || errors == null || errors.isEmpty()) return JOptionPane.NO_OPTION; 199 final int answer = ConditionalOptionPaneUtil.showOptionDialog( 200 "rerun_validation_when_ignorelist_changed", 201 MainApplication.getMainFrame(), 202 tr("{0}Should the validation be rerun?{1}", "<hmtl><h3>", "</h3></html>"), 203 tr("Ignored error filter changed"), 204 JOptionPane.YES_NO_CANCEL_OPTION, 205 JOptionPane.QUESTION_MESSAGE, 206 null, 207 null); 208 if (answer == JOptionPane.YES_OPTION) { 209 validateAction.doValidate(true); 210 } 211 return answer; 212 } 213 } -
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)
