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.
5 #include "chrome/browser/translate/translate_ui_delegate.h"
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_tab_helper.h"
13 #include "components/translate/core/browser/translate_download_manager.h"
14 #include "components/translate/core/browser/translate_prefs.h"
15 #include "components/translate/core/common/translate_constants.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/web_contents.h"
19 #include "third_party/icu/source/i18n/unicode/coll.h"
20 #include "ui/base/l10n/l10n_util.h"
24 const char kDeclineTranslate
[] = "Translate.DeclineTranslate";
25 const char kRevertTranslation
[] = "Translate.RevertTranslation";
26 const char kPerformTranslate
[] = "Translate.Translate";
27 const char kNeverTranslateLang
[] = "Translate.NeverTranslateLang";
28 const char kNeverTranslateSite
[] = "Translate.NeverTranslateSite";
29 const char kAlwaysTranslateLang
[] = "Translate.AlwaysTranslateLang";
30 const char kModifyOriginalLang
[] = "Translate.ModifyOriginalLang";
31 const char kModifyTargetLang
[] = "Translate.ModifyTargetLang";
32 const char kDeclineTranslateDismissUI
[] = "Translate.DeclineTranslateDismissUI";
33 const char kShowErrorUI
[] = "Translate.ShowErrorUI";
37 TranslateUIDelegate::TranslateUIDelegate(content::WebContents
* web_contents
,
38 const std::string
& original_language
,
39 const std::string
& target_language
)
40 : web_contents_(web_contents
),
41 original_language_index_(NO_INDEX
),
42 initial_original_language_index_(NO_INDEX
),
43 target_language_index_(NO_INDEX
) {
44 DCHECK(web_contents_
);
46 std::vector
<std::string
> language_codes
;
47 TranslateDownloadManager::GetSupportedLanguages(&language_codes
);
49 // Preparing for the alphabetical order in the locale.
50 UErrorCode error
= U_ZERO_ERROR
;
51 std::string locale
= g_browser_process
->GetApplicationLocale();
52 icu::Locale
loc(locale
.c_str());
53 scoped_ptr
<icu::Collator
> collator(icu::Collator::createInstance(loc
, error
));
54 collator
->setStrength(icu::Collator::PRIMARY
);
56 languages_
.reserve(language_codes
.size());
57 for (std::vector
<std::string
>::const_iterator iter
= language_codes
.begin();
58 iter
!= language_codes
.end(); ++iter
) {
59 std::string language_code
= *iter
;
61 base::string16 language_name
= l10n_util::GetDisplayNameForLocale(
62 language_code
, g_browser_process
->GetApplicationLocale(), true);
63 // Insert the language in languages_ in alphabetical order.
64 std::vector
<LanguageNamePair
>::iterator iter2
;
65 for (iter2
= languages_
.begin(); iter2
!= languages_
.end(); ++iter2
) {
66 if (base::i18n::CompareString16WithCollator(collator
.get(),
67 language_name
, iter2
->second
) == UCOL_LESS
) {
71 languages_
.insert(iter2
, LanguageNamePair(language_code
, language_name
));
73 for (std::vector
<LanguageNamePair
>::const_iterator iter
= languages_
.begin();
74 iter
!= languages_
.end(); ++iter
) {
75 std::string language_code
= iter
->first
;
76 if (language_code
== original_language
) {
77 original_language_index_
= iter
- languages_
.begin();
78 initial_original_language_index_
= original_language_index_
;
80 if (language_code
== target_language
)
81 target_language_index_
= iter
- languages_
.begin();
85 Profile::FromBrowserContext(web_contents_
->GetBrowserContext());
86 prefs_
= TranslateTabHelper::CreateTranslatePrefs(profile
->GetPrefs());
89 TranslateUIDelegate::~TranslateUIDelegate() {
92 void TranslateUIDelegate::OnErrorShown(TranslateErrors::Type error_type
) {
93 DCHECK_LE(TranslateErrors::NONE
, error_type
);
94 DCHECK_LT(error_type
, TranslateErrors::TRANSLATE_ERROR_MAX
);
96 if (error_type
== TranslateErrors::NONE
)
99 UMA_HISTOGRAM_ENUMERATION(kShowErrorUI
, error_type
,
100 TranslateErrors::TRANSLATE_ERROR_MAX
);
103 size_t TranslateUIDelegate::GetNumberOfLanguages() const {
104 return languages_
.size();
107 size_t TranslateUIDelegate::GetOriginalLanguageIndex() const {
108 return original_language_index_
;
111 void TranslateUIDelegate::UpdateOriginalLanguageIndex(size_t language_index
) {
112 if (original_language_index_
== language_index
)
115 UMA_HISTOGRAM_BOOLEAN(kModifyOriginalLang
, true);
116 original_language_index_
= language_index
;
119 size_t TranslateUIDelegate::GetTargetLanguageIndex() const {
120 return target_language_index_
;
123 void TranslateUIDelegate::UpdateTargetLanguageIndex(size_t language_index
) {
124 if (target_language_index_
== language_index
)
127 DCHECK_LT(language_index
, GetNumberOfLanguages());
128 UMA_HISTOGRAM_BOOLEAN(kModifyTargetLang
, true);
129 target_language_index_
= language_index
;
133 std::string
TranslateUIDelegate::GetLanguageCodeAt(size_t index
) const {
134 DCHECK_LT(index
, GetNumberOfLanguages());
135 return languages_
[index
].first
;
138 base::string16
TranslateUIDelegate::GetLanguageNameAt(size_t index
) const {
139 if (index
== static_cast<size_t>(NO_INDEX
))
140 return base::string16();
141 DCHECK_LT(index
, GetNumberOfLanguages());
142 return languages_
[index
].second
;
145 std::string
TranslateUIDelegate::GetOriginalLanguageCode() const {
146 return (GetOriginalLanguageIndex() == static_cast<size_t>(NO_INDEX
)) ?
147 translate::kUnknownLanguageCode
:
148 GetLanguageCodeAt(GetOriginalLanguageIndex());
151 std::string
TranslateUIDelegate::GetTargetLanguageCode() const {
152 return GetLanguageCodeAt(GetTargetLanguageIndex());
155 void TranslateUIDelegate::Translate() {
156 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
157 prefs_
->ResetTranslationDeniedCount(GetOriginalLanguageCode());
158 prefs_
->IncrementTranslationAcceptedCount(GetOriginalLanguageCode());
160 TranslateManager::GetInstance()->TranslatePage(web_contents(),
161 GetOriginalLanguageCode(),
162 GetTargetLanguageCode());
164 UMA_HISTOGRAM_BOOLEAN(kPerformTranslate
, true);
167 void TranslateUIDelegate::RevertTranslation() {
168 TranslateManager::GetInstance()->RevertTranslation(web_contents());
170 UMA_HISTOGRAM_BOOLEAN(kRevertTranslation
, true);
173 void TranslateUIDelegate::TranslationDeclined(bool explicitly_closed
) {
174 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
175 prefs_
->ResetTranslationAcceptedCount(GetOriginalLanguageCode());
176 prefs_
->IncrementTranslationDeniedCount(GetOriginalLanguageCode());
179 // Remember that the user declined the translation so as to prevent showing a
180 // translate infobar for that page again. (TranslateManager initiates
181 // translations when getting a LANGUAGE_DETERMINED from the page, which
182 // happens when a load stops. That could happen multiple times, including
183 // after the user already declined the translation.)
184 TranslateTabHelper::FromWebContents(web_contents())->
185 GetLanguageState().set_translation_declined(true);
187 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate
, true);
189 if (!explicitly_closed
)
190 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslateDismissUI
, true);
193 bool TranslateUIDelegate::IsLanguageBlocked() {
194 return prefs_
->IsBlockedLanguage(GetOriginalLanguageCode());
197 void TranslateUIDelegate::SetLanguageBlocked(bool value
) {
199 prefs_
->BlockLanguage(GetOriginalLanguageCode());
200 TranslateTabHelper
* translate_tab_helper
=
201 TranslateTabHelper::FromWebContents(web_contents());
202 DCHECK(translate_tab_helper
);
203 translate_tab_helper
->GetLanguageState().SetTranslateEnabled(false);
205 prefs_
->UnblockLanguage(GetOriginalLanguageCode());
208 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang
, true);
211 bool TranslateUIDelegate::IsSiteBlacklisted() {
212 std::string host
= GetPageHost();
213 return !host
.empty() && prefs_
->IsSiteBlacklisted(host
);
216 void TranslateUIDelegate::SetSiteBlacklist(bool value
) {
217 std::string host
= GetPageHost();
222 prefs_
->BlacklistSite(host
);
223 TranslateTabHelper
* translate_tab_helper
=
224 TranslateTabHelper::FromWebContents(web_contents());
225 DCHECK(translate_tab_helper
);
226 translate_tab_helper
->GetLanguageState().SetTranslateEnabled(false);
228 prefs_
->RemoveSiteFromBlacklist(host
);
231 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite
, true);
234 bool TranslateUIDelegate::ShouldAlwaysTranslate() {
235 return prefs_
->IsLanguagePairWhitelisted(GetOriginalLanguageCode(),
236 GetTargetLanguageCode());
239 void TranslateUIDelegate::SetAlwaysTranslate(bool value
) {
240 const std::string
& original_lang
= GetOriginalLanguageCode();
241 const std::string
& target_lang
= GetTargetLanguageCode();
243 prefs_
->WhitelistLanguagePair(original_lang
, target_lang
);
245 prefs_
->RemoveLanguagePairFromWhitelist(original_lang
, target_lang
);
247 UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang
, true);
250 std::string
TranslateUIDelegate::GetPageHost() {
251 content::NavigationEntry
* entry
=
252 web_contents()->GetController().GetActiveEntry();
253 return entry
? entry
->GetURL().HostNoBrackets() : std::string();