language_switch_menu.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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 "chrome/browser/chromeos/login/language_switch_menu.h"
6
7#include "app/resource_bundle.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chromeos/cros/cros_library.h"
11#include "chrome/browser/chromeos/cros/keyboard_library.h"
12#include "chrome/browser/chromeos/input_method/input_method_util.h"
13#include "chrome/browser/chromeos/language_preferences.h"
14#include "chrome/browser/chromeos/login/screen_observer.h"
15#include "chrome/browser/prefs/pref_service.h"
16#include "chrome/common/pref_names.h"
17#include "grit/generated_resources.h"
18#include "views/widget/widget_gtk.h"
19
20namespace {
21
22const int kLanguageMainMenuSize = 5;
23// TODO(glotov): need to specify the list as a part of the image customization.
24const char kLanguagesTopped[] = "es,it,de,fr,en-US";
25const int kMoreLanguagesSubMenu = 200;
26
27}  // namespace
28
29namespace chromeos {
30
31LanguageSwitchMenu::LanguageSwitchMenu()
32    : ALLOW_THIS_IN_INITIALIZER_LIST(menu_model_(this)),
33      ALLOW_THIS_IN_INITIALIZER_LIST(menu_model_submenu_(this)),
34      delta_x_(0),
35      delta_y_(0) {
36}
37
38void LanguageSwitchMenu::InitLanguageMenu() {
39  // Update LanguageList to contain entries in current locale.
40  language_list_.reset(new LanguageList);
41  language_list_->CopySpecifiedLanguagesUp(kLanguagesTopped);
42
43  // Clear older menu items.
44  menu_model_.Clear();
45  menu_model_submenu_.Clear();
46
47  // Fill menu items with updated items.
48  for (int line = 0; line != kLanguageMainMenuSize; line++) {
49    menu_model_.AddItem(
50        line, WideToUTF16(language_list_->GetLanguageNameAt(line)));
51  }
52  menu_model_.AddSeparator();
53  menu_model_.AddSubMenuWithStringId(kMoreLanguagesSubMenu,
54                                     IDS_LANGUAGES_MORE,
55                                     &menu_model_submenu_);
56  for (int line = kLanguageMainMenuSize;
57       line != language_list_->get_languages_count(); line++) {
58    menu_model_submenu_.AddItem(
59        line, WideToUTF16(language_list_->GetLanguageNameAt(line)));
60  }
61
62  // Initialize menu here so it appears fast when called.
63  menu_.reset(new views::Menu2(&menu_model_));
64}
65
66std::wstring LanguageSwitchMenu::GetCurrentLocaleName() const {
67  DCHECK(g_browser_process);
68  const std::string locale = g_browser_process->GetApplicationLocale();
69  return language_list_->GetLanguageNameAt(
70      language_list_->GetIndexFromLocale(locale));
71};
72
73void LanguageSwitchMenu::SetFirstLevelMenuWidth(int width) {
74  DCHECK(menu_ != NULL);
75  menu_->SetMinimumWidth(width);
76}
77
78// static
79void LanguageSwitchMenu::SwitchLanguage(const std::string& locale) {
80  // Save new locale.
81  DCHECK(g_browser_process);
82  PrefService* prefs = g_browser_process->local_state();
83  // TODO(markusheintz): If the preference is managed and can not be changed by
84  // the user, changing the language should be disabled in the UI.
85  // TODO(markusheintz): Change the if condition to prefs->IsUserModifiable()
86  // once Mattias landed his pending patch.
87  if (!prefs->IsManagedPreference(prefs::kApplicationLocale)) {
88    prefs->SetString(prefs::kApplicationLocale, locale);
89    prefs->SavePersistentPrefs();
90
91    // Switch the locale.
92    ResourceBundle::ReloadSharedInstance(locale);
93
94    // Enable the keyboard layouts that are necessary for the new locale.
95    input_method::EnableInputMethods(
96        locale, input_method::kKeyboardLayoutsOnly,
97        CrosLibrary::Get()->GetKeyboardLibrary()->
98            GetHardwareKeyboardLayoutName());
99
100    // The following line does not seem to affect locale anyhow. Maybe in
101    // future..
102    g_browser_process->SetApplicationLocale(locale);
103  }
104}
105
106////////////////////////////////////////////////////////////////////////////////
107// views::ViewMenuDelegate implementation.
108
109void LanguageSwitchMenu::RunMenu(views::View* source, const gfx::Point& pt) {
110  DCHECK(menu_ != NULL);
111  gfx::Point point(pt);
112  point.Offset(delta_x_, delta_y_);
113  menu_->RunMenuAt(point, views::Menu2::ALIGN_TOPRIGHT);
114}
115
116////////////////////////////////////////////////////////////////////////////////
117// menus::SimpleMenuModel::Delegate implementation.
118
119bool LanguageSwitchMenu::IsCommandIdChecked(int command_id) const {
120  return false;
121}
122
123bool LanguageSwitchMenu::IsCommandIdEnabled(int command_id) const {
124  return true;
125}
126
127bool LanguageSwitchMenu::GetAcceleratorForCommandId(
128    int command_id, menus::Accelerator* accelerator) {
129  return false;
130}
131
132void LanguageSwitchMenu::ExecuteCommand(int command_id) {
133  const std::string locale = language_list_->GetLocaleFromIndex(command_id);
134  SwitchLanguage(locale);
135  InitLanguageMenu();
136
137  // Update all view hierarchies that the locale has changed.
138  views::Widget::NotifyLocaleChanged();
139}
140
141}  // namespace chromeos
142