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

Last change on this file since 2710 was 2710, checked in by stoecker, 14 years ago

close #4222 - unify design of right menus again

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