Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / spellchecker / feedback.cc
blob01c21031e5b7ce5d71adf0a92407846e73d6eb09
1 // Copyright (c) 2013 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 // The |Feedback| object keeps track of each instance of user feedback in a map
6 // |misspellings_|. This is a map from uint32 hashes to |Misspelling| objects.
7 //
8 // Each misspelling should be present in only one renderer process. The
9 // |Feedback| objects keeps track of misspelling-renderer relationship in the
10 // |renderers_| map of renderer process identifiers to a set of hashes.
12 // When the user adds a misspelling to their custom dictionary, all of the
13 // |Misspelling| objects with the same misspelled string are updated. The
14 // |Feedback| object facilitates efficient access to these misspellings through
15 // a |text_| map of misspelled strings to a set of hashes.
17 #include "chrome/browser/spellchecker/feedback.h"
19 #include <algorithm>
20 #include <iterator>
22 #include "base/stl_util.h"
24 namespace spellcheck {
26 Feedback::Feedback() {}
28 Feedback::~Feedback() {}
30 Misspelling* Feedback::GetMisspelling(uint32 hash) {
31 HashMisspellingMap::iterator misspelling_it = misspellings_.find(hash);
32 if (misspelling_it == misspellings_.end())
33 return NULL;
34 return &misspelling_it->second;
37 void Feedback::FinalizeRemovedMisspellings(
38 int renderer_process_id,
39 const std::vector<uint32>& remaining_markers) {
40 RendererHashesMap::iterator renderer_it =
41 renderers_.find(renderer_process_id);
42 if (renderer_it == renderers_.end() || renderer_it->second.empty())
43 return;
44 HashCollection& renderer_hashes = renderer_it->second;
45 HashCollection remaining_hashes(remaining_markers.begin(),
46 remaining_markers.end());
47 std::vector<uint32> removed_hashes =
48 base::STLSetDifference<std::vector<uint32>>(renderer_hashes,
49 remaining_hashes);
50 for (std::vector<uint32>::const_iterator hash_it = removed_hashes.begin();
51 hash_it != removed_hashes.end(); ++hash_it) {
52 HashMisspellingMap::iterator misspelling_it = misspellings_.find(*hash_it);
53 if (misspelling_it != misspellings_.end() &&
54 !misspelling_it->second.action.IsFinal()) {
55 misspelling_it->second.action.Finalize();
60 bool Feedback::RendererHasMisspellings(int renderer_process_id) const {
61 RendererHashesMap::const_iterator renderer_it =
62 renderers_.find(renderer_process_id);
63 return renderer_it != renderers_.end() && !renderer_it->second.empty();
66 std::vector<Misspelling> Feedback::GetMisspellingsInRenderer(
67 int renderer_process_id) const {
68 std::vector<Misspelling> misspellings_in_renderer;
69 RendererHashesMap::const_iterator renderer_it =
70 renderers_.find(renderer_process_id);
71 if (renderer_it == renderers_.end() || renderer_it->second.empty())
72 return misspellings_in_renderer;
73 const HashCollection& renderer_hashes = renderer_it->second;
74 for (HashCollection::const_iterator hash_it = renderer_hashes.begin();
75 hash_it != renderer_hashes.end(); ++hash_it) {
76 HashMisspellingMap::const_iterator misspelling_it =
77 misspellings_.find(*hash_it);
78 if (misspelling_it != misspellings_.end())
79 misspellings_in_renderer.push_back(misspelling_it->second);
81 return misspellings_in_renderer;
84 void Feedback::EraseFinalizedMisspellings(int renderer_process_id) {
85 RendererHashesMap::iterator renderer_it =
86 renderers_.find(renderer_process_id);
87 if (renderer_it == renderers_.end())
88 return;
89 HashCollection& renderer_hashes = renderer_it->second;
90 for (HashCollection::const_iterator hash_it = renderer_hashes.begin();
91 hash_it != renderer_hashes.end();) {
92 HashMisspellingMap::iterator misspelling_it = misspellings_.find(*hash_it);
93 HashCollection::iterator erasable_hash_it = hash_it;
94 ++hash_it;
95 if (misspelling_it == misspellings_.end())
96 continue;
97 const Misspelling& misspelling = misspelling_it->second;
98 if (!misspelling.action.IsFinal())
99 continue;
100 renderer_hashes.erase(erasable_hash_it);
101 text_[misspelling.GetMisspelledString()].erase(misspelling.hash);
102 misspellings_.erase(misspelling_it);
104 if (renderer_hashes.empty())
105 renderers_.erase(renderer_it);
108 bool Feedback::HasMisspelling(uint32 hash) const {
109 return !!misspellings_.count(hash);
112 void Feedback::AddMisspelling(int renderer_process_id,
113 const Misspelling& misspelling) {
114 HashMisspellingMap::iterator misspelling_it =
115 misspellings_.find(misspelling.hash);
116 if (misspelling_it != misspellings_.end()) {
117 const Misspelling& existing_misspelling = misspelling_it->second;
118 text_[existing_misspelling.GetMisspelledString()].erase(misspelling.hash);
119 for (RendererHashesMap::iterator renderer_it = renderers_.begin();
120 renderer_it != renderers_.end();) {
121 HashCollection& renderer_hashes = renderer_it->second;
122 RendererHashesMap::iterator erasable_renderer_it = renderer_it;
123 ++renderer_it;
124 renderer_hashes.erase(misspelling.hash);
125 if (renderer_hashes.empty())
126 renderers_.erase(erasable_renderer_it);
129 misspellings_[misspelling.hash] = misspelling;
130 text_[misspelling.GetMisspelledString()].insert(misspelling.hash);
131 renderers_[renderer_process_id].insert(misspelling.hash);
134 bool Feedback::Empty() const {
135 return misspellings_.empty();
138 std::vector<int> Feedback::GetRendersWithMisspellings() const {
139 std::vector<int> renderers_with_misspellings;
140 for (RendererHashesMap::const_iterator renderer_it = renderers_.begin();
141 renderer_it != renderers_.end(); ++renderer_it) {
142 if (!renderer_it->second.empty())
143 renderers_with_misspellings.push_back(renderer_it->first);
145 return renderers_with_misspellings;
148 void Feedback::FinalizeAllMisspellings() {
149 for (HashMisspellingMap::iterator misspelling_it = misspellings_.begin();
150 misspelling_it != misspellings_.end(); ++misspelling_it) {
151 if (!misspelling_it->second.action.IsFinal())
152 misspelling_it->second.action.Finalize();
156 std::vector<Misspelling> Feedback::GetAllMisspellings() const {
157 std::vector<Misspelling> all_misspellings;
158 for (HashMisspellingMap::const_iterator misspelling_it =
159 misspellings_.begin();
160 misspelling_it != misspellings_.end(); ++misspelling_it) {
161 all_misspellings.push_back(misspelling_it->second);
163 return all_misspellings;
166 void Feedback::Clear() {
167 misspellings_.clear();
168 text_.clear();
169 renderers_.clear();
172 const std::set<uint32>& Feedback::FindMisspellings(
173 const base::string16& misspelled_text) const {
174 const TextHashesMap::const_iterator text_it = text_.find(misspelled_text);
175 return text_it == text_.end() ? empty_hash_collection_ : text_it->second;
178 } // namespace spellcheck