/plugins/Console/tags/release-3-1/console/CommandoDialog.java

# · Java · 871 lines · 651 code · 133 blank · 87 comment · 103 complexity · 75e17f8862c585713e63418373f3f4db MD5 · raw file

  1. /*
  2. * CommandoDialog.java - Commando dialog box
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2001 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package console;
  23. //{{{ Imports
  24. import bsh.*;
  25. import com.microstar.xml.*;
  26. import javax.swing.border.*;
  27. import javax.swing.event.*;
  28. import javax.swing.*;
  29. import java.awt.event.*;
  30. import java.awt.*;
  31. import java.io.*;
  32. import java.util.*;
  33. import org.gjt.sp.jedit.gui.*;
  34. import org.gjt.sp.jedit.*;
  35. import org.gjt.sp.util.Log;
  36. //}}}
  37. public class CommandoDialog extends EnhancedDialog
  38. {
  39. //{{{ CommandoDialog method
  40. public CommandoDialog(View view, String command)
  41. {
  42. super(view,jEdit.getProperty("commando.title"),false);
  43. this.view = view;
  44. JPanel content = new JPanel(new BorderLayout(0,12));
  45. content.setBorder(new EmptyBorder(12,12,12,12));
  46. setContentPane(content);
  47. JPanel top = new JPanel(new BorderLayout());
  48. JLabel label = new JLabel(jEdit.getProperty("commando.caption"));
  49. label.setBorder(new EmptyBorder(0,0,0,12));
  50. top.add(BorderLayout.WEST,label);
  51. content.add(BorderLayout.NORTH,top);
  52. CommandoCommand[] commands = ConsolePlugin.getCommandoCommands();
  53. ActionHandler actionListener = new ActionHandler();
  54. commandCombo = new JComboBox(commands);
  55. commandCombo.addActionListener(actionListener);
  56. top.add(BorderLayout.CENTER,commandCombo);
  57. tabs = new JTabbedPane();
  58. tabs.addTab(jEdit.getProperty("commando.settings"),
  59. settings = pane = new SettingsPane());
  60. tabs.addTab(jEdit.getProperty("commando.commands"),
  61. commandLine = new TextAreaPane());
  62. tabs.addChangeListener(new ChangeHandler());
  63. if(command == null)
  64. command = jEdit.getProperty("commando.last-command");
  65. for(int i = 0; i < commands.length; i++)
  66. {
  67. if(commands[i].name.equals(command))
  68. {
  69. commandCombo.setSelectedIndex(i);
  70. break;
  71. }
  72. }
  73. content.add(BorderLayout.CENTER,tabs);
  74. Box buttons = new Box(BoxLayout.X_AXIS);
  75. buttons.add(Box.createGlue());
  76. ok = new JButton(jEdit.getProperty("common.ok"));
  77. ok.addActionListener(actionListener);
  78. getRootPane().setDefaultButton(ok);
  79. buttons.add(ok);
  80. buttons.add(Box.createHorizontalStrut(6));
  81. cancel = new JButton(jEdit.getProperty("common.cancel"));
  82. cancel.addActionListener(actionListener);
  83. buttons.add(cancel);
  84. buttons.add(Box.createGlue());
  85. content.add(BorderLayout.SOUTH,buttons);
  86. pack();
  87. setLocationRelativeTo(view);
  88. show();
  89. } //}}}
  90. //{{{ ok() method
  91. public void ok()
  92. {
  93. jEdit.setProperty("commando.last-command",command.name);
  94. Vector commands = new Vector();
  95. for(int i = 0; i < scripts.size(); i++)
  96. {
  97. Script script = (Script)scripts.elementAt(i);
  98. Command command = script.getCommand();
  99. if(command == null)
  100. {
  101. // user has already seen the BeanShell error,
  102. // so just exit
  103. return;
  104. }
  105. commands.addElement(command);
  106. }
  107. // open a console
  108. DockableWindowManager wm = view.getDockableWindowManager();
  109. wm.addDockableWindow("console");
  110. CommandoThread thread = new CommandoThread(
  111. (Console)wm.getDockable("console"),
  112. commands);
  113. thread.start();
  114. dispose();
  115. } //}}}
  116. //{{{ cancel() method
  117. public void cancel()
  118. {
  119. jEdit.setProperty("commando.last-command",command.name);
  120. dispose();
  121. } //}}}
  122. //{{{ Private members
  123. //{{{ Instance variables
  124. private View view;
  125. private JComboBox commandCombo;
  126. private JTabbedPane tabs;
  127. private SettingsPane settings;
  128. private SettingsPane pane;
  129. private TextAreaPane commandLine;
  130. private JButton ok;
  131. private JButton cancel;
  132. private CommandoCommand command;
  133. private NameSpace nameSpace;
  134. private Vector scripts;
  135. private boolean init;
  136. //}}}
  137. //{{{ load() method
  138. private void load(CommandoCommand command)
  139. {
  140. init = true;
  141. this.command = command;
  142. settings.removeAll();
  143. commandLine.setText(null);
  144. nameSpace = new NameSpace(BeanShell.getNameSpace(),
  145. "commando");
  146. scripts = new Vector();
  147. XmlParser parser = new XmlParser();
  148. CommandoHandler handler = new CommandoHandler();
  149. parser.setHandler(handler);
  150. try
  151. {
  152. parser.parse(null, null, command.openStream());
  153. }
  154. catch(XmlException xe)
  155. {
  156. Log.log(Log.ERROR,this,xe);
  157. int line = xe.getLine();
  158. String message = xe.getMessage();
  159. Object[] pp = { command.name + ".xml", new Integer(line),
  160. message };
  161. GUIUtilities.error(null,"commando.xml-error",pp);
  162. }
  163. catch(IOException io)
  164. {
  165. Log.log(Log.ERROR,this,io);
  166. Object[] pp = { command.name + ".xml", io.toString() };
  167. GUIUtilities.error(null,"read-error",pp);
  168. }
  169. catch(Exception e)
  170. {
  171. Log.log(Log.ERROR,this,e);
  172. }
  173. getRootPane().revalidate();
  174. pack();
  175. init = false;
  176. tabs.setSelectedIndex(0);
  177. } //}}}
  178. //{{{ updateTextArea() method
  179. private void updateTextAreas()
  180. {
  181. if(init)
  182. return;
  183. StringBuffer buf = new StringBuffer();
  184. for(int i = 0; i < scripts.size(); i++)
  185. {
  186. Script script = (Script)scripts.elementAt(i);
  187. Command command = script.getCommand();
  188. if(command == null)
  189. {
  190. // user has already seen the BeanShell error,
  191. // so just exit
  192. return;
  193. }
  194. buf.append(command.shell);
  195. buf.append(": ");
  196. buf.append(command.command);
  197. buf.append('\n');
  198. }
  199. commandLine.setText(buf.toString());
  200. } //}}}
  201. //}}}
  202. //{{{ Inner classes
  203. //{{{ Script class
  204. class Script
  205. {
  206. boolean confirm;
  207. boolean toBuffer;
  208. String shell;
  209. String code;
  210. Script(boolean confirm, boolean toBuffer, String shell, String code)
  211. {
  212. this.confirm = confirm;
  213. this.toBuffer = toBuffer;
  214. this.shell = shell;
  215. this.code = code;
  216. }
  217. Command getCommand()
  218. {
  219. Object command = BeanShell.eval(view,nameSpace,
  220. code,false);
  221. if(command == null)
  222. return null;
  223. return new Command(confirm,toBuffer,
  224. shell,String.valueOf(command));
  225. }
  226. } //}}}
  227. //{{{ Command class
  228. // static for use by CommandoThread
  229. static class Command
  230. {
  231. boolean confirm;
  232. boolean toBuffer;
  233. String shell;
  234. String command;
  235. Command(boolean confirm, boolean toBuffer, String shell, String command)
  236. {
  237. this.confirm = confirm;
  238. this.toBuffer = toBuffer;
  239. this.shell = shell;
  240. this.command = command;
  241. }
  242. } //}}}
  243. //{{{ ActionHandler class
  244. class ActionHandler implements ActionListener
  245. {
  246. public void actionPerformed(ActionEvent evt)
  247. {
  248. if(evt.getSource() == commandCombo)
  249. {
  250. CommandoCommand command = (CommandoCommand)commandCombo
  251. .getSelectedItem();
  252. load(command);
  253. }
  254. else if(evt.getSource() == ok)
  255. ok();
  256. else if(evt.getSource() == cancel)
  257. cancel();
  258. }
  259. } //}}}
  260. //{{{ ChangeHandler class
  261. class ChangeHandler implements ChangeListener
  262. {
  263. public void stateChanged(ChangeEvent evt)
  264. {
  265. if(tabs.getSelectedIndex() == 1)
  266. updateTextAreas();
  267. }
  268. } //}}}
  269. //{{{ CommandoHandler class
  270. class CommandoHandler extends HandlerBase
  271. {
  272. //{{{ CommandoHandler constructor
  273. CommandoHandler()
  274. {
  275. stateStack = new Stack();
  276. options = new Vector();
  277. } //}}}
  278. //{{{ resolveEntity() method
  279. public Object resolveEntity(String publicId, String systemId)
  280. {
  281. if("commando.dtd".equals(systemId))
  282. {
  283. try
  284. {
  285. return new BufferedReader(new InputStreamReader(
  286. CommandoHandler.class.getResourceAsStream(
  287. "/console/commando/commando.dtd")));
  288. }
  289. catch(Exception e)
  290. {
  291. Log.log(Log.ERROR,this,"Error while opening"
  292. + " commando.dtd:");
  293. Log.log(Log.ERROR,this,e);
  294. }
  295. }
  296. return null;
  297. } //}}}
  298. //{{{ attribute() method
  299. public void attribute(String aname, String value, boolean isSpecified)
  300. {
  301. aname = (aname == null) ? null : aname.intern();
  302. value = (value == null) ? null : value.intern();
  303. if(aname == "LABEL")
  304. label = value;
  305. else if(aname == "VARNAME")
  306. varName = value;
  307. else if(aname == "DEFAULT")
  308. defaultValue = value;
  309. else if(aname == "EVAL")
  310. eval = value;
  311. else if(aname == "VALUE")
  312. optionValue = value;
  313. else if(aname == "CONFIRM")
  314. confirm = "TRUE".equals(value);
  315. else if(aname == "TO_BUFFER")
  316. toBuffer = "TRUE".equals(value);
  317. else if(aname == "SHELL")
  318. shell = value;
  319. } //}}}
  320. //{{{ doctypeDecl() method
  321. public void doctypeDecl(String name, String publicId,
  322. String systemId) throws Exception
  323. {
  324. if("COMMANDO".equals(name))
  325. return;
  326. Log.log(Log.ERROR,this,command.name + ".xml: DOCTYPE must be COMMANDO");
  327. } //}}}
  328. //{{{ charData() method
  329. public void charData(char[] c, int off, int len)
  330. {
  331. String tag = peekElement();
  332. String text = new String(c, off, len);
  333. if(tag == "COMMAND")
  334. code = text;
  335. } //}}}
  336. //{{{ startElement() method
  337. public void startElement(String name)
  338. {
  339. pushElement(name);
  340. String tag = peekElement();
  341. if(tag == "CAPTION")
  342. {
  343. pane = new SettingsPane();
  344. pane.setBorder(new TitledBorder(label));
  345. settings.addComponent(pane);
  346. label = null;
  347. }
  348. else if(tag == "CHOICE")
  349. {
  350. choiceLabel = label;
  351. }
  352. } //}}}
  353. //{{{ endElement() method
  354. public void endElement(String name)
  355. {
  356. if(name == null)
  357. return;
  358. String tag = peekElement();
  359. if(name.equals(tag))
  360. {
  361. if(tag == "TOGGLE")
  362. {
  363. pane.addComponent(
  364. new CommandoCheckBox(
  365. label,varName,defaultValue,eval));
  366. label = varName = eval = null;
  367. }
  368. else if(tag == "ENTRY")
  369. {
  370. JLabel left = new JLabel(label);
  371. left.setBorder(new EmptyBorder(0,0,0,12));
  372. pane.addComponent(left,
  373. new CommandoTextField(
  374. varName,defaultValue,eval));
  375. label = varName = eval = null;
  376. }
  377. else if(tag == "TOGGLE_ENTRY")
  378. {
  379. // XXX
  380. label = varName = eval = null;
  381. }
  382. else if(tag == "CHOICE")
  383. {
  384. JLabel left = new JLabel(choiceLabel);
  385. left.setBorder(new EmptyBorder(0,0,0,12));
  386. pane.addComponent(left,
  387. new CommandoComboBox(
  388. varName,defaultValue,eval,options));
  389. options = new Vector();
  390. choiceLabel = varName = eval = null;
  391. }
  392. else if(tag == "OPTION")
  393. {
  394. options.addElement(new Option(label,optionValue));
  395. label = optionValue = null;
  396. }
  397. else if(tag == "CAPTION")
  398. {
  399. pane = settings;
  400. }
  401. else if(tag == "COMMAND")
  402. {
  403. scripts.addElement(new Script(
  404. confirm,toBuffer,shell,code));
  405. confirm = false;
  406. toBuffer = false;
  407. shell = code = null;
  408. }
  409. popElement();
  410. }
  411. else
  412. {
  413. // can't happen
  414. throw new InternalError();
  415. }
  416. } //}}}
  417. //{{{ startDocument() method
  418. public void startDocument()
  419. {
  420. try
  421. {
  422. pushElement(null);
  423. }
  424. catch (Exception e)
  425. {
  426. e.printStackTrace();
  427. }
  428. } //}}}
  429. //{{{ Private members
  430. //{{{ Instance variables
  431. private String varName;
  432. private String defaultValue;
  433. private String eval;
  434. private String optionValue;
  435. private String choiceLabel;
  436. private String label;
  437. private boolean confirm;
  438. private boolean toBuffer;
  439. private String shell;
  440. private String code;
  441. private Vector options;
  442. private Stack stateStack;
  443. //}}}
  444. //{{{ pushElement() method
  445. private void pushElement(String name)
  446. {
  447. name = (name == null) ? null : name.intern();
  448. stateStack.push(name);
  449. } //}}}
  450. //{{{ peekElement() method
  451. private String peekElement()
  452. {
  453. return (String) stateStack.peek();
  454. } //}}}
  455. //{{{ popElement() method
  456. private String popElement()
  457. {
  458. return (String) stateStack.pop();
  459. } //}}}
  460. //}}}
  461. } //}}}
  462. //{{{ CommandoCheckBox class
  463. class CommandoCheckBox extends JCheckBox
  464. {
  465. //{{{ CommandoCheckBox constructor
  466. CommandoCheckBox(String label, String varName, String defaultValue,
  467. String eval)
  468. {
  469. super(label);
  470. this.varName = varName;
  471. this.property = command.propertyPrefix + varName;
  472. setSelected("TRUE".equalsIgnoreCase(defaultValue));
  473. if(eval != null)
  474. {
  475. Object obj = BeanShell.eval(view,eval,false);
  476. if(Boolean.TRUE.equals(obj))
  477. setSelected(true);
  478. else
  479. setSelected(false);
  480. }
  481. else
  482. {
  483. if(jEdit.getProperty(property) != null)
  484. {
  485. if(jEdit.getBooleanProperty(property))
  486. setSelected(true);
  487. else
  488. setSelected(false);
  489. }
  490. else
  491. ; // use default value
  492. }
  493. addActionListener(new ActionHandler());
  494. valueChanged();
  495. } //}}}
  496. private String varName;
  497. private String property;
  498. //{{{ valueChanged() method
  499. private void valueChanged()
  500. {
  501. jEdit.setTemporaryProperty(property,isSelected() ? "true" : "false");
  502. try
  503. {
  504. nameSpace.setVariable(varName,new Primitive(
  505. isSelected()));
  506. }
  507. catch(EvalError e)
  508. {
  509. // can't do much...
  510. }
  511. } //}}}
  512. //{{{ ActionHandler class
  513. class ActionHandler implements ActionListener
  514. {
  515. public void actionPerformed(ActionEvent evt)
  516. {
  517. valueChanged();
  518. }
  519. } //}}}
  520. } //}}}
  521. //{{{ CommandoTextField class
  522. class CommandoTextField extends JTextField
  523. {
  524. //{{{{ CommandoTextField constructor
  525. CommandoTextField(String varName, String defaultValue, String eval)
  526. {
  527. super("commando." + varName);
  528. setText(defaultValue);
  529. this.varName = varName;
  530. this.property = CommandoDialog.this.command.propertyPrefix + varName;
  531. if(eval != null)
  532. {
  533. Object value = BeanShell.eval(view,eval,false);
  534. if(value != null)
  535. setText(value.toString());
  536. }
  537. else
  538. {
  539. String value = jEdit.getProperty(property);
  540. if(value != null)
  541. setText(value);
  542. }
  543. Dimension size = CommandoTextField.this.getPreferredSize();
  544. size.width = 200;
  545. setPreferredSize(size);
  546. addActionListener(new ActionHandler());
  547. CommandoTextField.this.addFocusListener(new FocusHandler());
  548. valueChanged();
  549. } //}}}
  550. private String varName;
  551. private String property;
  552. //{{{ valueChanged() method
  553. private void valueChanged()
  554. {
  555. String text = getText();
  556. if(text == null)
  557. text = "";
  558. jEdit.setTemporaryProperty(property,text);
  559. try
  560. {
  561. nameSpace.setVariable(varName,text);
  562. }
  563. catch(EvalError e)
  564. {
  565. // can't do much...
  566. }
  567. } //}}}
  568. //{{{ ActionHandler class
  569. class ActionHandler implements ActionListener
  570. {
  571. public void actionPerformed(ActionEvent evt)
  572. {
  573. valueChanged();
  574. }
  575. } //}}}
  576. //{{{ FocusHandler class
  577. class FocusHandler implements FocusListener
  578. {
  579. public void focusGained(FocusEvent evt) {}
  580. public void focusLost(FocusEvent evt)
  581. {
  582. valueChanged();
  583. }
  584. } //}}}
  585. } //}}}
  586. //{{{ CommandoCheckBox class
  587. class CommandoComboBox extends JComboBox
  588. {
  589. //{{{ CommandoComboBox constructor
  590. CommandoComboBox(String varName, String defaultValue, String eval,
  591. Vector options)
  592. {
  593. super(options);
  594. this.varName = varName;
  595. this.property = command.propertyPrefix + varName;
  596. if(eval != null)
  597. {
  598. defaultValue = String.valueOf(BeanShell.eval(
  599. view,eval,false));
  600. }
  601. else
  602. {
  603. String value = jEdit.getProperty(property);
  604. if(value != null)
  605. defaultValue = value;
  606. }
  607. if(defaultValue != null)
  608. {
  609. for(int i = 0; i < options.size(); i++)
  610. {
  611. Option opt = (Option)options.elementAt(i);
  612. if(defaultValue.equals(opt.value))
  613. {
  614. setSelectedIndex(i);
  615. break;
  616. }
  617. }
  618. }
  619. addActionListener(new ActionHandler());
  620. valueChanged();
  621. } //}}}
  622. private String varName;
  623. private String property;
  624. private String eval;
  625. //{{{ valueChanged() method
  626. private void valueChanged()
  627. {
  628. Option value = (Option)getSelectedItem();
  629. jEdit.setTemporaryProperty(property,value.value);
  630. try
  631. {
  632. nameSpace.setVariable(varName,value.value);
  633. }
  634. catch(EvalError e)
  635. {
  636. // can't do much...
  637. }
  638. } //}}}
  639. //{{{ ActionHandler class
  640. class ActionHandler implements ActionListener
  641. {
  642. public void actionPerformed(ActionEvent evt)
  643. {
  644. valueChanged();
  645. }
  646. } //}}}
  647. } //}}}
  648. //{{{ Option class
  649. static class Option
  650. {
  651. String label;
  652. String value;
  653. Option(String label, String value)
  654. {
  655. this.label = label;
  656. this.value = value;
  657. }
  658. public String toString()
  659. {
  660. return label;
  661. }
  662. } //}}}
  663. //{{{ SettingsPane class
  664. static class SettingsPane extends JPanel
  665. {
  666. //{{{ SettingsPane constructor
  667. SettingsPane()
  668. {
  669. setLayout(gridBag = new GridBagLayout());
  670. } //}}}
  671. //{{{ addComponent() method
  672. void addComponent(Component left, Component right)
  673. {
  674. GridBagConstraints cons = new GridBagConstraints();
  675. cons.gridy = y++;
  676. cons.gridheight = 1;
  677. cons.gridwidth = 1;
  678. cons.weightx = 0.0f;
  679. cons.fill = GridBagConstraints.BOTH;
  680. gridBag.setConstraints(left,cons);
  681. add(left);
  682. cons.gridx = 1;
  683. cons.weightx = 1.0f;
  684. gridBag.setConstraints(right,cons);
  685. add(right);
  686. } //}}}
  687. //{{{ addComponent() method
  688. void addComponent(Component comp)
  689. {
  690. GridBagConstraints cons = new GridBagConstraints();
  691. cons.gridy = y++;
  692. cons.gridheight = 1;
  693. cons.gridwidth = cons.REMAINDER;
  694. cons.fill = GridBagConstraints.BOTH;
  695. cons.anchor = GridBagConstraints.WEST;
  696. cons.weightx = 1.0f;
  697. gridBag.setConstraints(comp,cons);
  698. add(comp);
  699. } //}}}
  700. private GridBagLayout gridBag;
  701. private int y;
  702. } //}}}
  703. //{{{ TextAreaPane class
  704. static class TextAreaPane extends JPanel
  705. {
  706. //{{{ TextAreaPane constructor
  707. TextAreaPane()
  708. {
  709. super(new BorderLayout());
  710. JPanel panel = new JPanel(new BorderLayout());
  711. panel.setBorder(new EmptyBorder(6,0,6,0));
  712. panel.add(BorderLayout.WEST,copy = new JButton(
  713. jEdit.getProperty("commando.copy")));
  714. copy.addActionListener(new ActionHandler());
  715. add(BorderLayout.NORTH,panel);
  716. add(BorderLayout.CENTER,new JScrollPane(
  717. textArea = new JTextArea(4,30)));
  718. textArea.setEditable(false);
  719. textArea.setLineWrap(true);
  720. } //}}}
  721. //{{{ setText() method
  722. void setText(String text)
  723. {
  724. textArea.setText(text);
  725. } //}}}
  726. private JButton copy;
  727. private JTextArea textArea;
  728. //{{{ ActionHandler class
  729. class ActionHandler implements ActionListener
  730. {
  731. public void actionPerformed(ActionEvent evt)
  732. {
  733. textArea.copy();
  734. }
  735. } //}}}
  736. } //}}}
  737. //}}}
  738. }