diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-11 22:50:31 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-11 22:50:31 +0000 |
commit | d3ad7359b7bb6b279d71c2b9e2f0937a3413f0fb (patch) | |
tree | 3ff462c0bbcb18a7efee05cf7677d3a670784601 /chrome | |
parent | 9913ab8cc18beafd08427e3fd9d4786836e69949 (diff) | |
download | chromium_src-d3ad7359b7bb6b279d71c2b9e2f0937a3413f0fb.zip chromium_src-d3ad7359b7bb6b279d71c2b9e2f0937a3413f0fb.tar.gz chromium_src-d3ad7359b7bb6b279d71c2b9e2f0937a3413f0fb.tar.bz2 |
GTK: Implement translate toolbar. Tested on spiegel.de, www.lemonde.fr and mainichi.jp (from an English profile).
BUG=36714,37528
TEST=Open up a page that's not in your current language. You should be presented with a toolbar offering to apply Google Translate to the page.
Review URL: http://codereview.chromium.org/830005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_main.cc | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.cc | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.h | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/options/advanced_contents_gtk.cc | 85 | ||||
-rw-r--r-- | chrome/browser/gtk/options/advanced_contents_gtk.h | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/translate_infobars.cc | 370 | ||||
-rw-r--r-- | chrome/browser/gtk/translate_infobars.h | 99 | ||||
-rw-r--r-- | chrome/browser/translate/translate_infobars_delegates.cc | 9 | ||||
-rw-r--r-- | chrome/browser/views/infobars/translate_infobars.h | 4 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
11 files changed, 570 insertions, 22 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 8cadec5..ccba43d 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -844,12 +844,8 @@ int BrowserMain(const MainFunctionParams& parameters) { process_singleton.Create(); -#if !defined(OS_LINUX) // Create the TranslateManager singleton. - // TODO(jcampan): enable on Linux when the info-bars are implemented. - // http://crbug.com/36714 Singleton<TranslateManager>::get(); -#endif // !OS_LINUX // Show the First Run UI if this is the first time Chrome has been run on // this computer, or we're being compelled to do so by a command line flag. diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc index 88b60fb..c9512b2 100644 --- a/chrome/browser/gtk/gtk_util.cc +++ b/chrome/browser/gtk/gtk_util.cc @@ -424,14 +424,16 @@ void InitRCStyles() { gtk_rc_parse_string(kRCText); } -void CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, bool pack_at_end, - int padding) { +GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, + bool pack_at_end, int padding) { GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(centering_vbox), widget, TRUE, FALSE, 0); if (pack_at_end) gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, padding); else gtk_box_pack_start(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, padding); + + return centering_vbox; } std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) { diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h index dad4d6b..d2fca75 100644 --- a/chrome/browser/gtk/gtk_util.h +++ b/chrome/browser/gtk/gtk_util.h @@ -126,9 +126,10 @@ void InitRCStyles(); // Stick the widget in the given hbox without expanding vertically. The widget // is packed at the start of the hbox. This is useful for widgets that would -// otherwise expand to fill the vertical space of the hbox (e.g. buttons). -void CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, bool pack_at_end, - int padding); +// otherwise expand to fill the vertical space of the hbox +// (e.g. buttons). Returns the vbox that widget was packed in. +GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, + bool pack_at_end, int padding); // Change windows accelerator style to GTK style. (GTK uses _ for // accelerators. Windows uses & with && as an escape for &.) diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc index 79c3290..60d618c 100644 --- a/chrome/browser/gtk/infobar_gtk.cc +++ b/chrome/browser/gtk/infobar_gtk.cc @@ -162,8 +162,8 @@ void InfoBar::SetThemeProvider(GtkThemeProvider* theme_provider) { } void InfoBar::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { + const NotificationSource& source, + const NotificationDetails& details) { UpdateBorderColor(); } diff --git a/chrome/browser/gtk/options/advanced_contents_gtk.cc b/chrome/browser/gtk/options/advanced_contents_gtk.cc index 665da0e..edb9256 100644 --- a/chrome/browser/gtk/options/advanced_contents_gtk.cc +++ b/chrome/browser/gtk/options/advanced_contents_gtk.cc @@ -33,6 +33,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/gtk_signal.h" #include "chrome/common/pref_names.h" #include "chrome/common/process_watcher.h" #include "grit/chromium_strings.h" @@ -473,6 +474,85 @@ void NetworkSection::StartProxyConfigUtil(const ProxyConfigCommand& command) { } /////////////////////////////////////////////////////////////////////////////// +// TranslateSection + +class TranslateSection : public OptionsPageBase { + public: + explicit TranslateSection(Profile* profile); + virtual ~TranslateSection() {} + + GtkWidget* get_page_widget() const { + return page_; + } + + private: + // Overridden from OptionsPageBase. + virtual void NotifyPrefChanged(const std::wstring* pref_name); + + CHROMEGTK_CALLBACK_0(TranslateSection, void, OnTranslateClicked); + + // Preferences for this section: + BooleanPrefMember enable_translate_; + + // The widget containing the options for this section. + GtkWidget* page_; + + // The checkbox. + GtkWidget* translate_checkbox_; + + // Flag to ignore gtk callbacks while we are loading prefs, to avoid + // then turning around and saving them again. + bool pref_changing_; + + scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; + + DISALLOW_COPY_AND_ASSIGN(TranslateSection); +}; + +TranslateSection::TranslateSection(Profile* profile) + : OptionsPageBase(profile), + pref_changing_(true) { + page_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); + + accessible_widget_helper_.reset(new AccessibleWidgetHelper( + page_, profile)); + + translate_checkbox_ = CreateCheckButtonWithWrappedLabel( + IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE); + gtk_box_pack_start(GTK_BOX(page_), translate_checkbox_, + FALSE, FALSE, 0); + g_signal_connect(translate_checkbox_, "clicked", + G_CALLBACK(OnTranslateClickedThunk), this); + accessible_widget_helper_->SetWidgetName( + translate_checkbox_, + IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE); + + // Init member prefs so we can update the controls if prefs change. + enable_translate_.Init(prefs::kEnableTranslate, profile->GetPrefs(), this); + + NotifyPrefChanged(NULL); +} + +void TranslateSection::NotifyPrefChanged(const std::wstring* pref_name) { + pref_changing_ = true; + if (!pref_name || *pref_name == prefs::kAlternateErrorPagesEnabled) { + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(translate_checkbox_), enable_translate_.GetValue()); + } + pref_changing_ = false; +} + +void TranslateSection::OnTranslateClicked(GtkWidget* widget) { + if (pref_changing_) + return; + bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + UserMetricsRecordAction( + enabled ? "Options_Translate_Enable" : "Options_Translate_Disable", + profile()->GetPrefs()); + enable_translate_.SetValue(enabled); +} + +/////////////////////////////////////////////////////////////////////////////// // PrivacySection class PrivacySection : public OptionsPageBase { @@ -1102,6 +1182,11 @@ void AdvancedContentsGtk::Init() { l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK), network_section_->get_page_widget(), false); + translate_section_.reset(new TranslateSection(profile_)); + options_builder.AddOptionGroup( + l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_SECTION_TITLE_TRANSLATE), + translate_section_->get_page_widget(), false); + download_section_.reset(new DownloadSection(profile_)); options_builder.AddOptionGroup( l10n_util::GetStringUTF8(IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME), diff --git a/chrome/browser/gtk/options/advanced_contents_gtk.h b/chrome/browser/gtk/options/advanced_contents_gtk.h index befd3c5..40a04b62 100644 --- a/chrome/browser/gtk/options/advanced_contents_gtk.h +++ b/chrome/browser/gtk/options/advanced_contents_gtk.h @@ -15,6 +15,7 @@ class DownloadSection; class NetworkSection; class PrivacySection; class SecuritySection; +class TranslateSection; class WebContentSection; class AdvancedContentsGtk { @@ -35,6 +36,7 @@ class AdvancedContentsGtk { // The sections of the page. scoped_ptr<DownloadSection> download_section_; scoped_ptr<NetworkSection> network_section_; + scoped_ptr<TranslateSection> translate_section_; scoped_ptr<PrivacySection> privacy_section_; scoped_ptr<SecuritySection> security_section_; scoped_ptr<WebContentSection> web_content_section_; diff --git a/chrome/browser/gtk/translate_infobars.cc b/chrome/browser/gtk/translate_infobars.cc new file mode 100644 index 0000000..63ea67d --- /dev/null +++ b/chrome/browser/gtk/translate_infobars.cc @@ -0,0 +1,370 @@ +// 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_infobars.h" + +#include "app/l10n_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/gtk/gtk_util.h" +#include "chrome/browser/gtk/menu_gtk.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" +#include "chrome/browser/translate/options_menu_model.h" +#include "chrome/common/notification_service.h" +#include "grit/app_resources.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "grit/theme_resources.h" + +namespace { + +// Reorders the widgets in the NULL terminated array |widgets| that are all +// children of |box|. +void ReorderWidgetsTo(GtkWidget* box, GtkWidget** widgets) { + for (int count = 0; *widgets != NULL; widgets++) { + gtk_box_reorder_child(GTK_BOX(box), *widgets, count++); + gtk_widget_show_all(*widgets); + } +} + +// Creates a combobox set up to display text from a list of language codes +// (translating the codes into the display string). +GtkWidget* BuildLanguageComboboxFrom( + const std::vector<std::string>& languages) { + GtkListStore* model = gtk_list_store_new(1, G_TYPE_STRING); + for (std::vector<std::string>::const_iterator iter = languages.begin(); + iter != languages.end(); ++iter) { + GtkTreeIter tree_iter; + std::string name = UTF16ToUTF8( + TranslateInfoBarDelegate::GetDisplayNameForLocale(*iter)); + gtk_list_store_append(model, &tree_iter); + gtk_list_store_set(model, &tree_iter, 0, name.c_str(), -1); + } + + GtkWidget* combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); + 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", 0, NULL); + + return combobox; +} + +// Builds a button with an arrow in it to emulate the menu-button style from +// the windows version. +GtkWidget* 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; +} + +} // namespace + +TranslateInfoBar::TranslateInfoBar(TranslateInfoBarDelegate* delegate) + : InfoBar(delegate), + swapped_language_placeholders_(false) { + BuildWidgets(); + + // Register for PAGE_TRANSLATED notification. + notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED, + Source<TabContents>(GetDelegate()->tab_contents())); +} + +TranslateInfoBar::~TranslateInfoBar() { +} + +void TranslateInfoBar::Observe(NotificationType type, + const NotificationSource& source, const NotificationDetails& details) { + if (type.value == NotificationType::PAGE_TRANSLATED) { + TabContents* tab = Source<TabContents>(source).ptr(); + if (tab != GetDelegate()->tab_contents()) + return; + + UpdateState(TranslateInfoBarDelegate::kAfterTranslate); + } else { + InfoBar::Observe(type, source, details); + } +} + +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, + menus::Accelerator* accelerator) { + return false; +} + +void TranslateInfoBar::ExecuteCommand(int command_id) { + 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; + } +} + +void TranslateInfoBar::BuildWidgets() { + translate_box_ = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); + gtk_widget_set_no_show_all(translate_box_, TRUE); + + // Add all labels to the translate_box_. Unlike views or cocoa, there's no + // concept of manual layout in GTK, so we'll manually reorder these widgets + // inside |translate_box_| and selectively show and hide them. + label_1_ = gtk_label_new(NULL); + gtk_box_pack_start(GTK_BOX(translate_box_), label_1_, FALSE, FALSE, 0); + + label_2_ = gtk_label_new(NULL); + gtk_box_pack_start(GTK_BOX(translate_box_), label_2_, FALSE, FALSE, 0); + + label_3_ = gtk_label_new(NULL); + gtk_box_pack_start(GTK_BOX(translate_box_), label_3_, FALSE, FALSE, 0); + + translating_label_ = gtk_label_new( + l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_TRANSLATING).c_str()); + gtk_box_pack_start(GTK_BOX(translate_box_), translating_label_, + FALSE, FALSE, 0); + + accept_button_ = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_ACCEPT).c_str()); + g_signal_connect(accept_button_, "clicked", + G_CALLBACK(&OnAcceptPressedThunk), this); + accept_button_vbox_ = gtk_util::CenterWidgetInHBox( + translate_box_, accept_button_, false, 0); + + deny_button_ = gtk_button_new_with_label( + l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_DENY).c_str()); + g_signal_connect(deny_button_, "clicked", + G_CALLBACK(&OnDenyPressedThunk), this); + deny_button_vbox_ = gtk_util::CenterWidgetInHBox( + translate_box_, deny_button_, false, 0); + + std::vector<std::string> orig_languages; + GetDelegate()->GetAvailableOriginalLanguages(&orig_languages); + original_language_combobox_ = BuildLanguageComboboxFrom(orig_languages); + g_signal_connect(original_language_combobox_, "changed", + G_CALLBACK(&OnOriginalModifiedThunk), this); + original_language_combobox_vbox_ = gtk_util::CenterWidgetInHBox( + translate_box_, original_language_combobox_, false, 0); + + std::vector<std::string> target_languages; + GetDelegate()->GetAvailableTargetLanguages(&target_languages); + target_language_combobox_ = BuildLanguageComboboxFrom(target_languages); + g_signal_connect(target_language_combobox_, "changed", + G_CALLBACK(&OnTargetModifiedThunk), this); + target_language_combobox_vbox_ = gtk_util::CenterWidgetInHBox( + translate_box_, target_language_combobox_, false, 0); + + gtk_box_pack_start(GTK_BOX(hbox_), translate_box_, FALSE, FALSE, 0); + + // The options button sits outside the translate_box so that it can be end + // packed in hbox_. + 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); + + UpdateState(GetDelegate()->state()); + + gtk_widget_show_all(border_bin_.get()); +} + +void TranslateInfoBar::UpdateState( + TranslateInfoBarDelegate::TranslateState new_state) { + // Show the box... + gtk_widget_show(translate_box_); + // ...but hide all children of the translate box. They will be selectively + // unhidden and reordered based on the current translate state. + gtk_container_foreach( + GTK_CONTAINER(translate_box_), + reinterpret_cast<void (*)(GtkWidget*, void*)>(gtk_widget_hide_all), NULL); + + switch (new_state) { + case TranslateInfoBarDelegate::kBeforeTranslate: { + SetLabels(); + + GtkWidget* before_state[] = { + label_1_, + original_language_combobox_vbox_, + label_2_, + accept_button_vbox_, + deny_button_vbox_, + NULL + }; + ReorderWidgetsTo(translate_box_, before_state); + + gtk_combo_box_set_active(GTK_COMBO_BOX(original_language_combobox_), + GetDelegate()->original_lang_index()); + break; + } + case TranslateInfoBarDelegate::kTranslating: { + gtk_widget_show(translating_label_); + break; + } + case TranslateInfoBarDelegate::kAfterTranslate: { + SetLabels(); + GtkWidget* first_button_box = + swapped_language_placeholders_ ? + target_language_combobox_vbox_ : original_language_combobox_vbox_; + GtkWidget* second_button_box = + swapped_language_placeholders_ ? + original_language_combobox_vbox_ : target_language_combobox_vbox_; + + GtkWidget* after_state[] = { + label_1_, + first_button_box, + label_2_, + second_button_box, + label_3_, + NULL + }; + ReorderWidgetsTo(translate_box_, after_state); + + gtk_combo_box_set_active(GTK_COMBO_BOX(original_language_combobox_), + GetDelegate()->original_lang_index()); + gtk_combo_box_set_active(GTK_COMBO_BOX(target_language_combobox_), + GetDelegate()->target_lang_index()); + break; + } + default: { + NOTIMPLEMENTED() << "Received state " << new_state; + } + } + + // Clear options menu model so that it'll be created for new state. + options_menu_model_.reset(); +} + +void TranslateInfoBar::SetLabels() { + std::vector<size_t> offsets; + string16 message_text_utf16; + GetDelegate()->GetMessageText(&message_text_utf16, &offsets, + &swapped_language_placeholders_); + + string16 text = message_text_utf16.substr(0, offsets[0]); + gtk_label_set_text(GTK_LABEL(label_1_), UTF16ToUTF8(text).c_str()); + + text = message_text_utf16.substr(offsets[0], offsets[1] - offsets[0]); + gtk_label_set_text(GTK_LABEL(label_2_), UTF16ToUTF8(text).c_str()); + + if (offsets.size() == 3) { + text = message_text_utf16.substr(offsets[1], offsets[2] - offsets[1]); + gtk_label_set_text(GTK_LABEL(label_3_), UTF16ToUTF8(text).c_str()); + } +} + +TranslateInfoBarDelegate* TranslateInfoBar::GetDelegate() const { + return static_cast<TranslateInfoBarDelegate*>(delegate()); +} + +void TranslateInfoBar::LanguageModified() { + options_menu_model_.reset(); + + // Selecting an item from the "from language" menu in the before translate + // phase shouldn't trigger translation - http://crbug.com/36666 + if (GetDelegate()->state() == TranslateInfoBarDelegate::kAfterTranslate) + GetDelegate()->Translate(); +} + +void TranslateInfoBar::OnOriginalModified(GtkWidget* sender) { + int index = gtk_combo_box_get_active(GTK_COMBO_BOX(sender)); + if (index == GetDelegate()->original_lang_index()) + return; + + GetDelegate()->ModifyOriginalLanguage(index); + + LanguageModified(); +} + +void TranslateInfoBar::OnTargetModified(GtkWidget* sender) { + int index = gtk_combo_box_get_active(GTK_COMBO_BOX(sender)); + if (index == GetDelegate()->target_lang_index()) + return; + + GetDelegate()->ModifyTargetLanguage(index); + + LanguageModified(); +} + +void TranslateInfoBar::OnAcceptPressed(GtkWidget* sender) { + GetDelegate()->Translate(); + UpdateState(GetDelegate()->state()); +} + +void TranslateInfoBar::OnDenyPressed(GtkWidget* sender) { + GetDelegate()->TranslationDeclined(); + RemoveInfoBar(); +} + +void TranslateInfoBar::OnOptionsClicked(GtkWidget* sender) { + if (!options_menu_model_.get()) { + options_menu_model_.reset(new OptionsMenuModel(this, GetDelegate())); + options_menu_menu_.reset(new MenuGtk(this, options_menu_model_.get())); + } + options_menu_menu_->Popup(sender, 1, gtk_get_current_event_time()); +} + +// TranslateInfoBarDelegate, InfoBarDelegate overrides: ------------------ + +InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { + return new TranslateInfoBar(this); +} diff --git a/chrome/browser/gtk/translate_infobars.h b/chrome/browser/gtk/translate_infobars.h new file mode 100644 index 0000000..56f69c2 --- /dev/null +++ b/chrome/browser/gtk/translate_infobars.h @@ -0,0 +1,99 @@ +// 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_INFOBARS_H_ +#define CHROME_BROWSER_GTK_TRANSLATE_INFOBARS_H_ + +#include <gtk/gtk.h> + +#include "app/menus/simple_menu_model.h" +#include "chrome/browser/gtk/infobar_gtk.h" +#include "chrome/browser/gtk/menu_gtk.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" +#include "chrome/common/gtk_signal.h" +#include "chrome/common/notification_registrar.h" + +class OptionsMenuModel; + +// InfoBar that asks user if they want to translate a page that isn't in the +// user's language to their language. Bar changes during and after translation. +class TranslateInfoBar : public InfoBar, + public menus::SimpleMenuModel::Delegate, + public MenuGtk::Delegate { + public: + explicit TranslateInfoBar(TranslateInfoBarDelegate* delegate); + virtual ~TranslateInfoBar(); + + // Overridden from NotificationObserver (through InfoBar): + virtual void Observe(NotificationType type, + const NotificationSource& source, const NotificationDetails& details); + + // Overridden for both menus::SimpleMenuModel::Delegate and MenuGtk::Delegate: + virtual bool IsCommandIdChecked(int command_id) const; + virtual bool IsCommandIdEnabled(int command_id) const; + + // Overridden from menus::SimpleMenuModel::Delegate: + virtual bool GetAcceleratorForCommandId(int command_id, + menus::Accelerator* accelerator); + virtual void ExecuteCommand(int command_id); + + // Overridden from MenuGtk::Delegate: + virtual void ExecuteCommandById(int command_id) { + ExecuteCommand(command_id); + } + + private: + // Builds all the widgets and sets the initial view of the dialog. + void BuildWidgets(); + + // Changes the layout of the info bar, displaying the correct widgets in the + // correct order for |new_state|. + void UpdateState(TranslateInfoBarDelegate::TranslateState new_state); + + // Sets the text in the three labels for the current state. + void SetLabels(); + + // Casts delegate() to the only possible subclass. + TranslateInfoBarDelegate* GetDelegate() const; + + // Called after OnOriginalModified or OnTargetModified. + void LanguageModified(); + + CHROMEGTK_CALLBACK_0(TranslateInfoBar, void, OnOriginalModified); + CHROMEGTK_CALLBACK_0(TranslateInfoBar, void, OnTargetModified); + CHROMEGTK_CALLBACK_0(TranslateInfoBar, void, OnAcceptPressed); + CHROMEGTK_CALLBACK_0(TranslateInfoBar, void, OnDenyPressed); + CHROMEGTK_CALLBACK_0(TranslateInfoBar, void, OnOptionsClicked); + + GtkWidget* translate_box_; + GtkWidget* label_1_; + GtkWidget* label_2_; + GtkWidget* label_3_; + GtkWidget* translating_label_; + + GtkWidget* accept_button_; + GtkWidget* accept_button_vbox_; + + GtkWidget* deny_button_; + GtkWidget* deny_button_vbox_; + + GtkWidget* original_language_combobox_; + GtkWidget* original_language_combobox_vbox_; + + GtkWidget* target_language_combobox_; + GtkWidget* target_language_combobox_vbox_; + + GtkWidget* options_menu_button_; + scoped_ptr<MenuGtk> options_menu_menu_; + scoped_ptr<OptionsMenuModel> options_menu_model_; + + // This is true if language placeholders in label have been swapped. + bool swapped_language_placeholders_; + + NotificationRegistrar notification_registrar_; + + DISALLOW_COPY_AND_ASSIGN(TranslateInfoBar); +}; + +#endif // CHROME_BROWSER_GTK_TRANSLATE_INFOBARS_H_ diff --git a/chrome/browser/translate/translate_infobars_delegates.cc b/chrome/browser/translate/translate_infobars_delegates.cc index db03c5c..948e337 100644 --- a/chrome/browser/translate/translate_infobars_delegates.cc +++ b/chrome/browser/translate/translate_infobars_delegates.cc @@ -215,15 +215,6 @@ string16 TranslateInfoBarDelegate::GetDisplayNameForLocale( language_code, g_browser_process->GetApplicationLocale(), true); } -#if !defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) -// TranslateInfoBarDelegate: InfoBarDelegate overrides: ------------------------ - -InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { - NOTIMPLEMENTED(); - return NULL; -} -#endif // !TOOLKIT_VIEWS - // TranslateInfoBarDelegate: private: ------------------------------------------ TranslateInfoBarDelegate::TranslateInfoBarDelegate(TabContents* tab_contents, diff --git a/chrome/browser/views/infobars/translate_infobars.h b/chrome/browser/views/infobars/translate_infobars.h index 4cc7703..c343eb0 100644 --- a/chrome/browser/views/infobars/translate_infobars.h +++ b/chrome/browser/views/infobars/translate_infobars.h @@ -6,11 +6,11 @@ #define CHROME_BROWSER_VIEWS_INFOBARS_TRANSLATE_INFOBARS_H_ #include "app/menus/simple_menu_model.h" -#include "chrome/common/notification_registrar.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 "chrome/common/notification_registrar.h" #include "views/controls/menu/menu_2.h" +#include "views/controls/menu/view_menu_delegate.h" namespace views { class ImageButton; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 08441c5..49463ca 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1266,6 +1266,8 @@ 'browser/gtk/theme_install_bubble_view_gtk.h', 'browser/gtk/toolbar_star_toggle_gtk.cc', 'browser/gtk/toolbar_star_toggle_gtk.h', + 'browser/gtk/translate_infobars.cc', + 'browser/gtk/translate_infobars.h', 'browser/gtk/view_id_util.cc', 'browser/gtk/view_id_util.h', 'browser/hang_monitor/hung_plugin_action.cc', |