/jEdit/tags/jedit-4-0-pre3/macros/Misc/Display_Abbreviations.bsh
Unknown | 385 lines | 364 code | 21 blank | 0 comment | 0 complexity | 58be4a009710116f7117a5b4d7570ef5 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
1/*
2 * Display_abbreviations.bsh - a BeanShell macro script for the
3 * jEdit text editor - displays all defined abbreviations
4 * Copyright (C) 2001 John Gellene
5 * email: jgellene@nyc.rr.com
6 * http://community.jedit.org
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * $Id: Display_Abbreviations.bsh 3873 2001-11-06 17:57:35Z jgellene $
23 *
24 * requires JDK 1.2, jEdit3.0
25 *
26 * Notes on use:
27 *
28 * This macro will display a sorted list of all defined abbreviations
29 * in a dialog. A combo box lists all eidting modes for which abbreviations
30 * are currently defined, as well as the "global" abbreviation set.
31 *
32 * Pressing a letter key will cause the table to scroll to the first row
33 * with a label beginning with the letter (or the imeediately preceding row if
34 * no item begins with that letter). The table is read-only; the dialog is
35 * dismissed by clicking "OK" or pressing Esc or Enter.
36 *
37 * The macro has two global constants defined to permit customization of the
38 * script's behavior. STARTING_SET contains the name of the abbreviation set
39 * that will be first displayed. If the other variable, EXCLUDE_EMPTY_SETS,
40 * is set to true, the drop-down menu and the results of clicking the
41 * "Write All" button will only include abbreviations sets containing
42 * entries.
43 *
44 * The table being displayed at any time is not updated if changes are made to
45 * the abbreviation set in the "Global Options" dialog. If EXCLUDE_EMPTY_SETS
46 * is set to true, the drop-down list will not by updated. Clsoing the dialog
47 * and running the macro again will obtain current data.
48 *
49 *
50 * Checked for jEdit 4.0 API
51 *
52 */
53
54import javax.swing.table.*;
55
56/*
57 * getActiveSets()
58 * This returns an array with the names of the abbreviation sets
59 * (beginning with "global"). If EXCLUDE_EMPTY_SETS is set to true, only sets
60 * with abbreviations are included.
61 */
62Object[] getActiveSets()
63{
64 Mode[] modes = jEdit.getModes();
65 Vector setVector = new Vector(modes.length + 1);
66 setVector.addElement("global");
67 for(int i = 0; i < modes.length; i++)
68 {
69 String name = modes[i].getName();
70 if(EXCLUDE_EMPTY_SETS)
71 {
72 Hashtable ht = Abbrevs.getModeAbbrevs().get(name);
73 if( ht == null || ht.isEmpty())
74 continue;
75 }
76 setVector.addElement(name);
77 }
78 Object[] sets = new Object[setVector.size()];
79 setVector.copyInto(sets);
80 return sets;
81}
82
83/*
84 * makeTableDataForMode()
85 * This extracts the abbreviations from the named set. If extraction is
86 * successful, the vector named by the first parameter will have its
87 * elements removed before the variable is set to the newly created vector.
88 */
89Vector makeTableDataForMode(Vector v, String name)
90{
91 if(name.equals(currentSet))
92 return v;
93 Hashtable htable = null;
94 if(name.equals("global"))
95 {
96 htable = Abbrevs.getGlobalAbbrevs();
97 }
98 else
99 {
100 Hashtable modeAbbrevs = Abbrevs.getModeAbbrevs();
101 htable = modeAbbrevs.get(name);
102 }
103 if(htable != null)
104 {
105 Enumeration abbrevEnum = htable.keys();
106 Enumeration expandEnum = htable.elements();
107 Vector newData = new Vector(20, 5);
108 while(abbrevEnum.hasMoreElements())
109 {
110 Vector row = new Vector(2);
111 row.addElement(abbrevEnum.nextElement());
112 row.addElement(expandEnum.nextElement());
113 newData.addElement(row);
114 }
115 MiscUtilities.quicksort(newData,
116 new MiscUtilities.StringICaseCompare());
117 currentSet = name;
118 if( v != null)
119 v.removeAllElements();
120 v = newData;
121 }
122 return v;
123}
124
125/*
126 * showAbbrevs()
127 * This is the macro's principal method.
128 */
129void showAbbrevs()
130{
131 currentSet = null;
132 data = makeTableDataForMode(data, STARTING_SET);
133 if(data.size() == 0)
134 {
135 STARTING_SET = "global";
136 data = makeTableDataForMode(data, STARTING_SET);
137 }
138 Vector columnNames = new Vector(2);
139 columnNames.addElement(new String("Abbreviation"));
140 columnNames.addElement(new String("Expansion"));
141 table = new JTable();
142 table.setModel(new DefaultTableModel(data, columnNames));
143 table.setRowSelectionAllowed(true);
144 /* The next line prevents the table from being edited.
145 * The normal approach in Java would be to subclass the TableModel
146 * associated with the JTable and define TableModel.isCellEditable()
147 * to return false. However, BeanShell does not allow conventional
148 * class creation, and the desired behavior cannot be achieved using
149 * its scripted object feature.
150 */
151 table.setDefaultEditor(Object.class, null);
152 if(table.getRowCount() != 0)
153 table.setRowSelectionInterval(0,0);
154 tablePane = new JScrollPane(table);
155 tablePane.setPreferredSize(new Dimension(450, 300));
156
157 combo = new JComboBox(abbrevSets);
158 Dimension dim = combo.getPreferredSize();
159 dim.width = Math.max(dim.width, 120);
160 combo.setPreferredSize(dim);
161 combo.setSelectedItem(STARTING_SET);
162 comboPanel = new JPanel(new FlowLayout());
163 comboPanel.add(new JLabel("Abbreviation set:"));
164 comboPanel.add(combo);
165
166 close = new JButton("Close");
167 write_set = new JButton("Write set");
168 write_all = new JButton("Write all");
169 buttonPanel = new JPanel(new FlowLayout());
170 buttonPanel.add(write_set);
171 buttonPanel.add(write_all);
172 buttonPanel.add(close);
173
174 close.addActionListener(this);
175 write_set.addActionListener(this);
176 write_all.addActionListener(this);
177 combo.addActionListener(this);
178 void actionPerformed(e)
179 {
180 Component source = e.getSource();
181 if(source == close)
182 dialog.hide();
183 else if(source == write_set)
184 writeTableToNewBuffer(super.data, (String)combo.getSelectedItem());
185 else if(source == write_all)
186 writeAllToNewBuffer();
187 else if(source == combo)
188 {
189 super.data = makeTableDataForMode(super.data, (String)combo.getSelectedItem());
190 if( data != null)
191 {
192 DefaultTableModel model = (DefaultTableModel)table.getModel();
193 model.setDataVector(super.data, columnNames);
194 }
195 }
196 }
197
198 // workaround required by Swing bug; scheduled to be fixed in JDK 1.4
199 combo.getComponent(0).addKeyListener(this);
200 table.addKeyListener(this);
201 write_set.addKeyListener(this);
202 write_all.addKeyListener(this);
203 close.addKeyListener(this);
204 void keyPressed(e)
205 {
206 if(combo.isPopupVisible()) return;
207 if(e.getKeyCode() == KeyEvent.VK_ESCAPE ||
208 e.getKeyCode() == KeyEvent.VK_ENTER)
209 {
210 dialog.hide();
211 }
212 else if(e.getSource() != combo)
213 {
214 char ch = e.getKeyChar();
215 if(Character.isLetter(ch))
216 {
217 e.consume();
218 row = findFirstItem(ch);
219 /* The next few lines set the last visible row
220 * of the table so that you can look ahead of
221 * the selected row.
222 */
223 visibleRows =
224 table.getVisibleRect().height / table.getRowHeight();
225 oldRow = table.getSelectedRow();
226 table.setRowSelectionInterval(row,row);
227 if (visibleRows > 5 && row - oldRow > visibleRows - 3)
228 {
229 row = Math.min( super.data.size() - 1, row + 3);
230 }
231 table.scrollRectToVisible(table.getCellRect(row,0,true));
232 }
233 }
234 }
235 /*
236 * Having these members of KeyListener implemented as no-ops
237 * will speedup execution. Otherwise BeanShell throws an
238 * exception that jEdit handles internally.
239 * Under BeanShell 1.2, implementation of these methods is
240 * required.
241 */
242 void keyReleased(e) {}
243 void keyTyped(e) {}
244
245 /*
246 * findFirstItem()
247 * A simple linear search for the table entry that begins with the
248 * given letter. It returns the first row with an entry beginning with
249 * the letter, or the immdediately preceding row if there is no match
250 * on the letter.
251 *
252 */
253 int findFirstItem(char ch)
254 {
255 ch = Character.toUpperCase(ch);
256 int row = 0;
257 for(int i = 0; i < data.size(); ++i)
258 {
259 String name = ((Vector)data.elementAt(i)).elementAt(0);
260 char ch_test = Character.toUpperCase(name.charAt(0));
261 if( ch_test > ch) break;
262 else
263 {
264 row = i;
265 if( ch_test == ch) break;
266 }
267 }
268 return row;
269 }
270
271 title = "Abbreviation list";
272 dialog = new JDialog(view, title, false);
273 c = dialog.getContentPane();
274 c.add(tablePane, "Center");
275 c.add(comboPanel, "North");
276 c.add(buttonPanel, "South");
277 dialog.getRootPane().setDefaultButton(close);
278 dialog.pack();
279 dialog.setLocationRelativeTo(view);
280 dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
281 dialog.show();
282}
283
284/*
285 * The next four methods deal with writing the abbreviation sets to a new
286 * text buffer.
287 */
288void writeTableToNewBuffer(Vector v, String setName)
289{
290 Log.log(Log.DEBUG, BeanShell.class,
291 "calling writeTableToNewBuffer for " + setName);
292 writeHeader();
293 Log.log(Log.DEBUG, BeanShell.class, "size of vector = "
294 + String.valueOf(v.size()));
295 writeSet(v, setName);
296}
297
298void writeAllToNewBuffer()
299{
300 writeHeader();
301 Vector vOut = new Vector();
302 for( int i = 0; i < abbrevSets.length; ++i)
303 {
304 String setName = (String)abbrevSets[i];
305 vOut = makeTableDataForMode(vOut, setName);
306 writeSet(vOut, setName);
307 textArea.setSelectedText("\n\n");
308 }
309}
310
311void writeHeader()
312{
313 jEdit.newFile(view);
314 textArea.setSelectedText("jEdit Keyboard Shortcut Table\n\n");
315}
316
317/*
318 * This truncates the definition text at 18 characters and the expansion text
319 * at 58.
320 */
321void writeSet(Vector v, String setName)
322{
323 textArea.setSelectedText("Abbreviation set: " + setName + "\n");
324 textArea.setSelectedText("Abbreviation Expansion\n\n");
325 if(v.size() == 0)
326 textArea.setSelectedText("<< No abbreviations >>\n");
327 else for( int i = 0; i < v.size(); ++i)
328 {
329 StringBuffer sb = new StringBuffer(85);
330 spaceString = " ";
331 char[] space = spaceString.toCharArray();
332 Vector row = (Vector)v.elementAt(i);
333 abbrevName = (String)row.elementAt(0);
334 if(abbrevName == null) continue;
335 if(abbrevName.length() > 18)
336 abbrevName = abbrevName.substring(0, 14) + "...";
337 sb.append(abbrevName);
338 sb.append(space, 0, 16 - (abbrevName.length()));
339 expansion = row.elementAt(1);
340 if(shortcut1 != null)
341 {
342 if(expansion.length() > 58)
343 expansion = expansion.substring(0, 54) + "...";
344 sb.append(expansion);
345 }
346 sb.append('\n');
347 textArea.setSelectedText(sb.toString());
348 }
349}
350
351
352/*
353 * main routine, including definition of global variables
354 */
355STARTING_SET = "global";
356EXCLUDE_EMPTY_SETS = true;
357abbrevSets = getActiveSets();
358currentSet = null;
359Vector data = new Vector(20, 5);
360showAbbrevs();
361
362/*
363 Macro index data (in DocBook format)
364
365<listitem>
366 <para><filename>Display_Abbreviations.bsh</filename></para>
367 <abstract><para>
368 Displays the abbreviations registered for each of jEdit's
369 editing modes.
370 </para></abstract>
371 <para>
372 The macro provides a read-only view of the abbreviations
373 contained in the <quote>Abbreviations</quote> option pane. Pressing
374 a letter key will scroll the table to the first entry beginning with
375 that letter. A further option is provided to write a selected mode's
376 abbreviations or all abbreviations in a text buffer for printing as a
377 reference. Notes in the source code listing point out some display options
378 that are configured by modifying global variables.
379 </para>
380</listitem>
381
382*/
383
384// end Display_Abbreviations.bsh
385