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