001// License: GPL. For details, see LICENSE file. 002// Author: David Earl 003package org.openstreetmap.josm.actions; 004 005import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 006import static org.openstreetmap.josm.tools.I18n.tr; 007 008import java.awt.event.ActionEvent; 009import java.awt.event.KeyEvent; 010import java.util.Collection; 011 012import javax.swing.JOptionPane; 013 014import org.openstreetmap.josm.Main; 015import org.openstreetmap.josm.data.osm.OsmPrimitive; 016import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 017import org.openstreetmap.josm.gui.layer.OsmDataLayer; 018import org.openstreetmap.josm.tools.Shortcut; 019import org.openstreetmap.josm.tools.Utils; 020 021/** 022 * Copy OSM primitives to clipboard in order to paste them, or their tags, somewhere else. 023 * @since 404 024 */ 025public final class CopyAction extends JosmAction { 026 027 /** regular expression that matches text clipboard contents after copying */ 028 public static final String CLIPBOARD_REGEXP = "((node|way|relation)\\s\\d+,)*(node|way|relation)\\s\\d+"; 029 030 /** 031 * Constructs a new {@code CopyAction}. 032 */ 033 public CopyAction() { 034 super(tr("Copy"), "copy", 035 tr("Copy selected objects to paste buffer."), 036 Shortcut.registerShortcut("system:copy", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_C, Shortcut.CTRL), true); 037 putValue("help", ht("/Action/Copy")); 038 // CUA shortcut for copy (https://en.wikipedia.org/wiki/IBM_Common_User_Access#Description) 039 Main.registerActionShortcut(this, 040 Shortcut.registerShortcut("system:copy:cua", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_INSERT, Shortcut.CTRL)); 041 } 042 043 @Override 044 public void actionPerformed(ActionEvent e) { 045 if (isEmptySelection()) return; 046 Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected(); 047 048 copy(getLayerManager().getEditLayer(), selection); 049 } 050 051 /** 052 * Copies the given primitive ids to the clipboard. The output by this function 053 * looks similar to: node 1089302677,node 1089303458,way 93793372 054 * @param source The OSM data layer source 055 * @param primitives The OSM primitives to copy 056 */ 057 public static void copy(OsmDataLayer source, Collection<OsmPrimitive> primitives) { 058 // copy ids to the clipboard 059 String ids = getCopyString(primitives); 060 Utils.copyToClipboard(ids); 061 062 Main.pasteBuffer.makeCopy(primitives); 063 Main.pasteSource = source; 064 } 065 066 static String getCopyString(Collection<? extends OsmPrimitive> primitives) { 067 StringBuilder idsBuilder = new StringBuilder(); 068 for (OsmPrimitive p : primitives) { 069 idsBuilder.append(OsmPrimitiveType.from(p).getAPIName()).append(' ').append(p.getId()).append(','); 070 } 071 return idsBuilder.substring(0, idsBuilder.length() - 1); 072 } 073 074 @Override 075 protected void updateEnabledState() { 076 updateEnabledStateOnCurrentSelection(); 077 } 078 079 @Override 080 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { 081 setEnabled(selection != null && !selection.isEmpty()); 082 } 083 084 private boolean isEmptySelection() { 085 Collection<OsmPrimitive> sel = getLayerManager().getEditDataSet().getSelected(); 086 if (sel.isEmpty()) { 087 JOptionPane.showMessageDialog( 088 Main.parent, 089 tr("Please select something to copy."), 090 tr("Information"), 091 JOptionPane.INFORMATION_MESSAGE 092 ); 093 return true; 094 } 095 return false; 096 } 097}