View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2006 Bartek Teodorczyk <barteo@barteo.net>
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.microemu.device.impl;
21  
22  import javax.microedition.lcdui.TextField;
23  
24  import org.microemu.MIDletBridge;
25  import org.microemu.device.DeviceFactory;
26  import org.microemu.device.InputMethod;
27  import org.microemu.device.InputMethodEvent;
28  import org.microemu.device.InputMethodListener;
29  
30  public abstract class InputMethodImpl extends InputMethod implements Runnable {
31  
32  	protected boolean resetKey;
33  	
34  	protected Button lastButton;
35  	
36  	protected int lastButtonCharIndex;
37  
38  	private boolean cancel;
39  	
40  	private Thread t;
41  
42  	public InputMethodImpl() {
43  		this.lastButton = null;
44  		this.lastButtonCharIndex = -1;
45  		
46  		this.cancel = false;
47  		this.t = new Thread(this, "InputMethodThread");
48  		this.t.setDaemon(true);
49  		this.t.start();
50  	}
51  
52  	// TODO to be removed when event dispatcher will run input method task
53  	public void dispose() {
54  		cancel = true;
55  		synchronized (this) {
56  			notify();
57  		}
58  	}
59  
60  	// Runnable
61  	public void run() 
62  	{
63  		while (!cancel) {
64  			try {
65  				resetKey = true;
66  				synchronized (this) {
67  					wait(1500);
68  				}
69  			} catch (InterruptedException ex) {
70  			}
71  			synchronized (this) {
72  				if (resetKey && lastButton != null && inputMethodListener != null) {
73  					int caret = inputMethodListener.getCaretPosition() + 1;
74                      if (caret <= inputMethodListener.getText().length()) {
75      					lastButton = null;
76      					lastButtonCharIndex = -1;
77  						InputMethodEvent event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, inputMethodListener.getText());
78  						inputMethodListener.caretPositionChanged(event);
79                      }
80  				}
81  			}
82  		}
83  	}
84  	
85      public void setInputMethodListener(InputMethodListener l) {
86          super.setInputMethodListener(l);
87  
88          lastButton = null;
89          lastButtonCharIndex = -1;
90      }
91  	
92  	public void pointerPressed(int x, int y) {		
93  		if (DeviceFactory.getDevice().hasPointerEvents()) {
94  			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerPressed(x, y);
95  		}
96  	}
97  
98  	public void pointerReleased(int x, int y) {
99  		if (DeviceFactory.getDevice().hasPointerEvents()) {
100 			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerReleased(x, y);
101 		}
102 	}
103 
104 	public void pointerDragged(int x, int y) {
105 		if (DeviceFactory.getDevice().hasPointerMotionEvents()) {
106 			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerDragged(x, y);
107 		}
108 	}
109 	
110 	protected void insertText(String str) {
111 		if (str.length() > 0) {
112 			int caret = inputMethodListener.getCaretPosition();
113 			String tmp = "";
114 			synchronized (this) {
115 				if (lastButton != null) {
116 					caret++;
117 					lastButton = null;
118 					lastButtonCharIndex = -1;
119 				}
120 				if (caret > 0) {
121 					tmp += inputMethodListener.getText().substring(0, caret);
122 				}
123 				tmp += str;
124 				if (caret < inputMethodListener.getText().length()) {
125 					tmp += inputMethodListener.getText().substring(caret);
126 				}
127 				caret += str.length();
128 			}
129             if (!validate(tmp, inputMethodListener.getConstraints())) {
130                 return;
131             }
132 			InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, tmp);
133 			inputMethodListener.inputMethodTextChanged(event);
134 			event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, tmp);
135 			inputMethodListener.caretPositionChanged(event);
136 		}
137 	}
138 
139 	protected char[] filterConstraints(char[] chars) {
140 		char[] result = new char[chars.length];
141 		int i, j;
142 
143 		for (i = 0, j = 0; i < chars.length; i++) {
144             switch (inputMethodListener.getConstraints() & TextField.CONSTRAINT_MASK) {
145                 case TextField.ANY :
146                     result[j] = chars[i];
147                     j++;
148                     break;
149                 case TextField.EMAILADDR :
150                     // TODO
151                     break;
152                 case TextField.NUMERIC :
153                     if (Character.isDigit(chars[i]) || chars[i] == '-') {
154                         result[j] = chars[i];
155                         j++;
156                     }
157                     break;
158                 case TextField.PHONENUMBER :
159                     // TODO
160                     break;
161                 case TextField.URL :
162                     if (chars[i] != '\n') {
163                         result[j] = chars[i];
164                         j++;
165                     }
166                     break;
167                 case TextField.DECIMAL :
168                     if (Character.isDigit(chars[i]) || chars[i] == '-' || chars[i] == '.') {
169                         result[j] = chars[i];
170                         j++;
171                     }
172                     break;
173             }
174 		}
175 		if (i != j) {
176 			char[] newresult = new char[j];
177 			System.arraycopy(result, 0, newresult, 0, j);
178 			result = newresult;
179 		}
180 
181 		return result;
182 	}
183 
184 	protected char[] filterInputMode(char[] chars) {
185 	    if (chars == null) {
186 	        return new char[0];
187 	    }
188 	    
189 		int inputMode = getInputMode();
190 		char[] result = new char[chars.length];
191 		int i, j;
192 
193 		for (i = 0, j = 0; i < chars.length; i++) {
194 			if (inputMode == InputMethod.INPUT_ABC_UPPER) {
195 				result[j] = Character.toUpperCase(chars[i]);
196 				j++;
197 			} else if (inputMode == InputMethod.INPUT_ABC_LOWER) {
198 				result[j] = Character.toLowerCase(chars[i]);
199 				j++;
200 			} else if (inputMode == InputMethod.INPUT_123) {
201 				if (Character.isDigit(chars[i]) || chars[i] == '-' || chars[i] == '.') {
202 					result[j] = chars[i];
203 					j++;
204 				}
205 			}
206 		}
207 		if (i != j) {
208 			char[] newresult = new char[j];
209 			System.arraycopy(result, 0, newresult, 0, j);
210 			result = newresult;
211 		}
212 
213 		return result;
214 	}
215 	
216 }