Drive: Add BatchableRequest subclass.
[chromium-blink-merge.git] / ui / views / ime / input_method_bridge.cc
blob9abb1e2074473d75a9a58db80fa67a72e5e8356f
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/geometry/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 ~HostObserver() override;
26 void OnTextInputTypeChanged(const ui::TextInputClient* client) override {}
27 void OnFocus() override {}
28 void OnBlur() override {}
29 void OnCaretBoundsChanged(const ui::TextInputClient* client) override {}
30 void OnTextInputStateChanged(const ui::TextInputClient* client) override {}
31 void OnInputMethodDestroyed(const ui::InputMethod* input_method) override;
32 void OnShowImeIfNeeded() override {}
34 private:
35 InputMethodBridge* bridge_;
37 DISALLOW_COPY_AND_ASSIGN(HostObserver);
40 InputMethodBridge::HostObserver::HostObserver(InputMethodBridge* bridge)
41 : bridge_(bridge) {
42 bridge_->host_->AddObserver(this);
45 InputMethodBridge::HostObserver::~HostObserver() {
46 if (bridge_->host_)
47 bridge_->host_->RemoveObserver(this);
50 void InputMethodBridge::HostObserver::OnInputMethodDestroyed(
51 const ui::InputMethod* input_method) {
52 DCHECK_EQ(bridge_->host_, input_method);
53 bridge_->host_->RemoveObserver(this);
54 bridge_->host_ = NULL;
57 // InputMethodBridge class -----------------------------------------------------
59 InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate,
60 ui::InputMethod* host,
61 bool shared_input_method)
62 : host_(host),
63 shared_input_method_(shared_input_method) {
64 DCHECK(host_);
65 SetDelegate(delegate);
67 host_observer_.reset(new HostObserver(this));
70 InputMethodBridge::~InputMethodBridge() {
71 // By the time we get here it's very likely |widget_|'s NativeWidget has been
72 // destroyed. This means any calls to |widget_| that go to the NativeWidget,
73 // such as IsActive(), will crash. SetFocusedTextInputClient() may callback to
74 // this and go into |widget_|. NULL out |widget_| so we don't attempt to use
75 // it.
76 DetachFromWidget();
78 // Host input method might have been destroyed at this point.
79 if (host_)
80 host_->DetachTextInputClient(this);
83 void InputMethodBridge::OnFocus() {
84 DCHECK(host_);
86 // Direct the shared IME to send TextInputClient messages to |this| object.
87 if (shared_input_method_ || !host_->GetTextInputClient())
88 host_->SetFocusedTextInputClient(this);
90 // TODO(yusukes): We don't need to call OnTextInputTypeChanged() once we move
91 // text input type tracker code to ui::InputMethodBase.
92 if (GetFocusedView()) {
93 OnTextInputTypeChanged(GetFocusedView());
94 OnCaretBoundsChanged(GetFocusedView());
98 void InputMethodBridge::OnBlur() {
99 DCHECK(host_);
101 if (HasCompositionText()) {
102 ConfirmCompositionText();
103 host_->CancelComposition(this);
106 if (host_->GetTextInputClient() == this)
107 host_->SetFocusedTextInputClient(NULL);
110 bool InputMethodBridge::OnUntranslatedIMEMessage(const base::NativeEvent& event,
111 NativeEventResult* result) {
112 DCHECK(host_);
114 return host_->OnUntranslatedIMEMessage(event, result);
117 void InputMethodBridge::DispatchKeyEvent(const ui::KeyEvent& key) {
118 DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED);
120 // We can just dispatch the event here since the |key| is already processed by
121 // the system-wide IME.
122 DispatchKeyEventPostIME(key);
125 void InputMethodBridge::OnTextInputTypeChanged(View* view) {
126 DCHECK(host_);
128 if (IsViewFocused(view))
129 host_->OnTextInputTypeChanged(this);
130 InputMethodBase::OnTextInputTypeChanged(view);
133 void InputMethodBridge::OnCaretBoundsChanged(View* view) {
134 DCHECK(host_);
136 if (IsViewFocused(view) && !IsTextInputTypeNone())
137 host_->OnCaretBoundsChanged(this);
140 void InputMethodBridge::CancelComposition(View* view) {
141 DCHECK(host_);
143 if (IsViewFocused(view))
144 host_->CancelComposition(this);
147 void InputMethodBridge::OnInputLocaleChanged() {
148 DCHECK(host_);
150 host_->OnInputLocaleChanged();
153 std::string InputMethodBridge::GetInputLocale() {
154 DCHECK(host_);
156 return host_->GetInputLocale();
159 bool InputMethodBridge::IsActive() {
160 DCHECK(host_);
162 return host_->IsActive();
165 bool InputMethodBridge::IsCandidatePopupOpen() const {
166 DCHECK(host_);
168 return host_->IsCandidatePopupOpen();
171 void InputMethodBridge::ShowImeIfNeeded() {
172 DCHECK(host_);
173 host_->ShowImeIfNeeded();
176 // Overridden from TextInputClient. Forward an event from the system-wide IME
177 // to the text input |client|, which is e.g. views::Textfield.
178 void InputMethodBridge::SetCompositionText(
179 const ui::CompositionText& composition) {
180 TextInputClient* client = GetTextInputClient();
181 if (client)
182 client->SetCompositionText(composition);
185 void InputMethodBridge::ConfirmCompositionText() {
186 TextInputClient* client = GetTextInputClient();
187 if (client)
188 client->ConfirmCompositionText();
191 void InputMethodBridge::ClearCompositionText() {
192 TextInputClient* client = GetTextInputClient();
193 if (client)
194 client->ClearCompositionText();
197 void InputMethodBridge::InsertText(const base::string16& text) {
198 TextInputClient* client = GetTextInputClient();
199 if (client)
200 client->InsertText(text);
203 void InputMethodBridge::InsertChar(base::char16 ch, int flags) {
204 TextInputClient* client = GetTextInputClient();
205 if (client)
206 client->InsertChar(ch, flags);
209 gfx::NativeWindow InputMethodBridge::GetAttachedWindow() const {
210 TextInputClient* client = GetTextInputClient();
211 return client ?
212 client->GetAttachedWindow() : static_cast<gfx::NativeWindow>(NULL);
215 ui::TextInputType InputMethodBridge::GetTextInputType() const {
216 TextInputClient* client = GetTextInputClient();
217 return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
220 ui::TextInputMode InputMethodBridge::GetTextInputMode() const {
221 TextInputClient* client = GetTextInputClient();
222 return client ? client->GetTextInputMode() : ui::TEXT_INPUT_MODE_DEFAULT;
225 int InputMethodBridge::GetTextInputFlags() const {
226 TextInputClient* client = GetTextInputClient();
227 return client ? client->GetTextInputFlags() : 0;
230 bool InputMethodBridge::CanComposeInline() const {
231 TextInputClient* client = GetTextInputClient();
232 return client ? client->CanComposeInline() : true;
235 gfx::Rect InputMethodBridge::GetCaretBounds() const {
236 TextInputClient* client = GetTextInputClient();
237 if (!client)
238 return gfx::Rect();
240 return client->GetCaretBounds();
243 bool InputMethodBridge::GetCompositionCharacterBounds(uint32 index,
244 gfx::Rect* rect) const {
245 DCHECK(rect);
246 TextInputClient* client = GetTextInputClient();
247 if (!client)
248 return false;
250 return client->GetCompositionCharacterBounds(index, rect);
253 bool InputMethodBridge::HasCompositionText() const {
254 TextInputClient* client = GetTextInputClient();
255 return client ? client->HasCompositionText() : false;
258 bool InputMethodBridge::GetTextRange(gfx::Range* range) const {
259 TextInputClient* client = GetTextInputClient();
260 return client ? client->GetTextRange(range) : false;
263 bool InputMethodBridge::GetCompositionTextRange(gfx::Range* range) const {
264 TextInputClient* client = GetTextInputClient();
265 return client ? client->GetCompositionTextRange(range) : false;
268 bool InputMethodBridge::GetSelectionRange(gfx::Range* range) const {
269 TextInputClient* client = GetTextInputClient();
270 return client ? client->GetSelectionRange(range) : false;
273 bool InputMethodBridge::SetSelectionRange(const gfx::Range& range) {
274 TextInputClient* client = GetTextInputClient();
275 return client ? client->SetSelectionRange(range) : false;
278 bool InputMethodBridge::DeleteRange(const gfx::Range& range) {
279 TextInputClient* client = GetTextInputClient();
280 return client ? client->DeleteRange(range) : false;
283 bool InputMethodBridge::GetTextFromRange(const gfx::Range& range,
284 base::string16* text) const {
285 TextInputClient* client = GetTextInputClient();
286 return client ? client->GetTextFromRange(range, text) : false;
289 void InputMethodBridge::OnInputMethodChanged() {
290 TextInputClient* client = GetTextInputClient();
291 if (client)
292 client->OnInputMethodChanged();
295 bool InputMethodBridge::ChangeTextDirectionAndLayoutAlignment(
296 base::i18n::TextDirection direction) {
297 TextInputClient* client = GetTextInputClient();
298 return client ?
299 client->ChangeTextDirectionAndLayoutAlignment(direction) : false;
302 void InputMethodBridge::ExtendSelectionAndDelete(size_t before, size_t after) {
303 TextInputClient* client = GetTextInputClient();
304 if (client)
305 client->ExtendSelectionAndDelete(before, after);
308 void InputMethodBridge::EnsureCaretInRect(const gfx::Rect& rect) {
309 TextInputClient* client = GetTextInputClient();
310 if (client)
311 client->EnsureCaretInRect(rect);
314 void InputMethodBridge::OnCandidateWindowShown() {
317 void InputMethodBridge::OnCandidateWindowUpdated() {
320 void InputMethodBridge::OnCandidateWindowHidden() {
323 bool InputMethodBridge::IsEditCommandEnabled(int command_id) {
324 TextInputClient* client = GetTextInputClient();
325 return client ? client->IsEditCommandEnabled(command_id) : false;
328 void InputMethodBridge::SetEditCommandForNextKeyEvent(int command_id) {
329 TextInputClient* client = GetTextInputClient();
330 if (client)
331 client->SetEditCommandForNextKeyEvent(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