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

Last change on this file since 3479 was 3479, checked in by jttt, 14 years ago

cosmetics

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