1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.h" 6 7#include "base/bind.h" 8#include "base/message_loop/message_loop.h" 9#include "base/strings/utf_string_conversions.h" 10#include "chrome/browser/translate/translate_infobar_delegate.h" 11#include "chrome/browser/ui/gtk/gtk_util.h" 12#include "grit/generated_resources.h" 13#include "ui/base/gtk/gtk_hig_constants.h" 14#include "ui/base/gtk/gtk_signal_registrar.h" 15#include "ui/base/l10n/l10n_util.h" 16 17AfterTranslateInfoBar::AfterTranslateInfoBar( 18 scoped_ptr<TranslateInfoBarDelegate> delegate) 19 : TranslateInfoBarBase(delegate.Pass()), 20 weak_factory_(this) { 21} 22 23AfterTranslateInfoBar::~AfterTranslateInfoBar() { 24} 25 26void AfterTranslateInfoBar::PlatformSpecificSetOwner() { 27 TranslateInfoBarBase::PlatformSpecificSetOwner(); 28 29 bool swapped_language_combos = false; 30 bool autodetermined_source_language = 31 GetDelegate()->original_language_index() == 32 TranslateInfoBarDelegate::kNoIndex; 33 34 std::vector<base::string16> strings; 35 TranslateInfoBarDelegate::GetAfterTranslateStrings( 36 &strings, &swapped_language_combos, autodetermined_source_language); 37 DCHECK_EQ(autodetermined_source_language ? 2U : 3U, strings.size()); 38 39 GtkWidget* new_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); 40 gtk_util::CenterWidgetInHBox(hbox(), new_hbox, false, 0); 41 42 size_t original_language_index = GetDelegate()->original_language_index(); 43 size_t target_language_index = GetDelegate()->target_language_index(); 44 bool exclude_the_other = original_language_index != target_language_index; 45 46 GtkWidget* original_lang_combo = NULL; 47 if (!autodetermined_source_language) { 48 original_lang_combo = CreateLanguageCombobox( 49 original_language_index, 50 exclude_the_other ? 51 target_language_index : TranslateInfoBarDelegate::kNoIndex); 52 signals()->Connect(original_lang_combo, "changed", 53 G_CALLBACK(&OnOriginalLanguageModifiedThunk), this); 54 } 55 GtkWidget* target_lang_combo = CreateLanguageCombobox( 56 target_language_index, 57 exclude_the_other ? original_language_index : 58 TranslateInfoBarDelegate::kNoIndex); 59 signals()->Connect(target_lang_combo, "changed", 60 G_CALLBACK(&OnTargetLanguageModifiedThunk), this); 61 62 gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[0])), 63 FALSE, FALSE, 0); 64 gtk_box_pack_start( 65 GTK_BOX(new_hbox), 66 (swapped_language_combos || autodetermined_source_language) ? 67 target_lang_combo : original_lang_combo, 68 FALSE, FALSE, 0); 69 gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[1])), 70 FALSE, FALSE, 0); 71 if (!autodetermined_source_language) { 72 gtk_box_pack_start(GTK_BOX(new_hbox), 73 swapped_language_combos ? 74 original_lang_combo : target_lang_combo, 75 FALSE, FALSE, 0); 76 gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[2])), 77 FALSE, FALSE, 0); 78 } 79 80 GtkWidget* button = gtk_button_new_with_label( 81 l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_REVERT).c_str()); 82 signals()->Connect(button, "clicked", 83 G_CALLBACK(&OnRevertPressedThunk), this); 84 gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0); 85} 86 87bool AfterTranslateInfoBar::ShowOptionsMenuButton() const { 88 return true; 89} 90 91void AfterTranslateInfoBar::SetOriginalLanguage(size_t language_index) { 92 GetDelegate()->UpdateOriginalLanguageIndex(language_index); 93 GetDelegate()->Translate(); 94} 95 96void AfterTranslateInfoBar::SetTargetLanguage(size_t language_index) { 97 GetDelegate()->UpdateTargetLanguageIndex(language_index); 98 GetDelegate()->Translate(); 99} 100 101void AfterTranslateInfoBar::OnOriginalLanguageModified(GtkWidget* sender) { 102 size_t index = GetLanguageComboboxActiveId(GTK_COMBO_BOX(sender)); 103 if (index == GetDelegate()->original_language_index()) 104 return; 105 106 // Setting the language will lead to a new translation that is going to close 107 // the infobar. This is not OK to do this from the signal handler, so we'll 108 // defer it. 109 base::MessageLoop::current()->PostTask( 110 FROM_HERE, 111 base::Bind(&AfterTranslateInfoBar::SetOriginalLanguage, 112 weak_factory_.GetWeakPtr(), 113 index)); 114} 115 116void AfterTranslateInfoBar::OnTargetLanguageModified(GtkWidget* sender) { 117 size_t index = GetLanguageComboboxActiveId(GTK_COMBO_BOX(sender)); 118 if (index == GetDelegate()->target_language_index()) 119 return; 120 121 // See comment in OnOriginalLanguageModified on why we use a task. 122 base::MessageLoop::current()->PostTask( 123 FROM_HERE, 124 base::Bind(&AfterTranslateInfoBar::SetTargetLanguage, 125 weak_factory_.GetWeakPtr(), 126 index)); 127} 128 129void AfterTranslateInfoBar::OnRevertPressed(GtkWidget* sender) { 130 GetDelegate()->RevertTranslation(); 131} 132