source: josm/trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java@ 14206

Last change on this file since 14206 was 13940, checked in by Don-vip, 6 years ago

refactor/cleanup validator tree API

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Graphics2D;
7import java.io.File;
8import java.util.Collections;
9import java.util.List;
10
11import javax.swing.Action;
12import javax.swing.Icon;
13import javax.swing.tree.DefaultMutableTreeNode;
14
15import org.openstreetmap.josm.actions.RenameLayerAction;
16import org.openstreetmap.josm.actions.SaveActionBase;
17import org.openstreetmap.josm.data.Bounds;
18import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
19import org.openstreetmap.josm.data.validation.OsmValidator;
20import org.openstreetmap.josm.data.validation.Severity;
21import org.openstreetmap.josm.data.validation.TestError;
22import org.openstreetmap.josm.gui.MainApplication;
23import org.openstreetmap.josm.gui.MapView;
24import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
25import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
26import org.openstreetmap.josm.gui.dialogs.validator.ValidatorTreePanel;
27import org.openstreetmap.josm.gui.io.importexport.ValidatorErrorExporter;
28import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
29import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
30import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
31import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
32import org.openstreetmap.josm.gui.layer.validation.PaintVisitor;
33import org.openstreetmap.josm.tools.ImageProvider;
34import org.openstreetmap.josm.tools.MultiMap;
35
36/**
37 * A layer showing error messages.
38 *
39 * @author frsantos
40 *
41 * @since 3669 (creation)
42 * @since 10386 (new LayerChangeListener interface)
43 */
44public class ValidatorLayer extends Layer implements LayerChangeListener {
45 private final Runnable invalidator = this::invalidate;
46
47 /**
48 * Constructs a new Validator layer
49 */
50 public ValidatorLayer() {
51 super(tr("Validation errors"));
52 MainApplication.getLayerManager().addLayerChangeListener(this);
53 MainApplication.getMap().validatorDialog.tree.addInvalidationListener(invalidator);
54 }
55
56 /**
57 * Return a static icon.
58 */
59 @Override
60 public Icon getIcon() {
61 return ImageProvider.get("layer", "validator_small");
62 }
63
64 /**
65 * Draw all primitives in this layer but do not draw modified ones (they
66 * are drawn by the edit layer).
67 * Draw nodes last to overlap the ways they belong to.
68 */
69 @Override
70 public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
71 DefaultMutableTreeNode root = MainApplication.getMap().validatorDialog.tree.getRoot();
72 if (root == null || root.getChildCount() == 0)
73 return;
74
75 PaintVisitor paintVisitor = new PaintVisitor(g, mv);
76
77 DefaultMutableTreeNode severity = (DefaultMutableTreeNode) root.getLastChild();
78 while (severity != null) {
79 ValidatorTreePanel.visitTestErrors(severity, paintVisitor::visit);
80
81 // Severities in inverse order
82 severity = severity.getPreviousSibling();
83 }
84
85 paintVisitor.clearPaintedObjects();
86 }
87
88 @Override
89 public String getToolTipText() {
90 MultiMap<Severity, TestError> errorTree = new MultiMap<>();
91 List<TestError> errors = MainApplication.getMap().validatorDialog.tree.getErrors();
92 for (TestError e : errors) {
93 errorTree.put(e.getSeverity(), e);
94 }
95
96 StringBuilder b = new StringBuilder();
97 for (Severity s : Severity.values()) {
98 if (errorTree.containsKey(s)) {
99 b.append(tr(s.toString())).append(": ").append(errorTree.get(s).size()).append("<br>");
100 }
101 }
102
103 if (b.length() == 0)
104 return "<html>" + tr("No validation errors") + "</html>";
105 else
106 return "<html>" + tr("Validation errors") + ":<br>" + b + "</html>";
107 }
108
109 @Override
110 public void mergeFrom(Layer from) {
111 // Do nothing
112 }
113
114 @Override
115 public boolean isMergable(Layer other) {
116 return false;
117 }
118
119 @Override
120 public void visitBoundingBox(BoundingXYVisitor v) {
121 // Do nothing
122 }
123
124 @Override
125 public Object getInfoComponent() {
126 return getToolTipText();
127 }
128
129 @Override
130 public Action[] getMenuEntries() {
131 return new Action[] {
132 LayerListDialog.getInstance().createShowHideLayerAction(),
133 LayerListDialog.getInstance().createDeleteLayerAction(),
134 SeparatorLayerAction.INSTANCE,
135 new RenameLayerAction(null, this),
136 SeparatorLayerAction.INSTANCE,
137 new LayerListPopup.InfoAction(this),
138 new LayerSaveAsAction(this)
139 };
140 }
141
142 @Override
143 public File createAndOpenSaveFileChooser() {
144 return SaveActionBase.createAndOpenSaveFileChooser(tr("Save Validation errors file"), ValidatorErrorExporter.FILE_FILTER);
145 }
146
147 @Override
148 public void layerOrderChanged(LayerOrderChangeEvent e) {
149 // Do nothing
150 }
151
152 @Override
153 public void layerAdded(LayerAddEvent e) {
154 // Do nothing
155 }
156
157 /**
158 * If layer is the OSM Data layer, remove all errors
159 */
160 @Override
161 public void layerRemoving(LayerRemoveEvent e) {
162 // Removed layer is still in that list.
163 if (e.getRemovedLayer() instanceof OsmDataLayer && e.getSource().getLayersOfType(OsmDataLayer.class).size() <= 1) {
164 e.scheduleRemoval(Collections.singleton(this));
165 } else if (e.getRemovedLayer() == this) {
166 OsmValidator.resetErrorLayer();
167 }
168 }
169
170 @Override
171 public LayerPositionStrategy getDefaultLayerPosition() {
172 return LayerPositionStrategy.IN_FRONT;
173 }
174
175 @Override
176 public synchronized void destroy() {
177 MainApplication.getMap().validatorDialog.tree.removeInvalidationListener(invalidator);
178 MainApplication.getLayerManager().removeLayerChangeListener(this);
179 super.destroy();
180 }
181}
Note: See TracBrowser for help on using the repository browser.