Add include.
[chromium-blink-merge.git] / ui / views / ime / input_method_bridge.cc
blob92f886ea78e2fb5055f0cb833dea027232112af2
1 // Copyright (c) 2012 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.
5 #include "ui/views/ime/input_method_bridge.h"
7 #include "ui/base/ime/input_method.h"
8 #include "ui/base/ime/input_method_observer.h"
9 #include "ui/events/event.h"
10 #include "ui/gfx/rect.h"
11 #include "ui/views/view.h"
12 #include "ui/views/widget/widget.h"
14 namespace views {
16 // InputMethodBridge::HostObserver class ---------------------------------------
18 // An observer class for observing the host input method. When the host input
19 // method is destroyed, it will null out the |host_| field on the
20 // InputMethodBridge object.
21 class InputMethodBridge::HostObserver : public ui::InputMethodObserver {
22 public:
23 explicit HostObserver(InputMethodBridge* bridge);
24 virtual ~HostObserver();
26 virtual void OnTextInputTypeChanged(
27 const ui::TextInputClient* client) override {}
28 virtual void OnFocus() override {}
29 virtual void OnBlur() override {}
30 virtual void OnCaretBoundsChanged(
31 const ui::TextInputClient* client) override {}
32 virtual void OnTextInputStateChanged(
33 const ui::TextInputClient* client) override {}
34 virtual void OnInputMethodDestroyed(
35 const ui::InputMethod* input_method) override;
36 virtual void OnShowImeIfNeeded() override {}
38 private:
39 InputMethodBridge* bridge_;
41 DISALLOW_COPY_AND_ASSIGN(HostObserver);
44 InputMethodBridge::HostObserver::HostObserver(InputMethodBridge* bridge)
45 : bridge_(bridge) {
46 bridge_->host_->AddObserver(this);
49 InputMethodBridge::HostObserver::~HostObserver() {
50 if (bridge_->host_)
51 bridge_->host_->RemoveObserver(this);
54 void InputMethodBridge::HostObserver::OnInputMethodDestroyed(
55 const ui::InputMethod* input_method) {
56 DCHECK_EQ(bridge_->host_, input_method);
57 bridge_->host_->RemoveObserver(this);
58 bridge_->host_ = NULL;
61 // InputMethodBridge class -----------------------------------------------------
63 InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate,
64 ui::InputMethod* host,
65 bool shared_input_method)
66 : host_(host),
67 shared_input_method_(shared_input_method) {
68 DCHECK(host_);
69 SetDelegate(delegate);
71 host_observer_.reset(new HostObserver(this));
74 InputMethodBridge::~InputMethodBridge() {
75 // By the time we get here it's very likely |widget_|'s NativeWidget has been
76 // destroyed. This means any calls to |widget_| that go to the NativeWidget,
77 // such as IsActive(), will crash. SetFocusedTextInputClient() may callback to
78 // this and go into |widget_|. NULL out |widget_| so we don't attempt to use
79 // it.
80 DetachFromWidget();
82 // Host input method might have been destroyed at this point.
83 if (host_)
84 host_->DetachTextInputClient(this);
87 void InputMethodBridge::OnFocus() {
88 DCHECK(host_);
90 // Direct the shared IME to send TextInputClient messages to |this| object.
91 if (shared_input_method_ || !host_->GetTextInputClient())
92 host_->SetFocusedTextInputClient(this);
94 // TODO(yusukes): We don't need to call OnTextInputTypeChanged() once we move
95 // text input type tracker code to ui::InputMethodBase.
96 if (GetFocusedView()) {
97 OnTextInputTypeChanged(GetFocusedView());
98 OnCaretBoundsChanged(GetFocusedView());
102 void InputMethodBridge::OnBlur() {
103 DCHECK(host_);
105 if (HasCompositionText()) {
106 ConfirmCompositionText();
107 host_->CancelComposition(this);
110 if (host_->GetTextInputClient() == this)
111 host_->SetFocusedTextInputClient(NULL);
114 bool InputMethodBridge::OnUntranslatedIMEMessage(const base::NativeEvent& event,
115 NativeEventResult* result) {
116 DCHECK(host_);
118 return host_->OnUntranslatedIMEMessage(event, result);
121 void InputMethodBridge::DispatchKeyEvent(const ui::KeyEvent& key) {
122 DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED);
124 // We can just dispatch the event here since the |key| is already processed by
125 // the system-wide IME.
126 DispatchKeyEventPostIME(key);
129 void InputMethodBridge::OnTextInputTypeChanged(View* view) {
130 DCHECK(host_);
132 if (IsViewFocused(view))
133 host_->OnTextInputTypeChanged(this);
134 InputMethodBase::OnTextInputTypeChanged(view);
137 void InputMethodBridge::OnCaretBoundsChanged(View* view) {
138 DCHECK(host_);
140 if (IsViewFocused(view) && !IsTextInputTypeNone())
141 host_->OnCaretBoundsChanged(this);
144 void InputMethodBridge::CancelComposition(View* view) {
145 DCHECK(host_);
147 if (IsViewFocused(view))
148 host_->CancelComposition(this);
151 void InputMethodBridge::OnInputLocaleChanged() {
152 DCHECK(host_);
154 host_->OnInputLocaleChanged();
157 std::string InputMethodBridge::GetInputLocale() {
158 DCHECK(host_);
160 return host_->GetInputLocale();
163 bool InputMethodBridge::IsActive() {
164 DCHECK(host_);
166 return host_->IsActive();
169 bool InputMethodBridge::IsCandidatePopupOpen() const {
170 DCHECK(host_);
172 return host_->IsCandidatePopupOpen();
175 void InputMethodBridge::ShowImeIfNeeded() {
176 DCHECK(host_);
177 host_->ShowImeIfNeeded();
180 // Overridden from TextInputClient. Forward an event from the system-wide IME
181 // to the text input |client|, which is e.g. views::Textfield.
182 void InputMethodBridge::SetCompositionText(
183 const ui::CompositionText& composition) {
184 TextInputClient* client = GetTextInputClient();
185 if (client)
186 client->SetCompositionText(composition);
189 void InputMethodBridge::ConfirmCompositionText() {
190 TextInputClient* client = GetTextInputClient();
191 if (client)
192 client->ConfirmCompositionText();
195 void InputMethodBridge::ClearCompositionText() {
196 TextInputClient* client = GetTextInputClient();
197 if (client)
198 client->ClearCompositionText();
201 void InputMethodBridge::InsertText(const base::string16& text) {
202 TextInputClient* client = GetTextInputClient();
203 if (client)
204 client->InsertText(text);
207 void InputMethodBridge::InsertChar(base::char16 ch, int flags) {
208 TextInputClient* client = GetTextInputClient();
209 if (client)
210 client->InsertChar(ch, flags);
213 gfx::NativeWindow InputMethodBridge::GetAttachedWindow() const {
214 TextInputClient* client = GetTextInputClient();
215 return client ?
216 client->GetAttachedWindow() : static_cast<gfx::NativeWindow>(NULL);
219 ui::TextInputType InputMethodBridge::GetTextInputType() const {
220 TextInputClient* client = GetTextInputClient();
221 return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
224 ui::TextInputMode InputMethodBridge::GetTextInputMode() const {
225 TextInputClient* client = GetTextInputClient();
226 return client ? client->GetTextInputMode() : ui::TEXT_INPUT_MODE_DEFAULT;
229 int InputMethodBridge::GetTextInputFlags() const {
230 TextInputClient* client = GetTextInputClient();
231 return client ? client->GetTextInputFlags() : 0;
234 bool InputMethodBridge::CanComposeInline() const {
235 TextInputClient* client = GetTextInputClient();
236 return client ? client->CanComposeInline() : true;
239 gfx::Rect InputMethodBridge::GetCaretBounds() const {
240 TextInputClient* client = GetTextInputClient();
241 if (!client)
242 return gfx::Rect();
244 return client->GetCaretBounds();
247 bool InputMethodBridge::GetCompositionCharacterBounds(uint32 index,
248 gfx::Rect* rect) const {
249 DCHECK(rect);
250 TextInputClient* client = GetTextInputClient();
251 if (!client)
252 return false;
254 return client->GetCompositionCharacterBounds(index, rect);
257 bool InputMethodBridge::HasCompositionText() const {
258 TextInputClient* client = GetTextInputClient();
259 return client ? client->HasCompositionText() : false;
262 bool InputMethodBridge::GetTextRange(gfx::Range* range) const {
263 TextInputClient* client = GetTextInputClient();
264 return client ? client->GetTextRange(range) : false;
267 bool InputMethodBridge::GetCompositionTextRange(gfx::Range* range) const {
268 TextInputClient* client = GetTextInputClient();
269 return client ? client->GetCompositionTextRange(range) : false;
272 bool InputMethodBridge::GetSelectionRange(gfx::Range* range) const {
273 TextInputClient* client = GetTextInputClient();
274 return client ? client->GetSelectionRange(range) : false;
277 bool InputMethodBridge::SetSelectionRange(const gfx::Range& range) {
278 TextInputClient* client = GetTextInputClient();
279 return client ? client->SetSelectionRange(range) : false;
282 bool InputMethodBridge::DeleteRange(const gfx::Range& range) {
283 TextInputClient* client = GetTextInputClient();
284 return client ? client->DeleteRange(range) : false;
287 bool InputMethodBridge::GetTextFromRange(const gfx::Range& range,
288 base::string16* text) const {
289 TextInputClient* client = GetTextInputClient();
290 return client ? client->GetTextFromRange(range, text) : false;
293 void InputMethodBridge::OnInputMethodChanged() {
294 TextInputClient* client = GetTextInputClient();
295 if (client)
296 client->OnInputMethodChanged();
299 bool InputMethodBridge::ChangeTextDirectionAndLayoutAlignment(
300 base::i18n::TextDirection direction) {
301 TextInputClient* client = GetTextInputClient();
302 return client ?
303 client->ChangeTextDirectionAndLayoutAlignment(direction) : false;
306 void InputMethodBridge::ExtendSelectionAndDelete(size_t before, size_t after) {
307 TextInputClient* client = GetTextInputClient();
308 if (client)
309 client->ExtendSelectionAndDelete(before, after);
312 void InputMethodBridge::EnsureCaretInRect(const gfx::Rect& rect) {
313 TextInputClient* client = GetTextInputClient();
314 if (client)
315 client->EnsureCaretInRect(rect);
318 void InputMethodBridge::OnCandidateWindowShown() {
321 void InputMethodBridge::OnCandidateWindowUpdated() {
324 void InputMethodBridge::OnCandidateWindowHidden() {
327 bool InputMethodBridge::IsEditingCommandEnabled(int command_id) {
328 return false;
331 void InputMethodBridge::ExecuteEditingCommand(int command_id) {
334 // Overridden from FocusChangeListener.
335 void InputMethodBridge::OnWillChangeFocus(View* focused_before, View* focused) {
336 if (HasCompositionText()) {
337 ConfirmCompositionText();
338 CancelComposition(focused_before);
342 void InputMethodBridge::OnDidChangeFocus(View* focused_before, View* focused) {
343 DCHECK_EQ(GetFocusedView(), focused);
344 OnTextInputTypeChanged(focused);
345 OnCaretBoundsChanged(focused);
348 ui::InputMethod* InputMethodBridge::GetHostInputMethod() const {
349 return host_;
353 } // namespace views