/******************************************************************************* | |
* <copyright> | |
* | |
* Copyright (c) 2013, 2013 SAP AG. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* SAP AG - initial API, implementation and documentation | |
* | |
* </copyright> | |
* | |
*******************************************************************************/ | |
package org.eclipse.fmc.blockdiagram.editor.clipboard; | |
import java.awt.Graphics2D; | |
import java.awt.Toolkit; | |
import java.awt.datatransfer.Clipboard; | |
import java.awt.datatransfer.DataFlavor; | |
import java.awt.datatransfer.Transferable; | |
import java.awt.datatransfer.UnsupportedFlavorException; | |
import java.awt.image.BufferedImage; | |
import java.awt.image.DataBufferInt; | |
import java.io.File; | |
import java.io.IOException; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.util.List; | |
import javax.imageio.ImageIO; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.emf.common.CommonPlugin; | |
import org.eclipse.emf.common.util.URI; | |
import org.eclipse.fmc.blockdiagram.editor.Activator; | |
import org.eclipse.fmc.blockdiagram.editor.BlockDiagramEditor; | |
import org.eclipse.graphiti.ui.editor.DiagramEditorInput; | |
import org.eclipse.graphiti.ui.internal.GraphitiUIPlugin; | |
import org.eclipse.jface.resource.ImageDescriptor; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.graphics.Image; | |
import org.eclipse.swt.graphics.ImageData; | |
import org.eclipse.swt.graphics.ImageLoader; | |
import org.eclipse.swt.graphics.PaletteData; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.ui.statushandlers.StatusManager; | |
/** | |
* This class is the main entry point for pasting from the clipboard. | |
* | |
* @author Benjamin Schmeling | |
* | |
*/ | |
@SuppressWarnings("restriction") | |
public class PasteFromClipboard { | |
private static final String IMG_TYPE = ".png"; | |
/** | |
* Folder where the images will be saved to. | |
*/ | |
private static final String PASTED_IMAGES_FOLDER = ".images/"; | |
private static final String CLIP_NAME = "clip"; | |
private static final String IMAGE_PREFIX = "org.eclipse.fmc."; | |
/** | |
* Retrieves image from the clipboard and writes it to the disk to | |
* PASTED_IMAGES_FOLDER. Creates a imageId and registers it for the | |
* ImageProvider of the diagram. | |
* | |
* @param editor | |
* The diagram editor. | |
* | |
* @return Returns the imageId as String. | |
*/ | |
public static String pasteImagesFromClipboard(BlockDiagramEditor editor) { | |
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); | |
String nextImageName = getNextImageName(editor); | |
if (clipboard.getAvailableDataFlavors().length == 0) | |
return null; | |
DataFlavor dataFlavor = clipboard.getAvailableDataFlavors()[0]; | |
try { | |
Transferable contents = clipboard.getContents(dataFlavor); | |
Object transferData = contents.getTransferData(contents | |
.getTransferDataFlavors()[0]); | |
if (transferData instanceof BufferedImage) { | |
BufferedImage img = (BufferedImage) transferData; | |
writeImageToDisk(editor, | |
transformToSWTImage(Display.getDefault(), img)); | |
return IMAGE_PREFIX + nextImageName; | |
} else if (transferData instanceof List) { | |
List<?> files = (List<?>) transferData; | |
for (Object f : files) { | |
if (f instanceof File) { | |
BufferedImage img = ImageIO.read((File) f); | |
writeImageToDisk(editor, | |
transformToSWTImage(Display.getDefault(), img)); | |
return IMAGE_PREFIX + nextImageName; | |
} | |
} | |
} | |
} catch (IOException e) { | |
StatusManager.getManager().handle( | |
new Status(Status.ERROR, Activator.PLUGIN_ID, | |
"Error while writing copied image to disk", e)); | |
} catch (UnsupportedFlavorException e) { | |
StatusManager.getManager().handle( | |
new Status(Status.ERROR, Activator.PLUGIN_ID, | |
"Error while pasting from clipboard", e)); | |
} | |
return null; | |
} | |
/** | |
* Writes the image to the image folder. | |
* | |
* @param editor | |
* The diagram editor. | |
* @param img | |
* The image to be written to the disk. | |
*/ | |
private static void writeImageToDisk(BlockDiagramEditor editor, Image img) { | |
ImageLoader loader = new ImageLoader(); | |
loader.data = new ImageData[] { img.getImageData() }; | |
String imageName = getNextImageName(editor); | |
String imageNameWithEnding = imageName + IMG_TYPE; | |
String absoluteImagePath = getImageFolder(editor).toFileString() + "\\" | |
+ imageNameWithEnding; | |
loader.save(absoluteImagePath, SWT.IMAGE_PNG); | |
GraphitiUIPlugin.getDefault().getImageRegistry() | |
.put(IMAGE_PREFIX + imageName, img); | |
} | |
/** | |
* Transforms an AWT Image into an SWT Image. | |
* | |
* @param display | |
* The SWT Display. | |
* @param awtImage | |
* The AWT Image to be transformed. | |
* @return The SWT Image that has been created. | |
* @throws Exception | |
*/ | |
private static Image transformToSWTImage(Display display, | |
java.awt.Image awtImage) { | |
int width = awtImage.getWidth(null); | |
int height = awtImage.getHeight(null); | |
BufferedImage bufferedImage = new BufferedImage(width, height, | |
BufferedImage.TYPE_INT_RGB); | |
Graphics2D g2d = bufferedImage.createGraphics(); | |
g2d.drawImage(awtImage, 0, 0, null); | |
g2d.dispose(); | |
int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()) | |
.getData(); | |
ImageData imageData = new ImageData(width, height, 24, new PaletteData( | |
0xFF0000, 0x00FF00, 0x0000FF)); | |
imageData.setPixels(0, 0, data.length, data, 0); | |
Image swtImage = new Image(display, imageData); | |
return swtImage; | |
} | |
/** | |
* Returns the next available image name starting with CLIP_NAME + 1. | |
* | |
* @param editor | |
* The diagram editor. | |
* @return | |
*/ | |
private static String getNextImageName(BlockDiagramEditor editor) { | |
File[] files = loadClipFiles(editor); | |
int max = -1; | |
for (File file : files) { | |
String name = file.getName().split("\\.")[0]; | |
Integer num = Integer.valueOf(name.replace(CLIP_NAME, "")); | |
if (num > max) | |
max = num; | |
} | |
return CLIP_NAME + (max + 1); | |
} | |
/** | |
* Creates the image folder if it does not already exist. Returns the | |
* already pasted files which have already been written to the disk. | |
* | |
* @param editor | |
* The diagram editor. | |
* @return Array of image files stored to the image folder. | |
*/ | |
private static File[] loadClipFiles(BlockDiagramEditor editor) { | |
URI resolvedImagesURI = getImageFolder(editor); | |
File f = new File(resolvedImagesURI.toFileString()); | |
if (!f.exists()) { | |
if (!f.mkdir()) | |
throw new IllegalStateException("Cannot create image folder: " | |
+ f.getAbsolutePath()); | |
} | |
File[] files = f.listFiles(); | |
if (files == null) | |
files = new File[] {}; | |
return files; | |
} | |
/** | |
* Registers all images that have been pasted to the image provider of the | |
* editor. | |
* | |
* @param editor | |
* The diagram editor. | |
* @throws MalformedURLException | |
*/ | |
public static void registerClipImages(BlockDiagramEditor editor) | |
throws MalformedURLException { | |
for (File file : loadClipFiles(editor)) { | |
ImageDescriptor descriptor = ImageDescriptor.createFromURL(new URL( | |
"file:///" + file.getAbsolutePath())); | |
if (GraphitiUIPlugin.getDefault().getImageRegistry() | |
.get(IMAGE_PREFIX + file.getName().replace(IMG_TYPE, "")) == null) | |
GraphitiUIPlugin | |
.getDefault() | |
.getImageRegistry() | |
.put(IMAGE_PREFIX | |
+ file.getName().replace(IMG_TYPE, ""), | |
descriptor); | |
} | |
} | |
/** | |
* Returns the URI to the folder containing the image files. | |
* | |
* @param editor | |
* The diagram editor. | |
* @return URI to the folder images are pasted and written to. | |
*/ | |
private static URI getImageFolder(BlockDiagramEditor editor) { | |
DiagramEditorInput input = (DiagramEditorInput) editor.getEditorInput(); | |
String projectName = URI.createURI(input.getUriString()).segment(1); | |
URI projectURI = URI.createPlatformResourceURI(projectName, true); | |
URI imagesURI = URI.createURI(projectURI.toString() + "/" | |
+ PASTED_IMAGES_FOLDER); | |
URI resolvedImagesURI = CommonPlugin.resolve(imagesURI); | |
return resolvedImagesURI; | |
} | |
} |