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.
4
5#ifndef COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_INFOBAR_DELEGATE_H_
6#define COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_INFOBAR_DELEGATE_H_
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include "base/logging.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/weak_ptr.h"
15#include "components/infobars/core/infobar_delegate.h"
16#include "components/translate/core/browser/translate_prefs.h"
17#include "components/translate/core/browser/translate_step.h"
18#include "components/translate/core/browser/translate_ui_delegate.h"
19#include "components/translate/core/common/translate_constants.h"
20#include "components/translate/core/common/translate_errors.h"
21
22namespace infobars {
23class InfoBarManager;
24}
25
26namespace translate {
27
28class TranslateClient;
29class TranslateDriver;
30class TranslateManager;
31
32class TranslateInfoBarDelegate : public infobars::InfoBarDelegate {
33 public:
34  // The types of background color animations.
35  enum BackgroundAnimationType {
36    NONE,
37    NORMAL_TO_ERROR,
38    ERROR_TO_NORMAL
39  };
40
41  static const size_t kNoIndex;
42
43  virtual ~TranslateInfoBarDelegate();
44
45  // Factory method to create a translate infobar.  |error_type| must be
46  // specified iff |step| == TRANSLATION_ERROR.  For other translate steps,
47  // |original_language| and |target_language| must be ASCII language codes
48  // (e.g. "en", "fr", etc.) for languages the TranslateManager supports
49  // translating.  The lone exception is when the user initiates translation
50  // from the context menu, in which case it's legal to call this with
51  // |step| == TRANSLATING and |original_language| == kUnknownLanguageCode.
52  //
53  // If |replace_existing_infobar| is true, the infobar is created and added to
54  // the infobar manager, replacing any other translate infobar already present
55  // there.  Otherwise, the infobar will only be added if there is no other
56  // translate infobar already present.
57  static void Create(bool replace_existing_infobar,
58                     const base::WeakPtr<TranslateManager>& translate_manager,
59                     infobars::InfoBarManager* infobar_manager,
60                     bool is_off_the_record,
61                     translate::TranslateStep step,
62                     const std::string& original_language,
63                     const std::string& target_language,
64                     TranslateErrors::Type error_type,
65                     bool triggered_from_menu);
66
67  // Returns the number of languages supported.
68  size_t num_languages() const { return ui_delegate_.GetNumberOfLanguages(); }
69
70  // Returns the ISO code for the language at |index|.
71  std::string language_code_at(size_t index) const {
72    return ui_delegate_.GetLanguageCodeAt(index);
73  }
74
75  // Returns the displayable name for the language at |index|.
76  base::string16 language_name_at(size_t index) const {
77    return ui_delegate_.GetLanguageNameAt(index);
78  }
79
80  translate::TranslateStep translate_step() const { return step_; }
81
82  bool is_off_the_record() { return is_off_the_record_; }
83
84  TranslateErrors::Type error_type() const { return error_type_; }
85
86  size_t original_language_index() const {
87    return ui_delegate_.GetOriginalLanguageIndex();
88  }
89  void UpdateOriginalLanguageIndex(size_t language_index);
90
91  size_t target_language_index() const {
92    return ui_delegate_.GetTargetLanguageIndex();
93  }
94  void UpdateTargetLanguageIndex(size_t language_index);
95
96  // Convenience methods.
97  std::string original_language_code() const {
98    return ui_delegate_.GetOriginalLanguageCode();
99  }
100  std::string target_language_code() const {
101    return ui_delegate_.GetTargetLanguageCode();
102  }
103
104  // Returns true if the current infobar indicates an error (in which case it
105  // should get a yellow background instead of a blue one).
106  bool is_error() const {
107    return step_ == translate::TRANSLATE_STEP_TRANSLATE_ERROR;
108  }
109
110  // Return true if the translation was triggered by a menu entry instead of
111  // via an infobar/bubble or preference.
112  bool triggered_from_menu() const {
113    return triggered_from_menu_;
114  }
115
116  // Returns what kind of background fading effect the infobar should use when
117  // its is shown.
118  BackgroundAnimationType background_animation_type() const {
119    return background_animation_;
120  }
121
122  virtual void Translate();
123  virtual void RevertTranslation();
124  void ReportLanguageDetectionError();
125
126  // Called when the user declines to translate a page, by either closing the
127  // infobar or pressing the "Don't translate" button.
128  virtual void TranslationDeclined();
129
130  // Methods called by the Options menu delegate.
131  virtual bool IsTranslatableLanguageByPrefs();
132  virtual void ToggleTranslatableLanguageByPrefs();
133  virtual bool IsSiteBlacklisted();
134  virtual void ToggleSiteBlacklist();
135  virtual bool ShouldAlwaysTranslate();
136  virtual void ToggleAlwaysTranslate();
137
138  // Methods called by the extra-buttons that can appear on the "before
139  // translate" infobar (when the user has accepted/declined the translation
140  // several times).
141  void AlwaysTranslatePageLanguage();
142  void NeverTranslatePageLanguage();
143
144  // The following methods are called by the infobar that displays the status
145  // while translating and also the one displaying the error message.
146  base::string16 GetMessageInfoBarText();
147  base::string16 GetMessageInfoBarButtonText();
148  void MessageInfoBarButtonPressed();
149  bool ShouldShowMessageInfoBarButton();
150
151  // Called by the before translate infobar to figure-out if it should show
152  // an extra shortcut to let the user black-list/white-list that language
153  // (based on how many times the user accepted/declined translation).
154  // The shortcut itself is platform specific, it can be a button or a new bar
155  // for example.
156  bool ShouldShowNeverTranslateShortcut();
157  bool ShouldShowAlwaysTranslateShortcut();
158
159  // Adds the strings that should be displayed in the after translate infobar to
160  // |strings|. If |autodetermined_source_language| is false, the text in that
161  // infobar is:
162  // "The page has been translated from <lang1> to <lang2>."
163  // Otherwise:
164  // "The page has been translated to <lang1>."
165  // Because <lang1>, or <lang1> and <lang2> are displayed in menu buttons, the
166  // text is split in 2 or 3 chunks. |swap_languages| is set to true if
167  // |autodetermined_source_language| is false, and <lang1> and <lang2>
168  // should be inverted (some languages express the sentense as "The page has
169  // been translate to <lang2> from <lang1>."). It is ignored if
170  // |autodetermined_source_language| is true.
171  static void GetAfterTranslateStrings(std::vector<base::string16>* strings,
172                                       bool* swap_languages,
173                                       bool autodetermined_source_language);
174
175  // Gets the TranslateDriver associated with this object.
176  // May return NULL if the driver has been destroyed.
177  TranslateDriver* GetTranslateDriver();
178
179 protected:
180  TranslateInfoBarDelegate(
181      const base::WeakPtr<TranslateManager>& translate_manager,
182      bool is_off_the_record,
183      translate::TranslateStep step,
184      TranslateInfoBarDelegate* old_delegate,
185      const std::string& original_language,
186      const std::string& target_language,
187      TranslateErrors::Type error_type,
188      bool triggered_from_menu);
189
190 private:
191  friend class TranslationInfoBarTest;
192  typedef std::pair<std::string, base::string16> LanguageNamePair;
193
194  // InfoBarDelegate:
195  virtual void InfoBarDismissed() OVERRIDE;
196  virtual int GetIconID() const OVERRIDE;
197  virtual infobars::InfoBarDelegate::Type GetInfoBarType() const OVERRIDE;
198  virtual bool ShouldExpire(const NavigationDetails& details) const OVERRIDE;
199  virtual TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() OVERRIDE;
200
201  bool is_off_the_record_;
202  translate::TranslateStep step_;
203
204  // The type of fading animation if any that should be used when showing this
205  // infobar.
206  BackgroundAnimationType background_animation_;
207
208  TranslateUIDelegate ui_delegate_;
209  base::WeakPtr<TranslateManager> translate_manager_;
210
211  // The error that occurred when trying to translate (NONE if no error).
212  TranslateErrors::Type error_type_;
213
214  // The translation related preferences.
215  scoped_ptr<TranslatePrefs> prefs_;
216
217  // Whether the translation was triggered via a menu click vs automatically
218  // (due to language detection, preferences...)
219  bool triggered_from_menu_;
220  DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarDelegate);
221};
222
223}  // namespace translate
224
225#endif  // COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_INFOBAR_DELEGATE_H_
226