PageRenderTime 120ms CodeModel.GetById 99ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

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

#
Java | 554 lines | 419 code | 94 blank | 41 comment | 58 complexity | 646acbf017ca7ffdea1b1f76cc2b3829 MD5 | raw file
  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
 21package org.gjt.sp.jedit.gui;
 22
 23import javax.swing.*;
 24import javax.swing.border.*;
 25import javax.swing.event.*;
 26import javax.swing.tree.*;
 27import java.awt.*;
 28import java.awt.event.*;
 29import java.util.*;
 30import org.gjt.sp.jedit.*;
 31import org.gjt.sp.jedit.options.*;
 32import org.gjt.sp.util.Log;
 33
 34/**
 35 * An abstract tabbed options dialog box.
 36 * @author Slava Pestov
 37 * @version $Id: OptionsDialog.java 3972 2002-01-17 10:37:55Z spestov $
 38 */
 39public class OptionsDialog extends EnhancedDialog
 40	implements ActionListener, TreeSelectionListener
 41{
 42	public OptionsDialog(View view)
 43	{
 44		super(view, jEdit.getProperty("options.title"), true);
 45
 46		view.showWaitCursor();
 47
 48		JPanel content = new JPanel(new BorderLayout());
 49		content.setBorder(new EmptyBorder(12,12,12,12));
 50		setContentPane(content);
 51
 52		content.setLayout(new BorderLayout());
 53
 54		JPanel stage = new JPanel(new BorderLayout());
 55		stage.setBorder(new EmptyBorder(0,6,0,0));
 56		content.add(stage, BorderLayout.CENTER);
 57
 58		// currentLabel displays the path of the currently selected
 59		// OptionPane at the top of the stage area
 60		currentLabel = new JLabel();
 61		currentLabel.setHorizontalAlignment(JLabel.LEFT);
 62		currentLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1,
 63			0, Color.black));
 64		stage.add(currentLabel, BorderLayout.NORTH);
 65
 66		cardPanel = new JPanel(new CardLayout());
 67		cardPanel.setBorder(new EmptyBorder(5,0,0,0));
 68		stage.add(cardPanel, BorderLayout.CENTER);
 69
 70		paneTree = new JTree(createOptionTreeModel());
 71
 72		paneTree.setCellRenderer(new PaneNameRenderer());
 73		paneTree.putClientProperty("JTree.lineStyle", "Angled");
 74		paneTree.setShowsRootHandles(true);
 75		paneTree.setRootVisible(false);
 76		content.add(new JScrollPane(paneTree,
 77			JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
 78			JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
 79			BorderLayout.WEST);
 80
 81		JPanel buttons = new JPanel();
 82		buttons.setBorder(new EmptyBorder(12,0,0,0));
 83		buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS));
 84		buttons.add(Box.createGlue());
 85
 86		ok = new JButton(jEdit.getProperty("common.ok"));
 87		ok.addActionListener(this);
 88		buttons.add(ok);
 89		buttons.add(Box.createHorizontalStrut(6));
 90		getRootPane().setDefaultButton(ok);
 91		cancel = new JButton(jEdit.getProperty("common.cancel"));
 92		cancel.addActionListener(this);
 93		buttons.add(cancel);
 94		buttons.add(Box.createHorizontalStrut(6));
 95		apply = new JButton(jEdit.getProperty("common.apply"));
 96		apply.addActionListener(this);
 97		buttons.add(apply);
 98
 99		buttons.add(Box.createGlue());
100
101		content.add(buttons, BorderLayout.SOUTH);
102
103		// register the Options dialog as a TreeSelectionListener.
104		// this is done before the initial selection to ensure that the
105		// first selected OptionPane is displayed on startup.
106		paneTree.getSelectionModel().addTreeSelectionListener(this);
107
108		paneTree.expandPath(new TreePath(
109			new Object[] { paneTree.getModel().getRoot(), jEditGroup }));
110		paneTree.setSelectionRow(0);
111
112		view.hideWaitCursor();
113
114		pack();
115		setLocationRelativeTo(view);
116		show();
117	}
118
119	public void addOptionGroup(OptionGroup group)
120	{
121		addOptionGroup(group, pluginsGroup);
122	}
123
124	public void addOptionPane(OptionPane pane)
125	{
126		addOptionPane(pane, pluginsGroup);
127	}
128
129	// EnhancedDialog implementation
130	public void ok()
131	{
132		ok(true);
133	}
134
135	public void cancel()
136	{
137		dispose();
138	}
139	// end EnhancedDialog implementation
140
141	public void ok(boolean dispose)
142	{
143		OptionTreeModel m = (OptionTreeModel) paneTree
144			.getModel();
145		((OptionGroup) m.getRoot()).save();
146
147		/* This will fire the PROPERTIES_CHANGED event */
148		jEdit.propertiesChanged();
149
150		// Save settings to disk
151		jEdit.saveSettings();
152
153		// get rid of this dialog if necessary
154		if(dispose)
155			dispose();
156	}
157
158	public void actionPerformed(ActionEvent evt)
159	{
160		Object source = evt.getSource();
161
162		if(source == ok)
163		{
164			ok();
165		}
166		else if(source == cancel)
167		{
168			cancel();
169		}
170		else if(source == apply)
171		{
172			ok(false);
173		}
174	}
175
176	public void valueChanged(TreeSelectionEvent evt)
177	{
178		TreePath path = evt.getPath();
179
180		if (path == null || !(path.getLastPathComponent() instanceof
181			OptionPane)) return;
182
183		Object[] nodes = path.getPath();
184
185		StringBuffer buf = new StringBuffer();
186
187		OptionPane optionPane = null;
188		String name = null;
189
190		int lastIdx = nodes.length - 1;
191
192		for (int i = paneTree.isRootVisible() ? 0 : 1;
193			i <= lastIdx; i++)
194		{
195			if (nodes[i] instanceof OptionPane)
196			{
197				optionPane = (OptionPane)nodes[i];
198				name = optionPane.getName();
199			}
200			else if (nodes[i] instanceof OptionGroup)
201			{
202				name = ((OptionGroup)nodes[i]).getName();
203			}
204			else
205			{
206				continue;
207			}
208
209			if (name != null)
210			{
211				String label = jEdit.getProperty("options." +
212					name + ".label");
213
214				if (label == null)
215				{
216					buf.append(name);
217				}
218				else
219				{
220					buf.append(label);
221				}
222			}
223
224			if (i != lastIdx) buf.append(": ");
225		}
226
227		currentLabel.setText(buf.toString());
228
229		optionPane.init();
230
231		pack();
232		((CardLayout)cardPanel.getLayout()).show(cardPanel, name);
233	}
234
235	// private members
236	private Hashtable panes;
237	private JTree paneTree;
238	private JPanel cardPanel;
239	private JLabel currentLabel;
240	private JButton ok;
241	private JButton cancel;
242	private JButton apply;
243	private OptionGroup jEditGroup;
244	private OptionGroup pluginsGroup;
245
246	private OptionTreeModel createOptionTreeModel()
247	{
248		OptionTreeModel paneTreeModel = new OptionTreeModel();
249		OptionGroup rootGroup = (OptionGroup) paneTreeModel.getRoot();
250
251		addOptionPane(new OverviewOptionPane(), rootGroup);
252
253		// initialize the jEdit branch of the options tree
254		jEditGroup = new OptionGroup("jedit");
255
256		addOptionPane(new GeneralOptionPane(), jEditGroup);
257		addOptionPane(new AppearanceOptionPane(), jEditGroup);
258		addOptionPane(new TextAreaOptionPane(), jEditGroup);
259		addOptionPane(new GutterOptionPane(), jEditGroup);
260		addOptionPane(new ColorOptionPane(), jEditGroup);
261		addOptionPane(new StyleOptionPane(), jEditGroup);
262		addOptionPane(new LoadSaveOptionPane(), jEditGroup);
263		addOptionPane(new EditingOptionPane(), jEditGroup);
264		addOptionPane(new ModeOptionPane(), jEditGroup);
265		addOptionPane(new ShortcutsOptionPane(), jEditGroup);
266		addOptionPane(new DockingOptionPane(), jEditGroup);
267		addOptionPane(new ContextOptionPane(), jEditGroup);
268		addOptionPane(new ToolBarOptionPane(), jEditGroup);
269		addOptionPane(new AbbrevsOptionPane(), jEditGroup);
270		addOptionPane(new PrintOptionPane(), jEditGroup);
271		addOptionPane(new FirewallOptionPane(), jEditGroup);
272
273		OptionGroup browserGroup = new OptionGroup("browser");
274		addOptionPane(new BrowserOptionPane(), browserGroup);
275		addOptionPane(new BrowserColorsOptionPane(), browserGroup);
276		addOptionGroup(browserGroup, jEditGroup);
277
278		addOptionGroup(jEditGroup, rootGroup);
279
280		// initialize the Plugins branch of the options tree
281		pluginsGroup = new OptionGroup("plugins");
282
283		// Query plugins for option panes
284		EditPlugin[] plugins = jEdit.getPlugins();
285		for(int i = 0; i < plugins.length; i++)
286		{
287			EditPlugin ep = plugins[i];
288			try
289			{
290				ep.createOptionPanes(this);
291			}
292			catch(Throwable t)
293			{
294				Log.log(Log.ERROR, ep,
295					"Error creating option pane");
296				Log.log(Log.ERROR, ep, t);
297			}
298		}
299
300		// only add the Plugins branch if there are OptionPanes
301		if (pluginsGroup.getMemberCount() > 0)
302		{
303			addOptionGroup(pluginsGroup, rootGroup);
304		}
305
306		return paneTreeModel;
307	}
308
309	private void addOptionGroup(OptionGroup child, OptionGroup parent)
310	{
311		Enumeration enum = child.getMembers();
312
313		while (enum.hasMoreElements())
314		{
315			Object elem = enum.nextElement();
316
317			if (elem instanceof OptionPane)
318			{
319				addOptionPane((OptionPane) elem, child);
320			}
321			else if (elem instanceof OptionGroup)
322			{
323				addOptionGroup((OptionGroup) elem, child);
324			}
325		}
326
327		parent.addOptionGroup(child);
328	}
329
330	private void addOptionPane(OptionPane pane, OptionGroup parent)
331	{
332		String name = pane.getName();
333
334		cardPanel.add(pane.getComponent(), name);
335
336		parent.addOptionPane(pane);
337	}
338
339	class PaneNameRenderer extends DefaultTreeCellRenderer
340	{
341		public PaneNameRenderer()
342		{
343			paneFont = UIManager.getFont("Tree.font");
344			groupFont = paneFont.deriveFont(Font.BOLD);
345		}
346
347		public Component getTreeCellRendererComponent(JTree tree,
348			Object value, boolean selected, boolean expanded,
349			boolean leaf, int row, boolean hasFocus)
350		{
351			super.getTreeCellRendererComponent(tree,value,
352				selected,expanded,leaf,row,hasFocus);
353
354			String name = null;
355
356			if (value instanceof OptionGroup)
357			{
358				name = ((OptionGroup)value).getName();
359				this.setFont(groupFont);
360			}
361			else if (value instanceof OptionPane)
362			{
363				name = ((OptionPane)value).getName();
364				this.setFont(paneFont);
365			}
366
367			if (name == null)
368			{
369				setText(null);
370			}
371			else
372			{
373				String label = jEdit.getProperty("options." +
374					name + ".label");
375
376				if (label == null)
377				{
378					// hahaha, suckers!!!
379					Log.log(Log.WARNING,this,
380						"options." + name + ".label"
381						+ " property not defined");
382					setText(name);
383				}
384				else
385				{
386					setText(label);
387				}
388			}
389
390			setIcon(null);
391
392			return this;
393		}
394
395		private Font paneFont;
396		private Font groupFont;
397	}
398
399	class OptionTreeModel implements TreeModel
400	{
401		public void addTreeModelListener(TreeModelListener l)
402		{
403			listenerList.add(TreeModelListener.class, l);
404		}
405
406		public void removeTreeModelListener(TreeModelListener l)
407		{
408			listenerList.remove(TreeModelListener.class, l);
409		}
410
411		public Object getChild(Object parent, int index)
412		{
413			if (parent instanceof OptionGroup)
414			{
415				return ((OptionGroup)parent).getMember(index);
416			}
417			else
418			{
419				return null;
420			}
421		}
422
423		public int getChildCount(Object parent)
424		{
425			if (parent instanceof OptionGroup)
426			{
427				return ((OptionGroup)parent).getMemberCount();
428			}
429			else
430			{
431				return 0;
432			}
433		}
434
435		public int getIndexOfChild(Object parent, Object child)
436		{
437			if (parent instanceof OptionGroup)
438			{
439				return ((OptionGroup)parent)
440					.getMemberIndex(child);
441			}
442			else
443			{
444				return -1;
445			}
446		}
447
448		public Object getRoot()
449		{
450			return root;
451		}
452
453		public boolean isLeaf(Object node)
454		{
455			return node instanceof OptionPane;
456		}
457
458		public void valueForPathChanged(TreePath path, Object newValue)
459		{
460			// this model may not be changed by the TableCellEditor
461		}
462
463		protected void fireNodesChanged(Object source, Object[] path,
464			int[] childIndices, Object[] children)
465		{
466			Object[] listeners = listenerList.getListenerList();
467
468			TreeModelEvent modelEvent = null;
469			for (int i = listeners.length - 2; i >= 0; i -= 2)
470			{
471				if (listeners[i] != TreeModelListener.class)
472					continue;
473
474				if (modelEvent == null)
475				{
476					modelEvent = new TreeModelEvent(source,
477						path, childIndices, children);
478				}
479
480				((TreeModelListener)listeners[i + 1])
481					.treeNodesChanged(modelEvent);
482			}
483		}
484
485		protected void fireNodesInserted(Object source, Object[] path,
486			int[] childIndices, Object[] children)
487		{
488			Object[] listeners = listenerList.getListenerList();
489
490			TreeModelEvent modelEvent = null;
491			for (int i = listeners.length - 2; i >= 0; i -= 2)
492			{
493				if (listeners[i] != TreeModelListener.class)
494					continue;
495
496				if (modelEvent == null)
497				{
498					modelEvent = new TreeModelEvent(source,
499						path, childIndices, children);
500				}
501
502				((TreeModelListener)listeners[i + 1])
503					.treeNodesInserted(modelEvent);
504			}
505		}
506
507		protected void fireNodesRemoved(Object source, Object[] path,
508			int[] childIndices, Object[] children)
509		{
510			Object[] listeners = listenerList.getListenerList();
511
512			TreeModelEvent modelEvent = null;
513			for (int i = listeners.length - 2; i >= 0; i -= 2)
514			{
515				if (listeners[i] != TreeModelListener.class)
516					continue;
517
518				if (modelEvent == null)
519				{
520					modelEvent = new TreeModelEvent(source,
521						path, childIndices, children);
522				}
523
524				((TreeModelListener)listeners[i + 1])
525					.treeNodesRemoved(modelEvent);
526			}
527		}
528
529		protected void fireTreeStructureChanged(Object source,
530			Object[] path, int[] childIndices, Object[] children)
531		{
532			Object[] listeners = listenerList.getListenerList();
533
534			TreeModelEvent modelEvent = null;
535			for (int i = listeners.length - 2; i >= 0; i -= 2)
536			{
537				if (listeners[i] != TreeModelListener.class)
538					continue;
539
540				if (modelEvent == null)
541				{
542					modelEvent = new TreeModelEvent(source,
543						path, childIndices, children);
544				}
545
546				((TreeModelListener)listeners[i + 1])
547					.treeStructureChanged(modelEvent);
548			}
549		}
550
551		private OptionGroup root = new OptionGroup(null);
552		private EventListenerList listenerList = new EventListenerList();
553	}
554}