<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/language_menu_button.h"

#include <string>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/status/language_menu_l10n_util.h"
#include "chrome/browser/chromeos/status/status_area_host.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "third_party/cros/chromeos_keyboard.h"

// The language menu consists of 3 parts (in this order):
//
//   (1) input method names. The size of the list is always >= 1.
//   (2) input method properties. This list might be empty.
//   (3) "Customize language and input..." button.
//
// Example of the menu (Japanese):
//
// ============================== (border of the popup window)
// [ ] English                    (|index| in the following functions is 0)
// [*] Japanese
// [ ] Chinese (Simplified)
// ------------------------------ (separator)
// [*] Hiragana                   (index = 5, The property has 2 radio groups)
// [ ] Katakana
// [ ] HalfWidthKatakana
// [*] Roman
// [ ] Kana
// ------------------------------ (separator)
// Customize language and input...(index = 11)
// ============================== (border of the popup window)
//
// Example of the menu (Simplified Chinese):
//
// ============================== (border of the popup window)
// [ ] English
// [ ] Japanese
// [*] Chinese (Simplified)
// ------------------------------ (separator)
// Switch to full letter mode     (The property has 2 command buttons)
// Switch to half punctuation mode
// ------------------------------ (separator)
// Customize language and input...
// ============================== (border of the popup window)
//

namespace {

// Constants to specify the type of items in |model_|.
enum {
  COMMAND_ID_INPUT_METHODS = 0,  // English, Chinese, Japanese, Arabic, ...
  COMMAND_ID_IME_PROPERTIES,  // Hiragana, Katakana, ...
  COMMAND_ID_CUSTOMIZE_LANGUAGE,  // "Customize language and input..." button.
};

// A group ID for IME properties starts from 0. We use the huge value for the
// input method list to avoid conflict.
const int kRadioGroupLanguage = 1 << 16;
const int kRadioGroupNone = -1;
const size_t kMaxLanguageNameLen = 2;
const wchar_t kSpacer[] = L"MMM";

// Returns the language name for the given |language_code|.
std::wstring GetLanguageName(const std::string& language_code) {
  const string16 language_name = l10n_util::GetDisplayNameForLocale(
      language_code, g_browser_process->GetApplicationLocale(), true);
  return UTF16ToWide(language_name);
}

// Converts chromeos::InputMethodDescriptor object into human readable string.
// Returns a string for the drop-down menu if |for_menu| is true. Otherwise,
// returns a string for the status area.
std::wstring FormatInputLanguage(
    const chromeos::InputMethodDescriptor& input_method, bool for_menu,
    bool add_method_name) {
  const std::string language_code
      = chromeos::LanguageLibrary::GetLanguageCodeFromDescriptor(input_method);

  std::wstring formatted;
  if (language_code == "t") {
    // "t" is used by input methods that do not associate with a
    // particular language. Returns the display name as-is.
    formatted = UTF8ToWide(input_method.display_name);
  }

  if (for_menu) {
    // For the drop-down menu, we'll show language names like
    // "Chinese (Simplified)" and "Japanese", instead of input method names
    // like "Pinyin" and "Anthy".
    if (formatted.empty()) {
      formatted = GetLanguageName(language_code);
      if (add_method_name) {
        formatted += L" - ";
        formatted += chromeos::LanguageMenuL10nUtil::GetString(
            input_method.display_name);
      }
    }
  } else {
    // For the status area, we use two-letter, upper-case language code like
    // "EN" and "JA".
    if (formatted.empty()) {
      formatted = UTF8ToWide(language_code);
    }
    formatted = StringToUpperASCII(formatted).substr(0, kMaxLanguageNameLen);
  }
  DCHECK(!formatted.empty());
  return formatted;
}

// Returns PrefService object associated with |host|. Returns NULL if we are NOT
// within a browser.
PrefService* GetPrefService(chromeos::StatusAreaHost* host) {
  if (host->GetProfile()) {
    return host->GetProfile()->GetPrefs();
  }
  return NULL;
}

}  // namespace

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
// LanguageMenuButton

LanguageMenuButton::LanguageMenuButton(StatusAreaHost* host)
    : MenuButton(NULL, std::wstring(), this, false),
      input_method_descriptors_(CrosLibrary::Get()->GetLanguageLibrary()->
                                GetActiveInputMethods()),
      model_(NULL),
      // Be aware that the constructor of |language_menu_| calls GetItemCount()
      // in this class. Therefore, GetItemCount() have to return 0 when
      // |model_| is NULL.
      ALLOW_THIS_IN_INITIALIZER_LIST(language_menu_(this)),
      host_(host) {
  DCHECK(input_method_descriptors_.get() &&
         !input_method_descriptors_->empty());
  set_border(NULL);
  SetFont(ResourceBundle::GetSharedInstance().GetFont(
      ResourceBundle::BaseFont).DeriveFont(1, gfx::Font::BOLD));
  SetEnabledColor(0xB3FFFFFF);  // White with 70% Alpha
  SetDisabledColor(0x00FFFFFF);  // White with 00% Alpha (invisible)
  SetShowHighlighted(false);
  // Update the model
  RebuildModel();
  // Grab the real estate.
  UpdateIcon(kSpacer, L"" /* no tooltip */);

  // Draw the default indicator "EN". The default indicator "EN" is used when
  // |pref_service| is not available (for example, unit tests) or |pref_service|
  // is available, but Chrome preferences are not available (for example,
  // initial OS boot).
  UpdateIcon(L"EN", L"");

  // Use the same keyboard layout on all windows.
  if (CrosLibrary::Get()->EnsureLoaded()) {
    SetKeyboardLayoutPerWindow(false);
  }

  // Sync current and previous input methods on Chrome prefs with ibus-daemon.
  // InputMethodChanged() will be called soon and the indicator will be updated.
  LanguageLibrary* library = CrosLibrary::Get()->GetLanguageLibrary();
  PrefService* pref_service = GetPrefService(host_);
  if (pref_service) {
    previous_input_method_pref_.Init(
        prefs::kLanguagePreviousInputMethod, pref_service, this);
    const std::wstring& previous_input_method_id =
        previous_input_method_pref_.GetValue();
    if (!previous_input_method_id.empty()) {
      library->ChangeInputMethod(WideToUTF8(previous_input_method_id));
    }
    current_input_method_pref_.Init(
        prefs::kLanguageCurrentInputMethod, pref_service, this);
    const std::wstring& current_input_method_id =
        current_input_method_pref_.GetValue();
    if (!current_input_method_id.empty()) {
      library->ChangeInputMethod(WideToUTF8(current_input_method_id));<commit_msg>This added to already failing browser_tests on the chromiumos builder on the waterfall.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/language_menu_button.h"

#include <string>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/status/language_menu_l10n_util.h"
#include "chrome/browser/chromeos/status/status_area_host.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

// The language menu consists of 3 parts (in this order):
//
//   (1) input method names. The size of the list is always >= 1.
//   (2) input method properties. This list might be empty.
//   (3) "Customize language and input..." button.
//
// Example of the menu (Japanese):
//
// ============================== (border of the popup window)
// [ ] English                    (|index| in the following functions is 0)
// [*] Japanese
// [ ] Chinese (Simplified)
// ------------------------------ (separator)
// [*] Hiragana                   (index = 5, The property has 2 radio groups)
// [ ] Katakana
// [ ] HalfWidthKatakana
// [*] Roman
// [ ] Kana
// ------------------------------ (separator)
// Customize language and input...(index = 11)
// ============================== (border of the popup window)
//
// Example of the menu (Simplified Chinese):
//
// ============================== (border of the popup window)
// [ ] English
// [ ] Japanese
// [*] Chinese (Simplified)
// ------------------------------ (separator)
// Switch to full letter mode     (The property has 2 command buttons)
// Switch to half punctuation mode
// ------------------------------ (separator)
// Customize language and input...
// ============================== (border of the popup window)
//

namespace {

// Constants to specify the type of items in |model_|.
enum {
  COMMAND_ID_INPUT_METHODS = 0,  // English, Chinese, Japanese, Arabic, ...
  COMMAND_ID_IME_PROPERTIES,  // Hiragana, Katakana, ...
  COMMAND_ID_CUSTOMIZE_LANGUAGE,  // "Customize language and input..." button.
};

// A group ID for IME properties starts from 0. We use the huge value for the
// input method list to avoid conflict.
const int kRadioGroupLanguage = 1 << 16;
const int kRadioGroupNone = -1;
const size_t kMaxLanguageNameLen = 2;
const wchar_t kSpacer[] = L"MMM";

// Returns the language name for the given |language_code|.
std::wstring GetLanguageName(const std::string& language_code) {
  const string16 language_name = l10n_util::GetDisplayNameForLocale(
      language_code, g_browser_process->GetApplicationLocale(), true);
  return UTF16ToWide(language_name);
}

// Converts chromeos::InputMethodDescriptor object into human readable string.
// Returns a string for the drop-down menu if |for_menu| is true. Otherwise,
// returns a string for the status area.
std::wstring FormatInputLanguage(
    const chromeos::InputMethodDescriptor& input_method, bool for_menu,
    bool add_method_name) {
  const std::string language_code
      = chromeos::LanguageLibrary::GetLanguageCodeFromDescriptor(input_method);

  std::wstring formatted;
  if (language_code == "t") {
    // "t" is used by input methods that do not associate with a
    // particular language. Returns the display name as-is.
    formatted = UTF8ToWide(input_method.display_name);
  }

  if (for_menu) {
    // For the drop-down menu, we'll show language names like
    // "Chinese (Simplified)" and "Japanese", instead of input method names
    // like "Pinyin" and "Anthy".
    if (formatted.empty()) {
      formatted = GetLanguageName(language_code);
      if (add_method_name) {
        formatted += L" - ";
        formatted += chromeos::LanguageMenuL10nUtil::GetString(
            input_method.display_name);
      }
    }
  } else {
    // For the status area, we use two-letter, upper-case language code like
    // "EN" and "JA".
    if (formatted.empty()) {
      formatted = UTF8ToWide(language_code);
    }
    formatted = StringToUpperASCII(formatted).substr(0, kMaxLanguageNameLen);
  }
  DCHECK(!formatted.empty());
  return formatted;
}

// Returns PrefService object associated with |host|. Returns NULL if we are NOT
// within a browser.
PrefService* GetPrefService(chromeos::StatusAreaHost* host) {
  if (host->GetProfile()) {
    return host->GetProfile()->GetPrefs();
  }
  return NULL;
}

}  // namespace

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
// LanguageMenuButton

LanguageMenuButton::LanguageMenuButton(StatusAreaHost* host)
    : MenuButton(NULL, std::wstring(), this, false),
      input_method_descriptors_(CrosLibrary::Get()->GetLanguageLibrary()->
                                GetActiveInputMethods()),
      model_(NULL),
      // Be aware that the constructor of |language_menu_| calls GetItemCount()
      // in this class. Therefore, GetItemCount() have to return 0 when
      // |model_| is NULL.
      ALLOW_THIS_IN_INITIALIZER_LIST(language_menu_(this)),
      host_(host) {
  DCHECK(input_method_descriptors_.get() &&
         !input_method_descriptors_->empty());
  set_border(NULL);
  SetFont(ResourceBundle::GetSharedInstance().GetFont(
      ResourceBundle::BaseFont).DeriveFont(1, gfx::Font::BOLD));
  SetEnabledColor(0xB3FFFFFF);  // White with 70% Alpha
  SetDisabledColor(0x00FFFFFF);  // White with 00% Alpha (invisible)
  SetShowHighlighted(false);
  // Update the model
  RebuildModel();
  // Grab the real estate.
  UpdateIcon(kSpacer, L"" /* no tooltip */);

  // Draw the default indicator "EN". The default indicator "EN" is used when
  // |pref_service| is not available (for example, unit tests) or |pref_service|
  // is available, but Chrome preferences are not available (for example,
  // initial OS boot).
  UpdateIcon(L"EN", L"");

  // Sync current and previous input methods on Chrome prefs with ibus-daemon.
  // InputMethodChanged() will be called soon and the indicator will be updated.
  LanguageLibrary* library = CrosLibrary::Get()->GetLanguageLibrary();
  PrefService* pref_service = GetPrefService(host_);
  if (pref_service) {
    previous_input_method_pref_.Init(
        prefs::kLanguagePreviousInputMethod, pref_service, this);
    const std::wstring& previous_input_method_id =
        previous_input_method_pref_.GetValue();
    if (!previous_input_method_id.empty()) {
      library->ChangeInputMethod(WideToUTF8(previous_input_method_id));
    }
    current_input_method_pref_.Init(
        prefs::kLanguageCurrentInputMethod, pref_service, this);
    const std::wstring& current_input_method_id =
        current_input_method_pref_.GetValue();
    if (!current_input_method_id.empty()) {
      library->ChangeInputMethod(WideToUTF8(current_input_method_id));
{'fraction_non_alphanumeric': 0.15784671532846714, 'fraction_numerical': 0.007018528916339135, 'mean_word_length': 3.304833836858006, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3222684', 'n_tokens_mistral': 4268, 'n_tokens_neox': 4109, 'n_words': 1166}