/**
* Copyright (C) 2008-2010 Daniel Senff
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package de.danielsenff.imageflow.tasks;
import ij.IJ;
import ij.ImageJ;
import ij.ImagePlus;
import ij.plugin.Macro_Runner;
import org.jdesktop.application.Application;
import de.danielsenff.imageflow.ImageFlow;
import de.danielsenff.imageflow.controller.GraphController;
import de.danielsenff.imageflow.imagej.MacroGenerator.ImageJResult;
import de.danielsenff.imageflow.models.connection.Output;
import de.danielsenff.imageflow.models.datatype.ImageDataType;
import de.danielsenff.imageflow.models.unit.UnitElement;
/**
* Task to Run the current workflow.
* @author Daniel Senff
*
*/
public class RunMacroTask extends GenerateMacroTask {
private boolean closeAll;
private boolean showImageJ;
/**
* ProgressObserver is a workaround.
* We get the status of the progress from ImageJ from a static class.
* We need to convert this to a synchronized object to
* be able to get the status in realtime.
*/
private static CallbackObserver callbackObserver;
/**
* @param app
* @param graphController
* @param showImageJ
* @param showCode
* @param closeAll
* @param silent
*/
public RunMacroTask(final Application app,
final GraphController graphController,
final boolean showImageJ,
final boolean showCode,
final boolean closeAll,
final boolean silent) {
super(app, graphController);
this.showCode = showCode;
this.showImageJ = showImageJ;
this.closeAll = closeAll;
this.silent = silent;
MacroCallbackListener listener = new MacroCallbackListener();
callbackObserver = new CallbackObserver(listener);
}
/**
* @param app
* @param graphController
* @param showCode
*/
public RunMacroTask(final Application app,
final GraphController graphController,
final boolean showCode) {
this(app, graphController, true, showCode, false, false);
}
@Override
protected String doInBackground() throws InterruptedException {
setMessage("Translating workflow... ");
// create macro
String macro = super.doInBackground();
setMessage("Executing Macro...");
System.out.println(macro);
// if the graph checks turn out false, the resulting macro will be just a null-pointer
if(macro != null) {
if(closeAll) {
String closeAllCommand = "while (nImages>0) { \n selectImage(nImages);\n close(); } ";
macro = closeAllCommand + macro;
}
ImageFlow imageFlow = (ImageFlow)ImageFlow.getInstance();
ImageJ imagej = imageFlow.getImageJInstance();
/*Macro_Runner mr = new Macro_Runner();
String resultString = mr.runMacro(macro, "");*/
IJ.runMacro(macro);
for (ImageJResult result : openedImages) {
Output parentOutput = result.parentOutput;
if (parentOutput.getDataType() instanceof ImageDataType) {
IJ.selectWindow(parentOutput.getDisplayName());
ImagePlus ip = IJ.getImage();
if (ip != null) {
UnitElement unitElement = (UnitElement) result.node;
unitElement.setIconScaled(ip.getImage());
}
}
}
imageFlow.setImageJVisible(this.showImageJ);
}
return macro;
}
/**
* Sets the current value of the ProgressBar. The parameter must be of type String
* to meet the demands of the macro call() function
* @param progress must be between 0.0 and 1.0
*/
public static void setProgress(String progress) {
float progressValue = Float.valueOf(progress).floatValue();
if (progressValue < 0) {progressValue = 0.0f;}
else if(progressValue > 1) {progressValue = 1.0f;}
callbackObserver.setProgressValue(progressValue);
}
public static void setOutputData(int nodeID, int outputID, double data) {
// write the data as DataObject for the output of the given ID
callbackObserver.setOutputData(nodeID, outputID, data);
}
public static void setOutputData(int nodeID, int outputID, int data) {
// write the data as DataObject for the output of the given ID
callbackObserver.setOutputData(nodeID, outputID, data);
}
public static void setOutputData(int nodeID, int outputID, String data) {
// write the data as DataObject for the output of the given ID
callbackObserver.setOutputData(nodeID, outputID, data);
}
/**
* Does not need to pass the object as an argument. Takes the current
* selected Image from ImageJ.
* @param nodeID
* @param outputId
*/
public static void setOutputImage(int nodeID, int outputID) {
// get ImagePlus by imageTitle from ImageJ instance
ImagePlus ip = IJ.getImage();
callbackObserver.setOutputData(nodeID, outputID, ip);
}
@Override protected void succeeded(final Object superclass) {
setMessage("Done");
}
@Override protected void cancelled() {
setMessage("Canceled");
}
private class MacroCallbackListener {
public void fireProgressChanged(float value) {
setProgress(value);
}
public void fireOutputData(int nodeID, int outputID, Object data) {
graphController.setOutputData(nodeID, outputID, data);
}
}
static class CallbackObserver {
MacroCallbackListener progListener;
public CallbackObserver(MacroCallbackListener listener) {
this.progListener = listener;
}
public void setProgressValue(float progressValue) {
progListener.fireProgressChanged(progressValue);
}
public void setOutputData(int nodeID, int outputID, Object data) {
progListener.fireOutputData(nodeID, outputID, data);
}
}
}