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/chrome_translate_client.h"
19 #include "chrome/browser/translate/translate_service.h"
20 #include "chrome/browser/ui/chrome_pages.h"
21 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h"
22 #include "chrome/common/url_constants.h"
23 #include "chrome/grit/generated_resources.h"
24 #include "components/translate/core/browser/translate_download_manager.h"
25 #include "components/translate/core/browser/translate_manager.h"
26 #include "components/translate/core/browser/translate_ui_delegate.h"
27 #include "content/public/browser/web_contents.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/models/combobox_model.h"
30 #include "ui/base/models/simple_combobox_model.h"
31 #include "ui/views/controls/button/checkbox.h"
32 #include "ui/views/controls/button/label_button.h"
33 #include "ui/views/controls/combobox/combobox.h"
34 #include "ui/views/controls/label.h"
35 #include "ui/views/controls/link.h"
36 #include "ui/views/layout/box_layout.h"
37 #include "ui/views/layout/grid_layout.h"
38 #include "ui/views/layout/layout_constants.h"
39 #include "ui/views/widget/widget.h"
43 enum DenialComboboxIndexes
{
45 INDEX_NEVER_TRANSLATE_LANGUAGE
= 2,
46 INDEX_NEVER_TRANSLATE_SITE
= 4,
49 views::LabelButton
* CreateLabelButton(views::ButtonListener
* listener
,
50 const base::string16
& label
,
52 views::LabelButton
* button
= new views::LabelButton(listener
, label
);
54 button
->SetStyle(views::Button::STYLE_BUTTON
);
58 views::Link
* CreateLink(views::LinkListener
* listener
,
61 views::Link
* link
= new views::Link(
62 l10n_util::GetStringUTF16(resource_id
));
63 link
->set_listener(listener
);
71 TranslateBubbleView
* TranslateBubbleView::translate_bubble_view_
= NULL
;
73 TranslateBubbleView::~TranslateBubbleView() {
74 // A child view could refer to a model which is owned by this class when
75 // the child view is destructed. For example, |source_language_combobx_model_|
76 // is referred by Combobox's destructor. Before destroying the models,
77 // removing the child views is needed.
78 RemoveAllChildViews(true);
82 void TranslateBubbleView::ShowBubble(
83 views::View
* anchor_view
,
84 content::WebContents
* web_contents
,
85 translate::TranslateStep step
,
86 translate::TranslateErrors::Type error_type
,
87 bool is_user_gesture
) {
88 if (translate_bubble_view_
) {
89 // When the user reads the advanced setting panel, the bubble should not be
90 // changed because they are focusing on the bubble.
91 if (translate_bubble_view_
->web_contents() == web_contents
&&
92 translate_bubble_view_
->model()->GetViewState() ==
93 TranslateBubbleModel::VIEW_STATE_ADVANCED
) {
96 if (step
!= translate::TRANSLATE_STEP_TRANSLATE_ERROR
) {
97 TranslateBubbleModel::ViewState state
=
98 TranslateBubbleModelImpl::TranslateStepToViewState(step
);
99 translate_bubble_view_
->SwitchView(state
);
101 translate_bubble_view_
->SwitchToErrorView(error_type
);
105 if (step
== translate::TRANSLATE_STEP_AFTER_TRANSLATE
&&
111 std::string source_language
;
112 std::string target_language
;
113 ChromeTranslateClient::GetTranslateLanguages(
114 web_contents
, &source_language
, &target_language
);
116 scoped_ptr
<translate::TranslateUIDelegate
> ui_delegate(
117 new translate::TranslateUIDelegate(
118 ChromeTranslateClient::GetManagerFromWebContents(web_contents
)
122 scoped_ptr
<TranslateBubbleModel
> model(
123 new TranslateBubbleModelImpl(step
, ui_delegate
.Pass()));
124 TranslateBubbleView
* view
= new TranslateBubbleView(anchor_view
,
129 views::BubbleDelegateView::CreateBubble(view
)->Show();
131 views::BubbleDelegateView::CreateBubble(view
)->ShowInactive();
135 void TranslateBubbleView::CloseBubble() {
136 if (!translate_bubble_view_
)
139 translate_bubble_view_
->GetWidget()->Close();
143 TranslateBubbleView
* TranslateBubbleView::GetCurrentBubble() {
144 return translate_bubble_view_
;
147 void TranslateBubbleView::Init() {
148 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
,
151 before_translate_view_
= CreateViewBeforeTranslate();
152 translating_view_
= CreateViewTranslating();
153 after_translate_view_
= CreateViewAfterTranslate();
154 error_view_
= CreateViewError();
155 advanced_view_
= CreateViewAdvanced();
157 AddChildView(before_translate_view_
);
158 AddChildView(translating_view_
);
159 AddChildView(after_translate_view_
);
160 AddChildView(error_view_
);
161 AddChildView(advanced_view_
);
163 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN
, ui::EF_NONE
));
165 UpdateChildVisibilities();
167 if (model_
->GetViewState() == TranslateBubbleModel::VIEW_STATE_ERROR
)
168 model_
->ShowError(error_type_
);
171 void TranslateBubbleView::ButtonPressed(views::Button
* sender
,
172 const ui::Event
& event
) {
173 HandleButtonPressed(static_cast<ButtonID
>(sender
->id()));
176 void TranslateBubbleView::WindowClosing() {
177 // The operations for |model_| are valid only when a WebContents is alive.
178 // TODO(hajimehoshi): TranslateBubbleViewModel(Impl) should not hold a
179 // WebContents as a member variable because the WebContents might be destroyed
180 // while the TranslateBubbleViewModel(Impl) is still alive. Instead,
181 // TranslateBubbleViewModel should take a reference of a WebContents at each
182 // method. (crbug/320497)
183 if (!translate_executed_
&& web_contents())
184 model_
->TranslationDeclined(denial_button_clicked_
);
186 // We have to reset |translate_bubble_view_| here, not in our destructor,
187 // because we'll be destroyed asynchronously and the shown state will be
188 // checked before then.
189 DCHECK_EQ(translate_bubble_view_
, this);
190 translate_bubble_view_
= NULL
;
193 bool TranslateBubbleView::AcceleratorPressed(
194 const ui::Accelerator
& accelerator
) {
195 switch (model_
->GetViewState()) {
196 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
: {
197 if (accelerator
.key_code() == ui::VKEY_RETURN
) {
198 HandleButtonPressed(BUTTON_ID_TRANSLATE
);
203 case TranslateBubbleModel::VIEW_STATE_TRANSLATING
:
205 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
: {
206 if (accelerator
.key_code() == ui::VKEY_RETURN
) {
207 HandleButtonPressed(BUTTON_ID_SHOW_ORIGINAL
);
212 case TranslateBubbleModel::VIEW_STATE_ERROR
:
214 case TranslateBubbleModel::VIEW_STATE_ADVANCED
: {
215 if (accelerator
.key_code() == ui::VKEY_RETURN
) {
216 HandleButtonPressed(BUTTON_ID_DONE
);
222 return BubbleDelegateView::AcceleratorPressed(accelerator
);
225 gfx::Size
TranslateBubbleView::GetPreferredSize() const {
227 for (int i
= 0; i
< child_count(); i
++) {
228 const views::View
* child
= child_at(i
);
229 width
= std::max(width
, child
->GetPreferredSize().width());
231 int height
= GetCurrentView()->GetPreferredSize().height();
232 return gfx::Size(width
, height
);
235 void TranslateBubbleView::OnPerformAction(views::Combobox
* combobox
) {
236 HandleComboboxPerformAction(static_cast<ComboboxID
>(combobox
->id()));
239 void TranslateBubbleView::LinkClicked(views::Link
* source
, int event_flags
) {
240 HandleLinkClicked(static_cast<LinkID
>(source
->id()));
243 void TranslateBubbleView::WebContentsDestroyed() {
244 GetWidget()->CloseNow();
247 TranslateBubbleModel::ViewState
TranslateBubbleView::GetViewState() const {
248 return model_
->GetViewState();
251 TranslateBubbleView::TranslateBubbleView(
252 views::View
* anchor_view
,
253 scoped_ptr
<TranslateBubbleModel
> model
,
254 translate::TranslateErrors::Type error_type
,
255 content::WebContents
* web_contents
)
256 : ManagedFullScreenBubbleDelegateView(anchor_view
, web_contents
),
257 WebContentsObserver(web_contents
),
258 before_translate_view_(NULL
),
259 translating_view_(NULL
),
260 after_translate_view_(NULL
),
262 advanced_view_(NULL
),
263 denial_combobox_(NULL
),
264 source_language_combobox_(NULL
),
265 target_language_combobox_(NULL
),
266 always_translate_checkbox_(NULL
),
267 advanced_cancel_button_(NULL
),
268 advanced_done_button_(NULL
),
269 model_(model
.Pass()),
270 error_type_(error_type
),
271 is_in_incognito_window_(
272 web_contents
? web_contents
->GetBrowserContext()->IsOffTheRecord()
274 translate_executed_(false),
275 denial_button_clicked_(false) {
276 if (model_
->GetViewState() !=
277 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
) {
278 translate_executed_
= true;
281 set_margins(gfx::Insets(views::kPanelVertMargin
, views::kPanelHorizMargin
,
282 views::kPanelVertMargin
, views::kPanelHorizMargin
));
284 translate_bubble_view_
= this;
287 views::View
* TranslateBubbleView::GetCurrentView() const {
288 switch (model_
->GetViewState()) {
289 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
:
290 return before_translate_view_
;
291 case TranslateBubbleModel::VIEW_STATE_TRANSLATING
:
292 return translating_view_
;
293 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
:
294 return after_translate_view_
;
295 case TranslateBubbleModel::VIEW_STATE_ERROR
:
297 case TranslateBubbleModel::VIEW_STATE_ADVANCED
:
298 return advanced_view_
;
304 void TranslateBubbleView::HandleButtonPressed(
305 TranslateBubbleView::ButtonID sender_id
) {
307 case BUTTON_ID_TRANSLATE
: {
308 translate_executed_
= true;
312 case BUTTON_ID_DONE
: {
313 if (always_translate_checkbox_
)
314 model_
->SetAlwaysTranslate(always_translate_checkbox_
->checked());
315 if (model_
->IsPageTranslatedInCurrentLanguages()) {
316 model_
->GoBackFromAdvanced();
317 UpdateChildVisibilities();
320 translate_executed_
= true;
322 SwitchView(TranslateBubbleModel::VIEW_STATE_TRANSLATING
);
326 case BUTTON_ID_CANCEL
: {
327 model_
->GoBackFromAdvanced();
328 UpdateChildVisibilities();
332 case BUTTON_ID_TRY_AGAIN
: {
333 translate_executed_
= true;
337 case BUTTON_ID_SHOW_ORIGINAL
: {
338 model_
->RevertTranslation();
339 GetWidget()->Close();
342 case BUTTON_ID_ALWAYS_TRANSLATE
: {
343 // Do nothing. The state of the checkbox affects only when the 'Done'
344 // button is pressed.
350 void TranslateBubbleView::HandleLinkClicked(
351 TranslateBubbleView::LinkID sender_id
) {
353 case LINK_ID_ADVANCED
: {
354 SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
357 case LINK_ID_LANGUAGE_SETTINGS
: {
358 GURL url
= chrome::GetSettingsUrl(chrome::kLanguageOptionsSubPage
);
359 web_contents()->OpenURL(content::OpenURLParams(
363 ui::PAGE_TRANSITION_LINK
,
370 void TranslateBubbleView::HandleComboboxPerformAction(
371 TranslateBubbleView::ComboboxID sender_id
) {
373 case COMBOBOX_ID_DENIAL
: {
374 denial_button_clicked_
= true;
375 int index
= denial_combobox_
->selected_index();
379 case INDEX_NEVER_TRANSLATE_LANGUAGE
:
380 model_
->SetNeverTranslateLanguage(true);
382 case INDEX_NEVER_TRANSLATE_SITE
:
383 model_
->SetNeverTranslateSite(true);
389 GetWidget()->Close();
392 case COMBOBOX_ID_SOURCE_LANGUAGE
: {
393 if (model_
->GetOriginalLanguageIndex() ==
394 source_language_combobox_
->selected_index()) {
397 model_
->UpdateOriginalLanguageIndex(
398 source_language_combobox_
->selected_index());
399 UpdateAdvancedView();
402 case COMBOBOX_ID_TARGET_LANGUAGE
: {
403 if (model_
->GetTargetLanguageIndex() ==
404 target_language_combobox_
->selected_index()) {
407 model_
->UpdateTargetLanguageIndex(
408 target_language_combobox_
->selected_index());
409 UpdateAdvancedView();
415 void TranslateBubbleView::UpdateChildVisibilities() {
416 for (int i
= 0; i
< child_count(); i
++) {
417 views::View
* view
= child_at(i
);
418 view
->SetVisible(view
== GetCurrentView());
422 views::View
* TranslateBubbleView::CreateViewBeforeTranslate() {
423 views::Label
* message_label
= new views::Label(
424 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE
));
426 base::string16 original_language_name
=
427 model_
->GetLanguageNameAt(model_
->GetOriginalLanguageIndex());
429 std::vector
<base::string16
> items
;
430 items
.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY
));
431 items
.push_back(base::string16());
432 items
.push_back(l10n_util::GetStringFUTF16(
433 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG
,
434 original_language_name
));
435 items
.push_back(base::string16());
436 items
.push_back(l10n_util::GetStringUTF16(
437 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE
));
439 denial_combobox_model_
.reset(new ui::SimpleComboboxModel(items
));
440 denial_combobox_
= new views::Combobox(denial_combobox_model_
.get());
441 denial_combobox_
->set_id(COMBOBOX_ID_DENIAL
);
442 denial_combobox_
->set_listener(this);
443 denial_combobox_
->SetStyle(views::Combobox::STYLE_ACTION
);
445 views::View
* view
= new views::View();
446 views::GridLayout
* layout
= new views::GridLayout(view
);
447 view
->SetLayoutManager(layout
);
449 using views::GridLayout
;
452 COLUMN_SET_ID_MESSAGE
,
453 COLUMN_SET_ID_CONTENT
,
456 views::ColumnSet
* cs
= layout
->AddColumnSet(COLUMN_SET_ID_MESSAGE
);
457 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
458 0, GridLayout::USE_PREF
, 0, 0);
459 cs
->AddPaddingColumn(0, views::kRelatedButtonHSpacing
);
460 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
461 0, GridLayout::USE_PREF
, 0, 0);
462 cs
->AddPaddingColumn(1, 0);
464 cs
= layout
->AddColumnSet(COLUMN_SET_ID_CONTENT
);
465 cs
->AddPaddingColumn(1, 0);
466 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
467 0, GridLayout::USE_PREF
, 0, 0);
468 cs
->AddPaddingColumn(0, views::kRelatedButtonHSpacing
);
469 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
470 0, GridLayout::USE_PREF
, 0, 0);
472 layout
->StartRow(0, COLUMN_SET_ID_MESSAGE
);
473 layout
->AddView(message_label
);
474 layout
->AddView(CreateLink(this,
475 IDS_TRANSLATE_BUBBLE_ADVANCED
,
478 layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
480 layout
->StartRow(0, COLUMN_SET_ID_CONTENT
);
481 views::LabelButton
* accept_button
= CreateLabelButton(
483 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT
),
484 BUTTON_ID_TRANSLATE
);
485 layout
->AddView(accept_button
);
486 accept_button
->SetIsDefault(true);
487 layout
->AddView(denial_combobox_
);
492 views::View
* TranslateBubbleView::CreateViewTranslating() {
493 base::string16 target_language_name
=
494 model_
->GetLanguageNameAt(model_
->GetTargetLanguageIndex());
495 views::Label
* label
= new views::Label(
496 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATING
));
498 views::View
* view
= new views::View();
499 views::GridLayout
* layout
= new views::GridLayout(view
);
500 view
->SetLayoutManager(layout
);
502 using views::GridLayout
;
505 COLUMN_SET_ID_MESSAGE
,
506 COLUMN_SET_ID_CONTENT
,
509 views::ColumnSet
* cs
= layout
->AddColumnSet(COLUMN_SET_ID_MESSAGE
);
510 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
511 0, views::GridLayout::USE_PREF
, 0, 0);
512 cs
->AddPaddingColumn(1, 0);
514 cs
= layout
->AddColumnSet(COLUMN_SET_ID_CONTENT
);
515 cs
->AddPaddingColumn(1, 0);
516 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
517 0, GridLayout::USE_PREF
, 0, 0);
519 layout
->StartRow(0, COLUMN_SET_ID_MESSAGE
);
520 layout
->AddView(label
);
522 layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
524 layout
->StartRow(0, COLUMN_SET_ID_CONTENT
);
525 views::LabelButton
* revert_button
= CreateLabelButton(
527 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT
),
528 BUTTON_ID_SHOW_ORIGINAL
);
529 revert_button
->SetEnabled(false);
530 layout
->AddView(revert_button
);
535 views::View
* TranslateBubbleView::CreateViewAfterTranslate() {
536 views::Label
* label
= new views::Label(
537 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATED
));
539 views::View
* view
= new views::View();
540 views::GridLayout
* layout
= new views::GridLayout(view
);
541 view
->SetLayoutManager(layout
);
543 using views::GridLayout
;
546 COLUMN_SET_ID_MESSAGE
,
547 COLUMN_SET_ID_CONTENT
,
550 views::ColumnSet
* cs
= layout
->AddColumnSet(COLUMN_SET_ID_MESSAGE
);
551 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
552 0, views::GridLayout::USE_PREF
, 0, 0);
553 cs
->AddPaddingColumn(0, views::kRelatedButtonHSpacing
);
554 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
555 0, views::GridLayout::USE_PREF
, 0, 0);
556 cs
->AddPaddingColumn(1, 0);
558 cs
= layout
->AddColumnSet(COLUMN_SET_ID_CONTENT
);
559 cs
->AddPaddingColumn(1, 0);
560 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
561 0, GridLayout::USE_PREF
, 0, 0);
563 layout
->StartRow(0, COLUMN_SET_ID_MESSAGE
);
564 layout
->AddView(label
);
565 layout
->AddView(CreateLink(this,
566 IDS_TRANSLATE_BUBBLE_ADVANCED
,
569 layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
571 layout
->StartRow(0, COLUMN_SET_ID_CONTENT
);
572 layout
->AddView(CreateLabelButton(
574 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT
),
575 BUTTON_ID_SHOW_ORIGINAL
));
580 views::View
* TranslateBubbleView::CreateViewError() {
581 views::Label
* label
= new views::Label(
582 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE
));
584 views::View
* view
= new views::View();
585 views::GridLayout
* layout
= new views::GridLayout(view
);
586 view
->SetLayoutManager(layout
);
588 using views::GridLayout
;
591 COLUMN_SET_ID_MESSAGE
,
592 COLUMN_SET_ID_CONTENT
,
595 views::ColumnSet
* cs
= layout
->AddColumnSet(COLUMN_SET_ID_MESSAGE
);
596 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
597 0, GridLayout::USE_PREF
, 0, 0);
598 cs
->AddPaddingColumn(0, views::kRelatedButtonHSpacing
);
599 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
600 0, GridLayout::USE_PREF
, 0, 0);
601 cs
->AddPaddingColumn(1, 0);
603 cs
= layout
->AddColumnSet(COLUMN_SET_ID_CONTENT
);
604 cs
->AddPaddingColumn(1, 0);
605 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
606 0, GridLayout::USE_PREF
, 0, 0);
608 layout
->StartRow(0, COLUMN_SET_ID_MESSAGE
);
609 layout
->AddView(label
);
610 layout
->AddView(CreateLink(this,
611 IDS_TRANSLATE_BUBBLE_ADVANCED
,
614 layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
616 layout
->StartRow(0, COLUMN_SET_ID_CONTENT
);
617 layout
->AddView(CreateLabelButton(
619 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN
),
620 BUTTON_ID_TRY_AGAIN
));
625 // TODO(hajimehoshi): Revice this later to show a specific message for each
626 // error. (crbug/307350)
627 views::View
* TranslateBubbleView::CreateViewAdvanced() {
628 views::Label
* source_language_label
= new views::Label(
629 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE
));
631 views::Label
* target_language_label
= new views::Label(
632 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE
));
634 int source_default_index
= model_
->GetOriginalLanguageIndex();
635 source_language_combobox_model_
.reset(
636 new LanguageComboboxModel(source_default_index
, model_
.get()));
637 source_language_combobox_
=
638 new views::Combobox(source_language_combobox_model_
.get());
640 source_language_combobox_
->set_id(COMBOBOX_ID_SOURCE_LANGUAGE
);
641 source_language_combobox_
->set_listener(this);
643 int target_default_index
= model_
->GetTargetLanguageIndex();
644 target_language_combobox_model_
.reset(
645 new LanguageComboboxModel(target_default_index
, model_
.get()));
646 target_language_combobox_
=
647 new views::Combobox(target_language_combobox_model_
.get());
649 target_language_combobox_
->set_id(COMBOBOX_ID_TARGET_LANGUAGE
);
650 target_language_combobox_
->set_listener(this);
652 // In an incognito window, "Always translate" checkbox shouldn't be shown.
653 if (!is_in_incognito_window_
) {
654 always_translate_checkbox_
= new views::Checkbox(base::string16());
655 always_translate_checkbox_
->set_id(BUTTON_ID_ALWAYS_TRANSLATE
);
656 always_translate_checkbox_
->set_listener(this);
659 views::View
* view
= new views::View();
660 views::GridLayout
* layout
= new views::GridLayout(view
);
661 view
->SetLayoutManager(layout
);
663 using views::GridLayout
;
666 COLUMN_SET_ID_LANGUAGES
,
667 COLUMN_SET_ID_BUTTONS
,
670 views::ColumnSet
* cs
= layout
->AddColumnSet(COLUMN_SET_ID_LANGUAGES
);
671 cs
->AddColumn(GridLayout::TRAILING
, GridLayout::CENTER
,
672 0, GridLayout::USE_PREF
, 0, 0);
673 cs
->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing
);
674 cs
->AddColumn(GridLayout::FILL
, GridLayout::CENTER
,
675 0, GridLayout::USE_PREF
, 0, 0);
676 cs
->AddPaddingColumn(1, 0);
678 cs
= layout
->AddColumnSet(COLUMN_SET_ID_BUTTONS
);
679 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
680 0, GridLayout::USE_PREF
, 0, 0);
681 cs
->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing
);
682 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
683 0, GridLayout::USE_PREF
, 0, 0);
684 cs
->AddPaddingColumn(0, views::kRelatedButtonHSpacing
);
685 cs
->AddColumn(GridLayout::LEADING
, GridLayout::CENTER
,
686 0, GridLayout::USE_PREF
, 0, 0);
688 layout
->StartRow(0, COLUMN_SET_ID_LANGUAGES
);
689 layout
->AddView(source_language_label
);
690 layout
->AddView(source_language_combobox_
);
692 layout
->AddPaddingRow(0, views::kRelatedControlVerticalSpacing
);
694 layout
->StartRow(0, COLUMN_SET_ID_LANGUAGES
);
695 layout
->AddView(target_language_label
);
696 layout
->AddView(target_language_combobox_
);
698 if (!is_in_incognito_window_
) {
699 layout
->AddPaddingRow(0, views::kRelatedControlVerticalSpacing
);
700 layout
->StartRow(0, COLUMN_SET_ID_LANGUAGES
);
701 layout
->SkipColumns(1);
702 layout
->AddView(always_translate_checkbox_
);
705 layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
707 layout
->StartRow(0, COLUMN_SET_ID_BUTTONS
);
708 layout
->AddView(CreateLink(this,
709 IDS_TRANSLATE_BUBBLE_LANGUAGE_SETTINGS
,
710 LINK_ID_LANGUAGE_SETTINGS
));
711 advanced_done_button_
= CreateLabelButton(
712 this, l10n_util::GetStringUTF16(IDS_DONE
), BUTTON_ID_DONE
);
713 advanced_done_button_
->SetIsDefault(true);
714 advanced_cancel_button_
= CreateLabelButton(
715 this, l10n_util::GetStringUTF16(IDS_CANCEL
), BUTTON_ID_CANCEL
);
716 layout
->AddView(advanced_done_button_
);
717 layout
->AddView(advanced_cancel_button_
);
719 UpdateAdvancedView();
724 void TranslateBubbleView::SwitchView(
725 TranslateBubbleModel::ViewState view_state
) {
726 if (model_
->GetViewState() == view_state
)
729 model_
->SetViewState(view_state
);
730 UpdateChildVisibilities();
731 if (view_state
== TranslateBubbleModel::VIEW_STATE_ADVANCED
)
732 UpdateAdvancedView();
736 void TranslateBubbleView::SwitchToErrorView(
737 translate::TranslateErrors::Type error_type
) {
738 SwitchView(TranslateBubbleModel::VIEW_STATE_ERROR
);
739 error_type_
= error_type
;
740 model_
->ShowError(error_type
);
743 void TranslateBubbleView::UpdateAdvancedView() {
744 DCHECK(source_language_combobox_
);
745 DCHECK(target_language_combobox_
);
746 DCHECK(advanced_done_button_
);
748 base::string16 source_language_name
=
749 model_
->GetLanguageNameAt(model_
->GetOriginalLanguageIndex());
750 base::string16 target_language_name
=
751 model_
->GetLanguageNameAt(model_
->GetTargetLanguageIndex());
753 // "Always translate" checkbox doesn't exist in an incognito window.
754 if (always_translate_checkbox_
) {
755 always_translate_checkbox_
->SetText(
756 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS
));
757 always_translate_checkbox_
->SetChecked(
758 model_
->ShouldAlwaysTranslate());
761 base::string16 label
;
762 if (model_
->IsPageTranslatedInCurrentLanguages())
763 label
= l10n_util::GetStringUTF16(IDS_DONE
);
765 label
= l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT
);
766 advanced_done_button_
->SetText(label
);
767 advanced_done_button_
->SizeToPreferredSize();
769 advanced_view_
->Layout();