font_settings_handler.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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/strings/string_number_conversions.h" 15#include "base/strings/string_util.h" 16#include "base/strings/utf_string_conversions.h" 17#include "base/values.h" 18#include "chrome/browser/browser_process.h" 19#include "chrome/browser/character_encoding.h" 20#include "chrome/browser/extensions/extension_service.h" 21#include "chrome/browser/extensions/extension_tab_util.h" 22#include "chrome/browser/profiles/profile.h" 23#include "chrome/browser/ui/browser_finder.h" 24#include "chrome/browser/ui/webui/options/font_settings_utils.h" 25#include "chrome/common/pref_names.h" 26#include "chrome/grit/generated_resources.h" 27#include "content/public/browser/font_list_async.h" 28#include "content/public/browser/notification_details.h" 29#include "content/public/browser/notification_service.h" 30#include "content/public/browser/web_ui.h" 31#include "extensions/browser/extension_registry.h" 32#include "extensions/browser/extension_system.h" 33#include "extensions/common/extension.h" 34#include "extensions/common/extension_urls.h" 35#include "ui/base/l10n/l10n_util.h" 36#include "url/gurl.h" 37 38#if defined(OS_WIN) 39#include "ui/gfx/font.h" 40#include "ui/gfx/platform_font_win.h" 41#endif 42 43namespace { 44 45// Returns the localized name of a font so that settings can find it within the 46// list of system fonts. On Windows, the list of system fonts has names only 47// for the system locale, but the pref value may be in the English name. 48std::string MaybeGetLocalizedFontName(const std::string& font_name) { 49#if defined(OS_WIN) 50 gfx::Font font(font_name, 12); // dummy font size 51 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> 52 GetLocalizedFontName(); 53#else 54 return font_name; 55#endif 56} 57 58const char kAdvancedFontSettingsExtensionId[] = 59 "caclkomlalccbpcdllchkeecicepbmbm"; 60 61} // namespace 62 63 64namespace options { 65 66FontSettingsHandler::FontSettingsHandler() 67 : extension_registry_observer_(this) { 68} 69 70FontSettingsHandler::~FontSettingsHandler() { 71} 72 73void FontSettingsHandler::GetLocalizedValues( 74 base::DictionaryValue* localized_strings) { 75 DCHECK(localized_strings); 76 77 static OptionsStringResource resources[] = { 78 { "fontSettingsStandard", 79 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_STANDARD_LABEL }, 80 { "fontSettingsSerif", 81 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SERIF_LABEL }, 82 { "fontSettingsSansSerif", 83 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SANS_SERIF_LABEL }, 84 { "fontSettingsFixedWidth", 85 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_FIXED_WIDTH_LABEL }, 86 { "fontSettingsMinimumSize", 87 IDS_FONT_LANGUAGE_SETTING_MINIMUM_FONT_SIZE_TITLE }, 88 { "fontSettingsEncoding", 89 IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_ENCODING_TITLE }, 90 { "fontSettingsSizeTiny", 91 IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_TINY }, 92 { "fontSettingsSizeHuge", 93 IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_HUGE }, 94 { "fontSettingsLoremIpsum", 95 IDS_FONT_LANGUAGE_SETTING_LOREM_IPSUM }, 96 { "advancedFontSettingsOptions", 97 IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_OPTIONS } 98 }; 99 100 RegisterStrings(localized_strings, resources, arraysize(resources)); 101 RegisterTitle(localized_strings, "fontSettingsPage", 102 IDS_FONT_LANGUAGE_SETTING_FONT_TAB_TITLE); 103 localized_strings->SetString("fontSettingsPlaceholder", 104 l10n_util::GetStringUTF16( 105 IDS_FONT_LANGUAGE_SETTING_PLACEHOLDER)); 106 107 GURL install_url(extension_urls::GetWebstoreItemDetailURLPrefix()); 108 localized_strings->SetString("advancedFontSettingsInstall", 109 l10n_util::GetStringFUTF16( 110 IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_INSTALL, 111 base::UTF8ToUTF16( 112 install_url.Resolve(kAdvancedFontSettingsExtensionId).spec()))); 113} 114 115void FontSettingsHandler::InitializeHandler() { 116 Profile* profile = Profile::FromWebUI(web_ui()); 117 extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile)); 118} 119 120void FontSettingsHandler::InitializePage() { 121 DCHECK(web_ui()); 122 SetUpStandardFontSample(); 123 SetUpSerifFontSample(); 124 SetUpSansSerifFontSample(); 125 SetUpFixedFontSample(); 126 SetUpMinimumFontSample(); 127 NotifyAdvancedFontSettingsAvailability(); 128} 129 130void FontSettingsHandler::RegisterMessages() { 131 // Perform validation for saved fonts. 132 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 133 FontSettingsUtilities::ValidateSavedFonts(pref_service); 134 135 // Register for preferences that we need to observe manually. 136 font_encoding_.Init(prefs::kDefaultCharset, pref_service); 137 138 standard_font_.Init(prefs::kWebKitStandardFontFamily, 139 pref_service, 140 base::Bind(&FontSettingsHandler::SetUpStandardFontSample, 141 base::Unretained(this))); 142 serif_font_.Init(prefs::kWebKitSerifFontFamily, 143 pref_service, 144 base::Bind(&FontSettingsHandler::SetUpSerifFontSample, 145 base::Unretained(this))); 146 sans_serif_font_.Init( 147 prefs::kWebKitSansSerifFontFamily, 148 pref_service, 149 base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample, 150 base::Unretained(this))); 151 152 base::Closure callback = base::Bind( 153 &FontSettingsHandler::SetUpFixedFontSample, base::Unretained(this)); 154 155 fixed_font_.Init(prefs::kWebKitFixedFontFamily, pref_service, callback); 156 default_fixed_font_size_.Init(prefs::kWebKitDefaultFixedFontSize, 157 pref_service, callback); 158 default_font_size_.Init( 159 prefs::kWebKitDefaultFontSize, 160 pref_service, 161 base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged, 162 base::Unretained(this))); 163 minimum_font_size_.Init( 164 prefs::kWebKitMinimumFontSize, 165 pref_service, 166 base::Bind(&FontSettingsHandler::SetUpMinimumFontSample, 167 base::Unretained(this))); 168 169 web_ui()->RegisterMessageCallback("fetchFontsData", 170 base::Bind(&FontSettingsHandler::HandleFetchFontsData, 171 base::Unretained(this))); 172 web_ui()->RegisterMessageCallback("openAdvancedFontSettingsOptions", 173 base::Bind(&FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions, 174 base::Unretained(this))); 175} 176 177void FontSettingsHandler::OnExtensionLoaded( 178 content::BrowserContext* browser_context, 179 const extensions::Extension* extension) { 180 NotifyAdvancedFontSettingsAvailability(); 181} 182 183void FontSettingsHandler::OnExtensionUnloaded( 184 content::BrowserContext* browser_context, 185 const extensions::Extension* extension, 186 extensions::UnloadedExtensionInfo::Reason reason) { 187 NotifyAdvancedFontSettingsAvailability(); 188} 189 190void FontSettingsHandler::HandleFetchFontsData(const base::ListValue* args) { 191 content::GetFontListAsync( 192 base::Bind(&FontSettingsHandler::FontsListHasLoaded, 193 base::Unretained(this))); 194} 195 196void FontSettingsHandler::FontsListHasLoaded( 197 scoped_ptr<base::ListValue> list) { 198 // Selects the directionality for the fonts in the given list. 199 for (size_t i = 0; i < list->GetSize(); i++) { 200 base::ListValue* font; 201 bool has_font = list->GetList(i, &font); 202 DCHECK(has_font); 203 base::string16 value; 204 bool has_value = font->GetString(1, &value); 205 DCHECK(has_value); 206 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(value); 207 font->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 208 } 209 210 base::ListValue encoding_list; 211 const std::vector<CharacterEncoding::EncodingInfo>* encodings; 212 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 213 encodings = CharacterEncoding::GetCurrentDisplayEncodings( 214 g_browser_process->GetApplicationLocale(), 215 pref_service->GetString(prefs::kStaticEncodings), 216 pref_service->GetString(prefs::kRecentlySelectedEncoding)); 217 DCHECK(encodings); 218 DCHECK(!encodings->empty()); 219 220 std::vector<CharacterEncoding::EncodingInfo>::const_iterator it; 221 for (it = encodings->begin(); it != encodings->end(); ++it) { 222 base::ListValue* option = new base::ListValue(); 223 if (it->encoding_id) { 224 int cmd_id = it->encoding_id; 225 std::string encoding = 226 CharacterEncoding::GetCanonicalEncodingNameByCommandId(cmd_id); 227 base::string16 name = it->encoding_display_name; 228 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(name); 229 option->Append(new base::StringValue(encoding)); 230 option->Append(new base::StringValue(name)); 231 option->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 232 } else { 233 // Add empty name/value to indicate a separator item. 234 option->Append(new base::StringValue(std::string())); 235 option->Append(new base::StringValue(std::string())); 236 } 237 encoding_list.Append(option); 238 } 239 240 base::ListValue selected_values; 241 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 242 standard_font_.GetValue()))); 243 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 244 serif_font_.GetValue()))); 245 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 246 sans_serif_font_.GetValue()))); 247 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 248 fixed_font_.GetValue()))); 249 selected_values.Append(new base::StringValue(font_encoding_.GetValue())); 250 251 web_ui()->CallJavascriptFunction("FontSettings.setFontsData", 252 *list.get(), encoding_list, 253 selected_values); 254} 255 256void FontSettingsHandler::SetUpStandardFontSample() { 257 base::StringValue font_value(standard_font_.GetValue()); 258 base::FundamentalValue size_value(default_font_size_.GetValue()); 259 web_ui()->CallJavascriptFunction( 260 "FontSettings.setUpStandardFontSample", font_value, size_value); 261} 262 263void FontSettingsHandler::SetUpSerifFontSample() { 264 base::StringValue font_value(serif_font_.GetValue()); 265 base::FundamentalValue size_value(default_font_size_.GetValue()); 266 web_ui()->CallJavascriptFunction( 267 "FontSettings.setUpSerifFontSample", font_value, size_value); 268} 269 270void FontSettingsHandler::SetUpSansSerifFontSample() { 271 base::StringValue font_value(sans_serif_font_.GetValue()); 272 base::FundamentalValue size_value(default_font_size_.GetValue()); 273 web_ui()->CallJavascriptFunction( 274 "FontSettings.setUpSansSerifFontSample", font_value, size_value); 275} 276 277void FontSettingsHandler::SetUpFixedFontSample() { 278 base::StringValue font_value(fixed_font_.GetValue()); 279 base::FundamentalValue size_value(default_fixed_font_size_.GetValue()); 280 web_ui()->CallJavascriptFunction( 281 "FontSettings.setUpFixedFontSample", font_value, size_value); 282} 283 284void FontSettingsHandler::SetUpMinimumFontSample() { 285 base::FundamentalValue size_value(minimum_font_size_.GetValue()); 286 web_ui()->CallJavascriptFunction("FontSettings.setUpMinimumFontSample", 287 size_value); 288} 289 290const extensions::Extension* 291FontSettingsHandler::GetAdvancedFontSettingsExtension() { 292 Profile* profile = Profile::FromWebUI(web_ui()); 293 ExtensionService* service = 294 extensions::ExtensionSystem::Get(profile)->extension_service(); 295 if (!service->IsExtensionEnabled(kAdvancedFontSettingsExtensionId)) 296 return NULL; 297 return service->GetInstalledExtension(kAdvancedFontSettingsExtensionId); 298} 299 300void FontSettingsHandler::NotifyAdvancedFontSettingsAvailability() { 301 web_ui()->CallJavascriptFunction( 302 "FontSettings.notifyAdvancedFontSettingsAvailability", 303 base::FundamentalValue(GetAdvancedFontSettingsExtension() != NULL)); 304} 305 306void FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions( 307 const base::ListValue* args) { 308 const extensions::Extension* extension = GetAdvancedFontSettingsExtension(); 309 if (!extension) 310 return; 311 extensions::ExtensionTabUtil::OpenOptionsPage(extension, 312 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); 313} 314 315void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() { 316 SetUpStandardFontSample(); 317 SetUpSerifFontSample(); 318 SetUpSansSerifFontSample(); 319} 320 321} // namespace options 322