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;
011import java.util.Collections;
012
013import javax.swing.JOptionPane;
014
015import org.openstreetmap.josm.data.osm.DataSet;
016import org.openstreetmap.josm.data.osm.OsmPrimitive;
017import org.openstreetmap.josm.gui.MainApplication;
018import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
019import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable;
020import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
021import org.openstreetmap.josm.gui.layer.OsmDataLayer;
022import org.openstreetmap.josm.tools.Shortcut;
023
024/**
025 * Copy OSM primitives to clipboard in order to paste them, or their tags, somewhere else.
026 * @since 404
027 */
028public class CopyAction extends JosmAction {
029    /**
030     * Constructs a new {@code CopyAction}.
031     */
032    public CopyAction() {
033        super(tr("Copy"), "copy",
034                tr("Copy selected objects to paste buffer."),
035                Shortcut.registerShortcut("system:copy", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_C, Shortcut.CTRL), true);
036        setHelpId(ht("/Action/Copy"));
037        // CUA shortcut for copy (https://en.wikipedia.org/wiki/IBM_Common_User_Access#Description)
038        MainApplication.registerActionShortcut(this,
039                Shortcut.registerShortcut("system:copy:cua", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_INSERT, Shortcut.CTRL));
040    }
041
042    @Override
043    public void actionPerformed(ActionEvent e) {
044        DataSet set = getLayerManager().getActiveDataSet();
045        Collection<OsmPrimitive> selection = set == null ? Collections.<OsmPrimitive>emptySet() : set.getSelected();
046        if (selection.isEmpty()) {
047            showEmptySelectionWarning();
048            return;
049        }
050
051        copy(getLayerManager().getActiveDataLayer(), selection);
052    }
053
054    /**
055     * Copies the given primitive ids to the clipboard. The output by this function
056     * looks similar to: node 1089302677,node 1089303458,way 93793372
057     * @param source The OSM data layer source
058     * @param primitives The OSM primitives to copy
059     */
060    public static void copy(OsmDataLayer source, Collection<OsmPrimitive> primitives) {
061        // copy ids to the clipboard
062        ClipboardUtils.copy(new PrimitiveTransferable(PrimitiveTransferData.getDataWithReferences(primitives), source));
063    }
064
065    @Override
066    protected void updateEnabledState() {
067        updateEnabledStateOnCurrentSelection(true);
068    }
069
070    @Override
071    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
072        setEnabled(selection != null && !selection.isEmpty());
073    }
074
075    protected void showEmptySelectionWarning() {
076        JOptionPane.showMessageDialog(
077                MainApplication.getMainFrame(),
078                tr("Please select something to copy."),
079                tr("Information"),
080                JOptionPane.INFORMATION_MESSAGE
081        );
082    }
083}