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;
023import org.openstreetmap.josm.tools.Utils;
024
025/**
026 * Copy OSM primitives to clipboard in order to paste them, or their tags, somewhere else.
027 * @since 404
028 */
029public class CopyAction extends JosmAction {
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        setHelpId(ht("/Action/Copy"));
038        // CUA shortcut for copy (https://en.wikipedia.org/wiki/IBM_Common_User_Access#Description)
039        MainApplication.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        DataSet set = getLayerManager().getActiveDataSet();
046        Collection<OsmPrimitive> selection = set == null ? Collections.<OsmPrimitive>emptySet() : set.getSelected();
047        if (selection.isEmpty()) {
048            showEmptySelectionWarning();
049            return;
050        }
051
052        copy(getLayerManager().getActiveDataLayer(), selection);
053    }
054
055    /**
056     * Copies the given primitive ids to the clipboard. The output by this function
057     * looks similar to: node 1089302677,node 1089303458,way 93793372
058     * @param source The OSM data layer source
059     * @param primitives The OSM primitives to copy
060     */
061    public static void copy(OsmDataLayer source, Collection<OsmPrimitive> primitives) {
062        // copy ids to the clipboard
063        ClipboardUtils.copy(new PrimitiveTransferable(PrimitiveTransferData.getDataWithReferences(primitives), source));
064    }
065
066    @Override
067    protected void updateEnabledState() {
068        updateEnabledStateOnCurrentSelection(true);
069    }
070
071    @Override
072    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
073        setEnabled(!Utils.isEmpty(selection));
074    }
075
076    protected void showEmptySelectionWarning() {
077        JOptionPane.showMessageDialog(
078                MainApplication.getMainFrame(),
079                tr("Please select something to copy."),
080                tr("Information"),
081                JOptionPane.INFORMATION_MESSAGE
082        );
083    }
084}