com.ebmwebsourcing.petals.services.eip.designer.actions.ExportDiagramAction.java Source code

Java tutorial

Introduction

Here is the source code for com.ebmwebsourcing.petals.services.eip.designer.actions.ExportDiagramAction.java

Source

/******************************************************************************
 * Copyright (c) 2011-2013, Linagora
 *
 * 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:
 *       Linagora - initial API and implementation
 *******************************************************************************/

package com.ebmwebsourcing.petals.services.eip.designer.actions;

import org.eclipse.draw2d.FreeformLayer;
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.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
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.Region;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;

import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;
import com.ebmwebsourcing.petals.services.eip.PetalsEipPlugin;
import com.ebmwebsourcing.petals.services.eip.designer.model.EipChain;

/**
 * @author Vincent Zurczak - EBM WebSourcing
 */
public class ExportDiagramAction extends Action {

    private final static int BORDER_MARGIN_SIDES = 8;
    private final static int BORDER_MARGIN_UPDOWN = 7;

    private final GraphicalViewer graphicalViewer;
    private final EipChain eipChain;

    /**
     * Constructor.
     * @param graphicalViewer
     * @param eipChain
     */
    public ExportDiagramAction(GraphicalViewer graphicalViewer, EipChain eipChain) {

        this.graphicalViewer = graphicalViewer;
        this.eipChain = eipChain;

        setId("com.ebmwebsourcing.petals.services.eip.contextmenu.exportdiagram");
        setText("Export as an image");
        setToolTipText("Export a diagram as an image");
        setDescription("Export a diagram in an image file.");

        ImageDescriptor desc = PetalsEipPlugin.getImageDescriptor("icons/obj16/image.gif");
        setImageDescriptor(desc);
    }

    /*
     * (non-Jsdoc)
     * @see org.eclipse.jface.action.Action
     * #run()
     */
    @Override
    public void run() {

        // Determine the export location
        FileDialog dlg = new FileDialog(new Shell(), SWT.SAVE);
        dlg.setText("Image Export");
        dlg.setOverwrite(true);
        dlg.setFilterNames(new String[] { "JPEG Files (*.jpg)", "PNG Files (*.png)", "GIF Files (*.gif)" });
        String[] extensions = new String[] { "*.jpg", "*.png", "*.gif" };
        dlg.setFilterExtensions(extensions);
        String path = dlg.open();

        if (path != null) {

            String ext = extensions[dlg.getFilterIndex()].substring(1);
            if (!path.endsWith(ext))
                path += ext;

            // Only print printable layers
            ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) this.graphicalViewer
                    .getEditPartRegistry().get(LayerManager.ID);
            IFigure rootFigure = ((LayerManager) rootEditPart).getLayer(LayerConstants.PRINTABLE_LAYERS);
            IFigure eipChainFigure = null;
            for (Object o : rootFigure.getChildren()) {
                if (o instanceof FreeformLayer)
                    eipChainFigure = (FreeformLayer) o;
            }

            Rectangle bounds = eipChainFigure == null ? rootFigure.getBounds() : eipChainFigure.getBounds();
            GC figureCanvasGC = new GC(this.graphicalViewer.getControl());

            // Add 20 pixels to write the title of the diagram on the image
            Image img = new Image(null, bounds.width, bounds.height);
            GC gc = new GC(img);
            gc.setBackground(figureCanvasGC.getBackground());
            gc.setForeground(figureCanvasGC.getForeground());
            gc.setFont(figureCanvasGC.getFont());
            gc.setLineStyle(figureCanvasGC.getLineStyle());
            gc.setLineWidth(figureCanvasGC.getLineWidth());
            Graphics imgGraphics = new SWTGraphics(gc);

            // Paint it...
            rootFigure.paint(imgGraphics);

            // Prepare the next step
            Font font = new Font(Display.getCurrent(), "Arial", 14, SWT.BOLD);
            gc.setFont(font);
            int height = Dialog.convertHeightInCharsToPixels(gc.getFontMetrics(), 1);
            gc.dispose();

            // Create a second image with the title and diagram version
            bounds.height += height + (height % 2 == 0 ? 6 : 7); // Write the title and its border
            bounds.height += 3 * BORDER_MARGIN_UPDOWN + 2; // Add a border + some margin
            bounds.width += 2 * BORDER_MARGIN_SIDES + 2; // Add a border

            Image finalImg = new Image(null, bounds.width, bounds.height);
            gc = new GC(finalImg);

            // Draw a surrounding border
            gc.setAntialias(SWT.ON);
            gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
            gc.drawLine(BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN, BORDER_MARGIN_SIDES,
                    bounds.height - BORDER_MARGIN_UPDOWN);
            gc.drawLine(BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN,
                    bounds.width - BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN);
            gc.drawLine(BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN, bounds.width - BORDER_MARGIN_SIDES,
                    BORDER_MARGIN_UPDOWN);
            gc.drawLine(bounds.width - BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN,
                    bounds.width - BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN);

            // Draw the title
            gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
            gc.setFont(font);
            gc.setClipping((Region) null);
            gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));

            String title = this.eipChain.getTitle() != null ? this.eipChain.getTitle() : "No diagram title";
            if (!StringUtils.isEmpty(this.eipChain.getVersion()))
                title += " - Version " + this.eipChain.getVersion().trim();

            int width = Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), title.length());
            if (width > bounds.width) {
                title = Dialog.shortenText(title, this.graphicalViewer.getControl());
                width = Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), title.length());
            }

            gc.drawText(title, 6 + BORDER_MARGIN_SIDES, 4 + BORDER_MARGIN_UPDOWN, true);

            // Draw a surrounding shape for the title
            gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
            Rectangle titleRectangle = new Rectangle(BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN,
                    BORDER_MARGIN_SIDES + width + (width % 2 == 0 ? 10 : 11),
                    BORDER_MARGIN_UPDOWN + height + (height % 2 == 0 ? 6 : 7));

            final int arrowPadding = (titleRectangle.height + bounds.y) / 2;
            gc.drawLine(titleRectangle.x, titleRectangle.height, titleRectangle.width, titleRectangle.height);

            gc.drawLine(titleRectangle.width, titleRectangle.y, titleRectangle.width + arrowPadding, arrowPadding);

            gc.drawLine(titleRectangle.width, titleRectangle.height, titleRectangle.width + arrowPadding,
                    arrowPadding);

            // Draw the image
            gc.drawImage(img, BORDER_MARGIN_SIDES + 1, BORDER_MARGIN_UPDOWN + titleRectangle.height + 1);

            // Save the second image
            ImageData[] imgData = new ImageData[1];
            imgData[0] = finalImg.getImageData();

            int format;
            String tail = path.toLowerCase().substring(path.length() - 4);
            if (tail.endsWith(".jpg"))
                format = SWT.IMAGE_JPEG;
            else if (tail.endsWith(".png"))
                format = SWT.IMAGE_PNG;
            else
                format = SWT.IMAGE_GIF;

            ImageLoader imgLoader = new ImageLoader();
            imgLoader.data = imgData;
            imgLoader.save(path, format);

            // Dispose everything
            figureCanvasGC.dispose();
            gc.dispose();
            img.dispose();
            finalImg.dispose();
            font.dispose();
        }
    }
}