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