OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/ime/input_method_win.h" | 5 #include "views/ime/input_method_win.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "ui/base/keycodes/keyboard_codes.h" | 10 #include "ui/base/keycodes/keyboard_codes.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 break; | 108 break; |
109 case WM_IME_STARTCOMPOSITION: | 109 case WM_IME_STARTCOMPOSITION: |
110 result = OnImeStartComposition(message, w_param, l_param, handled); | 110 result = OnImeStartComposition(message, w_param, l_param, handled); |
111 break; | 111 break; |
112 case WM_IME_COMPOSITION: | 112 case WM_IME_COMPOSITION: |
113 result = OnImeComposition(message, w_param, l_param, handled); | 113 result = OnImeComposition(message, w_param, l_param, handled); |
114 break; | 114 break; |
115 case WM_IME_ENDCOMPOSITION: | 115 case WM_IME_ENDCOMPOSITION: |
116 result = OnImeEndComposition(message, w_param, l_param, handled); | 116 result = OnImeEndComposition(message, w_param, l_param, handled); |
117 break; | 117 break; |
118 case WM_IME_REQUEST: | |
119 result = OnImeRequest(message, w_param, l_param, handled); | |
120 break; | |
118 case WM_CHAR: | 121 case WM_CHAR: |
119 case WM_SYSCHAR: | 122 case WM_SYSCHAR: |
120 result = OnChar(message, w_param, l_param, handled); | 123 result = OnChar(message, w_param, l_param, handled); |
121 break; | 124 break; |
122 case WM_DEADCHAR: | 125 case WM_DEADCHAR: |
123 case WM_SYSDEADCHAR: | 126 case WM_SYSDEADCHAR: |
124 result = OnDeadChar(message, w_param, l_param, handled); | 127 result = OnDeadChar(message, w_param, l_param, handled); |
125 break; | 128 break; |
126 default: | 129 default: |
127 NOTREACHED() << "Unknown IME message:" << message; | 130 NOTREACHED() << "Unknown IME message:" << message; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 return 0; | 215 return 0; |
213 | 216 |
214 if (GetTextInputClient()->HasCompositionText()) | 217 if (GetTextInputClient()->HasCompositionText()) |
215 GetTextInputClient()->ClearCompositionText(); | 218 GetTextInputClient()->ClearCompositionText(); |
216 | 219 |
217 ime_input_.ResetComposition(hwnd()); | 220 ime_input_.ResetComposition(hwnd()); |
218 ime_input_.DestroyImeWindow(hwnd()); | 221 ime_input_.DestroyImeWindow(hwnd()); |
219 return 0; | 222 return 0; |
220 } | 223 } |
221 | 224 |
225 LRESULT InputMethodWin::OnReconvertString(RECONVERTSTRING *reconv) { | |
James Su
2011/10/25 19:15:03
Please keep the order of methods in .cc file same
Peng
2011/10/25 22:01:21
Done.
James Su
2011/10/26 04:25:38
It's not done yet. OnReconvertString() and OnDocum
Peng
2011/10/26 16:20:16
Sorry. Done again.
| |
226 TextInputClient* client = GetTextInputClient(); | |
227 if (!client) | |
228 return 0; | |
229 | |
230 // If there is a composition string already, we don't allow reconversion. | |
231 if (client->HasCompositionText()) | |
232 return 0; | |
233 | |
234 ui::Range selection_range; | |
235 if (!client->GetSelectionRange(&selection_range) || | |
236 selection_range.is_empty()) { | |
237 return 0; | |
238 } | |
239 | |
240 size_t len = selection_range.length(); | |
241 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); | |
James Su
2011/10/25 19:15:03
It's better to return some extra content around se
Peng
2011/10/25 22:01:21
This logic is same with firefox. And currently we
James Su
2011/10/26 04:25:38
I think you misunderstood the purpose of those ext
Peng
2011/10/26 16:20:16
Done.
| |
242 | |
243 if (!reconv) | |
244 return need_size; | |
James Su
2011/10/25 19:15:03
The actual_range returned by TextInputClient::GetT
Peng
2011/10/25 22:01:21
Because text range must cover the selection range,
James Su
2011/10/26 04:25:38
You can't assume it here, especially if you want t
Peng
2011/10/26 16:20:16
Actually, I would like to remove actual_range from
James Su
2011/10/26 18:41:57
I don't think it's ok. The current api design look
Peng
2011/10/26 19:36:53
Remove acutal_range, can make both caller and text
James Su
2011/10/26 19:57:17
actual_range is necessary from the api design poin
Peng
2011/10/27 00:28:00
I didn't get it. Why we must have it from the API
James Su
2011/10/27 04:56:39
Without |actual_range| it's impossible for the cli
Peng
2011/10/27 16:12:24
I refined the document. The text input client must
| |
245 | |
246 if (reconv->dwSize < need_size) | |
247 return 0; | |
248 | |
249 string16 text; | |
250 ui::Range actual_range; | |
251 if (!GetTextInputClient()->GetTextFromRange( | |
252 selection_range, &text, &actual_range)) | |
253 return 0; | |
254 | |
255 reconv->dwVersion = 0; | |
256 reconv->dwStrLen = len; | |
257 reconv->dwStrOffset = sizeof(RECONVERTSTRING); | |
258 reconv->dwCompStrLen = len; | |
259 reconv->dwCompStrOffset = 0; | |
260 reconv->dwTargetStrLen = len; | |
261 reconv->dwTargetStrOffset = 0; | |
262 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), | |
263 text.c_str(), len * sizeof(WCHAR)); | |
264 | |
265 return need_size; | |
266 } | |
267 | |
268 LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING *reconv) { | |
James Su
2011/10/25 19:15:03
Please refer to the Microsoft sample to see how th
Peng
2011/10/25 22:01:21
It is almost same with MS sample. Only a little di
James Su
2011/10/26 04:25:38
I mean the extra context thing.
Peng
2011/10/26 16:20:16
This function returns all text which can be access
James Su
2011/10/26 18:41:57
I suggest to do the same thing as the Microsoft SD
Peng
2011/10/26 19:36:53
It is not easy task to decide how large context is
James Su
2011/10/26 19:57:17
The content in omnibox might be huge, especially w
Peng
2011/10/27 00:28:00
So I think currently it is better to just return t
James Su
2011/10/27 04:56:39
As I said, the document might be huge, and if the
Peng
2011/10/27 16:12:24
I would like to implement this function as firefox
| |
269 TextInputClient* client = GetTextInputClient(); | |
270 if (!client) | |
271 return 0; | |
272 | |
273 ui::Range text_range; | |
274 if (!client->GetTextRange(&text_range) || text_range.is_empty()) | |
275 return 0; | |
276 | |
277 ui::Range target_range; | |
278 do { | |
279 if (client->HasCompositionText() && | |
280 client->GetCompositionTextRange(&target_range) && | |
281 !target_range.is_empty()) { | |
282 break; | |
283 } | |
284 if (client->GetSelectionRange(&target_range)) | |
285 break; | |
286 return 0; | |
287 } while (0); | |
James Su
2011/10/25 19:15:03
nit: I don't like do { } while(0); style myself. I
Peng
2011/10/25 22:01:21
I tried using 'if else', but it looks worse.
James Su
2011/10/26 04:25:38
Please try your best to rewrite this piece of code
Peng
2011/10/26 16:20:16
I think it is not a big deal. It is very common fo
James Su
2011/10/26 18:41:57
I'd prefer something like:
ui::Range target_range
Peng
2011/10/26 19:36:53
Do not need check the return value of GetCompositi
James Su
2011/10/26 19:57:17
The return value is actually not a big deal here.
Peng
2011/10/27 00:28:00
Done.
| |
288 | |
289 if (!text_range.Contains(target_range)) | |
290 return 0; | |
291 | |
292 size_t len = text_range.length(); | |
293 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); | |
294 | |
295 if (!reconv) | |
296 return need_size; | |
297 | |
298 if (reconv->dwSize < need_size) | |
299 return 0; | |
300 | |
301 string16 text; | |
302 ui::Range actual_range; | |
303 if (!GetTextInputClient()->GetTextFromRange( | |
304 text_range, &text, &actual_range)) { | |
305 return 0; | |
306 } | |
307 | |
308 DCHECK(text_range == actual_range); | |
309 | |
310 reconv->dwVersion = 0; | |
311 reconv->dwStrLen = len; | |
312 reconv->dwStrOffset = sizeof(RECONVERTSTRING); | |
313 reconv->dwCompStrLen = | |
314 client->HasCompositionText() ? reconv->dwTargetStrOffset : 0; | |
315 reconv->dwCompStrOffset = | |
316 (target_range.GetMin() - text_range.start()) * sizeof(WCHAR); | |
317 reconv->dwTargetStrLen = target_range.length(); | |
318 reconv->dwTargetStrOffset = reconv->dwCompStrOffset; | |
319 | |
320 memcpy((char*)reconv + sizeof(RECONVERTSTRING), | |
321 text.c_str(), len * sizeof(WCHAR)); | |
322 | |
323 return need_size; | |
324 } | |
325 | |
326 LRESULT InputMethodWin::OnImeRequest( | |
327 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | |
328 *handled = FALSE; | |
329 | |
330 if (IsTextInputTypeNone()) | |
331 return 0; | |
332 | |
333 switch (wparam) { | |
334 case IMR_RECONVERTSTRING: | |
335 *handled = TRUE; | |
James Su
2011/10/25 19:15:03
should we set *handled to FALSE if any method of T
Peng
2011/10/25 22:01:21
I think we should set *handled to TRUE, because we
| |
336 return OnReconvertString(reinterpret_cast<RECONVERTSTRING*>(lparam)); | |
337 case IMR_DOCUMENTFEED: | |
338 *handled = TRUE; | |
339 return OnDocumentFeed(reinterpret_cast<RECONVERTSTRING*>(lparam)); | |
340 default: | |
341 return 0; | |
342 } | |
343 } | |
344 | |
222 LRESULT InputMethodWin::OnChar( | 345 LRESULT InputMethodWin::OnChar( |
223 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 346 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
224 *handled = TRUE; | 347 *handled = TRUE; |
225 | 348 |
226 // We need to send character events to the focused text input client event if | 349 // We need to send character events to the focused text input client event if |
227 // its text input type is ui::TEXT_INPUT_TYPE_NONE. | 350 // its text input type is ui::TEXT_INPUT_TYPE_NONE. |
228 if (!GetTextInputClient()) | 351 if (!GetTextInputClient()) |
229 return 0; | 352 return 0; |
230 | 353 |
231 int flags = 0; | 354 int flags = 0; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 case ui::TEXT_INPUT_TYPE_PASSWORD: | 396 case ui::TEXT_INPUT_TYPE_PASSWORD: |
274 ime_input_.DisableIME(hwnd()); | 397 ime_input_.DisableIME(hwnd()); |
275 break; | 398 break; |
276 default: | 399 default: |
277 ime_input_.EnableIME(hwnd()); | 400 ime_input_.EnableIME(hwnd()); |
278 break; | 401 break; |
279 } | 402 } |
280 } | 403 } |
281 | 404 |
282 } // namespace views | 405 } // namespace views |
OLD | NEW |