blob: ed233597011a92f0d73cee9e01705adcff7256a5 [file] [log] [blame]
/*******************************************************************************
* <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;
}
}