001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.event.ActionEvent; 008import java.awt.event.KeyEvent; 009import java.util.LinkedHashSet; 010import java.util.Set; 011import java.util.stream.Collectors; 012 013import javax.swing.JList; 014import javax.swing.JTable; 015 016import org.openstreetmap.josm.data.osm.OsmData; 017import org.openstreetmap.josm.data.osm.PrimitiveId; 018import org.openstreetmap.josm.gui.MainApplication; 019import org.openstreetmap.josm.gui.dialogs.OsmIdSelectionDialog; 020import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager; 021import org.openstreetmap.josm.io.NetworkManager; 022import org.openstreetmap.josm.io.OnlineResource; 023import org.openstreetmap.josm.tools.Shortcut; 024 025/** 026 * Display history information about OSM ways, nodes, or relations. 027 * @since 968 028 */ 029public class HistoryInfoAction extends JosmAction { 030 031 /** Action shortcut, made public in order to be used from {@code GettingStarted} page. */ 032 public static final Shortcut SHORTCUT = Shortcut.registerShortcut("core:historyinfo", tr("View: {0}", tr("History")), 033 KeyEvent.VK_H, Shortcut.CTRL); 034 035 /** 036 * Constructs a new {@code HistoryInfoAction}. 037 */ 038 public HistoryInfoAction() { 039 super(tr("History"), "dialogs/history", 040 tr("Display history information about OSM ways, nodes, or relations."), 041 SHORTCUT, true, "action/historyinfo", false); 042 setHelpId(ht("/Action/ObjectHistory")); 043 setEnabled(true); 044 } 045 046 @Override 047 public void actionPerformed(ActionEvent ae) { 048 // Generic handling of tables displaying OSM primitives 049 Set<PrimitiveId> sel = new LinkedHashSet<>(); 050 if (ae.getSource() instanceof JTable) { 051 JTable table = (JTable) ae.getSource(); 052 for (int row : table.getSelectedRows()) { 053 for (int col = 0; col < table.getModel().getColumnCount(); col++) { 054 Object value = table.getModel().getValueAt(row, col); 055 if (value instanceof PrimitiveId) { 056 sel.add((PrimitiveId) value); 057 break; 058 } 059 } 060 } 061 } else if (ae.getSource() instanceof JList) { 062 JList<?> list = (JList<?>) ae.getSource(); 063 sel = list.getSelectedValuesList() 064 .stream().filter(v -> v instanceof PrimitiveId) 065 .map(v -> (PrimitiveId) v) 066 .collect(Collectors.toCollection(LinkedHashSet::new)); 067 } 068 if (!sel.isEmpty()) { 069 HistoryBrowserDialogManager.getInstance().showHistory(sel); 070 return; 071 } 072 // Otherwise show history for currently selected objects 073 OsmData<?, ?, ?, ?> set = getLayerManager().getActiveData(); 074 if (set != null && !set.selectionEmpty()) { 075 HistoryBrowserDialogManager.getInstance().showHistory(set.getAllSelected()); 076 } else { 077 HistoryObjectIDDialog dialog = new HistoryObjectIDDialog(); 078 if (dialog.showDialog().getValue() == dialog.getContinueButtonIndex()) { 079 HistoryBrowserDialogManager.getInstance().showHistory(dialog.getOsmIds()); 080 } 081 } 082 } 083 084 /** 085 * Dialog allowing to choose object id if no one is selected. 086 * @since 6448 087 */ 088 public static class HistoryObjectIDDialog extends OsmIdSelectionDialog { 089 090 /** 091 * Constructs a new {@code HistoryObjectIDDialog}. 092 */ 093 public HistoryObjectIDDialog() { 094 super(MainApplication.getMainFrame(), tr("Show history"), tr("Show history"), tr("Cancel")); 095 setButtonIcons("dialogs/history", "cancel"); 096 init(); 097 } 098 099 @Override 100 public void setupDialog() { 101 super.setupDialog(); 102 buttons.get(0).setEnabled(!NetworkManager.isOffline(OnlineResource.OSM_API)); 103 } 104 } 105}