Ticket #12478: patch-ccp-primitives-copy-only-layers.patch

File patch-ccp-primitives-copy-only-layers.patch, 27.0 KB (added by michael2402, 9 years ago)
  • src/org/openstreetmap/josm/Main.java

    diff --git a/src/org/openstreetmap/josm/Main.java b/src/org/openstreetmap/josm/Main.java
    index 93ace13..ddfe403 100644
    a b import org.openstreetmap.josm.gui.MainPanel;  
    8484import org.openstreetmap.josm.gui.MapFrame;
    8585import org.openstreetmap.josm.gui.MapFrameListener;
    8686import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
     87import org.openstreetmap.josm.gui.datatransfer.data.OsmLayerTransferData;
    8788import org.openstreetmap.josm.gui.help.HelpUtil;
    8889import org.openstreetmap.josm.gui.io.SaveLayersDialog;
    8990import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
  • new file src/org/openstreetmap/josm/gui/datatransfer/LayerTransferable.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/LayerTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/LayerTransferable.java
    new file mode 100644
    index 0000000..c445a0c
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.awt.datatransfer.Transferable;
     6import java.awt.datatransfer.UnsupportedFlavorException;
     7import java.io.IOException;
     8import java.util.ArrayList;
     9import java.util.Collections;
     10import java.util.List;
     11
     12import org.openstreetmap.josm.gui.layer.Layer;
     13import org.openstreetmap.josm.gui.layer.LayerManager;
     14
     15/**
     16 * This class allows to transfer multiple layers in the current JOSM instance.
     17 * @author Michael Zangl
     18 * @since xxx
     19 */
     20public class LayerTransferable implements Transferable {
     21
     22    /**
     23     * A wrapper for a collection of {@link Layer}.
     24     */
     25    public static class Data {
     26        private final LayerManager manager;
     27        private final List<Layer> layers;
     28
     29        /**
     30         * Create a new data object
     31         * @param manager The layer manager the layers are from.
     32         * @param layers The layers.
     33         */
     34        public Data(LayerManager manager, List<Layer> layers) {
     35            super();
     36            this.manager = manager;
     37            this.layers = new ArrayList<>(layers);
     38        }
     39
     40        /**
     41         * Gets the layer manager the layers belong to.
     42         * @return The layer manager. It may be <code>null</code>
     43         */
     44        public LayerManager getManager() {
     45            return manager;
     46        }
     47
     48        /**
     49         * Gets the list of layers that were copied.
     50         * @return The layers.
     51         */
     52        public List<Layer> getLayers() {
     53            return Collections.unmodifiableList(layers);
     54        }
     55
     56        @Override
     57        public String toString() {
     58            return "Data [layers=" + layers + "]";
     59        }
     60    }
     61
     62    /**
     63     * Data flavor for {@link Layer}s which are wrapped in {@link Data}.
     64     */
     65    public static final DataFlavor LAYER_DATA = new DataFlavor(
     66            DataFlavor.javaJVMLocalObjectMimeType + ";class=" + Data.class.getName(), "Layers");
     67
     68    private final Data data;
     69
     70    /**
     71     * Create a new data object
     72     * @param manager The layer manager the layers are from.
     73     * @param layers The layers.
     74     */
     75    public LayerTransferable(LayerManager manager, List<Layer> layers) {
     76        this.data = new Data(manager, layers);
     77    }
     78
     79    @Override
     80    public DataFlavor[] getTransferDataFlavors() {
     81        return new DataFlavor[] { LAYER_DATA };
     82    }
     83
     84    @Override
     85    public boolean isDataFlavorSupported(DataFlavor flavor) {
     86        return LAYER_DATA.equals(flavor);
     87    }
     88
     89    @Override
     90    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
     91        if (!isDataFlavorSupported(flavor)) {
     92            throw new UnsupportedFlavorException(flavor);
     93        } else {
     94            return data;
     95        }
     96    }
     97}
  • src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java
    index 21e302a..9503818 100644
    a b import java.util.List;  
    1010
    1111import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1212import org.openstreetmap.josm.data.osm.PrimitiveData;
     13import org.openstreetmap.josm.gui.datatransfer.data.OsmLayerTransferData;
    1314import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
    1415import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
    1516import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    public class PrimitiveTransferable implements Transferable {  
    5051    @Override
    5152    public DataFlavor[] getTransferDataFlavors() {
    5253        ArrayList<DataFlavor> flavors = new ArrayList<>(PRIMITIVE_FLAVORS);
     54        if (sourceLayer != null) {
     55            flavors.addAll(OsmLayerTransferData.FLAVORS);
     56        }
    5357        return flavors.toArray(new DataFlavor[flavors.size()]);
    5458    }
    5559
    public class PrimitiveTransferable implements Transferable {  
    7276            return primitives;
    7377        } else if (TagTransferData.FLAVOR.equals(flavor)) {
    7478            return new TagTransferData(primitives.getDirectlyAdded());
     79        } else if (sourceLayer != null && OsmLayerTransferData.FLAVORS.contains(flavor)) {
     80            return new OsmLayerTransferData(null, sourceLayer);
    7581        } else {
    7682            throw new UnsupportedFlavorException(flavor);
    7783        }
  • new file src/org/openstreetmap/josm/gui/datatransfer/SingleLayerTransferable.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/SingleLayerTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/SingleLayerTransferable.java
    new file mode 100644
    index 0000000..b9aed6a
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.awt.datatransfer.Transferable;
     6import java.awt.datatransfer.UnsupportedFlavorException;
     7import java.io.IOException;
     8import java.util.List;
     9
     10import org.openstreetmap.josm.gui.datatransfer.data.LayerTransferData;
     11import org.openstreetmap.josm.gui.datatransfer.data.OsmLayerTransferData;
     12import org.openstreetmap.josm.gui.layer.Layer;
     13import org.openstreetmap.josm.gui.layer.LayerManager;
     14import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     15
     16/**
     17 * This class handles the transfer of a layer inside this JOSM instance.
     18 * @author Michael Zangl
     19 * @since xxx
     20 */
     21public class SingleLayerTransferable implements Transferable {
     22    private final LayerTransferData data;
     23
     24    /**
     25     * Create a new {@link SingleLayerTransferable}
     26     * @param manager The manager the layer belongs to
     27     * @param layer The layer that is transfered.
     28     */
     29    public SingleLayerTransferable(LayerManager manager, Layer layer) {
     30        if (layer instanceof OsmDataLayer) {
     31            this.data = new OsmLayerTransferData(manager, (OsmDataLayer) layer);
     32        } else {
     33            this.data = new LayerTransferData(manager, layer);
     34        }
     35    }
     36
     37    @Override
     38    public DataFlavor[] getTransferDataFlavors() {
     39        List<DataFlavor> flavors = data.getSupportedFlavors();
     40        return flavors.toArray(new DataFlavor[flavors.size()]);
     41    }
     42
     43    @Override
     44    public boolean isDataFlavorSupported(DataFlavor flavor) {
     45        return data.getSupportedFlavors().contains(flavor);
     46    }
     47
     48    @Override
     49    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
     50        if (isDataFlavorSupported(flavor)) {
     51            return data;
     52        } else {
     53            throw new UnsupportedFlavorException(flavor);
     54        }
     55    }
     56}
  • new file src/org/openstreetmap/josm/gui/datatransfer/data/LayerTransferData.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/data/LayerTransferData.java b/src/org/openstreetmap/josm/gui/datatransfer/data/LayerTransferData.java
    new file mode 100644
    index 0000000..e982911
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer.data;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.util.Arrays;
     6import java.util.Collections;
     7import java.util.List;
     8
     9import org.openstreetmap.josm.gui.datatransfer.LayerTransferable;
     10import org.openstreetmap.josm.gui.layer.Layer;
     11import org.openstreetmap.josm.gui.layer.LayerManager;
     12
     13/**
     14 * This transferable implements a layer transfer.
     15 * @author Michael Zangl
     16 * @since xxx
     17 */
     18public class LayerTransferData extends LayerTransferable.Data {
     19    /**
     20     * This is a data flavor for all layer types
     21     */
     22    public static final DataFlavor FLAVOR = new DataFlavor(
     23            DataFlavor.javaJVMLocalObjectMimeType + ";class=" + LayerTransferData.class.getName(), "Layer");
     24
     25    /**
     26     * The flavors that are supported by this data type.
     27     */
     28    private static final List<DataFlavor> FLAVORS = Arrays.asList(LayerTransferData.FLAVOR, LayerTransferable.LAYER_DATA);
     29
     30    private final Layer layer;
     31
     32    /**
     33     * Create a new transfer data for the given layer
     34     * @param layerManager The layer manager that the layer is moved in. May be <code>null</code>
     35     * @param layer The layer
     36     */
     37    public LayerTransferData(LayerManager layerManager, Layer layer) {
     38        super(layerManager, Collections.singletonList(layer));
     39        this.layer = layer;
     40    }
     41
     42    /**
     43     * Gets the layer to be transfered.
     44     * @return The layer
     45     */
     46    public Layer getLayer() {
     47        return layer;
     48    }
     49
     50    /**
     51     * Gets a list of flavors supported by this data.
     52     * @return The flavors.
     53     */
     54    public List<DataFlavor> getSupportedFlavors() {
     55        return Collections.unmodifiableList(FLAVORS);
     56    }
     57
     58    @Override
     59    public String toString() {
     60        return "LayerTransferData [layer=" + layer + "]";
     61    }
     62}
  • new file src/org/openstreetmap/josm/gui/datatransfer/data/OsmLayerTransferData.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/data/OsmLayerTransferData.java b/src/org/openstreetmap/josm/gui/datatransfer/data/OsmLayerTransferData.java
    new file mode 100644
    index 0000000..9cec879
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer.data;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.util.Arrays;
     6import java.util.Collections;
     7import java.util.List;
     8
     9import org.openstreetmap.josm.gui.datatransfer.LayerTransferable;
     10import org.openstreetmap.josm.gui.layer.LayerManager;
     11import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     12
     13/**
     14 * A special form of {@link LayerTransferData} that ensures you that the layer is an OSM data layer
     15 * @author Michael Zangl
     16 * @since xxx
     17 */
     18public class OsmLayerTransferData extends LayerTransferData {
     19
     20    /**
     21     * This is a data flavor specific for OSM data layers.
     22     * <p>
     23     * @see LayerTransferData#FLAVOR
     24     * @see #FLAVORS
     25     */
     26    public static final DataFlavor OSM_FLAVOR = new DataFlavor(
     27            DataFlavor.javaJVMLocalObjectMimeType + ";class=" + LayerTransferData.class.getName(), "Layer");
     28
     29    /**
     30     * The flavors that are supported by this data type.
     31     */
     32    public static final List<DataFlavor> FLAVORS = Collections
     33            .unmodifiableList(Arrays.asList(OSM_FLAVOR, LayerTransferData.FLAVOR, LayerTransferable.LAYER_DATA));
     34
     35    private final OsmDataLayer osmLayer;
     36
     37    /**
     38     * Create a new {@link OsmLayerTransferData} object
     39     * @param layerManager The layer manager
     40     * @param layer The layer that is moved.
     41     */
     42    public OsmLayerTransferData(LayerManager layerManager, OsmDataLayer layer) {
     43        super(layerManager, layer);
     44        osmLayer = layer;
     45    }
     46
     47    /**
     48     * Gets the OSM data layer.
     49     * @return The layer
     50     */
     51    public OsmDataLayer getOsmLayer() {
     52        return osmLayer;
     53    }
     54
     55    @Override
     56    public List<DataFlavor> getSupportedFlavors() {
     57        return FLAVORS;
     58    }
     59
     60    @Override
     61    public String toString() {
     62        return "OsmLayerTransferData [osmLayer=" + osmLayer + "]";
     63    }
     64}
  • src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java b/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
    index dadfdb3..643c277 100644
    a b import java.util.concurrent.CopyOnWriteArrayList;  
    2424import javax.swing.AbstractAction;
    2525import javax.swing.DefaultCellEditor;
    2626import javax.swing.DefaultListSelectionModel;
     27import javax.swing.DropMode;
    2728import javax.swing.ImageIcon;
    2829import javax.swing.JCheckBox;
    2930import javax.swing.JComponent;
    import org.openstreetmap.josm.gui.dialogs.layer.ActivateLayerAction;  
    5253import org.openstreetmap.josm.gui.dialogs.layer.DeleteLayerAction;
    5354import org.openstreetmap.josm.gui.dialogs.layer.DuplicateAction;
    5455import org.openstreetmap.josm.gui.dialogs.layer.IEnabledStateUpdating;
     56import org.openstreetmap.josm.gui.dialogs.layer.LayerListTransferHandler;
    5557import org.openstreetmap.josm.gui.dialogs.layer.LayerVisibilityAction;
    5658import org.openstreetmap.josm.gui.dialogs.layer.MergeAction;
    5759import org.openstreetmap.josm.gui.dialogs.layer.MoveDownAction;
    public class LayerListDialog extends ToggleDialog {  
    11041106
    11051107        @Override
    11061108        public void layerOrderChanged(LayerOrderChangeEvent e) {
    1107             // ignored for now, since only we change layer order.
     1109            fireTableDataChanged();
    11081110        }
    11091111
    11101112        /* ------------------------------------------------------------------------------ */
    public class LayerListDialog extends ToggleDialog {  
    11301132        LayerList(LayerListModel dataModel) {
    11311133            super(dataModel);
    11321134            dataModel.setLayerList(this);
     1135            setDragEnabled(true);
     1136            setDropMode(DropMode.INSERT_ROWS);
     1137            setTransferHandler(new LayerListTransferHandler());
    11331138        }
    11341139
    11351140        public void scrollToVisible(int row, int col) {
    public class LayerListDialog extends ToggleDialog {  
    11411146            rect.setLocation(rect.x - pt.x, rect.y - pt.y);
    11421147            viewport.scrollRectToVisible(rect);
    11431148        }
     1149
     1150        @Override
     1151        public LayerListModel getModel() {
     1152            return (LayerListModel) super.getModel();
     1153        }
    11441154    }
    11451155
    11461156    /**
  • src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java b/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java
    index 4adbefe..db55efa 100644
    a b package org.openstreetmap.josm.gui.dialogs.layer;  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.event.ActionEvent;
    7 import java.util.ArrayList;
    8 import java.util.List;
    97
    108import javax.swing.AbstractAction;
    119
    import org.openstreetmap.josm.tools.CheckParameterUtil;  
    1917import org.openstreetmap.josm.tools.ImageProvider;
    2018
    2119/**
    22  * The action to merge the currently selected layer into another layer.
     20 * The action to dupplicate the given selected layer into another layer.
    2321 */
    2422public final class DuplicateAction extends AbstractAction implements IEnabledStateUpdating {
    2523    private transient Layer layer;
    public final class DuplicateAction extends AbstractAction implements IEnabledSta  
    5149        updateEnabledState();
    5250    }
    5351
    54     private void duplicate(Layer layer) {
    55         if (!Main.isDisplayingMapView())
    56             return;
    57 
    58         List<String> layerNames = new ArrayList<>();
    59         for (Layer l: Main.getLayerManager().getLayers()) {
    60             layerNames.add(l.getName());
    61         }
     52    private static void duplicate(Layer layer) {
    6253        if (layer instanceof OsmDataLayer) {
     54            String newName = LayerListTransferHandler.suggestNewLayerName(layer.getName(), Main.getLayerManager().getLayers());
    6355            OsmDataLayer oldLayer = (OsmDataLayer) layer;
    64             // Translators: "Copy of {layer name}"
    65             String newName = tr("Copy of {0}", oldLayer.getName());
    66             int i = 2;
    67             while (layerNames.contains(newName)) {
    68                 // Translators: "Copy {number} of {layer name}"
    69                 newName = tr("Copy {1} of {0}", oldLayer.getName(), i);
    70                 i++;
    71             }
    7256            Main.getLayerManager().addLayer(new OsmDataLayer(new DataSet(oldLayer.data), newName, null));
    7357        }
    7458    }
  • new file src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java b/src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java
    new file mode 100644
    index 0000000..0e8255d
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.dialogs.layer;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.datatransfer.Transferable;
     7import java.awt.datatransfer.UnsupportedFlavorException;
     8import java.io.IOException;
     9import java.util.ArrayList;
     10import java.util.Collection;
     11import java.util.List;
     12
     13import javax.swing.JComponent;
     14import javax.swing.JTable;
     15import javax.swing.TransferHandler;
     16
     17import org.openstreetmap.josm.Main;
     18import org.openstreetmap.josm.data.osm.DataSet;
     19import org.openstreetmap.josm.gui.datatransfer.LayerTransferable;
     20import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
     21import org.openstreetmap.josm.gui.layer.Layer;
     22import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     23
     24/**
     25 * This class allows the user to transfer layers using drag+drop.
     26 * <p>
     27 * It supports copy (duplication) of layers, simple moves and linking layers to a new layer manager.
     28 *
     29 * @author Michael Zangl
     30 * @since xxx
     31 */
     32public class LayerListTransferHandler extends TransferHandler {
     33    @Override
     34    public int getSourceActions(JComponent c) {
     35        // we know that the source is a layer list, so don't check c.
     36        LayerListModel tableModel = (LayerListModel) ((JTable) c).getModel();
     37        if (tableModel.getSelectedLayers().isEmpty()) {
     38            return 0;
     39        }
     40        int actions = MOVE;
     41        if (onlyDataLayersSelected(tableModel)) {
     42            actions |= COPY;
     43        }
     44        return actions /* soon: | LINK*/;
     45    }
     46
     47    private static boolean onlyDataLayersSelected(LayerListModel tableModel) {
     48        for (Layer l : tableModel.getSelectedLayers()) {
     49            if (!(l instanceof OsmDataLayer)) {
     50                return false;
     51            }
     52        }
     53        return true;
     54    }
     55
     56    @Override
     57    protected Transferable createTransferable(JComponent c) {
     58        LayerListModel tableModel = (LayerListModel) ((JTable) c).getModel();
     59        return new LayerTransferable(tableModel.getLayerManager(), tableModel.getSelectedLayers());
     60    }
     61
     62    @Override
     63    public boolean canImport(TransferSupport support) {
     64        if (support.isDrop()) {
     65            support.setShowDropLocation(true);
     66        }
     67
     68        if (!support.isDataFlavorSupported(LayerTransferable.LAYER_DATA)) {
     69            return false;
     70        }
     71
     72        if (support.getDropAction() == LINK) {
     73            // cannot link yet.
     74            return false;
     75        }
     76
     77        return true;
     78    }
     79
     80    @Override
     81    public boolean importData(TransferSupport support) {
     82        try {
     83            LayerListModel tableModel = (LayerListModel) ((JTable) support.getComponent()).getModel();
     84
     85            LayerTransferable.Data layers = ((LayerTransferable.Data) support.getTransferable()
     86                    .getTransferData(LayerTransferable.LAYER_DATA));
     87
     88            int dropLocation;
     89            if (support.isDrop()) {
     90                JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
     91                dropLocation = dl.getRow();
     92            } else {
     93                dropLocation = layers.getLayers().get(0).getDefaultLayerPosition().getPosition(layers.getManager());
     94            }
     95
     96            boolean isSameLayerManager = tableModel.getLayerManager() == layers.getManager();
     97
     98            if (support.getDropAction() == MOVE && isSameLayerManager) {
     99                for (Layer layer : layers.getLayers()) {
     100                    boolean wasBeforeInsert = layers.getManager().getLayers().indexOf(layer) <= dropLocation;
     101                    if (wasBeforeInsert) {
     102                        // need to move insertion point one down to preserve order
     103                        dropLocation--;
     104                    }
     105                    layers.getManager().moveLayer(layer, dropLocation);
     106                    dropLocation++;
     107                }
     108            } else {
     109                List<Layer> layersToUse = layers.getLayers();
     110                if (support.getDropAction() == COPY) {
     111                    layersToUse = createCopy(layersToUse, layers.getManager().getLayers());
     112                }
     113                for (Layer layer : layersToUse) {
     114                    layers.getManager().addLayer(layer);
     115                    layers.getManager().moveLayer(layer, dropLocation);
     116                    dropLocation++;
     117                }
     118            }
     119
     120            return true;
     121        } catch (UnsupportedFlavorException e) {
     122            Main.warn("Flavor not supported", e);
     123            return false;
     124        } catch (IOException e) {
     125            Main.warn("Error while pasting layer", e);
     126            return false;
     127        }
     128    }
     129
     130    private static List<Layer> createCopy(List<Layer> layersToUse, List<Layer> namesToAvoid) {
     131        Collection<String> layerNames = getNames(namesToAvoid);
     132        ArrayList<Layer> layers = new ArrayList<>();
     133        for (Layer layer : layersToUse) {
     134            if (layer instanceof OsmDataLayer) {
     135                String newName = suggestNewLayerName(layer.getName(), layerNames);
     136                OsmDataLayer newLayer = new OsmDataLayer(new DataSet(((OsmDataLayer) layer).data), newName, null);
     137                layers.add(newLayer);
     138                layerNames.add(newName);
     139            }
     140        }
     141        return layers;
     142    }
     143
     144    /**
     145     * Suggests a new name in the form "copy of name"
     146     * @param name The base name
     147     * @param namesToAvoid The list of layers to use to avoid dupplicate names.
     148     * @return The new name
     149     */
     150    public static String suggestNewLayerName(String name, List<Layer> namesToAvoid) {
     151        Collection<String> layerNames = getNames(namesToAvoid);
     152
     153        return suggestNewLayerName(name, layerNames);
     154    }
     155
     156    private static List<String> getNames(List<Layer> namesToAvoid) {
     157        List<String> layerNames = new ArrayList<>();
     158        for (Layer l: namesToAvoid) {
     159            layerNames.add(l.getName());
     160        }
     161        return layerNames;
     162    }
     163
     164    private static String suggestNewLayerName(String name, Collection<String> layerNames) {
     165        // Translators: "Copy of {layer name}"
     166        String newName = tr("Copy of {0}", name);
     167        int i = 2;
     168        while (layerNames.contains(newName)) {
     169            // Translators: "Copy {number} of {layer name}"
     170            newName = tr("Copy {1} of {0}", name, i);
     171            i++;
     172        }
     173        return newName;
     174    }
     175}
     176 No newline at end of file
  • new file test/unit/org/openstreetmap/josm/gui/datatransfer/LayerTransferableTest.java

    diff --git a/test/unit/org/openstreetmap/josm/gui/datatransfer/LayerTransferableTest.java b/test/unit/org/openstreetmap/josm/gui/datatransfer/LayerTransferableTest.java
    new file mode 100644
    index 0000000..a79ef49
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer;
     3
     4import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertFalse;
     6import static org.junit.Assert.assertSame;
     7import static org.junit.Assert.assertTrue;
     8
     9import java.awt.datatransfer.DataFlavor;
     10import java.awt.datatransfer.UnsupportedFlavorException;
     11import java.io.IOException;
     12import java.util.Arrays;
     13
     14import org.junit.Before;
     15import org.junit.Test;
     16import org.openstreetmap.josm.gui.datatransfer.LayerTransferable.Data;
     17import org.openstreetmap.josm.gui.layer.Layer;
     18import org.openstreetmap.josm.gui.layer.LayerManagerTest;
     19import org.openstreetmap.josm.gui.layer.LayerManagerTest.TestLayer;
     20import org.openstreetmap.josm.gui.layer.MainLayerManager;
     21
     22/**
     23 * Tests for {@link LayerTransferable}
     24 * @author Michael Zangl
     25 * @since xxx
     26 */
     27public class LayerTransferableTest {
     28    private TestLayer layer1;
     29    private TestLayer layer2;
     30    private MainLayerManager manager;
     31
     32    /**
     33     * Set up test data
     34     */
     35    @Before
     36    public void createTestData() {
     37        layer1 = new LayerManagerTest.TestLayer();
     38        layer2 = new LayerManagerTest.TestLayer();
     39        manager = new MainLayerManager();
     40        manager.addLayer(layer1);
     41        manager.addLayer(layer2);
     42    }
     43
     44    /**
     45     * Test {@link LayerTransferable.Data}
     46     */
     47    @Test
     48    public void testLayerData() {
     49        Data data = new Data(manager, Arrays.<Layer> asList(layer1, layer2));
     50
     51        // need to be identity
     52        assertSame(manager, data.getManager());
     53        assertSame(layer1, data.getLayers().get(0));
     54        assertSame(layer2, data.getLayers().get(1));
     55    }
     56
     57    /**
     58     * Test {@link LayerTransferable#isDataFlavorSupported(java.awt.datatransfer.DataFlavor)}
     59     * and {@link LayerTransferable#getTransferDataFlavors()}
     60     */
     61    @Test
     62    public void testSupportedDataFlavor() {
     63        LayerTransferable transferable = new LayerTransferable(manager, Arrays.<Layer> asList(layer1, layer2));
     64
     65        assertFalse(transferable.isDataFlavorSupported(DataFlavor.imageFlavor));
     66        assertTrue(transferable.isDataFlavorSupported(LayerTransferable.LAYER_DATA));
     67
     68        DataFlavor[] flavors = transferable.getTransferDataFlavors();
     69        assertEquals(1, flavors.length);
     70        assertEquals(LayerTransferable.LAYER_DATA, flavors[0]);
     71    }
     72
     73    /**
     74     * Test {@link LayerTransferable#getTransferData(DataFlavor)}
     75     * @throws IOException
     76     * @throws UnsupportedFlavorException
     77     */
     78    @Test
     79    public void testTransferData() throws UnsupportedFlavorException, IOException {
     80        LayerTransferable transferable = new LayerTransferable(manager, Arrays.<Layer> asList(layer1, layer2));
     81
     82        Object object = transferable.getTransferData(LayerTransferable.LAYER_DATA);
     83        assertTrue(object instanceof Data);
     84        Data data = (Data) object;
     85        assertSame(manager, data.getManager());
     86        assertSame(layer1, data.getLayers().get(0));
     87        assertSame(layer2, data.getLayers().get(1));
     88    }
     89
     90    /**
     91     * Test {@link LayerTransferable#getTransferData(DataFlavor)} for unsupported {@link DataFlavor}
     92     * @throws IOException
     93     * @throws UnsupportedFlavorException
     94     */
     95    @Test(expected = UnsupportedFlavorException.class)
     96    public void testTransferDataUnsupported() throws UnsupportedFlavorException, IOException {
     97        LayerTransferable transferable = new LayerTransferable(manager, Arrays.<Layer> asList(layer1, layer2));
     98
     99        transferable.getTransferData(DataFlavor.imageFlavor);
     100    }
     101}