/* * Copyright (c) 2016 wetransform GmbH * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * wetransform GmbH <http://www.wetransform.to> */ package eu.esdihumboldt.cst.doc.functions.internal.content.image; import java.awt.Dimension; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.eclipse.zest.core.viewers.GraphViewer; import org.eclipse.zest.core.widgets.Graph; import org.eclipse.zest.core.widgets.GraphNode; import org.eclipse.zest.layouts.LayoutAlgorithm; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.hale.common.align.extension.function.FunctionDefinition; import eu.esdihumboldt.hale.common.align.extension.function.FunctionUtil; import eu.esdihumboldt.hale.ui.common.graph.content.FunctionGraphContentProvider; import eu.esdihumboldt.hale.ui.common.graph.labels.FunctionGraphLabelProvider; import eu.esdihumboldt.hale.ui.common.graph.layout.FunctionTreeLayoutAlgorithm; import eu.esdihumboldt.hale.ui.util.DisplayThread; import eu.esdihumboldt.hale.ui.util.graph.OffscreenGraph; /** * Function image content provider for the function help. * * @author Simon Templer */ public class ImageContent { private static final ALogger log = ALoggerFactory.getLogger(ImageContent.class); /** * Get the function image for the function with the given identifier. * * @param func_id the function identifier * @param tempDir the temporary directory where the function image may be * stored * @return the function image input stream or <code>null</code> * @throws Exception if an error occurs generating the image */ public static InputStream getImageContent(String func_id, File tempDir) throws Exception { final FunctionDefinition<?> function = FunctionUtil.getFunction(func_id, null); if (function == null) { log.warn("Unknown function " + func_id); return null; } final File _functionFile = new File(tempDir, func_id + ".png"); if (!_functionFile.exists()) { Display display; if (Display.getCurrent() != null) { // use the current display if available display = Display.getCurrent(); } else { try { // use workbench display if available display = PlatformUI.getWorkbench().getDisplay(); } catch (Throwable e) { // use a dedicated display thread if no workbench is // available display = DisplayThread.getInstance().getDisplay(); } } display.syncExec(new Runnable() { @Override public void run() { // create an initial off-screen graph with fixed values; // resize the graph after computing the figures width and // height OffscreenGraph off_graph = new OffscreenGraph(300, 200) { @Override protected void configureViewer(GraphViewer viewer) { LayoutAlgorithm algo = new FunctionTreeLayoutAlgorithm(); FunctionGraphContentProvider stcp = new FunctionGraphContentProvider(); // XXX no service provider given FunctionGraphLabelProvider fglp = new FunctionGraphLabelProvider(null, false); viewer.setContentProvider(stcp); viewer.setLabelProvider(fglp); viewer.setInput(function); viewer.setLayoutAlgorithm(algo); } }; Graph graph = off_graph.getGraph(); Dimension dim = computeSize(graph); int width; if (dim.width > 450) { width = dim.width; } else { // minimum width = 450 width = 450; } int height = dim.height; off_graph.resize(width, height); try { off_graph.saveImage( new BufferedOutputStream(new FileOutputStream(_functionFile)), null); } catch (IOException e) { log.warn("Conversion from Graph to Image failed!"); } finally { off_graph.dispose(); } } }); } if (_functionFile.exists()) { return new FileInputStream(_functionFile); } return null; } private static Dimension computeSize(Graph graph) { @SuppressWarnings("unchecked") List<GraphNode> list = graph.getNodes(); int height = 0; int width = 0; List<GraphNode> tempSourceList = new ArrayList<GraphNode>(); List<GraphNode> tempTargetList = new ArrayList<GraphNode>(); for (GraphNode gn : list) { int sourceCons = gn.getSourceConnections().size(); int targetCons = gn.getTargetConnections().size(); if (sourceCons == 0 && targetCons == 1) { tempSourceList.add(gn); } else if (sourceCons >= 1 && targetCons >= 1) { width = width + gn.getFigure().getBounds().width + 10; height = height + gn.getFigure().getBounds().height; } else { tempTargetList.add(gn); } } int accuSourceWidth = 0; int accuSourceHeight = 0; int accuHeight = 0; for (GraphNode node : tempSourceList) { Rectangle rec = node.getFigure().getBounds(); int sourceWidth = rec.width; int sourceHeight = rec.height; accuSourceHeight = accuSourceHeight + sourceHeight; if (accuSourceWidth < sourceWidth) { accuSourceWidth = sourceWidth; } if (accuHeight < accuSourceHeight) { accuHeight = accuSourceHeight; } } int accuTargetWidth = 0; int accuTargetHeight = 0; for (GraphNode node : tempTargetList) { Rectangle rec = node.getFigure().getBounds(); int targetWidth = rec.width; int targetHeight = rec.height; accuTargetHeight = accuTargetHeight + targetHeight; if (accuTargetWidth < targetWidth) { accuTargetWidth = targetWidth; } if (accuHeight < accuTargetHeight) { accuHeight = accuTargetHeight; } } width = width + accuSourceWidth + accuTargetWidth + 30; if (height < accuHeight) { height = accuHeight + 35; } height += 20; Dimension d = new Dimension(); d.setSize(width, height); return d; } }