1 // Copyright 2013 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.
5 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
11 #include "base/i18n/string_compare.h"
12 #include "base/memory/singleton.h"
13 #include "base/metrics/histogram.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/translate/translate_manager.h"
19 #include "chrome/browser/translate/translate_tab_helper.h"
20 #include "chrome/browser/translate/translate_ui_delegate.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h"
23 #include "chrome/common/url_constants.h"
24 #include "content/public/browser/web_contents.h"
25 #include "grit/generated_resources.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/models/combobox_model.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/views/controls/button/checkbox.h"
30 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/controls/combobox/combobox.h"
32 #include "ui/views/controls/label.h"
33 #include "ui/views/controls/link.h"
34 #include "ui/views/layout/box_layout.h"
35 #include "ui/views/layout/grid_layout.h"
36 #include "ui/views/layout/layout_constants.h"
37 #include "ui/views/widget/widget.h"
41 views::LabelButton* CreateLabelButton(views::ButtonListener* listener,
42 const string16& label, int id) {
43 views::LabelButton* button = new views::LabelButton(listener, label);
45 button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
49 views::Link* CreateLink(views::LinkListener* listener,
52 views::Link* link = new views::Link(
53 l10n_util::GetStringUTF16(resource_id));
54 link->set_listener(listener);
59 void GetTranslateLanguages(content::WebContents* web_contents,
61 std::string* target) {
62 DCHECK(source != NULL);
63 DCHECK(target != NULL);
65 TranslateTabHelper* translate_tab_helper =
66 TranslateTabHelper::FromWebContents(web_contents);
67 *source = translate_tab_helper->language_state().original_language();
68 *target = TranslateManager::GetLanguageCode(
69 g_browser_process->GetApplicationLocale());
72 // TODO(hajimehoshi): The interface to offer denial choices should be another
73 // control instead of Combobox. See crbug/305494.
74 class TranslateDenialComboboxModel : public ui::ComboboxModel {
78 INDEX_NEVER_TRANSLATE_LANGUAGE = 2,
79 INDEX_NEVER_TRANSLATE_SITE = 4,
82 explicit TranslateDenialComboboxModel(
83 const string16& original_language_name) {
84 items_.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY));
85 items_.push_back(string16());
86 items_.push_back(l10n_util::GetStringFUTF16(
87 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG,
88 original_language_name));
89 items_.push_back(string16());
90 items_.push_back(l10n_util::GetStringUTF16(
91 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE));
93 virtual ~TranslateDenialComboboxModel() {}
96 // Overridden from ui::ComboboxModel:
97 virtual int GetItemCount() const OVERRIDE {
100 virtual string16 GetItemAt(int index) OVERRIDE {
101 return items_[index];
103 virtual bool IsItemSeparatorAt(int index) OVERRIDE {
104 return items_[index].empty();
106 virtual int GetDefaultIndex() const OVERRIDE {
110 std::vector<string16> items_;
112 DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel);
118 TranslateBubbleView* TranslateBubbleView::translate_bubble_view_ = NULL;
120 TranslateBubbleView::~TranslateBubbleView() {
121 // A child view could refer to a model which is owned by this class when
122 // the child view is destructed. For example, |source_language_combobx_model_|
123 // is referred by Combobox's destructor. Before destroying the models,
124 // removing the child views is needed.
125 RemoveAllChildViews(true);
129 void TranslateBubbleView::ShowBubble(views::View* anchor_view,
130 content::WebContents* web_contents,
131 TranslateBubbleModel::ViewState type,
134 translate_bubble_view_->SwitchView(type);
138 std::string source_language;
139 std::string target_language;
140 GetTranslateLanguages(web_contents, &source_language, &target_language);
142 scoped_ptr<TranslateUIDelegate> ui_delegate(
143 new TranslateUIDelegate(web_contents, source_language, target_language));
144 scoped_ptr<TranslateBubbleModel> model(
145 new TranslateBubbleModelImpl(type, ui_delegate.Pass()));
146 bool is_in_incognito_window =
147 web_contents->GetBrowserContext()->IsOffTheRecord();
148 TranslateBubbleView* view = new TranslateBubbleView(anchor_view,
150 is_in_incognito_window,
152 views::BubbleDelegateView::CreateBubble(view)->Show();
156 bool TranslateBubbleView::IsShowing() {
157 return translate_bubble_view_ != NULL;
161 TranslateBubbleView* TranslateBubbleView::GetCurrentBubble() {
162 return translate_bubble_view_;
165 void TranslateBubbleView::Init() {
166 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
169 before_translate_view_ = CreateViewBeforeTranslate();
170 translating_view_ = CreateViewTranslating();
171 after_translate_view_ = CreateViewAfterTranslate();
172 error_view_ = CreateViewError();
173 advanced_view_ = CreateViewAdvanced();
175 AddChildView(before_translate_view_);
176 AddChildView(translating_view_);
177 AddChildView(after_translate_view_);
178 AddChildView(error_view_);
179 AddChildView(advanced_view_);
181 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
183 UpdateChildVisibilities();
186 void TranslateBubbleView::ButtonPressed(views::Button* sender,
187 const ui::Event& event) {
188 HandleButtonPressed(static_cast<ButtonID>(sender->id()));
191 void TranslateBubbleView::WindowClosing() {
192 if (!translate_executed_ &&
193 (browser_ == NULL || !browser_->IsAttemptingToCloseBrowser())) {
194 model_->TranslationDeclined();
197 // We have to reset |translate_bubble_view_| here, not in our destructor,
198 // because we'll be destroyed asynchronously and the shown state will be
199 // checked before then.
200 DCHECK_EQ(translate_bubble_view_, this);
201 translate_bubble_view_ = NULL;
204 bool TranslateBubbleView::AcceleratorPressed(
205 const ui::Accelerator& accelerator) {
206 switch (model_->GetViewState()) {
207 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE: {
208 if (accelerator.key_code() == ui::VKEY_RETURN) {
209 HandleButtonPressed(BUTTON_ID_TRANSLATE);
214 case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
216 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE: {
217 if (accelerator.key_code() == ui::VKEY_RETURN) {
218 HandleButtonPressed(BUTTON_ID_SHOW_ORIGINAL);
223 case TranslateBubbleModel::VIEW_STATE_ERROR:
225 case TranslateBubbleModel::VIEW_STATE_ADVANCED: {
226 if (accelerator.key_code() == ui::VKEY_RETURN) {
227 HandleButtonPressed(BUTTON_ID_DONE);
233 return BubbleDelegateView::AcceleratorPressed(accelerator);
236 gfx::Size TranslateBubbleView::GetPreferredSize() {
238 for (int i = 0; i < child_count(); i++) {
239 views::View* child = child_at(i);
240 width = std::max(width, child->GetPreferredSize().width());
242 int height = GetCurrentView()->GetPreferredSize().height();
243 return gfx::Size(width, height);
246 void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) {
247 HandleComboboxSelectedIndexChanged(static_cast<ComboboxID>(combobox->id()));
250 void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) {
251 HandleLinkClicked(static_cast<LinkID>(source->id()));
254 TranslateBubbleModel::ViewState TranslateBubbleView::GetViewState() const {
255 return model_->GetViewState();
258 TranslateBubbleView::TranslateBubbleView(
259 views::View* anchor_view,
260 scoped_ptr<TranslateBubbleModel> model,
261 bool is_in_incognito_window,
263 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
264 before_translate_view_(NULL),
265 translating_view_(NULL),
266 after_translate_view_(NULL),
268 advanced_view_(NULL),
269 denial_combobox_(NULL),
270 source_language_combobox_(NULL),
271 target_language_combobox_(NULL),
272 always_translate_checkbox_(NULL),
273 model_(model.Pass()),
274 is_in_incognito_window_(is_in_incognito_window),
276 translate_executed_(false) {
277 if (model_->GetViewState() !=
278 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) {
279 translate_executed_ = true;
282 set_margins(gfx::Insets(views::kPanelVertMargin, views::kPanelHorizMargin,
283 views::kPanelVertMargin, views::kPanelHorizMargin));
285 translate_bubble_view_ = this;
288 views::View* TranslateBubbleView::GetCurrentView() {
289 switch (model_->GetViewState()) {
290 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE:
291 return before_translate_view_;
292 case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
293 return translating_view_;
294 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE:
295 return after_translate_view_;
296 case TranslateBubbleModel::VIEW_STATE_ERROR:
298 case TranslateBubbleModel::VIEW_STATE_ADVANCED:
299 return advanced_view_;
305 void TranslateBubbleView::HandleButtonPressed(
306 TranslateBubbleView::ButtonID sender_id) {
308 case BUTTON_ID_TRANSLATE: {
309 translate_executed_ = true;
313 case BUTTON_ID_DONE: {
314 translate_executed_ = true;
318 case BUTTON_ID_CANCEL: {
319 model_->GoBackFromAdvanced();
320 UpdateChildVisibilities();
324 case BUTTON_ID_TRY_AGAIN: {
325 translate_executed_ = true;
329 case BUTTON_ID_SHOW_ORIGINAL: {
330 model_->RevertTranslation();
334 case BUTTON_ID_ALWAYS_TRANSLATE: {
335 DCHECK(always_translate_checkbox_);
336 model_->SetAlwaysTranslate(always_translate_checkbox_->checked());
337 UpdateAdvancedView();
343 void TranslateBubbleView::HandleLinkClicked(
344 TranslateBubbleView::LinkID sender_id) {
346 case LINK_ID_ADVANCED: {
347 SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
350 case LINK_ID_LEARN_MORE: {
351 browser_->OpenURL(content::OpenURLParams(
352 GURL(chrome::kAboutGoogleTranslateURL),
355 content::PAGE_TRANSITION_LINK,
362 void TranslateBubbleView::HandleComboboxSelectedIndexChanged(
363 TranslateBubbleView::ComboboxID sender_id) {
365 case COMBOBOX_ID_DENIAL: {
366 int index = denial_combobox_->selected_index();
368 case TranslateDenialComboboxModel::INDEX_NOPE:
369 if (!translate_executed_)
370 model_->TranslationDeclined();
373 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_LANGUAGE:
374 model_->SetNeverTranslateLanguage(true);
377 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_SITE:
378 model_->SetNeverTranslateSite(true);
387 case COMBOBOX_ID_SOURCE_LANGUAGE: {
388 model_->UpdateOriginalLanguageIndex(
389 source_language_combobox_->selected_index());
390 UpdateAdvancedView();
393 case COMBOBOX_ID_TARGET_LANGUAGE: {
394 model_->UpdateTargetLanguageIndex(
395 target_language_combobox_->selected_index());
396 UpdateAdvancedView();
402 void TranslateBubbleView::UpdateChildVisibilities() {
403 for (int i = 0; i < child_count(); i++) {
404 views::View* view = child_at(i);
405 view->SetVisible(view == GetCurrentView());
409 views::View* TranslateBubbleView::CreateViewBeforeTranslate() {
410 views::Label* message_label = new views::Label(
411 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE));
413 string16 original_language_name =
414 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
415 denial_combobox_ = new views::Combobox(
416 new TranslateDenialComboboxModel(original_language_name));
417 denial_combobox_->set_id(COMBOBOX_ID_DENIAL);
418 denial_combobox_->set_listener(this);
420 views::View* view = new views::View();
421 views::GridLayout* layout = new views::GridLayout(view);
422 view->SetLayoutManager(layout);
424 using views::GridLayout;
427 COLUMN_SET_ID_MESSAGE,
428 COLUMN_SET_ID_CONTENT,
431 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
432 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
433 0, GridLayout::USE_PREF, 0, 0);
434 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
435 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
436 0, GridLayout::USE_PREF, 0, 0);
437 cs->AddPaddingColumn(1, 0);
439 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
440 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
441 0, GridLayout::USE_PREF, 0, 0);
442 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
443 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
444 0, GridLayout::USE_PREF, 0, 0);
445 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
446 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
447 0, GridLayout::USE_PREF, 0, 0);
449 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
450 layout->AddView(message_label);
451 layout->AddView(CreateLink(this,
452 IDS_TRANSLATE_BUBBLE_ADVANCED,
455 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
457 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
458 layout->AddView(CreateLink(this,
459 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
460 LINK_ID_LEARN_MORE));
461 layout->AddView(denial_combobox_);
462 layout->AddView(CreateLabelButton(
464 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT),
465 BUTTON_ID_TRANSLATE));
470 views::View* TranslateBubbleView::CreateViewTranslating() {
471 string16 target_language_name =
472 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
473 views::Label* label = new views::Label(
474 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATING));
476 views::View* view = new views::View();
477 views::GridLayout* layout = new views::GridLayout(view);
478 view->SetLayoutManager(layout);
480 using views::GridLayout;
483 COLUMN_SET_ID_MESSAGE,
484 COLUMN_SET_ID_CONTENT,
487 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
488 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
489 0, views::GridLayout::USE_PREF, 0, 0);
490 cs->AddPaddingColumn(1, 0);
492 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
493 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
494 0, GridLayout::USE_PREF, 0, 0);
495 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
496 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
497 0, GridLayout::USE_PREF, 0, 0);
499 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
500 layout->AddView(label);
502 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
504 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
505 layout->AddView(CreateLink(this,
506 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
507 LINK_ID_LEARN_MORE));
508 views::LabelButton* revert_button = CreateLabelButton(
510 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
511 BUTTON_ID_SHOW_ORIGINAL);
512 revert_button->SetEnabled(false);
513 layout->AddView(revert_button);
518 views::View* TranslateBubbleView::CreateViewAfterTranslate() {
519 views::Label* label = new views::Label(
520 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATED));
522 views::View* view = new views::View();
523 views::GridLayout* layout = new views::GridLayout(view);
524 view->SetLayoutManager(layout);
526 using views::GridLayout;
529 COLUMN_SET_ID_MESSAGE,
530 COLUMN_SET_ID_CONTENT,
533 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
534 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
535 0, views::GridLayout::USE_PREF, 0, 0);
536 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
537 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
538 0, views::GridLayout::USE_PREF, 0, 0);
539 cs->AddPaddingColumn(1, 0);
541 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
542 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
543 0, GridLayout::USE_PREF, 0, 0);
544 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
545 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
546 0, GridLayout::USE_PREF, 0, 0);
548 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
549 layout->AddView(label);
550 layout->AddView(CreateLink(this,
551 IDS_TRANSLATE_BUBBLE_ADVANCED,
554 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
556 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
557 layout->AddView(CreateLink(this,
558 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
559 LINK_ID_LEARN_MORE));
560 layout->AddView(CreateLabelButton(
562 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
563 BUTTON_ID_SHOW_ORIGINAL));
568 views::View* TranslateBubbleView::CreateViewError() {
569 views::Label* label = new views::Label(
570 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE));
572 views::View* view = new views::View();
573 views::GridLayout* layout = new views::GridLayout(view);
574 view->SetLayoutManager(layout);
576 using views::GridLayout;
579 COLUMN_SET_ID_MESSAGE,
580 COLUMN_SET_ID_CONTENT,
583 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
584 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
585 0, GridLayout::USE_PREF, 0, 0);
586 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
587 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
588 0, GridLayout::USE_PREF, 0, 0);
589 cs->AddPaddingColumn(1, 0);
591 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
592 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
593 0, GridLayout::USE_PREF, 0, 0);
594 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
595 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
596 0, GridLayout::USE_PREF, 0, 0);
598 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
599 layout->AddView(label);
600 layout->AddView(CreateLink(this,
601 IDS_TRANSLATE_BUBBLE_ADVANCED,
604 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
606 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
607 layout->AddView(CreateLink(this,
608 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
609 LINK_ID_LEARN_MORE));
610 layout->AddView(CreateLabelButton(
612 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN),
613 BUTTON_ID_TRY_AGAIN));
618 // TODO(hajimehoshi): Revice this later to show a specific message for each
619 // error. (crbug/307350)
620 views::View* TranslateBubbleView::CreateViewAdvanced() {
621 views::Label* source_language_label = new views::Label(
622 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE));
624 views::Label* target_language_label = new views::Label(
625 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE));
627 int source_default_index = model_->GetOriginalLanguageIndex();
628 source_language_combobox_model_.reset(
629 new LanguageComboboxModel(source_default_index, model_.get()));
630 source_language_combobox_ =
631 new views::Combobox(source_language_combobox_model_.get());
633 source_language_combobox_->set_id(COMBOBOX_ID_SOURCE_LANGUAGE);
634 source_language_combobox_->set_listener(this);
636 int target_default_index = model_->GetTargetLanguageIndex();
637 target_language_combobox_model_.reset(
638 new LanguageComboboxModel(target_default_index, model_.get()));
639 target_language_combobox_ =
640 new views::Combobox(target_language_combobox_model_.get());
642 target_language_combobox_->set_id(COMBOBOX_ID_TARGET_LANGUAGE);
643 target_language_combobox_->set_listener(this);
645 // In an incognito window, "Always translate" checkbox shouldn't be shown.
646 if (!is_in_incognito_window_) {
647 always_translate_checkbox_ = new views::Checkbox(string16());
648 always_translate_checkbox_->set_id(BUTTON_ID_ALWAYS_TRANSLATE);
649 always_translate_checkbox_->set_listener(this);
652 views::View* view = new views::View();
653 views::GridLayout* layout = new views::GridLayout(view);
654 view->SetLayoutManager(layout);
656 using views::GridLayout;
659 COLUMN_SET_ID_LANGUAGES,
660 COLUMN_SET_ID_ALWAYS_TRANSLATE,
661 COLUMN_SET_ID_BUTTONS,
664 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_LANGUAGES);
665 cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER,
666 0, GridLayout::USE_PREF, 0, 0);
667 cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
668 cs->AddColumn(GridLayout::FILL, GridLayout::CENTER,
669 0, GridLayout::USE_PREF, 0, 0);
670 cs->AddPaddingColumn(1, 0);
672 if (!is_in_incognito_window_) {
673 cs = layout->AddColumnSet(COLUMN_SET_ID_ALWAYS_TRANSLATE);
674 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
675 0, GridLayout::USE_PREF, 0, 0);
676 cs->AddPaddingColumn(1, 0);
679 cs = layout->AddColumnSet(COLUMN_SET_ID_BUTTONS);
680 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
681 0, GridLayout::USE_PREF, 0, 0);
682 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
683 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
684 0, GridLayout::USE_PREF, 0, 0);
685 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
686 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
687 0, GridLayout::USE_PREF, 0, 0);
689 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
690 layout->AddView(source_language_label);
691 layout->AddView(source_language_combobox_);
693 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
695 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
696 layout->AddView(target_language_label);
697 layout->AddView(target_language_combobox_);
699 if (!is_in_incognito_window_) {
700 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
702 layout->StartRow(0, COLUMN_SET_ID_ALWAYS_TRANSLATE);
703 layout->AddView(always_translate_checkbox_);
706 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
708 layout->StartRow(0, COLUMN_SET_ID_BUTTONS);
709 layout->AddView(CreateLink(this,
710 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
711 LINK_ID_LEARN_MORE));
712 views::LabelButton* cancel_button = CreateLabelButton(
713 this, l10n_util::GetStringUTF16(IDS_CANCEL), BUTTON_ID_CANCEL);
714 layout->AddView(cancel_button);
715 views::LabelButton* done_button = CreateLabelButton(
716 this, l10n_util::GetStringUTF16(IDS_DONE), BUTTON_ID_DONE);
717 done_button->SetIsDefault(true);
718 layout->AddView(done_button);
720 UpdateAdvancedView();
725 void TranslateBubbleView::SwitchView(
726 TranslateBubbleModel::ViewState view_state) {
727 if (model_->GetViewState() == view_state)
730 model_->SetViewState(view_state);
731 UpdateChildVisibilities();
735 void TranslateBubbleView::UpdateAdvancedView() {
736 DCHECK(source_language_combobox_);
737 DCHECK(target_language_combobox_);
739 string16 source_language_name =
740 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
741 string16 target_language_name =
742 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
745 l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS,
746 source_language_name,
747 target_language_name);
748 // "Always translate" checkbox doesn't exist in an incognito window.
749 if (always_translate_checkbox_) {
750 always_translate_checkbox_->SetText(message);
751 always_translate_checkbox_->SetChecked(
752 model_->ShouldAlwaysTranslate());