source: josm/trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java@ 6147

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

sonar - move duplicated class between history and conflict to util

  • Property svn:eol-style set to native
File size: 11.3 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.GridBagConstraints;
7import java.awt.GridBagLayout;
8import java.awt.Insets;
9import java.awt.Point;
10import java.awt.event.ActionEvent;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13
14import javax.swing.AbstractAction;
15import javax.swing.JPanel;
16import javax.swing.JPopupMenu;
17import javax.swing.JScrollPane;
18import javax.swing.JTable;
19import javax.swing.ListSelectionModel;
20import javax.swing.table.TableModel;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.actions.AutoScaleAction;
24import org.openstreetmap.josm.data.osm.OsmPrimitive;
25import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
26import org.openstreetmap.josm.data.osm.PrimitiveId;
27import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
28import org.openstreetmap.josm.data.osm.history.History;
29import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
30import org.openstreetmap.josm.gui.layer.OsmDataLayer;
31import org.openstreetmap.josm.gui.util.AdjustmentSynchronizer;
32import org.openstreetmap.josm.gui.util.GuiHelper;
33import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
34import org.openstreetmap.josm.tools.ImageProvider;
35
36/**
37 * NodeListViewer is a UI component which displays the node list of two
38 * version of a {@link OsmPrimitive} in a {@link History}.
39 *
40 * <ul>
41 * <li>on the left, it displays the node list for the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
42 * <li>on the right, it displays the node list for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
43 * </ul>
44 *
45 */
46public class NodeListViewer extends JPanel {
47
48 private HistoryBrowserModel model;
49 private VersionInfoPanel referenceInfoPanel;
50 private VersionInfoPanel currentInfoPanel;
51 private AdjustmentSynchronizer adjustmentSynchronizer;
52 private SelectionSynchronizer selectionSynchronizer;
53 private NodeListPopupMenu popupMenu;
54
55 protected JScrollPane embeddInScrollPane(JTable table) {
56 JScrollPane pane = new JScrollPane(table);
57 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
58 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
59 adjustmentSynchronizer.participateInSynchronizedScrolling(pane.getVerticalScrollBar());
60 return pane;
61 }
62
63 protected JTable buildReferenceNodeListTable() {
64 JTable table = new JTable(
65 model.getNodeListTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
66 new NodeListTableColumnModel()
67 );
68 table.setName("table.referencenodelisttable");
69 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
70 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
71 table.addMouseListener(new InternalPopupMenuLauncher());
72 table.addMouseListener(new DoubleClickAdapter(table));
73 return table;
74 }
75
76 protected JTable buildCurrentNodeListTable() {
77 JTable table = new JTable(
78 model.getNodeListTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
79 new NodeListTableColumnModel()
80 );
81 table.setName("table.currentnodelisttable");
82 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
83 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
84 table.addMouseListener(new InternalPopupMenuLauncher());
85 table.addMouseListener(new DoubleClickAdapter(table));
86 return table;
87 }
88
89 protected void build() {
90 setLayout(new GridBagLayout());
91 GridBagConstraints gc = new GridBagConstraints();
92
93 // ---------------------------
94 gc.gridx = 0;
95 gc.gridy = 0;
96 gc.gridwidth = 1;
97 gc.gridheight = 1;
98 gc.weightx = 0.5;
99 gc.weighty = 0.0;
100 gc.insets = new Insets(5,5,5,0);
101 gc.fill = GridBagConstraints.HORIZONTAL;
102 gc.anchor = GridBagConstraints.FIRST_LINE_START;
103 referenceInfoPanel = new VersionInfoPanel(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
104 add(referenceInfoPanel,gc);
105
106 gc.gridx = 1;
107 gc.gridy = 0;
108 gc.gridwidth = 1;
109 gc.gridheight = 1;
110 gc.fill = GridBagConstraints.HORIZONTAL;
111 gc.weightx = 0.5;
112 gc.weighty = 0.0;
113 gc.anchor = GridBagConstraints.FIRST_LINE_START;
114 currentInfoPanel = new VersionInfoPanel(model, PointInTimeType.CURRENT_POINT_IN_TIME);
115 add(currentInfoPanel,gc);
116
117 adjustmentSynchronizer = new AdjustmentSynchronizer();
118 selectionSynchronizer = new SelectionSynchronizer();
119
120 popupMenu = new NodeListPopupMenu();
121
122 // ---------------------------
123 gc.gridx = 0;
124 gc.gridy = 1;
125 gc.gridwidth = 1;
126 gc.gridheight = 1;
127 gc.weightx = 0.5;
128 gc.weighty = 1.0;
129 gc.fill = GridBagConstraints.BOTH;
130 gc.anchor = GridBagConstraints.NORTHWEST;
131 add(embeddInScrollPane(buildReferenceNodeListTable()),gc);
132
133 gc.gridx = 1;
134 gc.gridy = 1;
135 gc.gridwidth = 1;
136 gc.gridheight = 1;
137 gc.weightx = 0.5;
138 gc.weighty = 1.0;
139 gc.fill = GridBagConstraints.BOTH;
140 gc.anchor = GridBagConstraints.NORTHWEST;
141 add(embeddInScrollPane(buildCurrentNodeListTable()),gc);
142 }
143
144 public NodeListViewer(HistoryBrowserModel model) {
145 setModel(model);
146 build();
147 }
148
149 protected void unregisterAsObserver(HistoryBrowserModel model) {
150 if (currentInfoPanel != null) {
151 model.deleteObserver(currentInfoPanel);
152 }
153 if (referenceInfoPanel != null) {
154 model.deleteObserver(referenceInfoPanel);
155 }
156 }
157 protected void registerAsObserver(HistoryBrowserModel model) {
158 if (currentInfoPanel != null) {
159 model.addObserver(currentInfoPanel);
160 }
161 if (referenceInfoPanel != null) {
162 model.addObserver(referenceInfoPanel);
163 }
164 }
165
166 public void setModel(HistoryBrowserModel model) {
167 if (this.model != null) {
168 unregisterAsObserver(model);
169 }
170 this.model = model;
171 if (this.model != null) {
172 registerAsObserver(model);
173 }
174 }
175
176 static class NodeListPopupMenu extends JPopupMenu {
177 private final ZoomToNodeAction zoomToNodeAction;
178 private final ShowHistoryAction showHistoryAction;
179
180 public NodeListPopupMenu() {
181 zoomToNodeAction = new ZoomToNodeAction();
182 add(zoomToNodeAction);
183 showHistoryAction = new ShowHistoryAction();
184 add(showHistoryAction);
185 }
186
187 public void prepare(PrimitiveId pid){
188 zoomToNodeAction.setPrimitiveId(pid);
189 zoomToNodeAction.updateEnabledState();
190
191 showHistoryAction.setPrimitiveId(pid);
192 showHistoryAction.updateEnabledState();
193 }
194 }
195
196 static class ZoomToNodeAction extends AbstractAction {
197 private PrimitiveId primitiveId;
198
199 public ZoomToNodeAction() {
200 putValue(NAME, tr("Zoom to node"));
201 putValue(SHORT_DESCRIPTION, tr("Zoom to this node in the current data layer"));
202 putValue(SMALL_ICON, ImageProvider.get("dialogs", "zoomin"));
203 }
204
205 @Override
206 public void actionPerformed(ActionEvent e) {
207 if (!isEnabled()) return;
208 OsmPrimitive p = getPrimitiveToZoom();
209 if (p!= null) {
210 getEditLayer().data.setSelected(p.getPrimitiveId());
211 AutoScaleAction.autoScale("selection");
212 }
213 }
214
215 public void setPrimitiveId(PrimitiveId pid) {
216 this.primitiveId = pid;
217 updateEnabledState();
218 }
219
220 protected OsmDataLayer getEditLayer() {
221 try {
222 return Main.map.mapView.getEditLayer();
223 } catch(NullPointerException e) {
224 return null;
225 }
226 }
227
228 protected OsmPrimitive getPrimitiveToZoom() {
229 if (primitiveId == null) return null;
230 OsmPrimitive p = getEditLayer().data.getPrimitiveById(primitiveId);
231 return p;
232 }
233
234 public void updateEnabledState() {
235 if (getEditLayer() == null) {
236 setEnabled(false);
237 return;
238 }
239 setEnabled(getPrimitiveToZoom() != null);
240 }
241 }
242
243 static class ShowHistoryAction extends AbstractAction {
244 private PrimitiveId primitiveId;
245
246 public ShowHistoryAction() {
247 putValue(NAME, tr("Show history"));
248 putValue(SHORT_DESCRIPTION, tr("Open a history browser with the history of this node"));
249 putValue(SMALL_ICON, ImageProvider.get("dialogs", "history"));
250 }
251
252 @Override
253 public void actionPerformed(ActionEvent e) {
254 if (!isEnabled()) return;
255 run();
256 }
257
258 public void setPrimitiveId(PrimitiveId pid) {
259 this.primitiveId = pid;
260 updateEnabledState();
261 }
262
263 public void run() {
264 if (HistoryDataSet.getInstance().getHistory(primitiveId) == null) {
265 Main.worker.submit(new HistoryLoadTask().add(primitiveId));
266 }
267 Runnable r = new Runnable() {
268 @Override
269 public void run() {
270 final History h = HistoryDataSet.getInstance().getHistory(primitiveId);
271 if (h == null)
272 return;
273 GuiHelper.runInEDT(new Runnable() {
274 @Override public void run() {
275 HistoryBrowserDialogManager.getInstance().show(h);
276 }
277 });
278 }
279 };
280 Main.worker.submit(r);
281 }
282
283 public void updateEnabledState() {
284 setEnabled(primitiveId != null && primitiveId.getUniqueId() > 0);
285 }
286 }
287
288 static private PrimitiveId primitiveIdAtRow(TableModel model, int row) {
289 DiffTableModel castedModel = (DiffTableModel) model;
290 Long id = (Long)castedModel.getValueAt(row, 0).value;
291 if(id == null) return null;
292 return new SimplePrimitiveId(id, OsmPrimitiveType.NODE);
293 }
294
295 class InternalPopupMenuLauncher extends PopupMenuLauncher {
296 public InternalPopupMenuLauncher() {
297 super(popupMenu);
298 }
299
300 @Override protected int checkTableSelection(JTable table, Point p) {
301 int row = super.checkTableSelection(table, p);
302 popupMenu.prepare(primitiveIdAtRow(table.getModel(), row));
303 return row;
304 }
305 }
306
307 static class DoubleClickAdapter extends MouseAdapter {
308 private JTable table;
309 private ShowHistoryAction showHistoryAction;
310
311 public DoubleClickAdapter(JTable table) {
312 this.table = table;
313 showHistoryAction = new ShowHistoryAction();
314 }
315
316 @Override
317 public void mouseClicked(MouseEvent e) {
318 if (e.getClickCount() < 2) return;
319 int row = table.rowAtPoint(e.getPoint());
320 if(row <= 0) return;
321 PrimitiveId pid = primitiveIdAtRow(table.getModel(), row);
322 if (pid == null)
323 return;
324 showHistoryAction.setPrimitiveId(pid);
325 showHistoryAction.run();
326 }
327 }
328}
Note: See TracBrowser for help on using the repository browser.