// License: GPL. See LICENSE file for details. package org.openstreetmap.josm.gui.layer; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Graphics2D; import java.util.Enumeration; import java.util.List; import javax.swing.Action; import javax.swing.Icon; import javax.swing.tree.DefaultMutableTreeNode; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.RenameLayerAction; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; import org.openstreetmap.josm.data.validation.OsmValidator; import org.openstreetmap.josm.data.validation.PaintVisitor; import org.openstreetmap.josm.data.validation.Severity; import org.openstreetmap.josm.data.validation.TestError; import org.openstreetmap.josm.gui.MapView; import org.openstreetmap.josm.gui.MapView.LayerChangeListener; import org.openstreetmap.josm.gui.dialogs.LayerListDialog; import org.openstreetmap.josm.gui.dialogs.LayerListPopup; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.MultiMap; /** * A layer showing error messages. * * @author frsantos */ public class ValidatorLayer extends Layer implements LayerChangeListener { private int updateCount = -1; /** * Constructs a new Validator layer */ public ValidatorLayer() { super(tr("Validation errors")); MapView.addLayerChangeListener(this); } /** * Return a static icon. */ @Override public Icon getIcon() { return ImageProvider.get("layer", "validator_small"); } /** * Draw all primitives in this layer but do not draw modified ones (they * are drawn by the edit layer). * Draw nodes last to overlap the ways they belong to. */ @SuppressWarnings("unchecked") @Override public void paint(final Graphics2D g, final MapView mv, Bounds bounds) { updateCount = Main.map.validatorDialog.tree.getUpdateCount(); DefaultMutableTreeNode root = Main.map.validatorDialog.tree.getRoot(); if (root == null || root.getChildCount() == 0) return; PaintVisitor paintVisitor = new PaintVisitor(g, mv); DefaultMutableTreeNode severity = (DefaultMutableTreeNode) root.getLastChild(); while (severity != null) { Enumeration errorMessages = severity.breadthFirstEnumeration(); while (errorMessages.hasMoreElements()) { Object tn = errorMessages.nextElement().getUserObject(); if (tn instanceof TestError) { paintVisitor.visit(((TestError) tn)); } } // Severities in inverse order severity = severity.getPreviousSibling(); } paintVisitor.clearPaintedObjects(); } @Override public String getToolTipText() { MultiMap errorTree = new MultiMap(); List errors = Main.map.validatorDialog.tree.getErrors(); for (TestError e : errors) { errorTree.put(e.getSeverity(), e); } StringBuilder b = new StringBuilder(); for (Severity s : Severity.values()) { if (errorTree.containsKey(s)) { b.append(tr(s.toString())).append(": ").append(errorTree.get(s).size()).append("
"); } } if (b.length() == 0) return "" + tr("No validation errors") + ""; else return "" + tr("Validation errors") + ":
" + b + ""; } @Override public void mergeFrom(Layer from) { } @Override public boolean isMergable(Layer other) { return false; } @Override public boolean isChanged() { return updateCount != Main.map.validatorDialog.tree.getUpdateCount(); } @Override public void visitBoundingBox(BoundingXYVisitor v) { } @Override public Object getInfoComponent() { return getToolTipText(); } @Override public Action[] getMenuEntries() { return new Action[] { LayerListDialog.getInstance().createShowHideLayerAction(), LayerListDialog.getInstance().createDeleteLayerAction(), SeparatorLayerAction.INSTANCE, new RenameLayerAction(null, this), SeparatorLayerAction.INSTANCE, new LayerListPopup.InfoAction(this) }; } @Override public void destroy() { } @Override public void activeLayerChange(Layer oldLayer, Layer newLayer) { } @Override public void layerAdded(Layer newLayer) { } /** * If layer is the OSM Data layer, remove all errors */ @Override public void layerRemoved(Layer oldLayer) { if (oldLayer instanceof OsmDataLayer && Main.map != null && Main.map.mapView.getEditLayer() == null) { Main.main.removeLayer(this); } else if (oldLayer == this) { MapView.removeLayerChangeListener(this); OsmValidator.errorLayer = null; } } }