font_settings_handler.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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/extensions/extension_constants.h" 27#include "chrome/common/pref_names.h" 28#include "content/public/browser/font_list_async.h" 29#include "content/public/browser/notification_details.h" 30#include "content/public/browser/notification_service.h" 31#include "content/public/browser/web_ui.h" 32#include "extensions/browser/extension_system.h" 33#include "extensions/common/extension.h" 34#include "grit/chromium_strings.h" 35#include "grit/generated_resources.h" 36#include "ui/base/l10n/l10n_util.h" 37#include "url/gurl.h" 38 39#if defined(OS_WIN) 40#include "ui/gfx/font.h" 41#include "ui/gfx/platform_font_win.h" 42#endif 43 44namespace { 45 46// Returns the localized name of a font so that settings can find it within the 47// list of system fonts. On Windows, the list of system fonts has names only 48// for the system locale, but the pref value may be in the English name. 49std::string MaybeGetLocalizedFontName(const std::string& font_name) { 50#if defined(OS_WIN) 51 gfx::Font font(font_name, 12); // dummy font size 52 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> 53 GetLocalizedFontName(); 54#else 55 return font_name; 56#endif 57} 58 59const char kAdvancedFontSettingsExtensionId[] = 60 "caclkomlalccbpcdllchkeecicepbmbm"; 61 62} // namespace 63 64 65namespace options { 66 67FontSettingsHandler::FontSettingsHandler() { 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 registrar_.Add(this, 117 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 118 content::NotificationService::AllSources()); 119 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 120 content::NotificationService::AllSources()); 121} 122 123void FontSettingsHandler::InitializePage() { 124 DCHECK(web_ui()); 125 SetUpStandardFontSample(); 126 SetUpSerifFontSample(); 127 SetUpSansSerifFontSample(); 128 SetUpFixedFontSample(); 129 SetUpMinimumFontSample(); 130 NotifyAdvancedFontSettingsAvailability(); 131} 132 133void FontSettingsHandler::RegisterMessages() { 134 // Perform validation for saved fonts. 135 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 136 FontSettingsUtilities::ValidateSavedFonts(pref_service); 137 138 // Register for preferences that we need to observe manually. 139 font_encoding_.Init(prefs::kDefaultCharset, pref_service); 140 141 standard_font_.Init(prefs::kWebKitStandardFontFamily, 142 pref_service, 143 base::Bind(&FontSettingsHandler::SetUpStandardFontSample, 144 base::Unretained(this))); 145 serif_font_.Init(prefs::kWebKitSerifFontFamily, 146 pref_service, 147 base::Bind(&FontSettingsHandler::SetUpSerifFontSample, 148 base::Unretained(this))); 149 sans_serif_font_.Init( 150 prefs::kWebKitSansSerifFontFamily, 151 pref_service, 152 base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample, 153 base::Unretained(this))); 154 155 base::Closure callback = base::Bind( 156 &FontSettingsHandler::SetUpFixedFontSample, base::Unretained(this)); 157 158 fixed_font_.Init(prefs::kWebKitFixedFontFamily, pref_service, callback); 159 default_fixed_font_size_.Init(prefs::kWebKitDefaultFixedFontSize, 160 pref_service, callback); 161 default_font_size_.Init( 162 prefs::kWebKitDefaultFontSize, 163 pref_service, 164 base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged, 165 base::Unretained(this))); 166 minimum_font_size_.Init( 167 prefs::kWebKitMinimumFontSize, 168 pref_service, 169 base::Bind(&FontSettingsHandler::SetUpMinimumFontSample, 170 base::Unretained(this))); 171 172 web_ui()->RegisterMessageCallback("fetchFontsData", 173 base::Bind(&FontSettingsHandler::HandleFetchFontsData, 174 base::Unretained(this))); 175 web_ui()->RegisterMessageCallback("openAdvancedFontSettingsOptions", 176 base::Bind(&FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions, 177 base::Unretained(this))); 178} 179 180void FontSettingsHandler::Observe(int type, 181 const content::NotificationSource& source, 182 const content::NotificationDetails& details) { 183 DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED || 184 type == chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED); 185 NotifyAdvancedFontSettingsAvailability(); 186} 187 188void FontSettingsHandler::HandleFetchFontsData(const base::ListValue* args) { 189 content::GetFontListAsync( 190 base::Bind(&FontSettingsHandler::FontsListHasLoaded, 191 base::Unretained(this))); 192} 193 194void FontSettingsHandler::FontsListHasLoaded( 195 scoped_ptr<base::ListValue> list) { 196 // Selects the directionality for the fonts in the given list. 197 for (size_t i = 0; i < list->GetSize(); i++) { 198 base::ListValue* font; 199 bool has_font = list->GetList(i, &font); 200 DCHECK(has_font); 201 base::string16 value; 202 bool has_value = font->GetString(1, &value); 203 DCHECK(has_value); 204 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(value); 205 font->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 206 } 207 208 base::ListValue encoding_list; 209 const std::vector<CharacterEncoding::EncodingInfo>* encodings; 210 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 211 encodings = CharacterEncoding::GetCurrentDisplayEncodings( 212 g_browser_process->GetApplicationLocale(), 213 pref_service->GetString(prefs::kStaticEncodings), 214 pref_service->GetString(prefs::kRecentlySelectedEncoding)); 215 DCHECK(encodings); 216 DCHECK(!encodings->empty()); 217 218 std::vector<CharacterEncoding::EncodingInfo>::const_iterator it; 219 for (it = encodings->begin(); it != encodings->end(); ++it) { 220 base::ListValue* option = new base::ListValue(); 221 if (it->encoding_id) { 222 int cmd_id = it->encoding_id; 223 std::string encoding = 224 CharacterEncoding::GetCanonicalEncodingNameByCommandId(cmd_id); 225 base::string16 name = it->encoding_display_name; 226 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(name); 227 option->Append(new base::StringValue(encoding)); 228 option->Append(new base::StringValue(name)); 229 option->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 230 } else { 231 // Add empty name/value to indicate a separator item. 232 option->Append(new base::StringValue(std::string())); 233 option->Append(new base::StringValue(std::string())); 234 } 235 encoding_list.Append(option); 236 } 237 238 base::ListValue selected_values; 239 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 240 standard_font_.GetValue()))); 241 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 242 serif_font_.GetValue()))); 243 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 244 sans_serif_font_.GetValue()))); 245 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 246 fixed_font_.GetValue()))); 247 selected_values.Append(new base::StringValue(font_encoding_.GetValue())); 248 249 web_ui()->CallJavascriptFunction("FontSettings.setFontsData", 250 *list.get(), encoding_list, 251 selected_values); 252} 253 254void FontSettingsHandler::SetUpStandardFontSample() { 255 base::StringValue font_value(standard_font_.GetValue()); 256 base::FundamentalValue size_value(default_font_size_.GetValue()); 257 web_ui()->CallJavascriptFunction( 258 "FontSettings.setUpStandardFontSample", font_value, size_value); 259} 260 261void FontSettingsHandler::SetUpSerifFontSample() { 262 base::StringValue font_value(serif_font_.GetValue()); 263 base::FundamentalValue size_value(default_font_size_.GetValue()); 264 web_ui()->CallJavascriptFunction( 265 "FontSettings.setUpSerifFontSample", font_value, size_value); 266} 267 268void FontSettingsHandler::SetUpSansSerifFontSample() { 269 base::StringValue font_value(sans_serif_font_.GetValue()); 270 base::FundamentalValue size_value(default_font_size_.GetValue()); 271 web_ui()->CallJavascriptFunction( 272 "FontSettings.setUpSansSerifFontSample", font_value, size_value); 273} 274 275void FontSettingsHandler::SetUpFixedFontSample() { 276 base::StringValue font_value(fixed_font_.GetValue()); 277 base::FundamentalValue size_value(default_fixed_font_size_.GetValue()); 278 web_ui()->CallJavascriptFunction( 279 "FontSettings.setUpFixedFontSample", font_value, size_value); 280} 281 282void FontSettingsHandler::SetUpMinimumFontSample() { 283 base::FundamentalValue size_value(minimum_font_size_.GetValue()); 284 web_ui()->CallJavascriptFunction("FontSettings.setUpMinimumFontSample", 285 size_value); 286} 287 288const extensions::Extension* 289FontSettingsHandler::GetAdvancedFontSettingsExtension() { 290 Profile* profile = Profile::FromWebUI(web_ui()); 291 ExtensionService* service = 292 extensions::ExtensionSystem::Get(profile)->extension_service(); 293 if (!service->IsExtensionEnabled(kAdvancedFontSettingsExtensionId)) 294 return NULL; 295 return service->GetInstalledExtension(kAdvancedFontSettingsExtensionId); 296} 297 298void FontSettingsHandler::NotifyAdvancedFontSettingsAvailability() { 299 web_ui()->CallJavascriptFunction( 300 "FontSettings.notifyAdvancedFontSettingsAvailability", 301 base::FundamentalValue(GetAdvancedFontSettingsExtension() != NULL)); 302} 303 304void FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions( 305 const base::ListValue* args) { 306 const extensions::Extension* extension = GetAdvancedFontSettingsExtension(); 307 if (!extension) 308 return; 309 extensions::ExtensionTabUtil::OpenOptionsPage(extension, 310 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); 311} 312 313void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() { 314 SetUpStandardFontSample(); 315 SetUpSerifFontSample(); 316 SetUpSansSerifFontSample(); 317} 318 319} // namespace options 320