font_settings_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/ui/webui/options/font_settings_handler.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/i18n/rtl.h"
13#include "base/prefs/pref_service.h"
14#include "base/string_util.h"
15#include "base/strings/string_number_conversions.h"
16#include "base/values.h"
17#include "chrome/browser/browser_process.h"
18#include "chrome/browser/character_encoding.h"
19#include "chrome/browser/profiles/profile.h"
20#include "chrome/browser/ui/webui/options/font_settings_utils.h"
21#include "chrome/common/chrome_notification_types.h"
22#include "chrome/common/pref_names.h"
23#include "content/public/browser/font_list_async.h"
24#include "content/public/browser/notification_details.h"
25#include "content/public/browser/web_ui.h"
26#include "grit/chromium_strings.h"
27#include "grit/generated_resources.h"
28#include "ui/base/l10n/l10n_util.h"
29
30#if defined(OS_WIN)
31#include "ui/gfx/font.h"
32#include "ui/gfx/platform_font_win.h"
33#endif
34
35namespace {
36
37// Returns the localized name of a font so that settings can find it within the
38// list of system fonts. On Windows, the list of system fonts has names only
39// for the system locale, but the pref value may be in the English name.
40std::string MaybeGetLocalizedFontName(const std::string& font_name) {
41#if defined(OS_WIN)
42  gfx::Font font(font_name, 12);  // dummy font size
43  return static_cast<gfx::PlatformFontWin*>(font.platform_font())->
44      GetLocalizedFontName();
45#else
46  return font_name;
47#endif
48}
49
50}  // namespace
51
52
53namespace options {
54
55FontSettingsHandler::FontSettingsHandler() {
56}
57
58FontSettingsHandler::~FontSettingsHandler() {
59}
60
61void FontSettingsHandler::GetLocalizedValues(
62    DictionaryValue* localized_strings) {
63  DCHECK(localized_strings);
64
65  static OptionsStringResource resources[] = {
66    { "fontSettingsStandard",
67      IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_STANDARD_LABEL },
68    { "fontSettingsSerif",
69      IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SERIF_LABEL },
70    { "fontSettingsSansSerif",
71      IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SANS_SERIF_LABEL },
72    { "fontSettingsFixedWidth",
73      IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_FIXED_WIDTH_LABEL },
74    { "fontSettingsMinimumSize",
75      IDS_FONT_LANGUAGE_SETTING_MINIMUM_FONT_SIZE_TITLE },
76    { "fontSettingsEncoding",
77      IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_ENCODING_TITLE },
78    { "fontSettingsSizeTiny",
79      IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_TINY },
80    { "fontSettingsSizeHuge",
81      IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_HUGE },
82    { "fontSettingsLoremIpsum",
83      IDS_FONT_LANGUAGE_SETTING_LOREM_IPSUM },
84  };
85
86  RegisterStrings(localized_strings, resources, arraysize(resources));
87  RegisterTitle(localized_strings, "fontSettingsPage",
88                IDS_FONT_LANGUAGE_SETTING_FONT_TAB_TITLE);
89  localized_strings->SetString("fontSettingsPlaceholder",
90      l10n_util::GetStringUTF16(
91          IDS_FONT_LANGUAGE_SETTING_PLACEHOLDER));
92}
93
94void FontSettingsHandler::InitializePage() {
95  DCHECK(web_ui());
96  SetUpStandardFontSample();
97  SetUpSerifFontSample();
98  SetUpSansSerifFontSample();
99  SetUpFixedFontSample();
100  SetUpMinimumFontSample();
101}
102
103void FontSettingsHandler::RegisterMessages() {
104  // Perform validation for saved fonts.
105  PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
106  FontSettingsUtilities::ValidateSavedFonts(pref_service);
107
108  // Register for preferences that we need to observe manually.
109  font_encoding_.Init(prefs::kDefaultCharset, pref_service);
110
111  standard_font_.Init(prefs::kWebKitStandardFontFamily,
112                      pref_service,
113                      base::Bind(&FontSettingsHandler::SetUpStandardFontSample,
114                                 base::Unretained(this)));
115  serif_font_.Init(prefs::kWebKitSerifFontFamily,
116                   pref_service,
117                   base::Bind(&FontSettingsHandler::SetUpSerifFontSample,
118                              base::Unretained(this)));
119  sans_serif_font_.Init(
120      prefs::kWebKitSansSerifFontFamily,
121      pref_service,
122      base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample,
123                 base::Unretained(this)));
124
125  base::Closure callback = base::Bind(
126      &FontSettingsHandler::SetUpFixedFontSample, base::Unretained(this));
127
128  fixed_font_.Init(prefs::kWebKitFixedFontFamily, pref_service, callback);
129  default_fixed_font_size_.Init(prefs::kWebKitDefaultFixedFontSize,
130                                pref_service, callback);
131  default_font_size_.Init(
132      prefs::kWebKitDefaultFontSize,
133      pref_service,
134      base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged,
135                 base::Unretained(this)));
136  minimum_font_size_.Init(
137      prefs::kWebKitMinimumFontSize,
138      pref_service,
139      base::Bind(&FontSettingsHandler::SetUpMinimumFontSample,
140                 base::Unretained(this)));
141
142  web_ui()->RegisterMessageCallback("fetchFontsData",
143      base::Bind(&FontSettingsHandler::HandleFetchFontsData,
144                 base::Unretained(this)));
145}
146
147void FontSettingsHandler::HandleFetchFontsData(const ListValue* args) {
148  content::GetFontListAsync(
149      base::Bind(&FontSettingsHandler::FontsListHasLoaded,
150                 base::Unretained(this)));
151}
152
153void FontSettingsHandler::FontsListHasLoaded(
154    scoped_ptr<base::ListValue> list) {
155  // Selects the directionality for the fonts in the given list.
156  for (size_t i = 0; i < list->GetSize(); i++) {
157    ListValue* font;
158    bool has_font = list->GetList(i, &font);
159    DCHECK(has_font);
160    string16 value;
161    bool has_value = font->GetString(1, &value);
162    DCHECK(has_value);
163    bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(value);
164    font->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr"));
165  }
166
167  ListValue encoding_list;
168  const std::vector<CharacterEncoding::EncodingInfo>* encodings;
169  PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
170  encodings = CharacterEncoding::GetCurrentDisplayEncodings(
171      g_browser_process->GetApplicationLocale(),
172      pref_service->GetString(prefs::kStaticEncodings),
173      pref_service->GetString(prefs::kRecentlySelectedEncoding));
174  DCHECK(encodings);
175  DCHECK(!encodings->empty());
176
177  std::vector<CharacterEncoding::EncodingInfo>::const_iterator it;
178  for (it = encodings->begin(); it != encodings->end(); ++it) {
179    ListValue* option = new ListValue();
180    if (it->encoding_id) {
181      int cmd_id = it->encoding_id;
182      std::string encoding =
183      CharacterEncoding::GetCanonicalEncodingNameByCommandId(cmd_id);
184      string16 name = it->encoding_display_name;
185      bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(name);
186      option->Append(new base::StringValue(encoding));
187      option->Append(new base::StringValue(name));
188      option->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr"));
189    } else {
190      // Add empty name/value to indicate a separator item.
191      option->Append(new base::StringValue(""));
192      option->Append(new base::StringValue(""));
193    }
194    encoding_list.Append(option);
195  }
196
197  ListValue selected_values;
198  selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName(
199      standard_font_.GetValue())));
200  selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName(
201      serif_font_.GetValue())));
202  selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName(
203      sans_serif_font_.GetValue())));
204  selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName(
205      fixed_font_.GetValue())));
206  selected_values.Append(new base::StringValue(font_encoding_.GetValue()));
207
208  web_ui()->CallJavascriptFunction("FontSettings.setFontsData",
209                                   *list.get(), encoding_list,
210                                   selected_values);
211}
212
213void FontSettingsHandler::SetUpStandardFontSample() {
214  base::StringValue font_value(standard_font_.GetValue());
215  base::FundamentalValue size_value(default_font_size_.GetValue());
216  web_ui()->CallJavascriptFunction(
217      "FontSettings.setUpStandardFontSample", font_value, size_value);
218}
219
220void FontSettingsHandler::SetUpSerifFontSample() {
221  base::StringValue font_value(serif_font_.GetValue());
222  base::FundamentalValue size_value(default_font_size_.GetValue());
223  web_ui()->CallJavascriptFunction(
224      "FontSettings.setUpSerifFontSample", font_value, size_value);
225}
226
227void FontSettingsHandler::SetUpSansSerifFontSample() {
228  base::StringValue font_value(sans_serif_font_.GetValue());
229  base::FundamentalValue size_value(default_font_size_.GetValue());
230  web_ui()->CallJavascriptFunction(
231      "FontSettings.setUpSansSerifFontSample", font_value, size_value);
232}
233
234void FontSettingsHandler::SetUpFixedFontSample() {
235  base::StringValue font_value(fixed_font_.GetValue());
236  base::FundamentalValue size_value(default_fixed_font_size_.GetValue());
237  web_ui()->CallJavascriptFunction(
238      "FontSettings.setUpFixedFontSample", font_value, size_value);
239}
240
241void FontSettingsHandler::SetUpMinimumFontSample() {
242  base::FundamentalValue size_value(minimum_font_size_.GetValue());
243  web_ui()->CallJavascriptFunction("FontSettings.setUpMinimumFontSample",
244                                   size_value);
245}
246
247void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() {
248  SetUpStandardFontSample();
249  SetUpSerifFontSample();
250  SetUpSansSerifFontSample();
251}
252
253}  // namespace options
254