diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-14 07:32:14 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-14 07:32:14 +0000 |
commit | e56fd42a10e63ad2bcc823a0f364530af1748fe2 (patch) | |
tree | 2c1e63f77f2568bfcb0a33b7f0bb5e148332cfb4 /chrome/browser/chromeos/status | |
parent | d141dead2e5ae9120552f18ef93892b1a90bc487 (diff) | |
download | chromium_src-e56fd42a10e63ad2bcc823a0f364530af1748fe2.zip chromium_src-e56fd42a10e63ad2bcc823a0f364530af1748fe2.tar.gz chromium_src-e56fd42a10e63ad2bcc823a0f364530af1748fe2.tar.bz2 |
Use special indicator text for xkb:us:dvorak:eng, mozc, mozc-jp, m17n:t:latn-pre, and m17n:t:latn-post.
BUG=chromium-os:4001
TEST=manually
Review URL: http://codereview.chromium.org/2771013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49669 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/status')
6 files changed, 184 insertions, 123 deletions
diff --git a/chrome/browser/chromeos/status/language_menu_button.cc b/chrome/browser/chromeos/status/language_menu_button.cc index c89808a..d7a8edb 100644 --- a/chrome/browser/chromeos/status/language_menu_button.cc +++ b/chrome/browser/chromeos/status/language_menu_button.cc @@ -68,9 +68,30 @@ enum { // 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"; +// A mapping from an input method id to a text for the language indicator. The +// mapping is necessary since some input methods belong to the same language. +// For example, both "xkb:us::eng" and "xkb:us:dvorak:eng" are for US English. +const struct { + const char* input_method_id; + const char* indicator_text; +} kMappingFromIdToIndicatorText[] = { + // To distinguish from "xkb:us::eng" + { "xkb:us:dvorak:eng", "DV" }, + // To distinguish from "xkb:jp::jpn" + { "mozc", "\xe3\x81\x82" }, // Japanese Hiragana letter A in UTF-8. + { "mozc-jp", "\xe3\x81\x82" }, + + // Handle "m17n:t" input methods here since ICU is not able to handle the + // language code "t". Note: most users use either latn-pre or latn-post + // methods, not both. The same is true for mozc/mozc-jp. + { "m17n:t:latn-pre", "LAT" }, + { "m17n:t:latn-post", "LAT" }, +}; +const size_t kMappingFromIdToIndicatorTextLen = + ARRAYSIZE_UNSAFE(kMappingFromIdToIndicatorText); + // Returns the language name for the given |language_code|. std::wstring GetLanguageName(const std::string& language_code) { const string16 language_name = l10n_util::GetDisplayNameForLocale( @@ -78,46 +99,6 @@ std::wstring GetLanguageName(const std::string& language_code) { 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) { @@ -155,13 +136,13 @@ LanguageMenuButton::LanguageMenuButton(StatusAreaHost* host) // Update the model RebuildModel(); // Grab the real estate. - UpdateIcon(kSpacer, L"" /* no tooltip */); + UpdateIndicator(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""); + UpdateIndicator(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. @@ -321,8 +302,8 @@ string16 LanguageMenuButton::GetLabelAt(int index) const { LanguageLibrary::GetLanguageCodeFromDescriptor( input_method_descriptors_->at(index)); bool need_method_name = (need_method_name_.count(language_code) > 0); - name = FormatInputLanguage(input_method_descriptors_->at(index), true, - need_method_name); + name = GetTextForMenu(input_method_descriptors_->at(index), + need_method_name); } else if (GetPropertyIndex(index, &index)) { const ImePropertyList& property_list = CrosLibrary::Get()->GetLanguageLibrary()->current_ime_properties(); @@ -406,8 +387,7 @@ void LanguageMenuButton::InputMethodChanged(LanguageLibrary* obj) { obj->previous_input_method(); const InputMethodDescriptor& current_input_method = obj->current_input_method(); - UpdateIconFromInputMethod(current_input_method); - + UpdateIndicatorFromInputMethod(current_input_method); // Update Chrome prefs as well. if (GetPrefService(host_)) { // Sometimes (e.g. initial boot) |previous_input_method.id| is empty. @@ -418,8 +398,8 @@ void LanguageMenuButton::InputMethodChanged(LanguageLibrary* obj) { void LanguageMenuButton::ActiveInputMethodsChanged(LanguageLibrary* obj) { // Update the icon if active input methods are changed. See also - // comments in UpdateIcon() - UpdateIconFromInputMethod(obj->current_input_method()); + // comments in UpdateIndicator() + UpdateIndicatorFromInputMethod(obj->current_input_method()); } void LanguageMenuButton::ImePropertiesChanged(LanguageLibrary* obj) { @@ -431,12 +411,12 @@ void LanguageMenuButton::ImePropertiesChanged(LanguageLibrary* obj) { void LanguageMenuButton::LocaleChanged() { const InputMethodDescriptor& input_method = CrosLibrary::Get()->GetLanguageLibrary()->current_input_method(); - UpdateIconFromInputMethod(input_method); + UpdateIndicatorFromInputMethod(input_method); Layout(); SchedulePaint(); } -void LanguageMenuButton::UpdateIcon( +void LanguageMenuButton::UpdateIndicator( const std::wstring& name, const std::wstring& tooltip) { if (!tooltip.empty()) { SetTooltipText(tooltip); @@ -460,11 +440,12 @@ void LanguageMenuButton::UpdateIcon( SchedulePaint(); } -void LanguageMenuButton::UpdateIconFromInputMethod( +void LanguageMenuButton::UpdateIndicatorFromInputMethod( const InputMethodDescriptor& input_method) { - const std::wstring name = FormatInputLanguage(input_method, false, false); - const std::wstring tooltip = FormatInputLanguage(input_method, true, true); - UpdateIcon(name, tooltip); + const std::wstring name = GetTextForIndicator(input_method); + const std::wstring tooltip = + GetTextForMenu(input_method, true /* add_method_name */); + UpdateIndicator(name, tooltip); } void LanguageMenuButton::RebuildModel() { @@ -563,4 +544,57 @@ bool LanguageMenuButton::IndexPointsToConfigureImeMenuItem(int index) const { (model_->GetCommandIdAt(index) == COMMAND_ID_CUSTOMIZE_LANGUAGE)); } +std::wstring LanguageMenuButton::GetTextForIndicator( + const InputMethodDescriptor& input_method) { + // For the status area, we use two-letter, upper-case language code like + // "EN" and "JA". + std::wstring text; + + // Check special cases first. + for (size_t i = 0; i < kMappingFromIdToIndicatorTextLen; ++i) { + if (kMappingFromIdToIndicatorText[i].input_method_id == input_method.id) { + text = UTF8ToWide(kMappingFromIdToIndicatorText[i].indicator_text); + break; + } + } + // TODO(yusukes): Some languages have two or more input methods. For example, + // Thai has 3, Traditional Chinese has many. If these input methods could be + // activated at the same time, we should do either of the following: + // (1) Add mappings to |kMappingFromIdToIndicatorText| + // (2) Add suffix (1, 2, ...) to |text| when ambiguous. + + if (text.empty()) { + const size_t kMaxLanguageNameLen = 2; + const std::wstring language_code = UTF8ToWide( + LanguageLibrary::GetLanguageCodeFromDescriptor(input_method)); + text = StringToUpperASCII(language_code).substr(0, kMaxLanguageNameLen); + } + DCHECK(!text.empty()); + return text; +} + +std::wstring LanguageMenuButton::GetTextForMenu( + const InputMethodDescriptor& input_method, bool add_method_name) { + const std::string language_code + = LanguageLibrary::GetLanguageCodeFromDescriptor(input_method); + + std::wstring text; + if (language_code == "t") { + text = UTF8ToWide(input_method.display_name); + } + + // For the drop-down menu and tooltip, we'll show language names like + // "Chinese (Simplified)" and "Japanese", instead of input method names + // like "Pinyin" and "Mozc". + if (text.empty()) { + text = GetLanguageName(language_code); + if (add_method_name) { + text += L" - "; + text += LanguageMenuL10nUtil::GetString(input_method.display_name); + } + } + DCHECK(!text.empty()); + return text; +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/status/language_menu_button.h b/chrome/browser/chromeos/status/language_menu_button.h index 78fe470..a7e4b64 100644 --- a/chrome/browser/chromeos/status/language_menu_button.h +++ b/chrome/browser/chromeos/status/language_menu_button.h @@ -59,6 +59,16 @@ class LanguageMenuButton : public views::MenuButton, const NotificationSource& source, const NotificationDetails& details) {} + // Converts an InputMethodDescriptor object into human readable string. + // Returns a text for the indicator on top right corner of the Chrome window. + static std::wstring GetTextForIndicator( + const InputMethodDescriptor& input_method); + + // Converts an InputMethodDescriptor object into human readable string. + // Returns a string for the drop-down menu and the tooltip for the indicator. + static std::wstring GetTextForMenu( + const InputMethodDescriptor& input_method, bool add_method_name); + protected: // views::View implementation. virtual void LocaleChanged(); @@ -68,10 +78,10 @@ class LanguageMenuButton : public views::MenuButton, virtual void RunMenu(views::View* source, const gfx::Point& pt); // Updates the status area with |name| and tooltip with |tooltip|. - void UpdateIcon(const std::wstring& name, const std::wstring& tooltip); + void UpdateIndicator(const std::wstring& name, const std::wstring& tooltip); // Updates the status area from the given input method. - void UpdateIconFromInputMethod( + void UpdateIndicatorFromInputMethod( const InputMethodDescriptor& input_method); // Rebuilds |model_|. This function should be called whenever diff --git a/chrome/browser/chromeos/status/language_menu_button_browsertest.cc b/chrome/browser/chromeos/status/language_menu_button_browsertest.cc index 74b9c41..976c2d9 100644 --- a/chrome/browser/chromeos/status/language_menu_button_browsertest.cc +++ b/chrome/browser/chromeos/status/language_menu_button_browsertest.cc @@ -16,26 +16,11 @@ namespace chromeos { -using ::testing::Return; -using ::testing::ReturnRef; - class LanguageMenuButtonTest : public CrosInProcessBrowserTest { protected: LanguageMenuButtonTest() - : CrosInProcessBrowserTest(), - korean_desc_("hangul", // The engine id for ibus-hangul. - "Korean", // The display name for the input method. - "us", // The input method assumes US keyboard layout. - "ko"), // The input method is for Korean language. - persian_desc_("m17n:fa:isiri", // The engine id for ibus-m17n - "isiri (m17n)", // The display name for the input method. - "us", // The input method assumes US keyboard layout. - "fa"), // The input method is for Farsi/Persian language. - invalid_desc_("invalid-id", - "unregistered string", - "us", - "xx") // Unknown language code. - {} + : CrosInProcessBrowserTest() { + } virtual void SetUpInProcessBrowserTestFixture() { InitStatusAreaMocks(); @@ -47,10 +32,6 @@ class LanguageMenuButtonTest : public CrosInProcessBrowserTest { return static_cast<BrowserStatusAreaView*>(view-> GetViewByID(VIEW_ID_STATUS_AREA))->language_view(); } - - InputMethodDescriptor korean_desc_; - InputMethodDescriptor persian_desc_; - InputMethodDescriptor invalid_desc_; }; IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, InitialIndicatorTest) { @@ -63,40 +44,4 @@ IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, InitialIndicatorTest) { EXPECT_EQ(L"EN", indicator); } -IN_PROC_BROWSER_TEST_F(LanguageMenuButtonTest, IndicatorAndTooltipUpdateTest) { - EXPECT_CALL(*mock_language_library_, previous_input_method()) - .Times(3) - .WillOnce(ReturnRef(invalid_desc_)) - .WillOnce(ReturnRef(invalid_desc_)) - .WillOnce(ReturnRef(invalid_desc_)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock_language_library_, current_input_method()) - .Times(3) - .WillOnce(ReturnRef(korean_desc_)) - .WillOnce(ReturnRef(persian_desc_)) - .WillOnce(ReturnRef(invalid_desc_)) - .RetiresOnSaturation(); - LanguageMenuButton* language = GetLanguageMenuButton(); - ASSERT_TRUE(language != NULL); - - language->InputMethodChanged(mock_language_library_); - std::wstring indicator = language->text(); - EXPECT_EQ(L"KO", indicator); - std::wstring tooltip; - language->GetTooltipText(gfx::Point(), &tooltip); - EXPECT_EQ(L"Korean - Korean input method", tooltip); - - language->InputMethodChanged(mock_language_library_); - indicator = language->text(); - EXPECT_EQ(L"FA", indicator); - language->GetTooltipText(gfx::Point(), &tooltip); - EXPECT_EQ(L"Persian - Persian input method (ISIRI 2901 layout)", tooltip); - - language->InputMethodChanged(mock_language_library_); - indicator = language->text(); - EXPECT_EQ(L"XX", indicator); - language->GetTooltipText(gfx::Point(), &tooltip); - EXPECT_EQ(L"xx - unregistered string", tooltip); -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/status/language_menu_button_unittest.cc b/chrome/browser/chromeos/status/language_menu_button_unittest.cc new file mode 100644 index 0000000..3f3372c --- /dev/null +++ b/chrome/browser/chromeos/status/language_menu_button_unittest.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2010 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 "base/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +TEST(LanguageMenuButtonTest, GetTextForIndicatorTest) { + // Test normal cases. Two-letter language code should be returned. + { + InputMethodDescriptor desc("m17n:fa:isiri", // input method engine id + "isiri (m17n)", // input method name + "us", // keyboard layout name + "fa"); // language name + EXPECT_EQ(L"FA", LanguageMenuButton::GetTextForIndicator(desc)); + } + { + InputMethodDescriptor desc("hangul", "Korean", "us", "ko"); + EXPECT_EQ(L"KO", LanguageMenuButton::GetTextForIndicator(desc)); + } + { + InputMethodDescriptor desc("invalid-id", "unregistered string", "us", "xx"); + // Upper-case string of the unknown language code, "xx", should be returned. + EXPECT_EQ(L"XX", LanguageMenuButton::GetTextForIndicator(desc)); + } + + // Test special cases. + { + InputMethodDescriptor desc("xkb:us:dvorak:eng", "Dvorak", "us", "us"); + EXPECT_EQ(L"DV", LanguageMenuButton::GetTextForIndicator(desc)); + } + { + InputMethodDescriptor desc("mozc", "Mozc", "us", "ja"); + EXPECT_EQ(UTF8ToWide("\xe3\x81\x82"), + LanguageMenuButton::GetTextForIndicator(desc)); + } + { + InputMethodDescriptor desc("mozc-jp", "Mozc", "jp", "ja"); + EXPECT_EQ(UTF8ToWide("\xe3\x81\x82"), + LanguageMenuButton::GetTextForIndicator(desc)); + } + { + InputMethodDescriptor desc("m17n:t:latn-pre", "latn-pre", "us", "t"); + EXPECT_EQ(L"LAT", + LanguageMenuButton::GetTextForIndicator(desc)); + } +} + +TEST(LanguageMenuButtonTest, GetTextForTooltipTest) { + const bool kAddMethodName = true; + { + InputMethodDescriptor desc("m17n:fa:isiri", "isiri (m17n)", "us", "fa"); + EXPECT_EQ(L"Persian - Persian input method (ISIRI 2901 layout)", + LanguageMenuButton::GetTextForMenu(desc, kAddMethodName)); + } + { + InputMethodDescriptor desc("hangul", "Korean", "us", "ko"); + EXPECT_EQ(L"Korean - Korean input method", + LanguageMenuButton::GetTextForMenu(desc, kAddMethodName)); + } + { + InputMethodDescriptor desc("invalid-id", "unregistered string", "us", "xx"); + // You can safely ignore the "Resouce ID is not found for: unregistered + // string" error. + EXPECT_EQ(L"xx - unregistered string", + LanguageMenuButton::GetTextForMenu(desc, kAddMethodName)); + } + { + InputMethodDescriptor desc("m17n:t:latn-pre", "latn-pre", "us", "t"); + EXPECT_EQ(L"latn-pre", + LanguageMenuButton::GetTextForMenu(desc, kAddMethodName)); + } +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/status/language_menu_l10n_util.cc b/chrome/browser/chromeos/status/language_menu_l10n_util.cc index c9f8378..711e461 100644 --- a/chrome/browser/chromeos/status/language_menu_l10n_util.cc +++ b/chrome/browser/chromeos/status/language_menu_l10n_util.cc @@ -154,8 +154,6 @@ namespace chromeos { std::wstring LanguageMenuL10nUtil::GetString( const std::string& english_string) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)) - << "You should not call this function from non-UI threads"; string16 localized_string; if (GetLocalizedString(english_string, &localized_string)) { return UTF16ToWide(localized_string); @@ -165,8 +163,6 @@ std::wstring LanguageMenuL10nUtil::GetString( std::string LanguageMenuL10nUtil::GetStringUTF8( const std::string& english_string) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)) - << "You should not call this function from non-UI threads"; string16 localized_string; if (GetLocalizedString(english_string, &localized_string)) { return UTF16ToUTF8(localized_string); @@ -176,8 +172,6 @@ std::string LanguageMenuL10nUtil::GetStringUTF8( string16 LanguageMenuL10nUtil::GetStringUTF16( const std::string& english_string) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)) - << "You should not call this function from non-UI threads"; string16 localized_string; if (GetLocalizedString(english_string, &localized_string)) { return localized_string; @@ -187,8 +181,6 @@ string16 LanguageMenuL10nUtil::GetStringUTF16( bool LanguageMenuL10nUtil::StringIsSupported( const std::string& english_string) { - // Do not check the current thread since the function is supposed to be called - // from unit tests. string16 localized_string; return GetLocalizedString(english_string, &localized_string); } diff --git a/chrome/browser/chromeos/status/language_menu_l10n_util.h b/chrome/browser/chromeos/status/language_menu_l10n_util.h index dd3cf4b..be48515 100644 --- a/chrome/browser/chromeos/status/language_menu_l10n_util.h +++ b/chrome/browser/chromeos/status/language_menu_l10n_util.h @@ -16,7 +16,8 @@ class LanguageMenuL10nUtil { public: // Converts a string sent from IBus IME engines, which is written in English, // into Chrome's string ID, then pulls internationalized resource string from - // the resource bundle and returns it. + // the resource bundle and returns it. These functions are not thread-safe. + // Non-UI threads are not allowed to call them. static std::wstring GetString(const std::string& english_string); static std::string GetStringUTF8(const std::string& english_string); static string16 GetStringUTF16(const std::string& english_string); |