Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / ash / system / ime / tray_ime.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 "ash/system/ime/tray_ime.h"
6
7 #include <vector>
8
9 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/shelf/shelf_widget.h"
12 #include "ash/shell.h"
13 #include "ash/system/tray/hover_highlight_view.h"
14 #include "ash/system/tray/system_tray.h"
15 #include "ash/system/tray/system_tray_delegate.h"
16 #include "ash/system/tray/system_tray_notifier.h"
17 #include "ash/system/tray/tray_constants.h"
18 #include "ash/system/tray/tray_details_view.h"
19 #include "ash/system/tray/tray_item_more.h"
20 #include "ash/system/tray/tray_item_view.h"
21 #include "ash/system/tray/tray_utils.h"
22 #include "base/logging.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "grit/ash_resources.h"
25 #include "grit/ash_strings.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/font.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/views/controls/label.h"
31 #include "ui/views/layout/box_layout.h"
32 #include "ui/views/widget/widget.h"
33
34 namespace ash {
35 namespace internal {
36 namespace tray {
37
38 class IMEDefaultView : public TrayItemMore {
39  public:
40   explicit IMEDefaultView(SystemTrayItem* owner)
41       : TrayItemMore(owner, true) {
42     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
43
44     SetImage(bundle.GetImageNamed(
45         IDR_AURA_UBER_TRAY_IME).ToImageSkia());
46
47     IMEInfo info;
48     Shell::GetInstance()->system_tray_delegate()->GetCurrentIME(&info);
49     UpdateLabel(info);
50   }
51
52   virtual ~IMEDefaultView() {}
53
54   void UpdateLabel(const IMEInfo& info) {
55     SetLabel(info.name);
56     SetAccessibleName(info.name);
57   }
58
59  private:
60   DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
61 };
62
63 class IMEDetailedView : public TrayDetailsView,
64                         public ViewClickListener {
65  public:
66   IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
67       : TrayDetailsView(owner),
68         login_(login) {
69     SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
70     IMEInfoList list;
71     delegate->GetAvailableIMEList(&list);
72     IMEPropertyInfoList property_list;
73     delegate->GetCurrentIMEProperties(&property_list);
74     Update(list, property_list);
75   }
76
77   virtual ~IMEDetailedView() {}
78
79   void Update(const IMEInfoList& list,
80               const IMEPropertyInfoList& property_list) {
81     Reset();
82
83     AppendIMEList(list);
84     if (!property_list.empty())
85       AppendIMEProperties(property_list);
86     if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
87       AppendSettings();
88     AppendHeaderEntry();
89
90     Layout();
91     SchedulePaint();
92   }
93
94  private:
95   void AppendHeaderEntry() {
96     CreateSpecialRow(IDS_ASH_STATUS_TRAY_IME, this);
97   }
98
99   void AppendIMEList(const IMEInfoList& list) {
100     ime_map_.clear();
101     CreateScrollableList();
102     for (size_t i = 0; i < list.size(); i++) {
103       HoverHighlightView* container = new HoverHighlightView(this);
104       container->AddLabel(list[i].name,
105           list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
106       scroll_content()->AddChildView(container);
107       ime_map_[container] = list[i].id;
108     }
109   }
110
111   void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
112     property_map_.clear();
113     for (size_t i = 0; i < property_list.size(); i++) {
114       HoverHighlightView* container = new HoverHighlightView(this);
115       container->AddLabel(
116           property_list[i].name,
117           property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
118       if (i == 0)
119         container->SetBorder(views::Border::CreateSolidSidedBorder(
120             1, 0, 0, 0, kBorderLightColor));
121       scroll_content()->AddChildView(container);
122       property_map_[container] = property_list[i].key;
123     }
124   }
125
126   void AppendSettings() {
127     HoverHighlightView* container = new HoverHighlightView(this);
128     container->AddLabel(ui::ResourceBundle::GetSharedInstance().
129         GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
130         gfx::Font::NORMAL);
131     AddChildView(container);
132     settings_ = container;
133   }
134
135   // Overridden from ViewClickListener.
136   virtual void OnViewClicked(views::View* sender) OVERRIDE {
137     SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
138     if (sender == footer()->content()) {
139       TransitionToDefaultView();
140     } else if (sender == settings_) {
141       Shell::GetInstance()->metrics()->RecordUserMetricsAction(
142           ash::UMA_STATUS_AREA_IME_SHOW_DETAILED);
143       delegate->ShowIMESettings();
144     } else {
145       std::map<views::View*, std::string>::const_iterator ime_find;
146       ime_find = ime_map_.find(sender);
147       if (ime_find != ime_map_.end()) {
148         Shell::GetInstance()->metrics()->RecordUserMetricsAction(
149             ash::UMA_STATUS_AREA_IME_SWITCH_MODE);
150         std::string ime_id = ime_find->second;
151         delegate->SwitchIME(ime_id);
152         GetWidget()->Close();
153       } else {
154         std::map<views::View*, std::string>::const_iterator prop_find;
155         prop_find = property_map_.find(sender);
156         if (prop_find != property_map_.end()) {
157           const std::string key = prop_find->second;
158           delegate->ActivateIMEProperty(key);
159           GetWidget()->Close();
160         }
161       }
162     }
163   }
164
165   user::LoginStatus login_;
166
167   std::map<views::View*, std::string> ime_map_;
168   std::map<views::View*, std::string> property_map_;
169   views::View* settings_;
170
171   DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
172 };
173
174 }  // namespace tray
175
176 TrayIME::TrayIME(SystemTray* system_tray)
177     : SystemTrayItem(system_tray),
178       tray_label_(NULL),
179       default_(NULL),
180       detailed_(NULL) {
181   Shell::GetInstance()->system_tray_notifier()->AddIMEObserver(this);
182 }
183
184 TrayIME::~TrayIME() {
185   Shell::GetInstance()->system_tray_notifier()->RemoveIMEObserver(this);
186 }
187
188 void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
189   if (tray_label_) {
190     bool visible = count > 1;
191     tray_label_->SetVisible(visible);
192     // Do not change label before hiding because this change is noticeable.
193     if (!visible)
194       return;
195     if (current.third_party) {
196       tray_label_->label()->SetText(
197           current.short_name + base::UTF8ToUTF16("*"));
198     } else {
199       tray_label_->label()->SetText(current.short_name);
200     }
201     SetTrayLabelItemBorder(tray_label_, system_tray()->shelf_alignment());
202     tray_label_->Layout();
203   }
204 }
205
206 views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
207   CHECK(tray_label_ == NULL);
208   tray_label_ = new TrayItemView(this);
209   tray_label_->CreateLabel();
210   SetupLabelForTray(tray_label_->label());
211   // Hide IME tray when it is created, it will be updated when it is notified
212   // for IME refresh event.
213   tray_label_->SetVisible(false);
214   return tray_label_;
215 }
216
217 views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
218   SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
219   IMEInfoList list;
220   IMEPropertyInfoList property_list;
221   delegate->GetAvailableIMEList(&list);
222   delegate->GetCurrentIMEProperties(&property_list);
223   if (list.size() <= 1 && property_list.size() <= 1)
224     return NULL;
225   CHECK(default_ == NULL);
226   default_ = new tray::IMEDefaultView(this);
227   return default_;
228 }
229
230 views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
231   CHECK(detailed_ == NULL);
232   detailed_ = new tray::IMEDetailedView(this, status);
233   return detailed_;
234 }
235
236 void TrayIME::DestroyTrayView() {
237   tray_label_ = NULL;
238 }
239
240 void TrayIME::DestroyDefaultView() {
241   default_ = NULL;
242 }
243
244 void TrayIME::DestroyDetailedView() {
245   detailed_ = NULL;
246 }
247
248 void TrayIME::UpdateAfterLoginStatusChange(user::LoginStatus status) {
249 }
250
251 void TrayIME::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
252   SetTrayLabelItemBorder(tray_label_, alignment);
253   tray_label_->Layout();
254 }
255
256 void TrayIME::OnIMERefresh() {
257   SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
258   IMEInfoList list;
259   IMEInfo current;
260   IMEPropertyInfoList property_list;
261   delegate->GetCurrentIME(&current);
262   delegate->GetAvailableIMEList(&list);
263   delegate->GetCurrentIMEProperties(&property_list);
264
265   UpdateTrayLabel(current, list.size());
266
267   if (default_)
268     default_->UpdateLabel(current);
269   if (detailed_)
270     detailed_->Update(list, property_list);
271 }
272
273 }  // namespace internal
274 }  // namespace ash