Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(784)

Side by Side Diff: chrome/browser/ui/views/translate/translate_bubble_view.cc

Issue 25373009: Translate: New Bubble UX (for the view toolkit) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add the browser test Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
6
7 #include <algorithm>
8 #include <string>
9 #include <vector>
10
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"
38
39 namespace {
40
41 views::LabelButton* CreateLabelButton(views::ButtonListener* listener,
42 const string16& label, int id) {
43 views::LabelButton* button = new views::LabelButton(listener, label);
44 button->set_id(id);
45 button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
46 return button;
47 }
48
49 views::Link* CreateLink(views::LinkListener* listener,
50 int resource_id,
51 int id) {
52 views::Link* link = new views::Link(
53 l10n_util::GetStringUTF16(resource_id));
54 link->set_listener(listener);
55 link->set_id(id);
56 return link;
57 }
58
59 void GetTranslateLanguages(content::WebContents* web_contents,
60 std::string* source,
61 std::string* target) {
62 DCHECK(source != NULL);
63 DCHECK(target != NULL);
64
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());
70 }
71
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 {
75 public:
76 enum {
77 INDEX_NOPE = 0,
78 INDEX_NEVER_TRANSLATE_LANGUAGE = 2,
79 INDEX_NEVER_TRANSLATE_SITE = 4,
80 };
81
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));
92 }
93 virtual ~TranslateDenialComboboxModel() {}
94
95 private:
96 // Overridden from ui::ComboboxModel:
97 virtual int GetItemCount() const OVERRIDE {
98 return items_.size();
99 }
100 virtual string16 GetItemAt(int index) OVERRIDE {
101 return items_[index];
102 }
103 virtual bool IsItemSeparatorAt(int index) OVERRIDE {
104 return items_[index].empty();
105 }
106 virtual int GetDefaultIndex() const OVERRIDE {
107 return 0;
108 }
109
110 std::vector<string16> items_;
111
112 DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel);
113 };
114
115 const char* kUMATranslateModifyOriginalLang = "Translate.ModifyOriginalLang";
116 const char* kUMATranslateModifyTargetLang = "Translate.ModifyTargetLang";
117
118 } // namespace
119
120 // static
121 TranslateBubbleView* TranslateBubbleView::translate_bubble_view_ = NULL;
122
123 TranslateBubbleView::~TranslateBubbleView() {
124 // A child view could refer to a model which is owned by this class when
125 // the child view is destructed. For example, |source_language_combobx_model_|
126 // is referred by Combobox's destructor. Before destroying the models,
127 // removing the child views is needed.
128 RemoveAllChildViews(true);
129 }
130
131 // static
132 void TranslateBubbleView::ShowBubble(views::View* anchor_view,
133 content::WebContents* web_contents,
134 TranslateBubbleModel::ViewState type,
135 Browser* browser) {
136 if (IsShowing()) {
137 translate_bubble_view_->SwitchView(type);
138 return;
139 }
140
141 std::string source_language;
142 std::string target_language;
143 GetTranslateLanguages(web_contents, &source_language, &target_language);
144
145 scoped_ptr<TranslateUIDelegate> ui_delegate(
146 new TranslateUIDelegate(web_contents, source_language, target_language));
147 scoped_ptr<TranslateBubbleModel> model(
148 new TranslateBubbleModelImpl(type, ui_delegate.Pass()));
149 bool is_in_incognito_window =
150 web_contents->GetBrowserContext()->IsOffTheRecord();
151 TranslateBubbleView* view = new TranslateBubbleView(anchor_view,
152 model.Pass(),
153 is_in_incognito_window,
154 browser);
155 views::BubbleDelegateView::CreateBubble(view)->Show();
156 }
157
158 // static
159 bool TranslateBubbleView::IsShowing() {
160 return translate_bubble_view_ != NULL;
161 }
162
163 // static
164 TranslateBubbleView* TranslateBubbleView::GetCurrentBubble() {
165 return translate_bubble_view_;
166 }
167
168 void TranslateBubbleView::Init() {
169 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
170 0, 0, 0));
171
172 before_translate_view_ = CreateViewBeforeTranslate();
173 translating_view_ = CreateViewTranslating();
174 after_translate_view_ = CreateViewAfterTranslate();
175 error_view_ = CreateViewError();
176 advanced_view_ = CreateViewAdvanced();
177
178 AddChildView(before_translate_view_);
179 AddChildView(translating_view_);
180 AddChildView(after_translate_view_);
181 AddChildView(error_view_);
182 AddChildView(advanced_view_);
183
184 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
185
186 UpdateChildVisibilities();
187 }
188
189 void TranslateBubbleView::ButtonPressed(views::Button* sender,
190 const ui::Event& event) {
191 HandleButtonPressed(static_cast<ButtonID>(sender->id()));
192 }
193
194 void TranslateBubbleView::WindowClosing() {
195 if (!translate_executed_ && !browser_->IsAttemptingToCloseBrowser())
196 model_->TranslationDeclined();
197
198 // We have to reset |translate_bubble_view_| here, not in our destructor,
199 // because we'll be destroyed asynchronously and the shown state will be
200 // checked before then.
201 DCHECK_EQ(translate_bubble_view_, this);
202 translate_bubble_view_ = NULL;
203 }
204
205 bool TranslateBubbleView::AcceleratorPressed(
206 const ui::Accelerator& accelerator) {
207 switch (model_->GetViewState()) {
208 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE: {
209 if (accelerator.key_code() == ui::VKEY_RETURN) {
210 HandleButtonPressed(BUTTON_ID_TRANSLATE);
211 return true;
212 }
213 break;
214 }
215 case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
216 break;
217 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE: {
218 if (accelerator.key_code() == ui::VKEY_RETURN) {
219 HandleButtonPressed(BUTTON_ID_SHOW_ORIGINAL);
220 return true;
221 }
222 break;
223 }
224 case TranslateBubbleModel::VIEW_STATE_ERROR:
225 break;
226 case TranslateBubbleModel::VIEW_STATE_ADVANCED: {
227 if (accelerator.key_code() == ui::VKEY_RETURN) {
228 HandleButtonPressed(BUTTON_ID_DONE);
229 return true;
230 }
231 break;
232 }
233 }
234 return BubbleDelegateView::AcceleratorPressed(accelerator);
235 }
236
237 gfx::Size TranslateBubbleView::GetPreferredSize() {
238 int width = 0;
239 for (int i = 0; i < child_count(); i++) {
240 views::View* child = child_at(i);
241 width = std::max(width, child->GetPreferredSize().width());
242 }
243 int height = GetCurrentView()->GetPreferredSize().height();
244 return gfx::Size(width, height);
245 }
246
247 void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) {
248 switch (static_cast<ComboboxID>(combobox->id())) {
249 case COMBOBOX_ID_DENIAL: {
250 int index = combobox->selected_index();
251 switch (index) {
252 case TranslateDenialComboboxModel::INDEX_NOPE:
253 if (!translate_executed_)
254 model_->TranslationDeclined();
255 StartFade(false);
256 break;
257 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_LANGUAGE:
258 model_->SetNeverTranslateLanguage(true);
259 StartFade(false);
260 break;
261 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_SITE:
262 model_->SetNeverTranslateSite(true);
263 StartFade(false);
264 break;
265 default:
266 NOTREACHED();
267 break;
268 }
269 break;
270 }
271 case COMBOBOX_ID_SOURCE_LANGUAGE: {
272 // TODO(hajimehoshi): This UMA should be counted at a model or a delegate
273 // not to dependent on platforms. However, this UMA has not been used at
274 // some platforms. See crbug/306365.
275 UMA_HISTOGRAM_BOOLEAN(kUMATranslateModifyOriginalLang, true);
276 UpdateAdvancedView();
277 break;
278 }
279 case COMBOBOX_ID_TARGET_LANGUAGE: {
280 // TODO(hajimehoshi): Ditto.
281 UMA_HISTOGRAM_BOOLEAN(kUMATranslateModifyTargetLang, true);
282 UpdateAdvancedView();
283 break;
284 }
285 }
286 }
287
288 void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) {
289 HandleLinkClicked(static_cast<LinkID>(source->id()));
290 }
291
292 TranslateBubbleModel::ViewState TranslateBubbleView::GetViewState() const {
293 return model_->GetViewState();
294 }
295
296 TranslateBubbleView::TranslateBubbleView(
297 views::View* anchor_view,
298 scoped_ptr<TranslateBubbleModel> model,
299 bool is_in_incognito_window,
300 Browser* browser)
301 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
302 source_language_combobox_(NULL),
303 target_language_combobox_(NULL),
304 always_translate_checkbox_(NULL),
305 model_(model.Pass()),
306 is_in_incognito_window_(is_in_incognito_window),
307 browser_(browser),
308 translate_executed_(false) {
309 if (model_->GetViewState() !=
310 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) {
311 translate_executed_ = true;
312 }
313
314 set_margins(gfx::Insets(views::kPanelVertMargin, views::kPanelHorizMargin,
315 views::kPanelVertMargin, views::kPanelHorizMargin));
316
317 translate_bubble_view_ = this;
318 }
319
320 views::View* TranslateBubbleView::GetCurrentView() {
321 switch (model_->GetViewState()) {
322 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE:
323 return before_translate_view_;
324 case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
325 return translating_view_;
326 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE:
327 return after_translate_view_;
328 case TranslateBubbleModel::VIEW_STATE_ERROR:
329 return error_view_;
330 case TranslateBubbleModel::VIEW_STATE_ADVANCED:
331 return advanced_view_;
332 }
333 NOTREACHED();
334 return NULL;
335 }
336
337 void TranslateBubbleView::HandleButtonPressed(
338 TranslateBubbleView::ButtonID sender_id) {
339 switch (sender_id) {
340 case BUTTON_ID_TRANSLATE: {
341 translate_executed_ = true;
342 model_->Translate();
343 break;
344 }
345 case BUTTON_ID_DONE: {
346 translate_executed_ = true;
347 DCHECK(source_language_combobox_);
348 DCHECK(target_language_combobox_);
349
350 model_->SetOriginalLanguageIndex(
351 source_language_combobox_->selected_index());
352 model_->SetTargetLanguageIndex(
353 target_language_combobox_->selected_index());
354 model_->Translate();
355 break;
356 }
357 case BUTTON_ID_CANCEL: {
358 model_->GoBackFromAdvanced();
359 UpdateChildVisibilities();
360 SizeToContents();
361 break;
362 }
363 case BUTTON_ID_TRY_AGAIN: {
364 translate_executed_ = true;
365 model_->Translate();
366 break;
367 }
368 case BUTTON_ID_SHOW_ORIGINAL: {
369 model_->RevertTranslation();
370 StartFade(false);
371 break;
372 }
373 case BUTTON_ID_ALWAYS_TRANSLATE: {
374 DCHECK(always_translate_checkbox_);
375 model_->SetAlwaysTranslate(always_translate_checkbox_->checked());
376 UpdateAdvancedView();
377 break;
378 }
379 }
380 }
381
382 void TranslateBubbleView::HandleLinkClicked(
383 TranslateBubbleView::LinkID sender_id) {
384 switch (sender_id) {
385 case LINK_ID_ADVANCED: {
386 SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
387 break;
388 }
389 case LINK_ID_LEARN_MORE: {
390 browser_->OpenURL(content::OpenURLParams(
391 GURL(chrome::kAboutGoogleTranslateURL),
392 content::Referrer(),
393 NEW_FOREGROUND_TAB,
394 content::PAGE_TRANSITION_LINK,
395 false));
396 break;
397 }
398 }
399 }
400
401 void TranslateBubbleView::UpdateChildVisibilities() {
402 for (int i = 0; i < child_count(); i++) {
403 views::View* view = child_at(i);
404 view->SetVisible(view == GetCurrentView());
405 }
406 }
407
408 views::View* TranslateBubbleView::CreateViewBeforeTranslate() {
409 views::Label* message_label = new views::Label(
410 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE));
411
412 string16 original_language_name =
413 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
414 views::Combobox* denial_combobox = new views::Combobox(
415 new TranslateDenialComboboxModel(original_language_name));
416 denial_combobox->set_id(COMBOBOX_ID_DENIAL);
417 denial_combobox->set_listener(this);
418
419 views::View* view = new views::View();
420 views::GridLayout* layout = new views::GridLayout(view);
421 view->SetLayoutManager(layout);
422
423 using views::GridLayout;
424
425 enum {
426 COLUMN_SET_ID_MESSAGE,
427 COLUMN_SET_ID_CONTENT,
428 };
429
430 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
431 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
432 0, GridLayout::USE_PREF, 0, 0);
433 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
434 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
435 0, GridLayout::USE_PREF, 0, 0);
436 cs->AddPaddingColumn(1, 0);
437
438 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
439 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
440 0, GridLayout::USE_PREF, 0, 0);
441 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
442 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
443 0, GridLayout::USE_PREF, 0, 0);
444 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
445 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
446 0, GridLayout::USE_PREF, 0, 0);
447
448 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
449 layout->AddView(message_label);
450 layout->AddView(CreateLink(this,
451 IDS_TRANSLATE_BUBBLE_ADVANCED,
452 LINK_ID_ADVANCED));
453
454 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
455
456 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
457 layout->AddView(CreateLink(this,
458 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
459 LINK_ID_LEARN_MORE));
460 layout->AddView(denial_combobox);
461 layout->AddView(CreateLabelButton(
462 this,
463 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT),
464 BUTTON_ID_TRANSLATE));
465
466 return view;
467 }
468
469 views::View* TranslateBubbleView::CreateViewTranslating() {
470 string16 target_language_name =
471 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
472 views::Label* label = new views::Label(
473 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATING));
474
475 views::View* view = new views::View();
476 views::GridLayout* layout = new views::GridLayout(view);
477 view->SetLayoutManager(layout);
478
479 using views::GridLayout;
480
481 enum {
482 COLUMN_SET_ID_MESSAGE,
483 COLUMN_SET_ID_CONTENT,
484 };
485
486 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
487 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
488 0, views::GridLayout::USE_PREF, 0, 0);
489 cs->AddPaddingColumn(1, 0);
490
491 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
492 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
493 0, GridLayout::USE_PREF, 0, 0);
494 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
495 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
496 0, GridLayout::USE_PREF, 0, 0);
497
498 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
499 layout->AddView(label);
500
501 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
502
503 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
504 layout->AddView(CreateLink(this,
505 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
506 LINK_ID_LEARN_MORE));
507 views::LabelButton* revert_button = CreateLabelButton(
508 this,
509 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
510 BUTTON_ID_SHOW_ORIGINAL);
511 revert_button->SetEnabled(false);
512 layout->AddView(revert_button);
513
514 return view;
515 }
516
517 views::View* TranslateBubbleView::CreateViewAfterTranslate() {
518 views::Label* label = new views::Label(
519 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATED));
520
521 views::View* view = new views::View();
522 views::GridLayout* layout = new views::GridLayout(view);
523 view->SetLayoutManager(layout);
524
525 using views::GridLayout;
526
527 enum {
528 COLUMN_SET_ID_MESSAGE,
529 COLUMN_SET_ID_CONTENT,
530 };
531
532 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
533 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
534 0, views::GridLayout::USE_PREF, 0, 0);
535 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
536 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
537 0, views::GridLayout::USE_PREF, 0, 0);
538 cs->AddPaddingColumn(1, 0);
539
540 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
541 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
542 0, GridLayout::USE_PREF, 0, 0);
543 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
544 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
545 0, GridLayout::USE_PREF, 0, 0);
546
547 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
548 layout->AddView(label);
549 layout->AddView(CreateLink(this,
550 IDS_TRANSLATE_BUBBLE_ADVANCED,
551 LINK_ID_ADVANCED));
552
553 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
554
555 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
556 layout->AddView(CreateLink(this,
557 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
558 LINK_ID_LEARN_MORE));
559 layout->AddView(CreateLabelButton(
560 this,
561 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT),
562 BUTTON_ID_SHOW_ORIGINAL));
563
564 return view;
565 }
566
567 views::View* TranslateBubbleView::CreateViewError() {
568 views::Label* label = new views::Label(
569 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE));
570
571 views::View* view = new views::View();
572 views::GridLayout* layout = new views::GridLayout(view);
573 view->SetLayoutManager(layout);
574
575 using views::GridLayout;
576
577 enum {
578 COLUMN_SET_ID_MESSAGE,
579 COLUMN_SET_ID_CONTENT,
580 };
581
582 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE);
583 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
584 0, GridLayout::USE_PREF, 0, 0);
585 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
586 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
587 0, GridLayout::USE_PREF, 0, 0);
588 cs->AddPaddingColumn(1, 0);
589
590 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT);
591 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
592 0, GridLayout::USE_PREF, 0, 0);
593 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
594 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
595 0, GridLayout::USE_PREF, 0, 0);
596
597 layout->StartRow(0, COLUMN_SET_ID_MESSAGE);
598 layout->AddView(label);
599 layout->AddView(CreateLink(this,
600 IDS_TRANSLATE_BUBBLE_ADVANCED,
601 LINK_ID_ADVANCED));
602
603 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
604
605 layout->StartRow(0, COLUMN_SET_ID_CONTENT);
606 layout->AddView(CreateLink(this,
607 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
608 LINK_ID_LEARN_MORE));
609 layout->AddView(CreateLabelButton(
610 this,
611 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN),
612 BUTTON_ID_TRY_AGAIN));
613
614 return view;
615 }
616
617 // TODO(hajimehoshi): Revice this later to show a specific message for each
618 // error. (crbug/307350)
619 views::View* TranslateBubbleView::CreateViewAdvanced() {
620 views::Label* source_language_label = new views::Label(
621 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE));
622
623 views::Label* target_language_label = new views::Label(
624 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE));
625
626 int source_default_index = model_->GetOriginalLanguageIndex();
627 source_language_combobox_model_.reset(
628 new LanguageComboboxModel(source_default_index, model_.get()));
629 source_language_combobox_ =
630 new views::Combobox(source_language_combobox_model_.get());
631
632 source_language_combobox_->set_id(COMBOBOX_ID_SOURCE_LANGUAGE);
633 source_language_combobox_->set_listener(this);
634
635 int target_default_index = model_->GetTargetLanguageIndex();
636 target_language_combobox_model_.reset(
637 new LanguageComboboxModel(target_default_index, model_.get()));
638 target_language_combobox_ =
639 new views::Combobox(target_language_combobox_model_.get());
640
641 target_language_combobox_->set_id(COMBOBOX_ID_TARGET_LANGUAGE);
642 target_language_combobox_->set_listener(this);
643
644 // In an incognito window, "Always translate" checkbox shouldn't be shown.
645 if (!is_in_incognito_window_) {
646 always_translate_checkbox_ = new views::Checkbox(string16());
647 always_translate_checkbox_->set_id(BUTTON_ID_ALWAYS_TRANSLATE);
648 always_translate_checkbox_->set_listener(this);
649 }
650
651 views::View* view = new views::View();
652 views::GridLayout* layout = new views::GridLayout(view);
653 view->SetLayoutManager(layout);
654
655 using views::GridLayout;
656
657 enum {
658 COLUMN_SET_ID_LANGUAGES,
659 COLUMN_SET_ID_ALWAYS_TRANSLATE,
660 COLUMN_SET_ID_BUTTONS,
661 };
662
663 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_LANGUAGES);
664 cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER,
665 0, GridLayout::USE_PREF, 0, 0);
666 cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
667 cs->AddColumn(GridLayout::FILL, GridLayout::CENTER,
668 0, GridLayout::USE_PREF, 0, 0);
669 cs->AddPaddingColumn(1, 0);
670
671 if (!is_in_incognito_window_) {
672 cs = layout->AddColumnSet(COLUMN_SET_ID_ALWAYS_TRANSLATE);
673 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER,
674 0, GridLayout::USE_PREF, 0, 0);
675 cs->AddPaddingColumn(1, 0);
676 }
677
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);
687
688 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
689 layout->AddView(source_language_label);
690 layout->AddView(source_language_combobox_);
691
692 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
693
694 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES);
695 layout->AddView(target_language_label);
696 layout->AddView(target_language_combobox_);
697
698 if (!is_in_incognito_window_) {
699 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
700
701 layout->StartRow(0, COLUMN_SET_ID_ALWAYS_TRANSLATE);
702 layout->AddView(always_translate_checkbox_);
703 }
704
705 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
706
707 layout->StartRow(0, COLUMN_SET_ID_BUTTONS);
708 layout->AddView(CreateLink(this,
709 IDS_TRANSLATE_BUBBLE_LEARN_MORE,
710 LINK_ID_LEARN_MORE));
711 views::LabelButton* cancel_button = CreateLabelButton(
712 this, l10n_util::GetStringUTF16(IDS_CANCEL), BUTTON_ID_CANCEL);
713 layout->AddView(cancel_button);
714 views::LabelButton* done_button = CreateLabelButton(
715 this, l10n_util::GetStringUTF16(IDS_DONE), BUTTON_ID_DONE);
716 done_button->SetIsDefault(true);
717 layout->AddView(done_button);
718
719 UpdateAdvancedView();
720
721 return view;
722 }
723
724 void TranslateBubbleView::SwitchView(
725 TranslateBubbleModel::ViewState view_state) {
726 if (model_->GetViewState() == view_state)
727 return;
728
729 model_->SetViewState(view_state);
730 UpdateChildVisibilities();
731 SizeToContents();
732 }
733
734 void TranslateBubbleView::UpdateAdvancedView() {
735 DCHECK(source_language_combobox_);
736 DCHECK(target_language_combobox_);
737
738 model_->SetOriginalLanguageIndex(
739 source_language_combobox_->selected_index());
740 model_->SetTargetLanguageIndex(
741 target_language_combobox_->selected_index());
742
743 string16 source_language_name =
744 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
745 string16 target_language_name =
746 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex());
747
748 string16 message =
749 l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS,
750 source_language_name,
751 target_language_name);
752 // "Always translate" checkbox doesn't exist in an incognito window.
753 if (always_translate_checkbox_) {
754 always_translate_checkbox_->SetText(message);
755 always_translate_checkbox_->SetChecked(
756 model_->ShouldAlwaysTranslate());
757 }
758 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698