| OLD | NEW |
| (Empty) |
| 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 "chrome/browser/chromeos/status/input_method_menu.h" | |
| 6 | |
| 7 #include <string> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/string_split.h" | |
| 11 #include "base/string_util.h" | |
| 12 #include "base/time.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "chrome/browser/browser_process.h" | |
| 15 #include "chrome/browser/chromeos/input_method/input_method_util.h" | |
| 16 #include "chrome/browser/chromeos/status/status_area_view_chromeos.h" | |
| 17 #include "content/public/browser/user_metrics.h" | |
| 18 #include "grit/generated_resources.h" | |
| 19 #include "grit/theme_resources.h" | |
| 20 #include "ui/base/l10n/l10n_util.h" | |
| 21 #include "ui/base/models/simple_menu_model.h" | |
| 22 #include "ui/base/resource/resource_bundle.h" | |
| 23 #include "ui/views/controls/menu/menu_model_adapter.h" | |
| 24 #include "ui/views/controls/menu/menu_runner.h" | |
| 25 #include "ui/views/controls/menu/submenu_view.h" | |
| 26 #include "ui/views/widget/widget.h" | |
| 27 | |
| 28 using content::UserMetricsAction; | |
| 29 | |
| 30 // The language menu consists of 3 parts (in this order): | |
| 31 // | |
| 32 // (1) input method names. The size of the list is always >= 1. | |
| 33 // (2) input method properties. This list might be empty. | |
| 34 // (3) "Customize language and input..." button. | |
| 35 // | |
| 36 // Example of the menu (Japanese): | |
| 37 // | |
| 38 // ============================== (border of the popup window) | |
| 39 // [ ] English (|index| in the following functions is 0) | |
| 40 // [*] Japanese | |
| 41 // [ ] Chinese (Simplified) | |
| 42 // ------------------------------ (separator) | |
| 43 // [*] Hiragana (index = 5, The property has 2 radio groups) | |
| 44 // [ ] Katakana | |
| 45 // [ ] HalfWidthKatakana | |
| 46 // [*] Roman | |
| 47 // [ ] Kana | |
| 48 // ------------------------------ (separator) | |
| 49 // Customize language and input...(index = 11) | |
| 50 // ============================== (border of the popup window) | |
| 51 // | |
| 52 // Example of the menu (Simplified Chinese): | |
| 53 // | |
| 54 // ============================== (border of the popup window) | |
| 55 // [ ] English | |
| 56 // [ ] Japanese | |
| 57 // [*] Chinese (Simplified) | |
| 58 // ------------------------------ (separator) | |
| 59 // Switch to full letter mode (The property has 2 command buttons) | |
| 60 // Switch to half punctuation mode | |
| 61 // ------------------------------ (separator) | |
| 62 // Customize language and input... | |
| 63 // ============================== (border of the popup window) | |
| 64 // | |
| 65 | |
| 66 namespace { | |
| 67 | |
| 68 // Constants to specify the type of items in |model_|. | |
| 69 enum { | |
| 70 COMMAND_ID_INPUT_METHODS = 0, // English, Chinese, Japanese, Arabic, ... | |
| 71 COMMAND_ID_IME_PROPERTIES, // Hiragana, Katakana, ... | |
| 72 COMMAND_ID_CUSTOMIZE_LANGUAGE, // "Customize language and input..." button. | |
| 73 }; | |
| 74 | |
| 75 // A group ID for IME properties starts from 0. We use the huge value for the | |
| 76 // input method list to avoid conflict. | |
| 77 const int kRadioGroupLanguage = 1 << 16; | |
| 78 const int kRadioGroupNone = -1; | |
| 79 | |
| 80 // Returns the language name for the given |language_code|. | |
| 81 string16 GetLanguageName(const std::string& language_code) { | |
| 82 const string16 language_name = l10n_util::GetDisplayNameForLocale( | |
| 83 language_code, g_browser_process->GetApplicationLocale(), true); | |
| 84 return language_name; | |
| 85 } | |
| 86 | |
| 87 } // namespace | |
| 88 | |
| 89 namespace chromeos { | |
| 90 | |
| 91 using input_method::InputMethodManager; | |
| 92 | |
| 93 //////////////////////////////////////////////////////////////////////////////// | |
| 94 // InputMethodMenu | |
| 95 | |
| 96 InputMethodMenu::InputMethodMenu() | |
| 97 : input_method_descriptors_( | |
| 98 InputMethodManager::GetInstance()->GetActiveInputMethods()), | |
| 99 model_(new ui::SimpleMenuModel(NULL)), | |
| 100 ALLOW_THIS_IN_INITIALIZER_LIST(input_method_menu_delegate_( | |
| 101 new views::MenuModelAdapter(this))), | |
| 102 input_method_menu_( | |
| 103 new views::MenuItemView(input_method_menu_delegate_.get())), | |
| 104 input_method_menu_runner_(new views::MenuRunner(input_method_menu_)), | |
| 105 minimum_input_method_menu_width_(0), | |
| 106 menu_alignment_(views::MenuItemView::TOPRIGHT) { | |
| 107 DCHECK(input_method_descriptors_.get() && | |
| 108 !input_method_descriptors_->empty()); | |
| 109 AddObserver(); | |
| 110 } | |
| 111 | |
| 112 InputMethodMenu::~InputMethodMenu() { | |
| 113 // RemoveObserver() is no-op if |this| object is already removed from the | |
| 114 // observer list | |
| 115 RemoveObserver(); | |
| 116 } | |
| 117 | |
| 118 //////////////////////////////////////////////////////////////////////////////// | |
| 119 // ui::MenuModel implementation: | |
| 120 | |
| 121 int InputMethodMenu::GetCommandIdAt(int index) const { | |
| 122 return index; | |
| 123 } | |
| 124 | |
| 125 bool InputMethodMenu::IsItemDynamicAt(int index) const { | |
| 126 // Menu content for the language button could change time by time. | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 130 bool InputMethodMenu::GetAcceleratorAt( | |
| 131 int index, ui::Accelerator* accelerator) const { | |
| 132 // Views for Chromium OS does not support accelerators yet. | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 bool InputMethodMenu::IsItemCheckedAt(int index) const { | |
| 137 DCHECK_GE(index, 0); | |
| 138 DCHECK(input_method_descriptors_.get()); | |
| 139 | |
| 140 if (IndexIsInInputMethodList(index)) { | |
| 141 const input_method::InputMethodDescriptor& input_method | |
| 142 = input_method_descriptors_->at(index); | |
| 143 return input_method == InputMethodManager::GetInstance()-> | |
| 144 GetCurrentInputMethod(); | |
| 145 } | |
| 146 | |
| 147 if (GetPropertyIndex(index, &index)) { | |
| 148 const input_method::InputMethodPropertyList& property_list | |
| 149 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 150 return property_list.at(index).is_selection_item_checked; | |
| 151 } | |
| 152 | |
| 153 // Separator(s) or the "Customize language and input..." button. | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 int InputMethodMenu::GetGroupIdAt(int index) const { | |
| 158 DCHECK_GE(index, 0); | |
| 159 | |
| 160 if (IndexIsInInputMethodList(index)) | |
| 161 return kRadioGroupLanguage; | |
| 162 | |
| 163 if (GetPropertyIndex(index, &index)) { | |
| 164 const input_method::InputMethodPropertyList& property_list | |
| 165 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 166 return property_list.at(index).selection_item_id; | |
| 167 } | |
| 168 | |
| 169 return kRadioGroupNone; | |
| 170 } | |
| 171 | |
| 172 bool InputMethodMenu::HasIcons() const { | |
| 173 // We don't support icons on Chrome OS. | |
| 174 return false; | |
| 175 } | |
| 176 | |
| 177 bool InputMethodMenu::GetIconAt(int index, SkBitmap* icon) { | |
| 178 return false; | |
| 179 } | |
| 180 | |
| 181 ui::ButtonMenuItemModel* InputMethodMenu::GetButtonMenuItemAt( | |
| 182 int index) const { | |
| 183 return NULL; | |
| 184 } | |
| 185 | |
| 186 bool InputMethodMenu::IsEnabledAt(int index) const { | |
| 187 // Just return true so all input method names and input method propertie names | |
| 188 // could be clicked. | |
| 189 return true; | |
| 190 } | |
| 191 | |
| 192 ui::MenuModel* InputMethodMenu::GetSubmenuModelAt(int index) const { | |
| 193 // We don't use nested menus. | |
| 194 return NULL; | |
| 195 } | |
| 196 | |
| 197 void InputMethodMenu::HighlightChangedTo(int index) { | |
| 198 // Views for Chromium OS does not support this interface yet. | |
| 199 } | |
| 200 | |
| 201 void InputMethodMenu::MenuWillShow() { | |
| 202 // Views for Chromium OS does not support this interface yet. | |
| 203 } | |
| 204 | |
| 205 void InputMethodMenu::SetMenuModelDelegate(ui::MenuModelDelegate* delegate) { | |
| 206 // Not needed for current usage. | |
| 207 } | |
| 208 | |
| 209 int InputMethodMenu::GetItemCount() const { | |
| 210 if (!model_.get()) { | |
| 211 // Model is not constructed yet. This means that | |
| 212 // InputMethodMenu is being constructed. Return zero. | |
| 213 return 0; | |
| 214 } | |
| 215 return model_->GetItemCount(); | |
| 216 } | |
| 217 | |
| 218 ui::MenuModel::ItemType InputMethodMenu::GetTypeAt(int index) const { | |
| 219 DCHECK_GE(index, 0); | |
| 220 | |
| 221 if (IndexPointsToConfigureImeMenuItem(index)) { | |
| 222 return ui::MenuModel::TYPE_COMMAND; // "Customize language and input" | |
| 223 } | |
| 224 | |
| 225 if (IndexIsInInputMethodList(index)) | |
| 226 return ui::MenuModel::TYPE_RADIO; | |
| 227 | |
| 228 if (GetPropertyIndex(index, &index)) { | |
| 229 const input_method::InputMethodPropertyList& property_list | |
| 230 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 231 if (property_list.at(index).is_selection_item) { | |
| 232 return ui::MenuModel::TYPE_RADIO; | |
| 233 } | |
| 234 return ui::MenuModel::TYPE_COMMAND; | |
| 235 } | |
| 236 | |
| 237 return ui::MenuModel::TYPE_SEPARATOR; | |
| 238 } | |
| 239 | |
| 240 string16 InputMethodMenu::GetLabelAt(int index) const { | |
| 241 DCHECK_GE(index, 0); | |
| 242 DCHECK(input_method_descriptors_.get()); | |
| 243 | |
| 244 // We use IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE here as the button | |
| 245 // opens the same dialog that is opened from the main options dialog. | |
| 246 if (IndexPointsToConfigureImeMenuItem(index)) { | |
| 247 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE); | |
| 248 } | |
| 249 | |
| 250 string16 name; | |
| 251 if (IndexIsInInputMethodList(index)) { | |
| 252 name = GetTextForMenu(input_method_descriptors_->at(index)); | |
| 253 } else if (GetPropertyIndex(index, &index)) { | |
| 254 InputMethodManager* manager = InputMethodManager::GetInstance(); | |
| 255 const input_method::InputMethodPropertyList& property_list = | |
| 256 manager->GetCurrentInputMethodProperties(); | |
| 257 return manager->GetInputMethodUtil()->TranslateString( | |
| 258 property_list.at(index).label); | |
| 259 } | |
| 260 | |
| 261 return name; | |
| 262 } | |
| 263 | |
| 264 void InputMethodMenu::ActivatedAt(int index) { | |
| 265 DCHECK_GE(index, 0); | |
| 266 DCHECK(input_method_descriptors_.get()); | |
| 267 | |
| 268 if (IndexPointsToConfigureImeMenuItem(index)) { | |
| 269 OpenConfigUI(); | |
| 270 return; | |
| 271 } | |
| 272 | |
| 273 if (IndexIsInInputMethodList(index)) { | |
| 274 // Inter-IME switching. | |
| 275 const input_method::InputMethodDescriptor& input_method | |
| 276 = input_method_descriptors_->at(index); | |
| 277 InputMethodManager::GetInstance()->ChangeInputMethod( | |
| 278 input_method.id()); | |
| 279 content::RecordAction( | |
| 280 UserMetricsAction("LanguageMenuButton_InputMethodChanged")); | |
| 281 return; | |
| 282 } | |
| 283 | |
| 284 if (GetPropertyIndex(index, &index)) { | |
| 285 // Intra-IME switching (e.g. Japanese-Hiragana to Japanese-Katakana). | |
| 286 const input_method::InputMethodPropertyList& property_list | |
| 287 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 288 const std::string key = property_list.at(index).key; | |
| 289 if (property_list.at(index).is_selection_item) { | |
| 290 // Radio button is clicked. | |
| 291 const int id = property_list.at(index).selection_item_id; | |
| 292 // First, deactivate all other properties in the same radio group. | |
| 293 for (int i = 0; i < static_cast<int>(property_list.size()); ++i) { | |
| 294 if (i != index && id == property_list.at(i).selection_item_id) { | |
| 295 InputMethodManager::GetInstance()->SetImePropertyActivated( | |
| 296 property_list.at(i).key, false); | |
| 297 } | |
| 298 } | |
| 299 // Then, activate the property clicked. | |
| 300 InputMethodManager::GetInstance()->SetImePropertyActivated( | |
| 301 key, true); | |
| 302 } else { | |
| 303 // Command button like "Switch to half punctuation mode" is clicked. | |
| 304 // We can always use "Deactivate" for command buttons. | |
| 305 InputMethodManager::GetInstance()->SetImePropertyActivated( | |
| 306 key, false); | |
| 307 } | |
| 308 return; | |
| 309 } | |
| 310 | |
| 311 LOG(ERROR) << "Unexpected index: " << index; | |
| 312 } | |
| 313 | |
| 314 //////////////////////////////////////////////////////////////////////////////// | |
| 315 // views::MenuButtonListener implementation: | |
| 316 | |
| 317 void InputMethodMenu::OnMenuButtonClicked(views::View* source, | |
| 318 const gfx::Point& point) { | |
| 319 PrepareForMenuOpen(); | |
| 320 | |
| 321 if (minimum_input_method_menu_width_ > 0) { | |
| 322 DCHECK(input_method_menu_->HasSubmenu()); | |
| 323 views::SubmenuView* submenu = input_method_menu_->GetSubmenu(); | |
| 324 submenu->set_minimum_preferred_width(minimum_input_method_menu_width_); | |
| 325 } | |
| 326 | |
| 327 gfx::Point screen_location; | |
| 328 views::View::ConvertPointToScreen(source, &screen_location); | |
| 329 gfx::Rect bounds(screen_location, source->size()); | |
| 330 if (input_method_menu_runner_->RunMenuAt( | |
| 331 source->GetWidget()->GetTopLevelWidget(), NULL, bounds, | |
| 332 menu_alignment_, views::MenuRunner::HAS_MNEMONICS) == | |
| 333 views::MenuRunner::MENU_DELETED) | |
| 334 return; | |
| 335 } | |
| 336 | |
| 337 //////////////////////////////////////////////////////////////////////////////// | |
| 338 // InputMethodManager::Observer implementation: | |
| 339 | |
| 340 void InputMethodMenu::InputMethodChanged( | |
| 341 InputMethodManager* manager, | |
| 342 const input_method::InputMethodDescriptor& current_input_method, | |
| 343 size_t num_active_input_methods) { | |
| 344 UpdateUIFromInputMethod(current_input_method, num_active_input_methods); | |
| 345 } | |
| 346 | |
| 347 void InputMethodMenu::PropertyListChanged( | |
| 348 InputMethodManager* manager, | |
| 349 const input_method::InputMethodPropertyList& current_ime_properties) { | |
| 350 // Usual order of notifications of input method change is: | |
| 351 // 1. RegisterProperties(empty) | |
| 352 // 2. RegisterProperties(list-of-new-properties) | |
| 353 // 3. GlobalInputMethodChanged | |
| 354 // However, due to the asynchronicity, we occasionally (but rarely) face to | |
| 355 // 1. RegisterProperties(empty) | |
| 356 // 2. GlobalInputMethodChanged | |
| 357 // 3. RegisterProperties(list-of-new-properties) | |
| 358 // this order. On this unusual case, we must rebuild the menu after the last | |
| 359 // RegisterProperties. For the other cases, no rebuild is needed. Actually | |
| 360 // it is better to be avoided. Otherwise users can sometimes observe the | |
| 361 // awkward clear-then-register behavior. | |
| 362 if (!current_ime_properties.empty()) { | |
| 363 const input_method::InputMethodDescriptor& input_method = | |
| 364 manager->GetCurrentInputMethod(); | |
| 365 size_t num_active_input_methods = manager->GetNumActiveInputMethods(); | |
| 366 UpdateUIFromInputMethod(input_method, num_active_input_methods); | |
| 367 } | |
| 368 } | |
| 369 | |
| 370 void InputMethodMenu::PrepareForMenuOpen() { | |
| 371 content::RecordAction(UserMetricsAction("LanguageMenuButton_Open")); | |
| 372 PrepareMenuModel(); | |
| 373 } | |
| 374 | |
| 375 void InputMethodMenu::PrepareMenuModel() { | |
| 376 input_method_descriptors_.reset(InputMethodManager::GetInstance()-> | |
| 377 GetActiveInputMethods()); | |
| 378 RebuildModel(); | |
| 379 } | |
| 380 | |
| 381 void InputMethodMenu::ActiveInputMethodsChanged( | |
| 382 InputMethodManager* manager, | |
| 383 const input_method::InputMethodDescriptor& current_input_method, | |
| 384 size_t num_active_input_methods) { | |
| 385 // Update the icon if active input methods are changed. See also | |
| 386 // comments in UpdateUI() in input_method_menu_button.cc. | |
| 387 UpdateUIFromInputMethod(current_input_method, num_active_input_methods); | |
| 388 } | |
| 389 | |
| 390 void InputMethodMenu::UpdateUIFromInputMethod( | |
| 391 const input_method::InputMethodDescriptor& input_method, | |
| 392 size_t num_active_input_methods) { | |
| 393 InputMethodManager* manager = InputMethodManager::GetInstance(); | |
| 394 const string16 name = manager->GetInputMethodUtil()-> | |
| 395 GetInputMethodShortName(input_method); | |
| 396 const string16 tooltip = GetTextForMenu(input_method); | |
| 397 UpdateUI(input_method.id(), name, tooltip, num_active_input_methods); | |
| 398 } | |
| 399 | |
| 400 void InputMethodMenu::RebuildModel() { | |
| 401 model_->Clear(); | |
| 402 string16 dummy_label = UTF8ToUTF16(""); | |
| 403 // Indicates if separator's needed before each section. | |
| 404 bool need_separator = false; | |
| 405 | |
| 406 if (!input_method_descriptors_->empty()) { | |
| 407 // We "abuse" the command_id and group_id arguments of AddRadioItem method. | |
| 408 // A COMMAND_ID_XXX enum value is passed as command_id, and array index of | |
| 409 // |input_method_descriptors_| or |property_list| is passed as group_id. | |
| 410 for (size_t i = 0; i < input_method_descriptors_->size(); ++i) { | |
| 411 model_->AddRadioItem(COMMAND_ID_INPUT_METHODS, dummy_label, i); | |
| 412 } | |
| 413 | |
| 414 need_separator = true; | |
| 415 } | |
| 416 | |
| 417 const input_method::InputMethodPropertyList& property_list | |
| 418 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 419 if (!property_list.empty()) { | |
| 420 if (need_separator) { | |
| 421 model_->AddSeparator(); | |
| 422 } | |
| 423 for (size_t i = 0; i < property_list.size(); ++i) { | |
| 424 model_->AddRadioItem(COMMAND_ID_IME_PROPERTIES, dummy_label, i); | |
| 425 } | |
| 426 need_separator = true; | |
| 427 } | |
| 428 | |
| 429 if (ShouldSupportConfigUI()) { | |
| 430 // Note: We use AddSeparator() for separators, and AddRadioItem() for all | |
| 431 // other items even if an item is not actually a radio item. | |
| 432 if (need_separator) { | |
| 433 model_->AddSeparator(); | |
| 434 } | |
| 435 model_->AddRadioItem(COMMAND_ID_CUSTOMIZE_LANGUAGE, dummy_label, | |
| 436 0 /* dummy */); | |
| 437 } | |
| 438 | |
| 439 // Rebuild the menu from the model. | |
| 440 input_method_menu_delegate_->BuildMenu(input_method_menu_); | |
| 441 } | |
| 442 | |
| 443 bool InputMethodMenu::IndexIsInInputMethodList(int index) const { | |
| 444 DCHECK_GE(index, 0); | |
| 445 DCHECK(model_.get()); | |
| 446 if (index >= model_->GetItemCount()) { | |
| 447 return false; | |
| 448 } | |
| 449 | |
| 450 return ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && | |
| 451 (model_->GetCommandIdAt(index) == COMMAND_ID_INPUT_METHODS) && | |
| 452 input_method_descriptors_.get() && | |
| 453 (index < static_cast<int>(input_method_descriptors_->size()))); | |
| 454 } | |
| 455 | |
| 456 bool InputMethodMenu::GetPropertyIndex(int index, int* property_index) const { | |
| 457 DCHECK_GE(index, 0); | |
| 458 DCHECK(property_index); | |
| 459 DCHECK(model_.get()); | |
| 460 if (index >= model_->GetItemCount()) { | |
| 461 return false; | |
| 462 } | |
| 463 | |
| 464 if ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && | |
| 465 (model_->GetCommandIdAt(index) == COMMAND_ID_IME_PROPERTIES)) { | |
| 466 const int tmp_property_index = model_->GetGroupIdAt(index); | |
| 467 const input_method::InputMethodPropertyList& property_list | |
| 468 = InputMethodManager::GetInstance()->GetCurrentInputMethodProperties(); | |
| 469 if (tmp_property_index < static_cast<int>(property_list.size())) { | |
| 470 *property_index = tmp_property_index; | |
| 471 return true; | |
| 472 } | |
| 473 } | |
| 474 return false; | |
| 475 } | |
| 476 | |
| 477 bool InputMethodMenu::IndexPointsToConfigureImeMenuItem(int index) const { | |
| 478 DCHECK_GE(index, 0); | |
| 479 DCHECK(model_.get()); | |
| 480 if (index >= model_->GetItemCount()) { | |
| 481 return false; | |
| 482 } | |
| 483 | |
| 484 return ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && | |
| 485 (model_->GetCommandIdAt(index) == COMMAND_ID_CUSTOMIZE_LANGUAGE)); | |
| 486 } | |
| 487 | |
| 488 string16 InputMethodMenu::GetTextForMenu( | |
| 489 const input_method::InputMethodDescriptor& input_method) { | |
| 490 if (!input_method.name().empty()) { | |
| 491 // If the descriptor has a name, use it. | |
| 492 return UTF8ToUTF16(input_method.name()); | |
| 493 } | |
| 494 | |
| 495 // We don't show language here. Name of keyboard layout or input method | |
| 496 // usually imply (or explicitly include) its language. | |
| 497 | |
| 498 input_method::InputMethodManager* manager = | |
| 499 input_method::InputMethodManager::GetInstance(); | |
| 500 | |
| 501 // Special case for German, French and Dutch: these languages have multiple | |
| 502 // keyboard layouts and share the same layout of keyboard (Belgian). We need | |
| 503 // to show explicitly the language for the layout. For Arabic, Amharic, and | |
| 504 // Indic languages: they share "Standard Input Method". | |
| 505 const string16 standard_input_method_text = l10n_util::GetStringUTF16( | |
| 506 IDS_OPTIONS_SETTINGS_LANGUAGES_M17N_STANDARD_INPUT_METHOD); | |
| 507 const std::string language_code = input_method.language_code(); | |
| 508 | |
| 509 string16 text = | |
| 510 manager->GetInputMethodUtil()->TranslateString(input_method.id()); | |
| 511 if (text == standard_input_method_text || | |
| 512 language_code == "de" || | |
| 513 language_code == "fr" || | |
| 514 language_code == "nl") { | |
| 515 text = GetLanguageName(language_code) + UTF8ToUTF16(" - ") + text; | |
| 516 } | |
| 517 | |
| 518 DCHECK(!text.empty()); | |
| 519 return text; | |
| 520 } | |
| 521 | |
| 522 void InputMethodMenu::SetMinimumWidth(int width) { | |
| 523 // On the OOBE network selection screen, fixed width menu would be preferable. | |
| 524 minimum_input_method_menu_width_ = width; | |
| 525 } | |
| 526 | |
| 527 void InputMethodMenu::AddObserver() { | |
| 528 InputMethodManager* manager = InputMethodManager::GetInstance(); | |
| 529 manager->AddObserver(this); | |
| 530 } | |
| 531 | |
| 532 void InputMethodMenu::RemoveObserver() { | |
| 533 InputMethodManager* manager = InputMethodManager::GetInstance(); | |
| 534 manager->RemoveObserver(this); | |
| 535 } | |
| 536 | |
| 537 } // namespace chromeos | |
| OLD | NEW |