1 // Copyright 2014 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 "components/translate/core/browser/translate_ui_delegate.h"
7 #include "base/i18n/string_compare.h"
8 #include "base/metrics/histogram.h"
9 #include "components/translate/core/browser/language_state.h"
10 #include "components/translate/core/browser/translate_client.h"
11 #include "components/translate/core/browser/translate_download_manager.h"
12 #include "components/translate/core/browser/translate_driver.h"
13 #include "components/translate/core/browser/translate_manager.h"
14 #include "components/translate/core/browser/translate_prefs.h"
15 #include "components/translate/core/common/translate_constants.h"
16 #include "third_party/icu/source/i18n/unicode/coll.h"
17 #include "ui/base/l10n/l10n_util.h"
21 const char kDeclineTranslate
[] = "Translate.DeclineTranslate";
22 const char kRevertTranslation
[] = "Translate.RevertTranslation";
23 const char kPerformTranslate
[] = "Translate.Translate";
24 const char kNeverTranslateLang
[] = "Translate.NeverTranslateLang";
25 const char kNeverTranslateSite
[] = "Translate.NeverTranslateSite";
26 const char kAlwaysTranslateLang
[] = "Translate.AlwaysTranslateLang";
27 const char kModifyOriginalLang
[] = "Translate.ModifyOriginalLang";
28 const char kModifyTargetLang
[] = "Translate.ModifyTargetLang";
29 const char kDeclineTranslateDismissUI
[] = "Translate.DeclineTranslateDismissUI";
30 const char kShowErrorUI
[] = "Translate.ShowErrorUI";
36 TranslateUIDelegate::TranslateUIDelegate(
37 const base::WeakPtr
<TranslateManager
>& translate_manager
,
38 const std::string
& original_language
,
39 const std::string
& target_language
)
41 translate_manager
->translate_client()->GetTranslateDriver()),
42 translate_manager_(translate_manager
),
43 original_language_index_(kNoIndex
),
44 initial_original_language_index_(kNoIndex
),
45 target_language_index_(kNoIndex
) {
46 DCHECK(translate_driver_
);
47 DCHECK(translate_manager_
);
49 std::vector
<std::string
> language_codes
;
50 TranslateDownloadManager::GetSupportedLanguages(&language_codes
);
52 // Preparing for the alphabetical order in the locale.
53 UErrorCode error
= U_ZERO_ERROR
;
55 TranslateDownloadManager::GetInstance()->application_locale();
56 icu::Locale
loc(locale
.c_str());
57 scoped_ptr
<icu::Collator
> collator(icu::Collator::createInstance(loc
, error
));
58 collator
->setStrength(icu::Collator::PRIMARY
);
60 languages_
.reserve(language_codes
.size());
61 for (std::vector
<std::string
>::const_iterator iter
= language_codes
.begin();
62 iter
!= language_codes
.end();
64 std::string language_code
= *iter
;
66 base::string16 language_name
=
67 l10n_util::GetDisplayNameForLocale(language_code
, locale
, true);
68 // Insert the language in languages_ in alphabetical order.
69 std::vector
<LanguageNamePair
>::iterator iter2
;
70 for (iter2
= languages_
.begin(); iter2
!= languages_
.end(); ++iter2
) {
71 if (base::i18n::CompareString16WithCollator(
72 collator
.get(), language_name
, iter2
->second
) == UCOL_LESS
) {
76 languages_
.insert(iter2
, LanguageNamePair(language_code
, language_name
));
78 for (std::vector
<LanguageNamePair
>::const_iterator iter
= languages_
.begin();
79 iter
!= languages_
.end();
81 std::string language_code
= iter
->first
;
82 if (language_code
== original_language
) {
83 original_language_index_
= iter
- languages_
.begin();
84 initial_original_language_index_
= original_language_index_
;
86 if (language_code
== target_language
)
87 target_language_index_
= iter
- languages_
.begin();
90 prefs_
= translate_manager_
->translate_client()->GetTranslatePrefs();
93 TranslateUIDelegate::~TranslateUIDelegate() {}
95 void TranslateUIDelegate::OnErrorShown(TranslateErrors::Type error_type
) {
96 DCHECK_LE(TranslateErrors::NONE
, error_type
);
97 DCHECK_LT(error_type
, TranslateErrors::TRANSLATE_ERROR_MAX
);
99 if (error_type
== TranslateErrors::NONE
)
102 UMA_HISTOGRAM_ENUMERATION(
103 kShowErrorUI
, error_type
, TranslateErrors::TRANSLATE_ERROR_MAX
);
106 const LanguageState
& TranslateUIDelegate::GetLanguageState() {
107 return translate_manager_
->GetLanguageState();
110 size_t TranslateUIDelegate::GetNumberOfLanguages() const {
111 return languages_
.size();
114 size_t TranslateUIDelegate::GetOriginalLanguageIndex() const {
115 return original_language_index_
;
118 void TranslateUIDelegate::UpdateOriginalLanguageIndex(size_t language_index
) {
119 if (original_language_index_
== language_index
)
122 UMA_HISTOGRAM_BOOLEAN(kModifyOriginalLang
, true);
123 original_language_index_
= language_index
;
126 size_t TranslateUIDelegate::GetTargetLanguageIndex() const {
127 return target_language_index_
;
130 void TranslateUIDelegate::UpdateTargetLanguageIndex(size_t language_index
) {
131 if (target_language_index_
== language_index
)
134 DCHECK_LT(language_index
, GetNumberOfLanguages());
135 UMA_HISTOGRAM_BOOLEAN(kModifyTargetLang
, true);
136 target_language_index_
= language_index
;
139 std::string
TranslateUIDelegate::GetLanguageCodeAt(size_t index
) const {
140 DCHECK_LT(index
, GetNumberOfLanguages());
141 return languages_
[index
].first
;
144 base::string16
TranslateUIDelegate::GetLanguageNameAt(size_t index
) const {
145 if (index
== kNoIndex
)
146 return base::string16();
147 DCHECK_LT(index
, GetNumberOfLanguages());
148 return languages_
[index
].second
;
151 std::string
TranslateUIDelegate::GetOriginalLanguageCode() const {
152 return (GetOriginalLanguageIndex() == kNoIndex
) ?
153 translate::kUnknownLanguageCode
:
154 GetLanguageCodeAt(GetOriginalLanguageIndex());
157 std::string
TranslateUIDelegate::GetTargetLanguageCode() const {
158 return GetLanguageCodeAt(GetTargetLanguageIndex());
161 void TranslateUIDelegate::Translate() {
162 if (!translate_driver_
->IsOffTheRecord()) {
163 prefs_
->ResetTranslationDeniedCount(GetOriginalLanguageCode());
164 prefs_
->IncrementTranslationAcceptedCount(GetOriginalLanguageCode());
167 if (translate_manager_
) {
168 translate_manager_
->TranslatePage(
169 GetOriginalLanguageCode(), GetTargetLanguageCode(), false);
170 UMA_HISTOGRAM_BOOLEAN(kPerformTranslate
, true);
174 void TranslateUIDelegate::RevertTranslation() {
175 if (translate_manager_
) {
176 translate_manager_
->RevertTranslation();
177 UMA_HISTOGRAM_BOOLEAN(kRevertTranslation
, true);
181 void TranslateUIDelegate::TranslationDeclined(bool explicitly_closed
) {
182 if (!translate_driver_
->IsOffTheRecord()) {
183 prefs_
->ResetTranslationAcceptedCount(GetOriginalLanguageCode());
184 prefs_
->IncrementTranslationDeniedCount(GetOriginalLanguageCode());
185 prefs_
->UpdateLastDeniedTime();
188 // Remember that the user declined the translation so as to prevent showing a
189 // translate UI for that page again. (TranslateManager initiates translations
190 // when getting a LANGUAGE_DETERMINED from the page, which happens when a load
191 // stops. That could happen multiple times, including after the user already
192 // declined the translation.)
193 if (translate_manager_
) {
194 translate_manager_
->GetLanguageState().set_translation_declined(true);
195 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate
, true);
198 if (!explicitly_closed
)
199 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslateDismissUI
, true);
202 bool TranslateUIDelegate::IsLanguageBlocked() {
203 return prefs_
->IsBlockedLanguage(GetOriginalLanguageCode());
206 void TranslateUIDelegate::SetLanguageBlocked(bool value
) {
208 prefs_
->BlockLanguage(GetOriginalLanguageCode());
209 if (translate_manager_
) {
210 translate_manager_
->GetLanguageState().SetTranslateEnabled(false);
213 prefs_
->UnblockLanguage(GetOriginalLanguageCode());
216 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang
, true);
219 bool TranslateUIDelegate::IsSiteBlacklisted() {
220 std::string host
= GetPageHost();
221 return !host
.empty() && prefs_
->IsSiteBlacklisted(host
);
224 void TranslateUIDelegate::SetSiteBlacklist(bool value
) {
225 std::string host
= GetPageHost();
230 prefs_
->BlacklistSite(host
);
231 if (translate_manager_
) {
232 translate_manager_
->GetLanguageState().SetTranslateEnabled(false);
235 prefs_
->RemoveSiteFromBlacklist(host
);
238 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite
, true);
241 bool TranslateUIDelegate::ShouldAlwaysTranslate() {
242 return prefs_
->IsLanguagePairWhitelisted(GetOriginalLanguageCode(),
243 GetTargetLanguageCode());
246 void TranslateUIDelegate::SetAlwaysTranslate(bool value
) {
247 const std::string
& original_lang
= GetOriginalLanguageCode();
248 const std::string
& target_lang
= GetTargetLanguageCode();
250 prefs_
->WhitelistLanguagePair(original_lang
, target_lang
);
252 prefs_
->RemoveLanguagePairFromWhitelist(original_lang
, target_lang
);
254 UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang
, true);
257 std::string
TranslateUIDelegate::GetPageHost() {
258 if (!translate_driver_
->HasCurrentPage())
259 return std::string();
260 return translate_driver_
->GetActiveURL().HostNoBrackets();
263 } // namespace translate