package ij;
import ij.plugin.Converter;
import ij.plugin.frame.Recorder;
import ij.plugin.frame.Editor;
import ij.text.TextWindow;
import ij.plugin.frame.PlugInFrame;
import ij.plugin.frame.Commands;
import ij.util.Tools;
import ij.macro.Interpreter;
import java.awt.*;
import java.util.*;
import ij.gui.*;
public class WindowManager {
public static boolean checkForDuplicateName;
private static Vector imageList = new Vector(); private static Vector activations = new Vector(); private static Vector nonImageList = new Vector(); private static ImageWindow currentWindow; private static Window frontWindow;
private static Window frontTable;
private static Frame frontFrame;
private static Hashtable tempImageTable = new Hashtable();
private WindowManager() {
}
public static void setCurrentWindow(ImageWindow win) {
if (win==null || win.isClosed() || win.getImagePlus()==null) return;
setWindow(win);
tempImageTable.remove(Thread.currentThread());
if (win==currentWindow || imageList.size()==0)
return;
if (currentWindow!=null) {
ImagePlus imp = currentWindow.getImagePlus();
if (imp!=null ) {
if (!Prefs.keepUndoBuffers)
imp.trimProcessor();
imp.saveRoi();
}
}
Undo.reset();
currentWindow = win;
activations.remove(win);
activations.add(win);
Menus.updateMenus();
if (Recorder.record && !IJ.isMacro())
Recorder.record("selectWindow", win.getImagePlus().getTitle());
}
public static ImageWindow getCurrentWindow() {
return currentWindow;
}
static int getCurrentIndex() {
return imageList.indexOf(currentWindow);
}
public static ImagePlus getCurrentImage() {
ImagePlus img = (ImagePlus)tempImageTable.get(Thread.currentThread());
if (img==null)
img = getActiveImage();
return img;
}
public static void setTempCurrentImage(ImagePlus img) {
if (img==null)
tempImageTable.remove(Thread.currentThread());
else
tempImageTable.put(Thread.currentThread(), img);
}
public static void setTempCurrentImage(Thread thread, ImagePlus img) {
if (thread==null)
throw new RuntimeException("thread==null");
if (img==null)
tempImageTable.remove(thread);
else
tempImageTable.put(thread, img);
}
private static ImagePlus getActiveImage() {
if (currentWindow!=null)
return currentWindow.getImagePlus();
else if (frontWindow!=null && (frontWindow instanceof ImageWindow))
return frontWindow!=null?((ImageWindow)frontWindow).getImagePlus():null;
else if (imageList.size()>0) {
ImagePlus imp = getFocusManagerActiveImage();
if (imp!=null)
return imp;
ImageWindow win = (ImageWindow)imageList.get(imageList.size()-1);
return win.getImagePlus();
} else
return Interpreter.getLastBatchModeImage();
}
private static ImagePlus getFocusManagerActiveImage() {
if (IJ.isMacro())
return null;
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Window win = kfm.getActiveWindow();
ImagePlus imp = null;
if (win!=null && (win instanceof ImageWindow))
imp = ((ImageWindow)win).getImagePlus();
return imp;
}
public static int getWindowCount() {
int count = imageList.size();
return count;
}
public static int getImageCount() {
int count = imageList.size();
count += Interpreter.getBatchModeImageCount();
if (count==0 && getCurrentImage()!=null)
count = 1;
return count;
}
public static Window getActiveWindow() {
return frontWindow;
}
public static Window getActiveTable() {
return frontTable;
}
public static Frame getFrontWindow() {
return frontFrame;
}
public synchronized static int[] getIDList() {
int nWindows = imageList.size();
int[] batchModeImages = Interpreter.getBatchModeImageIDs();
int nBatchImages = batchModeImages.length;
if ((nWindows+nBatchImages)==0)
return null;
int[] list = new int[nWindows+nBatchImages];
for (int i=0; i<nBatchImages; i++)
list[i] = batchModeImages[i];
int index = 0;
for (int i=nBatchImages; i<nBatchImages+nWindows; i++) {
ImageWindow win = (ImageWindow)imageList.get(index++);
list[i] = win.getImagePlus().getID();
}
return list;
}
public synchronized static String[] getImageTitles() {
int[] list = getIDList();
if (list==null)
return new String[0];
String[] titles = new String[list.length];
for (int i=0; i<list.length; i++) {
ImagePlus img = getImage(list[i]);
titles[i] = img.getTitle();
}
return titles;
}
public synchronized static Frame[] getNonImageWindows() {
ArrayList list = new ArrayList();
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
if (win instanceof Frame)
list.add(win);
}
Frame[] frames = new Frame[list.size()];
list.toArray(frames);
return frames;
}
public synchronized static Window[] getAllNonImageWindows() {
ArrayList list = new ArrayList();
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
if (win instanceof Window)
list.add(win);
}
Window[] windows = new Window[list.size()];
list.toArray(windows);
return windows;
}
public synchronized static String[] getNonImageTitles() {
ArrayList list = new ArrayList();
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
String title = win instanceof Frame?((Frame)win).getTitle():((Dialog)win).getTitle();
list.add(title);
}
String[] titles = new String[list.size()];
list.toArray(titles);
return titles;
}
public synchronized static ImagePlus getImage(int imageID) {
if (imageID>0)
imageID = getNthImageID(imageID);
if (imageID==0 || getImageCount()==0)
return null;
ImagePlus imp2 = Interpreter.getBatchModeImage(imageID);
if (imp2!=null)
return imp2;
ImagePlus imp = null;
for (int i=0; i<imageList.size(); i++) {
ImageWindow win = (ImageWindow)imageList.get(i);
imp2 = win.getImagePlus();
if (imageID==imp2.getID()) {
imp = imp2;
break;
}
}
imp2 = getCurrentImage();
if (imp==null &&imp2!=null && imp2.getID()==imageID)
return imp2;
return imp;
}
public synchronized static int getNthImageID(int n) {
if (n<=0) return 0;
if (Interpreter.isBatchMode()) {
int[] list = getIDList();
if (n>list.length)
return 0;
else
return list[n-1];
} else {
if (n>imageList.size()) return 0;
ImageWindow win = (ImageWindow)imageList.get(n-1);
if (win!=null)
return win.getImagePlus().getID();
else
return 0;
}
}
public synchronized static ImagePlus getImage(String title) {
int[] wList = getIDList();
if (wList==null) return null;
for (int i=0; i<wList.length; i++) {
ImagePlus imp = getImage(wList[i]);
if (imp!=null && imp.getTitle().equals(title))
return imp;
}
return null;
}
public synchronized static void addWindow(Window win) {
if (win==null)
return;
else if (win instanceof ImageWindow)
addImageWindow((ImageWindow)win);
else {
Menus.insertWindowMenuItem(win);
nonImageList.add(win);
}
}
public static void addWindow(Frame win) {
addWindow((Window)win);
}
private static void addImageWindow(ImageWindow win) {
ImagePlus imp = win.getImagePlus();
if (imp==null) return;
checkForDuplicateName(imp);
imageList.add(win);
Menus.addWindowMenuItem(imp);
setCurrentWindow(win);
}
static void checkForDuplicateName(ImagePlus imp) {
if (checkForDuplicateName) {
String name = imp.getTitle();
if (isDuplicateName(name))
imp.setTitle(getUniqueName(name));
}
checkForDuplicateName = false;
}
static boolean isDuplicateName(String name) {
if (name==null)
return false;
int n = imageList.size();
for (int i=0; i<n; i++) {
ImageWindow win = (ImageWindow)imageList.get(i);
String name2 = win.getImagePlus().getTitle();
if (name.equals(name2))
return true;
}
return false;
}
public static String getUniqueName(String name) {
return getUniqueName(null, name);
}
public static String getUniqueName(ImagePlus imp, String name) {
String name2 = name;
String extension = "";
int len = name2.length();
int lastDot = name2.lastIndexOf(".");
if (lastDot!=-1 && len-lastDot<6 && lastDot!=len-1) {
extension = name2.substring(lastDot, len);
name2 = name2.substring(0, lastDot);
}
int lastDash = name2.lastIndexOf("-");
len = name2.length();
if (imp!=null && imp.getProp("UniqueName")==null)
lastDash = -1;
if (lastDash!=-1&&len-lastDash<4&&lastDash<len-1&&Character.isDigit(name2.charAt(lastDash+1))&&name2.charAt(lastDash+1)!='0')
name2 = name2.substring(0, lastDash);
for (int i=1; i<=99; i++) {
String name3 = name2+"-"+ i + extension;
if (!isDuplicateName(name3))
return name3;
}
return name;
}
public static String makeUniqueName(String name) {
return isDuplicateName(name)?getUniqueName(name):name;
}
public static void removeWindow(Window win) {
if (win instanceof ImageWindow)
removeImageWindow((ImageWindow)win);
else {
int index = nonImageList.indexOf(win);
ImageJ ij = IJ.getInstance();
if (index>=0) {
Menus.removeWindowMenuItem(index);
nonImageList.removeElement(win);
}
if (win!=null && win==frontTable)
frontTable = null;
}
setWindow(null);
}
public static void removeWindow(Frame win) {
removeWindow((Window)win);
}
private static void removeImageWindow(ImageWindow win) {
int index = imageList.indexOf(win);
if (index==-1)
return; try {
synchronized(WindowManager.class) {
imageList.remove(win);
}
activations.remove(win);
if (imageList.size()>1 && !Prefs.closingAll) {
ImageWindow win2 = activations.size()>0?(ImageWindow)activations.get(activations.size()-1):null;
setCurrentWindow(win2);
} else
currentWindow = null;
setTempCurrentImage(null); int nonImageCount = nonImageList.size();
if (nonImageCount>0)
nonImageCount++;
Menus.removeWindowMenuItem(nonImageCount+index);
Menus.updateMenus();
Undo.reset();
} catch (Exception e) { }
}
public static void setWindow(Window win) {
frontWindow = win;
if (win instanceof Frame)
frontFrame = (Frame)win;
}
public static void setWindow(Frame win) {
frontWindow = win;
frontFrame = win;
if (win!=null && win instanceof TextWindow && !(win instanceof Editor) && !"Log".equals(((TextWindow)win).getTitle()))
frontTable = win;
}
public synchronized static boolean closeAllWindows() {
Prefs.closingAll = true;
while (imageList.size()>0) {
if (!((ImageWindow)imageList.get(0)).close()) {
Prefs.closingAll = false;
return false;
}
if (!quittingViaMacro())
IJ.wait(100);
}
Prefs.closingAll = false;
Frame[] nonImages = getNonImageWindows();
for (int i=0; i<nonImages.length; i++) {
Frame frame = nonImages[i];
if (frame!=null && frame instanceof Commands)
((Commands)frame).close();
else if (frame!=null && (frame instanceof Editor)) {
((Editor)frame).close();
if (((Editor)frame).fileChanged())
return false;
if (!quittingViaMacro())
IJ.wait(100);
}
}
ImageJ ij = IJ.getInstance();
if (ij!=null && ij.quitting() && IJ.getApplet()==null)
return true;
for (int i=0; i<nonImages.length; i++) {
Frame frame = nonImages[i];
if ((frame instanceof PlugInFrame) && !(frame instanceof Editor))
((PlugInFrame)frame).close();
else if (frame instanceof TextWindow)
((TextWindow)frame).close();
else {
frame.dispose();
}
}
return true;
}
private static boolean quittingViaMacro() {
ImageJ ij = IJ.getInstance();
return ij!=null && ij.quittingViaMacro();
}
public static void putBehind() {
if (IJ.debugMode) IJ.log("putBehind");
if (imageList.size()<1 || currentWindow==null)
return;
int index = imageList.indexOf(currentWindow);
ImageWindow win = null;
int count = 0;
do {
index--;
if (index<0) index = imageList.size()-1;
win = (ImageWindow)imageList.get(index);
if (++count==imageList.size()) return;
} while (win instanceof HistogramWindow || win instanceof PlotWindow);
if (win==null) return;
ImagePlus imp = win.getImagePlus();
if (imp!=null)
IJ.selectWindow(imp.getID());
}
public static ImagePlus getTempCurrentImage() {
return (ImagePlus)tempImageTable.get(Thread.currentThread());
}
public static Window getWindow(String title) {
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
String winTitle = win instanceof Frame?((Frame)win).getTitle():((Dialog)win).getTitle();
if (title.equals(winTitle))
return (Window)win;
}
return getImageWindow(title);
}
public static Frame getFrame(String title) {
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
String winTitle = win instanceof Frame?((Frame)win).getTitle():null;
if (title.equals(winTitle))
return (Frame)win;
}
Frame frame = getImageWindow(title);
if (frame==null) {
Window win = getWindow(title);
if (win!=null)
frame = new Frame("Proxy");
}
return frame;
}
private static Frame getImageWindow(String title) {
int[] wList = getIDList();
int len = wList!=null?wList.length:0;
for (int i=0; i<len; i++) {
ImagePlus imp = getImage(wList[i]);
if (imp!=null) {
if (imp.getTitle().equals(title))
return imp.getWindow();
}
}
return null;
}
synchronized static void activateWindow(String menuItemLabel, MenuItem item) {
for (int i=0; i<nonImageList.size(); i++) {
Object win = nonImageList.get(i);
String title = win instanceof Frame?((Frame)win).getTitle():((Dialog)win).getTitle();
if (menuItemLabel.equals(title)) {
if (win instanceof Frame)
toFront((Frame)win);
else
((Dialog)win).toFront();
((CheckboxMenuItem)item).setState(false);
if (Recorder.record && !IJ.isMacro())
Recorder.record("selectWindow", title);
return;
}
}
int lastSpace = menuItemLabel.lastIndexOf(' ');
if (lastSpace>0) menuItemLabel = menuItemLabel.substring(0, lastSpace);
String idString = item.getActionCommand();
int id = (int)Tools.parseDouble(idString, 0);
ImagePlus imp = WindowManager.getImage(id);
if (imp==null) return;
ImageWindow win1 = imp.getWindow();
if (win1==null) return;
setCurrentWindow(win1);
toFront(win1);
int index = imageList.indexOf(win1);
int n = Menus.window.getItemCount();
int start = Menus.WINDOW_MENU_ITEMS+Menus.windowMenuItems2;
for (int j=start; j<n; j++) {
MenuItem mi = Menus.window.getItem(j);
if (mi instanceof CheckboxMenuItem)
((CheckboxMenuItem)mi).setState((j-start)==index);
}
}
public synchronized static void repaintImageWindows() {
int[] list = getIDList();
if (list==null) return;
for (int i=0; i<list.length; i++) {
ImagePlus imp2 = getImage(list[i]);
if (imp2!=null) {
imp2.setTitle(imp2.getTitle()); ImageWindow win = imp2.getWindow();
if (win!=null) win.repaint();
}
}
}
public static void showList() {
for (int i=0; i<imageList.size(); i++) {
ImageWindow win = (ImageWindow)imageList.get(i);
ImagePlus imp = win.getImagePlus();
IJ.log(i + " " + imp.getTitle() + (win==currentWindow?"*":"")+" "+imp.getID());
}
for (int i=0; i<activations.size(); i++) {
ImageWindow win = (ImageWindow)activations.get(i);
ImagePlus imp = win.getImagePlus();
IJ.log(i + " " + imp.getTitle() + " " + imp.getID());
}
if (imageList.size()==0) IJ.log("imageList is empty");
if (activations.size()==0) IJ.log("activations list is empty");
IJ.log(" ");
}
public static void toFront(Frame frame) {
if (frame==null) return;
if (frame.getState()==Frame.ICONIFIED)
frame.setState(Frame.NORMAL);
frame.toFront();
}
public static void toFront(Window window) {
if (window==null) return;
if (window instanceof Frame && ((Frame)window).getState()==Frame.ICONIFIED)
((Frame)window).setState(Frame.NORMAL);
window.toFront();
}
}