PageRenderTime 45ms CodeModel.GetById 19ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/gui/AbstractContextOptionPane.java

#
Java | 339 lines | 229 code | 35 blank | 75 comment | 38 complexity | 3660d276526c3eb154223e6bffd204e5 MD5 | raw file
  1/*
  2 * Copyright (C) 2000, 2001 Slava Pestov
  3 *
  4 * This program is free software; you can redistribute it and/or
  5 * modify it under the terms of the GNU General Public License
  6 * as published by the Free Software Foundation; either version 2
  7 * of the License, or any later version.
  8 *
  9 * This program is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write to the Free Software
 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 17 */
 18
 19package org.gjt.sp.jedit.gui;
 20
 21import javax.swing.border.*;
 22import javax.swing.event.*;
 23import javax.swing.*;
 24import java.awt.event.*;
 25import java.awt.*;
 26import java.util.*;
 27
 28import org.gjt.sp.jedit.*;
 29import org.gjt.sp.jedit.browser.VFSBrowser;
 30import org.gjt.sp.util.StandardUtilities;
 31
 32/**
 33 * An abstract base class for context menu editors. Provides the base
 34 * UI and functionality for creating a context menu populated with
 35 * jEdit actions.
 36 *
 37 * @author Slava Pestov
 38 * @author Marcelo Vanzin
 39 * @version $Id: AbstractContextOptionPane.java 19655 2011-07-07 10:02:06Z kpouer $
 40 * @since jEdit 4.3pre13
 41 */
 42public abstract class AbstractContextOptionPane extends AbstractOptionPane
 43{
 44	private final ActionContext actionContext;
 45
 46	/**
 47	 * Constructor that takes a name as an argument, for use by
 48	 * subclasses.
 49	 *
 50	 * @param name    Name of the option pane.
 51	 * @param caption String to use as the caption of the context menu
 52	 *                configuration list.
 53	 * @since jEdit 4.3pre13
 54	 */
 55	protected AbstractContextOptionPane(String name, String caption)
 56	{
 57		this(name, caption, jEdit.getActionContext());
 58	}
 59
 60	/**
 61	 * Constructor that takes a name as an argument, for use by
 62	 * subclasses.
 63	 *
 64	 * @param name    Name of the option pane.
 65	 * @param caption String to use as the caption of the context menu
 66	 *                configuration list.
 67	 * @param actionContext the actionContext
 68	 * @since jEdit 4.5pre1
 69	 */
 70	protected AbstractContextOptionPane(String name, String caption, ActionContext actionContext)
 71	{
 72		super(name);
 73		this.actionContext = actionContext;
 74		this.caption = new JLabel(caption);
 75	}
 76
 77	/**
 78	 * Initializes the pane's UI.
 79	 */
 80	@Override
 81	protected void _init()
 82	{
 83		setLayout(new BorderLayout());
 84
 85		add(BorderLayout.NORTH, caption);
 86
 87		listModel = new DefaultListModel();
 88		reloadContextList(getContextMenu());
 89
 90		list = new JList(listModel);
 91		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 92		list.addListSelectionListener(new ListHandler());
 93
 94		add(BorderLayout.CENTER, new JScrollPane(list));
 95
 96		buttons = new JPanel();
 97		buttons.setBorder(new EmptyBorder(3, 0, 0, 0));
 98		buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
 99		ActionHandler actionHandler = new ActionHandler();
100		add = new RolloverButton(GUIUtilities.loadIcon(jEdit.getProperty("options.context.add.icon")));
101		add.setToolTipText(jEdit.getProperty("common.add"));
102		add.addActionListener(actionHandler);
103		buttons.add(add);
104		buttons.add(Box.createHorizontalStrut(6));
105		remove = new RolloverButton(GUIUtilities.loadIcon(jEdit.getProperty("options.context.remove.icon")));
106		remove.setToolTipText(jEdit.getProperty("common.remove"));
107		remove.addActionListener(actionHandler);
108		buttons.add(remove);
109		buttons.add(Box.createHorizontalStrut(6));
110		moveUp = new RolloverButton(GUIUtilities.loadIcon(jEdit.getProperty("options.context.moveUp.icon")));
111		moveUp.setToolTipText(jEdit.getProperty("common.moveUp"));
112		moveUp.addActionListener(actionHandler);
113		buttons.add(moveUp);
114		buttons.add(Box.createHorizontalStrut(6));
115		moveDown = new RolloverButton(GUIUtilities.loadIcon(jEdit.getProperty("options.context.moveDown.icon")));
116		moveDown.setToolTipText(jEdit.getProperty("common.moveDown"));
117		moveDown.addActionListener(actionHandler);
118		buttons.add(moveDown);
119		buttons.add(Box.createGlue());
120
121		// add "reset to defaults" button
122		reset = new RolloverButton(GUIUtilities.loadIcon(jEdit.getProperty("options.context.reset.icon")));
123		reset.setToolTipText(jEdit.getProperty("options.context.reset"));
124		reset.addActionListener(actionHandler);
125		buttons.add(reset);
126
127		updateButtons();
128		add(BorderLayout.SOUTH, buttons);
129	}
130
131	/**
132	 * Returns the context menu to be edited. The default implementation
133	 * returns jEdit's context menu. Subclasses overriding this method
134	 * should also override {@link #saveContextMenu(String menu) saveContextMenu}.
135	 *
136	 * @since jEdit 4.3pre13
137	 */
138	protected abstract String getContextMenu();
139
140	/**
141	 * Saves the context menu configuration.
142	 *
143	 * @since jEdit 4.3pre13
144	 */
145	protected abstract void saveContextMenu(String menu);
146
147	/**
148	 * Adds a widget to the "buttons" panel at the bottom. The component
149	 * will be added at the very right of the button row (separated from
150	 * the normal buttons).
151	 *
152	 * @since jEdit 4.3pre13
153	 */
154	protected void addButton(JComponent c)
155	{
156		buttons.add(c);
157	}
158
159	static class MenuItemCompare implements Comparator<MenuItem>
160	{
161		@Override
162		public int compare(MenuItem obj1, MenuItem obj2)
163		{
164			return StandardUtilities.compareStrings(obj1.label, obj2.label, false);
165		}
166	}
167
168	@Override
169	protected void _save()
170	{
171		StringBuilder buf = new StringBuilder();
172		for (int i = 0; i < listModel.getSize(); i++)
173		{
174			if (i != 0)
175				buf.append(' ');
176			buf.append(((MenuItem) listModel.elementAt(i)).actionName);
177		}
178		saveContextMenu(buf.toString());
179	}
180
181	// private members
182	private DefaultListModel listModel;
183	private JList list;
184	private JButton add;
185	private JButton remove;
186	private JButton moveUp, moveDown;
187	private JButton reset;
188	private JLabel caption;
189	private JPanel buttons;
190
191	private void updateButtons()
192	{
193		int index = list.getSelectedIndex();
194		remove.setEnabled(index != -1 && listModel.getSize() != 0);
195		moveUp.setEnabled(index > 0);
196		moveDown.setEnabled(index != -1 && index != listModel.getSize() - 1);
197	}
198
199	private void reloadContextList(String contextMenu)
200	{
201		listModel.clear();
202		StringTokenizer st = new StringTokenizer(contextMenu);
203		while (st.hasMoreTokens())
204		{
205			String actionName = st.nextToken();
206			if (actionName.equals("-"))
207				listModel.addElement(new AbstractContextOptionPane.MenuItem("-", "-"));
208			else
209			{
210				EditAction action = actionContext.getAction(actionName);
211
212				if (action == null)
213					continue;
214				String label = action.getLabel();
215				if (label == null)
216					continue;
217				listModel.addElement(new AbstractContextOptionPane.MenuItem(actionName, label));
218			}
219		}
220	}
221
222	static class MenuItem
223	{
224		String actionName;
225		String label;
226
227		MenuItem(String actionName, String label)
228		{
229			this.actionName = actionName;
230			this.label = GUIUtilities.prettifyMenuLabel(label);
231		}
232
233		public String toString()
234		{
235			return label;
236		}
237	}
238
239	class ActionHandler implements ActionListener
240	{
241		@Override
242		public void actionPerformed(ActionEvent evt)
243		{
244			Object source = evt.getSource();
245
246			if (source == add)
247			{
248				ContextAddDialog dialog = new ContextAddDialog(
249					AbstractContextOptionPane.this, actionContext);
250				String selection = dialog.getSelection();
251				if (selection == null)
252					return;
253
254				int index = list.getSelectedIndex();
255				if (index == -1)
256					index = listModel.getSize();
257				else
258					index++;
259
260				MenuItem menuItem;
261				if (selection.equals("-"))
262					menuItem = new AbstractContextOptionPane.MenuItem("-", "-");
263				else
264				{
265					EditAction action = actionContext.getAction(selection);
266					String label = action
267						.getLabel();
268					menuItem = new AbstractContextOptionPane.MenuItem(selection,
269						label);
270				}
271
272				listModel.insertElementAt(menuItem, index);
273				list.setSelectedIndex(index);
274				list.ensureIndexIsVisible(index);
275			} else if (source == remove)
276			{
277				int index = list.getSelectedIndex();
278				listModel.removeElementAt(index);
279				if (listModel.getSize() != 0)
280				{
281					list.setSelectedIndex(
282						Math.min(listModel.getSize() - 1,
283							index));
284				}
285				updateButtons();
286			} else if (source == moveUp)
287			{
288				int index = list.getSelectedIndex();
289				Object selected = list.getSelectedValue();
290				listModel.removeElementAt(index);
291				listModel.insertElementAt(selected, index - 1);
292				list.setSelectedIndex(index - 1);
293				list.ensureIndexIsVisible(index - 1);
294			} else if (source == moveDown)
295			{
296				int index = list.getSelectedIndex();
297				Object selected = list.getSelectedValue();
298				listModel.removeElementAt(index);
299				listModel.insertElementAt(selected, index + 1);
300				list.setSelectedIndex(index + 1);
301				list.ensureIndexIsVisible(index + 1);
302			} else if (source == reset)
303			{
304				String dialogType = "options.context.reset.dialog";
305				int result = GUIUtilities.confirm(list, dialogType, null,
306					JOptionPane.YES_NO_OPTION,
307					JOptionPane.WARNING_MESSAGE);
308
309				if (result == JOptionPane.YES_OPTION)
310				{
311					// the user should be able to cancel the options dialog 
312					// so we need to modify the list, not the actual property
313					// since the default value is not available, 
314					// we reset, fetch default value and re-set to original
315					String orgContext = jEdit.getProperty("view.context");
316					jEdit.resetProperty("view.context");
317					String defaultContext = jEdit.getProperty("view.context");
318					jEdit.setProperty("view.context", orgContext);
319					reloadContextList(defaultContext);
320
321					// reset selection if user had more buttons than default
322					list.setSelectedIndex(0);
323					list.ensureIndexIsVisible(0);
324					updateButtons();
325				}
326			}
327		}
328	}
329
330	class ListHandler implements ListSelectionListener
331	{
332		@Override
333		public void valueChanged(ListSelectionEvent evt)
334		{
335			updateButtons();
336		}
337	}
338}
339