PageRenderTime 39ms CodeModel.GetById 2ms app.highlight 33ms 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
  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 3827 2001-10-05 08:55:14Z 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		// compute the jEdit branch
104		TreePath jEditPath = new TreePath(new Object[]{ paneTree
105			.getModel().getRoot(), jEditGroup });
106
107		// register the Options dialog as a TreeSelectionListener.
108		// this is done before the initial selection to ensure that the
109		// first selected OptionPane is displayed on startup.
110		paneTree.getSelectionModel().addTreeSelectionListener(this);
111
112		// select the first member of the jEdit group
113		paneTree.setSelectionPath(jEditPath.pathByAddingChild(
114			jEditGroup.getMember(0)));
115
116		view.hideWaitCursor();
117
118		pack();
119		setLocationRelativeTo(view);
120		show();
121	}
122
123	public void addOptionGroup(OptionGroup group)
124	{
125		addOptionGroup(group, pluginsGroup);
126	}
127
128	public void addOptionPane(OptionPane pane)
129	{
130		addOptionPane(pane, pluginsGroup);
131	}
132
133	// EnhancedDialog implementation
134	public void ok()
135	{
136		ok(true);
137	}
138
139	public void cancel()
140	{
141		dispose();
142	}
143	// end EnhancedDialog implementation
144
145	public void ok(boolean dispose)
146	{
147		OptionTreeModel m = (OptionTreeModel) paneTree
148			.getModel();
149		((OptionGroup) m.getRoot()).save();
150
151		/* This will fire the PROPERTIES_CHANGED event */
152		jEdit.propertiesChanged();
153
154		// Save settings to disk
155		jEdit.saveSettings();
156
157		// get rid of this dialog if necessary
158		if(dispose)
159			dispose();
160	}
161
162	public void actionPerformed(ActionEvent evt)
163	{
164		Object source = evt.getSource();
165
166		if(source == ok)
167		{
168			ok();
169		}
170		else if(source == cancel)
171		{
172			cancel();
173		}
174		else if(source == apply)
175		{
176			ok(false);
177		}
178	}
179
180	public void valueChanged(TreeSelectionEvent evt)
181	{
182		TreePath path = evt.getPath();
183
184		if (path == null || !(path.getLastPathComponent() instanceof
185			OptionPane)) return;
186
187		Object[] nodes = path.getPath();
188
189		StringBuffer buf = new StringBuffer();
190
191		OptionPane optionPane = null;
192		String name = null;
193
194		int lastIdx = nodes.length - 1;
195
196		for (int i = paneTree.isRootVisible() ? 0 : 1;
197			i <= lastIdx; i++)
198		{
199			if (nodes[i] instanceof OptionPane)
200			{
201				optionPane = (OptionPane)nodes[i];
202				name = optionPane.getName();
203			}
204			else if (nodes[i] instanceof OptionGroup)
205			{
206				name = ((OptionGroup)nodes[i]).getName();
207			}
208			else
209			{
210				continue;
211			}
212
213			if (name != null)
214			{
215				String label = jEdit.getProperty("options." +
216					name + ".label");
217
218				if (label == null)
219				{
220					buf.append(name);
221				}
222				else
223				{
224					buf.append(label);
225				}
226			}
227
228			if (i != lastIdx) buf.append(": ");
229		}
230
231		currentLabel.setText(buf.toString());
232
233		optionPane.init();
234
235		pack();
236		((CardLayout)cardPanel.getLayout()).show(cardPanel, name);
237	}
238
239	// private members
240	private Hashtable panes;
241	private JTree paneTree;
242	private JPanel cardPanel;
243	private JLabel currentLabel;
244	private JButton ok;
245	private JButton cancel;
246	private JButton apply;
247	private OptionGroup jEditGroup;
248	private OptionGroup pluginsGroup;
249
250	private OptionTreeModel createOptionTreeModel()
251	{
252		OptionTreeModel paneTreeModel = new OptionTreeModel();
253		OptionGroup rootGroup = (OptionGroup) paneTreeModel.getRoot();
254
255		// initialize the jEdit branch of the options tree
256		jEditGroup = new OptionGroup("jedit");
257
258		addOptionPane(new GeneralOptionPane(), jEditGroup);
259		addOptionPane(new AppearanceOptionPane(), jEditGroup);
260		addOptionPane(new TextAreaOptionPane(), jEditGroup);
261		addOptionPane(new GutterOptionPane(), jEditGroup);
262		addOptionPane(new ColorOptionPane(), jEditGroup);
263		addOptionPane(new StyleOptionPane(), jEditGroup);
264		addOptionPane(new LoadSaveOptionPane(), jEditGroup);
265		addOptionPane(new EditingOptionPane(), jEditGroup);
266		addOptionPane(new ModeOptionPane(), jEditGroup);
267		addOptionPane(new ShortcutsOptionPane(), jEditGroup);
268		addOptionPane(new DockingOptionPane(), jEditGroup);
269		addOptionPane(new ContextOptionPane(), jEditGroup);
270		addOptionPane(new ToolBarOptionPane(), jEditGroup);
271		addOptionPane(new AbbrevsOptionPane(), jEditGroup);
272		addOptionPane(new PrintOptionPane(), jEditGroup);
273
274		OptionGroup browserGroup = new OptionGroup("browser");
275		addOptionPane(new BrowserOptionPane(), browserGroup);
276		addOptionPane(new BrowserColorsOptionPane(), browserGroup);
277		addOptionGroup(browserGroup, jEditGroup);
278
279		addOptionGroup(jEditGroup, rootGroup);
280
281		// initialize the Plugins branch of the options tree
282		pluginsGroup = new OptionGroup("plugins");
283
284		// Query plugins for option panes
285		EditPlugin[] plugins = jEdit.getPlugins();
286		for(int i = 0; i < plugins.length; i++)
287		{
288			EditPlugin ep = plugins[i];
289			try
290			{
291				ep.createOptionPanes(this);
292			}
293			catch(Throwable t)
294			{
295				Log.log(Log.ERROR, ep,
296					"Error creating option pane");
297				Log.log(Log.ERROR, ep, t);
298			}
299		}
300
301		// only add the Plugins branch if there are OptionPanes
302		if (pluginsGroup.getMemberCount() > 0)
303		{
304			addOptionGroup(pluginsGroup, rootGroup);
305		}
306
307		return paneTreeModel;
308	}
309
310	private void addOptionGroup(OptionGroup child, OptionGroup parent)
311	{
312		Enumeration enum = child.getMembers();
313
314		while (enum.hasMoreElements())
315		{
316			Object elem = enum.nextElement();
317
318			if (elem instanceof OptionPane)
319			{
320				addOptionPane((OptionPane) elem, child);
321			}
322			else if (elem instanceof OptionGroup)
323			{
324				addOptionGroup((OptionGroup) elem, child);
325			}
326		}
327
328		parent.addOptionGroup(child);
329	}
330
331	private void addOptionPane(OptionPane pane, OptionGroup parent)
332	{
333		String name = pane.getName();
334
335		cardPanel.add(pane.getComponent(), name);
336
337		parent.addOptionPane(pane);
338	}
339
340	class PaneNameRenderer extends JLabel implements TreeCellRenderer
341	{
342		public PaneNameRenderer()
343		{
344			setOpaque(true);
345
346			paneFont = UIManager.getFont("Tree.font");
347			groupFont = new Font(paneFont.getName(),
348				paneFont.getStyle() | Font.BOLD,
349				paneFont.getSize());
350		}
351
352		public Component getTreeCellRendererComponent(JTree tree,
353			Object value, boolean selected, boolean expanded,
354			boolean leaf, int row, boolean hasFocus)
355		{
356			if (selected)
357			{
358				this.setBackground(UIManager.getColor(
359					"Tree.selectionBackground"));
360				this.setForeground(UIManager.getColor(
361					"Tree.selectionForeground"));
362			}
363			else
364			{
365				this.setBackground(UIManager.getColor(
366					"Tree.background"));
367				this.setForeground(UIManager.getColor(
368					"Tree.foreground"));
369			}
370
371			String name = null;
372
373			if (value instanceof OptionGroup)
374			{
375				name = ((OptionGroup)value).getName();
376				this.setFont(groupFont);
377			}
378			else if (value instanceof OptionPane)
379			{
380				name = ((OptionPane)value).getName();
381				this.setFont(paneFont);
382			}
383
384			if (name == null)
385			{
386				setText(null);
387			}
388			else
389			{
390				String label = jEdit.getProperty("options." +
391					name + ".label");
392
393				if (label == null)
394				{
395					setText(name);
396				}
397				else
398				{
399					setText(label);
400				}
401			}
402
403			setIcon(null);
404
405			return this;
406		}
407
408		private Border noFocusBorder = BorderFactory.createEmptyBorder(
409			1, 1, 1, 1);
410		private Border focusBorder = BorderFactory.createLineBorder(
411			UIManager.getColor("Tree.selectionBorderColor"));
412
413		private Font paneFont;
414		private Font groupFont;
415	}
416
417	class OptionTreeModel implements TreeModel
418	{
419		public void addTreeModelListener(TreeModelListener l)
420		{
421			listenerList.add(TreeModelListener.class, l);
422		}
423
424		public void removeTreeModelListener(TreeModelListener l)
425		{
426			listenerList.remove(TreeModelListener.class, l);
427		}
428
429		public Object getChild(Object parent, int index)
430		{
431			if (parent instanceof OptionGroup)
432			{
433				return ((OptionGroup)parent).getMember(index);
434			}
435			else
436			{
437				return null;
438			}
439		}
440
441		public int getChildCount(Object parent)
442		{
443			if (parent instanceof OptionGroup)
444			{
445				return ((OptionGroup)parent).getMemberCount();
446			}
447			else
448			{
449				return 0;
450			}
451		}
452
453		public int getIndexOfChild(Object parent, Object child)
454		{
455			if (parent instanceof OptionGroup)
456			{
457				return ((OptionGroup)parent)
458					.getMemberIndex(child);
459			}
460			else
461			{
462				return -1;
463			}
464		}
465
466		public Object getRoot()
467		{
468			return root;
469		}
470
471		public boolean isLeaf(Object node)
472		{
473			return node instanceof OptionPane;
474		}
475
476		public void valueForPathChanged(TreePath path, Object newValue)
477		{
478			// this model may not be changed by the TableCellEditor
479		}
480
481		protected void fireNodesChanged(Object source, Object[] path,
482			int[] childIndices, Object[] children)
483		{
484			Object[] listeners = listenerList.getListenerList();
485
486			TreeModelEvent modelEvent = null;
487			for (int i = listeners.length - 2; i >= 0; i -= 2)
488			{
489				if (listeners[i] != TreeModelListener.class)
490					continue;
491
492				if (modelEvent == null)
493				{
494					modelEvent = new TreeModelEvent(source,
495						path, childIndices, children);
496				}
497
498				((TreeModelListener)listeners[i + 1])
499					.treeNodesChanged(modelEvent);
500			}
501		}
502
503		protected void fireNodesInserted(Object source, Object[] path,
504			int[] childIndices, Object[] children)
505		{
506			Object[] listeners = listenerList.getListenerList();
507
508			TreeModelEvent modelEvent = null;
509			for (int i = listeners.length - 2; i >= 0; i -= 2)
510			{
511				if (listeners[i] != TreeModelListener.class)
512					continue;
513
514				if (modelEvent == null)
515				{
516					modelEvent = new TreeModelEvent(source,
517						path, childIndices, children);
518				}
519
520				((TreeModelListener)listeners[i + 1])
521					.treeNodesInserted(modelEvent);
522			}
523		}
524
525		protected void fireNodesRemoved(Object source, Object[] path,
526			int[] childIndices, Object[] children)
527		{
528			Object[] listeners = listenerList.getListenerList();
529
530			TreeModelEvent modelEvent = null;
531			for (int i = listeners.length - 2; i >= 0; i -= 2)
532			{
533				if (listeners[i] != TreeModelListener.class)
534					continue;
535
536				if (modelEvent == null)
537				{
538					modelEvent = new TreeModelEvent(source,
539						path, childIndices, children);
540				}
541
542				((TreeModelListener)listeners[i + 1])
543					.treeNodesRemoved(modelEvent);
544			}
545		}
546
547		protected void fireTreeStructureChanged(Object source,
548			Object[] path, int[] childIndices, Object[] children)
549		{
550			Object[] listeners = listenerList.getListenerList();
551
552			TreeModelEvent modelEvent = null;
553			for (int i = listeners.length - 2; i >= 0; i -= 2)
554			{
555				if (listeners[i] != TreeModelListener.class)
556					continue;
557
558				if (modelEvent == null)
559				{
560					modelEvent = new TreeModelEvent(source,
561						path, childIndices, children);
562				}
563
564				((TreeModelListener)listeners[i + 1])
565					.treeStructureChanged(modelEvent);
566			}
567		}
568
569		private OptionGroup root = new OptionGroup("root");
570		private EventListenerList listenerList = new EventListenerList();
571	}
572}