source: josm/trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserDialogManager.java@ 6643

Last change on this file since 6643 was 6448, checked in by simon04, 10 years ago

fix #3626 - Show history for any object in history dialog

If no object is selected, the objects are selected by id via dialog.

  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Dimension;
7import java.awt.Point;
8import java.util.ArrayList;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.List;
12import java.util.Map;
13
14import javax.swing.JOptionPane;
15import javax.swing.SwingUtilities;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.PrimitiveId;
20import org.openstreetmap.josm.data.osm.history.History;
21import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
22import org.openstreetmap.josm.gui.MapView;
23import org.openstreetmap.josm.gui.layer.Layer;
24import org.openstreetmap.josm.tools.BugReportExceptionHandler;
25import org.openstreetmap.josm.tools.Predicate;
26import org.openstreetmap.josm.tools.Utils;
27import org.openstreetmap.josm.tools.WindowGeometry;
28
29public class HistoryBrowserDialogManager implements MapView.LayerChangeListener {
30 static private HistoryBrowserDialogManager instance;
31 static public HistoryBrowserDialogManager getInstance() {
32 if (instance == null) {
33 instance = new HistoryBrowserDialogManager();
34 }
35 return instance;
36 }
37
38 private Map<Long, HistoryBrowserDialog> dialogs;
39
40 protected HistoryBrowserDialogManager() {
41 dialogs = new HashMap<Long, HistoryBrowserDialog>();
42 MapView.addLayerChangeListener(this);
43 }
44
45 public boolean existsDialog(long id) {
46 return dialogs.containsKey(id);
47 }
48
49 public void show(long id, HistoryBrowserDialog dialog) {
50 if (dialogs.values().contains(dialog)) {
51 show(id);
52 } else {
53 placeOnScreen(dialog);
54 dialog.setVisible(true);
55 dialogs.put(id, dialog);
56 }
57 }
58
59 public void show(long id) {
60 if (dialogs.keySet().contains(id)) {
61 dialogs.get(id).toFront();
62 }
63 }
64
65 protected boolean hasDialogWithCloseUpperLeftCorner(Point p) {
66 for (HistoryBrowserDialog dialog: dialogs.values()) {
67 Point corner = dialog.getLocation();
68 if (p.x >= corner.x -5 && corner.x + 5 >= p.x
69 && p.y >= corner.y -5 && corner.y + 5 >= p.y)
70 return true;
71 }
72 return false;
73 }
74
75 public void placeOnScreen(HistoryBrowserDialog dialog) {
76 WindowGeometry geometry = WindowGeometry.centerOnScreen(new Dimension(800,500));
77 geometry.applySafe(dialog);
78 Point p = dialog.getLocation();
79 while(hasDialogWithCloseUpperLeftCorner(p)) {
80 p.x +=20;
81 p.y += 20;
82 }
83 dialog.setLocation(p);
84 }
85
86 public void hide(HistoryBrowserDialog dialog) {
87 long id = 0;
88 for (long i: dialogs.keySet()) {
89 if (dialogs.get(i) == dialog) {
90 id = i;
91 break;
92 }
93 }
94 if (id > 0) {
95 dialogs.remove(id);
96 }
97 dialog.setVisible(false);
98 dialog.dispose();
99 }
100
101 /**
102 * Hides and destroys all currently visible history browser dialogs
103 *
104 */
105 public void hideAll() {
106 List<HistoryBrowserDialog> dialogs = new ArrayList<HistoryBrowserDialog>();
107 dialogs.addAll(this.dialogs.values());
108 for (HistoryBrowserDialog dialog: dialogs) {
109 dialog.unlinkAsListener();
110 hide(dialog);
111 }
112 }
113
114 public void show(History h) {
115 if (h == null)
116 return;
117 if (existsDialog(h.getId())) {
118 show(h.getId());
119 } else {
120 HistoryBrowserDialog dialog = new HistoryBrowserDialog(h);
121 show(h.getId(), dialog);
122 }
123 }
124
125 /* ----------------------------------------------------------------------------- */
126 /* LayerChangeListener */
127 /* ----------------------------------------------------------------------------- */
128 @Override
129 public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
130 @Override
131 public void layerAdded(Layer newLayer) {}
132
133 @Override
134 public void layerRemoved(Layer oldLayer) {
135 // remove all history browsers if the number of layers drops to 0
136 //
137 if (Main.isDisplayingMapView() && Main.map.mapView.getNumLayers() == 0) {
138 hideAll();
139 }
140 }
141
142 public void showHistory(final Collection<? extends PrimitiveId> primitives) {
143 final Collection<? extends PrimitiveId> notNewPrimitives = Utils.filter(primitives, notNewPredicate);
144 if (notNewPrimitives.isEmpty()) {
145 JOptionPane.showMessageDialog(
146 Main.parent,
147 tr("Please select at least one already uploaded node, way, or relation."),
148 tr("Warning"),
149 JOptionPane.WARNING_MESSAGE);
150 return;
151 }
152
153 Collection<PrimitiveId> toLoad = Utils.filter(primitives, unloadedHistoryPredicate);
154 if (!toLoad.isEmpty()) {
155 HistoryLoadTask task = new HistoryLoadTask();
156 for (PrimitiveId p : notNewPrimitives) {
157 task.add(p);
158 }
159 Main.worker.submit(task);
160 }
161
162 Runnable r = new Runnable() {
163
164 @Override
165 public void run() {
166 try {
167 for (PrimitiveId p : notNewPrimitives) {
168 final History h = HistoryDataSet.getInstance().getHistory(p);
169 if (h == null) {
170 continue;
171 }
172 SwingUtilities.invokeLater(new Runnable() {
173 @Override
174 public void run() {
175 show(h);
176 }
177 });
178 }
179 } catch (final Exception e) {
180 BugReportExceptionHandler.handleException(e);
181 }
182
183 }
184 };
185 Main.worker.submit(r);
186 }
187
188 private final Predicate<PrimitiveId> unloadedHistoryPredicate = new Predicate<PrimitiveId>() {
189
190 HistoryDataSet hds = HistoryDataSet.getInstance();
191
192 @Override
193 public boolean evaluate(PrimitiveId p) {
194 History h = hds.getHistory(p);
195 if (h == null)
196 // reload if the history is not in the cache yet
197 return true;
198 else if (!p.isNew() && h.getByVersion(p.getUniqueId()) == null)
199 // reload if the history object of the selected object is not in the cache yet
200 return true;
201 else
202 return false;
203 }
204 };
205
206 private final Predicate<PrimitiveId> notNewPredicate = new Predicate<PrimitiveId>() {
207
208 @Override
209 public boolean evaluate(PrimitiveId p) {
210 return !p.isNew();
211 }
212 };
213
214}
Note: See TracBrowser for help on using the repository browser.