summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-04 21:37:53 +0000
committerkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-04 21:37:53 +0000
commit5fd00714eb3eed6f6cc8dcc8d310dbc18f42059f (patch)
treeec79e4150383891307895bc6ee7f240e3102a979 /chrome
parent5638498ac845b895d35158a4e703949d83497744 (diff)
downloadchromium_src-5fd00714eb3eed6f6cc8dcc8d310dbc18f42059f.zip
chromium_src-5fd00714eb3eed6f6cc8dcc8d310dbc18f42059f.tar.gz
chromium_src-5fd00714eb3eed6f6cc8dcc8d310dbc18f42059f.tar.bz2
merge translate infobars from trunk to branch 249
- merge is completely manual with quite some changes to code; practically a new changelist is created based on changelists committed on trunk. - code that calls backend is currently blocked with TODO for jay to unblock when he merges the backend. BUG=31297 TEST=none for now. Review URL: http://codereview.chromium.org/563026 git-svn-id: svn://svn.chromium.org/chrome/branches/249/src@38134 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/chrome_dll_resource.h11
-rw-r--r--chrome/app/resources/locale_settings.grd5
-rw-r--r--chrome/browser/tab_contents/infobar_delegate.h10
-rw-r--r--chrome/browser/translate/languages_menu_model.cc33
-rw-r--r--chrome/browser/translate/languages_menu_model.h24
-rw-r--r--chrome/browser/translate/options_menu_model.cc40
-rw-r--r--chrome/browser/translate/options_menu_model.h24
-rw-r--r--chrome/browser/translate/translate_infobars_delegates.cc212
-rw-r--r--chrome/browser/translate/translate_infobars_delegates.h122
-rw-r--r--chrome/browser/translate/translate_prefs.cc171
-rw-r--r--chrome/browser/translate/translate_prefs.h51
-rw-r--r--chrome/browser/views/infobars/infobars.cc60
-rw-r--r--chrome/browser/views/infobars/infobars.h17
-rw-r--r--chrome/browser/views/infobars/translate_infobars.cc606
-rw-r--r--chrome/browser/views/infobars/translate_infobars.h146
-rwxr-xr-xchrome/chrome.gyp10
16 files changed, 1511 insertions, 31 deletions
diff --git a/chrome/app/chrome_dll_resource.h b/chrome/app/chrome_dll_resource.h
index be95402..84be54a 100644
--- a/chrome/app/chrome_dll_resource.h
+++ b/chrome/app/chrome_dll_resource.h
@@ -223,13 +223,22 @@
#define IDC_CHECK_SPELLING_OF_THIS_FIELD 41107
#define IDC_SYNC_BOOKMARKS 41108
#define IDC_SPELLPANEL_TOGGLE 41109
+
+// Translate
+#define IDC_TRANSLATE_OPTIONS_ALWAYS 42000
+#define IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG 42001
+#define IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE 42002
+#define IDC_TRANSLATE_OPTIONS_ABOUT 42003
+#define IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE 42100
+#define IDC_TRANSLATE_TARGET_LANGUAGE_BASE 42400
+
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 3001
-#define _APS_NEXT_COMMAND_VALUE 42000
+#define _APS_NEXT_COMMAND_VALUE 43000
#define _APS_NEXT_CONTROL_VALUE 4017
#define _APS_NEXT_SYMED_VALUE 1001
#endif
diff --git a/chrome/app/resources/locale_settings.grd b/chrome/app/resources/locale_settings.grd
index db478fa..b778b0d 100644
--- a/chrome/app/resources/locale_settings.grd
+++ b/chrome/app/resources/locale_settings.grd
@@ -735,6 +735,11 @@
4
</message>
+ <!-- The URL for About Google Translate. -->
+ <message name="IDS_ABOUT_GOOGLE_TRANSLATE_URL" translateable="false">
+ http://www.google.com/support/chrome/bin/answer.py?answer=173424&amp;hl=[GRITLANGCODE]
+ </message>
+
<!-- The width and height of the Content Settings Exceptions dialog box in -->
<!-- characters and lines (See above). -->
<message name="IDS_CONTENT_EXCEPTION_DIALOG_WIDTH_CHARS" use_name_for_id="true">
diff --git a/chrome/browser/tab_contents/infobar_delegate.h b/chrome/browser/tab_contents/infobar_delegate.h
index d6a1899..4e37848 100644
--- a/chrome/browser/tab_contents/infobar_delegate.h
+++ b/chrome/browser/tab_contents/infobar_delegate.h
@@ -15,6 +15,7 @@ class AlertInfoBarDelegate;
class ConfirmInfoBarDelegate;
class InfoBar;
class LinkInfoBarDelegate;
+class TranslateInfoBarDelegate;
class SkBitmap;
class ThemeInstalledInfoBarDelegate;
@@ -47,7 +48,8 @@ class InfoBarDelegate {
enum Type {
INFO_TYPE,
WARNING_TYPE,
- ERROR_TYPE
+ ERROR_TYPE,
+ PAGE_ACTION_TYPE
};
// Returns true if the supplied |delegate| is equal to this one. Equality is
@@ -102,6 +104,12 @@ class InfoBarDelegate {
return NULL;
}
+ // Returns a pointer to the TranslateInfoBarDelegate interface, if
+ // implemented.
+ virtual TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() {
+ return NULL;
+ }
+
// Returns the type of the infobar. The type determines the appearance (such
// as background color) of the infobar.
virtual Type GetInfoBarType() {
diff --git a/chrome/browser/translate/languages_menu_model.cc b/chrome/browser/translate/languages_menu_model.cc
new file mode 100644
index 0000000..f05292b
--- /dev/null
+++ b/chrome/browser/translate/languages_menu_model.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/translate/languages_menu_model.h"
+
+#include "base/string_util.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/translate/translate_infobars_delegates.h"
+
+LanguagesMenuModel::LanguagesMenuModel(
+ views::SimpleMenuModel::Delegate* menu_delegate,
+ TranslateInfoBarDelegate* translate_delegate,
+ bool original_language)
+ : views::SimpleMenuModel(menu_delegate) {
+ std::vector<std::string> languages;
+ int base_command_id = 0;
+ if (original_language) {
+ base_command_id = IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE;
+ translate_delegate->GetAvailableOriginalLanguages(&languages);
+ } else {
+ base_command_id = IDC_TRANSLATE_TARGET_LANGUAGE_BASE;
+ translate_delegate->GetAvailableTargetLanguages(&languages);
+ }
+ std::vector<std::string>::const_iterator iter = languages.begin();
+ for (int i = base_command_id; iter != languages.end(); ++i, ++iter) {
+ AddItem(i, TranslateInfoBarDelegate::GetDisplayNameForLocale(*iter));
+ }
+}
+
+LanguagesMenuModel::~LanguagesMenuModel() {
+}
+
diff --git a/chrome/browser/translate/languages_menu_model.h b/chrome/browser/translate/languages_menu_model.h
new file mode 100644
index 0000000..1434aa3
--- /dev/null
+++ b/chrome/browser/translate/languages_menu_model.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef CHROME_BROWSER_TRANSLATE_LANGUAGES_MENU_MODEL_H_
+#define CHROME_BROWSER_TRANSLATE_LANGUAGES_MENU_MODEL_H_
+
+#include "views/controls/menu/simple_menu_model.h"
+
+class TranslateInfoBarDelegate;
+
+// A menu model that builds the contents of the language menus in the translate
+// infobar, i.e. the original and target languages.
+class LanguagesMenuModel : public views::SimpleMenuModel {
+ public:
+ explicit LanguagesMenuModel(views::SimpleMenuModel::Delegate* menu_delegate,
+ TranslateInfoBarDelegate* translate_delegate, bool original_language);
+ virtual ~LanguagesMenuModel();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LanguagesMenuModel);
+};
+
+#endif // CHROME_BROWSER_TRANSLATE_LANGUAGES_MENU_MODEL_H_
diff --git a/chrome/browser/translate/options_menu_model.cc b/chrome/browser/translate/options_menu_model.cc
new file mode 100644
index 0000000..4a663f8
--- /dev/null
+++ b/chrome/browser/translate/options_menu_model.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/translate/options_menu_model.h"
+
+#include "app/l10n_util.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/translate/translate_infobars_delegates.h"
+#include "grit/generated_resources.h"
+
+OptionsMenuModel::OptionsMenuModel(views::SimpleMenuModel::Delegate* delegate,
+ TranslateInfoBarDelegate* translate_delegate, bool before_translate)
+ : views::SimpleMenuModel(delegate) {
+ string16 original_language =
+ TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ translate_delegate->original_lang_code());
+ if (before_translate) {
+ AddCheckItem(IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG,
+ l10n_util::GetStringFUTF16(
+ IDS_TRANSLATE_INFOBAR_OPTIONS_NEVER_TRANSLATE_LANG,
+ original_language));
+ AddCheckItem(IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE,
+ l10n_util::GetStringUTF16(
+ IDS_TRANSLATE_INFOBAR_OPTIONS_NEVER_TRANSLATE_SITE));
+ } else {
+ string16 target_language =
+ TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ translate_delegate->target_lang_code());
+ AddCheckItem(IDC_TRANSLATE_OPTIONS_ALWAYS,
+ l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS_ALWAYS,
+ original_language, target_language));
+ }
+ AddItemWithStringId(IDC_TRANSLATE_OPTIONS_ABOUT,
+ IDS_TRANSLATE_INFOBAR_OPTIONS_ABOUT);
+}
+
+OptionsMenuModel::~OptionsMenuModel() {
+}
+
diff --git a/chrome/browser/translate/options_menu_model.h b/chrome/browser/translate/options_menu_model.h
new file mode 100644
index 0000000..c43eb25
--- /dev/null
+++ b/chrome/browser/translate/options_menu_model.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef CHROME_BROWSER_TRANSLATE_OPTIONS_MENU_MODEL_H_
+#define CHROME_BROWSER_TRANSLATE_OPTIONS_MENU_MODEL_H_
+
+#include "views/controls/menu/simple_menu_model.h"
+
+class TranslateInfoBarDelegate;
+
+// A menu model that builds the contents of the options menu in the translate
+// infobar. This menu has only one level (no submenus).
+class OptionsMenuModel : public views::SimpleMenuModel {
+ public:
+ explicit OptionsMenuModel(views::SimpleMenuModel::Delegate* menu_delegate,
+ TranslateInfoBarDelegate* translate_delegate, bool before_translate);
+ virtual ~OptionsMenuModel();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OptionsMenuModel);
+};
+
+#endif // CHROME_BROWSER_TRANSLATE_OPTIONS_MENU_MODEL_H_
diff --git a/chrome/browser/translate/translate_infobars_delegates.cc b/chrome/browser/translate/translate_infobars_delegates.cc
new file mode 100644
index 0000000..9a457b1
--- /dev/null
+++ b/chrome/browser/translate/translate_infobars_delegates.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/translate/translate_infobars_delegates.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "chrome/browser/browser_process.h"
+// TODO(jcampan): unblock when backend is merged in.
+// #include "chrome/browser/renderer_host/translation_service.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+
+// TranslateInfoBarDelegate: InfoBarDelegate overrides: ------------------------
+
+SkBitmap* TranslateInfoBarDelegate::GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_TRANSLATE);
+}
+
+bool TranslateInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
+ TranslateInfoBarDelegate* translate_delegate =
+ delegate->AsTranslateInfoBarDelegate();
+ // There can be only 1 translate infobar at any one time.
+ return (!!translate_delegate);
+}
+
+void TranslateInfoBarDelegate::InfoBarClosed() {
+ delete this;
+}
+
+// TranslateInfoBarDelegate: public: -------------------------------------------
+
+void TranslateInfoBarDelegate::ModifyOriginalLanguage(int lang_index) {
+ original_lang_index_ = lang_index;
+ // TODO(kuan): Send stats to Google Translate that original language has been
+ // modified.
+}
+
+void TranslateInfoBarDelegate::ModifyTargetLanguage(int lang_index) {
+ NOTREACHED() << "Subclass should override";
+}
+
+void TranslateInfoBarDelegate::GetAvailableOriginalLanguages(
+ std::vector<std::string>* languages) {
+ // TODO(jcampan): unblock when backend is merged in.
+ // TranslationService::GetSupportedLanguages(languages);
+}
+
+void TranslateInfoBarDelegate::GetAvailableTargetLanguages(
+ std::vector<std::string>* languages) {
+ NOTREACHED() << "Subclass should override";
+}
+
+void TranslateInfoBarDelegate::Translate() {
+ // TODO(jcampan): unblock when backend is merged in.
+ /*
+ if (original_lang_index_ != target_lang_index_)
+ tab_contents_->TranslatePage(original_lang_code(), target_lang_code());
+ */
+}
+
+bool TranslateInfoBarDelegate::IsLanguageBlacklisted() {
+ NOTREACHED() << "Subclass should override";
+ return false;
+}
+
+bool TranslateInfoBarDelegate::IsSiteBlacklisted() {
+ NOTREACHED() << "Subclass should override";
+ return false;
+}
+
+bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() {
+ NOTREACHED() << "Subclass should override";
+ return false;
+}
+
+void TranslateInfoBarDelegate::ToggleLanguageBlacklist() {
+ NOTREACHED() << "Subclass should override";
+}
+
+void TranslateInfoBarDelegate::ToggleSiteBlacklist() {
+ NOTREACHED() << "Subclass should override";
+}
+
+void TranslateInfoBarDelegate::ToggleAlwaysTranslate() {
+ NOTREACHED() << "Subclass should override";
+}
+
+// TranslateInfoBarDelegate: static: -------------------------------------------
+
+string16 TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ const std::string& language_code) {
+ return l10n_util::GetDisplayNameForLocale(
+ language_code, g_browser_process->GetApplicationLocale(), true);
+}
+
+// TranslateInfoBarDelegate: protected: ----------------------------------------
+
+TranslateInfoBarDelegate::TranslateInfoBarDelegate(TabContents* tab_contents,
+ PrefService* user_prefs, const std::string& original_lang_code,
+ const std::string& target_lang_code)
+ : InfoBarDelegate(tab_contents),
+ tab_contents_(tab_contents),
+ original_lang_index_(0),
+ target_lang_index_(0),
+ prefs_(user_prefs) {
+ // TODO(jcampan): unblock when backend is merged in.
+ // TranslationService::GetSupportedLanguages(&supported_languages_);
+ for (size_t i = 0; i < supported_languages_.size(); ++i) {
+ if (original_lang_code == supported_languages_[i]) {
+ original_lang_index_ = i;
+ break;
+ }
+ }
+ for (size_t i = 0; i < supported_languages_.size(); ++i) {
+ if (target_lang_code == supported_languages_[i]) {
+ target_lang_index_ = i;
+ break;
+ }
+ }
+}
+
+// BeforeTranslateInfoBarDelegate: public: -------------------------------------
+
+BeforeTranslateInfoBarDelegate::BeforeTranslateInfoBarDelegate(
+ TabContents* tab_contents, PrefService* user_prefs, const GURL& url,
+ const std::string& original_lang_code, const std::string& target_lang_code)
+ : TranslateInfoBarDelegate(tab_contents, user_prefs, original_lang_code,
+ target_lang_code),
+ site_(url.HostNoBrackets()),
+ never_translate_language_(false),
+ never_translate_site_(false) {
+}
+
+bool BeforeTranslateInfoBarDelegate::IsLanguageBlacklisted() {
+ never_translate_language_ =
+ prefs_.IsLanguageBlacklisted(original_lang_code());
+ return never_translate_language_;
+}
+
+void BeforeTranslateInfoBarDelegate::ToggleLanguageBlacklist() {
+ never_translate_language_ = !never_translate_language_;
+ if (never_translate_language_)
+ prefs_.BlacklistLanguage(original_lang_code());
+ else
+ prefs_.RemoveLanguageFromBlacklist(original_lang_code());
+}
+
+bool BeforeTranslateInfoBarDelegate::IsSiteBlacklisted() {
+ never_translate_site_ = prefs_.IsSiteBlacklisted(site_);
+ return never_translate_site_;
+}
+
+void BeforeTranslateInfoBarDelegate::ToggleSiteBlacklist() {
+ never_translate_site_ = !never_translate_site_;
+ if (never_translate_site_)
+ prefs_.BlacklistSite(site_);
+ else
+ prefs_.RemoveSiteFromBlacklist(site_);
+}
+
+#if !defined(TOOLKIT_VIEWS)
+InfoBar* BeforeTranslateInfoBarDelegate::CreateInfoBar() {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+#endif // !TOOLKIT_VIEWS
+
+// AfterTranslateInfoBarDelegate: public: --------------------------------------
+
+AfterTranslateInfoBarDelegate::AfterTranslateInfoBarDelegate(
+ TabContents* tab_contents, PrefService* user_prefs,
+ const std::string& original_lang_code, const std::string& target_lang_code)
+ : TranslateInfoBarDelegate(tab_contents, user_prefs, original_lang_code,
+ target_lang_code),
+ always_translate_(false) {
+}
+
+void AfterTranslateInfoBarDelegate::GetAvailableTargetLanguages(
+ std::vector<std::string>* languages) {
+ // TODO(jcampan): unblock when backend is merged in.
+ // TranslationService::GetSupportedLanguages(languages);
+}
+
+void AfterTranslateInfoBarDelegate::ModifyTargetLanguage(int lang_index) {
+ target_lang_index_ = lang_index;
+}
+
+bool AfterTranslateInfoBarDelegate::ShouldAlwaysTranslate() {
+ always_translate_ = prefs_.IsLanguagePairWhitelisted(original_lang_code(),
+ target_lang_code());
+ return always_translate_;
+}
+
+void AfterTranslateInfoBarDelegate::ToggleAlwaysTranslate() {
+ always_translate_ = !always_translate_;
+ if (always_translate_)
+ prefs_.WhitelistLanguagePair(original_lang_code(), target_lang_code());
+ else
+ prefs_.RemoveLanguagePairFromWhitelist(original_lang_code(),
+ target_lang_code());
+}
+
+#if !defined(TOOLKIT_VIEWS)
+InfoBar* AfterTranslateInfoBarDelegate::CreateInfoBar() {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+#endif // !TOOLKIT_VIEWS
diff --git a/chrome/browser/translate/translate_infobars_delegates.h b/chrome/browser/translate/translate_infobars_delegates.h
new file mode 100644
index 0000000..5b10f3f
--- /dev/null
+++ b/chrome/browser/translate/translate_infobars_delegates.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBARS_DELEGATES_H_
+#define CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBARS_DELEGATES_H_
+
+#include "chrome/browser/tab_contents/infobar_delegate.h"
+#include "chrome/browser/translate/translate_prefs.h"
+
+class SkBitmap;
+
+// An interface derived from InfoBarDelegate to form the base interface for
+// translate infobars.
+class TranslateInfoBarDelegate : public InfoBarDelegate {
+ public:
+ virtual void GetAvailableOriginalLanguages(
+ std::vector<std::string>* languages);
+ virtual void GetAvailableTargetLanguages(
+ std::vector<std::string>* languages);
+ virtual void ModifyOriginalLanguage(int lang_index);
+ virtual void ModifyTargetLanguage(int lang_index);
+ virtual void Translate();
+ virtual bool IsLanguageBlacklisted();
+ virtual void ToggleLanguageBlacklist();
+ virtual bool IsSiteBlacklisted();
+ virtual void ToggleSiteBlacklist();
+ virtual bool ShouldAlwaysTranslate();
+ virtual void ToggleAlwaysTranslate();
+
+ int original_lang_index() const {
+ return original_lang_index_;
+ }
+ int target_lang_index() const {
+ return target_lang_index_;
+ }
+ const std::string& original_lang_code() const {
+ return supported_languages_[original_lang_index_];
+ }
+ const std::string& target_lang_code() const {
+ return supported_languages_[target_lang_index_];
+ }
+ const std::string& GetLocaleFromIndex(int lang_index) const {
+ return supported_languages_[lang_index];
+ }
+ TabContents* tab_contents() const {
+ return tab_contents_;
+ }
+
+ // Overridden from InfoBarDelegate.
+ virtual Type GetInfoBarType() {
+ return PAGE_ACTION_TYPE;
+ }
+ virtual SkBitmap* GetIcon() const;
+ virtual bool EqualsDelegate(InfoBarDelegate* delegate) const;
+ virtual TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() {
+ return this;
+ }
+ virtual void InfoBarClosed();
+
+ // Returns the printable version of the language code |language_code|.
+ static string16 GetDisplayNameForLocale(const std::string& language_code);
+
+ protected:
+ TranslateInfoBarDelegate(TabContents* contents, PrefService* user_prefs,
+ const std::string& original_language, const std::string& target_language);
+
+ TabContents* tab_contents_; // Weak.
+ int original_lang_index_;
+ int target_lang_index_;
+ TranslatePrefs prefs_;
+ // The list of languages supported.
+ std::vector<std::string> supported_languages_;
+
+ DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarDelegate);
+};
+
+class BeforeTranslateInfoBarDelegate : public TranslateInfoBarDelegate {
+ public:
+ BeforeTranslateInfoBarDelegate(TabContents* contents, PrefService* user_prefs,
+ const GURL& url, const std::string& original_language,
+ const std::string& target_language);
+
+ // Overriden from TranslateInfoBarDelegate:
+ virtual bool IsLanguageBlacklisted();
+ virtual void ToggleLanguageBlacklist();
+ virtual bool IsSiteBlacklisted();
+ virtual void ToggleSiteBlacklist();
+
+ // Overridden from InfoBarDelegate:
+ virtual InfoBar* CreateInfoBar();
+
+ private:
+ std::string site_;
+ bool never_translate_language_;
+ bool never_translate_site_;
+
+ DISALLOW_COPY_AND_ASSIGN(BeforeTranslateInfoBarDelegate);
+};
+
+class AfterTranslateInfoBarDelegate : public TranslateInfoBarDelegate {
+ public:
+ AfterTranslateInfoBarDelegate(TabContents* contents, PrefService* user_prefs,
+ const std::string& original_language, const std::string& target_language);
+
+ // Overriden from TranslateInfoBar:
+ virtual void GetAvailableTargetLanguages(
+ std::vector<std::string>* languages);
+ virtual void ModifyTargetLanguage(int lang_index);
+ virtual bool ShouldAlwaysTranslate();
+ virtual void ToggleAlwaysTranslate();
+
+ // Overridden from InfoBarDelegate:
+ virtual InfoBar* CreateInfoBar();
+
+ private:
+ bool always_translate_;
+
+ DISALLOW_COPY_AND_ASSIGN(AfterTranslateInfoBarDelegate);
+};
+
+#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_INFOBARS_DELEGATES_H_
diff --git a/chrome/browser/translate/translate_prefs.cc b/chrome/browser/translate/translate_prefs.cc
new file mode 100644
index 0000000..ab69058
--- /dev/null
+++ b/chrome/browser/translate/translate_prefs.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/translate/translate_prefs.h"
+
+#include "base/string_util.h"
+#include "chrome/common/pref_service.h"
+
+static const wchar_t kPrefTranslateLanguageBlacklist[] =
+ L"translate_language_blacklist";
+static const wchar_t kPrefTranslateSiteBlacklist[] =
+ L"translate_site_blacklist";
+static const wchar_t kPrefTranslateWhitelists[] = L"translate_whitelists";
+
+// TranslatePrefs: public: -----------------------------------------------------
+
+TranslatePrefs::TranslatePrefs(PrefService* user_prefs)
+ : prefs_(user_prefs) {
+ Register();
+}
+
+bool TranslatePrefs::IsLanguageBlacklisted(
+ const std::string& original_language) {
+ return IsValueBlacklisted(kPrefTranslateLanguageBlacklist, original_language);
+}
+
+void TranslatePrefs::BlacklistLanguage(const std::string& original_language) {
+ BlacklistValue(kPrefTranslateLanguageBlacklist, original_language);
+}
+
+void TranslatePrefs::RemoveLanguageFromBlacklist(
+ const std::string& original_language) {
+ RemoveValueFromBlacklist(kPrefTranslateLanguageBlacklist, original_language);
+}
+
+bool TranslatePrefs::IsSiteBlacklisted(const std::string& site) {
+ return IsValueBlacklisted(kPrefTranslateSiteBlacklist, site);
+}
+
+void TranslatePrefs::BlacklistSite(const std::string& site) {
+ BlacklistValue(kPrefTranslateSiteBlacklist, site);
+}
+
+void TranslatePrefs::RemoveSiteFromBlacklist(const std::string& site) {
+ RemoveValueFromBlacklist(kPrefTranslateSiteBlacklist, site);
+}
+
+bool TranslatePrefs::IsLanguagePairWhitelisted(
+ const std::string& original_language,
+ const std::string& target_language) {
+ const DictionaryValue* dict = prefs_->GetDictionary(kPrefTranslateWhitelists);
+ if (dict && !dict->empty()) {
+ ListValue* whitelist = NULL;
+ if (dict->GetList(ASCIIToWide(original_language), &whitelist) &&
+ whitelist && !whitelist->empty() &&
+ IsValueInList(whitelist, target_language))
+ return true;
+ }
+ return false;
+}
+
+void TranslatePrefs::WhitelistLanguagePair(
+ const std::string& original_language,
+ const std::string& target_language) {
+ DictionaryValue* dict = prefs_->GetMutableDictionary(
+ kPrefTranslateWhitelists);
+ if (!dict) {
+ NOTREACHED() << "Unregistered translate whitelist pref";
+ return;
+ }
+ std::wstring wide_original(ASCIIToWide(original_language));
+ StringValue* language = new StringValue(target_language);
+ ListValue* whitelist = NULL;
+ if (dict->GetList(wide_original, &whitelist) && whitelist) {
+ whitelist->Append(language);
+ } else {
+ ListValue new_whitelist;
+ new_whitelist.Append(language);
+ dict->Set(wide_original, new_whitelist.DeepCopy());
+ }
+ prefs_->ScheduleSavePersistentPrefs();
+}
+
+void TranslatePrefs::RemoveLanguagePairFromWhitelist(
+ const std::string& original_language,
+ const std::string& target_language) {
+ DictionaryValue* dict = prefs_->GetMutableDictionary(
+ kPrefTranslateWhitelists);
+ if (!dict) {
+ NOTREACHED() << "Unregistered translate whitelist pref";
+ return;
+ }
+ ListValue* whitelist = NULL;
+ std::wstring wide_original(ASCIIToWide(original_language));
+ if (dict->GetList(wide_original, &whitelist) && whitelist) {
+ StringValue language(target_language);
+ if (whitelist->Remove(language) != -1) {
+ if (whitelist->empty()) // If list is empty, remove key from dict.
+ dict->Remove(wide_original, NULL);
+ prefs_->ScheduleSavePersistentPrefs();
+ }
+ }
+}
+
+// TranslatePrefs: static: -----------------------------------------------------
+
+bool TranslatePrefs::CanTranslate(PrefService* user_prefs,
+ const std::string& original_language, const GURL& url) {
+ TranslatePrefs prefs(user_prefs);
+ if (prefs.IsSiteBlacklisted(url.HostNoBrackets()))
+ return false;
+ return (!prefs.IsLanguageBlacklisted(original_language));
+}
+
+bool TranslatePrefs::ShouldAutoTranslate(PrefService* user_prefs,
+ const std::string& original_language,
+ const std::string& target_language) {
+ TranslatePrefs prefs(user_prefs);
+ return prefs.IsLanguagePairWhitelisted(original_language, target_language);
+}
+
+// TranslatePrefs: private: ----------------------------------------------------
+
+void TranslatePrefs::Register() {
+ if (!prefs_->FindPreference(kPrefTranslateLanguageBlacklist))
+ prefs_->RegisterListPref(kPrefTranslateLanguageBlacklist);
+ if (!prefs_->FindPreference(kPrefTranslateSiteBlacklist))
+ prefs_->RegisterListPref(kPrefTranslateSiteBlacklist);
+ if (!prefs_->FindPreference(kPrefTranslateWhitelists))
+ prefs_->RegisterDictionaryPref(kPrefTranslateWhitelists);
+}
+
+bool TranslatePrefs::IsValueInList(const ListValue* list,
+ const std::string& in_value) {
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ std::string value;
+ if (list->GetString(i, &value) && value == in_value)
+ return true;
+ }
+ return false;
+}
+
+bool TranslatePrefs::IsValueBlacklisted(const wchar_t* pref_id,
+ const std::string& value) {
+ const ListValue* blacklist = prefs_->GetList(pref_id);
+ return (blacklist && !blacklist->empty() && IsValueInList(blacklist, value));
+}
+
+void TranslatePrefs::BlacklistValue(const wchar_t* pref_id,
+ const std::string& value) {
+ ListValue* blacklist = prefs_->GetMutableList(pref_id);
+ if (!blacklist) {
+ NOTREACHED() << "Unregistered translate blacklist pref";
+ return;
+ }
+ blacklist->Append(new StringValue(value));
+ prefs_->ScheduleSavePersistentPrefs();
+}
+
+void TranslatePrefs::RemoveValueFromBlacklist(const wchar_t* pref_id,
+ const std::string& value) {
+ ListValue* blacklist = prefs_->GetMutableList(pref_id);
+ if (!blacklist) {
+ NOTREACHED() << "Unregistered translate blacklist pref";
+ return;
+ }
+ StringValue string_value(value);
+ if (blacklist->Remove(string_value) != -1)
+ prefs_->ScheduleSavePersistentPrefs();
+}
diff --git a/chrome/browser/translate/translate_prefs.h b/chrome/browser/translate/translate_prefs.h
new file mode 100644
index 0000000..542dacc
--- /dev/null
+++ b/chrome/browser/translate/translate_prefs.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_PREFS_H_
+#define CHROME_BROWSER_TRANSLATE_TRANSLATE_PREFS_H_
+
+#include <vector>
+
+#include "googleurl/src/gurl.h"
+
+class ListValue;
+class PrefService;
+
+class TranslatePrefs {
+ public:
+ explicit TranslatePrefs(PrefService* user_prefs);
+
+ bool IsLanguageBlacklisted(const std::string& original_language);
+ void BlacklistLanguage(const std::string& original_language);
+ void RemoveLanguageFromBlacklist(const std::string& original_language);
+
+ bool IsSiteBlacklisted(const std::string& site);
+ void BlacklistSite(const std::string& site);
+ void RemoveSiteFromBlacklist(const std::string& site);
+
+ bool IsLanguagePairWhitelisted(const std::string& original_language,
+ const std::string& target_language);
+ void WhitelistLanguagePair(const std::string& original_language,
+ const std::string& target_language);
+ void RemoveLanguagePairFromWhitelist(const std::string& original_language,
+ const std::string& target_language);
+
+ static bool CanTranslate(PrefService* user_prefs,
+ const std::string& original_language, const GURL& url);
+ static bool ShouldAutoTranslate(PrefService* user_prefs,
+ const std::string& original_language,
+ const std::string& target_language);
+
+ private:
+ void Register();
+ bool IsValueBlacklisted(const wchar_t* pref_id, const std::string& value);
+ void BlacklistValue(const wchar_t* pref_id, const std::string& value);
+ void RemoveValueFromBlacklist(const wchar_t* pref_id,
+ const std::string& value);
+ bool IsValueInList(const ListValue* list, const std::string& value);
+
+ PrefService* prefs_; // Weak.
+};
+
+#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_PREFS_H_
diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc
index 1cba466..fd6437b7 100644
--- a/chrome/browser/views/infobars/infobars.cc
+++ b/chrome/browser/views/infobars/infobars.cc
@@ -22,12 +22,13 @@
#include "views/widget/widget.h"
// static
-const double InfoBar::kTargetHeight = 37.0;
-
-static const int kVerticalPadding = 3;
-static const int kHorizontalPadding = 3;
-static const int kIconLabelSpacing = 5;
-static const int kButtonSpacing = 5;
+const double InfoBar::kTargetHeight = 36.0;
+const int InfoBar::kHorizontalPadding = 6;
+const int InfoBar::kIconLabelSpacing = 6;
+const int InfoBar::kButtonButtonSpacing = 10;
+const int InfoBar::kEndOfLabelSpacing = 16;
+const int InfoBar::kCloseButtonSpacing = 12;
+const int InfoBar::kButtonInLabelSpacing = 5;
static const SkColor kInfoBackgroundColorTop = SkColorSetRGB(170, 214, 112);
static const SkColor kInfoBackgroundColorBottom = SkColorSetRGB(146, 205, 114);
@@ -40,25 +41,12 @@ static const SkColor kErrorBackgroundColorTop = kWarningBackgroundColorTop;
static const SkColor kErrorBackgroundColorBottom =
kWarningBackgroundColorBottom;
-static const int kSeparatorLineHeight = 1;
-
-namespace {
-// Returns a centered y-position of a control of height specified in |prefsize|
-// within the standard InfoBar height. Stable during an animation.
-int CenterY(const gfx::Size prefsize) {
- return std::max((static_cast<int>(InfoBar::kTargetHeight) -
- prefsize.height()) / 2, 0);
-}
+static const SkColor kPageActionBackgroundColorTop =
+ SkColorSetRGB(209, 222, 245);
+static const SkColor kPageActionBackgroundColorBottom =
+ SkColorSetRGB(178, 201, 239);
-// Returns a centered y-position of a control of height specified in |prefsize|
-// within the standard InfoBar height, adjusted according to the current amount
-// of animation offset the |parent| InfoBar currently has. Changes during an
-// animation.
-int OffsetY(views::View* parent, const gfx::Size prefsize) {
- return CenterY(prefsize) -
- (static_cast<int>(InfoBar::kTargetHeight) - parent->height());
-}
-}
+static const int kSeparatorLineHeight = 1;
// InfoBarBackground -----------------------------------------------------------
@@ -80,6 +68,10 @@ class InfoBarBackground : public views::Background {
top_color = kErrorBackgroundColorTop;
bottom_color = kErrorBackgroundColorBottom;
break;
+ case InfoBarDelegate::PAGE_ACTION_TYPE:
+ top_color = kPageActionBackgroundColorTop;
+ bottom_color = kPageActionBackgroundColorBottom;
+ break;
default:
NOTREACHED();
break;
@@ -169,7 +161,7 @@ gfx::Size InfoBar::GetPreferredSize() {
void InfoBar::Layout() {
gfx::Size button_ps = close_button_->GetPreferredSize();
- close_button_->SetBounds(width() - kButtonSpacing - button_ps.width(),
+ close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(),
OffsetY(this, button_ps), button_ps.width(),
button_ps.height());
}
@@ -188,13 +180,23 @@ void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent,
// InfoBar, protected: ---------------------------------------------------------
int InfoBar::GetAvailableWidth() const {
- return close_button_->x() - kButtonSpacing;
+ return close_button_->x() - kCloseButtonSpacing;
}
void InfoBar::RemoveInfoBar() const {
container_->RemoveDelegate(delegate());
}
+int InfoBar::CenterY(const gfx::Size prefsize) {
+ return std::max((static_cast<int>(InfoBar::kTargetHeight) -
+ prefsize.height()) / 2, 0);
+}
+
+int InfoBar::OffsetY(views::View* parent, const gfx::Size prefsize) {
+ return CenterY(prefsize) -
+ (static_cast<int>(InfoBar::kTargetHeight) - parent->height());
+}
+
// InfoBar, views::ButtonListener implementation: ------------------
void InfoBar::ButtonPressed(views::Button* sender, const views::Event& event) {
@@ -453,7 +455,7 @@ void ConfirmInfoBar::Layout() {
cancel_button_->SetBounds(available_width - cancel_button_width,
OffsetY(this, cancel_ps), cancel_ps.width(),
cancel_ps.height());
- int spacing = cancel_button_width > 0 ? kButtonSpacing : 0;
+ int spacing = cancel_button_width > 0 ? kButtonButtonSpacing : 0;
ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width,
OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height());
AlertInfoBar::Layout();
@@ -487,9 +489,9 @@ void ConfirmInfoBar::ButtonPressed(
int ConfirmInfoBar::GetAvailableWidth() const {
if (ok_button_)
- return ok_button_->x() - kButtonSpacing;
+ return ok_button_->x() - kEndOfLabelSpacing;
if (cancel_button_)
- return cancel_button_->x() - kButtonSpacing;
+ return cancel_button_->x() - kEndOfLabelSpacing;
return InfoBar::GetAvailableWidth();
}
diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h
index 9870ad4..970b1ab 100644
--- a/chrome/browser/views/infobars/infobars.h
+++ b/chrome/browser/views/infobars/infobars.h
@@ -56,6 +56,13 @@ class InfoBar : public views::View,
// is (due to animation).
static const double kTargetHeight;
+ static const int kHorizontalPadding;
+ static const int kIconLabelSpacing;
+ static const int kButtonButtonSpacing;
+ static const int kEndOfLabelSpacing;
+ static const int kCloseButtonSpacing;
+ static const int kButtonInLabelSpacing;
+
// Overridden from views::View:
virtual gfx::Size GetPreferredSize();
virtual void Layout();
@@ -74,6 +81,16 @@ class InfoBar : public views::View,
// (Will lead to this InfoBar being closed).
void RemoveInfoBar() const;
+ // Returns a centered y-position of a control of height specified in
+ // |prefsize| within the standard InfoBar height. Stable during an animation.
+ int CenterY(const gfx::Size prefsize);
+
+ // Returns a centered y-position of a control of height specified in
+ // |prefsize| within the standard InfoBar height, adjusted according to the
+ // current amount of animation offset the |parent| InfoBar currently has.
+ // Changes during an animation.
+ int OffsetY(views::View* parent, const gfx::Size prefsize);
+
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
diff --git a/chrome/browser/views/infobars/translate_infobars.cc b/chrome/browser/views/infobars/translate_infobars.cc
new file mode 100644
index 0000000..c1850df
--- /dev/null
+++ b/chrome/browser/views/infobars/translate_infobars.cc
@@ -0,0 +1,606 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/infobars/translate_infobars.h"
+
+#include "app/gfx/canvas.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/translate/languages_menu_model.h"
+#include "chrome/browser/translate/options_menu_model.h"
+#include "grit/app_resources.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/button/menu_button.h"
+#include "views/controls/button/text_button.h"
+#include "views/controls/image_view.h"
+#include "views/controls/label.h"
+#include "views/controls/message_box_view.h"
+
+// IDs for various menus.
+static const int kMenuIDOptions = 1000;
+static const int kMenuIDOriginalLanguage = 1001;
+static const int kMenuIDTargetLanguage = 1002;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TranslateButtonBorder
+//
+// A TextButtonBorder subclass that adds to also paint button frame in normal
+// state, and changes the images used.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class TranslateButtonBorder : public views::TextButtonBorder {
+ public:
+ TranslateButtonBorder();
+ virtual ~TranslateButtonBorder();
+
+ // Overriden from Border
+ virtual void Paint(const views::View& view, gfx::Canvas* canvas) const;
+
+ private:
+ MBBImageSet normal_set_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TranslateButtonBorder);
+};
+
+// TranslateButtonBorder, public: ----------------------------------------------
+
+TranslateButtonBorder::TranslateButtonBorder() {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
+ normal_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_N);
+ normal_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_N);
+ normal_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_N);
+ normal_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_N);
+ normal_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_N);
+ normal_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_N);
+ normal_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_N);
+ normal_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_N);
+ normal_set_.bottom_right = rb.GetBitmapNamed(
+ IDR_INFOBARBUTTON_BOTTOM_RIGHT_N);
+
+ hot_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_H);
+ hot_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_H);
+ hot_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_H);
+ hot_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_H);
+ hot_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_H);
+ hot_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_H);
+ hot_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_H);
+ hot_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_H);
+ hot_set_.bottom_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_RIGHT_H);
+
+ pushed_set_.top_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_LEFT_P);
+ pushed_set_.top = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_P);
+ pushed_set_.top_right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_TOP_RIGHT_P);
+ pushed_set_.left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_LEFT_P);
+ pushed_set_.center = rb.GetBitmapNamed(IDR_INFOBARBUTTON_CENTER_P);
+ pushed_set_.right = rb.GetBitmapNamed(IDR_INFOBARBUTTON_RIGHT_P);
+ pushed_set_.bottom_left = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_LEFT_P);
+ pushed_set_.bottom = rb.GetBitmapNamed(IDR_INFOBARBUTTON_BOTTOM_P);
+ pushed_set_.bottom_right = rb.GetBitmapNamed(
+ IDR_INFOBARBUTTON_BOTTOM_RIGHT_P);
+}
+
+TranslateButtonBorder::~TranslateButtonBorder() {
+}
+
+// TranslateButtonBorder, Border overrides: ------------------------------------
+
+void TranslateButtonBorder::Paint(const views::View& view, gfx::Canvas* canvas)
+ const {
+ const views::TextButton* mb = static_cast<const views::TextButton*>(&view);
+ int state = mb->state();
+
+ // TextButton takes care of deciding when to call Paint.
+ const MBBImageSet* set = &normal_set_;
+ if (state == views::TextButton::BS_HOT)
+ set = &hot_set_;
+ else if (state == views::TextButton::BS_PUSHED)
+ set = &pushed_set_;
+
+ TextButtonBorder::Paint(view, canvas, *set);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TranslateTextButton
+//
+// A TextButton subclass that overrides OnMousePressed to default to
+// CustomButton so as to create pressed state effect.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class TranslateTextButton : public views::TextButton {
+ public:
+ TranslateTextButton(views::ButtonListener* listener, int label_id);
+ virtual ~TranslateTextButton();
+
+ protected:
+ // Overriden from TextButton:
+ virtual bool OnMousePressed(const views::MouseEvent& e);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TranslateTextButton);
+};
+
+// TranslateButtonBorder, public: ----------------------------------------------
+
+TranslateTextButton::TranslateTextButton(views::ButtonListener* listener,
+ int label_id)
+ : TextButton(listener, l10n_util::GetString(label_id)) {
+ set_border(new TranslateButtonBorder);
+ SetNormalHasBorder(true); // Normal button state has border.
+ SetAnimationDuration(0); // Disable animation during state change.
+}
+
+TranslateTextButton::~TranslateTextButton() {
+}
+
+// TranslateButtonBorder, protected:--------------------------------------------
+bool TranslateTextButton::OnMousePressed(const views::MouseEvent& e) {
+ return views::CustomButton::OnMousePressed(e);
+}
+
+// TranslateInfoBar, public: ---------------------------------------------------
+
+TranslateInfoBar::TranslateInfoBar(TranslateInfoBarDelegate* delegate,
+ bool before_translate, int label_id)
+ : InfoBar(delegate),
+ before_translate_(before_translate),
+ swapped_language_placeholders_(false) {
+ icon_ = new views::ImageView;
+ SkBitmap* image = delegate->GetIcon();
+ if (image)
+ icon_->SetImage(image);
+ AddChildView(icon_);
+
+ // Set up the labels.
+ std::vector<size_t> offsets;
+ std::wstring message_text = l10n_util::GetStringF(label_id, std::wstring(),
+ std::wstring(), &offsets);
+ if (!offsets.empty() && offsets.size() <= 2) {
+ // Sort the offsets if necessary.
+ if (offsets.size() == 2 && offsets[0] > offsets[1]) {
+ size_t offset0 = offsets[0];
+ offsets[0] = offsets[1];
+ offsets[1] = offset0;
+ swapped_language_placeholders_ = true;
+ }
+ if (offsets[offsets.size() - 1] != message_text.length())
+ offsets.push_back(message_text.length());
+ } else {
+ NOTREACHED() << "Invalid no. of placeholders in label.";
+ }
+
+ const gfx::Font& font = ResourceBundle::GetSharedInstance().GetFont(
+ ResourceBundle::MediumFont);
+ label_1_ = new views::Label(message_text.substr(0, offsets[0]), font);
+ label_1_->SetColor(SK_ColorBLACK);
+ label_1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(label_1_);
+
+ label_2_ = new views::Label(
+ message_text.substr(offsets[0], offsets[1] - offsets[0]), font);
+ label_2_->SetColor(SK_ColorBLACK);
+ label_2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(label_2_);
+
+ if (offsets.size() == 3) {
+ label_3_ = new views::Label(
+ message_text.substr(offsets[1], offsets[2] - offsets[1]), font);
+ label_3_->SetColor(SK_ColorBLACK);
+ label_3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(label_3_);
+ } else {
+ label_3_ = NULL;
+ }
+
+ string16 language_name = TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ GetDelegate()->original_lang_code());
+ original_language_menu_button_ = CreateMenuButton(kMenuIDOriginalLanguage,
+ UTF16ToWideHack(language_name));
+ AddChildView(original_language_menu_button_);
+
+ options_menu_button_ = CreateMenuButton(kMenuIDOptions,
+ l10n_util::GetString(IDS_TRANSLATE_INFOBAR_OPTIONS));
+ AddChildView(options_menu_button_);
+}
+
+TranslateInfoBar::~TranslateInfoBar() {
+}
+
+// TranslateInfoBar, views::View overrides: ------------------------------------
+
+void TranslateInfoBar::Layout() {
+ // Layout the close button.
+ InfoBar::Layout();
+
+ // Layout the icon on left of bar.
+ gfx::Size icon_ps = icon_->GetPreferredSize();
+ icon_->SetBounds(InfoBar::kHorizontalPadding, InfoBar::OffsetY(this, icon_ps),
+ icon_ps.width(), icon_ps.height());
+
+ // Layout the options menu button on right of bar.
+ int available_width = InfoBar::GetAvailableWidth();
+ gfx::Size options_ps = options_menu_button_->GetPreferredSize();
+ options_menu_button_->SetBounds(available_width - options_ps.width(),
+ OffsetY(this, options_ps), options_ps.width(), options_ps.height());
+
+ // Layout the controls between icon and options i.e. labels, original language
+ // menu button, and if available, target language menu button.
+ // We layout target language menu button here (as opposed to in
+ // AfterTranslateInfoBar) because the 2 language menu buttons could be swapped
+ // for different locales.
+ views::MenuButton* button1 = original_language_menu_button_;
+ views::MenuButton* button2 = target_language_menu_button();
+ if (button2 && swapped_language_placeholders_) {
+ button1 = button2;
+ button2 = original_language_menu_button_;
+ }
+ gfx::Size button1_ps = button1->GetPreferredSize();
+ int available_text_width = std::max(GetAvailableWidth(), 0);
+ gfx::Size label1_ps = label_1_->GetPreferredSize();
+ gfx::Size label2_ps = label_2_->GetPreferredSize();
+ gfx::Size label3_ps;
+ if (label_3_)
+ label3_ps = label_3_->GetPreferredSize();
+ int text1_width = label1_ps.width();
+ int text2_width = label2_ps.width();
+ int text3_width = label3_ps.width();
+ int total_text_width = text1_width + text2_width + text3_width;
+ if (total_text_width > available_text_width) {
+ double ratio = static_cast<double>(available_text_width) /
+ static_cast<double>(total_text_width);
+ text1_width = static_cast<int>(text1_width * ratio);
+ text2_width = static_cast<int>(text2_width * ratio);
+ text3_width = static_cast<int>(text3_width * ratio);
+ }
+ label_1_->SetBounds(icon_->bounds().right() + InfoBar::kIconLabelSpacing,
+ InfoBar::OffsetY(this, label1_ps), text1_width, label1_ps.height());
+
+ // Place first language menu button after label_1.
+ button1->SetBounds(label_1_->bounds().right() +
+ InfoBar::kButtonInLabelSpacing, OffsetY(this, button1_ps),
+ button1_ps.width(), button1_ps.height());
+
+ // Place label_2 after first language menu button.
+ label_2_->SetBounds(button1->bounds().right() +
+ GetSpacingAfterFirstLanguageButton(), InfoBar::OffsetY(this, label2_ps),
+ text2_width, label2_ps.height());
+
+ // If second language menu button is available, place it after label_2.
+ if (button2) {
+ gfx::Size button2_ps = button2->GetPreferredSize();
+ button2->SetBounds(label_2_->bounds().right() +
+ InfoBar::kButtonInLabelSpacing, OffsetY(this, button2_ps),
+ button2_ps.width(), button2_ps.height());
+
+ if (label_3_) {
+ gfx::Size label3_ps = label_3_->GetPreferredSize();
+ // Place label_3 after first language menu button.
+ label_3_->SetBounds(button2->bounds().right() +
+ InfoBar::kButtonInLabelSpacing, InfoBar::OffsetY(this, label3_ps),
+ text3_width, label3_ps.height());
+ }
+ }
+}
+
+// TranslateInfoBar, InfoBar overrides: ----------------------------------------
+
+int TranslateInfoBar::GetAvailableWidth() const {
+ gfx::Size icon_ps = icon_->GetPreferredSize();
+ // For language button, reserve spacing before and after it.
+ gfx::Size language_ps = original_language_menu_button_->GetPreferredSize();
+ int language_spacing = InfoBar::kButtonInLabelSpacing +
+ GetSpacingAfterFirstLanguageButton();
+ // Options button could come after different types of controls, so we reserve
+ // different spacings for each:
+ // - after label_3 (i.e. this label follows the second language button):
+ // spacing after second language button and for end of sentence
+ // - after second language button (i.e. there's no label_3): spacing for end
+ // of sentence
+ // - all other cases, regular button spacing before options button
+ gfx::Size options_ps = options_menu_button_->GetPreferredSize();
+ int options_spacing =
+ (label_3_ ? InfoBar::kButtonInLabelSpacing + InfoBar::kEndOfLabelSpacing :
+ (target_language_menu_button() ? InfoBar::kEndOfLabelSpacing :
+ InfoBar::kButtonButtonSpacing));
+ return (InfoBar::GetAvailableWidth() - options_ps.width() - options_spacing -
+ language_ps.width() - language_spacing -
+ icon_->bounds().right() - InfoBar::kIconLabelSpacing);
+}
+
+// TranslateInfoBar, views::ViewMenuDelegate implementation: -------------------
+
+void TranslateInfoBar::RunMenu(views::View* source, const gfx::Point& pt) {
+ int menu_id = source->GetID();
+ if (menu_id == kMenuIDOptions) {
+ if (!options_menu_model_.get()) {
+ options_menu_model_.reset(new OptionsMenuModel(this, GetDelegate(),
+ before_translate_));
+ options_menu_menu_.reset(new views::Menu2(options_menu_model_.get()));
+ }
+ options_menu_menu_->RunMenuAt(pt,
+ (UILayoutIsRightToLeft() ? views::Menu2::ALIGN_TOPLEFT :
+ views::Menu2::ALIGN_TOPRIGHT));
+ } else if (menu_id == kMenuIDOriginalLanguage) {
+ if (!original_language_menu_model_.get()) {
+ original_language_menu_model_.reset(
+ new LanguagesMenuModel(this, GetDelegate(), true));
+ original_language_menu_menu_.reset(
+ new views::Menu2(original_language_menu_model_.get()));
+ }
+ views::Menu2::Alignment alignment;
+ gfx::Point menu_position = DetermineMenuPositionAndAlignment(
+ original_language_menu_button_, &alignment);
+ original_language_menu_menu_->RunMenuAt(menu_position, alignment);
+ } else {
+ NOTREACHED() << "Invalid source menu.";
+ }
+}
+
+// TranslateInfoBar, views::SimpleMenuModel::Delegate implementation: ----------
+
+bool TranslateInfoBar::IsCommandIdChecked(int command_id) const {
+ TranslateInfoBarDelegate* translate_delegate = GetDelegate();
+ switch (command_id) {
+ case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG :
+ return translate_delegate->IsLanguageBlacklisted();
+
+ case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE :
+ return translate_delegate->IsSiteBlacklisted();
+
+ case IDC_TRANSLATE_OPTIONS_ALWAYS :
+ return translate_delegate->ShouldAlwaysTranslate();
+
+ default:
+ NOTREACHED() << "Invalid command_id from menu";
+ break;
+ }
+ return false;
+}
+
+bool TranslateInfoBar::IsCommandIdEnabled(int command_id) const {
+ return true;
+}
+
+bool TranslateInfoBar::GetAcceleratorForCommandId(int command_id,
+ views::Accelerator* accelerator) {
+ return false;
+}
+
+void TranslateInfoBar::ExecuteCommand(int command_id) {
+ if (command_id >= IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE) {
+ OnLanguageModified(original_language_menu_button_,
+ command_id - IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE);
+ } else {
+ switch (command_id) {
+ case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG:
+ GetDelegate()->ToggleLanguageBlacklist();
+ break;
+
+ case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE:
+ GetDelegate()->ToggleSiteBlacklist();
+ break;
+
+ case IDC_TRANSLATE_OPTIONS_ALWAYS:
+ GetDelegate()->ToggleAlwaysTranslate();
+ break;
+
+ case IDC_TRANSLATE_OPTIONS_ABOUT: {
+ TabContents* tab_contents = GetDelegate()->tab_contents();
+ if (tab_contents) {
+ string16 url = l10n_util::GetStringUTF16(
+ IDS_ABOUT_GOOGLE_TRANSLATE_URL);
+ tab_contents->OpenURL(GURL(url), GURL(), NEW_FOREGROUND_TAB,
+ PageTransition::LINK);
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED() << "Invalid command id from menu.";
+ break;
+ }
+ }
+}
+
+// TranslateInfoBar, protected: ------------------------------------------------
+
+views::MenuButton* TranslateInfoBar::CreateMenuButton(int menu_id,
+ const std::wstring& label) {
+ views::MenuButton* menu_button =
+ new views::MenuButton(NULL, label, this, true);
+ menu_button->SetID(menu_id);
+ menu_button->set_border(new TranslateButtonBorder);
+ menu_button->SetNormalHasBorder(true);
+ menu_button->SetAnimationDuration(0);
+ return menu_button;
+}
+
+int TranslateInfoBar::GetAvailableX() const {
+ return ((label_3_ ? label_3_->bounds().right() : label_2_->bounds().right()) +
+ InfoBar::kEndOfLabelSpacing);
+}
+
+gfx::Point TranslateInfoBar::DetermineMenuPositionAndAlignment(
+ views::MenuButton* menu_button, views::Menu2::Alignment* alignment) {
+ gfx::Rect lb = menu_button->GetLocalBounds(true);
+ gfx::Point menu_position(lb.origin());
+ menu_position.Offset(2, lb.height() - 3);
+ if (UILayoutIsRightToLeft()) {
+ menu_position.Offset(lb.width() - 4, 0);
+ *alignment = views::Menu2::ALIGN_TOPRIGHT;
+ } else {
+ *alignment = views::Menu2::ALIGN_TOPLEFT;
+ }
+ View::ConvertPointToScreen(menu_button, &menu_position);
+#if defined(OS_WIN)
+ int left_bound = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ if (menu_position.x() < left_bound)
+ menu_position.set_x(left_bound);
+#endif
+ return menu_position;
+}
+
+void TranslateInfoBar::OnLanguageModified(views::MenuButton* menu_button,
+ int new_language_index) {
+ // Only proceed if a different language has been selected.
+ if (menu_button == original_language_menu_button_) {
+ if (new_language_index == GetDelegate()->original_lang_index())
+ return;
+ GetDelegate()->ModifyOriginalLanguage(new_language_index);
+ } else {
+ if (new_language_index == GetDelegate()->target_lang_index())
+ return;
+ GetDelegate()->ModifyTargetLanguage(new_language_index);
+ }
+
+ string16 new_language = TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ GetDelegate()->GetLocaleFromIndex(new_language_index));
+ menu_button->SetText(UTF16ToWideHack(new_language));
+ menu_button->ClearMaxTextSize();
+ menu_button->SizeToPreferredSize();
+ Layout();
+ SchedulePaint();
+ // Clear options menu model so that it'll be created with new language.
+ options_menu_model_.reset();
+ if (!before_translate_)
+ GetDelegate()->Translate();
+}
+
+TranslateInfoBarDelegate* TranslateInfoBar::GetDelegate() const {
+ return static_cast<TranslateInfoBarDelegate*>(delegate());
+}
+
+// BeforeTranslateInfoBar, public: ---------------------------------------------
+
+BeforeTranslateInfoBar::BeforeTranslateInfoBar(
+ BeforeTranslateInfoBarDelegate* delegate)
+ : TranslateInfoBar(delegate, true, IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE) {
+ accept_button_ = new TranslateTextButton(this, IDS_TRANSLATE_INFOBAR_ACCEPT);
+ AddChildView(accept_button_);
+
+ deny_button_ = new TranslateTextButton(this, IDS_TRANSLATE_INFOBAR_DENY);
+ AddChildView(deny_button_);
+}
+
+BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
+}
+
+// BeforeTranslateInfoBar, InfoBar overrides: ----------------------------------
+
+int BeforeTranslateInfoBar::GetAvailableWidth() const {
+ gfx::Size accept_ps = accept_button_->GetPreferredSize();
+ gfx::Size deny_ps = deny_button_->GetPreferredSize();
+ return (TranslateInfoBar::GetAvailableWidth() -
+ accept_ps.width() - InfoBar::kEndOfLabelSpacing -
+ deny_ps.width() - InfoBar::kButtonButtonSpacing);
+}
+
+// BeforeTranslateInfoBar, views::View overrides: ------------------------------
+
+void BeforeTranslateInfoBar::Layout() {
+ // Layout the icon, options menu, language menu and close buttons.
+ TranslateInfoBar::Layout();
+
+ // Layout accept button.
+ gfx::Size accept_ps = accept_button_->GetPreferredSize();
+ accept_button_->SetBounds(TranslateInfoBar::GetAvailableX(),
+ OffsetY(this, accept_ps), accept_ps.width(), accept_ps.height());
+
+ // Layout deny button.
+ gfx::Size deny_ps = deny_button_->GetPreferredSize();
+ deny_button_->SetBounds(
+ accept_button_->bounds().right() + InfoBar::kButtonButtonSpacing,
+ OffsetY(this, deny_ps), deny_ps.width(), deny_ps.height());
+}
+
+// BeforeTranslateInfoBar, views::ButtonListener overrides: --------------------
+
+void BeforeTranslateInfoBar::ButtonPressed(
+ views::Button* sender, const views::Event& event) {
+ if (sender == accept_button_) {
+ // TODO(kuan): If privacy warning box is needed (awaiting PM/UX decision),
+ // implement it.
+ GetDelegate()->Translate();
+ } else if (sender != deny_button_) { // Let base InfoBar handle close button.
+ InfoBar::ButtonPressed(sender, event);
+ }
+ RemoveInfoBar();
+}
+
+// AfterTranslateInfoBar, public: ----------------------------------------------
+
+AfterTranslateInfoBar::AfterTranslateInfoBar(
+ AfterTranslateInfoBarDelegate* delegate)
+ : TranslateInfoBar(delegate, false, IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE) {
+ string16 language_name = TranslateInfoBarDelegate::GetDisplayNameForLocale(
+ GetDelegate()->target_lang_code());
+ target_language_menu_button_ = CreateMenuButton(kMenuIDTargetLanguage,
+ UTF16ToWideHack(language_name));
+ AddChildView(target_language_menu_button_);
+}
+
+AfterTranslateInfoBar::~AfterTranslateInfoBar() {
+}
+
+// AfterTranslateInfoBar, InfoBar overrides: ----------------------------------
+
+int AfterTranslateInfoBar::GetAvailableWidth() const {
+ gfx::Size target_ps = target_language_menu_button_->GetPreferredSize();
+ return (TranslateInfoBar::GetAvailableWidth() - target_ps.width() -
+ InfoBar::kButtonInLabelSpacing);
+}
+
+// AfterTranslateInfoBar, views::ViewMenuDelegate implementation: --------------
+
+void AfterTranslateInfoBar::RunMenu(views::View* source, const gfx::Point& pt) {
+ if (source->GetID() == kMenuIDTargetLanguage) {
+ if (!target_language_menu_model_.get()) {
+ target_language_menu_model_.reset(
+ new LanguagesMenuModel(this, GetDelegate(), false));
+ target_language_menu_menu_.reset(
+ new views::Menu2(target_language_menu_model_.get()));
+ }
+ views::Menu2::Alignment alignment;
+ gfx::Point menu_position = DetermineMenuPositionAndAlignment(
+ target_language_menu_button_, &alignment);
+ target_language_menu_menu_->RunMenuAt(menu_position, alignment);
+ } else {
+ TranslateInfoBar::RunMenu(source, pt);
+ }
+}
+
+// AfterTranslateInfoBar, views::SimpleMenuModel::Delegate implementation: -----
+
+void AfterTranslateInfoBar::ExecuteCommand(int command_id) {
+ if (command_id >= IDC_TRANSLATE_TARGET_LANGUAGE_BASE) {
+ OnLanguageModified(target_language_menu_button_,
+ command_id - IDC_TRANSLATE_TARGET_LANGUAGE_BASE);
+ } else {
+ TranslateInfoBar::ExecuteCommand(command_id);
+ }
+}
+
+// BeforeTranslateInfoBarDelegate, InfoBarDelegate overrides: ------------------
+
+InfoBar* BeforeTranslateInfoBarDelegate::CreateInfoBar() {
+ return new BeforeTranslateInfoBar(this);
+}
+
+// AfterTranslateInfoBarDelegate, InfoBarDelegate overrides: ------------------
+
+InfoBar* AfterTranslateInfoBarDelegate::CreateInfoBar() {
+ return new AfterTranslateInfoBar(this);
+}
+
diff --git a/chrome/browser/views/infobars/translate_infobars.h b/chrome/browser/views/infobars/translate_infobars.h
new file mode 100644
index 0000000..a571a7e
--- /dev/null
+++ b/chrome/browser/views/infobars/translate_infobars.h
@@ -0,0 +1,146 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBARS_H_
+#define CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBARS_H_
+
+#include "views/controls/menu/simple_menu_model.h"
+#include "chrome/browser/translate/translate_infobars_delegates.h"
+#include "chrome/browser/views/infobars/infobars.h"
+#include "views/controls/menu/view_menu_delegate.h"
+#include "views/controls/menu/menu_2.h"
+
+namespace views {
+class ImageButton;
+class ImageView;
+class Label;
+class MenuButton;
+}
+class LanguagesMenuModel;
+class OptionsMenuModel;
+class TranslateTextButton;
+
+// This file contains implementations for infobars for the Translate feature.
+
+class TranslateInfoBar : public InfoBar,
+ public views::ViewMenuDelegate,
+ public views::SimpleMenuModel::Delegate {
+ public:
+ TranslateInfoBar(TranslateInfoBarDelegate* delegate, bool before_translate,
+ int label_id);
+ virtual ~TranslateInfoBar();
+
+ // Overridden from views::View:
+ virtual void Layout();
+
+ // Overridden from views::MenuDelegate:
+ virtual void RunMenu(views::View* source, const gfx::Point& pt);
+
+ // Overridden from views::SimpleMenuModel::Delegate:
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ views::Accelerator* accelerator);
+ virtual void ExecuteCommand(int command_id);
+
+ protected:
+ views::MenuButton* CreateMenuButton(int menu_id, const std::wstring& label);
+ gfx::Point DetermineMenuPositionAndAlignment(views::MenuButton* menu_button,
+ views::Menu2::Alignment* alignment);
+ void OnLanguageModified(views::MenuButton* menu_button,
+ int new_language_index);
+ TranslateInfoBarDelegate* GetDelegate() const;
+
+ // Overridden from InfoBar:
+ virtual int GetAvailableWidth() const;
+
+ // Returns the leftmost position that subclasses can position their controls.
+ virtual int GetAvailableX() const;
+
+ virtual views::MenuButton* target_language_menu_button() const {
+ return NULL;
+ }
+
+ virtual int GetSpacingAfterFirstLanguageButton() const {
+ return InfoBar::kButtonInLabelSpacing;
+ }
+
+ private:
+ bool before_translate_;
+ views::ImageView* icon_;
+ views::Label* label_1_;
+ views::Label* label_2_;
+ views::Label* label_3_;
+ views::MenuButton* original_language_menu_button_;
+ views::MenuButton* options_menu_button_;
+
+ scoped_ptr<LanguagesMenuModel> original_language_menu_model_;
+ scoped_ptr<OptionsMenuModel> options_menu_model_;
+
+ scoped_ptr<views::Menu2> original_language_menu_menu_;
+ scoped_ptr<views::Menu2> options_menu_menu_;
+
+ // This is true if language placeholders in label have been swapped.
+ bool swapped_language_placeholders_;
+
+ DISALLOW_COPY_AND_ASSIGN(TranslateInfoBar);
+};
+
+class BeforeTranslateInfoBar : public TranslateInfoBar {
+ public:
+ explicit BeforeTranslateInfoBar(BeforeTranslateInfoBarDelegate* delegate);
+ virtual ~BeforeTranslateInfoBar();
+
+ // Overridden from views::View:
+ virtual void Layout();
+
+ protected:
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ // Overriden from TranslateInfoBar:
+ virtual int GetSpacingAfterFirstLanguageButton() const {
+ return 10;
+ }
+
+ // Overridden from InfoBar:
+ virtual int GetAvailableWidth() const;
+
+ private:
+ TranslateTextButton* accept_button_;
+ TranslateTextButton* deny_button_;
+
+ DISALLOW_COPY_AND_ASSIGN(BeforeTranslateInfoBar);
+};
+
+class AfterTranslateInfoBar : public TranslateInfoBar {
+ public:
+ explicit AfterTranslateInfoBar(AfterTranslateInfoBarDelegate* delegate);
+ virtual ~AfterTranslateInfoBar();
+
+ // Overridden from views::MenuDelegate:
+ virtual void RunMenu(views::View* source, const gfx::Point& pt);
+
+ // Overridden from views::SimpleMenuModel::Delegate:
+ virtual void ExecuteCommand(int command_id);
+
+ protected:
+ // Overridden from InfoBar:
+ virtual int GetAvailableWidth() const;
+
+ virtual views::MenuButton* target_language_menu_button() const {
+ return target_language_menu_button_;
+ }
+
+ private:
+ views::MenuButton* target_language_menu_button_;
+
+ scoped_ptr<LanguagesMenuModel> target_language_menu_model_;
+
+ scoped_ptr<views::Menu2> target_language_menu_menu_;
+
+ DISALLOW_COPY_AND_ASSIGN(AfterTranslateInfoBar);
+};
+
+#endif // CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBARS_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6da2208e..a7ec0e2 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2262,6 +2262,14 @@
'browser/thumbnail_store.h',
'browser/toolbar_model.cc',
'browser/toolbar_model.h',
+ 'browser/translate/languages_menu_model.cc',
+ 'browser/translate/languages_menu_model.h',
+ 'browser/translate/options_menu_model.cc',
+ 'browser/translate/options_menu_model.h',
+ 'browser/translate/translate_infobars_delegates.cc',
+ 'browser/translate/translate_infobars_delegates.h',
+ 'browser/translate/translate_prefs.cc',
+ 'browser/translate/translate_prefs.h',
'browser/user_data_manager.cc',
'browser/user_data_manager.h',
'browser/utility_process_host.cc',
@@ -2406,6 +2414,8 @@
'browser/views/infobars/infobar_container.h',
'browser/views/infobars/infobars.cc',
'browser/views/infobars/infobars.h',
+ 'browser/views/infobars/translate_infobars.cc',
+ 'browser/views/infobars/translate_infobars.h',
'browser/views/jsmessage_box_dialog.cc',
'browser/views/jsmessage_box_dialog.h',
'browser/views/keyword_editor_view.cc',