package ij.plugin.frame;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import ij.*;
import ij.plugin.*;
import ij.plugin.frame.*;
import ij.text.*;
import ij.gui.*;
import ij.util.*;
import ij.io.*;
import ij.process.*;
import ij.measure.*;
public class Recorder extends PlugInFrame implements PlugIn, ActionListener, ImageListener, ItemListener {
public static boolean record;
public static boolean recordInMacros;
private final static int MACRO=0, JAVASCRIPT=1, BEANSHELL=2, PYTHON=3, JAVA=4;
private final static String[] modes = {"Macro", "JavaScript", "BeanShell", "Python", "Java"};
private Choice mode;
private Button makeMacro, help;
private TextField fileName;
private String fitTypeStr = CurveFitter.fitList[0];
private static TextArea textArea;
private static Recorder instance;
private static String commandName;
private static String commandOptions;
private static String defaultName = "Macro.ijm";
private static boolean recordPath = true;
private static boolean scriptMode;
private static boolean imageUpdated;
private static int imageID;
private static boolean fgColorSet, bgColorSet;
private static boolean bbSet;
public Recorder() {
this(true);
}
public Recorder(boolean showFrame) {
super("Recorder");
if (instance!=null) {
WindowManager.toFront(instance);
return;
}
WindowManager.addWindow(this);
instance = this;
record = true;
scriptMode = false;
recordInMacros = false;
Panel panel = new Panel(new FlowLayout(FlowLayout.LEFT, 0, 0));
panel.add(new Label(" Record:"));
mode = new Choice();
for (int i=0; i<modes.length; i++)
mode.addItem(modes[i]);
mode.addItemListener(this);
String m = Prefs.get("recorder.mode", modes[MACRO]);
if (m.equals("Plugin")) m=modes[JAVA];
mode.select(m);
panel.add(mode);
panel.add(new Label(" Name:"));
fileName = new TextField(defaultName, 15);
setFileName();
panel.add(fileName);
panel.add(new Label(" "));
makeMacro = new Button("Create");
makeMacro.addActionListener(this);
panel.add(makeMacro);
panel.add(new Label(" "));
help = new Button("?");
help.addActionListener(this);
panel.add(help);
add("North", panel);
textArea = new TextArea("", 15, 80, TextArea.SCROLLBARS_VERTICAL_ONLY);
textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
if (IJ.isLinux()) textArea.setBackground(Color.white);
add("Center", textArea);
GUI.scale(this);
pack();
GUI.centerOnImageJScreen(this);
if (showFrame)
show();
IJ.register(Recorder.class);
fgColorSet = bgColorSet = false;
bbSet = false;
}
public static void record(String method) {
if (textArea==null)
return;
textArea.append(method+"();\n");
}
public static void setCommand(String command) {
String threadName = Thread.currentThread().getName();
boolean isMacro = threadName.startsWith("Run$_");
if (threadName.contains("Popup Menu") || threadName.contains("Developer Menu"))
isMacro = false;
if (textArea==null || (isMacro&&!recordInMacros))
return;
commandName = command;
commandOptions = null;
recordPath = true;
imageUpdated = false;
imageID = 0;
if (scriptMode) {
ImagePlus imp = WindowManager.getCurrentImage();
imageID = imp!=null?imp.getID():0;
if (imageID!=0)
ImagePlus.addImageListener(instance);
}
}
public static String getCommand() {
return commandName;
}
public static String fixPath (String path) {
if (path==null)
path = "";
if (!IJ.isWindows())
return path;
StringBuilder sb = new StringBuilder();
for (int i=0; i<path.length(); i++) {
char c=path.charAt(i);
if (c=='\\')
sb.append("/");
else
sb.append(c);
}
return new String(sb);
}
public static String fixString (String str) {
StringBuilder sb = new StringBuilder();
char c;
for (int i=0; i<str.length(); i++) {
c = str.charAt(i);
if (c =='\\' || c=='"')
sb.append("\\"+c);
else if (c == '\n')
sb.append("\\n");
else if (c < ' ' || c > '~' && c < 0xa0) {
sb.append('\\');
String octal = Integer.toString(c,8);
while (octal.length()<3)
octal = '0' + octal;
sb.append(octal);
} else
sb.append(c);
}
return new String(sb);
}
public static void record(String method, String arg) {
if (IJ.debugMode) IJ.log("record: "+method+" "+arg);
boolean sw = method.equals("selectWindow");
if (textArea!=null && !(scriptMode&&sw||commandName!=null&&sw)) {
if (scriptMode && method.equals("roiManager"))
textArea.append("rm.runCommand(imp,\""+arg+"\");\n");
else if (scriptMode && method.equals("run"))
textArea.append("IJ."+method+"(\""+arg+"\");\n");
else {
if (method.equals("setTool"))
method = "//"+(scriptMode?"IJ.":"")+method;
textArea.append(method+"(\""+arg+"\");\n");
}
}
}
public static void record(String method, String arg1, String arg2) {
if (textArea==null) return;
if (arg1.equals("Open")||arg1.equals("Save")||method.equals("saveAs"))
arg2 = fixPath(arg2);
if (scriptMode&&method.equals("roiManager"))
textArea.append("rm.runCommand(\""+arg1+"\", \""+arg2+"\");\n");
else {
if (scriptMode && method.equals("saveAs"))
method = "IJ." + method;
textArea.append(method+"(\""+arg1+"\", \""+arg2+"\");\n");
}
}
public static void record(String method, String arg1, String arg2, String arg3) {
if (textArea==null) return;
textArea.append(method+"(\""+arg1+"\", \""+arg2+"\",\""+arg3+"\");\n");
}
public static void record(String method, int a1) {
if (textArea==null) return;
textArea.append(method+"("+a1+");\n");
}
public static void record(String method, int a1, int a2) {
if (textArea==null) return;
textArea.append(method+"("+a1+", "+a2+");\n");
}
public static void record(String method, int a1, int a2, String a3) {
if (textArea==null) return;
textArea.append(method+"("+a1+", "+a2+", \""+a3+"\");\n");
}
public static void record(String method, double a1, double a2) {
if (textArea==null) return;
int places = Math.abs(a1)<0.0001||Math.abs(a2)<0.0001?9:4;
textArea.append(method+"("+IJ.d2s(a1,places)+", "+IJ.d2s(a2,places)+");\n");
}
public static void record(String method, int a1, int a2, int a3) {
if (textArea==null) return;
if (scriptMode&&method.endsWith("groundColor")) method = "IJ."+method;
textArea.append(method+"("+a1+", "+a2+", "+a3+");\n");
}
public static void record(String method, String a1, int a2) {
textArea.append(method+"(\""+a1+"\", "+a2+");\n");
}
public static void record(String method, String args, int a1, int a2) {
if (textArea==null) return;
textArea.append(method+"(\""+args+"\", "+a1+", "+a2+");\n");
}
public static void record(String method, int a1, int a2, int a3, int a4) {
if (textArea==null) return;
if (scriptMode&&method.startsWith("make")) {
if (method.equals("makeRectangle"))
recordString("imp.setRoi("+a1+","+a2+","+a3+","+a4+");\n");
else if (method.equals("makeOval"))
recordString("imp.setRoi(new OvalRoi("+a1+","+a2+","+a3+","+a4+"));\n");
else if (method.equals("makeLine"))
recordString("imp.setRoi(new Line("+a1+","+a2+","+a3+","+a4+"));\n");
else if (method.equals("makeArrow"))
recordString("imp.setRoi(new Arrow("+a1+","+a2+","+a3+","+a4+"));\n");
} else {
if (method.equals("makeArrow")) {
ImagePlus imp = WindowManager.getCurrentImage();
Roi roi = imp!=null?imp.getRoi():null;
if (roi!=null && (roi instanceof Line)) {
Arrow arrow = (Arrow)roi;
String options = Arrow.styles[arrow.getStyle()];
if (arrow.getOutline())
options += " outline";
if (arrow.getDoubleHeaded())
options += " double";
if (arrow.getHeadSize()<=5)
options += " small";
else if (arrow.getHeadSize()>=15)
options += " large";
options = options.toLowerCase();
int strokeWidth = (int)arrow.getStrokeWidth();
textArea.append(method+"("+a1+", "+a2+", "+a3+", "+a4+", \""+options+"\");\n");
if (strokeWidth!=1)
textArea.append("Roi.setStrokeWidth("+strokeWidth+");\n");
Color color = arrow.getStrokeColor();
if (color!=null)
textArea.append("Roi.setStrokeColor(\""+Colors.colorToString(color)+"\");\n");
return;
}
}
textArea.append(method+"("+a1+", "+a2+", "+a3+", "+a4+");\n");
}
}
public static void record(String method, int a1, int a2, int a3, int a4, int a5) {
textArea.append(method+"("+a1+", "+a2+", "+a3+", "+a4+", "+a5+");\n");
}
public static void record(String method, int a1, int a2, int a3, int a4, double a5) {
textArea.append(method+"("+a1+", "+a2+", "+a3+", "+a4+", "+IJ.d2s(a5,2)+");\n");
}
public static void record(String method, String path, String args, int a1, int a2, int a3, int a4, int a5) {
if (textArea==null)
return;
path = fixPath(path);
method = "//"+method;
textArea.append(method+"(\""+path+"\", "+"\""+args+"\", "+a1+", "+a2+", "+a3+", "+a4+", "+a5+");\n");
}
public static void recordString(String str) {
if (textArea!=null)
textArea.append(str);
}
public static void disableCommandRecording() {
commandName = null;
}
public static void recordCall(String call) {
recordCall(call, false);
}
public static void recordCall(String call, boolean recordCommand) {
if (IJ.debugMode) IJ.log("recordCall: "+call+" "+commandName);
boolean isMacro = Thread.currentThread().getName().endsWith("Macro$") && !recordInMacros;
if (textArea!=null && scriptMode && !IJ.macroRunning() && !isMacro) {
if (javaMode() && call.startsWith("rm.setSelected")) {
call = call.replace("[", "new int[]{");
call = call.replace("])", "})");
}
if (javaMode() && call.startsWith("rt = "))
call = "ResultTable " + call;
textArea.append(call+"\n");
if (!recordCommand)
commandName = null;
}
}
public static void recordCall(String className, String call) {
recordCall(javaMode()?className+" "+call:call);
}
public static void recordRoi(Roi roi) {
if (roi==null)
return;
Polygon polygon = roi.getPolygon();
recordRoi(polygon, roi.getType());
}
public static void recordRoi(Polygon p, int type) {
if (textArea==null)
return;
if (scriptMode)
{recordScriptRoi(p,type); return;}
if (type==Roi.ANGLE||type==Roi.POINT) {
String xarr = "newArray(", yarr="newArray(";
xarr += p.xpoints[0]+",";
yarr += p.ypoints[0]+",";
xarr += p.xpoints[1]+",";
yarr += p.ypoints[1]+",";
xarr += p.xpoints[2]+")";
yarr += p.ypoints[2]+")";
String typeStr= type==Roi.ANGLE?"angle":"point";
textArea.append("makeSelection(\""+typeStr+"\","+xarr+","+yarr+");\n");
} else {
String method = type>=Roi.LINE && type<=Roi.FREELINE?"makeLine":"makePolygon";
StringBuffer args = new StringBuffer();
for (int i=0; i<p.npoints; i++) {
args.append(p.xpoints[i]+",");
args.append(""+p.ypoints[i]);
if (i!=p.npoints-1) args.append(",");
}
textArea.append(method+"("+args.toString()+");\n");
}
}
public static void recordScriptRoi(Polygon p, int type) {
StringBuffer x = new StringBuffer();
for (int i=0; i<p.npoints; i++) {
x.append(p.xpoints[i]);
if (i!=p.npoints-1) x.append(",");
}
String xpoints = x.toString();
StringBuffer y = new StringBuffer();
for (int i=0; i<p.npoints; i++) {
y.append(p.ypoints[i]);
if (i!=p.npoints-1) y.append(",");
}
String ypoints = y.toString();
if (javaMode()) {
textArea.append("int[] xpoints = {"+xpoints+"};\n");
textArea.append("int[] ypoints = {"+ypoints+"};\n");
} else {
textArea.append("xpoints = ["+xpoints+"];\n");
textArea.append("ypoints = ["+ypoints+"];\n");
}
String typeStr = "POLYGON";
switch (type) {
case Roi.POLYLINE: typeStr = "POLYLINE"; break;
case Roi.ANGLE: typeStr = "ANGLE"; break;
}
typeStr = "Roi."+typeStr;
if (javaMode()) {
if (type==Roi.POINT)
textArea.append("imp.setRoi(new PointRoi(xpoints,ypoints,"+p.npoints+"));\n");
else
textArea.append("imp.setRoi(new PolygonRoi(xpoints,ypoints,"+p.npoints+","+typeStr+"));\n");
} else {
if (type==Roi.POINT)
textArea.append("imp.setRoi(new PointRoi(xpoints,ypoints));\n");
else
textArea.append("imp.setRoi(new PolygonRoi(xpoints,ypoints,"+typeStr+"));\n");
}
}
private static boolean javaMode() {
if (instance==null)
return false;
String m = instance.mode.getSelectedItem();
return m.equals(modes[BEANSHELL]) || m.equals(modes[JAVA]);
}
public static void recordOption(String key, String value) {
if (key==null) return;
key = fixString(key);
key = trimKey(key);
value = addQuotes(value);
checkForDuplicate(key+"=", value);
if (commandOptions==null)
commandOptions = key+"="+value;
else
commandOptions += " "+key+"="+value;
}
public static void recordOpen(String path) {
if (!record || path==null)
return;
path = fixPath(path);
String s = scriptMode?"imp = IJ.openImage":"open";
boolean openingLut = false;
if (scriptMode) {
if (isTextOrTable(path))
s = "IJ.open";
else if (path!=null && path.endsWith(".lut")) {
s = "lut = Opener.openLut";
openingLut = true;
}
}
textArea.append(s+"(\""+path+"\");\n");
ImagePlus imp = WindowManager.getCurrentImage();
if (openingLut && imp!=null && !imp.getTitle().endsWith(".lut"))
textArea.append("imp.setLut(lut);\n");
}
public static void recordPath(String key, String path) {
if (key==null || !recordPath) {
recordPath = true;
return;
}
key = trimKey(key);
path = fixPath(path);
path = addQuotes(path);
if (commandOptions!=null && commandOptions.contains(key+"="+path))
return; checkForDuplicate(key+"=", path);
if (commandOptions==null || commandOptions==" ")
commandOptions = key+"="+path;
else
commandOptions += " "+key+"="+path;
}
public static void recordOption(String key) {
if (key==null) return;
if (commandOptions==null && key.equals(" "))
commandOptions = " ";
else {
key = trimKey(key);
checkForDuplicate(" "+key, "");
if (commandOptions==null || commandOptions==" ")
commandOptions = key;
else
commandOptions += " "+key;
}
}
static void checkForDuplicate(String key, String value) {
if (commandOptions!=null && commandName!=null && commandOptions.indexOf(key)!=-1 && (value.equals("") || commandOptions.indexOf(value)==-1)) {
if (key.endsWith("=")) key = key.substring(0, key.length()-1);
IJ.showMessage("Recorder", "Duplicate keyword:\n \n"
+ " Command: " + "\"" + commandName +"\"\n"
+ " Keyword: " + "\"" + key +"\"\n"
+ " Value: " + value+"\n \n"
+ "Add an underscore to the corresponding label\n"
+ "in the dialog to make the first word unique.");
}
}
static String trimKey(String key) {
int index = key.indexOf(" ");
if (index>-1)
key = key.substring(0,index);
index = key.indexOf(":");
if (index>-1)
key = key.substring(0,index);
key = key.toLowerCase(Locale.US);
return key;
}
public static void saveCommand() {
String name = commandName;
ImagePlus imp = WindowManager.getCurrentImage();
if (name!=null) {
if (name.equals("Duplicate Image..."))
name = "Duplicate...";
if (name.equals("Make Binary") && imp!=null && imp.getStackSize()==1) {
name = "Convert to Mask";
commandOptions = null;
}
if (commandOptions==null && (name.equals("Fill")||name.equals("Clear")||name.equals("Draw"))) {
Roi roi = imp!=null?imp.getRoi():null;
if (!(roi!=null && (roi instanceof TextRoi) && (name.equals("Draw"))))
commandOptions = "slice";
}
if (!fgColorSet && (name.equals("Fill")||name.equals("Draw")))
setForegroundColor(Toolbar.getForegroundColor());
else if (!bgColorSet && (name.equals("Clear")||name.equals("Clear Outside")))
setBackgroundColor(Toolbar.getBackgroundColor());
if (!bbSet && (name.equals("Convert to Mask")||name.equals("Erode")
||name.equals("Dilate")||name.equals("Skeletonize")))
setBlackBackground();
if (name.equals("Add Shortcut by Name... "))
name = "Add Shortcut... ";
if (commandOptions!=null) {
if (name.equals("Open...") || name.equals("URL..."))
recordOpen(strip(commandOptions));
else if (name.equals("TIFF Virtual Stack...") && scriptMode) {
String s = "imp = IJ.openVirtual";
String path = strip(commandOptions);
textArea.append(s+"(\""+path+"\");\n");
} else if (isSaveAs()) {
if (name.endsWith("..."))
name= name.substring(0, name.length()-3);
if (name.equals("Save"))
name = "Tiff";
String path = strip(commandOptions);
String s = scriptMode?"IJ.saveAs(imp, ":"saveAs(";
textArea.append(s+"\""+name+"\", \""+path+"\");\n");
} else if (name.equals("Image..."))
appendNewImage(false);
else if (name.equals("Hyperstack...")||name.equals("New Hyperstack..."))
appendNewImage(true);
else if (name.equals("Set Slice..."))
textArea.append((scriptMode?"imp.":"")+"setSlice("+strip(commandOptions)+");\n");
else if (name.equals("Rename..."))
textArea.append((scriptMode?"imp.setTitle":"rename")+"(\""+strip(commandOptions)+"\");\n");
else if (name.equals("Wand Tool..."))
textArea.append("//run(\""+name+"\", \""+commandOptions+"\");\n");
else if (name.equals("Results... ")&&commandOptions.indexOf(".txt")==-1)
textArea.append((scriptMode?"IJ.":"")+"open(\""+strip(commandOptions)+"\");\n");
else if (name.equals("Results...")) ;
else if (name.equals("Run...")) ;
else if (scriptMode && name.equals("Text Image... ")) ;
else {
if (name.equals("Calibrate...")) {
if (commandOptions.startsWith("function=None unit=[Gray Value]"))
commandOptions = commandOptions.substring(0,13);
else if (commandOptions.startsWith("function=None")) {
int index = commandOptions.indexOf(" text1=");
if (index>0)
commandOptions = commandOptions.substring(0,index);
}
}
String prefix = "run(";
if (scriptMode) {
boolean addImp = imageUpdated || (WindowManager.getCurrentImage()!=null
&&(name.equals("Properties... ")||name.equals("Fit Spline")||commandOptions.contains("save=")));
if (commandOptions.contains("open="))
addImp = false;
prefix = addImp?"IJ.run(imp, ":"IJ.run(";
}
textArea.append(prefix+"\""+name+"\", \""+commandOptions+"\");\n");
if (nonAscii(commandOptions)) {
if (commandOptions!=null && !commandOptions.contains("="+IJ.micronSymbol+"m"))
textArea.append(" <<warning: the options string contains one or more non-ascii characters>>\n");
}
}
} else {
Roi roi = imp!=null?imp.getRoi():null;
if (name.equals("Threshold...") || name.equals("Fonts...") || name.equals("Brightness/Contrast...") || name.equals("Channels Tool..."))
textArea.append((scriptMode?"//IJ.":"//")+"run(\""+name+"\");\n");
else if (name.equals("Start Animation [\\]"))
textArea.append("doCommand(\"Start Animation [\\\\]\");\n");
else if (name.equals("Blobs"))
textArea.append("run(\"Blobs (25K)\");\n");
else if (name.equals("Split Channels") && scriptMode) {
String text = "channels = ChannelSplitter.split(imp);\n";
if (javaMode())
text = "ImagePlus[] " + text;
textArea.append(text);
} else if (name.equals("Add to Manager"))
;
else if (name.equals("Find Commands..."))
;
else if (scriptMode && name.equals("Create Mask"))
;
else if (roi!=null && (roi instanceof TextRoi) && (name.equals("Draw")||name.equals("Add Selection...")))
textArea.append(((TextRoi)roi).getMacroCode(name, imp));
else {
if (IJ.altKeyDown() && (name.equals("Open Next")||name.equals("Plot Profile")))
textArea.append("setKeyDown(\"alt\"); ");
if (scriptMode) {
boolean addImp = imageUpdated ||
(imp!=null&&(name.equals("Select None")||name.equals("Draw")||name.equals("Fit Spline")||name.equals("Add Selection...")));
String prefix = addImp?"IJ.run(imp, ":"IJ.run(";
textArea.append(prefix+"\""+name+"\", \"\");\n");
} else
textArea.append("run(\""+name+"\");\n");
}
}
}
commandName = null;
commandOptions = null;
if (imageID!=0) {
ImagePlus.removeImageListener(instance);
imageID = 0;
}
}
private static boolean nonAscii(String s) {
int len = s!=null?s.length():0;
for (int i=0; i<len; i++) {
if (s.charAt(i)>127)
return true;
}
return false;
}
static boolean isTextOrTable(String path) {
return path.endsWith(".txt") || path.endsWith(".csv") || path.endsWith(".xls") || path.endsWith(".tsv");
}
static boolean isSaveAs() {
return commandName.equals("Tiff...")
|| commandName.equals("Gif...")
|| commandName.equals("Jpeg...")
|| commandName.equals("Text Image...")
|| commandName.equals("ZIP...")
|| commandName.equals("Raw Data...")
|| commandName.equals("BMP...")
|| commandName.equals("PNG...")
|| commandName.equals("PGM...")
|| commandName.equals("FITS...")
|| commandName.equals("LUT...")
|| commandName.equals("Selection...")
|| commandName.equals("XY Coordinates...")
|| commandName.equals("Text... ")
|| commandName.equals("Save");
}
static void appendNewImage(boolean hyperstack) {
String options = getCommandOptions() + " ";
String title = Macro.getValue(options, "name", "Untitled");
String type = Macro.getValue(options, "type", "8-bit");
String fill = Macro.getValue(options, "fill", "");
if (!fill.equals(""))
type = type +" " + fill.toLowerCase();
if (hyperstack) {
String mode = Macro.getValue(options, "display", "");
if (!mode.equals(""))
type = type +" " + mode.toLowerCase() + "-mode";
if (options.contains(" label"))
type = type +" label";
}
int width = (int)Tools.parseDouble(Macro.getValue(options, "width", "512"));
int height = (int)Tools.parseDouble(Macro.getValue(options, "height", "512"));
String d1= ", " + (int)Tools.parseDouble(Macro.getValue(options, "slices", "1"));
String d2="", d3="";
if (hyperstack) {
d1 = ", " + (int)Tools.parseDouble(Macro.getValue(options, "channels", "1"));
d2 = ", " + (int)Tools.parseDouble(Macro.getValue(options, "slices", "1"));
d3 = ", " + (int)Tools.parseDouble(Macro.getValue(options, "frames", "1"));
}
textArea.append((scriptMode?"imp = IJ.createImage":"newImage")
+"(\""+title+"\", "+"\""+type+"\", "+width+", "+height+d1+d2+d3+");\n");
}
static String strip(String value) {
int index = value.indexOf('=');
if (index>=0)
value = value.substring(index+1);
if (value.startsWith("[")) {
int index2 = value.indexOf(']');
if (index2==-1) index2 = value.length();
value = value.substring(1, index2);
} else {
index = value.indexOf(' ');
if (index!=-1)
value = value.substring(0, index);
}
return value;
}
static String addQuotes(String value) {
if (value==null)
value = "";
int index = value.indexOf(' ');
if (index>-1)
value = "["+value+"]";
return value;
}
public static String getCommandOptions() {
return commandOptions;
}
public static void resetCommandOptions() {
commandOptions = null;
}
void createMacro() {
String text = textArea.getText();
if (text==null || text.equals("")) {
IJ.showMessage("Recorder", "A macro cannot be created until at least\none command has been recorded.");
return;
}
String name = fileName.getText();
Editor ed = new Editor(name);
boolean java = mode.getSelectedItem().equals(modes[JAVA]);
boolean beanshell = mode.getSelectedItem().equals(modes[BEANSHELL]);
boolean python = mode.getSelectedItem().equals(modes[PYTHON]);
int dotIndex = name.lastIndexOf(".");
if (scriptMode) { if (dotIndex>=0) name = name.substring(0, dotIndex);
if (text.indexOf("rm.")!=-1) {
text = (java?"RoiManager ":"")+ "rm = RoiManager.getRoiManager();\n"
+ text;
}
if (text.contains("overlay.add"))
text = (java?"Overlay ":"") + "overlay = new Overlay();\n" + text;
if ((text.contains("imp.")||text.contains("(imp")||text.contains("overlay.add")) && !text.contains("IJ.openImage")
&& !text.contains("IJ.openVirtual") && !text.contains("IJ.createImage"))
text = (java?"ImagePlus ":"") + "imp = IJ.getImage();\n" + text;
if (text.contains("overlay.add"))
text = text + "imp.setOverlay(overlay);\n";
if (text.indexOf("imp =")!=-1 && !(text.indexOf("IJ.getImage")!=-1||text.indexOf("IJ.saveAs")!=-1||text.indexOf("imp.close")!=-1))
text = text + "imp.show();\n";
if (python) {
text = text.replaceAll("new ", "");
text = text.replaceAll("\n//", "\n#");
}
if (java) {
name += ".java";
createPlugin(text, name);
return;
} else if (beanshell)
name += ".bsh";
else if (python)
name += ".py";
else
name += ".js";
} else { if (!name.endsWith(".txt")) {
if (dotIndex>=0) name = name.substring(0, dotIndex);
name += ".ijm";
}
}
ed.createMacro(name, text);
fgColorSet = bgColorSet = false;
bbSet = false;
}
void createPlugin(String text, String name) {
StringTokenizer st = new StringTokenizer(text, "\n");
int n = st.countTokens();
boolean impDeclared = false;
boolean lutDeclared = false;
String line;
StringBuffer sb = new StringBuffer();
for (int i=0; i<n; i++) {
line = st.nextToken();
if (line!=null && line.length()>3) {
sb.append("\t\t");
if (line.startsWith("imp =") && !impDeclared) {
sb.append("ImagePlus ");
impDeclared = true;
}
if (line.startsWith("lut =") && !lutDeclared) {
sb.append("LUT ");
lutDeclared = true;
}
sb.append(line);
sb.append('\n');
}
}
String text2 = new String(sb);
text2 = text2.replaceAll("print", "IJ.log");
NewPlugin np = (NewPlugin)IJ.runPlugIn("ij.plugin.NewPlugin", text2);
Editor ed = np.getEditor();
ed.updateClassName(ed.getTitle(), name);
ed.setTitle(name);
}
public static void disablePathRecording() {
recordPath = false;
}
public static boolean scriptMode() {
return scriptMode;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource()==makeMacro)
createMacro();
else if (e.getSource()==help)
showHelp();
}
public void itemStateChanged(ItemEvent e) {
setFileName();
Prefs.set("recorder.mode", mode.getSelectedItem());
}
void setFileName() {
String name = mode.getSelectedItem();
scriptMode = !name.equals(modes[MACRO]);
if (name.equals(modes[MACRO]))
fileName.setText("Macro.ijm");
else if (name.equals(modes[JAVASCRIPT]))
fileName.setText("Script.js");
else if (name.equals(modes[BEANSHELL]))
fileName.setText("Script.bsh");
else if (name.equals(modes[PYTHON]))
fileName.setText("Script.py");
else
fileName.setText("My_Plugin.java");
fgColorSet = bgColorSet = false;
bbSet = false;
}
public void imageUpdated(ImagePlus imp) {
if (imp.getID()==imageID)
imageUpdated = true;
}
public void imageOpened(ImagePlus imp) { }
public void imageClosed(ImagePlus imp) { }
void showHelp() {
IJ.showMessage("Recorder",
"Click \"Create\" to open recorded commands\n"
+"as a macro in an editor window.\n"
+" \n"
+"In the editor:\n"
+" \n"
+" Type ctrl+R (Macros>Run Macro) to\n"
+" run the macro.\n"
+" \n"
+" Use File>Save As to save it and\n"
+" ImageJ's Open command to open it.\n"
+" \n"
+" To create a command, save in the plugins\n"
+" folder and run Help>Refresh Menus.\n"
);
}
public void close() {
super.close();
record = false;
textArea = null;
commandName = null;
instance = null;
}
public String getText() {
if (textArea==null)
return "";
else
return textArea.getText();
}
public static Recorder getInstance() {
return instance;
}
public static void setForegroundColor(Color c) {
record("setForegroundColor", c.getRed(), c.getGreen(), c.getBlue());
fgColorSet = true;
}
public static void setBackgroundColor(Color c) {
record("setBackgroundColor", c.getRed(), c.getGreen(), c.getBlue());
bgColorSet = true;
}
public static void setBlackBackground() {
String bb = Prefs.blackBackground?"true":"false";
if (scriptMode)
recordString("Prefs.blackBackground = "+bb+";\n");
else
recordString("setOption(\"BlackBackground\", "+bb+");\n");
bbSet = true;
}
public void windowActivated(WindowEvent e) {
if (IJ.isMacintosh() && !IJ.isJava17())
this.setMenuBar(Menus.getMenuBar());
WindowManager.setWindow(this);
}
}