Changeset 13521 in josm


Ignore:
Timestamp:
2018-03-13T00:28:24+01:00 (6 weeks ago)
Author:
Don-vip
Message:

fix #16085 - add contextual menu in tag table of history dialog with following entries, similarly to properties dialog:

  • Copy Value
  • Copy selected Key(s)/Value(s)
  • Copy all Keys/Values
  • Go to OSM wiki for tag help
  • Go to Taginfo
Location:
trunk/src/org/openstreetmap/josm/gui
Files:
6 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java

    r13453 r13521  
    1414import java.awt.event.MouseAdapter;
    1515import java.awt.event.MouseEvent;
    16 import java.io.IOException;
    17 import java.net.URI;
    18 import java.net.URISyntaxException;
    1916import java.util.ArrayList;
    2017import java.util.Arrays;
     
    2421import java.util.HashMap;
    2522import java.util.HashSet;
    26 import java.util.LinkedList;
    2723import java.util.List;
    2824import java.util.Map;
     
    8076import org.openstreetmap.josm.data.osm.search.SearchCompiler;
    8177import org.openstreetmap.josm.data.osm.search.SearchSetting;
    82 import org.openstreetmap.josm.data.preferences.StringProperty;
    8378import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    8479import org.openstreetmap.josm.gui.ExtendedDialog;
     
    105100import org.openstreetmap.josm.tools.AlphanumComparator;
    106101import org.openstreetmap.josm.tools.GBC;
    107 import org.openstreetmap.josm.tools.HttpClient;
    108 import org.openstreetmap.josm.tools.ImageProvider;
    109102import org.openstreetmap.josm.tools.InputMapUtils;
    110 import org.openstreetmap.josm.tools.LanguageInfo;
    111103import org.openstreetmap.josm.tools.Logging;
    112 import org.openstreetmap.josm.tools.OpenBrowser;
    113104import org.openstreetmap.josm.tools.Shortcut;
    114105import org.openstreetmap.josm.tools.Utils;
     
    182173
    183174    private final transient DataSetListenerAdapter dataChangedAdapter = new DataSetListenerAdapter(this);
    184     private final HelpAction helpAction = new HelpAction();
    185     private final TaginfoAction taginfoAction = new TaginfoAction();
     175    private final HelpAction helpAction = new HelpAction(tagTable, editHelper::getDataKey, editHelper::getDataValues,
     176            membershipTable, x -> (Relation) membershipData.getValueAt(x, 0));
     177    private final TaginfoAction taginfoAction = new TaginfoAction(tagTable, editHelper::getDataKey, editHelper::getDataValues,
     178            membershipTable, x -> (Relation) membershipData.getValueAt(x, 0));
    186179    private final PasteValueAction pasteValueAction = new PasteValueAction();
    187     private final CopyValueAction copyValueAction = new CopyValueAction();
    188     private final CopyKeyValueAction copyKeyValueAction = new CopyKeyValueAction();
    189     private final CopyAllKeyValueAction copyAllKeyValueAction = new CopyAllKeyValueAction();
     180    private final CopyValueAction copyValueAction = new CopyValueAction(
     181            tagTable, editHelper::getDataKey, Main.main::getInProgressSelection);
     182    private final CopyKeyValueAction copyKeyValueAction = new CopyKeyValueAction(
     183            tagTable, editHelper::getDataKey, Main.main::getInProgressSelection);
     184    private final CopyAllKeyValueAction copyAllKeyValueAction = new CopyAllKeyValueAction(
     185            tagTable, editHelper::getDataKey, Main.main::getInProgressSelection);
    190186    private final SearchAction searchActionSame = new SearchAction(true);
    191187    private final SearchAction searchActionAny = new SearchAction(false);
     
    11281124    }
    11291125
    1130     class HelpAction extends AbstractAction {
    1131         HelpAction() {
    1132             putValue(NAME, tr("Go to OSM wiki for tag help"));
    1133             putValue(SHORT_DESCRIPTION, tr("Launch browser with wiki help for selected object"));
    1134             new ImageProvider("dialogs", "search").getResource().attachImageIcon(this, true);
    1135             putValue(ACCELERATOR_KEY, getKeyStroke());
    1136         }
    1137 
    1138         public KeyStroke getKeyStroke() {
    1139             return KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0);
    1140         }
    1141 
    1142         @Override
    1143         public void actionPerformed(ActionEvent e) {
    1144             try {
    1145                 String base = Config.getPref().get("url.openstreetmap-wiki", "https://wiki.openstreetmap.org/wiki/");
    1146                 String lang = LanguageInfo.getWikiLanguagePrefix();
    1147                 final List<URI> uris = new ArrayList<>();
    1148                 int row;
    1149                 if (tagTable.getSelectedRowCount() == 1) {
    1150                     row = tagTable.getSelectedRow();
    1151                     String key = Utils.encodeUrl(editHelper.getDataKey(row));
    1152                     Map<String, Integer> m = editHelper.getDataValues(row);
    1153                     String val = Utils.encodeUrl(m.entrySet().iterator().next().getKey());
    1154 
    1155                     uris.add(new URI(String.format("%s%sTag:%s=%s", base, lang, key, val)));
    1156                     uris.add(new URI(String.format("%sTag:%s=%s", base, key, val)));
    1157                     uris.add(new URI(String.format("%s%sKey:%s", base, lang, key)));
    1158                     uris.add(new URI(String.format("%sKey:%s", base, key)));
    1159                     uris.add(new URI(String.format("%s%sMap_Features", base, lang)));
    1160                     uris.add(new URI(String.format("%sMap_Features", base)));
    1161                 } else if (membershipTable.getSelectedRowCount() == 1) {
    1162                     row = membershipTable.getSelectedRow();
    1163                     String type = ((Relation) membershipData.getValueAt(row, 0)).get("type");
    1164                     if (type != null) {
    1165                         type = Utils.encodeUrl(type);
    1166                     }
    1167 
    1168                     if (type != null && !type.isEmpty()) {
    1169                         uris.add(new URI(String.format("%s%sRelation:%s", base, lang, type)));
    1170                         uris.add(new URI(String.format("%sRelation:%s", base, type)));
    1171                     }
    1172 
    1173                     uris.add(new URI(String.format("%s%sRelations", base, lang)));
    1174                     uris.add(new URI(String.format("%sRelations", base)));
    1175                 } else {
    1176                     // give the generic help page, if more than one element is selected
    1177                     uris.add(new URI(String.format("%s%sMap_Features", base, lang)));
    1178                     uris.add(new URI(String.format("%sMap_Features", base)));
    1179                 }
    1180 
    1181                 MainApplication.worker.execute(() -> displayHelp(uris));
    1182             } catch (URISyntaxException e1) {
    1183                 Logging.error(e1);
    1184             }
    1185         }
    1186 
    1187         private void displayHelp(final List<URI> uris) {
    1188             try {
    1189                 // find a page that actually exists in the wiki
    1190                 HttpClient.Response conn;
    1191                 for (URI u : uris) {
    1192                     conn = HttpClient.create(u.toURL(), "HEAD").connect();
    1193 
    1194                     if (conn.getResponseCode() != 200) {
    1195                         conn.disconnect();
    1196                     } else {
    1197                         long osize = conn.getContentLength();
    1198                         if (osize > -1) {
    1199                             conn.disconnect();
    1200 
    1201                             final URI newURI = new URI(u.toString()
    1202                                     .replace("=", "%3D") /* do not URLencode whole string! */
    1203                                     .replaceFirst("/wiki/", "/w/index.php?redirect=no&title=")
    1204                             );
    1205                             conn = HttpClient.create(newURI.toURL(), "HEAD").connect();
    1206                         }
    1207 
    1208                         /* redirect pages have different content length, but retrieving a "nonredirect"
    1209                          *  page using index.php and the direct-link method gives slightly different
    1210                          *  content lengths, so we have to be fuzzy.. (this is UGLY, recode if u know better)
    1211                          */
    1212                         if (osize > -1 && conn.getContentLength() != -1 && Math.abs(conn.getContentLength() - osize) > 200) {
    1213                             Logging.info("{0} is a mediawiki redirect", u);
    1214                             conn.disconnect();
    1215                         } else {
    1216                             conn.disconnect();
    1217 
    1218                             OpenBrowser.displayUrl(u.toString());
    1219                             break;
    1220                         }
    1221                     }
    1222                 }
    1223             } catch (URISyntaxException | IOException e1) {
    1224                 Logging.error(e1);
    1225             }
    1226         }
    1227     }
    1228 
    1229     class TaginfoAction extends JosmAction {
    1230 
    1231         final transient StringProperty TAGINFO_URL_PROP = new StringProperty("taginfo.url", "https://taginfo.openstreetmap.org/");
    1232 
    1233         TaginfoAction() {
    1234             super(tr("Go to Taginfo"), "dialogs/taginfo", tr("Launch browser with Taginfo statistics for selected object"), null, false);
    1235         }
    1236 
    1237         @Override
    1238         public void actionPerformed(ActionEvent e) {
    1239             final String url;
    1240             if (tagTable.getSelectedRowCount() == 1) {
    1241                 final int row = tagTable.getSelectedRow();
    1242                 final String key = Utils.encodeUrl(editHelper.getDataKey(row)).replaceAll("\\+", "%20");
    1243                 Map<String, Integer> values = editHelper.getDataValues(row);
    1244                 if (values.size() == 1) {
    1245                     url = TAGINFO_URL_PROP.get() + "tags/" + key
    1246                             + '=' + Utils.encodeUrl(values.keySet().iterator().next()).replaceAll("\\+", "%20");
    1247                 } else {
    1248                     url = TAGINFO_URL_PROP.get() + "keys/" + key;
    1249                 }
    1250             } else if (membershipTable.getSelectedRowCount() == 1) {
    1251                 final String type = ((Relation) membershipData.getValueAt(membershipTable.getSelectedRow(), 0)).get("type");
    1252                 url = TAGINFO_URL_PROP.get() + "relations/" + type;
    1253             } else {
    1254                 return;
    1255             }
    1256             OpenBrowser.displayUrl(url);
    1257         }
    1258     }
    1259 
    12601126    class PasteValueAction extends AbstractAction {
    12611127        PasteValueAction() {
     
    12771143    }
    12781144
    1279     abstract class AbstractCopyAction extends AbstractAction {
    1280 
    1281         protected abstract Collection<String> getString(OsmPrimitive p, String key);
    1282 
    1283         @Override
    1284         public void actionPerformed(ActionEvent ae) {
    1285             int[] rows = tagTable.getSelectedRows();
    1286             Set<String> values = new TreeSet<>();
    1287             Collection<OsmPrimitive> sel = Main.main.getInProgressSelection();
    1288             if (rows.length == 0 || sel.isEmpty()) return;
    1289 
    1290             for (int row: rows) {
    1291                 String key = editHelper.getDataKey(row);
    1292                 if (sel.isEmpty())
    1293                     return;
    1294                 for (OsmPrimitive p : sel) {
    1295                     Collection<String> s = getString(p, key);
    1296                     if (s != null) {
    1297                         values.addAll(s);
    1298                     }
    1299                 }
    1300             }
    1301             if (!values.isEmpty()) {
    1302                 ClipboardUtils.copyString(Utils.join("\n", values));
    1303             }
    1304         }
    1305     }
    1306 
    1307     class CopyValueAction extends AbstractCopyAction {
    1308 
    1309         /**
    1310          * Constructs a new {@code CopyValueAction}.
    1311          */
    1312         CopyValueAction() {
    1313             putValue(NAME, tr("Copy Value"));
    1314             putValue(SHORT_DESCRIPTION, tr("Copy the value of the selected tag to clipboard"));
    1315         }
    1316 
    1317         @Override
    1318         protected Collection<String> getString(OsmPrimitive p, String key) {
    1319             String v = p.get(key);
    1320             return v == null ? null : Collections.singleton(v);
    1321         }
    1322     }
    1323 
    1324     class CopyKeyValueAction extends AbstractCopyAction {
    1325 
    1326         CopyKeyValueAction() {
    1327             putValue(NAME, tr("Copy selected Key(s)/Value(s)"));
    1328             putValue(SHORT_DESCRIPTION, tr("Copy the key and value of the selected tag(s) to clipboard"));
    1329         }
    1330 
    1331         @Override
    1332         protected Collection<String> getString(OsmPrimitive p, String key) {
    1333             String v = p.get(key);
    1334             return v == null ? null : Collections.singleton(new Tag(key, v).toString());
    1335         }
    1336     }
    1337 
    1338     class CopyAllKeyValueAction extends AbstractCopyAction {
    1339 
    1340         CopyAllKeyValueAction() {
    1341             putValue(NAME, tr("Copy all Keys/Values"));
    1342             putValue(SHORT_DESCRIPTION, tr("Copy the key and value of all the tags to clipboard"));
    1343             Shortcut sc = Shortcut.registerShortcut("system:copytags", tr("Edit: {0}", tr("Copy Tags")), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
    1344             MainApplication.registerActionShortcut(this, sc);
    1345             sc.setAccelerator(this);
    1346         }
    1347 
    1348         @Override
    1349         protected Collection<String> getString(OsmPrimitive p, String key) {
    1350             List<String> r = new LinkedList<>();
    1351             for (Entry<String, String> kv : p.getKeys().entrySet()) {
    1352                 r.add(new Tag(kv.getKey(), kv.getValue()).toString());
    1353             }
    1354             return r;
    1355         }
    1356     }
    1357 
    13581145    class SearchAction extends AbstractAction {
    13591146        private final boolean sameType;
  • trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java

    r10637 r13521  
    44import java.awt.event.FocusEvent;
    55import java.awt.event.FocusListener;
     6import java.util.Arrays;
     7import java.util.Collection;
     8import java.util.HashMap;
     9import java.util.Map;
     10import java.util.function.Function;
     11import java.util.function.Supplier;
    612
     13import javax.swing.JPopupMenu;
    714import javax.swing.JTable;
    815import javax.swing.ListSelectionModel;
     16
     17import org.openstreetmap.josm.data.osm.Tagged;
     18import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
     19import org.openstreetmap.josm.gui.dialogs.properties.CopyAllKeyValueAction;
     20import org.openstreetmap.josm.gui.dialogs.properties.CopyKeyValueAction;
     21import org.openstreetmap.josm.gui.dialogs.properties.CopyValueAction;
     22import org.openstreetmap.josm.gui.dialogs.properties.HelpAction;
     23import org.openstreetmap.josm.gui.dialogs.properties.TaginfoAction;
     24import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    925
    1026/**
     
    1632 *   <li>on the right, it displays the list of tags for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
    1733 * </ul>
    18  *
     34 * @since 1709
    1935 */
    2036public class TagInfoViewer extends HistoryViewerPanel {
     
    4662    @Override
    4763    protected JTable buildReferenceTable() {
    48         JTable table = new JTable(
    49                 model.getTagTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
    50                 new TagTableColumnModel()
    51         );
    52         table.setName("table.referencetagtable");
    53         setUpDataTransfer(table);
    54         return table;
     64        return buildTable(PointInTimeType.REFERENCE_POINT_IN_TIME, "table.referencetagtable", model::getReferencePointInTime);
    5565    }
    5666
    5767    @Override
    5868    protected JTable buildCurrentTable() {
    59         JTable table = new JTable(
    60                 model.getTagTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
    61                 new TagTableColumnModel()
    62         );
    63         table.setName("table.currenttagtable");
    64         setUpDataTransfer(table);
    65         return table;
     69        return buildTable(PointInTimeType.CURRENT_POINT_IN_TIME, "table.currenttagtable", model::getCurrentPointInTime);
    6670    }
    6771
    68     private void setUpDataTransfer(JTable table) {
     72    private JTable buildTable(PointInTimeType pointInTime, String name, Supplier<HistoryOsmPrimitive> histoSp) {
     73        TagTableModel tagTableModel = model.getTagTableModel(pointInTime);
     74        JTable table = new JTable(tagTableModel, new TagTableColumnModel());
     75        table.setName(name);
    6976        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    7077        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
    7178        table.setTransferHandler(new TagInfoTransferHandler());
    7279        table.addFocusListener(new RepaintOnFocusChange());
     80        JPopupMenu tagMenu = new JPopupMenu();
     81
     82        Function<Integer, String> tagKeyFn = x -> (String) table.getValueAt(x, 0);
     83        Function<Integer, Map<String, Integer>> tagValuesFn = x -> {
     84            Map<String, Integer> map = new HashMap<>();
     85            String key = tagTableModel.getValue((String) table.getValueAt(x, 0));
     86            if (key != null) {
     87                map.put(key, 1);
     88            }
     89            return map;
     90        };
     91        Supplier<Collection<? extends Tagged>> objectSp = () -> Arrays.asList(histoSp.get());
     92
     93        tagMenu.add(new CopyValueAction(table, tagKeyFn, objectSp));
     94        tagMenu.add(new CopyKeyValueAction(table, tagKeyFn, objectSp));
     95        tagMenu.add(new CopyAllKeyValueAction(table, tagKeyFn, objectSp));
     96        tagMenu.addSeparator();
     97        tagMenu.add(new HelpAction(table, tagKeyFn, tagValuesFn, null, null));
     98        tagMenu.add(new TaginfoAction(table, tagKeyFn, tagValuesFn, null, null));
     99
     100        table.addMouseListener(new PopupMenuLauncher(tagMenu));
     101        return table;
    73102    }
    74103}
Note: See TracChangeset for help on using the changeset viewer.