source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java@ 2657

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

Fixed #4058 Relation history window does not show up

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.GridLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.KeyEvent;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.Collections;
16import java.util.List;
17
18import javax.swing.AbstractAction;
19import javax.swing.Action;
20import javax.swing.DefaultListSelectionModel;
21import javax.swing.JComponent;
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24import javax.swing.JScrollPane;
25import javax.swing.JTable;
26import javax.swing.ListSelectionModel;
27import javax.swing.SwingUtilities;
28import javax.swing.event.ListSelectionEvent;
29import javax.swing.event.ListSelectionListener;
30import javax.swing.table.DefaultTableCellRenderer;
31import javax.swing.table.DefaultTableColumnModel;
32import javax.swing.table.DefaultTableModel;
33import javax.swing.table.TableCellRenderer;
34import javax.swing.table.TableColumn;
35
36import org.openstreetmap.josm.Main;
37import org.openstreetmap.josm.data.SelectionChangedListener;
38import org.openstreetmap.josm.data.osm.DataSet;
39import org.openstreetmap.josm.data.osm.OsmPrimitive;
40import org.openstreetmap.josm.data.osm.PrimitiveId;
41import org.openstreetmap.josm.data.osm.history.History;
42import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
43import org.openstreetmap.josm.data.osm.history.HistoryDataSetListener;
44import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
45import org.openstreetmap.josm.gui.SideButton;
46import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager;
47import org.openstreetmap.josm.gui.history.HistoryLoadTask;
48import org.openstreetmap.josm.tools.BugReportExceptionHandler;
49import org.openstreetmap.josm.tools.ImageProvider;
50import org.openstreetmap.josm.tools.Shortcut;
51
52/**
53 * HistoryDialog displays a list of the currently selected primitives and provides
54 * two actions for (1) (re)loading the history of the selected primitives and (2)
55 * for launching a history browser for each selected primitive.
56 *
57 */
58public class HistoryDialog extends ToggleDialog implements HistoryDataSetListener {
59
60 /** the table model */
61 protected HistoryItemTableModel model;
62 /** the table with the history items */
63 protected JTable historyTable;
64
65 protected ShowHistoryAction showHistoryAction;
66 protected ReloadAction reloadAction;
67
68 /**
69 * builds the row with the command buttons
70 *
71 * @return the rows with the command buttons
72 */
73 protected JPanel buildButtonRow() {
74 JPanel buttons = new JPanel(new GridLayout(1,2));
75
76 SideButton btn = new SideButton(reloadAction = new ReloadAction());
77 btn.setName("btn.reload");
78 buttons.add(btn);
79
80 btn = new SideButton(showHistoryAction = new ShowHistoryAction());
81 btn.setName("btn.showhistory");
82 buttons.add(btn);
83
84 return buttons;
85 }
86
87 /**
88 * builds the GUI
89 */
90 protected void build() {
91 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
92 historyTable = new JTable(
93 model = new HistoryItemTableModel(selectionModel),
94 new HistoryTableColumnModel(),
95 selectionModel
96 );
97 historyTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
98 historyTable.setName("table.historyitems");
99 final TableCellRenderer oldRenderer = historyTable.getTableHeader().getDefaultRenderer();
100 historyTable.getTableHeader().setDefaultRenderer(new DefaultTableCellRenderer(){
101 @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
102 JComponent c = (JComponent)oldRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
103 if (!value.equals(""))
104 return c;
105 JLabel l = new JLabel(ImageProvider.get("misc","showhide"));
106 l.setForeground(c.getForeground());
107 l.setBackground(c.getBackground());
108 l.setFont(c.getFont());
109 l.setBorder(c.getBorder());
110 l.setOpaque(true);
111 return l;
112 }
113 });
114 historyTable.addMouseListener(new ShowHistoryMouseAdapter());
115
116 JScrollPane pane = new JScrollPane(historyTable);
117 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
118 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
119 historyTable.setTableHeader(null);
120 pane.setColumnHeaderView(null);
121 add(pane, BorderLayout.CENTER);
122
123 add(buildButtonRow(), BorderLayout.SOUTH);
124
125 // wire actions
126 //
127 historyTable.getSelectionModel().addListSelectionListener(showHistoryAction);
128 historyTable.getSelectionModel().addListSelectionListener(reloadAction);
129 }
130
131 public HistoryDialog() {
132 super(tr("History"), "history", tr("Display the history of all selected items."),
133 Shortcut.registerShortcut("subwindow:history", tr("Toggle: {0}", tr("History")), KeyEvent.VK_H,
134 Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
135 build();
136 DataSet.selListeners.add(model);
137 HistoryDataSet.getInstance().addHistoryDataSetListener(this);
138 }
139
140 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) {
141 model.refresh();
142 }
143
144 /**
145 * The table model with the history items
146 *
147 */
148 static class HistoryItemTableModel extends DefaultTableModel implements SelectionChangedListener{
149 private ArrayList<OsmPrimitive> data;
150 private DefaultListSelectionModel selectionModel;
151
152 public HistoryItemTableModel(DefaultListSelectionModel selectionModel) {
153 data = new ArrayList<OsmPrimitive>();
154 this.selectionModel = selectionModel;
155 }
156
157 @Override
158 public int getRowCount() {
159 if (data == null)
160 return 0;
161 return data.size();
162 }
163
164 @Override
165 public Object getValueAt(int row, int column) {
166 return data.get(row);
167 }
168
169 @Override
170 public boolean isCellEditable(int row, int column) {
171 return false;
172 }
173
174 protected List<OsmPrimitive> getSelectedPrimitives() {
175 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();
176 for (int i=0; i< data.size(); i++) {
177 if (selectionModel.isSelectedIndex(i)) {
178 ret.add(data.get(i));
179 }
180 }
181 return ret;
182 }
183
184 protected void selectPrimitives(Collection<OsmPrimitive> primitives) {
185 for (OsmPrimitive p: primitives) {
186 int idx = data.indexOf(p);
187 if (idx < 0) {
188 continue;
189 }
190 selectionModel.addSelectionInterval(idx, idx);
191 }
192 }
193
194 public void refresh() {
195 List<OsmPrimitive> selectedPrimitives = getSelectedPrimitives();
196 data.clear();
197 if (Main.main.getCurrentDataSet() == null)
198 return;
199 for (OsmPrimitive primitive: Main.main.getCurrentDataSet().getSelected()) {
200 if (primitive.isNew()) {
201 continue;
202 }
203 data.add(primitive);
204 }
205 fireTableDataChanged();
206 selectPrimitives(selectedPrimitives);
207 }
208
209 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
210 data.clear();
211 selectionModel.clearSelection();
212 if (newSelection == null || newSelection.isEmpty()) return;
213 for (OsmPrimitive primitive: newSelection) {
214 if (primitive.isNew()) {
215 continue;
216 }
217 data.add(primitive);
218 }
219 fireTableDataChanged();
220 selectionModel.addSelectionInterval(0, data.size()-1);
221 }
222
223 public List<OsmPrimitive> getPrimitives(int [] rows) {
224 if (rows == null || rows.length == 0) return Collections.emptyList();
225 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(rows.length);
226 for (int row: rows) {
227 ret.add(data.get(row));
228 }
229 return ret;
230 }
231
232 public OsmPrimitive getPrimitive(int row) {
233 return data.get(row);
234 }
235 }
236
237 /**
238 * The column model
239 */
240 static class HistoryTableColumnModel extends DefaultTableColumnModel {
241 protected void createColumns() {
242 TableColumn col = null;
243 OsmPrimitivRenderer renderer = new OsmPrimitivRenderer();
244 // column 0 - History item
245 col = new TableColumn(0);
246 col.setHeaderValue(tr("Object with history"));
247 col.setCellRenderer(renderer);
248 addColumn(col);
249 }
250
251 public HistoryTableColumnModel() {
252 createColumns();
253 }
254 }
255
256 /**
257 * The action for reloading history information of the currently selected primitives.
258 *
259 */
260 class ReloadAction extends AbstractAction implements ListSelectionListener {
261 public ReloadAction() {
262 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs","refresh"));
263 putValue(Action.NAME, tr("Reload"));
264 putValue(Action.SHORT_DESCRIPTION, tr("Reload all currently selected objects and refresh the list."));
265 updateEnabledState();
266 }
267
268 public void actionPerformed(ActionEvent e) {
269 int [] rows = historyTable.getSelectedRows();
270 if (rows == null || rows.length == 0) return;
271
272 List<OsmPrimitive> selectedItems = model.getPrimitives(rows);
273 HistoryLoadTask task = new HistoryLoadTask();
274 task.add(selectedItems);
275 Main.worker.execute(task);
276 }
277
278 protected void updateEnabledState() {
279 setEnabled(historyTable.getSelectedRowCount() > 0);
280 }
281
282 public void valueChanged(ListSelectionEvent e) {
283 updateEnabledState();
284 }
285 }
286
287 class ShowHistoryMouseAdapter extends MouseAdapter {
288 @Override
289 public void mouseClicked(MouseEvent e) {
290 if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
291 int row = historyTable.rowAtPoint(e.getPoint());
292 new ShowHistoryAction().showHistory(Collections.singletonList(model.getPrimitive(row)));
293 }
294 }
295 }
296
297 /**
298 * The action for showing history information of the current history item.
299 */
300 class ShowHistoryAction extends AbstractAction implements ListSelectionListener {
301 public ShowHistoryAction() {
302 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs","history"));
303 putValue(Action.NAME, tr("Show"));
304 putValue(Action.SHORT_DESCRIPTION, tr("Display the history of the selected objects."));
305 updateEnabledState();
306 }
307
308 protected List<OsmPrimitive> filterPrimitivesWithUnloadedHistory(Collection<OsmPrimitive> primitives) {
309 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(primitives.size());
310 for (OsmPrimitive p: primitives) {
311 if (HistoryDataSet.getInstance().getHistory(p.getPrimitiveId()) == null) {
312 ret.add(p);
313 }
314 }
315 return ret;
316 }
317
318 public void showHistory(final List<OsmPrimitive> primitives) {
319 List<OsmPrimitive> toLoad = filterPrimitivesWithUnloadedHistory(primitives);
320 if (!toLoad.isEmpty()) {
321 HistoryLoadTask task = new HistoryLoadTask();
322 task.add(primitives);
323 Main.worker.submit(task);
324 }
325
326 Runnable r = new Runnable() {
327 public void run() {
328 try {
329 for (OsmPrimitive p : primitives) {
330 History h = HistoryDataSet.getInstance().getHistory(p.getPrimitiveId());
331 if (h == null) {
332 continue;
333 }
334 HistoryBrowserDialogManager.getInstance().show(h);
335 }
336 } catch (final Exception e) {
337 SwingUtilities.invokeLater(new Runnable() {
338 public void run() {
339 BugReportExceptionHandler.handleException(e);
340 }
341 });
342 }
343
344 }
345 };
346 Main.worker.submit(r);
347 }
348
349 public void actionPerformed(ActionEvent e) {
350 int [] rows = historyTable.getSelectedRows();
351 if (rows == null || rows.length == 0) return;
352 showHistory(model.getPrimitives(rows));
353 }
354
355 protected void updateEnabledState() {
356 setEnabled(historyTable.getSelectedRowCount() > 0);
357 }
358
359 public void valueChanged(ListSelectionEvent e) {
360 updateEnabledState();
361 }
362 }
363}
Note: See TracBrowser for help on using the repository browser.