package ij.macro; import ij.*; import ij.plugin.*; import ij.plugin.frame.*; import java.awt.*; import java.awt.event.*; import java.util.Hashtable; import java.util.Arrays; import java.util.Iterator; import java.util.ArrayList; import java.util.Set; /** This class implements the text editor's Macros/Find Functions command. It was written by jerome.mutterer at ibmp.fr, and is based on Mark Longair's CommandFinder plugin. */ public class FunctionFinder implements TextListener, WindowListener, KeyListener, ItemListener { Dialog d; TextField prompt; List completions; String [] commands ; public FunctionFinder() { String exists = IJ.runMacro("return File.exists(getDirectory('macros')+'functions.html');"); if (exists=="0") { String installLocalMacroFunctionsFile = "functions = File.openUrlAsString('"+IJ.URL+"/developer/macro/functions.html');\n"+ "f = File.open(getDirectory('macros')+'functions.html');\n"+ "print (f, functions);\n"+ "File.close(f);"; try { IJ.runMacro(installLocalMacroFunctionsFile); } catch (Throwable e) { IJ.error("Problem downloading functions.html"); return;} } String f = IJ.runMacro("return File.openAsString(getDirectory('macros')+'functions.html');"); String [] l = f.split("\n"); commands= new String [l.length]; int c=0; for (int i=0; i<l.length; i++) { String line = l[i]; if (line.startsWith("<b>")) { commands[c]=line.substring(line.indexOf("<b>")+3,line.indexOf("</b>")); c++; } } if (c==0) { IJ.error("ImageJ/macros/functions.html is corrupted"); return; } ImageJ imageJ = IJ.getInstance(); d = new Dialog(imageJ, "Built-in Functions"); d.setLayout(new BorderLayout()); d.addWindowListener(this); Panel northPanel = new Panel(); prompt = new TextField("", 30); prompt.addTextListener(this); prompt.addKeyListener(this); northPanel.add(prompt); d.add(northPanel, BorderLayout.NORTH); completions = new List(12); completions.addKeyListener(this); populateList(""); d.add(completions, BorderLayout.CENTER); d.pack(); Frame frame = WindowManager.getFrontWindow(); if (frame==null) return; java.awt.Point posi=frame.getLocationOnScreen(); int initialX = (int)posi.getX() + 38; int initialY = (int)posi.getY() + 84; d.setLocation(initialX,initialY); d.setVisible(true); d.toFront(); } public void populateList(String matchingSubstring) { String substring = matchingSubstring.toLowerCase(); completions.removeAll(); try { for(int i=0; i<commands.length; ++i) { String commandName = commands[i]; if (commandName.length()==0) continue; String lowerCommandName = commandName.toLowerCase(); if( lowerCommandName.indexOf(substring) >= 0 ) { completions.add(commands[i]); } } } catch (Exception e){} } public void edPaste(String arg) { Frame frame = WindowManager.getFrontWindow(); try { TextArea ta = ((Editor)frame).getTextArea(); int start = ta.getSelectionStart( ); int end = ta.getSelectionEnd( ); try { ta.replaceRange(arg.substring(0,arg.length()), start, end); } catch (Exception e) { } if (IJ.isMacOSX()) ta.setCaretPosition(start+arg.length()); } catch (Exception e) { } } public void itemStateChanged(ItemEvent ie) { populateList(prompt.getText()); } protected void runFromLabel(String listLabel) { edPaste(listLabel); d.dispose(); } public void keyPressed(KeyEvent ke) { int key = ke.getKeyCode(); int items = completions.getItemCount(); Object source = ke.getSource(); if (source==prompt) { if (key==KeyEvent.VK_ENTER) { if (1==items) { String selected = completions.getItem(0); runFromLabel(selected); } } else if (key==KeyEvent.VK_UP) { completions.requestFocus(); if(items>0) completions.select(completions.getItemCount()-1); } else if (key==KeyEvent.VK_ESCAPE) { d.dispose(); } else if (key==KeyEvent.VK_DOWN) { completions.requestFocus(); if (items>0) completions.select(0); } } else if (source==completions) { if (key==KeyEvent.VK_ENTER) { String selected = completions.getSelectedItem(); if (selected!=null) runFromLabel(selected); } } } public void keyReleased(KeyEvent ke) { } public void keyTyped(KeyEvent ke) { } public void textValueChanged(TextEvent te) { populateList(prompt.getText()); } public void windowClosing(WindowEvent e) { d.dispose(); } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } }