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/views/infobars/before_translate_infobar.h" 6 7 #include "base/utf_string_conversions.h" 8 #include "chrome/browser/translate/translate_infobar_delegate.h" 9 #include "grit/generated_resources.h" 10 #include "ui/base/l10n/l10n_util.h" 11 #include "views/controls/button/menu_button.h" 12 #include "views/controls/label.h" 13 #include "views/controls/menu/menu_2.h" 14 15 BeforeTranslateInfoBar::BeforeTranslateInfoBar( 16 TranslateInfoBarDelegate* delegate) 17 : TranslateInfoBarBase(delegate), 18 label_1_(NULL), 19 label_2_(NULL), 20 language_menu_button_(NULL), 21 accept_button_(NULL), 22 deny_button_(NULL), 23 never_translate_button_(NULL), 24 always_translate_button_(NULL), 25 options_menu_button_(NULL), 26 languages_menu_model_(delegate, LanguagesMenuModel::ORIGINAL), 27 languages_menu_(new views::Menu2(&languages_menu_model_)), 28 options_menu_model_(delegate), 29 options_menu_(new views::Menu2(&options_menu_model_)) { 30 } 31 32 BeforeTranslateInfoBar::~BeforeTranslateInfoBar() { 33 } 34 35 void BeforeTranslateInfoBar::Layout() { 36 TranslateInfoBarBase::Layout(); 37 38 int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth()); 39 gfx::Size label_1_size = label_1_->GetPreferredSize(); 40 label_1_->SetBounds(StartX(), OffsetY(label_1_size), 41 std::min(label_1_size.width(), available_width), label_1_size.height()); 42 available_width = std::max(0, available_width - label_1_size.width()); 43 44 gfx::Size language_button_size = language_menu_button_->GetPreferredSize(); 45 language_menu_button_->SetBounds( 46 label_1_->bounds().right() + kButtonInLabelSpacing, 47 OffsetY(language_button_size), language_button_size.width(), 48 language_button_size.height()); 49 50 gfx::Size label_2_size = label_2_->GetPreferredSize(); 51 label_2_->SetBounds( 52 language_menu_button_->bounds().right() + kButtonInLabelSpacing, 53 OffsetY(label_2_size), std::min(label_2_size.width(), available_width), 54 label_2_size.height()); 55 56 gfx::Size accept_button_size = accept_button_->GetPreferredSize(); 57 accept_button_->SetBounds(label_2_->bounds().right() + kEndOfLabelSpacing, 58 OffsetY(accept_button_size), accept_button_size.width(), 59 accept_button_size.height()); 60 61 gfx::Size deny_button_size = deny_button_->GetPreferredSize(); 62 deny_button_->SetBounds( 63 accept_button_->bounds().right() + kButtonButtonSpacing, 64 OffsetY(deny_button_size), deny_button_size.width(), 65 deny_button_size.height()); 66 67 if (never_translate_button_) { 68 gfx::Size never_button_size = never_translate_button_->GetPreferredSize(); 69 never_translate_button_->SetBounds( 70 deny_button_->bounds().right() + kButtonButtonSpacing, 71 OffsetY(never_button_size), never_button_size.width(), 72 never_button_size.height()); 73 } 74 75 if (always_translate_button_) { 76 gfx::Size always_button_size = always_translate_button_->GetPreferredSize(); 77 always_translate_button_->SetBounds( 78 deny_button_->bounds().right() + kButtonButtonSpacing, 79 OffsetY(always_button_size), always_button_size.width(), 80 always_button_size.height()); 81 } 82 83 gfx::Size options_size = options_menu_button_->GetPreferredSize(); 84 options_menu_button_->SetBounds(EndX() - options_size.width(), 85 OffsetY(options_size), options_size.width(), options_size.height()); 86 } 87 88 void BeforeTranslateInfoBar::ViewHierarchyChanged(bool is_add, 89 View* parent, 90 View* child) { 91 if (!is_add || (child != this) || (label_1_ != NULL)) { 92 TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child); 93 return; 94 } 95 96 size_t offset = 0; 97 string16 text(l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE, 98 string16(), &offset)); 99 100 label_1_ = CreateLabel(text.substr(0, offset)); 101 AddChildView(label_1_); 102 103 language_menu_button_ = CreateMenuButton(string16(), true, this); 104 AddChildView(language_menu_button_); 105 106 label_2_ = CreateLabel(text.substr(offset)); 107 AddChildView(label_2_); 108 109 accept_button_ = CreateTextButton(this, 110 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_ACCEPT), false); 111 AddChildView(accept_button_); 112 113 deny_button_ = CreateTextButton(this, 114 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_DENY), false); 115 AddChildView(deny_button_); 116 117 TranslateInfoBarDelegate* delegate = GetDelegate(); 118 const string16& language(delegate->GetLanguageDisplayableNameAt( 119 delegate->original_language_index())); 120 if (delegate->ShouldShowNeverTranslateButton()) { 121 DCHECK(!delegate->ShouldShowAlwaysTranslateButton()); 122 never_translate_button_ = CreateTextButton(this, 123 l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE, 124 language), false); 125 AddChildView(never_translate_button_); 126 } else if (delegate->ShouldShowAlwaysTranslateButton()) { 127 always_translate_button_ = CreateTextButton(this, 128 l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE, 129 language), false); 130 AddChildView(always_translate_button_); 131 } 132 133 options_menu_button_ = CreateMenuButton( 134 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this); 135 AddChildView(options_menu_button_); 136 137 // This must happen after adding all other children so InfoBarView can ensure 138 // the close button is the last child. 139 TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child); 140 141 // This must happen after adding all children because it triggers layout, 142 // which assumes that particular children (e.g. the close button) have already 143 // been added. 144 OriginalLanguageChanged(); 145 } 146 147 int BeforeTranslateInfoBar::ContentMinimumWidth() const { 148 return 149 (kButtonInLabelSpacing + 150 language_menu_button_->GetPreferredSize().width() + 151 kButtonInLabelSpacing) + 152 (kEndOfLabelSpacing + accept_button_->GetPreferredSize().width()) + 153 (kButtonButtonSpacing + deny_button_->GetPreferredSize().width()) + 154 ((never_translate_button_ == NULL) ? 0 : 155 (kButtonButtonSpacing + 156 never_translate_button_->GetPreferredSize().width())) + 157 ((always_translate_button_ == NULL) ? 0 : 158 (kButtonButtonSpacing + 159 always_translate_button_->GetPreferredSize().width())) + 160 (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width()); 161 } 162 163 void BeforeTranslateInfoBar::ButtonPressed(views::Button* sender, 164 const views::Event& event) { 165 TranslateInfoBarDelegate* delegate = GetDelegate(); 166 if (sender == accept_button_) { 167 delegate->Translate(); 168 } else if (sender == deny_button_) { 169 delegate->TranslationDeclined(); 170 RemoveInfoBar(); 171 } else if (sender == never_translate_button_) { 172 delegate->NeverTranslatePageLanguage(); 173 } else if (sender == always_translate_button_) { 174 delegate->AlwaysTranslatePageLanguage(); 175 } else { 176 TranslateInfoBarBase::ButtonPressed(sender, event); 177 } 178 } 179 180 void BeforeTranslateInfoBar::OriginalLanguageChanged() { 181 UpdateLanguageButtonText(language_menu_button_, LanguagesMenuModel::ORIGINAL); 182 } 183 184 void BeforeTranslateInfoBar::RunMenu(View* source, const gfx::Point& pt) { 185 if (source == language_menu_button_) { 186 languages_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); 187 } else { 188 DCHECK_EQ(options_menu_button_, source); 189 options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); 190 } 191 } 192