Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: chrome/browser/spellchecker/spellcheck_service.cc

Issue 1156473007: Enables the user to select multiple languages for spellchecking (UI) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Replied to old comments and fixed small issues. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/spellchecker/spellcheck_service.h" 5 #include "chrome/browser/spellchecker/spellcheck_service.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/prefs/pref_member.h" 8 #include "base/prefs/pref_member.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
11 #include "base/supports_user_data.h"
11 #include "base/synchronization/waitable_event.h" 12 #include "base/synchronization/waitable_event.h"
12 #include "chrome/browser/spellchecker/feedback_sender.h" 13 #include "chrome/browser/spellchecker/feedback_sender.h"
13 #include "chrome/browser/spellchecker/spellcheck_factory.h" 14 #include "chrome/browser/spellchecker/spellcheck_factory.h"
14 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h" 15 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
15 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" 16 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h"
16 #include "chrome/browser/spellchecker/spellcheck_platform_mac.h" 17 #include "chrome/browser/spellchecker/spellcheck_platform_mac.h"
17 #include "chrome/browser/spellchecker/spelling_service_client.h" 18 #include "chrome/browser/spellchecker/spelling_service_client.h"
18 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
19 #include "chrome/common/spellcheck_common.h" 20 #include "chrome/common/spellcheck_common.h"
20 #include "chrome/common/spellcheck_messages.h" 21 #include "chrome/common/spellcheck_messages.h"
(...skipping 15 matching lines...) Expand all
36 SpellcheckService::EventType g_status_type = 37 SpellcheckService::EventType g_status_type =
37 SpellcheckService::BDICT_NOTINITIALIZED; 38 SpellcheckService::BDICT_NOTINITIALIZED;
38 39
39 SpellcheckService::SpellcheckService(content::BrowserContext* context) 40 SpellcheckService::SpellcheckService(content::BrowserContext* context)
40 : context_(context), 41 : context_(context),
41 weak_ptr_factory_(this) { 42 weak_ptr_factory_(this) {
42 DCHECK_CURRENTLY_ON(BrowserThread::UI); 43 DCHECK_CURRENTLY_ON(BrowserThread::UI);
43 PrefService* prefs = user_prefs::UserPrefs::Get(context); 44 PrefService* prefs = user_prefs::UserPrefs::Get(context);
44 pref_change_registrar_.Init(prefs); 45 pref_change_registrar_.Init(prefs);
45 46
46 StringListPrefMember dictionaries_pref;
47 dictionaries_pref.Init(prefs::kSpellCheckDictionaries, prefs);
48 std::string first_of_dictionaries; 47 std::string first_of_dictionaries;
49 if (!dictionaries_pref.GetValue().empty()) 48 if (!chrome::spellcheck_common::GetDictionaryLanguagesPref(prefs).empty()) {
50 first_of_dictionaries = dictionaries_pref.GetValue().front(); 49 first_of_dictionaries =
50 chrome::spellcheck_common::GetDictionaryLanguagesPref(prefs).front();
51 }
51 52
52 // For preference migration, set the new preference kSpellCheckDictionaries 53 // For preference migration, set the new preference kSpellCheckDictionaries
53 // to be the same as the old kSpellCheckDictionary. 54 // to be the same as the old kSpellCheckDictionary.
54 StringPrefMember single_dictionary_pref; 55 StringPrefMember single_dictionary_pref;
55 single_dictionary_pref.Init(prefs::kSpellCheckDictionary, prefs); 56 single_dictionary_pref.Init(prefs::kSpellCheckDictionary, prefs);
56 std::string single_dictionary = single_dictionary_pref.GetValue(); 57 std::string single_dictionary = single_dictionary_pref.GetValue();
57 58
58 if (first_of_dictionaries.empty() && !single_dictionary.empty()) { 59 if (first_of_dictionaries.empty() && !single_dictionary.empty()) {
59 first_of_dictionaries = single_dictionary; 60 first_of_dictionaries = single_dictionary;
61 StringListPrefMember dictionaries_pref;
62 dictionaries_pref.Init(prefs::kSpellCheckDictionaries, prefs);
60 dictionaries_pref.SetValue( 63 dictionaries_pref.SetValue(
61 std::vector<std::string>(1, first_of_dictionaries)); 64 std::vector<std::string>(1, first_of_dictionaries));
62 } 65 }
63 66
64 single_dictionary_pref.SetValue(""); 67 single_dictionary_pref.SetValue("");
65 68
66 std::string language_code; 69 std::string language_code;
67 std::string country_code; 70 std::string country_code;
68 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale( 71 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale(
69 first_of_dictionaries, 72 first_of_dictionaries,
70 &language_code, 73 &language_code,
71 &country_code); 74 &country_code);
72 feedback_sender_.reset(new spellcheck::FeedbackSender( 75 feedback_sender_.reset(new spellcheck::FeedbackSender(
73 context->GetRequestContext(), language_code, country_code)); 76 context->GetRequestContext(), language_code, country_code));
74 77
75 pref_change_registrar_.Add( 78 pref_change_registrar_.Add(
76 prefs::kEnableAutoSpellCorrect, 79 prefs::kEnableAutoSpellCorrect,
77 base::Bind(&SpellcheckService::OnEnableAutoSpellCorrectChanged, 80 base::Bind(&SpellcheckService::OnEnableAutoSpellCorrectChanged,
78 base::Unretained(this))); 81 base::Unretained(this)));
79 pref_change_registrar_.Add( 82 pref_change_registrar_.Add(
80 prefs::kSpellCheckDictionaries, 83 prefs::kSpellCheckDictionaries,
81 base::Bind(&SpellcheckService::OnSpellCheckDictionaryChanged, 84 base::Bind(&SpellcheckService::OnSpellCheckDictionariesChanged,
82 base::Unretained(this))); 85 base::Unretained(this)));
83 if (!chrome::spellcheck_common::IsMultilingualSpellcheckEnabled()) { 86 if (!chrome::spellcheck_common::IsMultilingualSpellcheckEnabled()) {
84 pref_change_registrar_.Add( 87 pref_change_registrar_.Add(
85 prefs::kSpellCheckUseSpellingService, 88 prefs::kSpellCheckUseSpellingService,
86 base::Bind(&SpellcheckService::OnUseSpellingServiceChanged, 89 base::Bind(&SpellcheckService::OnUseSpellingServiceChanged,
87 base::Unretained(this))); 90 base::Unretained(this)));
88 } 91 }
92
89 pref_change_registrar_.Add( 93 pref_change_registrar_.Add(
90 prefs::kEnableContinuousSpellcheck, 94 prefs::kEnableContinuousSpellcheck,
91 base::Bind(&SpellcheckService::InitForAllRenderers, 95 base::Bind(&SpellcheckService::InitForAllRenderers,
92 base::Unretained(this))); 96 base::Unretained(this)));
93 97
94 OnSpellCheckDictionaryChanged(); 98 OnSpellCheckDictionariesChanged();
95 99
96 custom_dictionary_.reset(new SpellcheckCustomDictionary(context_->GetPath())); 100 custom_dictionary_.reset(new SpellcheckCustomDictionary(context_->GetPath()));
97 custom_dictionary_->AddObserver(this); 101 custom_dictionary_->AddObserver(this);
98 custom_dictionary_->Load(); 102 custom_dictionary_->Load();
99 103
100 registrar_.Add(this, 104 registrar_.Add(this,
101 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 105 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
102 content::NotificationService::AllSources()); 106 content::NotificationService::AllSources());
103 } 107 }
104 108
105 SpellcheckService::~SpellcheckService() { 109 SpellcheckService::~SpellcheckService() {
106 // Remove pref observers 110 // Remove pref observers
107 pref_change_registrar_.RemoveAll(); 111 pref_change_registrar_.RemoveAll();
108 } 112 }
109 113
110 base::WeakPtr<SpellcheckService> SpellcheckService::GetWeakPtr() { 114 base::WeakPtr<SpellcheckService> SpellcheckService::GetWeakPtr() {
111 return weak_ptr_factory_.GetWeakPtr(); 115 return weak_ptr_factory_.GetWeakPtr();
112 } 116 }
113 117
114 // static 118 // static
115 int SpellcheckService::GetSpellCheckLanguages( 119 size_t SpellcheckService::GetSpellCheckLanguages(
116 base::SupportsUserData* context, 120 base::SupportsUserData* context,
117 std::vector<std::string>* languages) { 121 std::vector<std::string>* languages) {
118 PrefService* prefs = user_prefs::UserPrefs::Get(context); 122 PrefService* prefs = user_prefs::UserPrefs::Get(context);
119 StringPrefMember accept_languages_pref; 123 StringPrefMember accept_languages_pref;
120 accept_languages_pref.Init(prefs::kAcceptLanguages, prefs); 124 accept_languages_pref.Init(prefs::kAcceptLanguages, prefs);
121 125
122 std::string dictionary_language; 126 std::vector<std::string> accept_languages;
123 prefs->GetList(prefs::kSpellCheckDictionaries) 127 base::SplitString(accept_languages_pref.GetValue(), ',', &accept_languages);
124 ->GetString(0, &dictionary_language);
125 128
126 // Now scan through the list of accept languages, and find possible mappings 129 *languages = chrome::spellcheck_common::GetDictionaryLanguagesPref(prefs);
127 // from this list to the existing list of spell check languages. 130 size_t enabled_spellcheck_languages = languages->size();
128 std::vector<std::string> accept_languages;
129
130 #if defined(OS_MACOSX)
please use gerrit instead 2015/07/06 23:28:15 If you're removing Mac specific code because this
Julius 2015/07/07 01:14:21 Done.
131 if (spellcheck_mac::SpellCheckerAvailable())
132 spellcheck_mac::GetAvailableLanguages(&accept_languages);
133 else
134 base::SplitString(accept_languages_pref.GetValue(), ',', &accept_languages);
135 #else
136 base::SplitString(accept_languages_pref.GetValue(), ',', &accept_languages);
137 #endif // !OS_MACOSX
138
139 languages->push_back(dictionary_language);
140 131
141 for (std::vector<std::string>::const_iterator i = accept_languages.begin(); 132 for (std::vector<std::string>::const_iterator i = accept_languages.begin();
142 i != accept_languages.end(); ++i) { 133 i != accept_languages.end(); ++i) {
143 std::string language = 134 std::string language =
144 chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage(*i); 135 chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage(*i);
145 if (!language.empty() && 136 if (!language.empty() &&
146 std::find(languages->begin(), languages->end(), language) == 137 std::find(languages->begin(), languages->end(), language) ==
147 languages->end()) { 138 languages->end()) {
148 languages->push_back(language); 139 languages->push_back(language);
149 } 140 }
150 } 141 }
151 142
152 for (size_t i = 0; i < languages->size(); ++i) { 143 return enabled_spellcheck_languages;
153 if ((*languages)[i] == dictionary_language)
154 return i;
155 }
156
157 return -1;
158 } 144 }
159 145
160 // static 146 // static
161 bool SpellcheckService::SignalStatusEvent( 147 bool SpellcheckService::SignalStatusEvent(
162 SpellcheckService::EventType status_type) { 148 SpellcheckService::EventType status_type) {
163 DCHECK_CURRENTLY_ON(BrowserThread::UI); 149 DCHECK_CURRENTLY_ON(BrowserThread::UI);
164 150
165 if (!g_status_event) 151 if (!g_status_event)
166 return false; 152 return false;
167 g_status_type = status_type; 153 g_status_type = status_type;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 bool enabled = pref_change_registrar_.prefs()->GetBoolean( 278 bool enabled = pref_change_registrar_.prefs()->GetBoolean(
293 prefs::kEnableAutoSpellCorrect); 279 prefs::kEnableAutoSpellCorrect);
294 for (content::RenderProcessHost::iterator i( 280 for (content::RenderProcessHost::iterator i(
295 content::RenderProcessHost::AllHostsIterator()); 281 content::RenderProcessHost::AllHostsIterator());
296 !i.IsAtEnd(); i.Advance()) { 282 !i.IsAtEnd(); i.Advance()) {
297 content::RenderProcessHost* process = i.GetCurrentValue(); 283 content::RenderProcessHost* process = i.GetCurrentValue();
298 process->Send(new SpellCheckMsg_EnableAutoSpellCorrect(enabled)); 284 process->Send(new SpellCheckMsg_EnableAutoSpellCorrect(enabled));
299 } 285 }
300 } 286 }
301 287
302 void SpellcheckService::OnSpellCheckDictionaryChanged() { 288 void SpellcheckService::OnSpellCheckDictionariesChanged() {
303 if (hunspell_dictionary_.get()) 289 if (hunspell_dictionary_.get())
304 hunspell_dictionary_->RemoveObserver(this); 290 hunspell_dictionary_->RemoveObserver(this);
305 PrefService* prefs = user_prefs::UserPrefs::Get(context_);
306 DCHECK(prefs);
307 291
308 std::string dictionary; 292 std::string dictionary;
309 prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &dictionary); 293 std::vector<std::string> languages;
please use gerrit instead 2015/07/06 23:28:15 The current implementation is fine as is. Why chan
Julius 2015/07/07 01:14:21 Probably the better way.
294 size_t dictionary_languages = GetSpellCheckLanguages(context_, &languages);
295 if (dictionary_languages > 0) {
296 DCHECK(!languages.empty());
297 dictionary = languages.front();
298 }
310 299
311 hunspell_dictionary_.reset(new SpellcheckHunspellDictionary( 300 hunspell_dictionary_.reset(new SpellcheckHunspellDictionary(
312 dictionary, context_->GetRequestContext(), this)); 301 dictionary, context_->GetRequestContext(), this));
313 hunspell_dictionary_->AddObserver(this); 302 hunspell_dictionary_->AddObserver(this);
314 hunspell_dictionary_->Load(); 303 hunspell_dictionary_->Load();
315 std::string language_code; 304 std::string language_code;
316 std::string country_code; 305 std::string country_code;
317 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale( 306 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale(
318 dictionary, &language_code, &country_code); 307 dictionary, &language_code, &country_code);
319 feedback_sender_->OnLanguageCountryChange(language_code, country_code); 308 feedback_sender_->OnLanguageCountryChange(language_code, country_code);
320 UpdateFeedbackSenderState(); 309 UpdateFeedbackSenderState();
321 } 310 }
322 311
323 void SpellcheckService::OnUseSpellingServiceChanged() { 312 void SpellcheckService::OnUseSpellingServiceChanged() {
324 bool enabled = pref_change_registrar_.prefs()->GetBoolean( 313 bool enabled = pref_change_registrar_.prefs()->GetBoolean(
325 prefs::kSpellCheckUseSpellingService); 314 prefs::kSpellCheckUseSpellingService);
326 if (metrics_) 315 if (metrics_)
327 metrics_->RecordSpellingServiceStats(enabled); 316 metrics_->RecordSpellingServiceStats(enabled);
328 UpdateFeedbackSenderState(); 317 UpdateFeedbackSenderState();
329 } 318 }
330 319
331 void SpellcheckService::UpdateFeedbackSenderState() { 320 void SpellcheckService::UpdateFeedbackSenderState() {
332 if (SpellingServiceClient::IsAvailable( 321 if (SpellingServiceClient::IsAvailable(
333 context_, SpellingServiceClient::SPELLCHECK)) { 322 context_, SpellingServiceClient::SPELLCHECK)) {
334 feedback_sender_->StartFeedbackCollection(); 323 feedback_sender_->StartFeedbackCollection();
335 } else { 324 } else {
336 feedback_sender_->StopFeedbackCollection(); 325 feedback_sender_->StopFeedbackCollection();
337 } 326 }
338 } 327 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698