/* * GeoClipboard.java * * Created on March 20, 2007, 10:32 AM * */ package ika.geo.clipboard; import ika.geo.GeoSet; import ika.geoexport.*; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.SystemFlavorMap; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * * @author Bernhard Jenny, Institute of Cartography, ETH Zurich */ public class GeoTransferable implements Transferable, ClipboardOwner { private static DataFlavor DXFFLAVOR; private static DataFlavor PDFFLAVOR; private static DataFlavor AIFLAVOR; private static DataFlavor WMFFLAVOR; private static DataFlavor GEOFLAVOR; static { try { PDFFLAVOR = new DataFlavor("application/pdf"); DXFFLAVOR = new DataFlavor("image/vnd.dxf"); AIFLAVOR = new DataFlavor("application/postscript"); SystemFlavorMap flavorMap = (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); flavorMap.addUnencodedNativeForFlavor(AIFLAVOR, "'AICB' (CorePasteboardFlavorType 0x41494342)"); WMFFLAVOR = new DataFlavor("image/x-wmf"); GEOFLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=ika.geo.GeoSet"); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } } /** * The supported flavors in order of preference. * Only PDF seems to work with Illustrator. */ private DataFlavor[] transferDataFlavors = new DataFlavor[] { //WMFFLAVOR, PDFFLAVOR, //DXFFLAVOR, //AIFLAVOR, DataFlavor.stringFlavor, GEOFLAVOR }; private GeoSet geoSet; public GeoTransferable(GeoSet geoSet) { this.geoSet = geoSet; } /** * Returns the supported flavors of our implementation */ public DataFlavor[] getTransferDataFlavors() { return transferDataFlavors; } /** * Returns true if flavor is supported. */ public boolean isDataFlavorSupported(DataFlavor flavor) { for (int i = 0; i < this.transferDataFlavors.length; i++) { if (this.transferDataFlavors[i].isMimeTypeEqual(flavor)) return true; } return false; } /** * Returns an object in the requested data flavor. */ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException,IOException { System.out.println("DataFlavor requested: " + flavor.getMimeType()); if (DataFlavor.stringFlavor.equals(flavor)) { UngenerateExporter exporter = new UngenerateExporter(); ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); exporter.export(this.geoSet, outputStream); return outputStream.toString(); } else if (DXFFLAVOR.equals(flavor)) { return this.exportToFileInputStream(new DXFExporter()); } else if (PDFFLAVOR.equals(flavor)) { GeoSetExporter exporter = null; try { Class pathClass = Class.forName("ika.geoexport.PDFExporter"); Constructor con = pathClass.getConstructor(new Class[]{}); exporter = (GeoSetExporter) con.newInstance(new Object[] {}); } catch (Exception ex) { ex.printStackTrace(); throw new IOException(ex.getMessage()); } return this.exportToFileInputStream(exporter); } else if (AIFLAVOR.equals(flavor)) { return this.exportToFileInputStream(new IllustratorExporter()); } else if (WMFFLAVOR.equals(flavor)) { return this.exportToFileInputStream(new WMFExporter()); } else if (GEOFLAVOR.equals(flavor)) { return this.geoSet; } else { throw new UnsupportedFlavorException(flavor); } } private FileInputStream exportToFileInputStream(GeoSetExporter exporter) throws IOException { String ext = exporter.getFileExtension(); java.io.File file = java.io.File.createTempFile("clipboard", "." + ext); // delete this file when the virtual machine stops file.deleteOnExit(); java.io.FileOutputStream outputStream = new java.io.FileOutputStream(file); try { exporter.export(this.geoSet, outputStream); } finally { outputStream.close(); } java.io.FileInputStream in = new java.io.FileInputStream(file); return in; } /** * This object is no longer the owner of the clipboard content. Release the * private GeoSet, since it will not be used any longer. */ public void lostOwnership(Clipboard clipboard, Transferable contents) { //this.geoSet = null; } /** * Put the passed GeoSet onto the system clipboard. * The programmer must make sure that the passed GeoObjects are not altered * after being put into the clipboard. Cloning the referenced objects before * storing them in the clipboard is the solution. * @param geoSet The GeoSet to share with other applications. */ public static void storeInSystemClipboard(GeoSet geoSet) { GeoTransferable geoTrans = new GeoTransferable(geoSet); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents(geoTrans, geoTrans); } public static GeoSet retreiveSystemClipboardCopy() { try { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable trans = clipboard.getContents(null); if (trans != null && trans.isDataFlavorSupported(GEOFLAVOR)) { GeoSet geoSet = (GeoSet)trans.getTransferData(GEOFLAVOR); if (geoSet != null) return (GeoSet)geoSet.clone(); } } catch (Exception e) { e.printStackTrace(); } return null; } public static boolean isClipboardFull() { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); return clipboard.isDataFlavorAvailable(GEOFLAVOR); } }