1// Copyright (c) 2011 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#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBAR_DELEGATE_H_
6#define CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBAR_DELEGATE_H_
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include "base/compiler_specific.h"
13#include "base/logging.h"
14#include "chrome/browser/infobars/infobar_delegate.h"
15#include "chrome/browser/translate/translate_prefs.h"
16#include "chrome/common/chrome_constants.h"
17#include "chrome/common/translate/translate_errors.h"
18
19class PrefService;
20
21// The defaults after which extra shortcuts for options
22// can be shown.
23struct ShortcutConfiguration {
24  int always_translate_min_count;
25  int never_translate_min_count;
26};
27
28class TranslateInfoBarDelegate : public InfoBarDelegate {
29 public:
30  // The different types of infobars that can be shown for translation.
31  enum Type {
32    BEFORE_TRANSLATE,
33    TRANSLATING,
34    AFTER_TRANSLATE,
35    TRANSLATION_ERROR
36  };
37
38  // The types of background color animations.
39  enum BackgroundAnimationType {
40    NONE,
41    NORMAL_TO_ERROR,
42    ERROR_TO_NORMAL
43  };
44
45  static const size_t kNoIndex;
46
47  virtual ~TranslateInfoBarDelegate();
48
49  // Factory method to create a translate infobar.  |error_type| must be
50  // specified iff |infobar_type| == TRANSLATION_ERROR.  For other infobar
51  // types, |original_language| and |target_language| must be ASCII language
52  // codes (e.g. "en", "fr", etc.) for languages the TranslateManager supports
53  // translating.  The lone exception is when the user initiates translation
54  // from the context menu, in which case it's legal to call this with
55  // |infobar_type| == TRANSLATING and
56  // |original_language| == kUnknownLanguageCode.
57  //
58  // If |replace_existing_infobar| is true, the infobar is created and added to
59  // |infobar_service|, replacing any other translate infobar already present
60  // there.  Otherwise, the infobar will only be added if there is no other
61  // translate infobar already present.
62  static void Create(bool replace_existing_infobar,
63                     InfoBarService* infobar_service,
64                     Type infobar_type,
65                     const std::string& original_language,
66                     const std::string& target_language,
67                     TranslateErrors::Type error_type,
68                     PrefService* prefs,
69                     const ShortcutConfiguration& shortcut_config);
70
71  // Returns the number of languages supported.
72  size_t num_languages() const { return languages_.size(); }
73
74  // Returns the ISO code for the language at |index|.
75  std::string language_code_at(size_t index) const {
76    DCHECK_LT(index, num_languages());
77    return languages_[index].first;
78  }
79
80  // Returns the displayable name for the language at |index|.
81  string16 language_name_at(size_t index) const {
82    if (index == kNoIndex)
83      return string16();
84    DCHECK_LT(index, num_languages());
85    return languages_[index].second;
86  }
87
88  Type infobar_type() const { return infobar_type_; }
89
90  TranslateErrors::Type error_type() const { return error_type_; }
91
92  size_t original_language_index() const { return original_language_index_; }
93  void set_original_language_index(size_t language_index) {
94    DCHECK_LT(language_index, num_languages());
95    original_language_index_ = language_index;
96  }
97  size_t target_language_index() const { return target_language_index_; }
98  void set_target_language_index(size_t language_index) {
99    DCHECK_LT(language_index, num_languages());
100    target_language_index_ = language_index;
101  }
102
103  // Convenience methods.
104  std::string original_language_code() const {
105    return (original_language_index() == kNoIndex) ?
106        chrome::kUnknownLanguageCode :
107        language_code_at(original_language_index());
108  }
109  std::string target_language_code() const {
110    return language_code_at(target_language_index());
111  }
112
113  // Returns true if the current infobar indicates an error (in which case it
114  // should get a yellow background instead of a blue one).
115  bool is_error() const { return infobar_type_ == TRANSLATION_ERROR; }
116
117  // Returns what kind of background fading effect the infobar should use when
118  // its is shown.
119  BackgroundAnimationType background_animation_type() const {
120    return background_animation_;
121  }
122
123  virtual void Translate();
124  virtual void RevertTranslation();
125  void ReportLanguageDetectionError();
126
127  // Called when the user declines to translate a page, by either closing the
128  // infobar or pressing the "Don't translate" button.
129  virtual void TranslationDeclined();
130
131  // Methods called by the Options menu delegate.
132  virtual bool IsTranslatableLanguageByPrefs();
133  virtual void ToggleTranslatableLanguageByPrefs();
134  virtual bool IsSiteBlacklisted();
135  virtual void ToggleSiteBlacklist();
136  virtual bool ShouldAlwaysTranslate();
137  virtual void ToggleAlwaysTranslate();
138
139  // Methods called by the extra-buttons that can appear on the "before
140  // translate" infobar (when the user has accepted/declined the translation
141  // several times).
142  void AlwaysTranslatePageLanguage();
143  void NeverTranslatePageLanguage();
144
145  // The following methods are called by the infobar that displays the status
146  // while translating and also the one displaying the error message.
147  string16 GetMessageInfoBarText();
148  string16 GetMessageInfoBarButtonText();
149  void MessageInfoBarButtonPressed();
150  bool ShouldShowMessageInfoBarButton();
151
152  // Called by the before translate infobar to figure-out if it should show
153  // an extra shortcut to let the user black-list/white-list that language
154  // (based on how many times the user accepted/declined translation).
155  // The shortcut itself is platform specific, it can be a button or a new bar
156  // for example.
157  bool ShouldShowNeverTranslateShortcut();
158  bool ShouldShowAlwaysTranslateShortcut();
159
160  // Convenience method that returns the displayable language name for
161  // |language_code| in the current application locale.
162  static string16 GetLanguageDisplayableName(const std::string& language_code);
163
164  // Adds the strings that should be displayed in the after translate infobar to
165  // |strings|. If |autodetermined_source_language| is false, the text in that
166  // infobar is:
167  // "The page has been translated from <lang1> to <lang2>."
168  // Otherwise:
169  // "The page has been translated to <lang1>."
170  // Because <lang1>, or <lang1> and <lang2> are displayed in menu buttons, the
171  // text is split in 2 or 3 chunks. |swap_languages| is set to true if
172  // |autodetermined_source_language| is false, and <lang1> and <lang2>
173  // should be inverted (some languages express the sentense as "The page has
174  // been translate to <lang2> from <lang1>."). It is ignored if
175  // |autodetermined_source_language| is true.
176  static void GetAfterTranslateStrings(std::vector<string16>* strings,
177                                       bool* swap_languages,
178                                       bool autodetermined_source_language);
179
180 protected:
181  TranslateInfoBarDelegate(InfoBarService* infobar_service,
182                           Type infobar_type,
183                           TranslateInfoBarDelegate* old_delegate,
184                           const std::string& original_language,
185                           const std::string& target_language,
186                           TranslateErrors::Type error_type,
187                           PrefService* prefs,
188                           ShortcutConfiguration shortcut_config);
189
190 private:
191  typedef std::pair<std::string, string16> LanguageNamePair;
192
193  // InfoBarDelegate:
194  virtual InfoBar* CreateInfoBar(InfoBarService* infobar_service) OVERRIDE;
195  virtual void InfoBarDismissed() OVERRIDE;
196  virtual int GetIconID() const OVERRIDE;
197  virtual InfoBarDelegate::Type GetInfoBarType() const OVERRIDE;
198  virtual bool ShouldExpire(
199       const content::LoadCommittedDetails& details) const OVERRIDE;
200  virtual TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() OVERRIDE;
201
202  // Gets the host of the page being translated, or an empty string if no URL is
203  // associated with the current page.
204  std::string GetPageHost();
205
206  Type infobar_type_;
207
208  // The type of fading animation if any that should be used when showing this
209  // infobar.
210  BackgroundAnimationType background_animation_;
211
212  // The list supported languages for translation.
213  // The pair first string is the language ISO code (ex: en, fr...), the second
214  // string is the displayable name on the current locale.
215  // The languages are sorted alphabetically based on the displayable name.
216  std::vector<LanguageNamePair> languages_;
217
218  // The index for language the page is originally in.
219  size_t original_language_index_;
220
221  // The index for language the page is originally in that was originally
222  // reported (original_language_index_ changes if the user selects a new
223  // original language, but this one does not).  This is necessary to report
224  // language detection errors with the right original language even if the user
225  // changed the original language.
226  size_t initial_original_language_index_;
227
228  // The index for language the page should be translated to.
229  size_t target_language_index_;
230
231  // The error that occurred when trying to translate (NONE if no error).
232  TranslateErrors::Type error_type_;
233
234  // The translation related preferences.
235  TranslatePrefs prefs_;
236
237  // Translation shortcut configuration
238  ShortcutConfiguration shortcut_config_;
239  DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarDelegate);
240};
241
242#endif  // CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBAR_DELEGATE_H_
243