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