diff options
author | mwenz | 2015-09-17 13:35:44 +0000 |
---|---|---|
committer | Michael Wenz | 2015-10-15 14:10:02 +0000 |
commit | 4364ec2fe5eab301075306961ec671686163dc9d (patch) | |
tree | 3f8701e1ecca974e6f02ca89bd7689b8fb705145 | |
parent | c1273426518a9f939af52daf74064a7e20458398 (diff) | |
download | org.eclipse.graphiti-4364ec2fe5eab301075306961ec671686163dc9d.tar.gz org.eclipse.graphiti-4364ec2fe5eab301075306961ec671686163dc9d.tar.xz org.eclipse.graphiti-4364ec2fe5eab301075306961ec671686163dc9d.zip |
Bug 423018 - Direct Graphiti diagram exporter
* Introduce possibility to export a diagram as an image without opening
an editor
* Add example export as image context menu entry to context menu of
diagram files in explorer
* Allow the export also in case the Graphiti tool for the diagram type
is not installed
** Render images by using a default "not available" image
** Render platform graphics algorithms as "not available" shapes
Change-Id: I25ee2edca1e204322ff4cea191be2a68d4545ac7
13 files changed, 569 insertions, 8 deletions
diff --git a/examples/org.eclipse.graphiti.examples.common/plugin.properties b/examples/org.eclipse.graphiti.examples.common/plugin.properties index cf1fa4d4..65b094b0 100644 --- a/examples/org.eclipse.graphiti.examples.common/plugin.properties +++ b/examples/org.eclipse.graphiti.examples.common/plugin.properties @@ -1,7 +1,7 @@ ############################################################################### # <copyright> # -# Copyright (c) 2005, 2010 SAP AG. +# Copyright (c) 2005, 2015 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 @@ -11,6 +11,7 @@ # SAP AG - initial API, implementation and documentation # mwenz - Bug 336075 - DiagramEditor accepts URIEditorInput # mwenz - Bug 418409 - Graphiti new project and new diagram wizards have disappeared from toolbar new entry +# mwenz - Bug 423018 - Direct Graphiti diagram exporter # # </copyright> # @@ -28,3 +29,5 @@ wizard.description.0 = Creates a new Graphiti diagram (the type of the new diagr nature.name = Graphiti Example Nature perspective.name = Graphiti openDiagramFromFilecommand.name = Open Graphiti Diagram from File +saveAsImageCommand.name = Save as image... +saveAsImageCommand.label = Save diagram as an image file... diff --git a/examples/org.eclipse.graphiti.examples.common/plugin.xml b/examples/org.eclipse.graphiti.examples.common/plugin.xml index e4af5d8e..7d8af64f 100644 --- a/examples/org.eclipse.graphiti.examples.common/plugin.xml +++ b/examples/org.eclipse.graphiti.examples.common/plugin.xml @@ -3,7 +3,7 @@ <!-- <copyright> - Copyright (c) 2005, 2010 SAP AG. + Copyright (c) 2005, 2015 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 @@ -13,6 +13,7 @@ SAP AG - initial API, implementation and documentation mwenz - Bug 336075 - DiagramEditor accepts URIEditorInput mwenz - Bug 418409 - Graphiti new project and new diagram wizards have disappeared from toolbar new entry + mwenz - Bug 423018 - Direct Graphiti diagram exporter </copyright> @@ -203,4 +204,40 @@ </and> </definition> </extension> + + <!-- Command to save a diagram file as image --> + <extension point="org.eclipse.ui.commands"> + <command + defaultHandler="org.eclipse.graphiti.examples.common.handler.SaveDiagramAsImageHandler" + id="org.eclipse.graphiti.examples.common.saveAsImageCommand" + name="%saveAsImageCommand.name"> + </command> + </extension> + + <!-- Context menu entry when 1 diagram file is selected to save the diagram as image --> + <extension point="org.eclipse.ui.menus"> + <menuContribution + locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions"> + <command + commandId="org.eclipse.graphiti.examples.common.saveAsImageCommand" + label="%saveAsImageCommand.label" + style="push"> + <visibleWhen checkEnabled="false"> + <with variable="selection"> + <count value="1"/> + <iterate ifEmpty="false"> + <and> + <test + property="org.eclipse.core.resources.extension" + value="diagram"> + </test> + <adapt type="org.eclipse.core.resources.IFile"> + </adapt> + </and> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> + </extension> </plugin> diff --git a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/Messages.java b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/Messages.java index 2e74238b..fddfd76f 100644 --- a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/Messages.java +++ b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/Messages.java @@ -11,6 +11,7 @@ * SAP AG - initial API, implementation and documentation * mwenz - Bug 336075 - DiagramEditor accepts URIEditorInput * mwenz - Bug 460019 - Problem with CreateDiagramWizard_ErrorOccuredTitle + * mwenz - Bug 423018 - Direct Graphiti diagram exporter * * </copyright> * @@ -70,6 +71,25 @@ public class Messages extends NLS { public static String RenameActionProvider_ProvideNameDescription; public static String RenameActionProvider_ProvideNameTitle; public static String RenameActionProvider_RenameEClassText; + /** + * @since 0.13 + */ + public static String SaveDiagramAsImageHandler_NoDiagramFoundError; + /** + * @since 0.13 + */ + public static String SaveDiagramAsImageHandler_NoDiagramFoundDialogText; + + /** + * @since 0.13 + */ + public static String SaveDiagramAsImageHandler_DialogTitle; + + /** + * @since 0.13 + */ + public static String SaveDiagramAsImageHandler_SaveFileError; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/SaveDiagramAsImageHandler.java b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/SaveDiagramAsImageHandler.java new file mode 100644 index 00000000..6e92cf28 --- /dev/null +++ b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/SaveDiagramAsImageHandler.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * <copyright> + * + * Copyright (c) 2015, 2015 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: + * mwenz - Bug 423018 - Direct Graphiti diagram exporter + * + * </copyright> + * + *******************************************************************************/ +package org.eclipse.graphiti.examples.common.handler; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.emf.transaction.util.TransactionUtil; +import org.eclipse.graphiti.examples.common.Messages; +import org.eclipse.graphiti.mm.pictograms.Diagram; +import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal; +import org.eclipse.graphiti.ui.services.GraphitiUi; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Exports a diagram file as an image in dark mode (no need to have an open + * Graphiti diagram editor + * + * @since 0.13 + */ +public final class SaveDiagramAsImageHandler extends AbstractHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + // Get the current selection + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + + // Operation must be started on diagram node -> cancel if not + Object first = ((IStructuredSelection) selection).getFirstElement(); + if (!(first instanceof IFile)) { + return null; + } + + IFile file = (IFile) first; + URI diagramFileUri = GraphitiUiInternal.getEmfService().getFileURI(file); + + // the file's first base node has to be a diagram + URI diagramUri = GraphitiUiInternal.getEmfService().mapDiagramFileUriToDiagramUri(diagramFileUri); + + // Get the default resource set to hold the new resource + ResourceSet resourceSet = new ResourceSetImpl(); + TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(resourceSet); + if (editingDomain == null) { + // Not yet existing, create one + editingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resourceSet); + } + + Resource resource = editingDomain.getResourceSet().getResource(diagramFileUri, false); + if (resource == null) { + resource = editingDomain.getResourceSet().getResource(diagramFileUri, true); + } + EObject eObject = editingDomain.getResourceSet().getEObject(diagramUri, false); + if (!(eObject instanceof Diagram)) { + ErrorDialog.openError(Display.getCurrent().getActiveShell(), + Messages.SaveDiagramAsImageHandler_NoDiagramFoundError, + Messages.SaveDiagramAsImageHandler_NoDiagramFoundDialogText, Status.CANCEL_STATUS); + return null; + } + + Diagram diagram = (Diagram) eObject; + byte[] bytes = GraphitiUi.getImageService().convertDiagramToBytes(diagram, SWT.IMAGE_JPEG); + + // Ask for the file to save + FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); + dialog.setFilterExtensions(new String[] { "*.jpg", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ + dialog.setFilterIndex(0); + dialog.setText(Messages.SaveDiagramAsImageHandler_DialogTitle); + dialog.setFileName(file.getName()); + String fileName = dialog.open(); + if (fileName == null) { + // Cancelled + return null; + } + + FileOutputStream fos = null; + try { + fos = new FileOutputStream(fileName); + fos.write(bytes); + } catch (FileNotFoundException e) { + return showFileSelectionErrorDialog(e); + } catch (IOException e) { + return showFileSelectionErrorDialog(e); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + return showFileSelectionErrorDialog(e); + } + } + + // Dispose the editing domain to eliminate memory leak + editingDomain.dispose(); + + return null; + } + + private Object showFileSelectionErrorDialog(IOException e) { + IStatus status = new Status(IStatus.ERROR, "org.eclipse.graphiti.examples.common", e.getMessage(), e); //$NON-NLS-1$ + ErrorDialog.openError(Display.getCurrent().getActiveShell(), + Messages.SaveDiagramAsImageHandler_SaveFileError, e.getMessage(), status); + return null; + } +}
\ No newline at end of file diff --git a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/messages.properties b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/messages.properties index f818478e..e6c4b50a 100644 --- a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/messages.properties +++ b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/messages.properties @@ -44,3 +44,7 @@ OpenDiagramFromFileHandler_OpenEditorError=Could not open editor for file RenameActionProvider_ProvideNameDescription=Provide a new Name for the EClass RenameActionProvider_ProvideNameTitle=Provide String RenameActionProvider_RenameEClassText=Rename EClass +SaveDiagramAsImageHandler_NoDiagramFoundError=No Diagram Found +SaveDiagramAsImageHandler_NoDiagramFoundDialogText=There was no diagram object found inside the file +SaveDiagramAsImageHandler_DialogTitle=Save the Graphiti diagram as JPG file +SaveDiagramAsImageHandler_SaveFileError=Could not save image file
\ No newline at end of file diff --git a/plugins/org.eclipse.graphiti.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.graphiti.ui/META-INF/MANIFEST.MF index ed919908..43cadc1d 100644 --- a/plugins/org.eclipse.graphiti.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.graphiti.ui/META-INF/MANIFEST.MF @@ -34,7 +34,7 @@ Export-Package: org.eclipse.graphiti.ui.editor;version="0.13.0", org.eclipse.graphiti.ui.internal.platform;version="0.13.0";x-internal:=true, org.eclipse.graphiti.ui.internal.policy;version="0.13.0";x-friends:="org.eclipse.graphiti.bot.tests", org.eclipse.graphiti.ui.internal.requests;version="0.13.0";x-friends:="org.eclipse.graphiti.ui.tests", - org.eclipse.graphiti.ui.internal.services;version="0.13.0";x-friends:="org.eclipse.graphiti.bot.tests,org.eclipse.graphiti.export.batik", + org.eclipse.graphiti.ui.internal.services;version="0.13.0";x-friends:="org.eclipse.graphiti.bot.tests,org.eclipse.graphiti.export.batik,org.eclipse.graphiti.examples.common", org.eclipse.graphiti.ui.internal.services.impl;version="0.13.0";x-internal:=true, org.eclipse.graphiti.ui.internal.util;version="0.13.0";x-friends:="org.eclipse.graphiti.ui.tests", org.eclipse.graphiti.ui.internal.util.clipboard;version="0.13.0";x-friends:="org.eclipse.graphiti.bot.tests", diff --git a/plugins/org.eclipse.graphiti.ui/icons/NoImage.png b/plugins/org.eclipse.graphiti.ui/icons/NoImage.png Binary files differnew file mode 100644 index 00000000..47b4964a --- /dev/null +++ b/plugins/org.eclipse.graphiti.ui/icons/NoImage.png diff --git a/plugins/org.eclipse.graphiti.ui/plugin.xml b/plugins/org.eclipse.graphiti.ui/plugin.xml index 68e3381f..e785e625 100644 --- a/plugins/org.eclipse.graphiti.ui/plugin.xml +++ b/plugins/org.eclipse.graphiti.ui/plugin.xml @@ -12,6 +12,7 @@ Contributors: SAP AG - initial API, implementation and documentation Felix Velasco (mwenz) - Bug 323351 - Enable to suppress/reactivate the speed buttons + Laurent Le Moux, mwenz - Bug 423018 - Direct Graphiti diagram exporter </copyright> @@ -142,4 +143,23 @@ parentId="org.eclipse.ui.contexts.window"> </context> </extension> + + <extension point="org.eclipse.graphiti.ui.diagramTypeProviders"> + <diagramTypeProvider + class="org.eclipse.graphiti.ui.internal.services.impl.DummyExportAsImageDiagramTypeProvider" + description="A dummy diagram provider used for exporting diagrams as image without editor installed for that diagram type" + id="org.eclipse.graphiti.ui.internal.ExportDiagramAsImageDummyDiagramTypeProvider" + name="DummyExportDiagramAsImage"> + <imageProvider + id="org.eclipse.graphiti.ui.internal.ExportDiagramAsImageDummyImageProvider"> + </imageProvider> + </diagramTypeProvider> + </extension> + + <extension point="org.eclipse.graphiti.ui.imageProviders"> + <imageProvider + class="org.eclipse.graphiti.ui.internal.services.impl.ExportDiagramAsImageDummyImageProvider" + id="org.eclipse.graphiti.ui.internal.ExportDiagramAsImageDummyImageProvider"> + </imageProvider> + </extension> </plugin> diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/DummyExportAsImageDiagramTypeProvider.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/DummyExportAsImageDiagramTypeProvider.java new file mode 100644 index 00000000..c5395050 --- /dev/null +++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/DummyExportAsImageDiagramTypeProvider.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * <copyright> + * + * Copyright (c) 2015, 2015 Eclipse Modeling Project. + * 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: + * Laurent Le Moux, mwenz - Bug 423018 - Direct Graphiti diagram exporter + * + * </copyright> + * + *******************************************************************************/ +package org.eclipse.graphiti.ui.internal.services.impl; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.RectangleFigure; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.graphiti.dt.AbstractDiagramTypeProvider; +import org.eclipse.graphiti.features.IFeatureProvider; +import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRenderer; +import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRendererFactory; +import org.eclipse.graphiti.platform.ga.IRendererContext; +import org.eclipse.graphiti.platform.ga.IVisualState; +import org.eclipse.graphiti.platform.ga.IVisualStateChangeListener; +import org.eclipse.graphiti.platform.ga.IVisualStateHolder; +import org.eclipse.graphiti.platform.ga.VisualState; +import org.eclipse.graphiti.platform.ga.VisualStateChangedEvent; +import org.eclipse.graphiti.ui.features.DefaultFeatureProvider; +import org.eclipse.swt.SWT; + +public class DummyExportAsImageDiagramTypeProvider extends AbstractDiagramTypeProvider { + @Override + public IFeatureProvider getFeatureProvider() { + // To avoid NPE... + return new DefaultFeatureProvider(this); + } + + @Override + public IGraphicsAlgorithmRendererFactory getGraphicsAlgorithmRendererFactory() { + return new DummyExportAsImageAlgorithmRendererFactory(); + } + + // Used for rendering any tool specific platform graphics algorithm in a + // standard way (display shape with info text that this cannot be rendered). + private class DummyExportAsImageAlgorithmRendererFactory implements IGraphicsAlgorithmRendererFactory { + public IGraphicsAlgorithmRenderer createGraphicsAlgorithmRenderer(IRendererContext context) { + return new NoRendererAvailableFigure(); + } + } + + // Renderer for the standard text that this platform graphics algorithm + // cannot be rendered. + private class NoRendererAvailableFigure extends RectangleFigure implements IGraphicsAlgorithmRenderer, + IVisualStateHolder, IVisualStateChangeListener { + + private Insets defaultFigureInsets = new Insets(2); + + private VisualState visualState; + + public NoRendererAvailableFigure() { + super(); + } + + @Override + public IVisualState getVisualState() { + if (visualState == null) { + visualState = new VisualState(); + visualState.addChangeListener(this); + } + return visualState; + } + + @Override + public void visualStateChanged(VisualStateChangedEvent e) { + setBackgroundColor(ColorConstants.white); + setLineWidth(1); + } + + @Override + protected void fillShape(Graphics g) { + g.setAntialias(SWT.ON); + Rectangle innerBounds = getInnerBounds(); + g.setBackgroundColor(ColorConstants.white); + g.fillRectangle(new Rectangle(innerBounds.getLeft(), innerBounds.getRight())); + } + + @Override + protected void outlineShape(Graphics g) { + Rectangle innerBounds = getInnerBounds(); + + g.drawLine(innerBounds.getTopLeft(), innerBounds.getTopRight()); + g.drawLine(innerBounds.getTopRight(), innerBounds.getBottomRight()); + g.drawLine(innerBounds.getBottomRight(), innerBounds.getBottomLeft()); + g.drawLine(innerBounds.getBottomLeft(), innerBounds.getTopLeft()); + + g.setForegroundColor(ColorConstants.black); + g.drawText("Sorry!\n\nThis tool specific shape\ncannot be rendered.", innerBounds.x + 10, + innerBounds.y + 10); + } + + private Rectangle getInnerBounds() { + return getBounds().getCopy().getShrinked(defaultFigureInsets); + } + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ExportDiagramAsImageDummyImageProvider.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ExportDiagramAsImageDummyImageProvider.java new file mode 100644 index 00000000..068c13be --- /dev/null +++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ExportDiagramAsImageDummyImageProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * <copyright> + * + * Copyright (c) 2015, 2015 Eclipse Modeling Project. + * 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: + * Laurent Le Moux, mwenz - Bug 423018 - Direct Graphiti diagram exporter + * + * </copyright> + * + *******************************************************************************/ +package org.eclipse.graphiti.ui.internal.services.impl; + +import org.eclipse.graphiti.platform.AbstractExtension; +import org.eclipse.graphiti.ui.platform.IImageProvider; + +public class ExportDiagramAsImageDummyImageProvider extends AbstractExtension implements IImageProvider { + + private String pluginId; + + public ExportDiagramAsImageDummyImageProvider() { + super(); + } + + final public String getPluginId() { + return this.pluginId; + } + + final public void setPluginId(String pluginId) { + this.pluginId = pluginId; + } + + final public String getImageFilePath(String imageId) { + return "icons/NoImage.png"; //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ImageService.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ImageService.java index 2a421842..6010864d 100644 --- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ImageService.java +++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/services/impl/ImageService.java @@ -12,6 +12,7 @@ * fvelasco - Bug 396247 - ImageDescriptor changes * mwenz - Bug 413139 - Visibility of convertImageToBytes in DefaultSaveImageFeature * mjagielski - Bug 472219 - ImageService is not handling imageFilePath with protocol bundleentry + * Laurent Le Moux (mwenz) - Bug 423018 - Direct Graphiti diagram exporter * * </copyright> * @@ -24,21 +25,48 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.SWTGraphics; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalViewer; +import org.eclipse.gef.Handle; +import org.eclipse.gef.LayerConstants; +import org.eclipse.gef.editparts.LayerManager; +import org.eclipse.gef.editparts.ScalableRootEditPart; +import org.eclipse.gef.ui.parts.AbstractEditPartViewer; +import org.eclipse.graphiti.dt.IDiagramTypeProvider; +import org.eclipse.graphiti.mm.pictograms.Diagram; +import org.eclipse.graphiti.ui.editor.DefaultRefreshBehavior; +import org.eclipse.graphiti.ui.editor.DiagramBehavior; +import org.eclipse.graphiti.ui.editor.DiagramEditor; +import org.eclipse.graphiti.ui.editor.IDiagramContainerUI; import org.eclipse.graphiti.ui.internal.GraphitiUIPlugin; import org.eclipse.graphiti.ui.internal.T; +import org.eclipse.graphiti.ui.internal.config.ConfigurationProvider; +import org.eclipse.graphiti.ui.internal.config.IConfigurationProviderInternal; +import org.eclipse.graphiti.ui.internal.parts.DiagramEditPart; import org.eclipse.graphiti.ui.internal.platform.ExtensionManager; +import org.eclipse.graphiti.ui.platform.IConfigurationProvider; import org.eclipse.graphiti.ui.platform.IImageProvider; import org.eclipse.graphiti.ui.platform.PlatformImageProvider; +import org.eclipse.graphiti.ui.services.GraphitiUi; import org.eclipse.graphiti.ui.services.IImageService; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; +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.graphics.PaletteData; import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.plugin.AbstractUIPlugin; /** @@ -203,7 +231,9 @@ public class ImageService implements IImageService { URL imageFileUrl = new URL(imageFilePath); imageDescriptor = ImageDescriptor.createFromURL(imageFileUrl); } catch (MalformedURLException e) { - T.racer().error("Bundle entry/resource url for image could not be parsed, url was: " + imageFilePath, e); + T.racer() + .error("Bundle entry/resource url for image could not be parsed, url was: " + + imageFilePath, e); } } else { String pluginId = imageProvider.getPluginId(); @@ -319,4 +349,143 @@ public class ImageService implements IImageService { return newImageData; } -} + + @Override + public byte[] convertDiagramToBytes(Diagram diagram, int format) { + DummyEditor dummyEditor = new DummyEditor(); + dummyEditor.getGraphicalViewer().setRootEditPart(new ScalableRootEditPart()); + ImageGenerationDiagramBehavior imageGenerationDiagramBehavior = new ImageGenerationDiagramBehavior(dummyEditor, + diagram); + dummyEditor.getGraphicalViewer().setEditPartFactory( + ((IConfigurationProviderInternal) imageGenerationDiagramBehavior.getConfigurationProvider()) + .getEditPartFactory()); + + // Recursively launch all figure creations + dummyEditor.getGraphicalViewer().setContents(diagram); + + // Set the Graphiti diagram bounds... + int width = diagram.getGraphicsAlgorithm().getWidth(), height = diagram.getGraphicsAlgorithm().getHeight(); + IFigure diagramFigure = ((LayerManager) dummyEditor.getGraphicalViewer().getRootEditPart()) + .getLayer(LayerConstants.PRINTABLE_LAYERS); + diagramFigure.setBounds(new Rectangle(0, 0, width, height)); + // ...and trigger the figures validation + diagramFigure.validate(); + + // Set bounds to final narrowed image size + DiagramEditPart diagramEditPart = (DiagramEditPart) dummyEditor.getGraphicalViewer().getRootEditPart() + .getChildren().get(0); + int XMin = width; + int YMin = height; + int XMax = 0; + int YMax = 0; + for (Object o : diagramEditPart.getFigure().getChildren()) { + Figure f = (Figure) o; + if (f.getLocation().x < XMin) { + XMin = f.getLocation().x; + } + if (f.getLocation().y < YMin) { + YMin = f.getLocation().y; + } + if (f.getLocation().x + f.getBounds().width > XMax) { + XMax = f.getLocation().x + f.getBounds().width; + } + if (f.getLocation().y + f.getBounds().height > YMax) { + YMax = f.getLocation().y + f.getBounds().height; + } + } + + width = XMin + XMax; + height = YMin + YMax; + // Workaround for default diagram creation limited to 1000 x 1000 bounds + if (width > diagramFigure.getBounds().width || height > diagramFigure.getBounds().height) { + diagramFigure.setBounds(new Rectangle(0, 0, width, height)); + diagramFigure.validate(); + } + Image diagramImage = new Image(Display.getDefault(), width, height); + GC gc = new GC(diagramImage); + SWTGraphics graphics = new SWTGraphics(gc); + diagramFigure.paint(graphics); + graphics.dispose(); + gc.dispose(); + + return convertImageToBytes(diagramImage, format); + } + + private class ImageGenerationDiagramBehavior extends DiagramBehavior { + + private IConfigurationProviderInternal configurationProvider = null; + + public ImageGenerationDiagramBehavior(IDiagramContainerUI diagramContainer, Diagram diagram) { + super(diagramContainer); + + // Extract the diagram type from the given diagram and try to find + // the associated diagram type provider. That instance will have the + // correct image provider associated so that images will be rendered + // correctly. + // This will work only in case the graphical tool for the diagram + // type is installed. + IDiagramTypeProvider diagramTypeProvider = null; + String providerId = GraphitiUi.getExtensionManager().getDiagramTypeProviderId(diagram.getDiagramTypeId()); + if (providerId != null) { + diagramTypeProvider = ExtensionManager.getSingleton().createDiagramTypeProvider(providerId); + } + if (diagramTypeProvider == null) { + // In case no tool was found, use a dummy diagram type provider + // for the rendering. This will still not show the correct + // images and platform graphics algorithms but will render a + // default image or shape stating that the image or shape + // is not available for all rendered images. + diagramTypeProvider = ExtensionManager.getSingleton().createDiagramTypeProvider( + "org.eclipse.graphiti.ui.internal.ExportDiagramAsImageDummyDiagramTypeProvider"); + } + + diagramTypeProvider.init(diagram, this); + configurationProvider = new ConfigurationProvider(this, diagramTypeProvider); + } + + @Override + public IConfigurationProvider getConfigurationProvider() { + return configurationProvider; + } + + @Override + public boolean isAlive() { + // To trigger refresh without check on non-existing edit domain + return true; + } + + @Override + public DefaultRefreshBehavior getRefreshBehavior() { + return new DefaultRefreshBehavior(this); // To avoid NPE... + } + } + + private class DummyGraphicalViewer extends AbstractEditPartViewer implements GraphicalViewer { + + @Override + public EditPart findObjectAtExcluding(Point location, @SuppressWarnings("rawtypes") Collection exclusionSet, + Conditional conditional) { + return null; + } + + @Override + public Handle findHandleAt(Point p) { + return null; + } + + @Override + public Control createControl(Composite parent) { + return null; + } + } + + private class DummyEditor extends DiagramEditor { + + private DummyGraphicalViewer dummyGraphicalViewer = new DummyGraphicalViewer(); + + @Override + public GraphicalViewer getGraphicalViewer() { + return dummyGraphicalViewer; + } + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/services/IImageService.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/services/IImageService.java index 05e98d3d..ebf3db96 100644 --- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/services/IImageService.java +++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/services/IImageService.java @@ -1,7 +1,7 @@ /******************************************************************************* * <copyright> * - * Copyright (c) 2005, 2013 SAP AG. + * Copyright (c) 2005, 2015 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 @@ -11,12 +11,14 @@ * SAP AG - initial API, implementation and documentation * fvelasco - Bug 396247 - ImageDescriptor changes * mwenz - Bug 413139 - Visibility of convertImageToBytes in DefaultSaveImageFeature + * Laurent Le Moux (mwenz) - Bug 423018 - Direct Graphiti diagram exporter * * </copyright> * *******************************************************************************/ package org.eclipse.graphiti.ui.services; +import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageLoader; @@ -138,4 +140,19 @@ public interface IImageService { * @since 0.11 */ byte[] convertImageToBytes(Image image, int format); + + /** + * Converts the given diagram into an image byte array in the given format.<br> + * This allows end users to export diagrams without having to run the + * associated GEF editor. + * + * @param diagram + * The diagram to convert to a byte array + * @param format + * The format to use see {@link ImageLoader} + * @return A byte array containing the diagram image + * + * @since 0.13 + */ + byte[] convertDiagramToBytes(Diagram diagram, int format); } diff --git a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/internal/services/impl/EmfService.java b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/internal/services/impl/EmfService.java index b67c96ac..555b9a45 100644 --- a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/internal/services/impl/EmfService.java +++ b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/internal/services/impl/EmfService.java @@ -1,7 +1,7 @@ /******************************************************************************* * <copyright> * - * Copyright (c) 2005, 2010 SAP AG. + * Copyright (c) 2005, 2015 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 @@ -9,6 +9,7 @@ * * Contributors: * SAP AG - initial API, implementation and documentation + * Laurent Le Moux (mwenz) - Bug 423018 - Direct Graphiti diagram exporter * * </copyright> * @@ -33,7 +34,7 @@ public final class EmfService implements IEmfService { private WeakHashMap<Diagram, WeakReference<IDiagramTypeProvider>> diagToProvider = new WeakHashMap<Diagram, WeakReference<IDiagramTypeProvider>>(); public boolean isObjectAlive(EObject obj) { - return obj != null && obj.eResource() != null; + return obj != null; } public IDiagramTypeProvider getDTPForDiagram(Diagram d) { |