source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationDialogManager.java@ 11461

Last change on this file since 11461 was 11461, checked in by Don-vip, 7 years ago

sonar - fb-contrib:SPP_USE_CONTAINSKEY - Style - Method calls keySet() just to call contains, use containsKey instead

  • Property svn:eol-style set to native
File size: 8.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import java.awt.Point;
5import java.awt.event.WindowAdapter;
6import java.awt.event.WindowEvent;
7import java.util.HashMap;
8import java.util.Iterator;
9import java.util.Map;
10import java.util.Map.Entry;
11import java.util.Objects;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.gui.layer.Layer;
16import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
17import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
18import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
19import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
20import org.openstreetmap.josm.gui.layer.OsmDataLayer;
21
22/**
23 * RelationDialogManager keeps track of the open relation editors.
24 *
25 */
26public class RelationDialogManager extends WindowAdapter implements LayerChangeListener {
27
28 /** keeps track of open relation editors */
29 private static RelationDialogManager relationDialogManager;
30
31 /**
32 * Replies the singleton {@link RelationDialogManager}
33 *
34 * @return the singleton {@link RelationDialogManager}
35 */
36 public static RelationDialogManager getRelationDialogManager() {
37 if (RelationDialogManager.relationDialogManager == null) {
38 RelationDialogManager.relationDialogManager = new RelationDialogManager();
39 Main.getLayerManager().addLayerChangeListener(RelationDialogManager.relationDialogManager);
40 }
41 return RelationDialogManager.relationDialogManager;
42 }
43
44 /**
45 * Helper class for keeping the context of a relation editor. A relation editor
46 * is open for a specific relation managed by a specific {@link OsmDataLayer}
47 *
48 */
49 private static class DialogContext {
50 public final Relation relation;
51 public final OsmDataLayer layer;
52
53 DialogContext(OsmDataLayer layer, Relation relation) {
54 this.layer = layer;
55 this.relation = relation;
56 }
57
58 @Override
59 public int hashCode() {
60 return Objects.hash(relation, layer);
61 }
62
63 @Override
64 public boolean equals(Object obj) {
65 if (this == obj) return true;
66 if (obj == null || getClass() != obj.getClass()) return false;
67 DialogContext that = (DialogContext) obj;
68 return Objects.equals(relation, that.relation) &&
69 Objects.equals(layer, that.layer);
70 }
71
72 public boolean matchesLayer(OsmDataLayer layer) {
73 if (layer == null) return false;
74 return this.layer.equals(layer);
75 }
76
77 @Override
78 public String toString() {
79 return "[Context: layer=" + layer.getName() + ",relation=" + relation.getId() + ']';
80 }
81 }
82
83 /** the map of open dialogs */
84 private final Map<DialogContext, RelationEditor> openDialogs;
85
86 /**
87 * constructor
88 */
89 public RelationDialogManager() {
90 openDialogs = new HashMap<>();
91 }
92
93 /**
94 * Register the relation editor for a relation managed by a
95 * {@link OsmDataLayer}.
96 *
97 * @param layer the layer
98 * @param relation the relation
99 * @param editor the editor
100 */
101 public void register(OsmDataLayer layer, Relation relation, RelationEditor editor) {
102 if (relation == null) {
103 relation = new Relation();
104 }
105 DialogContext context = new DialogContext(layer, relation);
106 openDialogs.put(context, editor);
107 editor.addWindowListener(this);
108 }
109
110 public void updateContext(OsmDataLayer layer, Relation relation, RelationEditor editor) {
111 // lookup the entry for editor and remove it
112 //
113 for (Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator(); it.hasNext();) {
114 Entry<DialogContext, RelationEditor> entry = it.next();
115 if (Objects.equals(entry.getValue(), editor)) {
116 it.remove();
117 break;
118 }
119 }
120 // don't add a window listener. Editor is already known to the relation dialog manager
121 //
122 DialogContext context = new DialogContext(layer, relation);
123 openDialogs.put(context, editor);
124 }
125
126 /**
127 * Closes the editor open for a specific layer and a specific relation.
128 *
129 * @param layer the layer
130 * @param relation the relation
131 */
132 public void close(OsmDataLayer layer, Relation relation) {
133 DialogContext context = new DialogContext(layer, relation);
134 RelationEditor editor = openDialogs.get(context);
135 if (editor != null) {
136 editor.setVisible(false);
137 }
138 }
139
140 /**
141 * Replies true if there is an open relation editor for the relation managed
142 * by the given layer. Replies false if relation is null.
143 *
144 * @param layer the layer
145 * @param relation the relation. May be null.
146 * @return true if there is an open relation editor for the relation managed
147 * by the given layer; false otherwise
148 */
149 public boolean isOpenInEditor(OsmDataLayer layer, Relation relation) {
150 if (relation == null) return false;
151 DialogContext context = new DialogContext(layer, relation);
152 return openDialogs.containsKey(context);
153 }
154
155 /**
156 * Replies the editor for the relation managed by layer. Null, if no such editor
157 * is currently open. Returns null, if relation is null.
158 *
159 * @param layer the layer
160 * @param relation the relation
161 * @return the editor for the relation managed by layer. Null, if no such editor
162 * is currently open.
163 *
164 * @see #isOpenInEditor(OsmDataLayer, Relation)
165 */
166 public RelationEditor getEditorForRelation(OsmDataLayer layer, Relation relation) {
167 if (relation == null) return null;
168 DialogContext context = new DialogContext(layer, relation);
169 return openDialogs.get(context);
170 }
171
172 @Override
173 public void layerRemoving(LayerRemoveEvent e) {
174 Layer oldLayer = e.getRemovedLayer();
175 if (!(oldLayer instanceof OsmDataLayer))
176 return;
177 OsmDataLayer dataLayer = (OsmDataLayer) oldLayer;
178
179 Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator();
180 while (it.hasNext()) {
181 Entry<DialogContext, RelationEditor> entry = it.next();
182 if (entry.getKey().matchesLayer(dataLayer)) {
183 RelationEditor editor = entry.getValue();
184 it.remove();
185 editor.setVisible(false);
186 editor.dispose();
187 }
188 }
189 }
190
191 @Override
192 public void layerAdded(LayerAddEvent e) {
193 // ignore
194 }
195
196 @Override
197 public void layerOrderChanged(LayerOrderChangeEvent e) {
198 // ignore
199 }
200
201 @Override
202 public void windowClosed(WindowEvent e) {
203 RelationEditor editor = (RelationEditor) e.getWindow();
204 for (Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator(); it.hasNext();) {
205 if (editor.equals(it.next().getValue())) {
206 it.remove();
207 break;
208 }
209 }
210 }
211
212 /**
213 * Replies true, if there is another open {@link RelationEditor} whose
214 * upper left corner is close to <code>p</code>.
215 *
216 * @param p the reference point to check
217 * @param thisEditor the current editor
218 * @return true, if there is another open {@link RelationEditor} whose
219 * upper left corner is close to <code>p</code>.
220 */
221 protected boolean hasEditorWithCloseUpperLeftCorner(Point p, RelationEditor thisEditor) {
222 for (RelationEditor editor: openDialogs.values()) {
223 if (editor == thisEditor) {
224 continue;
225 }
226 Point corner = editor.getLocation();
227 if (p.x >= corner.x -5 && corner.x + 5 >= p.x
228 && p.y >= corner.y -5 && corner.y + 5 >= p.y)
229 return true;
230 }
231 return false;
232 }
233
234 /**
235 * Positions a {@link RelationEditor} on the screen. Tries to center it on the
236 * screen. If it hide another instance of an editor at the same position this
237 * method tries to reposition <code>editor</code> by moving it slightly down and
238 * slightly to the right.
239 *
240 * @param editor the editor
241 */
242 public void positionOnScreen(RelationEditor editor) {
243 if (editor == null) return;
244 if (!openDialogs.isEmpty()) {
245 Point corner = editor.getLocation();
246 while (hasEditorWithCloseUpperLeftCorner(corner, editor)) {
247 // shift a little, so that the dialogs are not exactly on top of each other
248 corner.x += 20;
249 corner.y += 20;
250 }
251 editor.setLocation(corner);
252 }
253 }
254
255}
Note: See TracBrowser for help on using the repository browser.