Issue #235 Ability to screen capture or print multiple frames at once.

Change-Id: I58176883e701fbe0d9e0bcc0e43b60bd5c0053a7

Former-commit-id: 9062fe4b8fdb62840b21aba7c648f48fa691986a
This commit is contained in:
Ben Steffensmeier 2012-02-07 15:33:23 -06:00
parent e79aa3bfa1
commit c74dae631e
5 changed files with 253 additions and 43 deletions

View file

@ -112,6 +112,37 @@
commandId="com.raytheon.viz.ui.loadSerialized"
label="Load Displays..."
style="push">
</command>
<separator
name="afterSerialized"
visible="true">
</separator>
<command
commandId="com.raytheon.viz.ui.actions.printScreenAction"
label="Print Screen"
style="push">
<parameter
name="frameSelection"
value="current">
</parameter>
</command>
<command
commandId="com.raytheon.viz.ui.actions.saveScreen"
label="Capture Current Frame"
style="push">
<parameter
name="frameSelection"
value="current">
</parameter>
</command>
<command
commandId="com.raytheon.viz.ui.actions.saveScreen"
label="Capture All Frames"
style="push">
<parameter
name="frameSelection"
value="all">
</parameter>
</command>
</menu>
<separator

View file

@ -207,6 +207,11 @@
categoryId="com.raytheon.uf.viz.core.commandCategory"
description="Print the currently active editor"
name="Print Screen">
<commandParameter
id="frameSelection"
name="Frame Selection"
optional="true">
</commandParameter>
</command>
<command
id="com.raytheon.viz.ui.newPage"
@ -217,7 +222,12 @@
categoryId="com.raytheon.uf.viz.core.commandCategory"
description="Save the current screen"
name="Save Screen">
</command>
<commandParameter
id="frameSelection"
name="Frame Selection"
optional="true">
</commandParameter>
</command>
<command
id="com.raytheon.viz.ui.actions.notImplemented"
name="Not Implemented">

View file

@ -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<BufferedImage> captureAllFrames(AbstractEditor editor)
throws VizException {
int startIndex = 0;
int endIndex = editor.getActiveDisplayPane().getDescriptor()
.getFramesInfo().getFrameCount();
return captureFrames(editor, startIndex, endIndex);
}
protected List<BufferedImage> captureFrames(AbstractEditor editor,
int startIndex, int endIndex) throws VizException {
if (startIndex < 0) {
startIndex = 0;
}
List<BufferedImage> images = new ArrayList<BufferedImage>(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);
}
}
}

View file

@ -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() {
}
}

View file

@ -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<ImageWriter> 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<BufferedImage> 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;
}