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

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

fix #17182 - restore contextual menu of history dialog

  • Property svn:eol-style set to native
File size: 9.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.Point;
7import java.awt.event.ActionEvent;
8import java.awt.event.MouseAdapter;
9import java.awt.event.MouseEvent;
10
11import javax.swing.AbstractAction;
12import javax.swing.JPopupMenu;
13import javax.swing.JTable;
14import javax.swing.ListSelectionModel;
15import javax.swing.event.TableModelEvent;
16import javax.swing.event.TableModelListener;
17
18import org.openstreetmap.josm.actions.AutoScaleAction;
19import org.openstreetmap.josm.actions.AutoScaleAction.AutoScaleMode;
20import org.openstreetmap.josm.data.osm.IPrimitive;
21import org.openstreetmap.josm.data.osm.OsmData;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
24import org.openstreetmap.josm.data.osm.PrimitiveId;
25import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
26import org.openstreetmap.josm.data.osm.history.History;
27import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
28import org.openstreetmap.josm.gui.MainApplication;
29import org.openstreetmap.josm.gui.util.GuiHelper;
30import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
31import org.openstreetmap.josm.tools.ImageProvider;
32
33/**
34 * NodeListViewer is a UI component which displays the node list of two
35 * version of a {@link OsmPrimitive} in a {@link History}.
36 *
37 * <ul>
38 * <li>on the left, it displays the node list for the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
39 * <li>on the right, it displays the node list for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
40 * </ul>
41 * @since 1709
42 */
43public class NodeListViewer extends HistoryViewerPanel {
44
45 /**
46 * Constructs a new {@code NodeListViewer}.
47 * @param model history browser model
48 */
49 public NodeListViewer(HistoryBrowserModel model) {
50 super(model);
51 }
52
53 @Override
54 protected JTable buildReferenceTable() {
55 return buildTable(PointInTimeType.REFERENCE_POINT_IN_TIME, "table.referencenodelisttable");
56 }
57
58 @Override
59 protected JTable buildCurrentTable() {
60 return buildTable(PointInTimeType.CURRENT_POINT_IN_TIME, "table.currentnodelisttable");
61 }
62
63 private JTable buildTable(PointInTimeType pointInTimeType, String name) {
64 final DiffTableModel tableModel = model.getNodeListTableModel(pointInTimeType);
65 final NodeListTableColumnModel columnModel = new NodeListTableColumnModel();
66 final JTable table = new JTable(tableModel, columnModel);
67 tableModel.addTableModelListener(new ReversedChangeListener(table, columnModel));
68 table.setName(name);
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 static final class ReversedChangeListener implements TableModelListener {
77 private final NodeListTableColumnModel columnModel;
78 private final JTable table;
79 private Boolean reversed;
80 private final String nonReversedText;
81 private final String reversedText;
82
83 ReversedChangeListener(JTable table, NodeListTableColumnModel columnModel) {
84 this.columnModel = columnModel;
85 this.table = table;
86 nonReversedText = tr("Nodes") + (table.getFont().canDisplay('\u25bc') ? " \u25bc" : " (1-n)");
87 reversedText = tr("Nodes") + (table.getFont().canDisplay('\u25b2') ? " \u25b2" : " (n-1)");
88 }
89
90 @Override
91 public void tableChanged(TableModelEvent e) {
92 if (e.getSource() instanceof DiffTableModel) {
93 final DiffTableModel mod = (DiffTableModel) e.getSource();
94 if (reversed == null || reversed != mod.isReversed()) {
95 reversed = mod.isReversed();
96 columnModel.getColumn(0).setHeaderValue(reversed ? reversedText : nonReversedText);
97 table.getTableHeader().setToolTipText(
98 reversed ? tr("The nodes of this way are in reverse order") : null);
99 table.getTableHeader().repaint();
100 }
101 }
102 }
103 }
104
105 static class NodeListPopupMenu extends JPopupMenu {
106 private final ZoomToNodeAction zoomToNodeAction;
107 private final ShowHistoryAction showHistoryAction;
108
109 NodeListPopupMenu() {
110 zoomToNodeAction = new ZoomToNodeAction();
111 add(zoomToNodeAction);
112 showHistoryAction = new ShowHistoryAction();
113 add(showHistoryAction);
114 }
115
116 public void prepare(PrimitiveId pid) {
117 zoomToNodeAction.setPrimitiveId(pid);
118 zoomToNodeAction.updateEnabledState();
119
120 showHistoryAction.setPrimitiveId(pid);
121 showHistoryAction.updateEnabledState();
122 }
123 }
124
125 static class ZoomToNodeAction extends AbstractAction {
126 private transient PrimitiveId primitiveId;
127
128 /**
129 * Constructs a new {@code ZoomToNodeAction}.
130 */
131 ZoomToNodeAction() {
132 putValue(NAME, tr("Zoom to node"));
133 putValue(SHORT_DESCRIPTION, tr("Zoom to this node in the current data layer"));
134 new ImageProvider("dialogs", "zoomin").getResource().attachImageIcon(this, true);
135 }
136
137 @Override
138 public void actionPerformed(ActionEvent e) {
139 if (!isEnabled())
140 return;
141 IPrimitive p = getPrimitiveToZoom();
142 if (p != null) {
143 OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData();
144 if (ds != null) {
145 ds.setSelected(p.getPrimitiveId());
146 AutoScaleAction.autoScale(AutoScaleMode.SELECTION);
147 }
148 }
149 }
150
151 public void setPrimitiveId(PrimitiveId pid) {
152 this.primitiveId = pid;
153 updateEnabledState();
154 }
155
156 protected IPrimitive getPrimitiveToZoom() {
157 if (primitiveId == null)
158 return null;
159 OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData();
160 if (ds == null)
161 return null;
162 return ds.getPrimitiveById(primitiveId);
163 }
164
165 public void updateEnabledState() {
166 setEnabled(MainApplication.getLayerManager().getActiveData() != null && getPrimitiveToZoom() != null);
167 }
168 }
169
170 static class ShowHistoryAction extends AbstractAction {
171 private transient PrimitiveId primitiveId;
172
173 /**
174 * Constructs a new {@code ShowHistoryAction}.
175 */
176 ShowHistoryAction() {
177 putValue(NAME, tr("Show history"));
178 putValue(SHORT_DESCRIPTION, tr("Open a history browser with the history of this node"));
179 new ImageProvider("dialogs", "history").getResource().attachImageIcon(this, true);
180 }
181
182 @Override
183 public void actionPerformed(ActionEvent e) {
184 if (isEnabled()) {
185 run();
186 }
187 }
188
189 public void setPrimitiveId(PrimitiveId pid) {
190 this.primitiveId = pid;
191 updateEnabledState();
192 }
193
194 public void run() {
195 if (HistoryDataSet.getInstance().getHistory(primitiveId) == null) {
196 MainApplication.worker.submit(new HistoryLoadTask().add(primitiveId));
197 }
198 MainApplication.worker.submit(() -> {
199 final History h = HistoryDataSet.getInstance().getHistory(primitiveId);
200 if (h == null)
201 return;
202 GuiHelper.runInEDT(() -> HistoryBrowserDialogManager.getInstance().show(h));
203 });
204 }
205
206 public void updateEnabledState() {
207 setEnabled(primitiveId != null && !primitiveId.isNew());
208 }
209 }
210
211 private static PrimitiveId primitiveIdAtRow(DiffTableModel model, int row) {
212 Long id = (Long) model.getValueAt(row, 0).value;
213 return id == null ? null : new SimplePrimitiveId(id, OsmPrimitiveType.NODE);
214 }
215
216 class InternalPopupMenuLauncher extends PopupMenuLauncher {
217 InternalPopupMenuLauncher() {
218 super(new NodeListPopupMenu());
219 }
220
221 @Override
222 protected int checkTableSelection(JTable table, Point p) {
223 int row = super.checkTableSelection(table, p);
224 ((NodeListPopupMenu) menu).prepare(primitiveIdAtRow((DiffTableModel) table.getModel(), row));
225 return row;
226 }
227 }
228
229 static class DoubleClickAdapter extends MouseAdapter {
230 private final JTable table;
231 private final ShowHistoryAction showHistoryAction;
232
233 DoubleClickAdapter(JTable table) {
234 this.table = table;
235 showHistoryAction = new ShowHistoryAction();
236 }
237
238 @Override
239 public void mouseClicked(MouseEvent e) {
240 if (e.getClickCount() < 2)
241 return;
242 int row = table.rowAtPoint(e.getPoint());
243 if (row <= 0)
244 return;
245 PrimitiveId pid = primitiveIdAtRow((DiffTableModel) table.getModel(), row);
246 if (pid == null || pid.isNew())
247 return;
248 showHistoryAction.setPrimitiveId(pid);
249 showHistoryAction.run();
250 }
251 }
252}
Note: See TracBrowser for help on using the repository browser.