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