PageRenderTime 76ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/jedit/gui/OptionsDialog.java

#
Java | 572 lines | 434 code | 96 blank | 42 comment | 59 complexity | 1e78a086afae63f4e4697cc59c2e447a MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * OptionsDialog.java - Global options dialog
  3. * Copyright (C) 1998, 1999, 2000, 2001 Slava Pestov
  4. * Portions copyright (C) 1999 mike dillon
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package org.gjt.sp.jedit.gui;
  21. import javax.swing.*;
  22. import javax.swing.border.*;
  23. import javax.swing.event.*;
  24. import javax.swing.tree.*;
  25. import java.awt.*;
  26. import java.awt.event.*;
  27. import java.util.*;
  28. import org.gjt.sp.jedit.*;
  29. import org.gjt.sp.jedit.options.*;
  30. import org.gjt.sp.util.Log;
  31. /**
  32. * An abstract tabbed options dialog box.
  33. * @author Slava Pestov
  34. * @version $Id: OptionsDialog.java 3827 2001-10-05 08:55:14Z spestov $
  35. */
  36. public class OptionsDialog extends EnhancedDialog
  37. implements ActionListener, TreeSelectionListener
  38. {
  39. public OptionsDialog(View view)
  40. {
  41. super(view, jEdit.getProperty("options.title"), true);
  42. view.showWaitCursor();
  43. JPanel content = new JPanel(new BorderLayout());
  44. content.setBorder(new EmptyBorder(12,12,12,12));
  45. setContentPane(content);
  46. content.setLayout(new BorderLayout());
  47. JPanel stage = new JPanel(new BorderLayout());
  48. stage.setBorder(new EmptyBorder(0,6,0,0));
  49. content.add(stage, BorderLayout.CENTER);
  50. // currentLabel displays the path of the currently selected
  51. // OptionPane at the top of the stage area
  52. currentLabel = new JLabel();
  53. currentLabel.setHorizontalAlignment(JLabel.LEFT);
  54. currentLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1,
  55. 0, Color.black));
  56. stage.add(currentLabel, BorderLayout.NORTH);
  57. cardPanel = new JPanel(new CardLayout());
  58. cardPanel.setBorder(new EmptyBorder(5,0,0,0));
  59. stage.add(cardPanel, BorderLayout.CENTER);
  60. paneTree = new JTree(createOptionTreeModel());
  61. paneTree.setCellRenderer(new PaneNameRenderer());
  62. paneTree.putClientProperty("JTree.lineStyle", "Angled");
  63. paneTree.setShowsRootHandles(true);
  64. paneTree.setRootVisible(false);
  65. content.add(new JScrollPane(paneTree,
  66. JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
  67. JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
  68. BorderLayout.WEST);
  69. JPanel buttons = new JPanel();
  70. buttons.setBorder(new EmptyBorder(12,0,0,0));
  71. buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS));
  72. buttons.add(Box.createGlue());
  73. ok = new JButton(jEdit.getProperty("common.ok"));
  74. ok.addActionListener(this);
  75. buttons.add(ok);
  76. buttons.add(Box.createHorizontalStrut(6));
  77. getRootPane().setDefaultButton(ok);
  78. cancel = new JButton(jEdit.getProperty("common.cancel"));
  79. cancel.addActionListener(this);
  80. buttons.add(cancel);
  81. buttons.add(Box.createHorizontalStrut(6));
  82. apply = new JButton(jEdit.getProperty("common.apply"));
  83. apply.addActionListener(this);
  84. buttons.add(apply);
  85. buttons.add(Box.createGlue());
  86. content.add(buttons, BorderLayout.SOUTH);
  87. // compute the jEdit branch
  88. TreePath jEditPath = new TreePath(new Object[]{ paneTree
  89. .getModel().getRoot(), jEditGroup });
  90. // register the Options dialog as a TreeSelectionListener.
  91. // this is done before the initial selection to ensure that the
  92. // first selected OptionPane is displayed on startup.
  93. paneTree.getSelectionModel().addTreeSelectionListener(this);
  94. // select the first member of the jEdit group
  95. paneTree.setSelectionPath(jEditPath.pathByAddingChild(
  96. jEditGroup.getMember(0)));
  97. view.hideWaitCursor();
  98. pack();
  99. setLocationRelativeTo(view);
  100. show();
  101. }
  102. public void addOptionGroup(OptionGroup group)
  103. {
  104. addOptionGroup(group, pluginsGroup);
  105. }
  106. public void addOptionPane(OptionPane pane)
  107. {
  108. addOptionPane(pane, pluginsGroup);
  109. }
  110. // EnhancedDialog implementation
  111. public void ok()
  112. {
  113. ok(true);
  114. }
  115. public void cancel()
  116. {
  117. dispose();
  118. }
  119. // end EnhancedDialog implementation
  120. public void ok(boolean dispose)
  121. {
  122. OptionTreeModel m = (OptionTreeModel) paneTree
  123. .getModel();
  124. ((OptionGroup) m.getRoot()).save();
  125. /* This will fire the PROPERTIES_CHANGED event */
  126. jEdit.propertiesChanged();
  127. // Save settings to disk
  128. jEdit.saveSettings();
  129. // get rid of this dialog if necessary
  130. if(dispose)
  131. dispose();
  132. }
  133. public void actionPerformed(ActionEvent evt)
  134. {
  135. Object source = evt.getSource();
  136. if(source == ok)
  137. {
  138. ok();
  139. }
  140. else if(source == cancel)
  141. {
  142. cancel();
  143. }
  144. else if(source == apply)
  145. {
  146. ok(false);
  147. }
  148. }
  149. public void valueChanged(TreeSelectionEvent evt)
  150. {
  151. TreePath path = evt.getPath();
  152. if (path == null || !(path.getLastPathComponent() instanceof
  153. OptionPane)) return;
  154. Object[] nodes = path.getPath();
  155. StringBuffer buf = new StringBuffer();
  156. OptionPane optionPane = null;
  157. String name = null;
  158. int lastIdx = nodes.length - 1;
  159. for (int i = paneTree.isRootVisible() ? 0 : 1;
  160. i <= lastIdx; i++)
  161. {
  162. if (nodes[i] instanceof OptionPane)
  163. {
  164. optionPane = (OptionPane)nodes[i];
  165. name = optionPane.getName();
  166. }
  167. else if (nodes[i] instanceof OptionGroup)
  168. {
  169. name = ((OptionGroup)nodes[i]).getName();
  170. }
  171. else
  172. {
  173. continue;
  174. }
  175. if (name != null)
  176. {
  177. String label = jEdit.getProperty("options." +
  178. name + ".label");
  179. if (label == null)
  180. {
  181. buf.append(name);
  182. }
  183. else
  184. {
  185. buf.append(label);
  186. }
  187. }
  188. if (i != lastIdx) buf.append(": ");
  189. }
  190. currentLabel.setText(buf.toString());
  191. optionPane.init();
  192. pack();
  193. ((CardLayout)cardPanel.getLayout()).show(cardPanel, name);
  194. }
  195. // private members
  196. private Hashtable panes;
  197. private JTree paneTree;
  198. private JPanel cardPanel;
  199. private JLabel currentLabel;
  200. private JButton ok;
  201. private JButton cancel;
  202. private JButton apply;
  203. private OptionGroup jEditGroup;
  204. private OptionGroup pluginsGroup;
  205. private OptionTreeModel createOptionTreeModel()
  206. {
  207. OptionTreeModel paneTreeModel = new OptionTreeModel();
  208. OptionGroup rootGroup = (OptionGroup) paneTreeModel.getRoot();
  209. // initialize the jEdit branch of the options tree
  210. jEditGroup = new OptionGroup("jedit");
  211. addOptionPane(new GeneralOptionPane(), jEditGroup);
  212. addOptionPane(new AppearanceOptionPane(), jEditGroup);
  213. addOptionPane(new TextAreaOptionPane(), jEditGroup);
  214. addOptionPane(new GutterOptionPane(), jEditGroup);
  215. addOptionPane(new ColorOptionPane(), jEditGroup);
  216. addOptionPane(new StyleOptionPane(), jEditGroup);
  217. addOptionPane(new LoadSaveOptionPane(), jEditGroup);
  218. addOptionPane(new EditingOptionPane(), jEditGroup);
  219. addOptionPane(new ModeOptionPane(), jEditGroup);
  220. addOptionPane(new ShortcutsOptionPane(), jEditGroup);
  221. addOptionPane(new DockingOptionPane(), jEditGroup);
  222. addOptionPane(new ContextOptionPane(), jEditGroup);
  223. addOptionPane(new ToolBarOptionPane(), jEditGroup);
  224. addOptionPane(new AbbrevsOptionPane(), jEditGroup);
  225. addOptionPane(new PrintOptionPane(), jEditGroup);
  226. OptionGroup browserGroup = new OptionGroup("browser");
  227. addOptionPane(new BrowserOptionPane(), browserGroup);
  228. addOptionPane(new BrowserColorsOptionPane(), browserGroup);
  229. addOptionGroup(browserGroup, jEditGroup);
  230. addOptionGroup(jEditGroup, rootGroup);
  231. // initialize the Plugins branch of the options tree
  232. pluginsGroup = new OptionGroup("plugins");
  233. // Query plugins for option panes
  234. EditPlugin[] plugins = jEdit.getPlugins();
  235. for(int i = 0; i < plugins.length; i++)
  236. {
  237. EditPlugin ep = plugins[i];
  238. try
  239. {
  240. ep.createOptionPanes(this);
  241. }
  242. catch(Throwable t)
  243. {
  244. Log.log(Log.ERROR, ep,
  245. "Error creating option pane");
  246. Log.log(Log.ERROR, ep, t);
  247. }
  248. }
  249. // only add the Plugins branch if there are OptionPanes
  250. if (pluginsGroup.getMemberCount() > 0)
  251. {
  252. addOptionGroup(pluginsGroup, rootGroup);
  253. }
  254. return paneTreeModel;
  255. }
  256. private void addOptionGroup(OptionGroup child, OptionGroup parent)
  257. {
  258. Enumeration enum = child.getMembers();
  259. while (enum.hasMoreElements())
  260. {
  261. Object elem = enum.nextElement();
  262. if (elem instanceof OptionPane)
  263. {
  264. addOptionPane((OptionPane) elem, child);
  265. }
  266. else if (elem instanceof OptionGroup)
  267. {
  268. addOptionGroup((OptionGroup) elem, child);
  269. }
  270. }
  271. parent.addOptionGroup(child);
  272. }
  273. private void addOptionPane(OptionPane pane, OptionGroup parent)
  274. {
  275. String name = pane.getName();
  276. cardPanel.add(pane.getComponent(), name);
  277. parent.addOptionPane(pane);
  278. }
  279. class PaneNameRenderer extends JLabel implements TreeCellRenderer
  280. {
  281. public PaneNameRenderer()
  282. {
  283. setOpaque(true);
  284. paneFont = UIManager.getFont("Tree.font");
  285. groupFont = new Font(paneFont.getName(),
  286. paneFont.getStyle() | Font.BOLD,
  287. paneFont.getSize());
  288. }
  289. public Component getTreeCellRendererComponent(JTree tree,
  290. Object value, boolean selected, boolean expanded,
  291. boolean leaf, int row, boolean hasFocus)
  292. {
  293. if (selected)
  294. {
  295. this.setBackground(UIManager.getColor(
  296. "Tree.selectionBackground"));
  297. this.setForeground(UIManager.getColor(
  298. "Tree.selectionForeground"));
  299. }
  300. else
  301. {
  302. this.setBackground(UIManager.getColor(
  303. "Tree.background"));
  304. this.setForeground(UIManager.getColor(
  305. "Tree.foreground"));
  306. }
  307. String name = null;
  308. if (value instanceof OptionGroup)
  309. {
  310. name = ((OptionGroup)value).getName();
  311. this.setFont(groupFont);
  312. }
  313. else if (value instanceof OptionPane)
  314. {
  315. name = ((OptionPane)value).getName();
  316. this.setFont(paneFont);
  317. }
  318. if (name == null)
  319. {
  320. setText(null);
  321. }
  322. else
  323. {
  324. String label = jEdit.getProperty("options." +
  325. name + ".label");
  326. if (label == null)
  327. {
  328. setText(name);
  329. }
  330. else
  331. {
  332. setText(label);
  333. }
  334. }
  335. setIcon(null);
  336. return this;
  337. }
  338. private Border noFocusBorder = BorderFactory.createEmptyBorder(
  339. 1, 1, 1, 1);
  340. private Border focusBorder = BorderFactory.createLineBorder(
  341. UIManager.getColor("Tree.selectionBorderColor"));
  342. private Font paneFont;
  343. private Font groupFont;
  344. }
  345. class OptionTreeModel implements TreeModel
  346. {
  347. public void addTreeModelListener(TreeModelListener l)
  348. {
  349. listenerList.add(TreeModelListener.class, l);
  350. }
  351. public void removeTreeModelListener(TreeModelListener l)
  352. {
  353. listenerList.remove(TreeModelListener.class, l);
  354. }
  355. public Object getChild(Object parent, int index)
  356. {
  357. if (parent instanceof OptionGroup)
  358. {
  359. return ((OptionGroup)parent).getMember(index);
  360. }
  361. else
  362. {
  363. return null;
  364. }
  365. }
  366. public int getChildCount(Object parent)
  367. {
  368. if (parent instanceof OptionGroup)
  369. {
  370. return ((OptionGroup)parent).getMemberCount();
  371. }
  372. else
  373. {
  374. return 0;
  375. }
  376. }
  377. public int getIndexOfChild(Object parent, Object child)
  378. {
  379. if (parent instanceof OptionGroup)
  380. {
  381. return ((OptionGroup)parent)
  382. .getMemberIndex(child);
  383. }
  384. else
  385. {
  386. return -1;
  387. }
  388. }
  389. public Object getRoot()
  390. {
  391. return root;
  392. }
  393. public boolean isLeaf(Object node)
  394. {
  395. return node instanceof OptionPane;
  396. }
  397. public void valueForPathChanged(TreePath path, Object newValue)
  398. {
  399. // this model may not be changed by the TableCellEditor
  400. }
  401. protected void fireNodesChanged(Object source, Object[] path,
  402. int[] childIndices, Object[] children)
  403. {
  404. Object[] listeners = listenerList.getListenerList();
  405. TreeModelEvent modelEvent = null;
  406. for (int i = listeners.length - 2; i >= 0; i -= 2)
  407. {
  408. if (listeners[i] != TreeModelListener.class)
  409. continue;
  410. if (modelEvent == null)
  411. {
  412. modelEvent = new TreeModelEvent(source,
  413. path, childIndices, children);
  414. }
  415. ((TreeModelListener)listeners[i + 1])
  416. .treeNodesChanged(modelEvent);
  417. }
  418. }
  419. protected void fireNodesInserted(Object source, Object[] path,
  420. int[] childIndices, Object[] children)
  421. {
  422. Object[] listeners = listenerList.getListenerList();
  423. TreeModelEvent modelEvent = null;
  424. for (int i = listeners.length - 2; i >= 0; i -= 2)
  425. {
  426. if (listeners[i] != TreeModelListener.class)
  427. continue;
  428. if (modelEvent == null)
  429. {
  430. modelEvent = new TreeModelEvent(source,
  431. path, childIndices, children);
  432. }
  433. ((TreeModelListener)listeners[i + 1])
  434. .treeNodesInserted(modelEvent);
  435. }
  436. }
  437. protected void fireNodesRemoved(Object source, Object[] path,
  438. int[] childIndices, Object[] children)
  439. {
  440. Object[] listeners = listenerList.getListenerList();
  441. TreeModelEvent modelEvent = null;
  442. for (int i = listeners.length - 2; i >= 0; i -= 2)
  443. {
  444. if (listeners[i] != TreeModelListener.class)
  445. continue;
  446. if (modelEvent == null)
  447. {
  448. modelEvent = new TreeModelEvent(source,
  449. path, childIndices, children);
  450. }
  451. ((TreeModelListener)listeners[i + 1])
  452. .treeNodesRemoved(modelEvent);
  453. }
  454. }
  455. protected void fireTreeStructureChanged(Object source,
  456. Object[] path, int[] childIndices, Object[] children)
  457. {
  458. Object[] listeners = listenerList.getListenerList();
  459. TreeModelEvent modelEvent = null;
  460. for (int i = listeners.length - 2; i >= 0; i -= 2)
  461. {
  462. if (listeners[i] != TreeModelListener.class)
  463. continue;
  464. if (modelEvent == null)
  465. {
  466. modelEvent = new TreeModelEvent(source,
  467. path, childIndices, children);
  468. }
  469. ((TreeModelListener)listeners[i + 1])
  470. .treeStructureChanged(modelEvent);
  471. }
  472. }
  473. private OptionGroup root = new OptionGroup("root");
  474. private EventListenerList listenerList = new EventListenerList();
  475. }
  476. }