package org.csstudio.sds.ui.dialogs; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.csstudio.sds.internal.persistence.PersistenceUtil; import org.csstudio.sds.model.DisplayModel; import org.csstudio.sds.ui.editparts.ExecutionMode; import org.csstudio.sds.ui.internal.editparts.DisplayEditPart; import org.csstudio.sds.ui.internal.editparts.WidgetEditPartFactory; 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.EditPart; import org.eclipse.gef.editparts.ScalableFreeformRootEditPart; import org.eclipse.gef.ui.parts.GraphicalViewerImpl; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class ThumbnailCreator { private static ThumbnailImageCache imageCache = new ThumbnailImageCache(); public ThumbnailCreator() { Display.getCurrent().addListener(SWT.Dispose, new Listener() { @Override public void handleEvent(Event arg0) { imageCache.shutdown(); } }); } public ImageData createImage(final File file, final int thumbSize, final Display display) { ImageData imageData = imageCache.getCachedImage(file); if (imageData == null) { ThumbnailCreationJob job = new ThumbnailCreationJob(display, file, thumbSize); imageData = job.getImageData(); if (imageData != null) { imageCache.cacheImage(file, imageData); } } return imageData; } private static class ThumbnailCreationJob implements Runnable { private final Display display; private final DisplayModel model; private final int thumbSize; private ImageData imageData; public ThumbnailCreationJob(Display display, File file, int thumbSize) { this.display = display; this.thumbSize = thumbSize; model = new DisplayModel(); FileInputStream fip = null; try { fip = new FileInputStream(file); PersistenceUtil.syncFillModel(model, fip); } catch (Exception e) { e.printStackTrace(); } finally { try { fip.close(); } catch (IOException e) { e.printStackTrace(); } } if (!display.isDisposed()) { display.syncExec(this); } } public ImageData getImageData() { return imageData; } @Override public void run() { if (!display.isDisposed()) { Shell shell = new Shell(display, SWT.NO_TRIM); Image image = null; try { shell.setLayout(new FillLayout()); shell.setSize(model.getWidth(), model.getHeight()); ThumbnailDrawingViewer viewer = new ThumbnailDrawingViewer(); viewer.createControl(shell); viewer.setEditPartFactory(new NoBorderWidgetEditPartFactory( ExecutionMode.EDIT_MODE)); viewer.setRootEditPart(new ScalableFreeformRootEditPart()); viewer.setContents(model); shell.layout(); image = viewer.createImage(thumbSize); imageData = image.getImageData(); } finally { if (image != null) { image.dispose(); } shell.dispose(); } } } } private static class ThumbnailDrawingViewer extends GraphicalViewerImpl { public Image createImage(int thumbSize) { IFigure figure = getLightweightSystem().getRootFigure(); Rectangle bounds = figure.getBounds(); double factor = Math.min( (double) thumbSize / (double) bounds.width, (double) thumbSize / (double) bounds.height); Image image = new Image(Display.getCurrent(), (int) Math.ceil((double) bounds.width * factor), (int) Math.ceil((double) bounds.height * factor)); GC gc = new GC(image); Graphics graphics = new SWTGraphics(gc); // TODO Antialiasing an GC oder Graphics konfigurieren graphics.scale(factor); figure.paint(graphics); gc.dispose(); // TODO disposing in finally-Block return image; } } private static class NoBorderWidgetEditPartFactory extends WidgetEditPartFactory { public NoBorderWidgetEditPartFactory(ExecutionMode executionMode) { super(executionMode); } @Override public EditPart createEditPart(EditPart context, Object modelElement) { EditPart result = super.createEditPart(context, modelElement); if (modelElement instanceof DisplayModel) { ((DisplayEditPart) result) .setExecutionMode(ExecutionMode.RUN_MODE); } return result; } } }