OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/translate/translate_bubble_view.h" | 5 #include "chrome/browser/ui/views/translate/translate_bubble_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/i18n/string_compare.h" | 11 #include "base/i18n/string_compare.h" |
12 #include "base/memory/singleton.h" | 12 #include "base/memory/singleton.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/browser/translate/translate_manager.h" | 18 #include "chrome/browser/translate/translate_manager.h" |
19 #include "chrome/browser/translate/translate_tab_helper.h" | 19 #include "chrome/browser/translate/translate_tab_helper.h" |
20 #include "chrome/browser/translate/translate_ui_delegate.h" | 20 #include "chrome/browser/translate/translate_ui_delegate.h" |
21 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
22 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" | 22 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" |
| 23 #include "chrome/browser/ui/translate/translate_denial_menu_model.h" |
23 #include "chrome/common/url_constants.h" | 24 #include "chrome/common/url_constants.h" |
24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
25 #include "grit/generated_resources.h" | 26 #include "grit/generated_resources.h" |
26 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
27 #include "ui/base/models/combobox_model.h" | 28 #include "ui/base/models/combobox_model.h" |
28 #include "ui/base/resource/resource_bundle.h" | 29 #include "ui/base/resource/resource_bundle.h" |
29 #include "ui/views/controls/button/checkbox.h" | 30 #include "ui/views/controls/button/checkbox.h" |
30 #include "ui/views/controls/button/label_button.h" | 31 #include "ui/views/controls/button/label_button.h" |
| 32 #include "ui/views/controls/button/multi_target_button.h" |
31 #include "ui/views/controls/combobox/combobox.h" | 33 #include "ui/views/controls/combobox/combobox.h" |
32 #include "ui/views/controls/label.h" | 34 #include "ui/views/controls/label.h" |
33 #include "ui/views/controls/link.h" | 35 #include "ui/views/controls/link.h" |
34 #include "ui/views/layout/box_layout.h" | 36 #include "ui/views/layout/box_layout.h" |
35 #include "ui/views/layout/grid_layout.h" | 37 #include "ui/views/layout/grid_layout.h" |
36 #include "ui/views/layout/layout_constants.h" | 38 #include "ui/views/layout/layout_constants.h" |
37 #include "ui/views/widget/widget.h" | 39 #include "ui/views/widget/widget.h" |
38 | 40 |
39 namespace { | 41 namespace { |
40 | 42 |
(...skipping 21 matching lines...) Expand all Loading... |
62 DCHECK(source != NULL); | 64 DCHECK(source != NULL); |
63 DCHECK(target != NULL); | 65 DCHECK(target != NULL); |
64 | 66 |
65 TranslateTabHelper* translate_tab_helper = | 67 TranslateTabHelper* translate_tab_helper = |
66 TranslateTabHelper::FromWebContents(web_contents); | 68 TranslateTabHelper::FromWebContents(web_contents); |
67 *source = translate_tab_helper->language_state().original_language(); | 69 *source = translate_tab_helper->language_state().original_language(); |
68 *target = TranslateManager::GetLanguageCode( | 70 *target = TranslateManager::GetLanguageCode( |
69 g_browser_process->GetApplicationLocale()); | 71 g_browser_process->GetApplicationLocale()); |
70 } | 72 } |
71 | 73 |
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 } // namespace | 74 } // namespace |
116 | 75 |
117 // static | 76 // static |
118 TranslateBubbleView* TranslateBubbleView::translate_bubble_view_ = NULL; | 77 TranslateBubbleView* TranslateBubbleView::translate_bubble_view_ = NULL; |
119 | 78 |
120 TranslateBubbleView::~TranslateBubbleView() { | 79 TranslateBubbleView::~TranslateBubbleView() { |
121 // A child view could refer to a model which is owned by this class when | 80 // 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_| | 81 // the child view is destructed. For example, |source_language_combobx_model_| |
123 // is referred by Combobox's destructor. Before destroying the models, | 82 // is referred by Combobox's destructor. Before destroying the models, |
124 // removing the child views is needed. | 83 // removing the child views is needed. |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 } | 203 } |
245 | 204 |
246 void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) { | 205 void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) { |
247 HandleComboboxSelectedIndexChanged(static_cast<ComboboxID>(combobox->id())); | 206 HandleComboboxSelectedIndexChanged(static_cast<ComboboxID>(combobox->id())); |
248 } | 207 } |
249 | 208 |
250 void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) { | 209 void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) { |
251 HandleLinkClicked(static_cast<LinkID>(source->id())); | 210 HandleLinkClicked(static_cast<LinkID>(source->id())); |
252 } | 211 } |
253 | 212 |
| 213 void TranslateBubbleView::OnExecutingDenialCommand( |
| 214 TranslateDenialMenuModelObserver::Command command) { |
| 215 switch (command) { |
| 216 case TranslateDenialMenuModelObserver::COMMAND_DENY: |
| 217 if (!translate_executed_) |
| 218 model_->TranslationDeclined(); |
| 219 StartFade(false); |
| 220 break; |
| 221 case TranslateDenialMenuModelObserver::COMMAND_NEVER_TRANSLATE_LANG: |
| 222 model_->SetNeverTranslateLanguage(true); |
| 223 StartFade(false); |
| 224 break; |
| 225 case TranslateDenialMenuModelObserver::COMMAND_NEVER_TRANSLATE_SITE: |
| 226 model_->SetNeverTranslateSite(true); |
| 227 StartFade(false); |
| 228 break; |
| 229 } |
| 230 } |
| 231 |
254 TranslateBubbleModel::ViewState TranslateBubbleView::GetViewState() const { | 232 TranslateBubbleModel::ViewState TranslateBubbleView::GetViewState() const { |
255 return model_->GetViewState(); | 233 return model_->GetViewState(); |
256 } | 234 } |
257 | 235 |
258 TranslateBubbleView::TranslateBubbleView( | 236 TranslateBubbleView::TranslateBubbleView( |
259 views::View* anchor_view, | 237 views::View* anchor_view, |
260 scoped_ptr<TranslateBubbleModel> model, | 238 scoped_ptr<TranslateBubbleModel> model, |
261 bool is_in_incognito_window, | 239 bool is_in_incognito_window, |
262 Browser* browser) | 240 Browser* browser) |
263 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), | 241 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), |
264 before_translate_view_(NULL), | 242 before_translate_view_(NULL), |
265 translating_view_(NULL), | 243 translating_view_(NULL), |
266 after_translate_view_(NULL), | 244 after_translate_view_(NULL), |
267 error_view_(NULL), | 245 error_view_(NULL), |
268 advanced_view_(NULL), | 246 advanced_view_(NULL), |
269 denial_combobox_(NULL), | 247 denial_button_(NULL), |
270 source_language_combobox_(NULL), | 248 source_language_combobox_(NULL), |
271 target_language_combobox_(NULL), | 249 target_language_combobox_(NULL), |
272 always_translate_checkbox_(NULL), | 250 always_translate_checkbox_(NULL), |
273 model_(model.Pass()), | 251 model_(model.Pass()), |
274 is_in_incognito_window_(is_in_incognito_window), | 252 is_in_incognito_window_(is_in_incognito_window), |
275 browser_(browser), | 253 browser_(browser), |
276 translate_executed_(false) { | 254 translate_executed_(false) { |
277 if (model_->GetViewState() != | 255 if (model_->GetViewState() != |
278 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { | 256 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { |
279 translate_executed_ = true; | 257 translate_executed_ = true; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 content::PAGE_TRANSITION_LINK, | 333 content::PAGE_TRANSITION_LINK, |
356 false)); | 334 false)); |
357 break; | 335 break; |
358 } | 336 } |
359 } | 337 } |
360 } | 338 } |
361 | 339 |
362 void TranslateBubbleView::HandleComboboxSelectedIndexChanged( | 340 void TranslateBubbleView::HandleComboboxSelectedIndexChanged( |
363 TranslateBubbleView::ComboboxID sender_id) { | 341 TranslateBubbleView::ComboboxID sender_id) { |
364 switch (sender_id) { | 342 switch (sender_id) { |
365 case COMBOBOX_ID_DENIAL: { | |
366 int index = denial_combobox_->selected_index(); | |
367 switch (index) { | |
368 case TranslateDenialComboboxModel::INDEX_NOPE: | |
369 if (!translate_executed_) | |
370 model_->TranslationDeclined(); | |
371 StartFade(false); | |
372 break; | |
373 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_LANGUAGE: | |
374 model_->SetNeverTranslateLanguage(true); | |
375 StartFade(false); | |
376 break; | |
377 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_SITE: | |
378 model_->SetNeverTranslateSite(true); | |
379 StartFade(false); | |
380 break; | |
381 default: | |
382 NOTREACHED(); | |
383 break; | |
384 } | |
385 break; | |
386 } | |
387 case COMBOBOX_ID_SOURCE_LANGUAGE: { | 343 case COMBOBOX_ID_SOURCE_LANGUAGE: { |
388 model_->UpdateOriginalLanguageIndex( | 344 model_->UpdateOriginalLanguageIndex( |
389 source_language_combobox_->selected_index()); | 345 source_language_combobox_->selected_index()); |
390 UpdateAdvancedView(); | 346 UpdateAdvancedView(); |
391 break; | 347 break; |
392 } | 348 } |
393 case COMBOBOX_ID_TARGET_LANGUAGE: { | 349 case COMBOBOX_ID_TARGET_LANGUAGE: { |
394 model_->UpdateTargetLanguageIndex( | 350 model_->UpdateTargetLanguageIndex( |
395 target_language_combobox_->selected_index()); | 351 target_language_combobox_->selected_index()); |
396 UpdateAdvancedView(); | 352 UpdateAdvancedView(); |
397 break; | 353 break; |
398 } | 354 } |
399 } | 355 } |
400 } | 356 } |
401 | 357 |
402 void TranslateBubbleView::UpdateChildVisibilities() { | 358 void TranslateBubbleView::UpdateChildVisibilities() { |
403 for (int i = 0; i < child_count(); i++) { | 359 for (int i = 0; i < child_count(); i++) { |
404 views::View* view = child_at(i); | 360 views::View* view = child_at(i); |
405 view->SetVisible(view == GetCurrentView()); | 361 view->SetVisible(view == GetCurrentView()); |
406 } | 362 } |
407 } | 363 } |
408 | 364 |
409 views::View* TranslateBubbleView::CreateViewBeforeTranslate() { | 365 views::View* TranslateBubbleView::CreateViewBeforeTranslate() { |
410 views::Label* message_label = new views::Label( | 366 views::Label* message_label = new views::Label( |
411 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE)); | 367 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE)); |
412 | 368 |
413 string16 original_language_name = | 369 string16 original_language_name = |
414 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); | 370 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); |
415 denial_combobox_ = new views::Combobox( | 371 denial_button_model_.reset( |
416 new TranslateDenialComboboxModel(original_language_name)); | 372 new TranslateDenialMenuModel(original_language_name, this)); |
417 denial_combobox_->set_id(COMBOBOX_ID_DENIAL); | 373 denial_button_ = new views::MultiTargetButton(denial_button_model_.get()); |
418 denial_combobox_->set_listener(this); | |
419 | 374 |
420 views::View* view = new views::View(); | 375 views::View* view = new views::View(); |
421 views::GridLayout* layout = new views::GridLayout(view); | 376 views::GridLayout* layout = new views::GridLayout(view); |
422 view->SetLayoutManager(layout); | 377 view->SetLayoutManager(layout); |
423 | 378 |
424 using views::GridLayout; | 379 using views::GridLayout; |
425 | 380 |
426 enum { | 381 enum { |
427 COLUMN_SET_ID_MESSAGE, | 382 COLUMN_SET_ID_MESSAGE, |
428 COLUMN_SET_ID_CONTENT, | 383 COLUMN_SET_ID_CONTENT, |
429 }; | 384 }; |
430 | 385 |
431 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); | 386 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); |
432 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | 387 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
433 0, GridLayout::USE_PREF, 0, 0); | 388 0, GridLayout::USE_PREF, 0, 0); |
434 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | 389 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); |
435 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | 390 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
436 0, GridLayout::USE_PREF, 0, 0); | 391 0, GridLayout::USE_PREF, 0, 0); |
437 cs->AddPaddingColumn(1, 0); | 392 cs->AddPaddingColumn(1, 0); |
438 | 393 |
439 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); | 394 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); |
440 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | 395 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
441 0, GridLayout::USE_PREF, 0, 0); | 396 0, GridLayout::USE_PREF, 0, 0); |
442 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | 397 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); |
443 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | 398 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
444 0, GridLayout::USE_PREF, 0, 0); | 399 0, GridLayout::USE_PREF, 0, 0); |
445 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | 400 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); |
446 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | 401 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
447 0, GridLayout::USE_PREF, 0, 0); | 402 0, GridLayout::USE_PREF, 0, 0); |
| 403 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); |
| 404 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, |
| 405 0, GridLayout::USE_PREF, 0, 0); |
448 | 406 |
449 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); | 407 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); |
450 layout->AddView(message_label); | 408 layout->AddView(message_label); |
451 layout->AddView(CreateLink(this, | 409 layout->AddView(CreateLink(this, |
452 IDS_TRANSLATE_BUBBLE_ADVANCED, | 410 IDS_TRANSLATE_BUBBLE_ADVANCED, |
453 LINK_ID_ADVANCED)); | 411 LINK_ID_ADVANCED)); |
454 | 412 |
455 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | 413 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); |
456 | 414 |
457 layout->StartRow(0, COLUMN_SET_ID_CONTENT); | 415 layout->StartRow(0, COLUMN_SET_ID_CONTENT); |
458 layout->AddView(CreateLink(this, | 416 layout->AddView(CreateLink(this, |
459 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | 417 IDS_TRANSLATE_BUBBLE_LEARN_MORE, |
460 LINK_ID_LEARN_MORE)); | 418 LINK_ID_LEARN_MORE)); |
461 layout->AddView(denial_combobox_); | 419 layout->AddView(denial_button_); |
462 layout->AddView(CreateLabelButton( | 420 layout->AddView(CreateLabelButton( |
463 this, | 421 this, |
464 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT), | 422 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT), |
465 BUTTON_ID_TRANSLATE)); | 423 BUTTON_ID_TRANSLATE)); |
466 | 424 |
467 return view; | 425 return view; |
468 } | 426 } |
469 | 427 |
470 views::View* TranslateBubbleView::CreateViewTranslating() { | 428 views::View* TranslateBubbleView::CreateViewTranslating() { |
471 string16 target_language_name = | 429 string16 target_language_name = |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS, | 703 l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS, |
746 source_language_name, | 704 source_language_name, |
747 target_language_name); | 705 target_language_name); |
748 // "Always translate" checkbox doesn't exist in an incognito window. | 706 // "Always translate" checkbox doesn't exist in an incognito window. |
749 if (always_translate_checkbox_) { | 707 if (always_translate_checkbox_) { |
750 always_translate_checkbox_->SetText(message); | 708 always_translate_checkbox_->SetText(message); |
751 always_translate_checkbox_->SetChecked( | 709 always_translate_checkbox_->SetChecked( |
752 model_->ShouldAlwaysTranslate()); | 710 model_->ShouldAlwaysTranslate()); |
753 } | 711 } |
754 } | 712 } |
OLD | NEW |