/jEdit/tags/jedit-4-3-pre15/org/gjt/sp/jedit/options/ShortcutsOptionPane.java

# · Java · 442 lines · 359 code · 51 blank · 32 comment · 42 complexity · 8527d8308d2042ec07503fe0906b59f6 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. package org.gjt.sp.jedit.options;
  24. import org.gjt.sp.jedit.*;
  25. import org.gjt.sp.jedit.gui.FilteredTableModel;
  26. import org.gjt.sp.jedit.gui.GrabKeyDialog;
  27. import org.gjt.sp.jedit.gui.GrabKeyDialog.KeyBinding;
  28. import org.gjt.sp.util.Log;
  29. import org.gjt.sp.util.StandardUtilities;
  30. import javax.swing.*;
  31. import javax.swing.event.DocumentEvent;
  32. import javax.swing.event.DocumentListener;
  33. import javax.swing.table.AbstractTableModel;
  34. import java.awt.*;
  35. import java.awt.event.ActionEvent;
  36. import java.awt.event.ActionListener;
  37. import java.awt.event.MouseAdapter;
  38. import java.awt.event.MouseEvent;
  39. import java.util.Collections;
  40. import java.util.Comparator;
  41. import java.util.List;
  42. import java.util.Vector;
  43. /**
  44. * Key binding editor.
  45. * @author Slava Pestov
  46. * @version $Id: ShortcutsOptionPane.java 12949 2008-06-27 08:47:25Z kpouer $
  47. */
  48. public class ShortcutsOptionPane extends AbstractOptionPane
  49. {
  50. public ShortcutsOptionPane()
  51. {
  52. super("shortcuts");
  53. }
  54. // protected members
  55. @Override
  56. protected void _init()
  57. {
  58. allBindings = new Vector<KeyBinding>();
  59. setLayout(new BorderLayout(12,12));
  60. initModels();
  61. selectModel = new JComboBox(models);
  62. selectModel.addActionListener(new ActionHandler());
  63. selectModel.setToolTipText(jEdit.getProperty("options.shortcuts.select.tooltip"));
  64. Box north = Box.createHorizontalBox();
  65. north.add(new JLabel(jEdit.getProperty(
  66. "options.shortcuts.select.label")));
  67. north.add(Box.createHorizontalStrut(6));
  68. north.add(selectModel);
  69. filterTF = new JTextField(40);
  70. filterTF.setToolTipText(jEdit.getProperty("options.shortcuts.filter.tooltip"));
  71. filterTF.getDocument().addDocumentListener(new DocumentListener()
  72. {
  73. public void changedUpdate(DocumentEvent e) {
  74. setFilter();
  75. }
  76. public void insertUpdate(DocumentEvent e) {
  77. setFilter();
  78. }
  79. public void removeUpdate(DocumentEvent e) {
  80. setFilter();
  81. }
  82. });
  83. JButton clearButton = new JButton(jEdit.getProperty(
  84. "options.shortcuts.clear.label"));
  85. clearButton.addActionListener(new ActionListener() {
  86. public void actionPerformed(ActionEvent arg0) {
  87. filterTF.setText("");
  88. filterTF.requestFocus();
  89. }
  90. });
  91. JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
  92. filterPanel.add(new JLabel(jEdit.getProperty("options.shortcuts.filter.label")));
  93. filterPanel.add(filterTF);
  94. filterPanel.add(clearButton);
  95. keyTable = new JTable(filteredModel);
  96. filteredModel.setTable(keyTable);
  97. keyTable.getTableHeader().setReorderingAllowed(false);
  98. keyTable.getTableHeader().addMouseListener(new HeaderMouseHandler());
  99. keyTable.addMouseListener(new TableMouseHandler());
  100. Dimension d = keyTable.getPreferredSize();
  101. d.height = Math.min(d.height,200);
  102. JScrollPane scroller = new JScrollPane(keyTable);
  103. scroller.setPreferredSize(d);
  104. JPanel tableFilterPanel = new JPanel(new BorderLayout());
  105. tableFilterPanel.add(BorderLayout.NORTH,filterPanel);
  106. tableFilterPanel.add(BorderLayout.CENTER,scroller);
  107. add(BorderLayout.NORTH,north);
  108. add(BorderLayout.CENTER,tableFilterPanel);
  109. try {
  110. selectModel.setSelectedIndex(jEdit.getIntegerProperty("options.shortcuts.select.index", 0));
  111. }
  112. catch (IllegalArgumentException eae) {}
  113. }
  114. private void setFilter()
  115. {
  116. filteredModel.setFilter(filterTF.getText());
  117. }
  118. @Override
  119. protected void _save()
  120. {
  121. if(keyTable.getCellEditor() != null)
  122. keyTable.getCellEditor().stopCellEditing();
  123. for (ShortcutsModel model : models)
  124. model.save();
  125. Macros.loadMacros();
  126. }
  127. private void initModels()
  128. {
  129. List<KeyBinding[]> allBindings = new Vector<KeyBinding[]>();
  130. models = new Vector<ShortcutsModel>();
  131. ActionSet[] actionSets = jEdit.getActionSets();
  132. for(int i = 0; i < actionSets.length; i++)
  133. {
  134. ActionSet actionSet = actionSets[i];
  135. if(actionSet.getActionCount() != 0)
  136. {
  137. String modelLabel = actionSet.getLabel();
  138. if(modelLabel == null)
  139. {
  140. Log.log(Log.ERROR,this,"Empty action set: "
  141. + actionSet.getPluginJAR());
  142. }
  143. ShortcutsModel model = createModel(modelLabel,
  144. actionSet.getActionNames());
  145. models.addElement(model);
  146. allBindings.addAll(model.getBindings());
  147. }
  148. }
  149. if (models.size() > 1)
  150. models.addElement(new ShortcutsModel("All", allBindings));
  151. Collections.sort(models,new StandardUtilities.StringCompare(true));
  152. ShortcutsModel currentModel = models.elementAt(0);
  153. filteredModel = new FilteredTableModel<ShortcutsModel>(currentModel)
  154. {
  155. @Override
  156. public String prepareFilter(String filter)
  157. {
  158. return filter.toLowerCase();
  159. }
  160. @Override
  161. public boolean passFilter(int row, String filter)
  162. {
  163. String name = delegated.getBindingAt(row, 0).label.toLowerCase();
  164. return name.contains(filter);
  165. }
  166. };
  167. }
  168. private ShortcutsModel createModel(String modelLabel, String[] actions)
  169. {
  170. List<GrabKeyDialog.KeyBinding[]> bindings = new Vector<GrabKeyDialog.KeyBinding[]>(actions.length);
  171. for(int i = 0; i < actions.length; i++)
  172. {
  173. String name = actions[i];
  174. EditAction ea = jEdit.getAction(name);
  175. String label = ea.getLabel();
  176. // Skip certain actions this way
  177. if(label == null)
  178. continue;
  179. label = GUIUtilities.prettifyMenuLabel(label);
  180. addBindings(name,label,bindings);
  181. }
  182. return new ShortcutsModel(modelLabel,bindings);
  183. }
  184. private void addBindings(String name, String label, List<GrabKeyDialog.KeyBinding[]> bindings)
  185. {
  186. GrabKeyDialog.KeyBinding[] b = new GrabKeyDialog.KeyBinding[2];
  187. b[0] = createBinding(name,label,
  188. jEdit.getProperty(name + ".shortcut"));
  189. b[1] = createBinding(name,label,
  190. jEdit.getProperty(name + ".shortcut2"));
  191. bindings.add(b);
  192. }
  193. private GrabKeyDialog.KeyBinding createBinding(String name,
  194. String label, String shortcut)
  195. {
  196. if(shortcut != null && shortcut.length() == 0)
  197. shortcut = null;
  198. GrabKeyDialog.KeyBinding binding
  199. = new GrabKeyDialog.KeyBinding(name,label,shortcut,false);
  200. allBindings.add(binding);
  201. return binding;
  202. }
  203. // private members
  204. private JTable keyTable;
  205. private Vector<ShortcutsModel> models;
  206. private FilteredTableModel<ShortcutsModel> filteredModel;
  207. private JComboBox selectModel;
  208. private List<KeyBinding> allBindings;
  209. private JTextField filterTF;
  210. private class HeaderMouseHandler extends MouseAdapter
  211. {
  212. @Override
  213. public void mouseClicked(MouseEvent evt)
  214. {
  215. ShortcutsModel shortcutsModel = filteredModel.getDelegated();
  216. switch(keyTable.getTableHeader().columnAtPoint(evt.getPoint()))
  217. {
  218. case 0:
  219. shortcutsModel.sort(0);
  220. break;
  221. case 1:
  222. shortcutsModel.sort(1);
  223. break;
  224. case 2:
  225. shortcutsModel.sort(2);
  226. break;
  227. }
  228. setFilter();
  229. }
  230. }
  231. private class TableMouseHandler extends MouseAdapter
  232. {
  233. @Override
  234. public void mouseClicked(MouseEvent evt)
  235. {
  236. int row = keyTable.getSelectedRow();
  237. int col = keyTable.getSelectedColumn();
  238. if(col != 0 && row != -1)
  239. {
  240. GrabKeyDialog gkd = new GrabKeyDialog(
  241. GUIUtilities.getParentDialog(
  242. ShortcutsOptionPane.this),
  243. filteredModel.getDelegated().getBindingAt(filteredModel.getTrueRow(row), col - 1),
  244. allBindings,null);
  245. if(gkd.isOK())
  246. filteredModel.setValueAt(
  247. gkd.getShortcut(),row,col);
  248. }
  249. }
  250. }
  251. private class ActionHandler implements ActionListener
  252. {
  253. public void actionPerformed(ActionEvent evt)
  254. {
  255. ShortcutsModel newModel
  256. = (ShortcutsModel)selectModel.getSelectedItem();
  257. if(filteredModel.getDelegated() != newModel)
  258. {
  259. jEdit.setIntegerProperty("options.shortcuts.select.index", selectModel.getSelectedIndex());
  260. filteredModel.setDelegated(newModel);
  261. setFilter();
  262. }
  263. }
  264. }
  265. private class ShortcutsModel extends AbstractTableModel
  266. {
  267. private List<GrabKeyDialog.KeyBinding[]> bindings;
  268. private String name;
  269. ShortcutsModel(String name, List<GrabKeyDialog.KeyBinding[]> bindings)
  270. {
  271. this.name = name;
  272. this.bindings = bindings;
  273. sort(0);
  274. }
  275. public List<GrabKeyDialog.KeyBinding[]> getBindings()
  276. {
  277. return bindings;
  278. }
  279. public void sort(int col)
  280. {
  281. Collections.sort(bindings,new KeyCompare(col));
  282. }
  283. public int getColumnCount()
  284. {
  285. return 3;
  286. }
  287. public int getRowCount()
  288. {
  289. return bindings.size();
  290. }
  291. public Object getValueAt(int row, int col)
  292. {
  293. switch(col)
  294. {
  295. case 0:
  296. return getBindingAt(row,0).label;
  297. case 1:
  298. return getBindingAt(row,0).shortcut;
  299. case 2:
  300. return getBindingAt(row,1).shortcut;
  301. default:
  302. return null;
  303. }
  304. }
  305. @Override
  306. public void setValueAt(Object value, int row, int col)
  307. {
  308. if(col == 0)
  309. return;
  310. getBindingAt(row,col-1).shortcut = (String)value;
  311. // redraw the whole table because a second shortcut
  312. // might have changed, too
  313. fireTableDataChanged();
  314. }
  315. @Override
  316. public String getColumnName(int index)
  317. {
  318. switch(index)
  319. {
  320. case 0:
  321. return jEdit.getProperty("options.shortcuts.name");
  322. case 1:
  323. return jEdit.getProperty("options.shortcuts.shortcut1");
  324. case 2:
  325. return jEdit.getProperty("options.shortcuts.shortcut2");
  326. default:
  327. return null;
  328. }
  329. }
  330. public void save()
  331. {
  332. for (GrabKeyDialog.KeyBinding[] binding : bindings)
  333. {
  334. jEdit.setProperty(
  335. binding[0].name + ".shortcut",
  336. binding[0].shortcut);
  337. jEdit.setProperty(
  338. binding[1].name + ".shortcut2",
  339. binding[1].shortcut);
  340. }
  341. }
  342. public GrabKeyDialog.KeyBinding getBindingAt(int row, int nr)
  343. {
  344. GrabKeyDialog.KeyBinding[] binding = bindings.get(row);
  345. return binding[nr];
  346. }
  347. @Override
  348. public String toString()
  349. {
  350. return name;
  351. }
  352. private class KeyCompare implements Comparator<GrabKeyDialog.KeyBinding[]>
  353. {
  354. private int col;
  355. KeyCompare(int col)
  356. {
  357. this.col = col;
  358. }
  359. public int compare(GrabKeyDialog.KeyBinding[] k1, GrabKeyDialog.KeyBinding[] k2)
  360. {
  361. String label1 = k1[0].label.toLowerCase();
  362. String label2 = k2[0].label.toLowerCase();
  363. if(col == 0)
  364. return StandardUtilities.compareStrings(
  365. label1,label2,true);
  366. else
  367. {
  368. String shortcut1, shortcut2;
  369. if(col == 1)
  370. {
  371. shortcut1 = k1[0].shortcut;
  372. shortcut2 = k2[0].shortcut;
  373. }
  374. else
  375. {
  376. shortcut1 = k1[1].shortcut;
  377. shortcut2 = k2[1].shortcut;
  378. }
  379. if(shortcut1 == null && shortcut2 != null)
  380. return 1;
  381. else if(shortcut2 == null && shortcut1 != null)
  382. return -1;
  383. else if(shortcut1 == null)
  384. return StandardUtilities.compareStrings(label1,label2,true);
  385. else
  386. return StandardUtilities.compareStrings(shortcut1,shortcut2,true);
  387. }
  388. }
  389. }
  390. }
  391. }