KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > gui > DefaultInputHandler


1 /*
2  * DefaultInputHandler.java - Default implementation of an input handler
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 1999, 2003 Slava Pestov
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
23 package org.gjt.sp.jedit.gui;
24
25 //{{{ Imports
26
import javax.swing.KeyStroke JavaDoc;
27 import java.awt.event.KeyEvent JavaDoc;
28 import java.awt.event.InputEvent JavaDoc;
29 import java.awt.Toolkit JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import org.gjt.sp.jedit.*;
33 import org.gjt.sp.util.Log;
34 import org.gjt.sp.jedit.msg.*;
35 import javax.swing.event.*;
36 //}}}
37

38 /**
39  * The default input handler. It maps sequences of keystrokes into actions
40  * and inserts key typed events into the text area.
41  * @author Slava Pestov
42  * @version $Id: DefaultInputHandler.java 7099 2006-09-21 01:08:35Z mediumnet $
43  */

44 public class DefaultInputHandler extends InputHandler
45 {
46     //{{{ DefaultInputHandler constructor
47
/**
48      * Creates a new input handler with no key bindings defined.
49      * @param view The view
50      * @param bindings An explicitly-specified set of key bindings,
51      * must not be null.
52      * @since jEdit 4.3pre1
53      */

54     public DefaultInputHandler(View view, Hashtable JavaDoc bindings)
55     {
56         super(view);
57
58         if(bindings == null)
59             throw new NullPointerException JavaDoc();
60         this.bindings = this.currentBindings = bindings;
61     } //}}}
62

63     //{{{ DefaultInputHandler constructor
64
/**
65      * Creates a new input handler with no key bindings defined.
66      * @param view The view
67      */

68     public DefaultInputHandler(View view)
69     {
70         this(view,new Hashtable JavaDoc());
71     } //}}}
72

73     //{{{ DefaultInputHandler constructor
74
/**
75      * Creates a new input handler with the same set of key bindings
76      * as the one specified. Note that both input handlers share
77      * a pointer to exactly the same key binding table; so adding
78      * a key binding in one will also add it to the other.
79      * @param copy The input handler to copy key bindings from
80      * @param view The view
81      */

82     public DefaultInputHandler(View view, DefaultInputHandler copy)
83     {
84         this(view,copy.bindings);
85     } //}}}
86

87     //{{{ addKeyBinding() method
88
/**
89      * Adds a key binding to this input handler. The key binding is
90      * a list of white space separated key strokes of the form
91      * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
92      * or S for Shift, and key is either a character (a-z) or a field
93      * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
94      * @param keyBinding The key binding
95      * @param action The action
96      * @since jEdit 4.2pre1
97      */

98     public void addKeyBinding(String JavaDoc keyBinding, String JavaDoc action)
99     {
100         addKeyBinding(keyBinding,(Object JavaDoc)action);
101     } //}}}
102

103     //{{{ addKeyBinding() method
104
/**
105      * Adds a key binding to this input handler. The key binding is
106      * a list of white space separated key strokes of the form
107      * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
108      * or S for Shift, and key is either a character (a-z) or a field
109      * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
110      * @param keyBinding The key binding
111      * @param action The action
112      */

113     public void addKeyBinding(String JavaDoc keyBinding, EditAction action)
114     {
115         addKeyBinding(keyBinding,(Object JavaDoc)action);
116     } //}}}
117

118     //{{{ addKeyBinding() method
119
/**
120      * Adds a key binding to this input handler. The key binding is
121      * a list of white space separated key strokes of the form
122      * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
123      * or S for Shift, and key is either a character (a-z) or a field
124      * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
125      * @param keyBinding The key binding
126      * @param action The action
127      * @since jEdit 4.3pre1
128      */

129     public void addKeyBinding(String JavaDoc keyBinding, Object JavaDoc action)
130     {
131         Hashtable JavaDoc current = bindings;
132
133         String JavaDoc prefixStr = null;
134
135         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(keyBinding);
136         while(st.hasMoreTokens())
137         {
138             String JavaDoc keyCodeStr = st.nextToken();
139             if(prefixStr == null)
140                 prefixStr = keyCodeStr;
141             else
142                 prefixStr = prefixStr + " " + keyCodeStr;
143
144             KeyEventTranslator.Key keyStroke = KeyEventTranslator.parseKey(keyCodeStr);
145             if(keyStroke == null)
146                 return;
147
148             if(st.hasMoreTokens())
149             {
150                 Object JavaDoc o = current.get(keyStroke);
151                 if(o instanceof Hashtable JavaDoc)
152                     current = (Hashtable JavaDoc)o;
153                 else
154                 {
155                     Hashtable JavaDoc hash = new Hashtable JavaDoc();
156                     hash.put(PREFIX_STR,prefixStr);
157                     o = hash;
158                     current.put(keyStroke,o);
159                     current = (Hashtable JavaDoc)o;
160                 }
161             }
162             else
163                 current.put(keyStroke,action);
164         }
165     } //}}}
166

167     //{{{ removeKeyBinding() method
168
/**
169      * Removes a key binding from this input handler. This is not yet
170      * implemented.
171      * @param keyBinding The key binding
172      */

173     public void removeKeyBinding(String JavaDoc keyBinding)
174     {
175         Hashtable JavaDoc current = bindings;
176
177         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(keyBinding);
178         while(st.hasMoreTokens())
179         {
180             String JavaDoc keyCodeStr = st.nextToken();
181             KeyEventTranslator.Key keyStroke = KeyEventTranslator.parseKey(keyCodeStr);
182             if(keyStroke == null)
183                 return;
184
185             if(st.hasMoreTokens())
186             {
187                 Object JavaDoc o = current.get(keyStroke);
188                 if(o instanceof Hashtable JavaDoc)
189                     current = ((Hashtable JavaDoc)o);
190                 else if(o != null)
191                 {
192                     // we have binding foo
193
// but user asks to remove foo bar?
194
current.remove(keyStroke);
195                     return;
196                 }
197                 else
198                 {
199                     // user asks to remove non-existent
200
return;
201                 }
202             }
203             else
204                 current.remove(keyStroke);
205         }
206     } //}}}
207

208     //{{{ removeAllKeyBindings() method
209
/**
210      * Removes all key bindings from this input handler.
211      */

212     public void removeAllKeyBindings()
213     {
214         bindings.clear();
215     } //}}}
216

217     //{{{ getKeyBinding() method
218
/**
219      * Returns either an edit action, or a hashtable if the specified key
220      * is a prefix.
221      * @param keyBinding The key binding
222      * @since jEdit 3.2pre5
223      */

224     public Object JavaDoc getKeyBinding(String JavaDoc keyBinding)
225     {
226         Hashtable JavaDoc current = bindings;
227         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(keyBinding);
228
229         while(st.hasMoreTokens())
230         {
231             KeyEventTranslator.Key keyStroke = KeyEventTranslator.parseKey(
232                 st.nextToken());
233             if(keyStroke == null)
234                 return null;
235
236             if(st.hasMoreTokens())
237             {
238                 Object JavaDoc o = current.get(keyStroke);
239                 if(o instanceof Hashtable JavaDoc)
240                 {
241                     if(!st.hasMoreTokens())
242                         return o;
243                     else
244                         current = (Hashtable JavaDoc)o;
245                 }
246                 else
247                     return o;
248             }
249             else
250             {
251                 return current.get(keyStroke);
252             }
253         }
254
255         return null;
256     } //}}}
257

258     //{{{ isPrefixActive() method
259
/**
260      * Returns if a prefix key has been pressed.
261      */

262     public boolean isPrefixActive()
263     {
264         return bindings != currentBindings
265             || super.isPrefixActive();
266     } //}}}
267

268     //{{{ setBindings() method
269
/**
270      * Replace the set of key bindings.
271      * @since jEdit 4.3pre1
272      */

273     public void setBindings(Hashtable JavaDoc bindings)
274     {
275         this.bindings = this.currentBindings = bindings;
276     } //}}}
277

278     //{{{ setCurrentBindings() method
279
public void setCurrentBindings(Hashtable JavaDoc bindings)
280     {
281         view.getStatus().setMessage((String JavaDoc)bindings.get(PREFIX_STR));
282         currentBindings = bindings;
283     } //}}}
284

285     //{{{ handleKey() method
286
/**
287      * Handles the given keystroke.
288      * @param keyStroke The key stroke
289      * @param dryRun only calculate the return value, do not have any other effect
290      * @since jEdit 4.2pre5
291      */

292     public boolean handleKey(KeyEventTranslator.Key keyStroke,boolean dryRun)
293     {
294         char input = '\0';
295         if(keyStroke.modifiers == null
296             || keyStroke.modifiers.equals("S"))
297         {
298             switch(keyStroke.key)
299             {
300             case '\n':
301             case '\t':
302                 input = (char)keyStroke.key;
303                 break;
304             default:
305                 input = keyStroke.input;
306                 break;
307             }
308         }
309
310         if(readNextChar != null)
311         {
312             if(input != '\0')
313             {
314                 if (!dryRun) {
315                     setCurrentBindings(bindings);
316                     invokeReadNextChar(input);
317                     repeatCount = 1;
318                 }
319                 return true;
320             }
321             else
322             {
323                 if (!dryRun) {
324                     readNextChar = null;
325                     view.getStatus().setMessage(null);
326                 }
327             }
328         }
329
330         Object JavaDoc o = currentBindings.get(keyStroke);
331         if(o == null)
332         {
333             if (!dryRun) {
334                 // Don't beep if the user presses some
335
// key we don't know about unless a
336
// prefix is active. Otherwise it will
337
// beep when caps lock is pressed, etc.
338
if(currentBindings != bindings)
339                 {
340                     Toolkit.getDefaultToolkit().beep();
341                     // F10 should be passed on, but C+e F10
342
// shouldn't
343
repeatCount = 1;
344                     setCurrentBindings(bindings);
345                 }
346                 else if(input != '\0') {
347                     if (!keyStroke.isFromGlobalContext()) { // let user input be only local
348
userInput(input);
349                     }
350                 } else {
351                     // this is retarded. excuse me while I drool
352
// and make stupid noises
353
if(KeyEventWorkaround.isNumericKeypad(keyStroke.key))
354                         KeyEventWorkaround.numericKeypadKey();
355                 }
356                 sendShortcutPrefixOff();
357             }
358         }
359         else if(o instanceof Hashtable JavaDoc)
360         {
361             if (!dryRun) {
362                 setCurrentBindings((Hashtable JavaDoc)o);
363                 ShortcutPrefixActiveEvent.firePrefixStateChange(currentBindings, true);
364                 shortcutOn = true;
365             }
366             return true;
367         }
368         else if(o instanceof String JavaDoc)
369         {
370             if (!dryRun) {
371                 setCurrentBindings(bindings);
372                 sendShortcutPrefixOff();
373                 invokeAction((String JavaDoc)o);
374             }
375             return true;
376         }
377         else if(o instanceof EditAction)
378         {
379             if (!dryRun) {
380                 setCurrentBindings(bindings);
381                 sendShortcutPrefixOff();
382                 invokeAction((EditAction)o);
383             }
384             return true;
385         }
386         if (!dryRun) {
387             sendShortcutPrefixOff();
388         }
389         return false;
390     } //}}}
391

392     //{{{ handleKey() methodprotected void sendShortcutPrefixOff()
393
/**
394      * If
395      */

396     protected void sendShortcutPrefixOff()
397     {
398         if( shortcutOn == true )
399         {
400             ShortcutPrefixActiveEvent.firePrefixStateChange(null, false);
401             shortcutOn = false;
402         }
403     } //}}}
404

405     protected boolean shortcutOn=false;
406     
407     //{{{ getSymbolicModifierName() method
408
/**
409      * Returns a the symbolic modifier name for the specified Java modifier
410      * flag.
411      *
412      * @param mod A modifier constant from <code>InputEvent</code>
413      *
414      * @since jEdit 4.1pre3
415      */

416     public static char getSymbolicModifierName(int mod)
417     {
418         return KeyEventTranslator.getSymbolicModifierName(mod);
419     } //}}}
420

421     //{{{ getModifierString() method
422
/**
423      * Returns a string containing symbolic modifier names set in the
424      * specified event.
425      *
426      * @param evt The event
427      *
428      * @since jEdit 4.1pre3
429      */

430     public static String JavaDoc getModifierString(InputEvent JavaDoc evt)
431     {
432         return KeyEventTranslator.getModifierString(evt);
433     } //}}}
434

435     //{{{ Private members
436

437     // Stores prefix name in bindings hashtable
438
public static Object JavaDoc PREFIX_STR = "PREFIX_STR";
439
440     private Hashtable JavaDoc bindings;
441     private Hashtable JavaDoc currentBindings;
442     //}}}
443

444 }
445
Popular Tags