001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.layer;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.util.ArrayList;
008import java.util.List;
009
010import javax.swing.AbstractAction;
011
012import org.openstreetmap.josm.Main;
013import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
014import org.openstreetmap.josm.gui.help.HelpUtil;
015import org.openstreetmap.josm.gui.layer.Layer;
016import org.openstreetmap.josm.gui.layer.OsmDataLayer;
017import org.openstreetmap.josm.tools.CheckParameterUtil;
018import org.openstreetmap.josm.tools.ImageProvider;
019
020/**
021 * The action to merge the currently selected layer into another layer.
022 */
023public final class DuplicateAction extends AbstractAction implements IEnabledStateUpdating {
024    private transient Layer layer;
025    private final LayerListModel model;
026
027    /**
028     * Constructs a new {@code DuplicateAction}.
029     * @param layer the layer
030     * @param model layer list model
031     * @throws IllegalArgumentException if {@code layer} is null
032     */
033    public DuplicateAction(Layer layer, LayerListModel model) {
034        this(model);
035        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
036        this.layer = layer;
037        updateEnabledState();
038    }
039
040    /**
041     * Constructs a new {@code DuplicateAction}.
042     * @param model layer list model
043     */
044    public DuplicateAction(LayerListModel model) {
045        this.model = model;
046        putValue(NAME, tr("Duplicate"));
047        putValue(SMALL_ICON, ImageProvider.get("dialogs", "duplicatelayer"));
048        putValue(SHORT_DESCRIPTION, tr("Duplicate this layer"));
049        putValue("help", HelpUtil.ht("/Dialog/LayerList#DuplicateLayer"));
050        updateEnabledState();
051    }
052
053    private void duplicate(Layer layer) {
054        if (!Main.isDisplayingMapView())
055            return;
056
057        List<String> layerNames = new ArrayList<>();
058        for (Layer l: Main.map.mapView.getAllLayers()) {
059            layerNames.add(l.getName());
060        }
061        if (layer instanceof OsmDataLayer) {
062            OsmDataLayer oldLayer = (OsmDataLayer) layer;
063            // Translators: "Copy of {layer name}"
064            String newName = tr("Copy of {0}", oldLayer.getName());
065            int i = 2;
066            while (layerNames.contains(newName)) {
067                // Translators: "Copy {number} of {layer name}"
068                newName = tr("Copy {1} of {0}", oldLayer.getName(), i);
069                i++;
070            }
071            Main.main.addLayer(new OsmDataLayer(oldLayer.data.clone(), newName, null));
072        }
073    }
074
075    @Override
076    public void actionPerformed(ActionEvent e) {
077        if (layer != null) {
078            duplicate(layer);
079        } else {
080            duplicate(model.getSelectedLayers().get(0));
081        }
082    }
083
084    @Override
085    public void updateEnabledState() {
086        if (layer == null) {
087            if (model.getSelectedLayers().size() == 1) {
088                setEnabled(model.getSelectedLayers().get(0) instanceof OsmDataLayer);
089            } else {
090                setEnabled(false);
091            }
092        } else {
093            setEnabled(layer instanceof OsmDataLayer);
094        }
095    }
096}