Ticket #11153: 11153.patch
| File 11153.patch, 12.4 KB (added by , 3 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerRule.java
Subject: [PATCH] #11153: improve readability of validator warnings --- IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerRule.java b/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerRule.java
a b 11 11 import java.util.HashMap; 12 12 import java.util.HashSet; 13 13 import java.util.List; 14 import java.util.Locale; 14 15 import java.util.Map; 15 16 import java.util.Objects; 16 17 import java.util.Optional; … … 44 45 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser; 45 46 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException; 46 47 import org.openstreetmap.josm.io.IllegalDataException; 48 import org.openstreetmap.josm.spi.preferences.Config; 47 49 import org.openstreetmap.josm.tools.CheckParameterUtil; 48 50 import org.openstreetmap.josm.tools.Logging; 49 51 import org.openstreetmap.josm.tools.Utils; … … 277 279 Integer.parseInt(m.group(1)), m.group(2), p); 278 280 try { 279 281 // Perform replacement with null-safe + regex-safe handling 280 m.appendReplacement(sb, String.valueOf(argument).replace("^(", "").replace(")$", "")); 282 final String replacement = String.valueOf(argument).replace("^(", "").replace(")$", ""); 283 final String type = m.group(2); 284 final String url; 285 if ("key".equals(type) || "tag".equals(type)) { 286 url = Config.getUrls().getOSMWiki() + "/wiki/" 287 + m.group(2).substring(0, 1).toUpperCase(Locale.ROOT) + m.group(2).substring(1) 288 + ":" + replacement; 289 } else { 290 url = null; 291 } 292 m.appendReplacement(sb, (url != null ? "<a href=\"" + url + "\">" : "") 293 + replacement 294 + (url != null ? "</a>" : "")); 281 295 } catch (IndexOutOfBoundsException | IllegalArgumentException e) { 282 296 Logging.log(Logging.LEVEL_ERROR, tr("Unable to replace argument {0} in {1}: {2}", argument, sb, e.getMessage()), e); 283 297 } -
src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java b/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java
a b 267 267 } 268 268 final String msg = addSize(searchMsg, errorsWithDescription); 269 269 270 final DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode( msg);270 final DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode("<html>" + msg + "</html>"); 271 271 DefaultMutableTreeNode currNode = groupNode != null ? groupNode : severityNode; 272 272 currNode.add(messageNode); 273 273 if (oldExpandedRows.contains(searchMsg)) { -
src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreeRenderer.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreeRenderer.java b/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreeRenderer.java
a b 3 3 4 4 import java.awt.Component; 5 5 6 import javax.swing.JLabel; 6 7 import javax.swing.JTree; 7 8 import javax.swing.tree.DefaultMutableTreeNode; 8 import javax.swing.tree.DefaultTreeCellRenderer;9 9 10 10 import org.openstreetmap.josm.data.validation.Severity; 11 11 import org.openstreetmap.josm.data.validation.TestError; 12 12 import org.openstreetmap.josm.data.validation.util.MultipleNameVisitor; 13 import org.openstreetmap.josm.gui.widgets.HtmlTreeCellRenderer; 13 14 import org.openstreetmap.josm.tools.ImageProvider; 14 15 15 16 /** 16 17 * Tree renderer for displaying errors 17 18 * @author frsantos 18 19 */ 19 public class ValidatorTreeRenderer extends DefaultTreeCellRenderer { 20 public class ValidatorTreeRenderer extends HtmlTreeCellRenderer { 21 22 private static final long serialVersionUID = 4750085115702320153L; 20 23 21 24 @Override 22 25 public Component getTreeCellRendererComponent(JTree tree, Object value, 23 26 boolean selected, boolean expanded, boolean leaf, int row, 24 27 boolean hasFocus) { 25 super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);28 final Component component = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 26 29 27 DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;28 Object nodeInfo = node.getUserObject();30 final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 31 final Object nodeInfo = node.getUserObject(); 29 32 30 if (nodeInfo instanceof Severity) { 31 Severity s = (Severity) nodeInfo; 32 setIcon(ImageProvider.get("data", s.getIcon())); 33 } else if (nodeInfo instanceof TestError) { 34 TestError error = (TestError) nodeInfo; 35 MultipleNameVisitor v = error.getNameVisitor(); 36 setText(v.getText()); 37 setIcon(v.getIcon()); 33 if (component instanceof JLabel) { 34 final JLabel label = (JLabel) component; 35 if (nodeInfo instanceof Severity) { 36 final Severity s = (Severity) nodeInfo; 37 label.setIcon(ImageProvider.get("data", s.getIcon())); 38 } else if (nodeInfo instanceof TestError) { 39 final TestError error = (TestError) nodeInfo; 40 MultipleNameVisitor v = error.getNameVisitor(); 41 label.setText(v.getText()); 42 label.setIcon(v.getIcon()); 43 } 38 44 } 39 return this;45 return component; 40 46 } 41 47 } -
new file src/org/openstreetmap/josm/gui/widgets/HtmlTreeCellRenderer.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/gui/widgets/HtmlTreeCellRenderer.java b/src/org/openstreetmap/josm/gui/widgets/HtmlTreeCellRenderer.java new file mode 100644
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.widgets; 3 4 import java.awt.Component; 5 import java.awt.Point; 6 import java.awt.Rectangle; 7 import java.awt.event.MouseEvent; 8 import java.util.Arrays; 9 10 import javax.annotation.Nullable; 11 import javax.swing.JTree; 12 import javax.swing.event.HyperlinkEvent; 13 import javax.swing.event.MouseInputAdapter; 14 import javax.swing.tree.DefaultMutableTreeNode; 15 import javax.swing.tree.DefaultTreeCellRenderer; 16 import javax.swing.tree.TreePath; 17 18 import org.openstreetmap.josm.tools.OpenBrowser; 19 20 /** 21 * A {@link javax.swing.tree.TreeCellRenderer} for cells that may contain hyperlinks. 22 * @since xxx 23 */ 24 public class HtmlTreeCellRenderer extends DefaultTreeCellRenderer { 25 /** 26 * This only exists since the JTree cannot pass events to subcomponents. 27 */ 28 private static class JTreeMouseInputListener extends MouseInputAdapter { 29 @Override 30 public void mouseClicked(MouseEvent mouseEvent) { 31 if (mouseEvent.getComponent() instanceof JTree) { 32 final Point p = mouseEvent.getPoint(); 33 final JTree tree = (JTree) mouseEvent.getComponent(); 34 final Component component = getComponentAt(tree, p); // p is translated here 35 if (component != null) { 36 component.dispatchEvent(new MouseEvent(component, // Use the component we found to fire the event 37 mouseEvent.getID(), mouseEvent.getWhen(), mouseEvent.getModifiers(), 38 p.x, p.y, mouseEvent.getClickCount(), mouseEvent.isPopupTrigger(), 39 mouseEvent.getButton())); 40 } 41 } 42 } 43 44 /** 45 * Get a component at 46 * @param tree The tree to get the component from 47 * @param p The point to get the component at (will be modified) 48 * @return The component 49 */ 50 @Nullable 51 private static Component getComponentAt(JTree tree, Point p) { 52 final TreePath path = tree.getPathForLocation(p.x, p.y); 53 if (path != null) { 54 final int row = tree.getRowForPath(path); 55 final Object last = path.getLastPathComponent(); 56 // We need to get the component as "shown" so that we can get the link clicked. 57 final Component component = tree.getCellRenderer().getTreeCellRendererComponent(tree, last, 58 tree.isRowSelected(row), tree.isExpanded(row), 59 tree.getModel().isLeaf(last), row, true); 60 final Rectangle bounds = tree.getPathBounds(path); 61 if (bounds != null) { 62 // If we don't translate the point, we are attempting to get the link in the wrong frame of reference 63 // The reference x/y are 0. This is set in BasicTextUI#getVisibleEditorRect, so we must translate the point here. 64 p.translate(-bounds.x, -bounds.y); 65 // Just make certain that we are consistent for other objects. 66 bounds.x = 0; 67 bounds.y = 0; 68 // Set the bounds from the JTree component (needed for proper layout) 69 component.setBounds(bounds); 70 return component; 71 } 72 } 73 return null; 74 } 75 } 76 77 private static final long serialVersionUID = -4842755204541968238L; 78 /** 79 * A reusable panel to avoid new objects where possible. 80 * It isn't worth it to make a new object for each row, since it doesn't receive mouse events (tested on Java 8). 81 */ 82 private final JosmEditorPane panel = new JosmEditorPane(); 83 /** JTree does not send mouse events to subcomponents */ 84 private final JTreeMouseInputListener mouseTreeListener = new JTreeMouseInputListener(); 85 86 /** 87 * Create a new renderer 88 */ 89 public HtmlTreeCellRenderer() { 90 panel.addHyperlinkListener(e -> { 91 if (e.getURL() != null && HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) { 92 OpenBrowser.displayUrl(e.getURL().toString()); 93 } 94 }); 95 JosmEditorPane.makeJLabelLike(panel, false); 96 } 97 98 @Override 99 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, 100 boolean leaf, int row, boolean hasFocus) { 101 if (value instanceof DefaultMutableTreeNode) { 102 if (Arrays.stream(tree.getMouseListeners()).noneMatch(this.mouseTreeListener::equals)) { 103 tree.addMouseListener(this.mouseTreeListener); 104 tree.addMouseMotionListener(this.mouseTreeListener); 105 } 106 final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 107 final Object object = node.getUserObject(); 108 if (object instanceof String && ((String) object).startsWith("<html>") && ((String) object).endsWith("</html>")) { 109 this.panel.setText((String) object); 110 return this.panel; 111 } 112 } 113 return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); 114 } 115 }
