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
BeforeTranslateInfoBar(TranslateInfoBarDelegate * delegate)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
~BeforeTranslateInfoBar()32 BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
33 }
34
Layout()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
ViewHierarchyChanged(bool is_add,View * parent,View * child)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
ContentMinimumWidth() const147 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
ButtonPressed(views::Button * sender,const views::Event & event)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
OriginalLanguageChanged()180 void BeforeTranslateInfoBar::OriginalLanguageChanged() {
181 UpdateLanguageButtonText(language_menu_button_, LanguagesMenuModel::ORIGINAL);
182 }
183
RunMenu(View * source,const gfx::Point & pt)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