font_settings_handler.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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, chrome::NOTIFICATION_EXTENSION_LOADED, 116 content::NotificationService::AllSources()); 117 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 118 content::NotificationService::AllSources()); 119} 120 121void FontSettingsHandler::InitializePage() { 122 DCHECK(web_ui()); 123 SetUpStandardFontSample(); 124 SetUpSerifFontSample(); 125 SetUpSansSerifFontSample(); 126 SetUpFixedFontSample(); 127 SetUpMinimumFontSample(); 128 NotifyAdvancedFontSettingsAvailability(); 129} 130 131void FontSettingsHandler::RegisterMessages() { 132 // Perform validation for saved fonts. 133 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 134 FontSettingsUtilities::ValidateSavedFonts(pref_service); 135 136 // Register for preferences that we need to observe manually. 137 font_encoding_.Init(prefs::kDefaultCharset, pref_service); 138 139 standard_font_.Init(prefs::kWebKitStandardFontFamily, 140 pref_service, 141 base::Bind(&FontSettingsHandler::SetUpStandardFontSample, 142 base::Unretained(this))); 143 serif_font_.Init(prefs::kWebKitSerifFontFamily, 144 pref_service, 145 base::Bind(&FontSettingsHandler::SetUpSerifFontSample, 146 base::Unretained(this))); 147 sans_serif_font_.Init( 148 prefs::kWebKitSansSerifFontFamily, 149 pref_service, 150 base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample, 151 base::Unretained(this))); 152 153 base::Closure callback = base::Bind( 154 &FontSettingsHandler::SetUpFixedFontSample, base::Unretained(this)); 155 156 fixed_font_.Init(prefs::kWebKitFixedFontFamily, pref_service, callback); 157 default_fixed_font_size_.Init(prefs::kWebKitDefaultFixedFontSize, 158 pref_service, callback); 159 default_font_size_.Init( 160 prefs::kWebKitDefaultFontSize, 161 pref_service, 162 base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged, 163 base::Unretained(this))); 164 minimum_font_size_.Init( 165 prefs::kWebKitMinimumFontSize, 166 pref_service, 167 base::Bind(&FontSettingsHandler::SetUpMinimumFontSample, 168 base::Unretained(this))); 169 170 web_ui()->RegisterMessageCallback("fetchFontsData", 171 base::Bind(&FontSettingsHandler::HandleFetchFontsData, 172 base::Unretained(this))); 173 web_ui()->RegisterMessageCallback("openAdvancedFontSettingsOptions", 174 base::Bind(&FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions, 175 base::Unretained(this))); 176} 177 178void FontSettingsHandler::Observe(int type, 179 const content::NotificationSource& source, 180 const content::NotificationDetails& details) { 181 DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED || 182 type == chrome::NOTIFICATION_EXTENSION_UNLOADED); 183 NotifyAdvancedFontSettingsAvailability(); 184} 185 186void FontSettingsHandler::HandleFetchFontsData(const base::ListValue* args) { 187 content::GetFontListAsync( 188 base::Bind(&FontSettingsHandler::FontsListHasLoaded, 189 base::Unretained(this))); 190} 191 192void FontSettingsHandler::FontsListHasLoaded( 193 scoped_ptr<base::ListValue> list) { 194 // Selects the directionality for the fonts in the given list. 195 for (size_t i = 0; i < list->GetSize(); i++) { 196 base::ListValue* font; 197 bool has_font = list->GetList(i, &font); 198 DCHECK(has_font); 199 base::string16 value; 200 bool has_value = font->GetString(1, &value); 201 DCHECK(has_value); 202 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(value); 203 font->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 204 } 205 206 base::ListValue encoding_list; 207 const std::vector<CharacterEncoding::EncodingInfo>* encodings; 208 PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); 209 encodings = CharacterEncoding::GetCurrentDisplayEncodings( 210 g_browser_process->GetApplicationLocale(), 211 pref_service->GetString(prefs::kStaticEncodings), 212 pref_service->GetString(prefs::kRecentlySelectedEncoding)); 213 DCHECK(encodings); 214 DCHECK(!encodings->empty()); 215 216 std::vector<CharacterEncoding::EncodingInfo>::const_iterator it; 217 for (it = encodings->begin(); it != encodings->end(); ++it) { 218 base::ListValue* option = new base::ListValue(); 219 if (it->encoding_id) { 220 int cmd_id = it->encoding_id; 221 std::string encoding = 222 CharacterEncoding::GetCanonicalEncodingNameByCommandId(cmd_id); 223 base::string16 name = it->encoding_display_name; 224 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(name); 225 option->Append(new base::StringValue(encoding)); 226 option->Append(new base::StringValue(name)); 227 option->Append(new base::StringValue(has_rtl_chars ? "rtl" : "ltr")); 228 } else { 229 // Add empty name/value to indicate a separator item. 230 option->Append(new base::StringValue(std::string())); 231 option->Append(new base::StringValue(std::string())); 232 } 233 encoding_list.Append(option); 234 } 235 236 base::ListValue selected_values; 237 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 238 standard_font_.GetValue()))); 239 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 240 serif_font_.GetValue()))); 241 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 242 sans_serif_font_.GetValue()))); 243 selected_values.Append(new base::StringValue(MaybeGetLocalizedFontName( 244 fixed_font_.GetValue()))); 245 selected_values.Append(new base::StringValue(font_encoding_.GetValue())); 246 247 web_ui()->CallJavascriptFunction("FontSettings.setFontsData", 248 *list.get(), encoding_list, 249 selected_values); 250} 251 252void FontSettingsHandler::SetUpStandardFontSample() { 253 base::StringValue font_value(standard_font_.GetValue()); 254 base::FundamentalValue size_value(default_font_size_.GetValue()); 255 web_ui()->CallJavascriptFunction( 256 "FontSettings.setUpStandardFontSample", font_value, size_value); 257} 258 259void FontSettingsHandler::SetUpSerifFontSample() { 260 base::StringValue font_value(serif_font_.GetValue()); 261 base::FundamentalValue size_value(default_font_size_.GetValue()); 262 web_ui()->CallJavascriptFunction( 263 "FontSettings.setUpSerifFontSample", font_value, size_value); 264} 265 266void FontSettingsHandler::SetUpSansSerifFontSample() { 267 base::StringValue font_value(sans_serif_font_.GetValue()); 268 base::FundamentalValue size_value(default_font_size_.GetValue()); 269 web_ui()->CallJavascriptFunction( 270 "FontSettings.setUpSansSerifFontSample", font_value, size_value); 271} 272 273void FontSettingsHandler::SetUpFixedFontSample() { 274 base::StringValue font_value(fixed_font_.GetValue()); 275 base::FundamentalValue size_value(default_fixed_font_size_.GetValue()); 276 web_ui()->CallJavascriptFunction( 277 "FontSettings.setUpFixedFontSample", font_value, size_value); 278} 279 280void FontSettingsHandler::SetUpMinimumFontSample() { 281 base::FundamentalValue size_value(minimum_font_size_.GetValue()); 282 web_ui()->CallJavascriptFunction("FontSettings.setUpMinimumFontSample", 283 size_value); 284} 285 286const extensions::Extension* 287FontSettingsHandler::GetAdvancedFontSettingsExtension() { 288 Profile* profile = Profile::FromWebUI(web_ui()); 289 ExtensionService* service = 290 extensions::ExtensionSystem::Get(profile)->extension_service(); 291 if (!service->IsExtensionEnabled(kAdvancedFontSettingsExtensionId)) 292 return NULL; 293 return service->GetInstalledExtension(kAdvancedFontSettingsExtensionId); 294} 295 296void FontSettingsHandler::NotifyAdvancedFontSettingsAvailability() { 297 web_ui()->CallJavascriptFunction( 298 "FontSettings.notifyAdvancedFontSettingsAvailability", 299 base::FundamentalValue(GetAdvancedFontSettingsExtension() != NULL)); 300} 301 302void FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions( 303 const base::ListValue* args) { 304 const extensions::Extension* extension = GetAdvancedFontSettingsExtension(); 305 if (!extension) 306 return; 307 extensions::ExtensionTabUtil::OpenOptionsPage(extension, 308 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); 309} 310 311void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() { 312 SetUpStandardFontSample(); 313 SetUpSerifFontSample(); 314 SetUpSansSerifFontSample(); 315} 316 317} // namespace options 318