summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/webui/options/language_options_handler.cc
blob: c34e61415aa378d1410c40007a4edc9493d901da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2012 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/ui/webui/options/language_options_handler.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_ui.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

using content::UserMetricsAction;

namespace options {

LanguageOptionsHandler::LanguageOptionsHandler() {
}

LanguageOptionsHandler::~LanguageOptionsHandler() {
}

void LanguageOptionsHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  LanguageOptionsHandlerCommon::GetLocalizedValues(localized_strings);

  RegisterTitle(localized_strings, "languagePage",
                IDS_OPTIONS_SETTINGS_LANGUAGES_DIALOG_TITLE);
  localized_strings->SetString("restart_button",
      l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON));
  localized_strings->Set("languageList", GetLanguageList());
}

void LanguageOptionsHandler::RegisterMessages() {
  LanguageOptionsHandlerCommon::RegisterMessages();

  web_ui()->RegisterMessageCallback("uiLanguageRestart",
      base::Bind(&LanguageOptionsHandler::RestartCallback,
                 base::Unretained(this)));
}

ListValue* LanguageOptionsHandler::GetLanguageList() {
  // Collect the language codes from the supported accept-languages.
  const std::string app_locale = g_browser_process->GetApplicationLocale();
  std::vector<std::string> language_codes;
  l10n_util::GetAcceptLanguagesForLocale(app_locale, &language_codes);

  // Map of display name -> {language code, native_display_name}.
  // In theory, we should be able to create a map that is sorted by
  // display names using ICU comparator, but doing it is hard, thus we'll
  // use an auxiliary vector to achieve the same result.
  typedef std::pair<std::string, string16> LanguagePair;
  typedef std::map<string16, LanguagePair> LanguageMap;
  LanguageMap language_map;
  // The auxiliary vector mentioned above.
  std::vector<string16> display_names;

  // Build the list of display names, and build the language map.
  for (size_t i = 0; i < language_codes.size(); ++i) {
    string16 display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], app_locale,
                                           false);
    string16 native_display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], language_codes[i],
                                           false);
    display_names.push_back(display_name);
    language_map[display_name] =
        std::make_pair(language_codes[i], native_display_name);
  }
  DCHECK_EQ(display_names.size(), language_map.size());

  // Sort display names using locale specific sorter.
  l10n_util::SortStrings16(app_locale, &display_names);

  // Build the language list from the language map.
  ListValue* language_list = new ListValue();
  for (size_t i = 0; i < display_names.size(); ++i) {
    string16& display_name = display_names[i];
    string16 adjusted_display_name(display_name);
    base::i18n::AdjustStringForLocaleDirection(&adjusted_display_name);

    const LanguagePair& pair = language_map[display_name];
    string16 adjusted_native_display_name(pair.second);
    base::i18n::AdjustStringForLocaleDirection(&adjusted_native_display_name);

    bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(display_name);
    std::string directionality = has_rtl_chars ? "rtl" : "ltr";

    DictionaryValue* dictionary = new DictionaryValue();
    dictionary->SetString("code",  pair.first);
    dictionary->SetString("displayName", adjusted_display_name);
    dictionary->SetString("textDirection", directionality);
    dictionary->SetString("nativeDisplayName", adjusted_native_display_name);
    language_list->Append(dictionary);
  }

  return language_list;
}

string16 LanguageOptionsHandler::GetProductName() {
  return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
}

void LanguageOptionsHandler::SetApplicationLocale(
    const std::string& language_code) {
  PrefService* pref_service = g_browser_process->local_state();
  pref_service->SetString(prefs::kApplicationLocale, language_code);
}

void LanguageOptionsHandler::RestartCallback(const ListValue* args) {
  content::RecordAction(UserMetricsAction("LanguageOptions_Restart"));
  chrome::AttemptRestart();
}

}  // namespace options