- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / ime / input_method_bridge.cc
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.
4
5 #include "ui/views/ime/input_method_bridge.h"
6
7 #include "ui/base/ime/input_method.h"
8 #include "ui/events/event.h"
9 #include "ui/gfx/rect.h"
10 #include "ui/views/view.h"
11 #include "ui/views/widget/widget.h"
12
13 namespace views {
14
15 InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate,
16                                      ui::InputMethod* host,
17                                      bool shared_input_method)
18     : host_(host),
19       shared_input_method_(shared_input_method) {
20   DCHECK(host_);
21   SetDelegate(delegate);
22 }
23
24 InputMethodBridge::~InputMethodBridge() {
25   // By the time we get here it's very likely |widget_|'s NativeWidget has been
26   // destroyed. This means any calls to |widget_| that go to the NativeWidget,
27   // such as IsActive(), will crash. SetFocusedTextInputClient() may callback to
28   // this and go into |widget_|. NULL out |widget_| so we don't attempt to use
29   // it.
30   DetachFromWidget();
31   host_->DetachTextInputClient(this);
32 }
33
34 void InputMethodBridge::OnFocus() {
35   // Direct the shared IME to send TextInputClient messages to |this| object.
36   if (shared_input_method_ || !host_->GetTextInputClient())
37     host_->SetFocusedTextInputClient(this);
38
39   // TODO(yusukes): We don't need to call OnTextInputTypeChanged() once we move
40   // text input type tracker code to ui::InputMethodBase.
41   if (GetFocusedView())
42     OnTextInputTypeChanged(GetFocusedView());
43 }
44
45 void InputMethodBridge::OnBlur() {
46   if (HasCompositionText()) {
47     ConfirmCompositionText();
48     host_->CancelComposition(this);
49   }
50
51   if (host_->GetTextInputClient() == this)
52     host_->SetFocusedTextInputClient(NULL);
53 }
54
55 bool InputMethodBridge::OnUntranslatedIMEMessage(const base::NativeEvent& event,
56                                                  NativeEventResult* result) {
57   return host_->OnUntranslatedIMEMessage(event, result);
58 }
59
60 void InputMethodBridge::DispatchKeyEvent(const ui::KeyEvent& key) {
61   DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED);
62
63   // We can just dispatch the event here since the |key| is already processed by
64   // the system-wide IME.
65   DispatchKeyEventPostIME(key);
66 }
67
68 void InputMethodBridge::OnTextInputTypeChanged(View* view) {
69   if (IsViewFocused(view))
70     host_->OnTextInputTypeChanged(this);
71   InputMethodBase::OnTextInputTypeChanged(view);
72 }
73
74 void InputMethodBridge::OnCaretBoundsChanged(View* view) {
75   if (IsViewFocused(view) && !IsTextInputTypeNone())
76     host_->OnCaretBoundsChanged(this);
77 }
78
79 void InputMethodBridge::CancelComposition(View* view) {
80   if (IsViewFocused(view))
81     host_->CancelComposition(this);
82 }
83
84 void InputMethodBridge::OnInputLocaleChanged() {
85   return host_->OnInputLocaleChanged();
86 }
87
88 std::string InputMethodBridge::GetInputLocale() {
89   return host_->GetInputLocale();
90 }
91
92 base::i18n::TextDirection InputMethodBridge::GetInputTextDirection() {
93   return host_->GetInputTextDirection();
94 }
95
96 bool InputMethodBridge::IsActive() {
97   return host_->IsActive();
98 }
99
100 bool InputMethodBridge::IsCandidatePopupOpen() const {
101   return host_->IsCandidatePopupOpen();
102 }
103
104 // Overridden from TextInputClient. Forward an event from the system-wide IME
105 // to the text input |client|, which is e.g. views::NativeTextfieldViews.
106 void InputMethodBridge::SetCompositionText(
107     const ui::CompositionText& composition) {
108   TextInputClient* client = GetTextInputClient();
109   if (client)
110     client->SetCompositionText(composition);
111 }
112
113 void InputMethodBridge::ConfirmCompositionText() {
114   TextInputClient* client = GetTextInputClient();
115   if (client)
116     client->ConfirmCompositionText();
117 }
118
119 void InputMethodBridge::ClearCompositionText() {
120   TextInputClient* client = GetTextInputClient();
121   if (client)
122     client->ClearCompositionText();
123 }
124
125 void InputMethodBridge::InsertText(const string16& text) {
126   TextInputClient* client = GetTextInputClient();
127   if (client)
128     client->InsertText(text);
129 }
130
131 void InputMethodBridge::InsertChar(char16 ch, int flags) {
132   TextInputClient* client = GetTextInputClient();
133   if (client)
134     client->InsertChar(ch, flags);
135 }
136
137 gfx::NativeWindow InputMethodBridge::GetAttachedWindow() const {
138   TextInputClient* client = GetTextInputClient();
139   return client ?
140       client->GetAttachedWindow() : static_cast<gfx::NativeWindow>(NULL);
141 }
142
143 ui::TextInputType InputMethodBridge::GetTextInputType() const {
144   TextInputClient* client = GetTextInputClient();
145   return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
146 }
147
148 ui::TextInputMode InputMethodBridge::GetTextInputMode() const {
149   TextInputClient* client = GetTextInputClient();
150   return client ? client->GetTextInputMode() : ui::TEXT_INPUT_MODE_DEFAULT;
151 }
152
153 bool InputMethodBridge::CanComposeInline() const {
154   TextInputClient* client = GetTextInputClient();
155   return client ? client->CanComposeInline() : true;
156 }
157
158 gfx::Rect InputMethodBridge::GetCaretBounds() const {
159   TextInputClient* client = GetTextInputClient();
160   if (!client)
161     return gfx::Rect();
162
163   return client->GetCaretBounds();
164 }
165
166 bool InputMethodBridge::GetCompositionCharacterBounds(uint32 index,
167                                                       gfx::Rect* rect) const {
168   DCHECK(rect);
169   TextInputClient* client = GetTextInputClient();
170   if (!client)
171     return false;
172
173   return client->GetCompositionCharacterBounds(index, rect);
174 }
175
176 bool InputMethodBridge::HasCompositionText() const {
177   TextInputClient* client = GetTextInputClient();
178   return client ? client->HasCompositionText() : false;
179 }
180
181 bool InputMethodBridge::GetTextRange(gfx::Range* range) const {
182   TextInputClient* client = GetTextInputClient();
183   return client ?  client->GetTextRange(range) : false;
184 }
185
186 bool InputMethodBridge::GetCompositionTextRange(gfx::Range* range) const {
187   TextInputClient* client = GetTextInputClient();
188   return client ? client->GetCompositionTextRange(range) : false;
189 }
190
191 bool InputMethodBridge::GetSelectionRange(gfx::Range* range) const {
192   TextInputClient* client = GetTextInputClient();
193   return client ? client->GetSelectionRange(range) : false;
194 }
195
196 bool InputMethodBridge::SetSelectionRange(const gfx::Range& range) {
197   TextInputClient* client = GetTextInputClient();
198   return client ? client->SetSelectionRange(range) : false;
199 }
200
201 bool InputMethodBridge::DeleteRange(const gfx::Range& range) {
202   TextInputClient* client = GetTextInputClient();
203   return client ? client->DeleteRange(range) : false;
204 }
205
206 bool InputMethodBridge::GetTextFromRange(const gfx::Range& range,
207                                          string16* text) const {
208   TextInputClient* client = GetTextInputClient();
209   return client ? client->GetTextFromRange(range, text) : false;
210 }
211
212 void InputMethodBridge::OnInputMethodChanged() {
213   TextInputClient* client = GetTextInputClient();
214   if (client)
215     client->OnInputMethodChanged();
216 }
217
218 bool InputMethodBridge::ChangeTextDirectionAndLayoutAlignment(
219     base::i18n::TextDirection direction) {
220   TextInputClient* client = GetTextInputClient();
221   return client ?
222       client->ChangeTextDirectionAndLayoutAlignment(direction) : false;
223 }
224
225 void InputMethodBridge::ExtendSelectionAndDelete(size_t before, size_t after) {
226   TextInputClient* client = GetTextInputClient();
227   if (client)
228     client->ExtendSelectionAndDelete(before, after);
229 }
230
231 void InputMethodBridge::EnsureCaretInRect(const gfx::Rect& rect) {
232   TextInputClient* client = GetTextInputClient();
233   if (client)
234     client->EnsureCaretInRect(rect);
235 }
236
237 // Overridden from FocusChangeListener.
238 void InputMethodBridge::OnWillChangeFocus(View* focused_before, View* focused) {
239   if (HasCompositionText()) {
240     ConfirmCompositionText();
241     CancelComposition(focused_before);
242   }
243 }
244
245 void InputMethodBridge::OnDidChangeFocus(View* focused_before, View* focused) {
246   DCHECK_EQ(GetFocusedView(), focused);
247   OnTextInputTypeChanged(focused);
248   OnCaretBoundsChanged(focused);
249 }
250
251 ui::InputMethod* InputMethodBridge::GetHostInputMethod() const {
252   return host_;
253 }
254
255
256 }  // namespace views