summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/translate
diff options
context:
space:
mode:
authorjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-19 00:52:05 +0000
committerjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-19 00:52:05 +0000
commitd905e7a7d5efb36cfa2ac0e474ffe8fed5008017 (patch)
tree76dda9173e629f7367f2511d19653fbdfd43c0de /chrome/browser/gtk/translate
parent6dc033c2daee6c71bec401c3324c4440975561bc (diff)
downloadchromium_src-d905e7a7d5efb36cfa2ac0e474ffe8fed5008017.zip
chromium_src-d905e7a7d5efb36cfa2ac0e474ffe8fed5008017.tar.gz
chromium_src-d905e7a7d5efb36cfa2ac0e474ffe8fed5008017.tar.bz2
Porting the infobars on Linux to the new TranslateInfobarDelegate2 (relanding)
Each translate infobar is now its own class and most of the logic is in the delegate. Original review: http://codereview.chromium.org/2836006/show BUG=40828 TEST=Thoroughly test the translate feature on Linux. Review URL: http://codereview.chromium.org/2817015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50308 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/translate')
-rw-r--r--chrome/browser/gtk/translate/after_translate_infobar_gtk.cc101
-rw-r--r--chrome/browser/gtk/translate/after_translate_infobar_gtk.h39
-rw-r--r--chrome/browser/gtk/translate/before_translate_infobar_gtk.cc71
-rw-r--r--chrome/browser/gtk/translate/before_translate_infobar_gtk.h31
-rw-r--r--chrome/browser/gtk/translate/translate_infobar_base_gtk.cc237
-rw-r--r--chrome/browser/gtk/translate/translate_infobar_base_gtk.h87
-rw-r--r--chrome/browser/gtk/translate/translate_message_infobar_gtk.cc40
-rw-r--r--chrome/browser/gtk/translate/translate_message_infobar_gtk.h26
8 files changed, 632 insertions, 0 deletions
diff --git a/chrome/browser/gtk/translate/after_translate_infobar_gtk.cc b/chrome/browser/gtk/translate/after_translate_infobar_gtk.cc
new file mode 100644
index 0000000..1fab560
--- /dev/null
+++ b/chrome/browser/gtk/translate/after_translate_infobar_gtk.cc
@@ -0,0 +1,101 @@
+// 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/gtk/translate/after_translate_infobar_gtk.h"
+
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/translate/translate_infobar_delegate2.h"
+#include "grit/generated_resources.h"
+
+AfterTranslateInfoBar::AfterTranslateInfoBar(
+ TranslateInfoBarDelegate2* delegate)
+ : TranslateInfoBarBase(delegate),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+}
+
+AfterTranslateInfoBar::~AfterTranslateInfoBar() {
+}
+
+void AfterTranslateInfoBar::Init() {
+ TranslateInfoBarBase::Init();
+
+ bool swapped_language_combos = false;
+ std::vector<string16> strings;
+ TranslateInfoBarDelegate2::GetAfterTranslateStrings(
+ &strings, &swapped_language_combos);
+ DCHECK(strings.size() == 3U);
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
+ gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+
+ GtkWidget* original_lang_combo =
+ CreateLanguageCombobox(GetDelegate()->original_language_index(),
+ GetDelegate()->target_language_index());
+ g_signal_connect(original_lang_combo, "changed",
+ G_CALLBACK(&OnOriginalLanguageModifiedThunk), this);
+ GtkWidget* target_lang_combo =
+ CreateLanguageCombobox(GetDelegate()->target_language_index(),
+ GetDelegate()->original_language_index());
+ g_signal_connect(target_lang_combo, "changed",
+ G_CALLBACK(&OnTargetLanguageModifiedThunk), this);
+
+ gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[0])),
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ swapped_language_combos ? target_lang_combo :
+ original_lang_combo,
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[1])),
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ swapped_language_combos ? original_lang_combo :
+ target_lang_combo,
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[2])),
+ FALSE, FALSE, 0);
+
+ GtkWidget* button = gtk_button_new_with_label(
+ l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_REVERT).c_str());
+ g_signal_connect(button, "clicked",G_CALLBACK(&OnRevertPressedThunk), this);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(border_bin_.get());
+}
+
+void AfterTranslateInfoBar::OnOriginalLanguageModified(GtkWidget* sender) {
+ int index = GetLanguageComboboxActiveId(GTK_COMBO_BOX(sender));
+ if (index == GetDelegate()->original_language_index())
+ return;
+
+ // Setting the language will lead to a new translation that is going to close
+ // the infobar. This is not OK to do this from the signal handler, so we'll
+ // defer it.
+ MessageLoop::current()->PostTask(FROM_HERE, method_factory_.NewRunnableMethod(
+ &AfterTranslateInfoBar::SetOriginalLanguage, index));
+}
+
+void AfterTranslateInfoBar::OnTargetLanguageModified(GtkWidget* sender) {
+ int index = GetLanguageComboboxActiveId(GTK_COMBO_BOX(sender));
+ if (index == GetDelegate()->target_language_index())
+ return;
+
+ // See comment in OnOriginalLanguageModified on why we use a task.
+ MessageLoop::current()->PostTask(FROM_HERE, method_factory_.NewRunnableMethod(
+ &AfterTranslateInfoBar::SetTargetLanguage, index));
+}
+
+void AfterTranslateInfoBar::OnRevertPressed(GtkWidget* sender) {
+ GetDelegate()->RevertTranslation();
+}
+
+void AfterTranslateInfoBar::SetOriginalLanguage(int language_index) {
+ GetDelegate()->SetOriginalLanguage(language_index);
+}
+
+void AfterTranslateInfoBar::SetTargetLanguage(int language_index) {
+ GetDelegate()->SetTargetLanguage(language_index);
+}
diff --git a/chrome/browser/gtk/translate/after_translate_infobar_gtk.h b/chrome/browser/gtk/translate/after_translate_infobar_gtk.h
new file mode 100644
index 0000000..576b023
--- /dev/null
+++ b/chrome/browser/gtk/translate/after_translate_infobar_gtk.h
@@ -0,0 +1,39 @@
+// 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_GTK_TRANSLATE_AFTER_TRANSLATE_INFOBAR_GTK_H_
+#define CHROME_BROWSER_GTK_TRANSLATE_AFTER_TRANSLATE_INFOBAR_GTK_H_
+
+#include "base/task.h"
+#include "chrome/browser/gtk/translate/translate_infobar_base_gtk.h"
+
+class TranslateInfoBarDelegate2;
+
+class AfterTranslateInfoBar : public TranslateInfoBarBase {
+ public:
+ explicit AfterTranslateInfoBar(TranslateInfoBarDelegate2* delegate);
+ virtual ~AfterTranslateInfoBar();
+
+ // Overridden from TranslateInfoBarBase:
+ virtual void Init();
+
+ protected:
+ virtual bool ShowOptionsMenuButton() const { return true; }
+
+ private:
+ CHROMEGTK_CALLBACK_0(AfterTranslateInfoBar, void, OnOriginalLanguageModified);
+ CHROMEGTK_CALLBACK_0(AfterTranslateInfoBar, void, OnTargetLanguageModified);
+ CHROMEGTK_CALLBACK_0(AfterTranslateInfoBar, void, OnRevertPressed);
+
+ // These methods set the original/target language on the
+ // TranslateInfobarDelegate.
+ void SetOriginalLanguage(int language_index);
+ void SetTargetLanguage(int language_index);
+
+ ScopedRunnableMethodFactory<AfterTranslateInfoBar> method_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AfterTranslateInfoBar);
+};
+
+#endif // CHROME_BROWSER_GTK_TRANSLATE_AFTER_TRANSLATE_INFOBAR_GTK_H_
diff --git a/chrome/browser/gtk/translate/before_translate_infobar_gtk.cc b/chrome/browser/gtk/translate/before_translate_infobar_gtk.cc
new file mode 100644
index 0000000..53b9773
--- /dev/null
+++ b/chrome/browser/gtk/translate/before_translate_infobar_gtk.cc
@@ -0,0 +1,71 @@
+// 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/gtk/translate/before_translate_infobar_gtk.h"
+
+#include "app/l10n_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/translate/translate_infobar_delegate2.h"
+#include "grit/generated_resources.h"
+
+BeforeTranslateInfoBar::BeforeTranslateInfoBar(
+ TranslateInfoBarDelegate2* delegate)
+ : TranslateInfoBarBase(delegate) {
+}
+
+BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
+}
+
+void BeforeTranslateInfoBar::Init() {
+ TranslateInfoBarBase::Init();
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
+ gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+ size_t offset = 0;
+ string16 text =
+ l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE,
+ string16(), &offset);
+
+ gtk_box_pack_start(GTK_BOX(hbox),
+ CreateLabel(UTF16ToUTF8(text.substr(0, offset))),
+ FALSE, FALSE, 0);
+ GtkWidget* combobox =
+ CreateLanguageCombobox(GetDelegate()->original_language_index(),
+ GetDelegate()->target_language_index());
+ g_signal_connect(combobox, "changed",
+ G_CALLBACK(&OnLanguageModifiedThunk), this);
+ gtk_box_pack_start(GTK_BOX(hbox), combobox, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ CreateLabel(UTF16ToUTF8(text.substr(offset))),
+ FALSE, FALSE, 0);
+
+ GtkWidget* button = gtk_button_new_with_label(
+ l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_ACCEPT).c_str());
+ g_signal_connect(button, "clicked",G_CALLBACK(&OnAcceptPressedThunk), this);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+ button = gtk_button_new_with_label(
+ l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_DENY).c_str());
+ g_signal_connect(button, "clicked",G_CALLBACK(&OnDenyPressedThunk), this);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(border_bin_.get());
+}
+
+void BeforeTranslateInfoBar::OnLanguageModified(GtkWidget* sender) {
+ int index = GetLanguageComboboxActiveId(GTK_COMBO_BOX(sender));
+ if (index == GetDelegate()->original_language_index())
+ return;
+
+ GetDelegate()->SetOriginalLanguage(index);
+}
+
+void BeforeTranslateInfoBar::OnAcceptPressed(GtkWidget* sender) {
+ GetDelegate()->Translate();
+}
+
+void BeforeTranslateInfoBar::OnDenyPressed(GtkWidget* sender) {
+ RemoveInfoBar();
+}
diff --git a/chrome/browser/gtk/translate/before_translate_infobar_gtk.h b/chrome/browser/gtk/translate/before_translate_infobar_gtk.h
new file mode 100644
index 0000000..f31c529
--- /dev/null
+++ b/chrome/browser/gtk/translate/before_translate_infobar_gtk.h
@@ -0,0 +1,31 @@
+// 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_GTK_TRANSLATE_BEFORE_TRANSLATE_INFOBAR_GTK_H_
+#define CHROME_BROWSER_GTK_TRANSLATE_BEFORE_TRANSLATE_INFOBAR_GTK_H_
+
+#include "chrome/browser/gtk/translate/translate_infobar_base_gtk.h"
+
+class TranslateInfoBarDelegate2;
+
+class BeforeTranslateInfoBar : public TranslateInfoBarBase {
+ public:
+ explicit BeforeTranslateInfoBar(TranslateInfoBarDelegate2* delegate);
+ virtual ~BeforeTranslateInfoBar();
+
+ // Overridden from TranslateInfoBarBase:
+ virtual void Init();
+
+ protected:
+ virtual bool ShowOptionsMenuButton() const { return true; }
+
+ private:
+ CHROMEGTK_CALLBACK_0(BeforeTranslateInfoBar, void, OnLanguageModified);
+ CHROMEGTK_CALLBACK_0(BeforeTranslateInfoBar, void, OnAcceptPressed);
+ CHROMEGTK_CALLBACK_0(BeforeTranslateInfoBar, void, OnDenyPressed);
+
+ DISALLOW_COPY_AND_ASSIGN(BeforeTranslateInfoBar);
+};
+
+#endif // CHROME_BROWSER_GTK_TRANSLATE_BEFORE_TRANSLATE_INFOBAR_GTK_H_
diff --git a/chrome/browser/gtk/translate/translate_infobar_base_gtk.cc b/chrome/browser/gtk/translate/translate_infobar_base_gtk.cc
new file mode 100644
index 0000000..a2d46e0
--- /dev/null
+++ b/chrome/browser/gtk/translate/translate_infobar_base_gtk.cc
@@ -0,0 +1,237 @@
+// 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/gtk/translate/translate_infobar_base_gtk.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "app/slide_animation.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/translate/options_menu_model2.h"
+#include "chrome/browser/translate/translate_infobar_delegate2.h"
+#include "chrome/browser/gtk/translate/after_translate_infobar_gtk.h"
+#include "chrome/browser/gtk/translate/before_translate_infobar_gtk.h"
+#include "chrome/browser/gtk/translate/translate_message_infobar_gtk.h"
+#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/gtk/menu_gtk.h"
+#include "gfx/canvas.h"
+#include "gfx/gtk_util.h"
+#include "grit/generated_resources.h"
+
+namespace {
+
+// To be able to map from language id <-> entry in the combo box, we
+// store the language id in the combo box data model in addition to the
+// displayed name.
+enum {
+ LANGUAGE_COMBO_COLUMN_ID,
+ LANGUAGE_COMBO_COLUMN_NAME,
+ LANGUAGE_COMBO_COLUMN_COUNT
+};
+
+} // namespace
+
+TranslateInfoBarBase::TranslateInfoBarBase(TranslateInfoBarDelegate2* delegate)
+ : InfoBar(delegate) {
+ TranslateInfoBarDelegate2::BackgroundAnimationType animation =
+ delegate->background_animation_type();
+ if (animation != TranslateInfoBarDelegate2::NONE) {
+ background_color_animation_.reset(new SlideAnimation(this));
+ background_color_animation_->SetTweenType(Tween::LINEAR);
+ background_color_animation_->SetSlideDuration(500);
+ if (animation == TranslateInfoBarDelegate2::NORMAL_TO_ERROR) {
+ background_color_animation_->Show();
+ } else {
+ DCHECK_EQ(TranslateInfoBarDelegate2::ERROR_TO_NORMAL, animation);
+ // Hide() runs the animation in reverse.
+ background_color_animation_->Reset(1.0);
+ background_color_animation_->Hide();
+ }
+ }
+}
+
+TranslateInfoBarBase::~TranslateInfoBarBase() {
+}
+
+void TranslateInfoBarBase::Init() {
+ if (!ShowOptionsMenuButton())
+ return;
+
+ // The options button sits outside the translate_box so that it can be end
+ // packed in hbox_.
+ GtkWidget* options_menu_button = BuildOptionsMenuButton();
+ g_signal_connect(options_menu_button, "clicked",
+ G_CALLBACK(&OnOptionsClickedThunk), this);
+ gtk_widget_show_all(options_menu_button);
+ gtk_util::CenterWidgetInHBox(hbox_, options_menu_button, true, 0);
+}
+
+void TranslateInfoBarBase::GetTopColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b) {
+ if (background_error_percent_ <= 0) {
+ InfoBar::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
+ } else if (background_error_percent_ >= 1) {
+ InfoBar::GetTopColor(InfoBarDelegate::ERROR_TYPE, r, g, b);
+ } else {
+ double normal_r, normal_g, normal_b;
+ InfoBar::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE,
+ &normal_r, &normal_g, &normal_b);
+
+ double error_r, error_g, error_b;
+ InfoBar::GetTopColor(InfoBarDelegate::ERROR_TYPE,
+ &error_r, &error_g, &error_b);
+
+ double offset_r = error_r - normal_r;
+ double offset_g = error_g - normal_g;
+ double offset_b = error_b - normal_b;
+
+ *r = normal_r + (background_error_percent_ * offset_r);
+ *g = normal_g + (background_error_percent_ * offset_g);
+ *b = normal_b + (background_error_percent_ * offset_b);
+ }
+}
+
+void TranslateInfoBarBase::GetBottomColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b) {
+ if (background_error_percent_ <= 0) {
+ InfoBar::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
+ } else if (background_error_percent_ >= 1) {
+ InfoBar::GetBottomColor(InfoBarDelegate::ERROR_TYPE, r, g, b);
+ } else {
+ double normal_r, normal_g, normal_b;
+ InfoBar::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE,
+ &normal_r, &normal_g, &normal_b);
+
+ double error_r, error_g, error_b;
+ InfoBar::GetBottomColor(InfoBarDelegate::ERROR_TYPE,
+ &error_r, &error_g, &error_b);
+
+ double offset_r = error_r - normal_r;
+ double offset_g = error_g - normal_g;
+ double offset_b = error_b - normal_b;
+
+ *r = normal_r + (background_error_percent_ * offset_r);
+ *g = normal_g + (background_error_percent_ * offset_g);
+ *b = normal_b + (background_error_percent_ * offset_b);
+ }
+}
+
+void TranslateInfoBarBase::AnimationProgressed(const Animation* animation) {
+ DCHECK(animation == background_color_animation_.get());
+ background_error_percent_ = animation->GetCurrentValue();
+ // Queue the info bar widget for redisplay so it repaints its background.
+ gtk_widget_queue_draw(widget());
+}
+
+GtkWidget* TranslateInfoBarBase::CreateLabel(const std::string& text) {
+ GtkWidget* label = gtk_label_new(text.c_str());
+ gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
+ return label;
+}
+
+GtkWidget* TranslateInfoBarBase::CreateLanguageCombobox(int selected_language,
+ int exclude_language) {
+ GtkListStore* model = gtk_list_store_new(LANGUAGE_COMBO_COLUMN_COUNT,
+ G_TYPE_INT, G_TYPE_STRING);
+ bool set_selection = false;
+ GtkTreeIter selected_iter;
+ TranslateInfoBarDelegate2* delegate = GetDelegate();
+ for (int i = 0; i < delegate->GetLanguageCount(); ++i) {
+ if (i == exclude_language)
+ continue;
+ GtkTreeIter tree_iter;
+ const string16& name = delegate->GetLanguageDisplayableNameAt(i);
+
+ gtk_list_store_append(model, &tree_iter);
+ gtk_list_store_set(model, &tree_iter,
+ LANGUAGE_COMBO_COLUMN_ID, i,
+ LANGUAGE_COMBO_COLUMN_NAME, UTF16ToUTF8(name).c_str(),
+ -1);
+ if (i == selected_language) {
+ selected_iter = tree_iter;
+ set_selection = true;
+ }
+ }
+
+ GtkWidget* combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
+ if (set_selection)
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combobox), &selected_iter);
+ g_object_unref(model);
+ GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer,
+ "text", LANGUAGE_COMBO_COLUMN_NAME,
+ NULL);
+ return combobox;
+}
+
+// static
+int TranslateInfoBarBase::GetLanguageComboboxActiveId(GtkComboBox* combo) {
+ GtkTreeIter iter;
+ if (!gtk_combo_box_get_active_iter(combo, &iter))
+ return 0;
+
+ gint id = 0;
+ gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter,
+ LANGUAGE_COMBO_COLUMN_ID, &id,
+ -1);
+ return id;
+}
+
+TranslateInfoBarDelegate2* TranslateInfoBarBase::GetDelegate() const {
+ return static_cast<TranslateInfoBarDelegate2*>(delegate());
+}
+
+// static
+GtkWidget* TranslateInfoBarBase::BuildOptionsMenuButton() {
+ GtkWidget* button = gtk_button_new();
+ GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button));
+ if (former_child)
+ gtk_container_remove(GTK_CONTAINER(button), former_child);
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
+
+ GtkWidget* label = gtk_label_new(
+ l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS).c_str());
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ gtk_box_pack_start(GTK_BOX(hbox), arrow, FALSE, FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(button), hbox);
+
+ return button;
+}
+
+void TranslateInfoBarBase::OnOptionsClicked(GtkWidget* sender) {
+ if (!options_menu_model_.get()) {
+ options_menu_model_.reset(new OptionsMenuModel2(GetDelegate()));
+ options_menu_menu_.reset(new MenuGtk(NULL, options_menu_model_.get()));
+ }
+ options_menu_menu_->Popup(sender, 1, gtk_get_current_event_time());
+}
+
+// TranslateInfoBarDelegate specific method:
+InfoBar* TranslateInfoBarDelegate2::CreateInfoBar() {
+ TranslateInfoBarBase* infobar = NULL;
+ switch (type_) {
+ case BEFORE_TRANSLATE:
+ infobar = new BeforeTranslateInfoBar(this);
+ break;
+ case AFTER_TRANSLATE:
+ infobar = new AfterTranslateInfoBar(this);
+ break;
+ case TRANSLATING:
+ case TRANSLATION_ERROR:
+ infobar = new TranslateMessageInfoBar(this);
+ break;
+ default:
+ NOTREACHED();
+ }
+ infobar->Init();
+ // Set |infobar_view_| so that the model can notify the infobar when it
+ // changes.
+ infobar_view_ = infobar;
+ return infobar;
+}
diff --git a/chrome/browser/gtk/translate/translate_infobar_base_gtk.h b/chrome/browser/gtk/translate/translate_infobar_base_gtk.h
new file mode 100644
index 0000000..f2911f6
--- /dev/null
+++ b/chrome/browser/gtk/translate/translate_infobar_base_gtk.h
@@ -0,0 +1,87 @@
+// 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_GTK_TRANSLATE_TRANSLATE_INFOBAR_BASE_GTK_H_
+#define CHROME_BROWSER_GTK_TRANSLATE_TRANSLATE_INFOBAR_BASE_GTK_H_
+
+#include "chrome/browser/translate/translate_infobar_view.h"
+#include "chrome/browser/gtk/infobar_gtk.h"
+
+class MenuGtk;
+class OptionsMenuModel2;
+class TranslateInfoBarDelegate2;
+
+// This class contains some of the base functionality that translate infobars
+// use.
+class TranslateInfoBarBase : public TranslateInfoBarView,
+ public InfoBar,
+ public AnimationDelegate {
+ public:
+ explicit TranslateInfoBarBase(TranslateInfoBarDelegate2* delegate);
+ virtual ~TranslateInfoBarBase();
+
+ // Initializes the infobar widgets. Should be called after the object has been
+ // created.
+ virtual void Init();
+
+ // Overridden from InfoBar:
+ virtual void GetTopColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b);
+ virtual void GetBottomColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b);
+
+ // Overridden from TranslateInfoBarView:
+ virtual void OriginalLanguageChanged() {}
+ virtual void TargetLanguageChanged() {}
+
+ // Overridden from AnimationDelegate:
+ virtual void AnimationProgressed(const Animation* animation);
+
+ protected:
+ // Sub-classes that want to have the options menu button showing sould
+ // override and return true.
+ virtual bool ShowOptionsMenuButton() const { return false; }
+
+ // Creates a label with the appropriate font and color for the translate
+ // infobars.
+ GtkWidget* CreateLabel(const std::string& text);
+
+ // Creates a combobox that displays the languages currently available.
+ // |selected_language| is the language index (as used in the
+ // TranslateInfoDelegate) that should be selected initially.
+ // |exclude_language| is the language index of the language that should not be
+ // included in the list (-1 means no language excluded).
+ GtkWidget* CreateLanguageCombobox(int selected_language,
+ int exclude_language);
+
+ // Given an above-constructed combobox, returns the currently selected
+ // language id.
+ static int GetLanguageComboboxActiveId(GtkComboBox* combo);
+
+ // Convenience to retrieve the TranslateInfoBarDelegate2 for this infobar.
+ TranslateInfoBarDelegate2* GetDelegate() const;
+
+ private:
+ // Builds a button with an arrow in it to emulate the menu-button style from
+ // the windows version.
+ static GtkWidget* BuildOptionsMenuButton();
+
+ // The menu displayed when the Options button is pressed.
+ scoped_ptr<OptionsMenuModel2> options_menu_model_;
+ scoped_ptr<MenuGtk> options_menu_menu_;
+
+ CHROMEGTK_CALLBACK_0(TranslateInfoBarBase, void, OnOptionsClicked);
+
+ // A percentage to average the normal page action background with the error
+ // background. When 0, the infobar background should be pure PAGE_ACTION_TYPE.
+ // When 1, the infobar background should be pure ERROR_TYPE.
+ double background_error_percent_;
+
+ // Changes the color of the background from normal to error color and back.
+ scoped_ptr<SlideAnimation> background_color_animation_;
+
+ DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarBase);
+};
+
+#endif // CHROME_BROWSER_GTK_TRANSLATE_TRANSLATE_INFOBAR_BASE_GTK_H_
diff --git a/chrome/browser/gtk/translate/translate_message_infobar_gtk.cc b/chrome/browser/gtk/translate/translate_message_infobar_gtk.cc
new file mode 100644
index 0000000..3a5b828
--- /dev/null
+++ b/chrome/browser/gtk/translate/translate_message_infobar_gtk.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/gtk/translate/translate_message_infobar_gtk.h"
+
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/translate/translate_infobar_delegate2.h"
+
+TranslateMessageInfoBar::TranslateMessageInfoBar(
+ TranslateInfoBarDelegate2* delegate)
+ : TranslateInfoBarBase(delegate) {
+}
+
+TranslateMessageInfoBar::~TranslateMessageInfoBar() {
+}
+
+void TranslateMessageInfoBar::Init() {
+ TranslateInfoBarBase::Init();
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
+ gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+
+ std::string text = UTF16ToUTF8(GetDelegate()->GetMessageInfoBarText());
+ gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(text.c_str()), FALSE, FALSE, 0);
+ string16 button_text = GetDelegate()->GetMessageInfoBarButtonText();
+ if (!button_text.empty()) {
+ GtkWidget* button =
+ gtk_button_new_with_label(UTF16ToUTF8(button_text).c_str());
+ g_signal_connect(button, "clicked",G_CALLBACK(&OnButtonPressedThunk), this);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ }
+
+ gtk_widget_show_all(border_bin_.get());
+}
+
+void TranslateMessageInfoBar::OnButtonPressed(GtkWidget* sender) {
+ GetDelegate()->MessageInfoBarButtonPressed();
+}
diff --git a/chrome/browser/gtk/translate/translate_message_infobar_gtk.h b/chrome/browser/gtk/translate/translate_message_infobar_gtk.h
new file mode 100644
index 0000000..f0e70a3
--- /dev/null
+++ b/chrome/browser/gtk/translate/translate_message_infobar_gtk.h
@@ -0,0 +1,26 @@
+// 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_GTK_TRANSLATE_TRANSLATE_MESSAGE_INFOBAR_GTK_H_
+#define CHROME_BROWSER_GTK_TRANSLATE_TRANSLATE_MESSAGE_INFOBAR_GTK_H_
+
+#include "chrome/browser/gtk/translate/translate_infobar_base_gtk.h"
+
+class TranslateInfoBarDelegate2;
+
+class TranslateMessageInfoBar : public TranslateInfoBarBase {
+ public:
+ explicit TranslateMessageInfoBar(TranslateInfoBarDelegate2* delegate);
+ virtual ~TranslateMessageInfoBar();
+
+ // Overridden from TranslateInfoBarBase:
+ virtual void Init();
+
+ private:
+ CHROMEGTK_CALLBACK_0(TranslateMessageInfoBar, void, OnButtonPressed);
+
+ DISALLOW_COPY_AND_ASSIGN(TranslateMessageInfoBar);
+};
+
+#endif // CHROME_BROWSER_GTK_TRANSLATE_TRANSLATE_MESSAGE_INFOBAR_GTK_H_