/*******************************************************************************
* Copyright (c) 2007, 2008 Spring IDE Developers
* 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:
* Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.webflow.ui.graph.actions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.ui.actions.WorkbenchPartAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.springframework.ide.eclipse.core.SpringCoreUtils;
import org.springframework.ide.eclipse.webflow.core.model.IWebflowConfig;
import org.springframework.ide.eclipse.webflow.ui.graph.Activator;
import org.springframework.ide.eclipse.webflow.ui.graph.WebflowEditor;
import org.springframework.ide.eclipse.webflow.ui.graph.WebflowEditorInput;
import org.springframework.ide.eclipse.webflow.ui.graph.WebflowImages;
/**
* {@link WorkbenchPartAction} that exports the current {@link IWebflowConfig}to an image file.
* @author Christian Dupuis
* @since 2.0
*/
public class ExportAction extends WorkbenchPartAction {
public static final String ID = "Export_action";
private WebflowEditor editor;
public ExportAction(WebflowEditor part) {
super(part);
this.editor = part;
setText("Export");
setId(ID);
setToolTipText("Exports the web flow to an image");
setImageDescriptor(WebflowImages.DESC_OBJS_EXPORT_ENABLED);
setDisabledImageDescriptor(WebflowImages.DESC_OBJS_EXPORT_DISABLED);
}
public void run() {
SaveAsDialog dialog = new SaveAsDialog(getWorkbenchPart().getSite()
.getShell());
IFile editorFile = ((WebflowEditorInput) this.editor.getEditorInput())
.getFile();
String fileName = editorFile.getName();
fileName = fileName.substring(0, fileName.lastIndexOf("."));
dialog.setTitle("Export to image");
dialog.setOriginalFile(editorFile);
dialog.create();
dialog.setMessage("Specify a name and location for the image. Either enter .png, .jpg or .bmp extension.");
dialog.open();
IPath path = dialog.getResult();
if (path != null) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IFile file = workspace.getRoot().getFile(path);
String ext = file.getFileExtension();
if (ext == null
|| ext.length() == 0
|| !(ext.equalsIgnoreCase("jpg")
|| ext.equalsIgnoreCase("jpeg")
|| ext.equalsIgnoreCase("bmp") || ext
.equalsIgnoreCase("png"))) {
ErrorDialog
.openError(
getWorkbenchPart().getSite().getShell(),
"Problem",
"Please specify one extension from the following options .png, .jpg or .bmp",
Activator.createErrorStatus("error", null));
}
else if (ext.equalsIgnoreCase("PNG")
&& !SpringCoreUtils.isEclipseSameOrNewer(3, 3)) {
ErrorDialog
.openError(
getWorkbenchPart().getSite().getShell(),
"Problem",
"Exporting to PNG format is only supported on Eclipse 3.3 or newer",
Activator.createErrorStatus("error", null));
}
else {
if ("PNG".equalsIgnoreCase(ext)) {
saveImage(file, SWT.IMAGE_PNG);
}
else if ("JPG".equalsIgnoreCase(ext)
|| "JPEG".equalsIgnoreCase(ext)) {
saveImage(file, SWT.IMAGE_JPEG);
}
else if ("BMP".equalsIgnoreCase(ext)) {
saveImage(file, SWT.IMAGE_BMP);
}
}
}
}
/**
* Saves an encoded image from this viewer.
*
* @param file
* @param format one of SWT.IMAGE_BMP, SWT.IMAGE_BMP_RLE, SWT.IMAGE_GIF
* SWT.IMAGE_ICO, SWT.IMAGE_JPEG or SWT.IMAGE_PNG
*
* @return the bytes of an encoded image for the specified viewer
*/
public void saveImage(final IFile file, final int format) {
WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
public void execute(final IProgressMonitor monitor)
throws CoreException {
try {
if (file.exists()) {
file.setContents(new ByteArrayInputStream(
createImage(format)), true, false, monitor);
}
else {
file.create(new ByteArrayInputStream(
createImage(format)), true, monitor);
}
}
catch (CoreException e) {
ErrorDialog.openError(getWorkbenchPart().getSite()
.getShell(), "Error",
"Error during processing of export", e.getStatus());
}
}
};
try {
Shell shell = getWorkbenchPart().getSite().getWorkbenchWindow()
.getShell();
new ProgressMonitorDialog(shell).run(false, true, op);
}
catch (InvocationTargetException e) {
Activator.log(e);
}
catch (InterruptedException e) {
}
}
protected boolean calculateEnabled() {
return true;
}
/**
* Returns the bytes of an encoded image from this viewer.
*
* @param format one of SWT.IMAGE_BMP, SWT.IMAGE_BMP_RLE, SWT.IMAGE_GIF
* SWT.IMAGE_ICO, SWT.IMAGE_JPEG or SWT.IMAGE_PNG
*
* @return the bytes of an encoded image for the specified viewer
*/
public byte[] createImage(int format) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
Device device = this.editor.getGraphViewer().getControl().getDisplay();
LayerManager lm = (LayerManager) this.editor.getGraphViewer()
.getEditPartRegistry().get(LayerManager.ID);
IFigure figure = lm.getLayer(LayerConstants.PRINTABLE_LAYERS);
Rectangle r = figure.getClientArea();
Image image = null;
GC gc = null;
Graphics g = null;
try {
image = new Image(device, r.width, r.height);
gc = new GC(image);
g = new SWTGraphics(gc);
g.translate(r.x * -1, r.y * -1);
figure.paint(g);
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { image.getImageData() };
imageLoader.save(result, format);
}
finally {
if (g != null) {
g.dispose();
}
if (gc != null) {
gc.dispose();
}
if (image != null) {
image.dispose();
}
}
return result.toByteArray();
}
}