PageRenderTime 51ms CodeModel.GetById 27ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/options/ShortcutsOptionPane.java

#
Java | 484 lines | 382 code | 54 blank | 48 comment | 44 complexity | 56c91bed05b0933d263788f91e7b1266 MD5 | raw file
  1/*
  2 * ShortcutsOptionPane.java - Shortcuts options panel
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 1999, 2000, 2001 Slava Pestov
  7 * Copyright (C) 2001 Dirk Moebius
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * as published by the Free Software Foundation; either version 2
 12 * of the License, or any later version.
 13 *
 14 * This program is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 17 * GNU General Public License for more details.
 18 *
 19 * You should have received a copy of the GNU General Public License
 20 * along with this program; if not, write to the Free Software
 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 22 */
 23
 24package org.gjt.sp.jedit.options;
 25
 26//{{{ Imports
 27import org.gjt.sp.jedit.*;
 28import org.gjt.sp.jedit.gui.FilteredTableModel;
 29import org.gjt.sp.jedit.gui.GrabKeyDialog;
 30import org.gjt.sp.jedit.gui.GrabKeyDialog.KeyBinding;
 31import org.gjt.sp.util.Log;
 32import org.gjt.sp.util.StandardUtilities;
 33
 34import javax.swing.*;
 35import javax.swing.event.DocumentEvent;
 36import javax.swing.event.DocumentListener;
 37import javax.swing.table.AbstractTableModel;
 38import java.awt.*;
 39import java.awt.event.ActionEvent;
 40import java.awt.event.ActionListener;
 41import java.awt.event.MouseAdapter;
 42import java.awt.event.MouseEvent;
 43import java.util.*;
 44import java.util.List;
 45//}}}
 46
 47/**
 48 * Key binding editor.
 49 * @author Slava Pestov
 50 * @version $Id: ShortcutsOptionPane.java 19268 2011-01-25 14:16:18Z kpouer $
 51 */
 52public class ShortcutsOptionPane extends AbstractOptionPane
 53{
 54	//{{{ ShortcutsOptionPane constructor
 55	public ShortcutsOptionPane()
 56	{
 57		super("shortcuts");
 58	} //}}}
 59
 60	//{{{ _init() method
 61	@Override
 62	protected void _init()
 63	{
 64		allBindings = new Vector<KeyBinding>();
 65
 66		setLayout(new BorderLayout(12,12));
 67
 68		initModels();
 69
 70		selectModel = new JComboBox(models);
 71		selectModel.addActionListener(new ActionHandler());
 72		selectModel.setToolTipText(jEdit.getProperty("options.shortcuts.select.tooltip"));
 73		Box north = Box.createHorizontalBox();
 74		north.add(new JLabel(jEdit.getProperty(
 75			"options.shortcuts.select.label")));
 76		north.add(Box.createHorizontalStrut(6));
 77		north.add(selectModel);
 78
 79		filterTF = new JTextField(40);
 80		filterTF.setToolTipText(jEdit.getProperty("options.shortcuts.filter.tooltip"));
 81		filterTF.getDocument().addDocumentListener(new DocumentListener()
 82		{
 83			@Override
 84			public void changedUpdate(DocumentEvent e)
 85			{
 86				setFilter();
 87			}
 88
 89			@Override
 90			public void insertUpdate(DocumentEvent e)
 91			{
 92				setFilter();
 93			}
 94
 95			@Override
 96			public void removeUpdate(DocumentEvent e)
 97			{
 98				setFilter();
 99			}
100		});
101		JButton clearButton = new JButton(jEdit.getProperty(
102				"options.shortcuts.clear.label"));
103		clearButton.addActionListener(new ActionListener()
104		{
105			@Override
106			public void actionPerformed(ActionEvent arg0)
107			{
108				filterTF.setText("");
109				filterTF.requestFocus();
110			}
111		});
112
113		JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
114		filterPanel.add(new JLabel(jEdit.getProperty("options.shortcuts.filter.label")));
115		filterPanel.add(filterTF);
116		filterPanel.add(clearButton);
117
118		keyTable = new JTable(filteredModel);
119		filteredModel.setTable(keyTable);
120		keyTable.getTableHeader().setReorderingAllowed(false);
121		keyTable.getTableHeader().addMouseListener(new HeaderMouseHandler());
122		keyTable.addMouseListener(new TableMouseHandler());
123		Dimension d = keyTable.getPreferredSize();
124		d.height = Math.min(d.height,200);
125		JScrollPane scroller = new JScrollPane(keyTable);
126		scroller.setPreferredSize(d);
127		JPanel tableFilterPanel = new JPanel(new BorderLayout());
128		tableFilterPanel.add(BorderLayout.NORTH,filterPanel);
129		tableFilterPanel.add(BorderLayout.CENTER,scroller);
130
131		add(BorderLayout.NORTH,north);
132		add(BorderLayout.CENTER,tableFilterPanel);
133		try
134		{
135			selectModel.setSelectedIndex(jEdit.getIntegerProperty("options.shortcuts.select.index", 0));
136		}
137		catch (IllegalArgumentException eae) {}
138	} //}}}
139
140	//{{{ _save() method
141	@Override
142	protected void _save()
143	{
144		if(keyTable.getCellEditor() != null)
145			keyTable.getCellEditor().stopCellEditing();
146
147		for (ShortcutsModel model : models)
148			model.save();
149
150		Macros.loadMacros();
151	} //}}}
152
153	//{{{ Private members
154	private JTable keyTable;
155	private Vector<ShortcutsModel> models;
156	private FilteredTableModel<ShortcutsModel> filteredModel;
157	private JComboBox selectModel;
158	private List<KeyBinding> allBindings;
159	private JTextField filterTF;
160
161	//{{{ setFilter() method
162	private void setFilter()
163	{
164		filteredModel.setFilter(filterTF.getText());
165	} //}}}
166
167	//{{{ initModels() method
168	private void initModels()
169	{
170		List<KeyBinding[]> allBindings = new ArrayList<KeyBinding[]>();
171		Set<String> knownBindings = new HashSet<String>();
172		models = new Vector<ShortcutsModel>();
173		ActionSet[] actionSets = jEdit.getActionSets();
174		for(int i = 0; i < actionSets.length; i++)
175		{
176			ActionSet actionSet = actionSets[i];
177			if(actionSet.getActionCount() != 0)
178			{
179				String modelLabel = actionSet.getLabel();
180				if(modelLabel == null)
181				{
182					Log.log(Log.ERROR,this,"Empty action set: "
183						+ actionSet.getPluginJAR());
184				}
185				ShortcutsModel model = createModel(modelLabel,
186						actionSet.getActionNames());
187				models.addElement(model);
188				List<KeyBinding[]> bindings = model.getBindings();
189				for (KeyBinding[] binding : bindings)
190				{
191					String name = binding[0].name;
192					if (!knownBindings.contains(name))
193					{
194						knownBindings.add(name);
195						allBindings.add(binding);
196					}
197				}
198			}
199		}
200		if (models.size() > 1)
201			models.addElement(new ShortcutsModel("All", allBindings));
202		Collections.sort(models,new StandardUtilities.StringCompare<ShortcutsModel>(true));
203		ShortcutsModel currentModel = models.elementAt(0);
204		filteredModel = new FilteredTableModel<ShortcutsModel>(currentModel)
205		{
206			@Override
207			public String prepareFilter(String filter)
208			{
209				return filter.toLowerCase();
210			}
211
212			@Override
213			public boolean passFilter(int row, String filter)
214			{
215				String name = delegated.getBindingAt(row, 0).label.toLowerCase();
216				return name.contains(filter);
217			}
218		};
219	} //}}}
220
221	//{{{ createModel() method
222	private ShortcutsModel createModel(String modelLabel, String[] actions)
223	{
224		List<GrabKeyDialog.KeyBinding[]> bindings = new ArrayList<GrabKeyDialog.KeyBinding[]>(actions.length);
225
226		for(int i = 0; i < actions.length; i++)
227		{
228			String name = actions[i];
229			EditAction ea = jEdit.getAction(name);
230			String label = ea.getLabel();
231			// Skip certain actions this way
232			if(label == null)
233				continue;
234
235			label = GUIUtilities.prettifyMenuLabel(label);
236			addBindings(name,label,bindings);
237		}
238
239		return new ShortcutsModel(modelLabel,bindings);
240	} //}}}
241
242	//{{{ addBindings() method
243	private void addBindings(String name, String label, Collection<KeyBinding[]> bindings)
244	{
245		GrabKeyDialog.KeyBinding[] b = new GrabKeyDialog.KeyBinding[2];
246
247		b[0] = createBinding(name,label,
248			jEdit.getProperty(name + ".shortcut"));
249		b[1] = createBinding(name,label,
250			jEdit.getProperty(name + ".shortcut2"));
251
252		bindings.add(b);
253	} //}}}
254
255	//{{{ createBinding() method
256	private GrabKeyDialog.KeyBinding createBinding(String name,
257		String label, String shortcut)
258	{
259		if(shortcut != null && shortcut.length() == 0)
260			shortcut = null;
261
262		GrabKeyDialog.KeyBinding binding
263			= new GrabKeyDialog.KeyBinding(name,label,shortcut,false);
264
265		allBindings.add(binding);
266		return binding;
267	} //}}}
268
269	//{{{ Inner classes
270
271	//{{{ HeaderMouseHandler class
272	private class HeaderMouseHandler extends MouseAdapter
273	{
274		@Override
275		public void mouseClicked(MouseEvent evt)
276		{
277			ShortcutsModel shortcutsModel = filteredModel.getDelegated();
278			switch(keyTable.getTableHeader().columnAtPoint(evt.getPoint()))
279			{
280			case 0:
281				shortcutsModel.sort(0);
282				break;
283			case 1:
284				shortcutsModel.sort(1);
285				break;
286			case 2:
287				shortcutsModel.sort(2);
288				break;
289			}
290			setFilter();
291		}
292	} //}}}
293
294	//{{{ TableMouseHandler class
295	private class TableMouseHandler extends MouseAdapter
296	{
297		@Override
298		public void mouseClicked(MouseEvent evt)
299		{
300			int row = keyTable.getSelectedRow();
301			int col = keyTable.getSelectedColumn();
302			if(col != 0 && row != -1)
303			{
304				 GrabKeyDialog gkd = new GrabKeyDialog(
305					GUIUtilities.getParentDialog(
306					ShortcutsOptionPane.this),
307					filteredModel.getDelegated().getBindingAt(filteredModel.getTrueRow(row), col - 1),
308					allBindings,null);
309				if(gkd.isOK())
310					filteredModel.setValueAt(
311						gkd.getShortcut(),row,col);
312			}
313		}
314	} //}}}
315
316	//{{{ ActionHandler class
317	private class ActionHandler implements ActionListener
318	{
319		@Override
320		public void actionPerformed(ActionEvent evt)
321		{
322			ShortcutsModel newModel
323				= (ShortcutsModel)selectModel.getSelectedItem();
324			if(filteredModel.getDelegated() != newModel)
325			{
326				jEdit.setIntegerProperty("options.shortcuts.select.index", selectModel.getSelectedIndex());
327				filteredModel.setDelegated(newModel);
328				setFilter();
329			}
330		}
331	} //}}}
332
333	//{{{ ShortcutsModel class
334	private static class ShortcutsModel extends AbstractTableModel
335	{
336		private final List<GrabKeyDialog.KeyBinding[]> bindings;
337		private final String name;
338
339		ShortcutsModel(String name, List<GrabKeyDialog.KeyBinding[]> bindings)
340		{
341			this.name = name;
342			this.bindings = bindings;
343			sort(0);
344		}
345
346		public List<GrabKeyDialog.KeyBinding[]> getBindings()
347		{
348			return bindings;
349		}
350
351		public void sort(int col)
352		{
353			Collections.sort(bindings,new KeyCompare(col));
354		}
355
356		@Override
357		public int getColumnCount()
358		{
359			return 3;
360		}
361
362		@Override
363		public int getRowCount()
364		{
365			return bindings.size();
366		}
367
368		@Override
369		public Object getValueAt(int row, int col)
370		{
371			switch(col)
372			{
373			case 0:
374				return getBindingAt(row,0).label;
375			case 1:
376				return getBindingAt(row,0).shortcut;
377			case 2:
378				return getBindingAt(row,1).shortcut;
379			default:
380				return null;
381			}
382		}
383
384		@Override
385		public void setValueAt(Object value, int row, int col)
386		{
387			if(col == 0)
388				return;
389
390			getBindingAt(row,col-1).shortcut = (String)value;
391
392			// redraw the whole table because a second shortcut
393			// might have changed, too
394			fireTableDataChanged();
395		}
396
397		@Override
398		public String getColumnName(int index)
399		{
400			switch(index)
401			{
402			case 0:
403				return jEdit.getProperty("options.shortcuts.name");
404			case 1:
405				return jEdit.getProperty("options.shortcuts.shortcut1");
406			case 2:
407				return jEdit.getProperty("options.shortcuts.shortcut2");
408			default:
409				return null;
410			}
411		}
412
413		public void save()
414		{
415			for (GrabKeyDialog.KeyBinding[] binding : bindings)
416			{
417				jEdit.setProperty(
418					binding[0].name + ".shortcut",
419					binding[0].shortcut);
420				jEdit.setProperty(
421					binding[1].name + ".shortcut2",
422					binding[1].shortcut);
423			}
424		}
425
426		public GrabKeyDialog.KeyBinding getBindingAt(int row, int nr)
427		{
428			GrabKeyDialog.KeyBinding[] binding = bindings.get(row);
429			return binding[nr];
430		}
431
432		@Override
433		public String toString()
434		{
435			return name;
436		}
437
438		private static class KeyCompare implements Comparator<GrabKeyDialog.KeyBinding[]>
439		{
440			private final int col;
441
442			KeyCompare(int col)
443			{
444				this.col = col;
445			}
446
447			@Override
448			public int compare(GrabKeyDialog.KeyBinding[] k1, GrabKeyDialog.KeyBinding[] k2)
449			{
450				String label1 = k1[0].label.toLowerCase();
451				String label2 = k2[0].label.toLowerCase();
452
453				if(col == 0)
454					return StandardUtilities.compareStrings(
455						label1,label2,true);
456				else
457				{
458					String shortcut1, shortcut2;
459					if(col == 1)
460					{
461						shortcut1 = k1[0].shortcut;
462						shortcut2 = k2[0].shortcut;
463					}
464					else
465					{
466						shortcut1 = k1[1].shortcut;
467						shortcut2 = k2[1].shortcut;
468					}
469
470					if(shortcut1 == null && shortcut2 != null)
471						return 1;
472					else if(shortcut2 == null && shortcut1 != null)
473						return -1;
474					else if(shortcut1 == null)
475						return StandardUtilities.compareStrings(label1,label2,true);
476					else
477						return StandardUtilities.compareStrings(shortcut1,shortcut2,true);
478				}
479			}
480		}
481	} //}}}
482	//}}}
483	//}}}
484}