PageRenderTime 30ms CodeModel.GetById 11ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/gui/KeyEventWorkaround.java

#
Java | 274 lines | 202 code | 15 blank | 57 comment | 52 complexity | f9cce32a3684715a6161afa83581fab8 MD5 | raw file
  1/*
  2 * KeyEventWorkaround.java - Works around bugs in Java event handling
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2000, 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
 23package org.gjt.sp.jedit.gui;
 24
 25//{{{ Imports
 26import java.awt.event.*;
 27import org.gjt.sp.jedit.Debug;
 28//}}}
 29
 30/**
 31 * Various hacks to get keyboard event handling to behave in a consistent manner
 32 * across Java implementations.
 33 *
 34 * @author Slava Pestov
 35 * @version $Id: KeyEventWorkaround.java 4841 2003-07-28 21:08:04Z spestov $
 36 */
 37public class KeyEventWorkaround
 38{
 39	//{{{ processKeyEvent() method
 40	public static KeyEvent processKeyEvent(KeyEvent evt)
 41	{
 42		int keyCode = evt.getKeyCode();
 43		char ch = evt.getKeyChar();
 44
 45		switch(evt.getID())
 46		{
 47		//{{{ KEY_PRESSED...
 48		case KeyEvent.KEY_PRESSED:
 49			lastKeyTime = System.currentTimeMillis();
 50			// get rid of keys we never need to handle
 51			switch(keyCode)
 52			{
 53			case KeyEvent.VK_DEAD_GRAVE:
 54			case KeyEvent.VK_DEAD_ACUTE:
 55			case KeyEvent.VK_DEAD_CIRCUMFLEX:
 56			case KeyEvent.VK_DEAD_TILDE:
 57			case KeyEvent.VK_DEAD_MACRON:
 58			case KeyEvent.VK_DEAD_BREVE:
 59			case KeyEvent.VK_DEAD_ABOVEDOT:
 60			case KeyEvent.VK_DEAD_DIAERESIS:
 61			case KeyEvent.VK_DEAD_ABOVERING:
 62			case KeyEvent.VK_DEAD_DOUBLEACUTE:
 63			case KeyEvent.VK_DEAD_CARON:
 64			case KeyEvent.VK_DEAD_CEDILLA:
 65			case KeyEvent.VK_DEAD_OGONEK:
 66			case KeyEvent.VK_DEAD_IOTA:
 67			case KeyEvent.VK_DEAD_VOICED_SOUND:
 68			case KeyEvent.VK_DEAD_SEMIVOICED_SOUND:
 69			case '\0':
 70				return null;
 71			case KeyEvent.VK_ALT:
 72				modifiers |= InputEvent.ALT_MASK;
 73				return null;
 74			case KeyEvent.VK_ALT_GRAPH:
 75				modifiers |= InputEvent.ALT_GRAPH_MASK;
 76				return null;
 77			case KeyEvent.VK_CONTROL:
 78				modifiers |= InputEvent.CTRL_MASK;
 79				return null;
 80			case KeyEvent.VK_SHIFT:
 81				modifiers |= InputEvent.SHIFT_MASK;
 82				return null;
 83			case KeyEvent.VK_META:
 84				modifiers |= InputEvent.META_MASK;
 85				return null;
 86			case KeyEvent.VK_NUMPAD0:
 87			case KeyEvent.VK_NUMPAD1:
 88			case KeyEvent.VK_NUMPAD2:
 89			case KeyEvent.VK_NUMPAD3:
 90			case KeyEvent.VK_NUMPAD4:
 91			case KeyEvent.VK_NUMPAD5:
 92			case KeyEvent.VK_NUMPAD6:
 93			case KeyEvent.VK_NUMPAD7:
 94			case KeyEvent.VK_NUMPAD8:
 95			case KeyEvent.VK_NUMPAD9:
 96			case KeyEvent.VK_MULTIPLY:
 97			case KeyEvent.VK_ADD:
 98			/* case KeyEvent.VK_SEPARATOR: */
 99			case KeyEvent.VK_SUBTRACT:
100			case KeyEvent.VK_DECIMAL:
101			case KeyEvent.VK_DIVIDE:
102			System.err.println(evt);
103				System.err.println("foo");
104				last = LAST_NUMKEYPAD;
105				return evt;
106			default:
107				if(!evt.isMetaDown())
108				{
109					if(evt.isControlDown()
110						&& evt.isAltDown())
111					{
112						lastKeyTime = 0L;
113					}
114					else if(!evt.isControlDown()
115						&& !evt.isAltDown())
116					{
117						lastKeyTime = 0L;
118
119						if(keyCode >= KeyEvent.VK_0
120							&& keyCode <= KeyEvent.VK_9)
121						{
122							return null;
123						}
124
125						if(keyCode >= KeyEvent.VK_A
126							&& keyCode <= KeyEvent.VK_Z)
127						{
128							return null;
129						}
130					}
131				}
132
133				if(Debug.ALT_KEY_PRESSED_DISABLED)
134				{
135					/* we don't handle key pressed A+ */
136					/* they're too troublesome */
137					if((modifiers & InputEvent.ALT_MASK) != 0)
138						return null;
139				}
140
141				last = LAST_NOTHING;
142				break;
143			}
144
145			return evt;
146		//}}}
147		//{{{ KEY_TYPED...
148		case KeyEvent.KEY_TYPED:
149			// need to let \b through so that backspace will work
150			// in HistoryTextFields
151			if((ch < 0x20 || ch == 0x7f || ch == 0xff)
152				&& ch != '\b' && ch != '\t' && ch != '\n')
153			{
154				return null;
155			}
156
157			if(System.currentTimeMillis() - lastKeyTime < 750)
158			{
159				if(!Debug.ALTERNATIVE_DISPATCHER)
160				{
161					if(((modifiers & InputEvent.CTRL_MASK) != 0
162						^ (modifiers & InputEvent.ALT_MASK) != 0)
163						|| (modifiers & InputEvent.META_MASK) != 0)
164					{
165						return null;
166					}
167				}
168
169				// if the last key was a numeric keypad key
170				// and NumLock is off, filter it out
171				if(last == LAST_NUMKEYPAD)
172				{
173					System.err.println("last was numpad");
174					last = LAST_NOTHING;
175					if((ch >= '0' && ch <= '9') || ch == '.'
176						|| ch == '/' || ch == '*'
177						|| ch == '-' || ch == '+')
178					{
179						System.err.println("kill");
180						return null;
181					}
182				}
183				// Windows JDK workaround
184				else if(last == LAST_ALT)
185				{
186					last = LAST_NOTHING;
187					switch(ch)
188					{
189					case 'B':
190					case 'M':
191					case 'X':
192					case 'c':
193					case '!':
194					case ',':
195					case '?':
196						return null;
197					}
198				}
199			}
200			else
201			{
202				if((modifiers & InputEvent.SHIFT_MASK) != 0)
203				{
204					switch(ch)
205					{
206					case '\n':
207					case '\t':
208					case ' ':
209						return null;
210					}
211				}
212				modifiers = 0;
213			}
214
215			return evt;
216		//}}}
217		//{{{ KEY_RELEASED...
218		case KeyEvent.KEY_RELEASED:
219			switch(keyCode)
220			{
221			case KeyEvent.VK_ALT:
222				modifiers &= ~InputEvent.ALT_MASK;
223				lastKeyTime = System.currentTimeMillis();
224				return null;
225			case KeyEvent.VK_ALT_GRAPH:
226				modifiers &= ~InputEvent.ALT_GRAPH_MASK;
227				return null;
228			case KeyEvent.VK_CONTROL:
229				modifiers &= ~InputEvent.CTRL_MASK;
230				return null;
231			case KeyEvent.VK_SHIFT:
232				modifiers &= ~InputEvent.SHIFT_MASK;
233				return null;
234			case KeyEvent.VK_META:
235				modifiers &= ~InputEvent.META_MASK;
236				return null;
237			case KeyEvent.VK_LEFT:
238			case KeyEvent.VK_RIGHT:
239				/* workaround for A+LEFT/RIGHT producing
240				 * garbage on Windows */
241				if(modifiers == InputEvent.ALT_MASK)
242					last = LAST_ALT;
243				break;
244			}
245			return evt;
246		//}}}
247		default:
248			return evt;
249		}
250	} //}}}
251
252	//{{{ numericKeypadKey() method
253	/**
254	 * A workaround for non-working NumLock status in some Java versions.
255	 * @since jEdit 4.0pre8
256	 */
257	public static void numericKeypadKey()
258	{
259		System.err.println("yank");
260		last = LAST_NOTHING;
261	} //}}}
262
263	//{{{ Package-private members
264	static long lastKeyTime;
265	static int modifiers;
266	//}}}
267
268	//{{{ Private members
269	private static int last;
270	private static final int LAST_NOTHING = 0;
271	private static final int LAST_NUMKEYPAD = 1;
272	private static final int LAST_ALT = 2;
273	//}}}
274}