1 // Copyright (c) 2011 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/translate/translate_prefs.h" 6 7 #include "base/string_util.h" 8 #include "chrome/browser/prefs/pref_service.h" 9 #include "chrome/browser/prefs/scoped_user_pref_update.h" 10 11 const char TranslatePrefs::kPrefTranslateLanguageBlacklist[] = 12 "translate_language_blacklist"; 13 const char TranslatePrefs::kPrefTranslateSiteBlacklist[] = 14 "translate_site_blacklist"; 15 const char TranslatePrefs::kPrefTranslateWhitelists[] = 16 "translate_whitelists"; 17 const char TranslatePrefs::kPrefTranslateDeniedCount[] = 18 "translate_denied_count"; 19 const char TranslatePrefs::kPrefTranslateAcceptedCount[] = 20 "translate_accepted_count"; 21 22 // TranslatePrefs: public: ----------------------------------------------------- 23 24 TranslatePrefs::TranslatePrefs(PrefService* user_prefs) 25 : prefs_(user_prefs) { 26 } 27 28 bool TranslatePrefs::IsLanguageBlacklisted( 29 const std::string& original_language) { 30 return IsValueBlacklisted(kPrefTranslateLanguageBlacklist, original_language); 31 } 32 33 void TranslatePrefs::BlacklistLanguage(const std::string& original_language) { 34 BlacklistValue(kPrefTranslateLanguageBlacklist, original_language); 35 } 36 37 void TranslatePrefs::RemoveLanguageFromBlacklist( 38 const std::string& original_language) { 39 RemoveValueFromBlacklist(kPrefTranslateLanguageBlacklist, original_language); 40 } 41 42 bool TranslatePrefs::IsSiteBlacklisted(const std::string& site) { 43 return IsValueBlacklisted(kPrefTranslateSiteBlacklist, site); 44 } 45 46 void TranslatePrefs::BlacklistSite(const std::string& site) { 47 BlacklistValue(kPrefTranslateSiteBlacklist, site); 48 } 49 50 void TranslatePrefs::RemoveSiteFromBlacklist(const std::string& site) { 51 RemoveValueFromBlacklist(kPrefTranslateSiteBlacklist, site); 52 } 53 54 bool TranslatePrefs::IsLanguagePairWhitelisted( 55 const std::string& original_language, 56 const std::string& target_language) { 57 const DictionaryValue* dict = prefs_->GetDictionary(kPrefTranslateWhitelists); 58 if (dict && !dict->empty()) { 59 std::string auto_target_lang; 60 if (dict->GetString(original_language, &auto_target_lang) && 61 auto_target_lang == target_language) 62 return true; 63 } 64 return false; 65 } 66 67 void TranslatePrefs::WhitelistLanguagePair( 68 const std::string& original_language, 69 const std::string& target_language) { 70 DictionaryPrefUpdate update(prefs_, kPrefTranslateWhitelists); 71 DictionaryValue* dict = update.Get(); 72 if (!dict) { 73 NOTREACHED() << "Unregistered translate whitelist pref"; 74 return; 75 } 76 dict->SetString(original_language, target_language); 77 prefs_->ScheduleSavePersistentPrefs(); 78 } 79 80 void TranslatePrefs::RemoveLanguagePairFromWhitelist( 81 const std::string& original_language, 82 const std::string& target_language) { 83 DictionaryPrefUpdate update(prefs_, kPrefTranslateWhitelists); 84 DictionaryValue* dict = update.Get(); 85 if (!dict) { 86 NOTREACHED() << "Unregistered translate whitelist pref"; 87 return; 88 } 89 if (dict->Remove(original_language, NULL)) 90 prefs_->ScheduleSavePersistentPrefs(); 91 } 92 93 int TranslatePrefs::GetTranslationDeniedCount(const std::string& language) { 94 const DictionaryValue* dict = 95 prefs_->GetDictionary(kPrefTranslateDeniedCount); 96 int count = 0; 97 return dict->GetInteger(language, &count) ? count : 0; 98 } 99 100 void TranslatePrefs::IncrementTranslationDeniedCount( 101 const std::string& language) { 102 DictionaryPrefUpdate update(prefs_, kPrefTranslateDeniedCount); 103 DictionaryValue* dict = update.Get(); 104 105 int count = 0; 106 dict->GetInteger(language, &count); 107 dict->SetInteger(language, count + 1); 108 } 109 110 void TranslatePrefs::ResetTranslationDeniedCount(const std::string& language) { 111 DictionaryPrefUpdate update(prefs_, kPrefTranslateDeniedCount); 112 update.Get()->SetInteger(language, 0); 113 } 114 115 int TranslatePrefs::GetTranslationAcceptedCount(const std::string& language) { 116 const DictionaryValue* dict = 117 prefs_->GetDictionary(kPrefTranslateAcceptedCount); 118 int count = 0; 119 return dict->GetInteger(language, &count) ? count : 0; 120 } 121 122 void TranslatePrefs::IncrementTranslationAcceptedCount( 123 const std::string& language) { 124 DictionaryPrefUpdate update(prefs_, kPrefTranslateAcceptedCount); 125 DictionaryValue* dict = update.Get(); 126 int count = 0; 127 dict->GetInteger(language, &count); 128 dict->SetInteger(language, count + 1); 129 } 130 131 void TranslatePrefs::ResetTranslationAcceptedCount( 132 const std::string& language) { 133 DictionaryPrefUpdate update(prefs_, kPrefTranslateAcceptedCount); 134 update.Get()->SetInteger(language, 0); 135 } 136 137 // TranslatePrefs: public, static: --------------------------------------------- 138 139 bool TranslatePrefs::CanTranslate(PrefService* user_prefs, 140 const std::string& original_language, const GURL& url) { 141 TranslatePrefs prefs(user_prefs); 142 if (prefs.IsSiteBlacklisted(url.HostNoBrackets())) 143 return false; 144 return (!prefs.IsLanguageBlacklisted(original_language)); 145 } 146 147 bool TranslatePrefs::ShouldAutoTranslate(PrefService* user_prefs, 148 const std::string& original_language, std::string* target_language) { 149 TranslatePrefs prefs(user_prefs); 150 return prefs.IsLanguageWhitelisted(original_language, target_language); 151 } 152 153 void TranslatePrefs::RegisterUserPrefs(PrefService* user_prefs) { 154 if (!user_prefs->FindPreference(kPrefTranslateLanguageBlacklist)) 155 user_prefs->RegisterListPref(kPrefTranslateLanguageBlacklist); 156 if (!user_prefs->FindPreference(kPrefTranslateSiteBlacklist)) 157 user_prefs->RegisterListPref(kPrefTranslateSiteBlacklist); 158 if (!user_prefs->FindPreference(kPrefTranslateWhitelists)) { 159 user_prefs->RegisterDictionaryPref(kPrefTranslateWhitelists); 160 MigrateTranslateWhitelists(user_prefs); 161 } 162 if (!user_prefs->FindPreference(kPrefTranslateDeniedCount)) 163 user_prefs->RegisterDictionaryPref(kPrefTranslateDeniedCount); 164 if (!user_prefs->FindPreference(kPrefTranslateAcceptedCount)) 165 user_prefs->RegisterDictionaryPref(kPrefTranslateAcceptedCount); 166 } 167 168 // TranslatePrefs: private, static: -------------------------------------------- 169 170 void TranslatePrefs::MigrateTranslateWhitelists(PrefService* user_prefs) { 171 // Old format of kPrefTranslateWhitelists 172 // - original language -> list of target langs to auto-translate 173 // - list of langs is in order of being enabled i.e. last in list is the 174 // most recent language that user enabled via 175 // Always translate |source_lang| to |target_lang|" 176 // - this results in a one-to-n relationship between source lang and target 177 // langs. 178 // New format: 179 // - original language -> one target language to auto-translate 180 // - each time that the user enables the "Always translate..." option, that 181 // target lang overwrites the previous one. 182 // - this results in a one-to-one relationship between source lang and target 183 // lang 184 // - we replace old list of target langs with the last target lang in list, 185 // assuming the last (i.e. most recent) target lang is what user wants to 186 // keep auto-translated. 187 DictionaryPrefUpdate update(user_prefs, kPrefTranslateWhitelists); 188 DictionaryValue* dict = update.Get(); 189 if (!dict || dict->empty()) 190 return; 191 bool save_prefs = false; 192 for (DictionaryValue::key_iterator iter(dict->begin_keys()); 193 iter != dict->end_keys(); ++iter) { 194 ListValue* list = NULL; 195 if (!dict->GetList(*iter, &list) || !list) 196 break; // Dictionary has either been migrated or new format. 197 save_prefs = true; 198 std::string target_lang; 199 if (list->empty() || !list->GetString(list->GetSize() - 1, &target_lang) || 200 target_lang.empty()) 201 dict->Remove(*iter, NULL); 202 else 203 dict->SetString(*iter, target_lang); 204 } 205 if (!save_prefs) 206 return; 207 user_prefs->ScheduleSavePersistentPrefs(); 208 } 209 210 // TranslatePrefs: private: ---------------------------------------------------- 211 212 bool TranslatePrefs::IsValueInList(const ListValue* list, 213 const std::string& in_value) { 214 for (size_t i = 0; i < list->GetSize(); ++i) { 215 std::string value; 216 if (list->GetString(i, &value) && value == in_value) 217 return true; 218 } 219 return false; 220 } 221 222 bool TranslatePrefs::IsValueBlacklisted(const char* pref_id, 223 const std::string& value) { 224 const ListValue* blacklist = prefs_->GetList(pref_id); 225 return (blacklist && !blacklist->empty() && IsValueInList(blacklist, value)); 226 } 227 228 void TranslatePrefs::BlacklistValue(const char* pref_id, 229 const std::string& value) { 230 { 231 ListPrefUpdate update(prefs_, pref_id); 232 ListValue* blacklist = update.Get(); 233 if (!blacklist) { 234 NOTREACHED() << "Unregistered translate blacklist pref"; 235 return; 236 } 237 blacklist->Append(new StringValue(value)); 238 } 239 prefs_->ScheduleSavePersistentPrefs(); 240 } 241 242 void TranslatePrefs::RemoveValueFromBlacklist(const char* pref_id, 243 const std::string& value) { 244 bool schedule_save = false; 245 { 246 ListPrefUpdate update(prefs_, pref_id); 247 ListValue* blacklist = update.Get(); 248 if (!blacklist) { 249 NOTREACHED() << "Unregistered translate blacklist pref"; 250 return; 251 } 252 StringValue string_value(value); 253 schedule_save = blacklist->Remove(string_value) != -1; 254 } 255 if (schedule_save) 256 prefs_->ScheduleSavePersistentPrefs(); 257 } 258 259 bool TranslatePrefs::IsLanguageWhitelisted( 260 const std::string& original_language, std::string* target_language) { 261 const DictionaryValue* dict = prefs_->GetDictionary(kPrefTranslateWhitelists); 262 if (dict && dict->GetString(original_language, target_language)) { 263 DCHECK(!target_language->empty()); 264 return !target_language->empty(); 265 } 266 return false; 267 } 268