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/base/ime/input_method_base.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/message_loop/message_loop.h" 10#include "ui/base/ime/input_method_delegate.h" 11#include "ui/base/ime/input_method_observer.h" 12#include "ui/base/ime/text_input_client.h" 13#include "ui/events/event.h" 14 15namespace ui { 16 17InputMethodBase::InputMethodBase() 18 : delegate_(NULL), 19 text_input_client_(NULL), 20 system_toplevel_window_focused_(false) { 21} 22 23InputMethodBase::~InputMethodBase() { 24 FOR_EACH_OBSERVER(InputMethodObserver, 25 observer_list_, 26 OnInputMethodDestroyed(this)); 27} 28 29void InputMethodBase::SetDelegate(internal::InputMethodDelegate* delegate) { 30 delegate_ = delegate; 31} 32 33void InputMethodBase::Init(bool focused) { 34 if (focused) 35 OnFocus(); 36} 37 38void InputMethodBase::OnFocus() { 39 DCHECK(!system_toplevel_window_focused_); 40 system_toplevel_window_focused_ = true; 41} 42 43void InputMethodBase::OnBlur() { 44 DCHECK(system_toplevel_window_focused_); 45 system_toplevel_window_focused_ = false; 46} 47 48void InputMethodBase::SetFocusedTextInputClient(TextInputClient* client) { 49 SetFocusedTextInputClientInternal(client); 50} 51 52void InputMethodBase::DetachTextInputClient(TextInputClient* client) { 53 if (text_input_client_ != client) 54 return; 55 SetFocusedTextInputClientInternal(NULL); 56} 57 58TextInputClient* InputMethodBase::GetTextInputClient() const { 59 return system_toplevel_window_focused_ ? text_input_client_ : NULL; 60} 61 62void InputMethodBase::OnTextInputTypeChanged(const TextInputClient* client) { 63 if (!IsTextInputClientFocused(client)) 64 return; 65 NotifyTextInputStateChanged(client); 66} 67 68TextInputType InputMethodBase::GetTextInputType() const { 69 TextInputClient* client = GetTextInputClient(); 70 return client ? client->GetTextInputType() : TEXT_INPUT_TYPE_NONE; 71} 72 73TextInputMode InputMethodBase::GetTextInputMode() const { 74 TextInputClient* client = GetTextInputClient(); 75 return client ? client->GetTextInputMode() : TEXT_INPUT_MODE_DEFAULT; 76} 77 78bool InputMethodBase::CanComposeInline() const { 79 TextInputClient* client = GetTextInputClient(); 80 return client ? client->CanComposeInline() : true; 81} 82 83void InputMethodBase::AddObserver(InputMethodObserver* observer) { 84 observer_list_.AddObserver(observer); 85} 86 87void InputMethodBase::RemoveObserver(InputMethodObserver* observer) { 88 observer_list_.RemoveObserver(observer); 89} 90 91bool InputMethodBase::IsTextInputClientFocused(const TextInputClient* client) { 92 return client && (client == GetTextInputClient()); 93} 94 95bool InputMethodBase::IsTextInputTypeNone() const { 96 return GetTextInputType() == TEXT_INPUT_TYPE_NONE; 97} 98 99void InputMethodBase::OnInputMethodChanged() const { 100 TextInputClient* client = GetTextInputClient(); 101 if (!IsTextInputTypeNone()) 102 client->OnInputMethodChanged(); 103} 104 105bool InputMethodBase::DispatchKeyEventPostIME( 106 const ui::KeyEvent& event) const { 107 if (!delegate_) 108 return false; 109 110 if (!event.HasNativeEvent()) 111 return delegate_->DispatchFabricatedKeyEventPostIME( 112 event.type(), event.key_code(), event.flags()); 113 114 return delegate_->DispatchKeyEventPostIME(event.native_event()); 115} 116 117void InputMethodBase::NotifyTextInputStateChanged( 118 const TextInputClient* client) { 119 FOR_EACH_OBSERVER(InputMethodObserver, 120 observer_list_, 121 OnTextInputStateChanged(client)); 122} 123 124void InputMethodBase::SetFocusedTextInputClientInternal( 125 TextInputClient* client) { 126 TextInputClient* old = text_input_client_; 127 if (old == client) 128 return; 129 OnWillChangeFocusedClient(old, client); 130 text_input_client_ = client; // NULL allowed. 131 OnDidChangeFocusedClient(old, client); 132 NotifyTextInputStateChanged(text_input_client_); 133} 134 135void InputMethodBase::OnCandidateWindowShown() { 136 base::MessageLoop::current()->PostTask( 137 FROM_HERE, 138 base::Bind(&InputMethodBase::CandidateWindowShownCallback, AsWeakPtr())); 139} 140 141void InputMethodBase::OnCandidateWindowUpdated() { 142 base::MessageLoop::current()->PostTask( 143 FROM_HERE, 144 base::Bind(&InputMethodBase::CandidateWindowUpdatedCallback, 145 AsWeakPtr())); 146} 147 148void InputMethodBase::OnCandidateWindowHidden() { 149 base::MessageLoop::current()->PostTask( 150 FROM_HERE, 151 base::Bind(&InputMethodBase::CandidateWindowHiddenCallback, AsWeakPtr())); 152} 153 154void InputMethodBase::CandidateWindowShownCallback() { 155 if (text_input_client_) 156 text_input_client_->OnCandidateWindowShown(); 157} 158 159void InputMethodBase::CandidateWindowUpdatedCallback() { 160 if (text_input_client_) 161 text_input_client_->OnCandidateWindowUpdated(); 162} 163 164void InputMethodBase::CandidateWindowHiddenCallback() { 165 if (text_input_client_) 166 text_input_client_->OnCandidateWindowHidden(); 167} 168 169} // namespace ui 170