blob: 2014da059f78113461618538511a3d2d761d9205 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/translate/translate_bubble_view.h"
#include <algorithm>
#include <string>
#include <vector>
#include "base/i18n/string_compare.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/translate/translate_manager.h"
#include "chrome/browser/translate/translate_tab_helper.h"
#include "chrome/browser/translate/translate_ui_delegate.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/translate/translate_bubble_model_impl.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
namespace {
views::LabelButton* CreateLabelButton(views::ButtonListener* listener,
const base::string16& label, int id) {
views::LabelButton* button = new views::LabelButton(listener, label);
button->set_id(id);
button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
return button;
}
views::Link* CreateLink(views::LinkListener* listener,
int resource_id,
int id) {
views::Link* link = new views::Link(
l10n_util::GetStringUTF16(resource_id));
link->set_listener(listener);
link->set_id(id);
return link;
}
void GetTranslateLanguages(content::WebContents* web_contents,
std::string* source,
std::string* target) {
DCHECK(source != NULL);
DCHECK(target != NULL);
TranslateTabHelper* translate_tab_helper =
TranslateTabHelper::FromWebContents(web_contents);
*source = translate_tab_helper->language_state().original_language();
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
Profile* original_profile = profile->GetOriginalProfile();
PrefService* prefs = original_profile->GetPrefs();
if (!web_contents->GetBrowserContext()->IsOffTheRecord()) {
std::string auto_translate_language =
TranslateManager::GetAutoTargetLanguage(*source, prefs);
if (!auto_translate_language.empty()) {
*target = auto_translate_language;
return;
}
}
*target = TranslateManager::GetTargetLanguage(prefs);
}
class TranslateDenialComboboxModel : public ui::ComboboxModel {
public:
enum {
INDEX_NOPE = 0,
INDEX_NEVER_TRANSLATE_LANGUAGE = 2,
INDEX_NEVER_TRANSLATE_SITE = 4,
};
explicit TranslateDenialComboboxModel(
const base::string16& original_language_name) {
items_.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY));
items_.push_back(string16());
items_.push_back(l10n_util::GetStringFUTF16(
IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG,
original_language_name));
items_.push_back(string16());
items_.push_back(l10n_util::GetStringUTF16(
IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE));
}
virtual ~TranslateDenialComboboxModel() {}
private:
// Overridden from ui::ComboboxModel:
virtual int GetItemCount() const OVERRIDE {
return items_.size();
}
virtual base::string16 GetItemAt(int index) OVERRIDE {
return items_[index];
}
virtual bool IsItemSeparatorAt(int index) OVERRIDE {
return items_[index].empty();
}
virtual int GetDefaultIndex() const OVERRIDE {
return 0;
}
std::vector<string16> items_;
DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel);
};
} // namespace
// static
TranslateBubbleView* TranslateBubbleView::translate_bubble_view_ = NULL;
TranslateBubbleView::~TranslateBubbleView() {
// A child view could refer to a model which is owned by this class when
// the child view is destructed. For example, |source_language_combobx_model_|
// is referred by Combobox's destructor. Before destroying the models,
// removing the child views is needed.
RemoveAllChildViews(true);
}
// static
void TranslateBubbleView::ShowBubble(views::View* anchor_view,
content::WebContents* web_contents,
TranslateBubbleModel::ViewState type,
TranslateErrors::Type error_type,
Browser* browser) {
// During auto-translating, the bubble should not be shown.
if (type == TranslateBubbleModel::VIEW_STATE_TRANSLATING ||
type == TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE) {
TranslateTabHelper* translate_tab_helper =
TranslateTabHelper::FromWebContents(web_contents);
if (!translate_tab_helper ||
translate_tab_helper->language_state().InTranslateNavigation()) {
return;
}
}
if (IsShowing()) {
// When the user reads the advanced setting panel, the bubble should not be
// changed because he/she is focusing on the bubble.
if (translate_bubble_view_->web_contents() == web_contents &&
translate_bubble_view_->model()->GetViewState() ==
TranslateBubbleModel::VIEW_STATE_ADVANCED) {
return;
}
translate_bubble_view_->SwitchView(type);
translate_bubble_view_->model()->SetErrorType(error_type);
return;
}
std::string source_language;
std::string target_language;
GetTranslateLanguages(web_contents, &source_language, &target_language);
scoped_ptr<TranslateUIDelegate> ui_delegate(
new TranslateUIDelegate(web_contents, source_language, target_language,
error_type));
scoped_ptr<TranslateBubbleModel> model(
new TranslateBubbleModelImpl(type, ui_delegate.Pass()));
TranslateBubbleView* view = new TranslateBubbleView(anchor_view,
model.Pass(),
browser,
web_contents);
views::BubbleDelegateView::CreateBubble(view)->Show();
}
// static
bool TranslateBubbleView::IsShowing() {
return translate_bubble_view_ != NULL;
}
// static
TranslateBubbleView* TranslateBubbleView::GetCurrentBubble() {
return translate_bubble_view_;
}
void TranslateBubbleView::Init() {
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
0, 0, 0));
before_translate_view_ = CreateViewBeforeTranslate();
translating_view_ = CreateViewTranslating();
after_translate_view_ = CreateViewAfterTranslate();
error_view_ = CreateViewError();
advanced_view_ = CreateViewAdvanced();
AddChildView(before_translate_view_);
AddChildView(translating_view_);
AddChildView(after_translate_view_);
AddChildView(error_view_);
AddChildView(advanced_view_);
AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
UpdateChildVisibilities();
}
void TranslateBubbleView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
HandleButtonPressed(static_cast<ButtonID>(sender->id()));
}
void TranslateBubbleView::WindowClosing() {
// The operations for |model_| are valid only when a WebContents is alive.
// TODO(hajimehoshi): TranslateBubbleViewModel(Impl) should not hold a
// WebContents as a member variable because the WebContents might be destroyed
// while the TranslateBubbleViewModel(Impl) is still alive. Instead,
// TranslateBubbleViewModel should take a reference of a WebContents at each
// method. (crbug/320497)
if (!translate_executed_ && web_contents())
model_->TranslationDeclined();
// We have to reset |translate_bubble_view_| here, not in our destructor,
// because we'll be destroyed asynchronously and the shown state will be
// checked before then.
DCHECK_EQ(translate_bubble_view_, this);
translate_bubble_view_ = NULL;
}
bool TranslateBubbleView::AcceleratorPressed(
const ui::Accelerator& accelerator) {
switch (model_->GetViewState()) {
case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE: {
if (accelerator.key_code() == ui::VKEY_RETURN) {
HandleButtonPressed(BUTTON_ID_TRANSLATE);
return true;
}
break;
}
case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
break;
case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE: {
if (accelerator.key_code() == ui::VKEY_RETURN) {
HandleButtonPressed(BUTTON_ID_SHOW_ORIGINAL);
return true;
}
break;
}
case TranslateBubbleModel::VIEW_STATE_ERROR:
break;
case TranslateBubbleModel::VIEW_STATE_ADVANCED: {
if (accelerator.key_code() == ui::VKEY_RETURN) {
HandleButtonPressed(BUTTON_ID_DONE);
return true;
}
break;
}
}
return BubbleDelegateView::AcceleratorPressed(accelerator);
}
gfx::Size TranslateBubbleView::GetPreferredSize() {
int width = 0;
for (int i = 0; i < child_count(); i++) {
views::View* child = child_at(i);
width = std::max(width, child->GetPreferredSize().width());
}
int height = GetCurrentView()->GetPreferredSize().height();
return gfx::Size(width, height);
}
void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) {
HandleComboboxSelectedIndexChanged(static_cast<ComboboxID>(combobox->id()));
}
void TranslateBubbleView::OnComboboxTextButtonClicked(
views::Combobox* combobox) {
if (combobox != denial_combobox_)
return;
int index = combobox->selected_index();
switch (index) {
case TranslateDenialComboboxModel::INDEX_NOPE:
if (!translate_executed_)
model_->TranslationDeclined();
StartFade(false);
break;
case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_LANGUAGE:
model_->SetNeverTranslateLanguage(true);
StartFade(false);
break;
case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_SITE:
model_->SetNeverTranslateSite(true);
StartFade(false);
break;
default:
NOTREACHED();
break;
}
}
void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) {
HandleLinkClicked(static_cast<LinkID>(source->id()));
}
void TranslateBubbleView::WebContentsDestroyed(
content::WebContents* web_contents) {
GetWidget()->CloseNow();
}
TranslateBubbleModel::ViewState TranslateBubbleView::GetViewState() const {
return model_->GetViewState();
}
TranslateBubbleView::TranslateBubbleView(
views::View* anchor_view,
scoped_ptr<TranslateBubbleModel> model,
Browser* browser,
content::WebContents* web_contents)
: BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
WebContentsObserver(web_contents),
before_translate_view_(NULL),
translating_view_(NULL),
after_translate_view_(NULL),
error_view_(NULL),
advanced_view_(NULL),
denial_combobox_(NULL),
source_language_combobox_(NULL),
target_language_combobox_(NULL),
always_translate_checkbox_(NULL),
advanced_cancel_button_(NULL),
advanced_done_button_(NULL),
model_(model.Pass()),
is_in_incognito_window_(
web_contents ?
web_contents->GetBrowserContext()->IsOffTheRecord() : false),
browser_(browser),
translate_executed_(false) {
if (model_->GetViewState() !=
TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) {
translate_executed_ = true;
}
set_margins(gfx::Insets(views::kPanelVertMargin, views::kPanelHorizMargin,
views::kPanelVertMargin, views::kPanelHorizMargin));
translate_bubble_view_ = this;
}
views::View* TranslateBubbleView::GetCurrentView() {
switch (model_->GetViewState()) {
case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE:
return before_translate_view_;
case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
return translating_view_;
case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE:
return after_translate_view_;
case TranslateBubbleModel::VIEW_STATE_ERROR:
return error_view_;
case TranslateBubbleModel::VIEW_STATE_ADVANCED:
return advanced_view_;
}
NOTREACHED();
return NULL;
}
void TranslateBubbleView::HandleButtonPressed(
TranslateBubbleView::ButtonID sender_id) {
switch (sender_id) {
case BUTTON_ID_TRANSLATE: {
translate_executed_ = true;
model_->Translate();
break;
}
case BUTTON_ID_DONE: {
if (always_translate_checkbox_)
model_->SetAlwaysTranslate(always_translate_checkbox_->checked());
if (model_->IsPageTranslatedInCurrentLanguages()) {
model_->GoBackFromAdvanced();
UpdateChildVisibilities();
SizeToContents();
} else {
translate_executed_ = true;
model_->Translate();
SwitchView(TranslateBubbleModel::VIEW_STATE_TRANSLATING);
}
break;
}
case BUTTON_ID_CANCEL: {
model_->GoBackFromAdvanced();
UpdateChildVisibilities();
SizeToContents();
break;
}
case BUTTON_ID_TRY_AGAIN: {
translate_executed_ = true;
model_->Translate();
break;
}
case BUTTON_ID_SHOW_ORIGINAL: {
model_->RevertTranslation();
StartFade(false);
break;
}
case BUTTON_ID_ALWAYS_TRANSLATE: {
// Do nothing. The state of the checkbox affects only when the 'Done'
// button is pressed.
break;
}
}
}
void TranslateBubbleView::HandleLinkClicked(
TranslateBubbleView::LinkID sender_id) {
switch (sender_id) {
case LINK_ID_ADVANCED: {
SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
break;
}
case LINK_ID_LEARN_MORE: {
browser_->OpenURL(content::OpenURLParams(
GURL(chrome::kAboutGoogleTranslateURL),
content::Referrer(),
NEW_FOREGROUND_TAB,
content::PAGE_TRANSITION_LINK,
false));
break;
}
}
}
void TranslateBubbleView::HandleComboboxSelectedIndexChanged(
TranslateBubbleView::ComboboxID sender_id) {
switch (sender_id) {
case COMBOBOX_ID_DENIAL: {
// do nothing
break;
}
case COMBOBOX_ID_SOURCE_LANGUAGE: {
if (model_->GetOriginalLanguageIndex() ==
source_language_combobox_->selected_index()) {
break;
}
model_->UpdateOriginalLanguageIndex(
source_language_combobox_->selected_index());
UpdateAdvancedView();
break;
}
case COMBOBOX_ID_TARGET_LANGUAGE: {
if (model_->GetTargetLanguageIndex() ==
target_language_combobox_->selected_index()) {
break;
}
model_->UpdateTargetLanguageIndex(
target_language_combobox_->selected_index());
UpdateAdvancedView();
break;
}
}
}
void TranslateBubbleView::UpdateChildVisibilities() {
for (int i = 0; i < child_count(); i++) {
views::View* view = child_at(i);
view->SetVisible(view == GetCurrentView());
}
}
views::View* TranslateBubbleView::CreateViewBeforeTranslate() {
views::Label* message_label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE));
base::string16 original_language_name =
model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
denial_combobox_ = new views::Combobox(
new TranslateDenialComboboxModel(original_language_name));
denial_combobox_->set_id(COMBOBOX_ID_DENIAL);
denial_combobox_->set_listener(this);
denial_combobox_->SetStyle(views::Combobox::STYLE_NOTIFY_ON_CLICK);
views::View* view = new views::View();
views::GridLayout* layout = new views::GridLayout(view);
view->SetLayoutManager(layout);
using views::GridLayout;
enum {
COLUMN_SET_ID_MESSAGE,
COLUMN_SET_ID_CONTENT,
};
views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, 0);
cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
cs->AddPaddingColumn(1, 0);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
layout->AddView(message_label);
layout->AddView(CreateLink(this,
IDS_TRANSLATE_BUBBLE_ADVANCED,
LINK_ID_ADVANCED));
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_CONTENT);
layout->AddView(denial_combobox_);
layout->AddView(CreateLabelButton(
this,
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT),
BUTTON_ID_TRANSLATE));
return view;
}
views::View* TranslateBubbleView::CreateViewTranslating() {
base::string16 target_language_name =
model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
views::Label* label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATING));
views::View* view = new views::View();
views::GridLayout* layout = new views::GridLayout(view);
view->SetLayoutManager(layout);
using views::GridLayout;
enum {
COLUMN_SET_ID_MESSAGE,
COLUMN_SET_ID_CONTENT,
};
views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, views::GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, 0);
cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
cs->AddPaddingColumn(1, 0);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
layout->AddView(label);
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_CONTENT);
views::LabelButton* revert_button = CreateLabelButton(
this,
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
BUTTON_ID_SHOW_ORIGINAL);
revert_button->SetEnabled(false);
layout->AddView(revert_button);
return view;
}
views::View* TranslateBubbleView::CreateViewAfterTranslate() {
views::Label* label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATED));
views::View* view = new views::View();
views::GridLayout* layout = new views::GridLayout(view);
view->SetLayoutManager(layout);
using views::GridLayout;
enum {
COLUMN_SET_ID_MESSAGE,
COLUMN_SET_ID_CONTENT,
};
views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, views::GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, views::GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, 0);
cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
cs->AddPaddingColumn(1, 0);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
layout->AddView(label);
layout->AddView(CreateLink(this,
IDS_TRANSLATE_BUBBLE_ADVANCED,
LINK_ID_ADVANCED));
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_CONTENT);
layout->AddView(CreateLabelButton(
this,
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
BUTTON_ID_SHOW_ORIGINAL));
return view;
}
views::View* TranslateBubbleView::CreateViewError() {
views::Label* label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE));
views::View* view = new views::View();
views::GridLayout* layout = new views::GridLayout(view);
view->SetLayoutManager(layout);
using views::GridLayout;
enum {
COLUMN_SET_ID_MESSAGE,
COLUMN_SET_ID_CONTENT,
};
views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, 0);
cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
cs->AddPaddingColumn(1, 0);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
layout->AddView(label);
layout->AddView(CreateLink(this,
IDS_TRANSLATE_BUBBLE_ADVANCED,
LINK_ID_ADVANCED));
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_CONTENT);
layout->AddView(CreateLabelButton(
this,
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN),
BUTTON_ID_TRY_AGAIN));
return view;
}
// TODO(hajimehoshi): Revice this later to show a specific message for each
// error. (crbug/307350)
views::View* TranslateBubbleView::CreateViewAdvanced() {
views::Label* source_language_label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE));
views::Label* target_language_label = new views::Label(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE));
int source_default_index = model_->GetOriginalLanguageIndex();
source_language_combobox_model_.reset(
new LanguageComboboxModel(source_default_index, model_.get()));
source_language_combobox_ =
new views::Combobox(source_language_combobox_model_.get());
source_language_combobox_->set_id(COMBOBOX_ID_SOURCE_LANGUAGE);
source_language_combobox_->set_listener(this);
int target_default_index = model_->GetTargetLanguageIndex();
target_language_combobox_model_.reset(
new LanguageComboboxModel(target_default_index, model_.get()));
target_language_combobox_ =
new views::Combobox(target_language_combobox_model_.get());
target_language_combobox_->set_id(COMBOBOX_ID_TARGET_LANGUAGE);
target_language_combobox_->set_listener(this);
// In an incognito window, "Always translate" checkbox shouldn't be shown.
if (!is_in_incognito_window_) {
always_translate_checkbox_ = new views::Checkbox(string16());
always_translate_checkbox_->set_id(BUTTON_ID_ALWAYS_TRANSLATE);
always_translate_checkbox_->set_listener(this);
}
views::View* view = new views::View();
views::GridLayout* layout = new views::GridLayout(view);
view->SetLayoutManager(layout);
using views::GridLayout;
enum {
COLUMN_SET_ID_LANGUAGES,
COLUMN_SET_ID_BUTTONS,
};
views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_LANGUAGES);
cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
cs->AddColumn(GridLayout::FILL, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, 0);
cs = layout->AddColumnSet(COLUMN_SET_ID_BUTTONS);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
0, GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
layout->AddView(source_language_label);
layout->AddView(source_language_combobox_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
layout->AddView(target_language_label);
layout->AddView(target_language_combobox_);
if (!is_in_incognito_window_) {
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
layout->SkipColumns(1);
layout->AddView(always_translate_checkbox_);
}
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
layout->StartRow(0, COLUMN_SET_ID_BUTTONS);
layout->AddView(CreateLink(this,
IDS_TRANSLATE_BUBBLE_LEARN_MORE,
LINK_ID_LEARN_MORE));
advanced_cancel_button_ = CreateLabelButton(
this, l10n_util::GetStringUTF16(IDS_CANCEL), BUTTON_ID_CANCEL);
layout->AddView(advanced_cancel_button_);
advanced_done_button_ = CreateLabelButton(
this, l10n_util::GetStringUTF16(IDS_DONE), BUTTON_ID_DONE);
advanced_done_button_->SetIsDefault(true);
layout->AddView(advanced_done_button_);
UpdateAdvancedView();
return view;
}
void TranslateBubbleView::SwitchView(
TranslateBubbleModel::ViewState view_state) {
if (model_->GetViewState() == view_state)
return;
model_->SetViewState(view_state);
UpdateChildVisibilities();
if (view_state == TranslateBubbleModel::VIEW_STATE_ADVANCED)
UpdateAdvancedView();
SizeToContents();
}
void TranslateBubbleView::UpdateAdvancedView() {
DCHECK(source_language_combobox_);
DCHECK(target_language_combobox_);
DCHECK(advanced_done_button_);
base::string16 source_language_name =
model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
base::string16 target_language_name =
model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
// "Always translate" checkbox doesn't exist in an incognito window.
if (always_translate_checkbox_) {
always_translate_checkbox_->SetText(
l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS));
always_translate_checkbox_->SetChecked(
model_->ShouldAlwaysTranslate());
}
base::string16 label;
if (model_->IsPageTranslatedInCurrentLanguages())
label = l10n_util::GetStringUTF16(IDS_DONE);
else
label = l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT);
advanced_done_button_->SetText(label);
}