001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.datatransfer; 003 004import java.awt.datatransfer.DataFlavor; 005import java.awt.datatransfer.Transferable; 006import java.awt.datatransfer.UnsupportedFlavorException; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.List; 010 011import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 012import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 013import org.openstreetmap.josm.data.osm.PrimitiveData; 014import org.openstreetmap.josm.gui.datatransfer.data.OsmLayerTransferData; 015import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTagTransferData; 016import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData; 017import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData; 018import org.openstreetmap.josm.gui.layer.OsmDataLayer; 019 020/** 021 * Transferable objects for {@link PrimitiveTransferData} objects 022 * @since 9369 023 * @since 10604 Complete rework 024 */ 025public class PrimitiveTransferable implements Transferable { 026 027 /** 028 * The flavors that are available for normal primitives. 029 */ 030 private static final List<DataFlavor> PRIMITIVE_FLAVORS = Arrays.asList(PrimitiveTransferData.DATA_FLAVOR, 031 TagTransferData.FLAVOR, DataFlavor.stringFlavor); 032 private final PrimitiveTransferData primitives; 033 private final OsmDataLayer sourceLayer; 034 035 /** 036 * Constructs a new {@code PrimitiveTransferable}. 037 * @param primitives collection of OSM primitives 038 */ 039 public PrimitiveTransferable(PrimitiveTransferData primitives) { 040 this(primitives, null); 041 } 042 043 /** 044 * Constructs a new {@code PrimitiveTransferable}. 045 * @param primitives collection of OSM primitives 046 * @param sourceLayer The layer the primitives are copied from 047 */ 048 public PrimitiveTransferable(PrimitiveTransferData primitives, OsmDataLayer sourceLayer) { 049 this.primitives = primitives; 050 this.sourceLayer = sourceLayer; 051 } 052 053 @Override 054 public DataFlavor[] getTransferDataFlavors() { 055 ArrayList<DataFlavor> flavors = new ArrayList<>(PRIMITIVE_FLAVORS); 056 if (sourceLayer != null) { 057 flavors.addAll(OsmLayerTransferData.FLAVORS); 058 } 059 return flavors.toArray(new DataFlavor[0]); 060 } 061 062 @Override 063 public boolean isDataFlavorSupported(DataFlavor flavor) { 064 DataFlavor[] flavors = getTransferDataFlavors(); 065 return Arrays.stream(flavors) 066 .anyMatch(flavor::equals); 067 } 068 069 @Override 070 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 071 if (DataFlavor.stringFlavor.equals(flavor)) { 072 return getStringData(); 073 } else if (PrimitiveTransferData.DATA_FLAVOR.equals(flavor)) { 074 return primitives; 075 } else if (PrimitiveTagTransferData.FLAVOR.equals(flavor)) { 076 return new PrimitiveTagTransferData(primitives); 077 } else if (TagTransferData.FLAVOR.equals(flavor)) { 078 return new TagTransferData(primitives.getDirectlyAdded()); 079 } else if (sourceLayer != null && OsmLayerTransferData.FLAVORS.contains(flavor)) { 080 return new OsmLayerTransferData(null, sourceLayer); 081 } else { 082 throw new UnsupportedFlavorException(flavor); 083 } 084 } 085 086 protected String getStringData() { 087 final StringBuilder sb = new StringBuilder(); 088 for (PrimitiveData primitive : primitives.getDirectlyAdded()) { 089 if (sb.length() > 0) { 090 sb.append('\n'); 091 } 092 sb.append(OsmPrimitiveType.from(primitive).getAPIName()).append(' ').append(primitive.getId()); 093 } 094 return DefaultNameFormatter.removeBiDiCharacters(sb.toString()); 095 } 096}