- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / translate / translate_ui_delegate.cc
1 // Copyright 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 #include "chrome/browser/translate/translate_ui_delegate.h"
6
7 #include "base/i18n/string_compare.h"
8 #include "base/metrics/histogram.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/translate/translate_manager.h"
12 #include "chrome/browser/translate/translate_prefs.h"
13 #include "chrome/browser/translate/translate_tab_helper.h"
14 #include "components/translate/common/translate_constants.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/browser/web_contents.h"
18 #include "third_party/icu/source/i18n/unicode/coll.h"
19 #include "ui/base/l10n/l10n_util.h"
20
21 namespace {
22
23 const char kDeclineTranslate[] = "Translate.DeclineTranslate";
24 const char kRevertTranslation[] = "Translate.RevertTranslation";
25 const char kPerformTranslate[] = "Translate.Translate";
26 const char kNeverTranslateLang[] = "Translate.NeverTranslateLang";
27 const char kNeverTranslateSite[] = "Translate.NeverTranslateSite";
28 const char kAlwaysTranslateLang[] = "Translate.AlwaysTranslateLang";
29 const char kModifyOriginalLang[] = "Translate.ModifyOriginalLang";
30 const char kModifyTargetLang[] = "Translate.ModifyTargetLang";
31
32 }  // namespace
33
34 TranslateUIDelegate::TranslateUIDelegate(content::WebContents* web_contents,
35                                          const std::string& original_language,
36                                          const std::string& target_language)
37     : web_contents_(web_contents),
38       original_language_index_(NO_INDEX),
39       initial_original_language_index_(NO_INDEX),
40       target_language_index_(NO_INDEX) {
41   std::vector<std::string> language_codes;
42   TranslateManager::GetSupportedLanguages(&language_codes);
43
44   // Preparing for the alphabetical order in the locale.
45   UErrorCode error = U_ZERO_ERROR;
46   std::string locale = g_browser_process->GetApplicationLocale();
47   icu::Locale loc(locale.c_str());
48   scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error));
49   collator->setStrength(icu::Collator::PRIMARY);
50
51   languages_.reserve(language_codes.size());
52   for (std::vector<std::string>::const_iterator iter = language_codes.begin();
53        iter != language_codes.end(); ++iter) {
54     std::string language_code = *iter;
55
56     string16 language_name = l10n_util::GetDisplayNameForLocale(
57         language_code, g_browser_process->GetApplicationLocale(), true);
58     // Insert the language in languages_ in alphabetical order.
59     std::vector<LanguageNamePair>::iterator iter2;
60     for (iter2 = languages_.begin(); iter2 != languages_.end(); ++iter2) {
61       if (base::i18n::CompareString16WithCollator(collator.get(),
62           language_name, iter2->second) == UCOL_LESS) {
63         break;
64       }
65     }
66     languages_.insert(iter2, LanguageNamePair(language_code, language_name));
67   }
68   for (std::vector<LanguageNamePair>::const_iterator iter = languages_.begin();
69        iter != languages_.end(); ++iter) {
70     std::string language_code = iter->first;
71     if (language_code == original_language) {
72       original_language_index_ = iter - languages_.begin();
73       initial_original_language_index_ = original_language_index_;
74     }
75     if (language_code == target_language)
76       target_language_index_ = iter - languages_.begin();
77   }
78
79   Profile* profile =
80       Profile::FromBrowserContext(web_contents->GetBrowserContext());
81   prefs_.reset(new TranslatePrefs(profile->GetPrefs()));
82 }
83
84 TranslateUIDelegate::~TranslateUIDelegate() {
85 }
86
87 size_t TranslateUIDelegate::GetNumberOfLanguages() const {
88   return languages_.size();
89 }
90
91 size_t TranslateUIDelegate::GetOriginalLanguageIndex() const {
92   return original_language_index_;
93 }
94
95 void TranslateUIDelegate::UpdateOriginalLanguageIndex(size_t language_index) {
96   if (original_language_index_ == language_index)
97     return;
98
99   UMA_HISTOGRAM_BOOLEAN(kModifyOriginalLang, true);
100   original_language_index_ = language_index;
101 }
102
103 size_t TranslateUIDelegate::GetTargetLanguageIndex() const {
104   return target_language_index_;
105 }
106
107 void TranslateUIDelegate::UpdateTargetLanguageIndex(size_t language_index) {
108   if (target_language_index_ == language_index)
109     return;
110
111   DCHECK_LT(language_index, GetNumberOfLanguages());
112   UMA_HISTOGRAM_BOOLEAN(kModifyTargetLang, true);
113   target_language_index_ = language_index;
114 }
115
116
117 std::string TranslateUIDelegate::GetLanguageCodeAt(size_t index) const {
118   DCHECK_LT(index, GetNumberOfLanguages());
119   return languages_[index].first;
120 }
121
122 string16 TranslateUIDelegate::GetLanguageNameAt(size_t index) const {
123   if (index == static_cast<size_t>(NO_INDEX))
124     return string16();
125   DCHECK_LT(index, GetNumberOfLanguages());
126   return languages_[index].second;
127 }
128
129 std::string TranslateUIDelegate::GetOriginalLanguageCode() const {
130   return (GetOriginalLanguageIndex() == static_cast<size_t>(NO_INDEX)) ?
131       translate::kUnknownLanguageCode :
132       GetLanguageCodeAt(GetOriginalLanguageIndex());
133 }
134
135 std::string TranslateUIDelegate::GetTargetLanguageCode() const {
136   return GetLanguageCodeAt(GetTargetLanguageIndex());
137 }
138
139 void TranslateUIDelegate::Translate() {
140   if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
141     prefs_->ResetTranslationDeniedCount(GetOriginalLanguageCode());
142     prefs_->IncrementTranslationAcceptedCount(GetOriginalLanguageCode());
143   }
144   TranslateManager::GetInstance()->TranslatePage(web_contents(),
145                                                  GetOriginalLanguageCode(),
146                                                  GetTargetLanguageCode());
147
148   UMA_HISTOGRAM_BOOLEAN(kPerformTranslate, true);
149 }
150
151 void TranslateUIDelegate::RevertTranslation() {
152   TranslateManager::GetInstance()->RevertTranslation(web_contents());
153
154   UMA_HISTOGRAM_BOOLEAN(kRevertTranslation, true);
155 }
156
157 void TranslateUIDelegate::TranslationDeclined() {
158   if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
159     prefs_->ResetTranslationAcceptedCount(GetOriginalLanguageCode());
160     prefs_->IncrementTranslationDeniedCount(GetOriginalLanguageCode());
161   }
162
163   // Remember that the user declined the translation so as to prevent showing a
164   // translate infobar for that page again.  (TranslateManager initiates
165   // translations when getting a LANGUAGE_DETERMINED from the page, which
166   // happens when a load stops. That could happen multiple times, including
167   // after the user already declined the translation.)
168   TranslateTabHelper::FromWebContents(web_contents())->
169       language_state().set_translation_declined(true);
170
171   UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate, true);
172 }
173
174 bool TranslateUIDelegate::IsLanguageBlocked() {
175   return prefs_->IsBlockedLanguage(GetOriginalLanguageCode());
176 }
177
178 void TranslateUIDelegate::SetLanguageBlocked(bool value) {
179   if (value) {
180     prefs_->BlockLanguage(GetOriginalLanguageCode());
181     TranslateTabHelper* translate_tab_helper =
182         TranslateTabHelper::FromWebContents(web_contents());
183     DCHECK(translate_tab_helper);
184     translate_tab_helper->language_state().SetTranslateEnabled(false);
185   } else {
186     prefs_->UnblockLanguage(GetOriginalLanguageCode());
187   }
188
189   UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang, true);
190 }
191
192 bool TranslateUIDelegate::IsSiteBlacklisted() {
193   std::string host = GetPageHost();
194   return !host.empty() && prefs_->IsSiteBlacklisted(host);
195 }
196
197 void TranslateUIDelegate::SetSiteBlacklist(bool value) {
198   std::string host = GetPageHost();
199   if (host.empty())
200     return;
201
202   if (value) {
203     prefs_->BlacklistSite(host);
204     TranslateTabHelper* translate_tab_helper =
205         TranslateTabHelper::FromWebContents(web_contents());
206     DCHECK(translate_tab_helper);
207     translate_tab_helper->language_state().SetTranslateEnabled(false);
208   } else {
209     prefs_->RemoveSiteFromBlacklist(host);
210   }
211
212   UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite, true);
213 }
214
215 bool TranslateUIDelegate::ShouldAlwaysTranslate() {
216   return prefs_->IsLanguagePairWhitelisted(GetOriginalLanguageCode(),
217                                            GetTargetLanguageCode());
218 }
219
220 void TranslateUIDelegate::SetAlwaysTranslate(bool value) {
221   const std::string& original_lang = GetOriginalLanguageCode();
222   const std::string& target_lang = GetTargetLanguageCode();
223   if (value)
224     prefs_->WhitelistLanguagePair(original_lang, target_lang);
225   else
226     prefs_->RemoveLanguagePairFromWhitelist(original_lang, target_lang);
227
228   UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang, true);
229 }
230
231 std::string TranslateUIDelegate::GetPageHost() {
232   content::NavigationEntry* entry =
233       web_contents()->GetController().GetActiveEntry();
234   return entry ? entry->GetURL().HostNoBrackets() : std::string();
235 }