Ticket #17268: clear_ignored_errors_v28.patch
File clear_ignored_errors_v28.patch, 27.1 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 -
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; … … 17 16 import java.util.Collection; 18 17 import java.util.Collections; 19 18 import java.util.EnumMap; 19 import java.util.Enumeration; 20 20 import java.util.HashMap; 21 import java.util.Iterator; 21 22 import java.util.List; 22 23 import java.util.Map; 24 import java.util.Map.Entry; 23 25 import java.util.SortedMap; 24 26 import java.util.TreeMap; 25 27 import java.util.TreeSet; … … 27 29 import java.util.stream.Collectors; 28 30 29 31 import javax.swing.JOptionPane; 32 import javax.swing.JTree; 33 import javax.swing.tree.DefaultMutableTreeNode; 34 import javax.swing.tree.TreeModel; 35 import javax.swing.tree.TreeNode; 30 36 31 37 import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; 32 38 import org.openstreetmap.josm.data.projection.ProjectionRegistry; … … 88 94 /** Grid detail, multiplier of east,north values for valuable cell sizing */ 89 95 private static double griddetail; 90 96 91 private static final Collection<String> ignoredErrors = new TreeSet<>(); 92 97 private static final SortedMap<String, String> ignoredErrors = new TreeMap<>(); 93 98 /** 94 99 * All registered tests 95 100 */ … … 169 174 public static void initialize() { 170 175 checkValidatorDir(); 171 176 initializeGridDetail(); 172 loadIgnoredErrors(); //FIXME: load only when needed177 loadIgnoredErrors(); 173 178 } 174 179 175 180 /** … … 204 209 private static void loadIgnoredErrors() { 205 210 ignoredErrors.clear(); 206 211 if (ValidatorPrefHelper.PREF_USE_IGNORE.get()) { 212 Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST).forEach(ignoredErrors::putAll); 207 213 Path path = Paths.get(getValidatorDir()).resolve("ignorederrors"); 208 214 try { 209 215 if (path.toFile().exists()) { 210 216 try { 211 ignoredErrors.addAll(Files.readAllLines(path, StandardCharsets.UTF_8)); 217 TreeSet<String> treeSet = new TreeSet<>(); 218 treeSet.addAll(Files.readAllLines(path, StandardCharsets.UTF_8)); 219 treeSet.forEach(ignore -> ignoredErrors.putIfAbsent(ignore, "")); 220 221 saveIgnoredErrors(); 222 Files.deleteIfExists(path); 223 212 224 } catch (FileNotFoundException e) { 213 225 Logging.debug(Logging.getErrorMessage(e)); 214 226 } catch (IOException e) { … … 228 240 * @see TestError#getIgnoreSubGroup() 229 241 */ 230 242 public static void addIgnoredError(String s) { 231 ignoredErrors.add(s);243 addIgnoredError(s, ""); 232 244 } 233 245 234 246 /** 247 * Adds an ignored error 248 * @param s The ignore group / sub group name 249 * @param description What the error actually is 250 * @see TestError#getIgnoreGroup() 251 * @see TestError#getIgnoreSubGroup() 252 */ 253 public static void addIgnoredError(String s, String description) { 254 if (description == null) description = ""; 255 ignoredErrors.put(s, description); 256 } 257 258 /** 259 * Make sure that we don't keep single entries for a "group ignore" or 260 * multiple different entries for the single entries that are in the same group. 261 */ 262 private static void cleanupIgnoredErrors() { 263 if (ignoredErrors.size() > 1) { 264 List<String> toRemove = new ArrayList<>(); 265 266 Iterator<Entry<String, String>> iter = ignoredErrors.entrySet().iterator(); 267 Entry<String, String> last = iter.next(); 268 while (iter.hasNext()) { 269 Entry<String, String> entry = iter.next(); 270 if (entry.getKey().startsWith(last.getKey())) { 271 toRemove.add(entry.getKey()); 272 } else { 273 last = entry; 274 } 275 } 276 toRemove.forEach(ignoredErrors::remove); 277 } 278 279 Map<String, String> tmap = buildIgnore(buildJTreeList()); 280 if (tmap != null && !tmap.isEmpty()) { 281 ignoredErrors.clear(); 282 ignoredErrors.putAll(tmap); 283 } 284 } 285 286 /** 235 287 * Check if a error should be ignored 236 288 * @param s The ignore group / sub group name 237 289 * @return <code>true</code> to ignore that error 238 290 */ 239 291 public static boolean hasIgnoredError(String s) { 240 return ignoredErrors.contains (s);292 return ignoredErrors.containsKey(s); 241 293 } 242 294 243 295 /** 244 * Saves the names of the ignored errors to a file 296 * Get the list of all ignored errors 297 * @return The <code>Collection<String></code> of errors that are ignored 245 298 */ 299 public static SortedMap<String, String> getIgnoredErrors() { 300 return ignoredErrors; 301 } 302 303 /** 304 * Build a JTree with a list 305 * @return <type>list as a {@code JTree} 306 */ 307 public static JTree buildJTreeList() { 308 DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("Ignore list")); 309 for (Entry<String, String> e: ignoredErrors.entrySet()) { 310 String key = e.getKey(); 311 String value = e.getValue(); 312 ArrayList<String> ignoredWayList = new ArrayList<>(); 313 String[] osmobjects = key.split(":(r|w|n)_"); 314 for (int i = 1; i < osmobjects.length; i++) { 315 String osmid = osmobjects[i]; 316 if (osmid.matches("^[0-9]+$")) { 317 osmid = '_' + osmid; 318 int index = key.indexOf(osmid); 319 if (index < key.lastIndexOf(']')) continue; 320 char type = key.charAt(index - 1); 321 ignoredWayList.add(type + osmid); 322 } 323 } 324 for (String osmignore : ignoredWayList) { 325 key = key.replace(':' + osmignore, ""); 326 } 327 328 DefaultMutableTreeNode trunk; 329 DefaultMutableTreeNode branch; 330 331 if (value != null && !value.isEmpty()) { 332 trunk = inTree(root, value); 333 branch = inTree(trunk, key); 334 trunk.add(branch); 335 } else { 336 trunk = inTree(root, key); 337 branch = trunk; 338 } 339 ignoredWayList.forEach(osmignore -> branch.add(new DefaultMutableTreeNode(osmignore))); 340 341 root.add(trunk); 342 } 343 return new JTree(root); 344 } 345 346 private static DefaultMutableTreeNode inTree(DefaultMutableTreeNode root, String name) { 347 @SuppressWarnings("unchecked") 348 Enumeration<TreeNode> trunks = root.children(); 349 while (trunks.hasMoreElements()) { 350 TreeNode ttrunk = trunks.nextElement(); 351 if (ttrunk instanceof DefaultMutableTreeNode) { 352 DefaultMutableTreeNode trunk = (DefaultMutableTreeNode) ttrunk; 353 if (name.equals(trunk.getUserObject())) { 354 return trunk; 355 } 356 } 357 } 358 return new DefaultMutableTreeNode(name); 359 } 360 361 /** 362 * Build a {@code HashMap} from a tree of ignored errors 363 * @param tree The JTree of ignored errors 364 * @return A {@code HashMap} of the ignored errors for comparison 365 */ 366 public static Map<String, String> buildIgnore(JTree tree) { 367 TreeModel model = tree.getModel(); 368 DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); 369 return buildIgnore(model, root); 370 } 371 372 private static Map<String, String> buildIgnore(TreeModel model, DefaultMutableTreeNode node) { 373 HashMap<String, String> rHashMap = new HashMap<>(); 374 375 String osmids = node.getUserObject().toString(); 376 String description = ""; 377 378 if (!model.getRoot().equals(node)) { 379 description = ((DefaultMutableTreeNode) node.getParent()).getUserObject().toString(); 380 } else { 381 description = node.getUserObject().toString(); 382 } 383 if (tr("Ignore list").equals(description)) description = ""; 384 if (!osmids.matches("^[0-9]+(_.*|$)")) { 385 description = osmids; 386 osmids = ""; 387 } 388 389 390 for (int i = 0; i < model.getChildCount(node); i++) { 391 DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(node, i); 392 if (model.getChildCount(child) == 0) { 393 String ignoreName = child.getUserObject().toString(); 394 if (ignoreName.matches("^(r|w|n)_.*")) { 395 osmids += ":" + child.getUserObject().toString(); 396 } else if (ignoreName.matches("^[0-9]+(_.*|)$")) { 397 rHashMap.put(ignoreName, description); 398 } 399 } else { 400 rHashMap.putAll(buildIgnore(model, child)); 401 } 402 } 403 if (!osmids.isEmpty() && osmids.indexOf(':') != 0) rHashMap.put(osmids, description); 404 return rHashMap; 405 } 406 407 /** 408 * Reset the error list by deleting {@code validator.ignorelist} 409 */ 410 public static void resetErrorList() { 411 saveIgnoredErrors(); 412 backupErrorList(); 413 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, null); 414 OsmValidator.initialize(); 415 } 416 417 /** 418 * Restore the error list by copying {@code validator.ignorelist.bak} to 419 * {@code validator.ignorelist} 420 */ 421 public static void restoreErrorList() { 422 saveIgnoredErrors(); 423 List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP); 424 backupErrorList(); 425 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, tlist); 426 OsmValidator.initialize(); 427 } 428 429 private static void backupErrorList() { 430 List<Map<String, String>> tlist = Config.getPref().getListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, null); 431 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST_BACKUP, tlist); 432 } 433 434 /** 435 * Saves the names of the ignored errors to a preference 436 */ 246 437 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); 438 List<Map<String, String>> list = new ArrayList<>(); 439 cleanupIgnoredErrors(); 440 list.add(ignoredErrors); 441 int i = 0; 442 while (i < list.size()) { 443 if (list.get(i) == null || list.get(i).isEmpty()) { 444 list.remove(i); 445 continue; 250 446 } 251 } catch (IOException e) { 252 Logging.error(e); 447 i++; 253 448 } 449 if (list.isEmpty()) list = null; 450 Config.getPref().putListOfMaps(ValidatorPrefHelper.PREF_IGNORELIST, list); 254 451 } 255 452 256 453 /** -
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) -
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.Rectangle; 8 import java.awt.event.ActionEvent; 9 import java.awt.event.KeyEvent; 10 import java.awt.event.KeyListener; 11 import java.awt.event.MouseAdapter; 12 import java.awt.event.MouseEvent; 13 import java.util.List; 14 import java.util.Locale; 15 import java.util.Map; 16 17 import javax.swing.AbstractAction; 18 import javax.swing.ImageIcon; 19 import javax.swing.JMenuItem; 20 import javax.swing.JOptionPane; 21 import javax.swing.JPanel; 22 import javax.swing.JPopupMenu; 23 import javax.swing.JScrollPane; 24 import javax.swing.JTree; 25 import javax.swing.tree.DefaultMutableTreeNode; 26 import javax.swing.tree.TreePath; 27 28 import org.openstreetmap.josm.actions.ValidateAction; 29 import org.openstreetmap.josm.data.validation.OsmValidator; 30 import org.openstreetmap.josm.data.validation.TestError; 31 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 32 import org.openstreetmap.josm.gui.ExtendedDialog; 33 import org.openstreetmap.josm.gui.MainApplication; 34 import org.openstreetmap.josm.gui.MapFrame; 35 import org.openstreetmap.josm.gui.util.GuiHelper; 36 import org.openstreetmap.josm.tools.GBC; 37 import org.openstreetmap.josm.tools.ImageProvider; 38 import org.openstreetmap.josm.tools.Logging; 39 40 41 /** 42 * A management window for the validator's ignorelist 43 * @author Taylor Smock 44 * @since xxx 45 */ 46 public class ValidatorListManagementDialog extends ExtendedDialog { 47 enum BUTTONS { 48 OK(0, tr("OK"), new ImageProvider("ok")), 49 CLEAR(1, tr("Clear All"), new ImageProvider("dialogs", "fix")), 50 RESTORE(2, tr("Restore"), new ImageProvider("copy")), 51 CANCEL(3, tr("Cancel"), new ImageProvider("cancel")); 52 53 private int index; 54 private String name; 55 private ImageIcon icon; 56 57 BUTTONS(int index, String name, ImageProvider image) { 58 this.index = index; 59 this.name = name; 60 this.icon = image.getResource().getImageIcon(); 61 } 62 63 public ImageIcon getImageIcon() { 64 return icon; 65 } 66 67 public int getIndex() { 68 return index; 69 } 70 71 public String getName() { 72 return name; 73 } 74 } 75 76 private static final String[] BUTTON_TEXTS = {BUTTONS.OK.getName(), BUTTONS.CLEAR.getName(), 77 BUTTONS.RESTORE.getName(), BUTTONS.CANCEL.getName() 78 }; 79 80 private static final ImageIcon[] BUTTON_IMAGES = {BUTTONS.OK.getImageIcon(), BUTTONS.CLEAR.getImageIcon(), 81 BUTTONS.RESTORE.getImageIcon(), BUTTONS.CANCEL.getImageIcon() 82 }; 83 84 private final JPanel panel = new JPanel(new GridBagLayout()); 85 86 private final JTree ignoreErrors; 87 88 private final String type; 89 90 /** 91 * Create a new {@link ValidatorListManagementDialog} 92 * @param type The type of list to create (first letter may or may not be 93 * capitalized, it is put into all lowercase after building the title) 94 */ 95 public ValidatorListManagementDialog(String type) { 96 super(MainApplication.getMainFrame(), tr("Validator {0} List Management", type), BUTTON_TEXTS, false); 97 this.type = type.toLowerCase(Locale.ENGLISH); 98 setButtonIcons(BUTTON_IMAGES); 99 100 ignoreErrors = buildList(); 101 JScrollPane scroll = GuiHelper.embedInVerticalScrollPane(ignoreErrors); 102 103 panel.add(scroll, GBC.eol().fill(GBC.BOTH).anchor(GBC.CENTER)); 104 setContent(panel); 105 setDefaultButton(1); 106 setupDialog(); 107 showDialog(); 108 } 109 110 @Override 111 public void buttonAction(int buttonIndex, ActionEvent evt) { 112 // Currently OK/Cancel buttons do nothing 113 final int answer; 114 if (buttonIndex == BUTTONS.RESTORE.getIndex()) { 115 dispose(); 116 answer = rerunValidatorPrompt(); 117 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 118 OsmValidator.restoreErrorList(); 119 } 120 } else if (buttonIndex == BUTTONS.CLEAR.getIndex()) { 121 dispose(); 122 answer = rerunValidatorPrompt(); 123 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 124 OsmValidator.resetErrorList(); 125 } 126 } else if (buttonIndex == BUTTONS.OK.getIndex()) { 127 Map<String, String> errors = OsmValidator.getIgnoredErrors(); 128 Map<String, String> tree = OsmValidator.buildIgnore(ignoreErrors); 129 if (!errors.equals(tree)) { 130 answer = rerunValidatorPrompt(); 131 if (answer == JOptionPane.YES_OPTION || answer == JOptionPane.NO_OPTION) { 132 OsmValidator.resetErrorList(); 133 tree.forEach((ignore, description) -> { 134 OsmValidator.addIgnoredError(ignore, description); 135 }); 136 OsmValidator.saveIgnoredErrors(); 137 OsmValidator.initialize(); 138 } 139 } 140 dispose(); 141 } else { 142 super.buttonAction(buttonIndex, evt); 143 } 144 } 145 146 /** 147 * Build a JTree with a list 148 * @return <type>list as a {@code JTree} 149 */ 150 public JTree buildList() { 151 JTree tree; 152 153 if ("ignore".equals(type)) { 154 tree = OsmValidator.buildJTreeList(); 155 } else { 156 Logging.error(tr("Cannot understand the following type: {0}", type)); 157 return null; 158 } 159 tree.setRootVisible(false); 160 tree.setShowsRootHandles(true); 161 tree.addMouseListener(new MouseAdapter() { 162 @Override 163 public void mousePressed(MouseEvent e) { 164 process(e); 165 } 166 167 @Override 168 public void mouseReleased(MouseEvent e) { 169 process(e); 170 } 171 172 private void process(MouseEvent e) { 173 if (e.isPopupTrigger()) { 174 TreePath[] paths = tree.getSelectionPaths(); 175 if (paths == null) return; 176 Rectangle bounds = tree.getUI().getPathBounds(tree, paths[0]); 177 if (bounds != null) { 178 JPopupMenu menu = new JPopupMenu(); 179 JMenuItem delete = new JMenuItem(new AbstractAction(tr("Delete")) { 180 @Override 181 public void actionPerformed(ActionEvent e1) { 182 deleteAction(tree, paths); 183 } 184 }); 185 menu.add(delete); 186 menu.show(e.getComponent(), e.getX(), e.getY()); 187 } 188 } 189 } 190 }); 191 192 tree.addKeyListener(new KeyListener() { 193 194 @Override 195 public void keyTyped(KeyEvent e) { 196 // Do nothing 197 } 198 199 @Override 200 public void keyPressed(KeyEvent e) { 201 // Do nothing 202 } 203 204 @Override 205 public void keyReleased(KeyEvent e) { 206 TreePath[] paths = tree.getSelectionPaths(); 207 if (e.getKeyCode() == KeyEvent.VK_DELETE && paths != null) { 208 deleteAction(tree, paths); 209 } 210 } 211 }); 212 return tree; 213 } 214 215 private void deleteAction(JTree tree, TreePath[] paths) { 216 for (TreePath path : paths) { 217 tree.clearSelection(); 218 tree.addSelectionPath(path); 219 DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 220 DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); 221 node.removeAllChildren(); 222 while (node.getChildCount() == 0) { 223 node.removeFromParent(); 224 node = parent; 225 if (parent == null || parent.isRoot()) break; 226 parent = (DefaultMutableTreeNode) node.getParent(); 227 } 228 } 229 tree.updateUI(); 230 } 231 232 233 /** 234 * Prompt to rerun the validator when the ignore list changes 235 * @return {@code JOptionPane.YES_OPTION}, {@code JOptionPane.NO_OPTION}, 236 * or {@code JOptionPane.CANCEL_OPTION} 237 */ 238 public int rerunValidatorPrompt() { 239 MapFrame map = MainApplication.getMap(); 240 List<TestError> errors = map.validatorDialog.tree.getErrors(); 241 ValidateAction validateAction = ValidatorDialog.validateAction; 242 if (!validateAction.isEnabled() || errors == null || errors.isEmpty()) return JOptionPane.NO_OPTION; 243 final int answer = ConditionalOptionPaneUtil.showOptionDialog( 244 "rerun_validation_when_ignorelist_changed", 245 MainApplication.getMainFrame(), 246 tr("{0}Should the validation be rerun?{1}", "<hmtl><h3>", "</h3></html>"), 247 tr("Ignored error filter changed"), 248 JOptionPane.YES_NO_CANCEL_OPTION, 249 JOptionPane.QUESTION_MESSAGE, 250 null, 251 null); 252 if (answer == JOptionPane.YES_OPTION) { 253 validateAction.doValidate(true); 254 } 255 return answer; 256 } 257 } -
src/org/openstreetmap/josm/spi/preferences/MapListSetting.java
6 6 import java.util.LinkedHashMap; 7 7 import java.util.List; 8 8 import java.util.Map; 9 import java.util.SortedMap; 9 10 10 11 /** 11 12 * Setting containing a {@link List} of {@link Map}s of {@link String} values. … … 40 41 if (value.contains(null)) 41 42 throw new IllegalArgumentException("Error: Null as list element in preference setting"); 42 43 for (Map<String, String> map : value) { 43 if ( map.containsKey(null))44 if (!(map instanceof SortedMap) && map.containsKey(null)) 44 45 throw new IllegalArgumentException("Error: Null as map key in preference setting"); 45 46 if (map.containsValue(null)) 46 47 throw new IllegalArgumentException("Error: Null as map value in preference setting");