/*******************************************************************************
* Copyright (c) 2004, 2010 BREDEX GmbH.
* 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:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.rc.common.commands;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.lang.ref.WeakReference;
import org.eclipse.jubula.communication.internal.ICommand;
import org.eclipse.jubula.communication.internal.message.Message;
import org.eclipse.jubula.communication.internal.message.TakeScreenshotMessage;
import org.eclipse.jubula.communication.internal.message.TakeScreenshotResponseMessage;
import org.eclipse.jubula.rc.common.AUTServer;
import org.eclipse.jubula.rc.common.driver.IRobot;
import org.eclipse.jubula.rc.common.driver.RobotConfiguration;
import org.eclipse.jubula.rc.common.tester.adapter.interfaces.IComponent;
import org.eclipse.jubula.tools.internal.serialisation.SerializedImage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author BREDEX GmbH
* @created Apr 19, 2010
*/
public class TakeScreenshotCommand implements ICommand {
/**
* make sure line length % 2 != 0 so that the center of the square is the
* actual pointing device position
*/
private static final int TOTAL_LINE_LENGTH = 11;
/** the distance from the center of the square to its bounds */
private static final int LINE_LENGTH_PER_DIRECTION =
(TOTAL_LINE_LENGTH - 1) / 2;
/** Logger */
private static final Logger LOG = LoggerFactory
.getLogger(TakeScreenshotCommand.class);
/** message */
private TakeScreenshotMessage m_message;
/**
* {@inheritDoc}
*/
public Message execute() {
TakeScreenshotResponseMessage response =
new TakeScreenshotResponseMessage();
IRobot robot = AUTServer.getInstance()
.getRobot();
final BufferedImage createScreenCapture = robot
.createFullScreenCapture();
try {
Point currentPointingDevicePosition =
robot.getCurrentMousePosition();
if (currentPointingDevicePosition != null) {
final int pdX = currentPointingDevicePosition.x;
final int pdY = currentPointingDevicePosition.y;
final int xStart = pdX - LINE_LENGTH_PER_DIRECTION;
final int yStart = pdY - LINE_LENGTH_PER_DIRECTION;
for (int i = 0; i < TOTAL_LINE_LENGTH; i++) {
for (int j = 0; j < TOTAL_LINE_LENGTH; j++) {
invertPixelAtPoint(createScreenCapture, xStart + i,
yStart + j);
}
}
}
} catch (Exception e) {
// ignore so the mouse position will not be visible
}
if (RobotConfiguration.getInstance().isErrorHighlighting()) {
WeakReference<IComponent> errorComponent =
AUTServer.getInstance().getErrorComponent();
if (errorComponent != null) {
try {
highlightErrorComponent(errorComponent,
robot, createScreenCapture);
} catch (RuntimeException e) {
LOG.error("Highlighting component during screenshot failed", e); //$NON-NLS-1$
}
}
}
final SerializedImage computedSerializeImage = SerializedImage
.computeSerializeImage(createScreenCapture);
response.setScreenshot(computedSerializeImage);
return response;
}
/**
* @param weakRefError weak reference to the component at which an error occured
* @param robot the robot
* @param screenCapture the screeenshot that was taken
*/
private void highlightErrorComponent(
WeakReference<IComponent> weakRefError,
IRobot robot, BufferedImage screenCapture) {
IComponent errorComp = weakRefError.get();
IRobot roboter = robot;
if (errorComp != null) {
BufferedImage image = screenCapture;
Graphics2D graphic = image.createGraphics();
Color recColor = new Color(0, 128, 0);
graphic.setColor(recColor);
graphic.setStroke(new BasicStroke(3));
Rectangle recErrorComp = robot.getComponentBounds(errorComp);
if (recErrorComp != null) {
graphic.drawRect((int)recErrorComp.getX() - 2,
(int)recErrorComp.getY() - 2,
(int)recErrorComp.getWidth() + 2,
(int)recErrorComp.getHeight() + 2);
}
}
}
/**
* If the given coordinates are outside of the image nothing will be
* inverted
*
* @param image
* the image to modify
* @param x
* the coordinate
* @param y
* the coordinate
*/
private void invertPixelAtPoint(BufferedImage image, final int x,
final int y) {
if (x < 0 || y < 0) {
return;
}
if (x >= image.getWidth() || y >= image.getHeight()) {
return;
}
int rgb = image.getRGB(x, y);
Color origPxColor = new Color(rgb);
Color newPxColor = new Color(
255 - origPxColor.getRed(),
255 - origPxColor.getGreen(),
255 - origPxColor.getBlue());
image.setRGB(x, y, newPxColor.getRGB());
}
/**
* {@inheritDoc}
*/
public void timeout() {
LOG.error(this.getClass().getName() + ".timeout() called"); //$NON-NLS-1$
}
/**
* @param message
* the message to set
*/
public void setMessage(Message message) {
m_message = (TakeScreenshotMessage)message;
}
/**
* @return the message
*/
public Message getMessage() {
return m_message;
}
}