Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ash / system / chromeos / tray_caps_lock.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/chromeos/tray_caps_lock.h"
6
7 #include "ash/metrics/user_metrics_recorder.h"
8 #include "ash/shell.h"
9 #include "ash/system/tray/actionable_view.h"
10 #include "ash/system/tray/fixed_sized_image_view.h"
11 #include "ash/system/tray/system_tray_delegate.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "ash/system/tray/tray_constants.h"
14 #include "base/sys_info.h"
15 #include "chromeos/ime/ime_keyboard.h"
16 #include "chromeos/ime/input_method_manager.h"
17 #include "grit/ash_resources.h"
18 #include "grit/ash_strings.h"
19 #include "ui/accessibility/ax_view_state.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/views/controls/image_view.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/layout/box_layout.h"
25 #include "ui/views/widget/widget.h"
26
27 namespace ash {
28 namespace {
29
30 bool CapsLockIsEnabled() {
31   chromeos::input_method::InputMethodManager* ime =
32       chromeos::input_method::InputMethodManager::Get();
33   return (ime && ime->GetImeKeyboard())
34              ? ime->GetImeKeyboard()->CapsLockIsEnabled()
35              : false;
36 }
37
38 }
39
40 class CapsLockDefaultView : public ActionableView {
41  public:
42   CapsLockDefaultView()
43       : text_label_(new views::Label),
44         shortcut_label_(new views::Label) {
45     SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
46                                           kTrayPopupPaddingHorizontal,
47                                           0,
48                                           kTrayPopupPaddingBetweenItems));
49
50     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
51     FixedSizedImageView* image =
52         new FixedSizedImageView(0, kTrayPopupItemHeight);
53     image->SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK).
54         ToImageSkia());
55     AddChildView(image);
56
57     text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
58     AddChildView(text_label_);
59
60     shortcut_label_->SetEnabled(false);
61     AddChildView(shortcut_label_);
62   }
63
64   virtual ~CapsLockDefaultView() {}
65
66   // Updates the label text and the shortcut text.
67   void Update(bool caps_lock_enabled) {
68     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
69     const int text_string_id = caps_lock_enabled ?
70         IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED :
71         IDS_ASH_STATUS_TRAY_CAPS_LOCK_DISABLED;
72     text_label_->SetText(bundle.GetLocalizedString(text_string_id));
73
74     int shortcut_string_id = 0;
75     bool search_mapped_to_caps_lock = Shell::GetInstance()->
76         system_tray_delegate()->IsSearchKeyMappedToCapsLock();
77     if (caps_lock_enabled) {
78       shortcut_string_id = search_mapped_to_caps_lock ?
79           IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH_OR_SHIFT :
80           IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH_OR_SHIFT;
81     } else {
82       shortcut_string_id = search_mapped_to_caps_lock ?
83           IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH :
84           IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH;
85     }
86     shortcut_label_->SetText(bundle.GetLocalizedString(shortcut_string_id));
87
88     Layout();
89   }
90
91  private:
92   // Overridden from views::View:
93   virtual void Layout() OVERRIDE {
94     views::View::Layout();
95
96     // Align the shortcut text with the right end
97     const int old_x = shortcut_label_->x();
98     const int new_x =
99         width() - shortcut_label_->width() - kTrayPopupPaddingHorizontal;
100     shortcut_label_->SetX(new_x);
101     const gfx::Size text_size = text_label_->size();
102     text_label_->SetSize(gfx::Size(text_size.width() + new_x - old_x,
103                                    text_size.height()));
104   }
105
106   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE {
107     state->role = ui::AX_ROLE_BUTTON;
108     state->name = text_label_->text();
109   }
110
111   // Overridden from ActionableView:
112   virtual bool PerformAction(const ui::Event& event) OVERRIDE {
113     chromeos::input_method::ImeKeyboard* keyboard =
114         chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
115     if (keyboard) {
116       Shell::GetInstance()->metrics()->RecordUserMetricsAction(
117           keyboard->CapsLockIsEnabled() ?
118           ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK :
119           ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK);
120       keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
121     }
122     return true;
123   }
124
125   views::Label* text_label_;
126   views::Label* shortcut_label_;
127
128   DISALLOW_COPY_AND_ASSIGN(CapsLockDefaultView);
129 };
130
131 TrayCapsLock::TrayCapsLock(SystemTray* system_tray)
132     : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_CAPS_LOCK),
133       default_(NULL),
134       detailed_(NULL),
135       caps_lock_enabled_(CapsLockIsEnabled()),
136       message_shown_(false) {
137   chromeos::input_method::InputMethodManager* ime =
138       chromeos::input_method::InputMethodManager::Get();
139   if (ime && ime->GetImeKeyboard())
140     ime->GetImeKeyboard()->AddObserver(this);
141 }
142
143 TrayCapsLock::~TrayCapsLock() {
144   chromeos::input_method::InputMethodManager* ime =
145       chromeos::input_method::InputMethodManager::Get();
146   if (ime && ime->GetImeKeyboard())
147     ime->GetImeKeyboard()->RemoveObserver(this);
148 }
149
150 void TrayCapsLock::OnCapsLockChanged(bool enabled) {
151   caps_lock_enabled_ = enabled;
152
153   if (tray_view())
154     tray_view()->SetVisible(caps_lock_enabled_);
155
156   if (default_) {
157     default_->Update(caps_lock_enabled_);
158   } else {
159     if (caps_lock_enabled_) {
160       if (!message_shown_) {
161         Shell::GetInstance()->metrics()->RecordUserMetricsAction(
162             ash::UMA_STATUS_AREA_CAPS_LOCK_POPUP);
163         PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
164         message_shown_ = true;
165       }
166     } else if (detailed_) {
167       detailed_->GetWidget()->Close();
168     }
169   }
170 }
171
172 bool TrayCapsLock::GetInitialVisibility() {
173   return CapsLockIsEnabled();
174 }
175
176 views::View* TrayCapsLock::CreateDefaultView(user::LoginStatus status) {
177   if (!caps_lock_enabled_)
178     return NULL;
179   DCHECK(default_ == NULL);
180   default_ = new CapsLockDefaultView;
181   default_->Update(caps_lock_enabled_);
182   return default_;
183 }
184
185 views::View* TrayCapsLock::CreateDetailedView(user::LoginStatus status) {
186   DCHECK(detailed_ == NULL);
187   detailed_ = new views::View;
188
189   detailed_->SetLayoutManager(new
190       views::BoxLayout(views::BoxLayout::kHorizontal,
191       kTrayPopupPaddingHorizontal, 10, kTrayPopupPaddingBetweenItems));
192
193   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
194   views::ImageView* image = new views::ImageView;
195   image->SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK).
196       ToImageSkia());
197
198   detailed_->AddChildView(image);
199
200   const int string_id = Shell::GetInstance()->system_tray_delegate()->
201                             IsSearchKeyMappedToCapsLock() ?
202       IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_SEARCH :
203       IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_ALT_SEARCH;
204   views::Label* label = new views::Label(bundle.GetLocalizedString(string_id));
205   label->SetMultiLine(true);
206   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
207   detailed_->AddChildView(label);
208   Shell::GetInstance()->metrics()->RecordUserMetricsAction(
209       ash::UMA_STATUS_AREA_CAPS_LOCK_DETAILED);
210
211   return detailed_;
212 }
213
214 void TrayCapsLock::DestroyDefaultView() {
215   default_ = NULL;
216 }
217
218 void TrayCapsLock::DestroyDetailedView() {
219   detailed_ = NULL;
220 }
221
222 }  // namespace ash