Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: views/ime/input_method_win.cc

Issue 6688049: New InputMethod api for Views. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update according to review feedbacks. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "views/ime/input_method_win.h"
6
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/string_util.h"
10 #include "ui/base/keycodes/keyboard_codes.h"
11 #include "views/events/event.h"
12
13 namespace views {
14
15 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate)
16 : active_(false),
17 direction_(base::i18n::UNKNOWN_DIRECTION),
18 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION) {
19 set_delegate(delegate);
20 }
21
22 InputMethodWin::~InputMethodWin() {
23 if (widget())
24 ime_input_.DisableIME(hwnd());
25 }
26
27 void InputMethodWin::Init(Widget* widget) {
28 InputMethodBase::Init(widget);
29
30 // Gets the initial input locale and text direction information.
31 OnInputLangChange(0, 0);
32 }
33
34 void InputMethodWin::DispatchKeyEvent(const KeyEvent& key) {
35 // Handles ctrl-shift key to change text direction and layout alignment.
36 if (ui::ImeInput::IsRTLKeyboardLayoutInstalled() &&
37 IsClientSupportTextInput()) {
38 ui::KeyboardCode code = key.key_code();
39 if (key.type() == ui::ET_KEY_PRESSED) {
40 if (code == ui::VKEY_SHIFT) {
41 base::i18n::TextDirection dir;
42 if (ui::ImeInput::IsCtrlShiftPressed(&dir))
43 pending_requested_direction_ = dir;
44 } else if (code != ui::VKEY_CONTROL) {
45 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
46 }
47 } else if (key.type() == ui::ET_KEY_RELEASED &&
48 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) &&
49 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) {
50 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment(
51 pending_requested_direction_);
52 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
53 }
54 }
55
56 DispatchKeyEventPostIME(key);
57 }
58
59 void InputMethodWin::OnTextInputTypeChanged(View* view) {
60 if (IsViewFocused(view)) {
61 ime_input_.CancelIME(hwnd());
62 UpdateIMEState();
63 }
64 }
65
66 void InputMethodWin::OnCaretBoundsChanged(View* view) {
67 gfx::Rect rect;
68 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
69 return;
70 ime_input_.UpdateCaretRect(hwnd(), rect);
71 }
72
73 void InputMethodWin::CancelComposition(View* view) {
74 if (IsViewFocused(view))
75 ime_input_.CancelIME(hwnd());
76 }
77
78 std::string InputMethodWin::GetInputLocale() {
79 return locale_;
80 }
81
82 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() {
83 return direction_;
84 }
85
86 bool InputMethodWin::IsActive() {
87 return active_;
88 }
89
90 void InputMethodWin::FocusedViewWillChange() {
91 ConfirmCompositionText();
92 }
93
94 void InputMethodWin::FocusedViewDidChange() {
95 UpdateIMEState();
96 }
97
98 void InputMethodWin::OnSetFocus() {
99 if (!widget_focused()) {
100 set_widget_focused(true);
101 UpdateIMEState();
102 }
103 }
104
105 void InputMethodWin::OnKillFocus() {
106 if (widget_focused()) {
107 ConfirmCompositionText();
108 set_widget_focused(false);
109 }
110 }
111
112 void InputMethodWin::OnInputLangChange(DWORD character_set,
113 HKL input_language_id) {
114 active_ = ime_input_.SetInputLanguage();
115 locale_ = ime_input_.GetInputLanguageName();
116 direction_ = ime_input_.GetTextDirection();
117 OnInputMethodChanged();
118 }
119
120 LRESULT InputMethodWin::OnImeSetContext(
121 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
122 active_ = (wparam == TRUE);
123 if (active_)
124 ime_input_.CreateImeWindow(hwnd());
125
126 OnInputMethodChanged();
127 return ime_input_.SetImeWindowStyle(hwnd(), message, wparam, lparam, handled);
128 }
129
130 LRESULT InputMethodWin::OnImeStartComposition(
131 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
132 // We have to prevent WTL from calling ::DefWindowProc() because the function
133 // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to
134 // over-write the position of IME windows.
135 *handled = TRUE;
136
137 if (!IsClientSupportTextInput())
138 return 0;
139
140 // Reset the composition status and create IME windows.
141 ime_input_.CreateImeWindow(hwnd());
142 ime_input_.ResetComposition(hwnd());
143 return 0;
144 }
145
146 LRESULT InputMethodWin::OnImeComposition(
147 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
148 // We have to prevent WTL from calling ::DefWindowProc() because we do not
149 // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages.
150 *handled = TRUE;
151
152 if (!IsClientSupportTextInput())
153 return 0;
154
155 // At first, update the position of the IME window.
156 ime_input_.UpdateImeWindow(hwnd());
157
158 // Retrieve the result string and its attributes of the ongoing composition
159 // and send it to a renderer process.
160 ui::CompositionText composition;
161 if (ime_input_.GetResult(hwnd(), lparam, &composition.text)) {
162 GetTextInputClient()->InsertText(composition.text);
163 ime_input_.ResetComposition(hwnd());
164 // Fall though and try reading the composition string.
165 // Japanese IMEs send a message containing both GCS_RESULTSTR and
166 // GCS_COMPSTR, which means an ongoing composition has been finished
167 // by the start of another composition.
168 }
169 // Retrieve the composition string and its attributes of the ongoing
170 // composition and send it to a renderer process.
171 if (ime_input_.GetComposition(hwnd(), lparam, &composition))
172 GetTextInputClient()->SetCompositionText(composition);
173
174 return 0;
175 }
176
177 LRESULT InputMethodWin::OnImeEndComposition(
178 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
179 // Let WTL call ::DefWindowProc() and release its resources.
180 *handled = FALSE;
181
182 if (!IsClientSupportTextInput())
183 return 0;
184
185 if (GetTextInputClient()->HasCompositionText())
186 GetTextInputClient()->ClearCompositionText();
187
188 ime_input_.ResetComposition(hwnd());
189 ime_input_.DestroyImeWindow(hwnd());
190 return 0;
191 }
192
193 LRESULT InputMethodWin::OnChar(
194 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
195 *handled = TRUE;
196
197 if (!IsClientSupportTextInput())
198 return 0;
199
200 int flags = 0;
201 flags |= (::GetKeyState(VK_MENU) & 0x80)? ui::EF_ALT_DOWN : 0;
202 flags |= (::GetKeyState(VK_SHIFT) & 0x80)? ui::EF_SHIFT_DOWN : 0;
203 flags |= (::GetKeyState(VK_CONTROL) & 0x80)? ui::EF_CONTROL_DOWN : 0;
204 GetTextInputClient()->InsertChar(static_cast<char16>(wparam), flags);
205 return 0;
206 }
207
208 LRESULT InputMethodWin::OnDeadChar(
209 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
210 *handled = TRUE;
211
212 if (!IsClientSupportTextInput())
213 return 0;
214
215 // Shows the dead character as a composition text, so that the user can know
216 // what dead key was pressed.
217 ui::CompositionText composition;
218 composition.text.assign(1, static_cast<char16>(wparam));
219 composition.selection = ui::Range(0, 1);
220 composition.underlines.push_back(
221 ui::CompositionUnderline(0, 1, SK_ColorBLACK, false));
222 GetTextInputClient()->SetCompositionText(composition);
223 return 0;
224 }
225
226 void InputMethodWin::ConfirmCompositionText() {
227 if (IsClientSupportTextInput()) {
228 ime_input_.CleanupComposition(hwnd());
229 // Though above line should confirm the client's composition text by sending
230 // a result text to us, in case the input method and the client are in
231 // inconsistent states, we check the client's composition state again.
232 if (GetTextInputClient()->HasCompositionText())
233 GetTextInputClient()->ConfirmCompositionText();
234 }
235 }
236
237 void InputMethodWin::UpdateIMEState() {
238 // We disable input method for password field.
239 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_TEXT)
240 ime_input_.EnableIME(hwnd());
241 else
242 ime_input_.DisableIME(hwnd());
243 }
244
245 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698