/* * Display_shortcuts.bsh - a BeanShell macro script for the * jEdit text editor - displays all shortcut key assignments * Copyright (C) 2001 John Gellene * email: jgellene@nyc.rr.com * http://community.jedit.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * $Id: Display_Shortcuts.bsh,v 1.3 2001/11/06 17:57:35 jgellene Exp $ * * requires jEdit3.1pre5 * * Notes on use: * * This macro will display a sorted list of all keyboard shortcuts * in a dialog. * * Pressing a letter key will cause the table to scroll to the first row * with a label beginning with the letter (or the imeediately preceding row if * no item begins with that letter). The table is read-only; the dialog is * dismissed by clicking "OK" or pressing Esc or Enter. * * General comment: * * This macro illustrates the limitations of BeanShell, which cannot create * true derived subclasses. To get the same features, the alternative to using * Vectors to hold the data would be to write a highly customized sorting * routine. Sorting by keyname would require a second custom sorting routine. * There is also a hack in the code creating the table. * * Checked for jEdit 4.0 API * */ import javax.swing.table.*; /* * method for creating vectors of row data describing shortcuts. */ Vector makeShortcutsVector() { EditAction[] actions = jEdit.getActions(); for(int i = 0; i < actions.length; i++) { EditAction action = actions[i]; String name = action.getName(); String label = action.getLabel(); if(label == null) label = name; else label = GUIUtilities.prettifyMenuLabel(label); String shortcut1 = jEdit.getProperty(name + ".shortcut"); if(shortcut1 == null) shortcut1 = ""; String shortcut2 = jEdit.getProperty(name + ".shortcut2"); if(shortcut2 == null) shortcut2 = ""; if(shortcut1.length() != 0 || shortcut2.length() != 0) { v.addElement(makeRow(label,shortcut1,shortcut2)); } } } /* * helper method to make vector of row data for table */ Vector makeRow(String name, String shortcut1, String shortcut2) { Vector row = new Vector(3); row.addElement(name); row.addElement(shortcut1); row.addElement(shortcut2); return row; } /* * methods for formatting and writing shortcut data to a text buffer */ void writeTableToNewBuffer(Vector v) { jEdit.newFile(view); textArea.setSelectedText("jEdit Keyboard Shortcut Table\n\n"); headings = makeRow("Name", "Shortcut - 1", "Shortcut - 2"); writeLine(headings); textArea.setSelectedText("\n"); for(int i = 0; i < v.size(); ++i) { writeLine((Vector)v.elementAt(i)); } } void writeLine(Vector row) { StringBuffer sb = new StringBuffer(85); spaceString = " "; char[] space = spaceString.toCharArray(); displayName = row.elementAt(0); if(displayName.length() > 38) displayName = displayName.substring(0, 34) + "..."; sb.append(displayName); sb.append(space, 0, 40 - (displayName.length())); shortcut1 = row.elementAt(1); if(shortcut1 != null) { sb.append(shortcut1); sb.append(space, 0, 20 - (shortcut1.length())); } else sb.append(space, 0, 20); shortcut2 = row.elementAt(2); if(shortcut2 != null) { sb.append(shortcut2); sb.append(space, 0, 20 - (shortcut2.length())); } sb.append('\n'); textArea.setSelectedText(sb.toString()); } /* * main routine * */ void showShortcuts() { v = makeShortcutsVector(); MiscUtilities.quicksort(v, new MiscUtilities.StringICaseCompare()); table = new JTable(v, makeRow( "Name", "Shortcut-1", "Shortcut-2")); table.getColumnModel().getColumn(0).setPreferredWidth(200); table.setRowSelectionAllowed(true); /* The next line prevents the table from being edited. * The normal approach in Java would be to subclass the TableModel * associated with the JTable and define TableModel.isCellEditable() * to return false. However, BeanShell does not allow conventional * class creation, and the desired behavior cannot be achieved using * its scripted object feature. */ table.setDefaultEditor(Object.class, null); if(table.getRowCount() != 0) { table.setRowSelectionInterval(0, 0); table.setColumnSelectionInterval(1, 1); } tablePane = new JScrollPane(table); tablePane.setPreferredSize(new Dimension(450, 300)); close = new JButton("Close"); close.addActionListener(this); write = new JButton("Write to buffer"); write.addActionListener(this); void actionPerformed(e) { if(e.getSource().getText().equals("Close")) dialog.hide(); else writeTableToNewBuffer(v); } buttonPanel = new JPanel(new FlowLayout()); buttonPanel.add(write); buttonPanel.add(close); title = "Keyboard shortcut list"; dialog = new JDialog(view, title, false); dialog.getContentPane().add(tablePane, "Center"); dialog.getContentPane().add(buttonPanel, "South"); dialog.getRootPane().setDefaultButton(close); table.addKeyListener(this); void keyPressed(e) { if(e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_ENTER) { dialog.hide(); } else { char ch = e.getKeyChar(); if(Character.isLetter(ch)) { e.consume(); row = findFirstItem(ch); /* The next few lines set the last visible row * of the table so that you can look ahead of * the selected row. */ visibleRows = table.getVisibleRect().height / table.getRowHeight(); oldRow = table.getSelectedRow(); table.setRowSelectionInterval(row,row); if (visibleRows > 5 && row - oldRow > visibleRows - 3) { row = Math.min( v.size() - 1, row + 3); } table.scrollRectToVisible(table.getCellRect(row,0,true)); } } } /* * Having these members of KeyListener implemented will speedup execution; * BeanShell will otherwise throw and handle an exception. * This idiom is required under BeanShell 1.2 */ void keyReleased(e) {} void keyTyped(e) {} /* * A simple linear search for the table entry that begins with the * given letter. It returns the first row with an entry beginning with * the letter, or the immdediately preceding row if there is no match * on the letter. If PUT_MACROS_AT_END is set to true, they will not be * searched. * */ int data_midpoint = 0; int findFirstItem(char ch) { ch = Character.toUpperCase(ch); int row = 0; for(int i = (ch > 'L' ? data_midpoint : 0); i < v.size(); ++i) { String name = ((Vector)v.elementAt(i)).elementAt(0); char ch_test = Character.toUpperCase(name.charAt(0)); if( ch_test > ch) break; else { row = i; if( ch_test == ch) break; } } return row; } /* This line caches the row that starts the second half of the * alphabet to speed up searches. 'M' was chosen as the midpoint * to speed up searches. */ data_midpoint = findFirstItem('M'); dialog.pack(); dialog.setLocationRelativeTo(view); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.show(); } showShortcuts(); /* Macro index data (in DocBook format) Display_Shortcuts.bsh Displays a sorted list of the keyboard shortcuts currently in effect. The macro provides a combined read-only view of command, macro and plugin shortcuts. Pressing a letter key will scroll the table to the first entry beginning with that letter. A further option is provided to write the shortcut assignments in a text buffer for printing as a reference. Notes in the source code listing point out some display options that are configured by modifying global variables. */ // end Display_Shortcuts.bsh