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_prefs.h"
13 #include "chrome/browser/translate/translate_tab_helper.h"
14 #include "components/translate/core/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"
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 const char kDeclineTranslateDismissUI
[] = "Translate.DeclineTranslateDismissUI";
32 const char kShowErrorUI
[] = "Translate.ShowErrorUI";
36 TranslateUIDelegate::TranslateUIDelegate(content::WebContents
* web_contents
,
37 const std::string
& original_language
,
38 const std::string
& target_language
)
39 : web_contents_(web_contents
),
40 original_language_index_(NO_INDEX
),
41 initial_original_language_index_(NO_INDEX
),
42 target_language_index_(NO_INDEX
) {
43 DCHECK(web_contents_
);
45 std::vector
<std::string
> language_codes
;
46 TranslateManager::GetSupportedLanguages(&language_codes
);
48 // Preparing for the alphabetical order in the locale.
49 UErrorCode error
= U_ZERO_ERROR
;
50 std::string locale
= g_browser_process
->GetApplicationLocale();
51 icu::Locale
loc(locale
.c_str());
52 scoped_ptr
<icu::Collator
> collator(icu::Collator::createInstance(loc
, error
));
53 collator
->setStrength(icu::Collator::PRIMARY
);
55 languages_
.reserve(language_codes
.size());
56 for (std::vector
<std::string
>::const_iterator iter
= language_codes
.begin();
57 iter
!= language_codes
.end(); ++iter
) {
58 std::string language_code
= *iter
;
60 base::string16 language_name
= l10n_util::GetDisplayNameForLocale(
61 language_code
, g_browser_process
->GetApplicationLocale(), true);
62 // Insert the language in languages_ in alphabetical order.
63 std::vector
<LanguageNamePair
>::iterator iter2
;
64 for (iter2
= languages_
.begin(); iter2
!= languages_
.end(); ++iter2
) {
65 if (base::i18n::CompareString16WithCollator(collator
.get(),
66 language_name
, iter2
->second
) == UCOL_LESS
) {
70 languages_
.insert(iter2
, LanguageNamePair(language_code
, language_name
));
72 for (std::vector
<LanguageNamePair
>::const_iterator iter
= languages_
.begin();
73 iter
!= languages_
.end(); ++iter
) {
74 std::string language_code
= iter
->first
;
75 if (language_code
== original_language
) {
76 original_language_index_
= iter
- languages_
.begin();
77 initial_original_language_index_
= original_language_index_
;
79 if (language_code
== target_language
)
80 target_language_index_
= iter
- languages_
.begin();
84 Profile::FromBrowserContext(web_contents_
->GetBrowserContext());
85 prefs_
.reset(new TranslatePrefs(profile
->GetPrefs()));
88 TranslateUIDelegate::~TranslateUIDelegate() {
91 void TranslateUIDelegate::OnErrorShown(TranslateErrors::Type error_type
) {
92 DCHECK_LE(TranslateErrors::NONE
, error_type
);
93 DCHECK_LT(error_type
, TranslateErrors::TRANSLATE_ERROR_MAX
);
95 if (error_type
== TranslateErrors::NONE
)
98 UMA_HISTOGRAM_ENUMERATION(kShowErrorUI
, error_type
,
99 TranslateErrors::TRANSLATE_ERROR_MAX
);
102 size_t TranslateUIDelegate::GetNumberOfLanguages() const {
103 return languages_
.size();
106 size_t TranslateUIDelegate::GetOriginalLanguageIndex() const {
107 return original_language_index_
;
110 void TranslateUIDelegate::UpdateOriginalLanguageIndex(size_t language_index
) {
111 if (original_language_index_
== language_index
)
114 UMA_HISTOGRAM_BOOLEAN(kModifyOriginalLang
, true);
115 original_language_index_
= language_index
;
118 size_t TranslateUIDelegate::GetTargetLanguageIndex() const {
119 return target_language_index_
;
122 void TranslateUIDelegate::UpdateTargetLanguageIndex(size_t language_index
) {
123 if (target_language_index_
== language_index
)
126 DCHECK_LT(language_index
, GetNumberOfLanguages());
127 UMA_HISTOGRAM_BOOLEAN(kModifyTargetLang
, true);
128 target_language_index_
= language_index
;
132 std::string
TranslateUIDelegate::GetLanguageCodeAt(size_t index
) const {
133 DCHECK_LT(index
, GetNumberOfLanguages());
134 return languages_
[index
].first
;
137 base::string16
TranslateUIDelegate::GetLanguageNameAt(size_t index
) const {
138 if (index
== static_cast<size_t>(NO_INDEX
))
139 return base::string16();
140 DCHECK_LT(index
, GetNumberOfLanguages());
141 return languages_
[index
].second
;
144 std::string
TranslateUIDelegate::GetOriginalLanguageCode() const {
145 return (GetOriginalLanguageIndex() == static_cast<size_t>(NO_INDEX
)) ?
146 translate::kUnknownLanguageCode
:
147 GetLanguageCodeAt(GetOriginalLanguageIndex());
150 std::string
TranslateUIDelegate::GetTargetLanguageCode() const {
151 return GetLanguageCodeAt(GetTargetLanguageIndex());
154 void TranslateUIDelegate::Translate() {
155 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
156 prefs_
->ResetTranslationDeniedCount(GetOriginalLanguageCode());
157 prefs_
->IncrementTranslationAcceptedCount(GetOriginalLanguageCode());
159 TranslateManager::GetInstance()->TranslatePage(web_contents(),
160 GetOriginalLanguageCode(),
161 GetTargetLanguageCode());
163 UMA_HISTOGRAM_BOOLEAN(kPerformTranslate
, true);
166 void TranslateUIDelegate::RevertTranslation() {
167 TranslateManager::GetInstance()->RevertTranslation(web_contents());
169 UMA_HISTOGRAM_BOOLEAN(kRevertTranslation
, true);
172 void TranslateUIDelegate::TranslationDeclined(bool explicitly_closed
) {
173 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) {
174 prefs_
->ResetTranslationAcceptedCount(GetOriginalLanguageCode());
175 prefs_
->IncrementTranslationDeniedCount(GetOriginalLanguageCode());
178 // Remember that the user declined the translation so as to prevent showing a
179 // translate infobar for that page again. (TranslateManager initiates
180 // translations when getting a LANGUAGE_DETERMINED from the page, which
181 // happens when a load stops. That could happen multiple times, including
182 // after the user already declined the translation.)
183 TranslateTabHelper::FromWebContents(web_contents())->
184 language_state().set_translation_declined(true);
186 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate
, true);
188 if (!explicitly_closed
)
189 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslateDismissUI
, true);
192 bool TranslateUIDelegate::IsLanguageBlocked() {
193 return prefs_
->IsBlockedLanguage(GetOriginalLanguageCode());
196 void TranslateUIDelegate::SetLanguageBlocked(bool value
) {
198 prefs_
->BlockLanguage(GetOriginalLanguageCode());
199 TranslateTabHelper
* translate_tab_helper
=
200 TranslateTabHelper::FromWebContents(web_contents());
201 DCHECK(translate_tab_helper
);
202 translate_tab_helper
->language_state().SetTranslateEnabled(false);
204 prefs_
->UnblockLanguage(GetOriginalLanguageCode());
207 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang
, true);
210 bool TranslateUIDelegate::IsSiteBlacklisted() {
211 std::string host
= GetPageHost();
212 return !host
.empty() && prefs_
->IsSiteBlacklisted(host
);
215 void TranslateUIDelegate::SetSiteBlacklist(bool value
) {
216 std::string host
= GetPageHost();
221 prefs_
->BlacklistSite(host
);
222 TranslateTabHelper
* translate_tab_helper
=
223 TranslateTabHelper::FromWebContents(web_contents());
224 DCHECK(translate_tab_helper
);
225 translate_tab_helper
->language_state().SetTranslateEnabled(false);
227 prefs_
->RemoveSiteFromBlacklist(host
);
230 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite
, true);
233 bool TranslateUIDelegate::ShouldAlwaysTranslate() {
234 return prefs_
->IsLanguagePairWhitelisted(GetOriginalLanguageCode(),
235 GetTargetLanguageCode());
238 void TranslateUIDelegate::SetAlwaysTranslate(bool value
) {
239 const std::string
& original_lang
= GetOriginalLanguageCode();
240 const std::string
& target_lang
= GetTargetLanguageCode();
242 prefs_
->WhitelistLanguagePair(original_lang
, target_lang
);
244 prefs_
->RemoveLanguagePairFromWhitelist(original_lang
, target_lang
);
246 UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang
, true);
249 std::string
TranslateUIDelegate::GetPageHost() {
250 content::NavigationEntry
* entry
=
251 web_contents()->GetController().GetActiveEntry();
252 return entry
? entry
->GetURL().HostNoBrackets() : std::string();