package ij;
import ij.util.Tools;
import ij.text.TextWindow;
import ij.plugin.MacroInstaller;
import ij.plugin.Duplicator;
import ij.plugin.frame.Recorder;
import ij.plugin.frame.Editor;
import ij.io.OpenDialog;
import java.io.*;
import java.util.*;
import java.awt.event.KeyEvent;
import java.awt.Menu;
import java.awt.GraphicsEnvironment;
public class Executer implements Runnable {
private static String previousCommand;
private static CommandListener listener;
private static Vector listeners = new Vector();
private String command;
private Thread thread;
private boolean repeatingCommand;
public Executer(String cmd) {
command = cmd;
}
public Executer(String cmd, ImagePlus imp) {
if (cmd.startsWith("Repeat")) {
command = previousCommand;
IJ.setKeyUp(KeyEvent.VK_SHIFT);
repeatingCommand = true;
} else {
command = cmd;
if (!(cmd.equals("Undo")||cmd.equals("Close")))
previousCommand = cmd;
}
IJ.resetEscape();
thread = new Thread(this, cmd);
thread.setPriority(Math.max(thread.getPriority()-2, Thread.MIN_PRIORITY));
if (imp!=null)
WindowManager.setTempCurrentImage(thread, imp);
thread.start();
}
public void run() {
if (command==null)
return;
if (listeners.size()>0) synchronized (listeners) {
for (int i=0; i<listeners.size(); i++) {
CommandListener listener = (CommandListener)listeners.elementAt(i);
command = listener.commandExecuting(command);
if (command==null) return;
}
}
try {
if (Recorder.record) {
Recorder.setCommand(command);
runCommand(command);
Recorder.saveCommand();
} else
runCommand(command);
int len = command.length();
if (len>0 && command.charAt(len-1)!=']')
IJ.setKeyUp(IJ.ALL_KEYS); } catch(Throwable e) {
IJ.showStatus("");
IJ.showProgress(1, 1);
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) imp.unlock();
String msg = e.getMessage();
if (e instanceof OutOfMemoryError)
IJ.outOfMemory(command);
else if (e instanceof RuntimeException && msg!=null && msg.equals(Macro.MACRO_CANCELED))
; else {
CharArrayWriter caw = new CharArrayWriter();
PrintWriter pw = new PrintWriter(caw);
e.printStackTrace(pw);
String s = caw.toString();
if (IJ.isMacintosh()) {
if (s.indexOf("ThreadDeath")>0)
return;
s = Tools.fixNewLines(s);
}
int w=500, h=340;
if (s.indexOf("UnsupportedClassVersionError")!=-1) {
if (s.indexOf("version 49.0")!=-1) {
s = e + "\n \nThis plugin requires Java 1.5 or later.";
w=700; h=150;
}
if (s.indexOf("version 50.0")!=-1) {
s = e + "\n \nThis plugin requires Java 1.6 or later.";
w=700; h=150;
}
if (s.indexOf("version 51.0")!=-1) {
s = e + "\n \nThis plugin requires Java 1.7 or later.";
w=700; h=150;
}
if (s.indexOf("version 52.0")!=-1) {
s = e + "\n \nThis plugin requires Java 1.8 or later.";
w=700; h=150;
}
}
if (IJ.getInstance()!=null) {
s = IJ.getInstance().getInfo()+"\n \n"+s;
new TextWindow("Exception", s, w, h);
} else
IJ.log(s);
}
} finally {
if (thread!=null)
WindowManager.setTempCurrentImage(null);
}
}
void runCommand(String cmd) {
Hashtable table = Menus.getCommands();
String className = (String)table.get(cmd);
if (className!=null) {
String arg = "";
if (className.endsWith("\")")) {
int argStart = className.lastIndexOf("(\"");
if (argStart>0) {
arg = className.substring(argStart+2, className.length()-2);
className = className.substring(0, argStart);
}
}
if (Prefs.nonBlockingFilterDialogs) {
ImagePlus imp = WindowManager.getCurrentImage();
boolean imageLocked = imp!=null && imp.isLockedByAnotherThread();
if (imageLocked && !allowedWithLockedImage(className)) {
IJ.beep();
IJ.showStatus("\""+cmd + "\" blocked because \"" + imp.getTitle() + "\" is locked");
return;
}
}
if (IJ.shiftKeyDown() && className.startsWith("ij.plugin.Macro_Runner") && !Menus.getShortcuts().contains("*"+cmd))
IJ.open(IJ.getDirectory("plugins")+arg);
else
IJ.runPlugIn(cmd, className, arg);
} else { if (MacroInstaller.runMacroCommand(cmd))
return;
if (loadLut(cmd))
return;
if (openRecent(cmd))
return;
if (IJ.getInstance()!=null && !GraphicsEnvironment.isHeadless()) {
if (Editor.openExample(cmd))
return;
}
if ("Auto Threshold".equals(cmd)&&(String)table.get("Auto Threshold...")!=null)
runCommand("Auto Threshold...");
else if ("Enhance Local Contrast (CLAHE)".equals(cmd)&&(String)table.get("CLAHE ")!=null)
runCommand("CLAHE ");
else {
if ("Table...".equals(cmd))
IJ.runPlugIn("ij.plugin.NewPlugin", "table");
else {
if (repeatingCommand)
IJ.runMacro(previousCommand);
else {
if (!extraCommand(cmd))
IJ.error("Unrecognized command: \"" + cmd+"\"");
}
}
}
}
}
private boolean extraCommand(String cmd) {
if (cmd!=null && cmd.equals("Duplicate Image...")) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) {
Duplicator.ignoreNextSelection();
IJ.run(imp, "Duplicate...", "");
} else
IJ.noImage();
return true;
} else
return false;
}
boolean allowedWithLockedImage(String className) {
return className.equals("ij.plugin.Zoom") ||
className.equals("ij.plugin.frame.ContrastAdjuster") ||
className.equals("ij.plugin.SimpleCommands") || className.equals("ij.plugin.WindowOrganizer") ||
className.equals("ij.plugin.URLOpener");
}
public static boolean loadLut(String name) {
String path = IJ.getDirectory("luts")+name.replace(" ","_")+".lut";
File f = new File(path);
if (!f.exists()) {
path = IJ.getDirectory("luts")+name+".lut";
f = new File(path);
}
if (!f.exists()) {
path = IJ.getDirectory("luts")+name.toLowerCase().replace(" ","_")+".lut";
f = new File(path);
}
if (!f.exists() && Character.isLowerCase(name.charAt(0))) {
String name2 = name.substring(0,1).toUpperCase()+name.substring(1);
path = IJ.getDirectory("luts")+name2+".lut";
f = new File(path);
}
if (!f.exists() && name.toLowerCase().equals("viridis")) {
path = IJ.getDirectory("luts")+"mpl-viridis.lut"; f = new File(path);
}
if (f.exists()) {
String dir = OpenDialog.getLastDirectory();
IJ.open(path);
OpenDialog.setLastDirectory(dir);
return true;
}
return false;
}
boolean openRecent(String cmd) {
Menu menu = Menus.getOpenRecentMenu();
if (menu==null) return false;
for (int i=0; i<menu.getItemCount(); i++) {
if (menu.getItem(i).getLabel().equals(cmd)) {
IJ.open(cmd);
return true;
}
}
return false;
}
public static String getCommand() {
return previousCommand;
}
public static void setAsRepeatCommand(String cmd) {
previousCommand = cmd;
}
public static void addCommandListener(CommandListener listener) {
listeners.addElement(listener);
}
public static void removeCommandListener(CommandListener listener) {
listeners.removeElement(listener);
}
public static int getListenerCount() {
return listeners.size();
}
}