Java tutorial
/****************************************************************************** * Copyright (c) 2006, 2009 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.diagram.ui.render.actions; import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.Request; import org.eclipse.gef.editparts.LayerManager; import org.eclipse.gmf.runtime.common.core.util.Log; import org.eclipse.gmf.runtime.common.core.util.Trace; import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction; import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.ISurfaceEditPart; import org.eclipse.gmf.runtime.diagram.ui.render.internal.DiagramUIRenderDebugOptions; import org.eclipse.gmf.runtime.diagram.ui.render.internal.DiagramUIRenderPlugin; import org.eclipse.gmf.runtime.diagram.ui.render.internal.DiagramUIRenderStatusCodes; import org.eclipse.gmf.runtime.diagram.ui.render.internal.dialogs.CopyToImageDialog; import org.eclipse.gmf.runtime.diagram.ui.render.internal.l10n.DiagramUIRenderMessages; import org.eclipse.gmf.runtime.diagram.ui.render.util.CopyToHTMLImageUtil; import org.eclipse.gmf.runtime.diagram.ui.render.util.CopyToImageUtil; import org.eclipse.gmf.runtime.diagram.ui.render.util.DiagramImageUtils; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWTError; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; /** * Action to copy the selected shapes in the diagram or the entire diagram to an * image file. * * @author Anthony Hunter, cmahoney */ public class CopyToImageAction extends DiagramAction { /** * the copy diagram to image file dialog used by the action. */ private CopyToImageDialog dialog = null; /** * Constructor for CopyToImageAction. * * @param page * the page of the workbench for the action */ public CopyToImageAction(IWorkbenchPage page) { super(page); } /** * Initialize with the correct text label, action id, and images. */ public void init() { super.init(); /* set the label for the action */ setText(DiagramUIRenderMessages.CopyToImageAction_Label); /* set the id */ setId(ActionIds.ACTION_COPY_TO_IMAGE); /* set the image */ ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); setHoverImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); setDisabledImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED)); } public void run() { IPath path = null; String fileName = null; if (getWorkbenchPart() instanceof IEditorPart) { IEditorPart editor = (IEditorPart) getWorkbenchPart(); // The editor's input may provide us with an IContainer where // we should store items related to it. IContainer container = (IContainer) editor.getEditorInput().getAdapter(IContainer.class); // If there is a container in the workspace and it exists then // we will use its path to store the image. if (container != null && container.exists()) { // The path has to be an absolute filesystem path for this // use case rather than just the path relative to the workspace // root. path = container.getLocation(); } // Otherwise, we will try to adapt the input to the IFile that // represents the place where the editor's input file resides. // We can extrapolate a destination path from this file. if (path == null) { IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class); // We can't necessarily assume that the editor input is a file. if (file != null) { path = file.getLocation().removeLastSegments(1); fileName = file.getLocation().removeFileExtension().lastSegment(); } } } dialog = new CopyToImageDialog(Display.getCurrent().getActiveShell(), path, fileName); runCopyToImageUI(dialog); } /** * Displays the dialog and performs <code>OutOfMemoryError</code> checking * * @param dialog the copy to image dialog */ private void runCopyToImageUI(CopyToImageDialog dialog) { if (dialog.open() == CopyToImageDialog.CANCEL) { return; } if (!overwriteExisting()) { return; } Trace.trace(DiagramUIRenderPlugin.getInstance(), "Copy Diagram to " + dialog.getDestination().toOSString() //$NON-NLS-1$ + " as " + dialog.getImageFormat().toString()); //$NON-NLS-1$ final MultiStatus status = new MultiStatus(DiagramUIRenderPlugin.getPluginId(), DiagramUIRenderStatusCodes.OK, DiagramUIRenderMessages.CopyToImageAction_Label, null); IRunnableWithProgress runnable = createRunnable(status); ProgressMonitorDialog progressMonitorDialog = new ProgressMonitorDialog( Display.getCurrent().getActiveShell()); try { progressMonitorDialog.run(false, true, runnable); } catch (InvocationTargetException e) { Log.warning(DiagramUIRenderPlugin.getInstance(), DiagramUIRenderStatusCodes.IGNORED_EXCEPTION_WARNING, e.getTargetException().getMessage(), e.getTargetException()); if (e.getTargetException() instanceof OutOfMemoryError) { if (dialog.exportToHTML()) { openErrorDialog(DiagramUIRenderMessages.CopyToImageAction_outOfMemoryMessage); } else { if (new MessageDialog(dialog.getShell(), DiagramUIRenderMessages.CopyToImageOutOfMemoryDialog_title, null, DiagramUIRenderMessages.CopyToImageOutOfMemoryDialog_message, MessageDialog.ERROR, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0) .open() == 0) { runCopyToImageUI(dialog); } } } else if (e.getTargetException() instanceof SWTError) { /** * SWT returns an out of handles error when processing large * diagrams */ if (dialog.exportToHTML()) { openErrorDialog(DiagramUIRenderMessages.CopyToImageAction_outOfMemoryMessage); } else { if (new MessageDialog(dialog.getShell(), DiagramUIRenderMessages.CopyToImageOutOfMemoryDialog_title, null, DiagramUIRenderMessages.CopyToImageOutOfMemoryDialog_message, MessageDialog.ERROR, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0) .open() == 0) { runCopyToImageUI(dialog); } } } else { openErrorDialog(e.getTargetException().getMessage()); } return; } catch (InterruptedException e) { /* the user pressed cancel */ Log.warning(DiagramUIRenderPlugin.getInstance(), DiagramUIRenderStatusCodes.IGNORED_EXCEPTION_WARNING, e.getMessage(), e); } if (!status.isOK()) { openErrorDialog(status.getChildren()[0].getMessage()); } } /** * copy the selected shapes in the diagram to an image file. * * @param diagramEditPart * the diagram editor * @param list * list of selected shapes in the diagram * @param destination * path to the new image file * @param imageFormat * image format to create * @return the runnable with a progress monitor */ private IRunnableWithProgress createRunnable(final MultiStatus status) { return new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { try { List editparts = getOperationSet(); CopyToImageUtil copyToImageUtil = null; if (dialog.exportToHTML()) { copyToImageUtil = new CopyToHTMLImageUtil(); } else { copyToImageUtil = new CopyToImageUtil(); } if (editparts.size() == 1 && editparts.get(0) instanceof DiagramEditPart) { monitor.beginTask("", 6); //$NON-NLS-1$ monitor.worked(1); monitor.setTaskName( NLS.bind(DiagramUIRenderMessages.CopyToImageAction_copyingDiagramToImageFileMessage, dialog.getDestination().toOSString())); copyToImageUtil.copyToImage((DiagramEditPart) editparts.get(0), dialog.getDestination(), dialog.getImageFormat(), monitor); } else { DiagramImageUtils.zOrderSort(editparts, LayerManager.Helper.find(getDiagramEditPart()) .getLayer(LayerConstants.PRINTABLE_LAYERS)); monitor.beginTask("", 6); //$NON-NLS-1$ monitor.worked(1); monitor.setTaskName(NLS.bind( DiagramUIRenderMessages.CopyToImageAction_copyingSelectedElementsToImageFileMessage, dialog.getDestination().toOSString())); copyToImageUtil.copyToImage(getDiagramEditPart(), editparts, dialog.getDestination(), dialog.getImageFormat(), monitor); } } catch (CoreException e) { Log.warning(DiagramUIRenderPlugin.getInstance(), DiagramUIRenderStatusCodes.IGNORED_EXCEPTION_WARNING, e.getMessage(), e); status.add(e.getStatus()); } finally { monitor.done(); } } }; } protected boolean calculateEnabled() { return !getOperationSet().isEmpty(); } /** * display an error dialog * * @param message * cause of the error */ private void openErrorDialog(String message) { MessageDialog.openError(Display.getCurrent().getActiveShell(), DiagramUIRenderMessages.CopyToImageAction_copyToImageErrorDialogTitle, NLS.bind(DiagramUIRenderMessages.CopyToImageAction_copyToImageErrorDialogMessage, message)); } /** * Warn the user with a question dialog if an existing file is going to be * overwritten and the user has not selected overwrite existing. * * @return true of it is ok to continue with the copy to image. */ private boolean overwriteExisting() { if (dialog.overwriteExisting()) { /** * the user has selected to overwrite existing */ return true; } if (!dialog.getDestination().toFile().exists()) { /** * the file does not already exist */ return true; } /** * ask the user to confirm to overwrite existing file. */ return MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), DiagramUIRenderMessages.CopyToImageAction_overwriteExistingConfirmDialogTitle, NLS.bind(DiagramUIRenderMessages.CopyToImageAction_overwriteExistingConfirmDialogMessage, dialog.getDestination().toOSString())); } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createOperationSet() */ protected List createOperationSet() { List selection = getSelectedObjects(); if (selection.size() == 1) { Object editpart = selection.get(0); if (editpart instanceof DiagramEditPart) { return selection; } if (editpart instanceof ISurfaceEditPart) { selection = ((ISurfaceEditPart) editpart).getPrimaryEditParts(); } } // must contain at least one shape for (Iterator iter = selection.iterator(); iter.hasNext();) { Object editpart = iter.next(); if (editpart instanceof ShapeEditPart) { return selection; } } return Collections.EMPTY_LIST; } protected boolean isSelectionListener() { return true; } /** * This action is not really a <code>DiagramAction</code> as it doesn't * have a request. The doRun() and calculatedEnabled() have been overwritten * appropriately. */ protected Request createTargetRequest() { return null; } protected void doRun(IProgressMonitor progressMonitor) { try { // whatever we are copying belongs to the same editing domain as // the Diagram getDiagramEditPart().getEditingDomain().runExclusive(new Runnable() { public void run() { CopyToImageAction.this.run(); } }); } catch (Exception e) { Trace.catching(DiagramUIRenderPlugin.getInstance(), DiagramUIRenderDebugOptions.EXCEPTIONS_CATCHING, getClass(), "doRun()", //$NON-NLS-1$ e); } } /** * Subclasses may override to specialize the rendering to an image file. * * @return the <code>CopyToImageUtil</code> class to be used. */ protected CopyToImageUtil getCopyToImageUtil() { return new CopyToImageUtil(); } }