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