001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.history; 003 004import java.awt.event.FocusEvent; 005import java.awt.event.FocusListener; 006import java.util.Collection; 007import java.util.Collections; 008import java.util.Map; 009import java.util.function.IntFunction; 010import java.util.function.Supplier; 011 012import javax.swing.JPopupMenu; 013import javax.swing.JTable; 014import javax.swing.ListSelectionModel; 015 016import org.openstreetmap.josm.data.osm.Tagged; 017import org.openstreetmap.josm.gui.dialogs.properties.CopyAllKeyValueAction; 018import org.openstreetmap.josm.gui.dialogs.properties.CopyKeyValueAction; 019import org.openstreetmap.josm.gui.dialogs.properties.CopyValueAction; 020import org.openstreetmap.josm.gui.dialogs.properties.HelpTagAction; 021import org.openstreetmap.josm.gui.dialogs.properties.TaginfoAction; 022import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher; 023 024/** 025 * TagInfoViewer is a UI component which displays the list of tags of two 026 * version of a {@link org.openstreetmap.josm.data.osm.OsmPrimitive} in a {@link org.openstreetmap.josm.data.osm.history.History}. 027 * 028 * <ul> 029 * <li>on the left, it displays the list of tags for the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li> 030 * <li>on the right, it displays the list of tags for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li> 031 * </ul> 032 * @since 1709 033 */ 034public class TagInfoViewer extends HistoryViewerPanel { 035 private static final class RepaintOnFocusChange implements FocusListener { 036 @Override 037 public void focusLost(FocusEvent e) { 038 repaintSelected(e); 039 } 040 041 @Override 042 public void focusGained(FocusEvent e) { 043 repaintSelected(e); 044 } 045 046 private static void repaintSelected(FocusEvent e) { 047 // we would only need the selected rows, but this is easier: 048 e.getComponent().repaint(); 049 } 050 } 051 052 /** 053 * Constructs a new {@code TagInfoViewer}. 054 * @param model The history browsing model 055 */ 056 public TagInfoViewer(HistoryBrowserModel model) { 057 super(model); 058 } 059 060 @Override 061 protected JTable buildTable(PointInTimeType pointInTime) { 062 TagTableModel tagTableModel = model.getTagTableModel(pointInTime); 063 JTable table = new JTable(tagTableModel, new TagTableColumnModel()); 064 table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 065 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel()); 066 table.setTransferHandler(new TagInfoTransferHandler()); 067 table.addFocusListener(new RepaintOnFocusChange()); 068 JPopupMenu tagMenu = new JPopupMenu(); 069 070 IntFunction<String> tagKeyFn = x -> (String) table.getValueAt(x, 0); 071 IntFunction<Map<String, Integer>> tagValuesFn = x -> { 072 String key = tagTableModel.getValue((String) table.getValueAt(x, 0)); 073 if (key != null) { 074 return Collections.singletonMap(key, 1); 075 } 076 return Collections.emptyMap(); 077 }; 078 Supplier<Collection<? extends Tagged>> objectSp = () -> Collections.singletonList(model.getPointInTime(pointInTime)); 079 080 tagMenu.add(trackJosmAction(new CopyValueAction(table, tagKeyFn, objectSp))); 081 final CopyKeyValueAction copyKeyValueAction = new CopyKeyValueAction(table, tagKeyFn, objectSp); 082 tagMenu.add(trackJosmAction(copyKeyValueAction)); 083 tagMenu.addPopupMenuListener(copyKeyValueAction); 084 tagMenu.add(trackJosmAction(new CopyAllKeyValueAction(table, tagKeyFn, objectSp))); 085 tagMenu.addSeparator(); 086 tagMenu.add(trackJosmAction(new HelpTagAction(table, tagKeyFn, tagValuesFn))); 087 tagMenu.add(trackJosmAction(new TaginfoAction(table, tagKeyFn, tagValuesFn, null, null))); 088 089 table.addMouseListener(new PopupMenuLauncher(tagMenu)); 090 return table; 091 } 092}