From c74dae631e7460b5f2b0b0cee0cc39b6914977f9 Mon Sep 17 00:00:00 2001 From: Ben Steffensmeier Date: Tue, 7 Feb 2012 15:33:23 -0600 Subject: [PATCH] Issue #235 Ability to screen capture or print multiple frames at once. Change-Id: I58176883e701fbe0d9e0bcc0e43b60bd5c0053a7 Former-commit-id: 9062fe4b8fdb62840b21aba7c648f48fa691986a --- .../plugin.xml | 31 ++++++ cave/com.raytheon.viz.ui/plugin.xml | 12 ++- .../actions/AbstractScreenCaptureAction.java | 100 ++++++++++++++++++ .../viz/ui/actions/PrintScreenAction.java | 98 +++++++++++------ .../viz/ui/actions/SaveScreenAction.java | 55 ++++++++-- 5 files changed, 253 insertions(+), 43 deletions(-) create mode 100644 cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/AbstractScreenCaptureAction.java diff --git a/cave/com.raytheon.viz.ui.personalities.awips/plugin.xml b/cave/com.raytheon.viz.ui.personalities.awips/plugin.xml index c21a36575d..4950549002 100644 --- a/cave/com.raytheon.viz.ui.personalities.awips/plugin.xml +++ b/cave/com.raytheon.viz.ui.personalities.awips/plugin.xml @@ -112,6 +112,37 @@ commandId="com.raytheon.viz.ui.loadSerialized" label="Load Displays..." style="push"> + + + + + + + + + + + + + + + + - + + + diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/AbstractScreenCaptureAction.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/AbstractScreenCaptureAction.java new file mode 100644 index 0000000000..d143d10d4f --- /dev/null +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/AbstractScreenCaptureAction.java @@ -0,0 +1,100 @@ +package com.raytheon.viz.ui.actions; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.swt.graphics.Rectangle; + +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IView; +import com.raytheon.uf.viz.core.datastructure.LoopProperties; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; + +public abstract class AbstractScreenCaptureAction extends AbstractHandler { + + protected BufferedImage captureCurrentFrames(AbstractEditor editor) { + return editor.screenshot(); + } + + protected List captureAllFrames(AbstractEditor editor) + throws VizException { + int startIndex = 0; + int endIndex = editor.getActiveDisplayPane().getDescriptor() + .getFramesInfo().getFrameCount(); + return captureFrames(editor, startIndex, endIndex); + } + + protected List captureFrames(AbstractEditor editor, + int startIndex, int endIndex) throws VizException { + if (startIndex < 0) { + startIndex = 0; + } + List images = new ArrayList(endIndex + - startIndex); + int origIndex = editor.getActiveDisplayPane().getDescriptor() + .getFramesInfo().getFrameIndex(); + for (int i = startIndex; i < endIndex; i++) { + for (IDisplayPane pane : editor.getDisplayPanes()) { + setFrameIndex(pane.getDescriptor(), i); + pane.refresh(); + renderPane(pane, editor.getLoopProperties()); + } + images.add(editor.screenshot()); + } + for (IDisplayPane pane : editor.getDisplayPanes()) { + setFrameIndex(pane.getDescriptor(), origIndex); + pane.refresh(); + } + return images; + } + + private void setFrameIndex(IDescriptor desc, int index) { + FramesInfo fi = desc.getFramesInfo(); + fi = new FramesInfo(fi.getFrameTimes(), index, fi.getTimeMap()); + desc.setFramesInfo(fi); + } + + private void renderPane(IDisplayPane pane, LoopProperties loopProperties) + throws VizException { + IGraphicsTarget target = pane.getTarget(); + IRenderableDisplay display = pane.getRenderableDisplay(); + + float alpha = 1.0f; + float zoomLevel = (float) pane.getZoomLevel(); + IView view = display.getView(); + Rectangle canvasBounds = pane.getBounds(); + boolean isZooming = false; + FramesInfo framesInfo = pane.getDescriptor().getFramesInfo(); + PaintProperties paintProps = new PaintProperties(alpha, zoomLevel, + view, canvasBounds, isZooming, framesInfo); + paintProps.setLoopProperties(loopProperties); + + // paint in a loop until any async tasks are done + while (target.isNeedsRefresh()) { + target.beginFrame(display, true); + display.paint(target, paintProps); + target.endFrame(); + } + } + + @Override + public void setEnabled(Object obj) { + IDisplayPaneContainer container = EditorUtil.getActiveVizContainer(); + if (container == null) { + setBaseEnabled(false); + } else { + setBaseEnabled(true); + } + } + +} diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/PrintScreenAction.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/PrintScreenAction.java index 86671a4936..8558af6d1d 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/PrintScreenAction.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/PrintScreenAction.java @@ -27,7 +27,6 @@ import java.awt.image.ComponentColorModel; import java.awt.image.IndexColorModel; import java.awt.image.WritableRaster; -import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.swt.graphics.GC; @@ -46,6 +45,8 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -65,7 +66,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * @author chammack * @version 1 */ -public class PrintScreenAction extends AbstractHandler { +public class PrintScreenAction extends AbstractScreenCaptureAction { /* * (non-Javadoc) @@ -88,17 +89,68 @@ public class PrintScreenAction extends AbstractHandler { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getShell(); + IDescriptor desc = editor.getActiveDisplayPane().getDescriptor(); + // display the printer dialog to get print options PrintDialog pd = new PrintDialog(shell); + String frameMode = event.getParameter("frameSelection"); + if (frameMode == null || frameMode.equalsIgnoreCase("current")) { + // selection doesn't seem to work. + pd.setScope(PrinterData.PAGE_RANGE); + pd.setStartPage(desc.getFramesInfo().getFrameIndex() + 1); + pd.setEndPage(desc.getFramesInfo().getFrameIndex() + 1); + } else if (frameMode.equalsIgnoreCase("all")) { + pd.setScope(PrinterData.ALL_PAGES); + } else { + throw new ExecutionException("Invalid frameMode: " + frameMode); + } PrinterData printerData = pd.open(); if (printerData == null) { return null; } - BufferedImage bi = editor.screenshot(); - Display display = editor.getActiveDisplayPane().getDisplay(); Printer printer = new Printer(printerData); + if (printer.startJob("CAVE")) { + switch (pd.getScope()) { + case PrinterData.ALL_PAGES: { + try { + for (BufferedImage bi : captureAllFrames(editor)) { + printImage(printer, display, bi); + } + } catch (VizException e) { + throw new ExecutionException( + "Error occurred while writing image", e); + } + break; + } + case PrinterData.PAGE_RANGE: { + try { + for (BufferedImage bi : captureFrames(editor, + pd.getStartPage() - 1, pd.getEndPage())) { + printImage(printer, display, bi); + } + } catch (VizException e) { + throw new ExecutionException( + "Error occurred while writing image", e); + } + break; + } + case PrinterData.SELECTION: { + BufferedImage bi = editor.screenshot(); + printImage(printer, display, bi); + break; + } + } + printer.endJob(); + + } + printer.dispose(); + + return null; + } + + private void printImage(Printer printer, Display display, BufferedImage bi) { Point screenDPI = display.getDPI(); Point printerDPI = printer.getDPI(); @@ -152,27 +204,20 @@ public class PrintScreenAction extends AbstractHandler { offset.x += printArea.width - (imageBounds.width) * scaleX; } - if (printer.startJob("CAVE")) { - if (printer.startPage()) { - GC gc = new GC(printer); - Transform transform = new Transform(gc.getDevice()); - transform.translate(offset.x, offset.y); - transform.scale(scaleX, scaleY); - gc.setTransform(transform); + if (printer.startPage()) { + GC gc = new GC(printer); + Transform transform = new Transform(gc.getDevice()); + transform.translate(offset.x, offset.y); + transform.scale(scaleX, scaleY); + gc.setTransform(transform); - gc.drawImage(image, 0, 0); + gc.drawImage(image, 0, 0); - transform.dispose(); - gc.dispose(); - printer.endPage(); - printer.endJob(); - } + transform.dispose(); + gc.dispose(); + printer.endPage(); } - image.dispose(); - printer.dispose(); - - return null; } @@ -228,15 +273,4 @@ public class PrintScreenAction extends AbstractHandler { } return null; } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() - */ - @Override - public void dispose() { - - } - } diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/SaveScreenAction.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/SaveScreenAction.java index ddd2359490..a249b7feef 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/SaveScreenAction.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/SaveScreenAction.java @@ -26,12 +26,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; +import java.util.List; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.stream.FileImageOutputStream; -import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.swt.SWT; @@ -43,6 +43,7 @@ import org.eclipse.ui.PlatformUI; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -60,7 +61,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * @author chammack * @version 1 */ -public class SaveScreenAction extends AbstractHandler { +public class SaveScreenAction extends AbstractScreenCaptureAction { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(SaveScreenAction.class); @@ -116,6 +117,7 @@ public class SaveScreenAction extends AbstractHandler { } String suffix = path.substring(path.lastIndexOf('.') + 1); + String basePath = path.substring(0, path.lastIndexOf('.')); Iterator iter = ImageIO.getImageWritersBySuffix(suffix); if (!iter.hasNext()) { String reason = "Unsupported filetype: \"" + suffix + "\""; @@ -125,15 +127,48 @@ public class SaveScreenAction extends AbstractHandler { } ImageWriter writer = iter.next(); - BufferedImage bi = editor.screenshot(); + String frameMode = arg0.getParameter("frameSelection"); - try { - writer.setOutput(new FileImageOutputStream(new File(path))); - writer.write(bi); - } catch (IOException e) { - String reason = "Error occurred while writing image"; - statusHandler.handle(Priority.PROBLEM, reason, e); - throw new ExecutionException(reason, e); + if (frameMode == null || frameMode.equalsIgnoreCase("current")) { + BufferedImage bi = editor.screenshot(); + + try { + writer.setOutput(new FileImageOutputStream(new File(path))); + writer.write(bi); + } catch (IOException e) { + String reason = "Error occurred while writing image"; + statusHandler.handle(Priority.PROBLEM, reason, e); + throw new ExecutionException(reason, e); + } + } else if (frameMode.equalsIgnoreCase("all")) { + List images = null; + try { + images = captureAllFrames(editor); + } catch (VizException e) { + String reason = "Error occurred while writing image"; + statusHandler.handle(Priority.PROBLEM, reason, e); + throw new ExecutionException(reason, e); + } + + for (int i = 0; i < images.size(); i++) { + + BufferedImage bi = images.get(i); + + path = basePath + "-" + (i + 1) + "." + suffix; + + try { + writer.setOutput(new FileImageOutputStream(new File(path))); + writer.write(bi); + } catch (IOException e) { + String reason = "Error occurred while writing image"; + statusHandler.handle(Priority.PROBLEM, reason, e); + throw new ExecutionException(reason, e); + } + } + } else { + String reason = "Invalid frameMode: " + frameMode; + statusHandler.handle(Priority.PROBLEM, reason); + throw new ExecutionException(reason); } return null; }