Chromium Code Reviews| 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/passwords/manage_passwords_bubble_view.h" | 5 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h" |
| 6 | 6 |
| 7 #include "base/timer/timer.h" | 7 #include "base/timer/timer.h" |
| 8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
| 9 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/browser_finder.h" | 10 #include "chrome/browser/ui/browser_finder.h" |
| 11 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" | 11 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
| 12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" | 12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" |
| 13 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" | 13 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" |
| 14 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h" | 14 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h" |
| 15 #include "chrome/browser/ui/views/frame/browser_view.h" | 15 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 16 #include "chrome/browser/ui/views/passwords/credentials_item_view.h" | 16 #include "chrome/browser/ui/views/passwords/credentials_item_view.h" |
| 17 #include "chrome/browser/ui/views/passwords/manage_credential_item_view.h" | 17 #include "chrome/browser/ui/views/passwords/manage_credential_item_view.h" |
| 18 #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" | 18 #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" |
| 19 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" | 19 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" |
| 20 #include "chrome/browser/ui/views/passwords/save_account_more_combobox_model.h" | |
| 20 #include "chrome/grit/generated_resources.h" | 21 #include "chrome/grit/generated_resources.h" |
| 21 #include "content/public/browser/render_view_host.h" | 22 #include "content/public/browser/render_view_host.h" |
| 22 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
| 23 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
| 24 #include "ui/views/controls/button/blue_button.h" | 25 #include "ui/views/controls/button/blue_button.h" |
| 25 #include "ui/views/controls/button/label_button.h" | 26 #include "ui/views/controls/button/label_button.h" |
| 26 #include "ui/views/controls/combobox/combobox.h" | 27 #include "ui/views/controls/combobox/combobox.h" |
| 27 #include "ui/views/controls/combobox/combobox_listener.h" | 28 #include "ui/views/controls/combobox/combobox_listener.h" |
| 28 #include "ui/views/controls/link.h" | 29 #include "ui/views/controls/link.h" |
| 29 #include "ui/views/controls/link_listener.h" | 30 #include "ui/views/controls/link_listener.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 41 | 42 |
| 42 namespace { | 43 namespace { |
| 43 | 44 |
| 44 const int kAutoSigninToastTimeout = 3; | 45 const int kAutoSigninToastTimeout = 3; |
| 45 const int kDesiredBubbleWidth = 370; | 46 const int kDesiredBubbleWidth = 370; |
| 46 | 47 |
| 47 enum ColumnSetType { | 48 enum ColumnSetType { |
| 48 // | | (FILL, FILL) | | | 49 // | | (FILL, FILL) | | |
| 49 // Used for the bubble's header, the credentials list, and for simple | 50 // Used for the bubble's header, the credentials list, and for simple |
| 50 // messages like "No passwords". | 51 // messages like "No passwords". |
| 51 SINGLE_VIEW_COLUMN_SET = 0, | 52 SINGLE_VIEW_COLUMN_SET, |
|
Mike West
2015/03/19 12:50:24
Nit: Why kill the assignments? Don't we need to en
vasilii
2015/03/19 14:48:57
There is no reason for them to be zero-based. Note
| |
| 52 | 53 |
| 53 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | | 54 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | |
| 54 // Used for buttons at the bottom of the bubble which should nest at the | 55 // Used for buttons at the bottom of the bubble which should nest at the |
| 55 // bottom-right corner. | 56 // bottom-right corner. |
| 56 DOUBLE_BUTTON_COLUMN_SET = 1, | 57 DOUBLE_BUTTON_COLUMN_SET, |
| 57 | 58 |
| 58 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | | 59 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | |
| 59 // Used for buttons at the bottom of the bubble which should occupy | 60 // Used for buttons at the bottom of the bubble which should occupy |
| 60 // the corners. | 61 // the corners. |
| 61 LINK_BUTTON_COLUMN_SET = 2, | 62 LINK_BUTTON_COLUMN_SET, |
| 62 | 63 |
| 63 // | | (TRAILING, CENTER) | | | 64 // | | (TRAILING, CENTER) | | |
| 64 // Used when there is only one button which should next at the bottom-right | 65 // Used when there is only one button which should next at the bottom-right |
| 65 // corner. | 66 // corner. |
| 66 SINGLE_BUTTON_COLUMN_SET = 3, | 67 SINGLE_BUTTON_COLUMN_SET, |
| 68 | |
| 69 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | | |
| 70 // Used when there are three buttons. | |
| 71 TRIPLE_BUTTON_COLUMN_SET, | |
| 67 }; | 72 }; |
| 68 | 73 |
| 69 enum TextRowType { ROW_SINGLE, ROW_MULTILINE }; | 74 enum TextRowType { ROW_SINGLE, ROW_MULTILINE }; |
| 70 | 75 |
| 71 // Construct an appropriate ColumnSet for the given |type|, and add it | 76 // Construct an appropriate ColumnSet for the given |type|, and add it |
| 72 // to |layout|. | 77 // to |layout|. |
| 73 void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) { | 78 void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) { |
| 74 views::ColumnSet* column_set = layout->AddColumnSet(type); | 79 views::ColumnSet* column_set = layout->AddColumnSet(type); |
| 75 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); | 80 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); |
| 76 int full_width = kDesiredBubbleWidth - (2 * views::kPanelHorizMargin); | 81 int full_width = kDesiredBubbleWidth - (2 * views::kPanelHorizMargin); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 0, | 119 0, |
| 115 0); | 120 0); |
| 116 break; | 121 break; |
| 117 case SINGLE_BUTTON_COLUMN_SET: | 122 case SINGLE_BUTTON_COLUMN_SET: |
| 118 column_set->AddColumn(views::GridLayout::TRAILING, | 123 column_set->AddColumn(views::GridLayout::TRAILING, |
| 119 views::GridLayout::CENTER, | 124 views::GridLayout::CENTER, |
| 120 1, | 125 1, |
| 121 views::GridLayout::USE_PREF, | 126 views::GridLayout::USE_PREF, |
| 122 0, | 127 0, |
| 123 0); | 128 0); |
| 129 case TRIPLE_BUTTON_COLUMN_SET: | |
| 130 column_set->AddColumn(views::GridLayout::LEADING, | |
| 131 views::GridLayout::CENTER, | |
| 132 1, | |
| 133 views::GridLayout::USE_PREF, | |
| 134 0, | |
| 135 0); | |
| 136 column_set->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 137 column_set->AddColumn(views::GridLayout::TRAILING, | |
| 138 views::GridLayout::CENTER, | |
| 139 0, | |
| 140 views::GridLayout::USE_PREF, | |
| 141 0, | |
| 142 0); | |
| 143 column_set->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 144 column_set->AddColumn(views::GridLayout::TRAILING, | |
| 145 views::GridLayout::CENTER, | |
| 146 0, | |
| 147 views::GridLayout::USE_PREF, | |
| 148 0, | |
| 149 0); | |
| 150 break; | |
| 124 } | 151 } |
| 125 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); | 152 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); |
| 126 } | 153 } |
| 127 | 154 |
| 128 // Given a layout and a model, add an appropriate title using a | 155 // Given a layout and a model, add an appropriate title using a |
| 129 // SINGLE_VIEW_COLUMN_SET, followed by a spacer row. | 156 // SINGLE_VIEW_COLUMN_SET, followed by a spacer row. |
| 130 void AddTitleRow(views::GridLayout* layout, ManagePasswordsBubbleModel* model) { | 157 void AddTitleRow(views::GridLayout* layout, ManagePasswordsBubbleModel* model) { |
| 131 views::Label* title_label = new views::Label(model->title()); | 158 views::Label* title_label = new views::Label(model->title()); |
| 132 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 159 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 133 title_label->SetMultiLine(true); | 160 title_label->SetMultiLine(true); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 case SavePasswordRefusalComboboxModel::INDEX_NOPE: | 407 case SavePasswordRefusalComboboxModel::INDEX_NOPE: |
| 381 parent_->model()->OnNopeClicked(); | 408 parent_->model()->OnNopeClicked(); |
| 382 parent_->Close(); | 409 parent_->Close(); |
| 383 break; | 410 break; |
| 384 case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE: | 411 case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE: |
| 385 parent_->NotifyNeverForThisSiteClicked(); | 412 parent_->NotifyNeverForThisSiteClicked(); |
| 386 break; | 413 break; |
| 387 } | 414 } |
| 388 } | 415 } |
| 389 | 416 |
| 390 // ManagePasswordsBubbleView::ConfirmNeverView --------------------------------- | 417 // ManagePasswordsBubbleView::SaveAccountView --------------------------------- |
| 418 | |
| 419 // A view offering the user the ability to save credentials. Contains 2 buttons | |
| 420 // and a "More" combobox. | |
| 421 class ManagePasswordsBubbleView::SaveAccountView | |
| 422 : public views::View, | |
| 423 public views::ButtonListener, | |
| 424 public views::ComboboxListener { | |
| 425 public: | |
| 426 explicit SaveAccountView(ManagePasswordsBubbleView* parent); | |
| 427 | |
| 428 private: | |
| 429 // views::ButtonListener: | |
| 430 void ButtonPressed(views::Button* sender, const ui::Event& event) override; | |
| 431 | |
| 432 // Handles the event when the user changes an index of a combobox. | |
| 433 void OnPerformAction(views::Combobox* source) override; | |
| 434 | |
| 435 ManagePasswordsBubbleView* parent_; | |
| 436 | |
| 437 views::BlueButton* save_button_; | |
| 438 views::LabelButton* no_button_; | |
| 439 | |
| 440 // The combobox doesn't take ownership of its model. If we created a | |
| 441 // combobox we need to ensure that we delete the model here, and because the | |
| 442 // combobox uses the model in it's destructor, we need to make sure we | |
| 443 // delete the model _after_ the combobox itself is deleted. | |
| 444 SaveAccountMoreComboboxModel combobox_model_; | |
| 445 scoped_ptr<views::Combobox> more_combobox_; | |
| 446 }; | |
| 447 | |
| 448 ManagePasswordsBubbleView::SaveAccountView::SaveAccountView( | |
| 449 ManagePasswordsBubbleView* parent) | |
| 450 : parent_(parent) { | |
| 451 views::GridLayout* layout = new views::GridLayout(this); | |
|
Mike West
2015/03/19 12:50:23
Nit: Can you DCHECK that the new UI amazingness is
vasilii
2015/03/19 14:48:57
Yeah. But it's one more line to fix later, right?
| |
| 452 layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0)); | |
| 453 SetLayoutManager(layout); | |
| 454 | |
| 455 save_button_ = new views::BlueButton( | |
| 456 this, | |
| 457 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_ACCOUNT_BUTTON)); | |
| 458 save_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( | |
| 459 ui::ResourceBundle::SmallFont)); | |
| 460 | |
| 461 no_button_ = new views::LabelButton(this, l10n_util::GetStringUTF16( | |
| 462 IDS_PASSWORD_MANAGER_SAVE_PASSWORD_SMART_LOCK_NO_THANKS_BUTTON)); | |
| 463 no_button_->SetStyle(views::Button::STYLE_BUTTON); | |
| 464 no_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( | |
| 465 ui::ResourceBundle::SmallFont)); | |
| 466 | |
| 467 more_combobox_.reset(new views::Combobox(&combobox_model_)); | |
| 468 more_combobox_->set_owned_by_client(); | |
| 469 more_combobox_->set_listener(this); | |
| 470 more_combobox_->SetStyle(views::Combobox::STYLE_ACTION); | |
| 471 | |
| 472 // Title row. | |
| 473 BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); | |
| 474 AddTitleRow(layout, parent_->model()); | |
| 475 | |
| 476 // Button row. | |
| 477 BuildColumnSet(layout, TRIPLE_BUTTON_COLUMN_SET); | |
| 478 layout->StartRow(0, TRIPLE_BUTTON_COLUMN_SET); | |
| 479 layout->AddView(more_combobox_.get()); | |
| 480 layout->AddView(save_button_); | |
| 481 layout->AddView(no_button_); | |
| 482 // Extra padding for visual awesomeness. | |
|
Mike West
2015/03/19 12:50:24
I smile every time I see this comment. :)
vasilii
2015/03/19 14:48:57
Should I write it somewhere here once more? ;-)
| |
| 483 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
| 484 | |
| 485 parent_->set_initially_focused_view(save_button_); | |
| 486 } | |
| 487 | |
| 488 void ManagePasswordsBubbleView::SaveAccountView::ButtonPressed( | |
| 489 views::Button* sender, | |
| 490 const ui::Event& event) { | |
| 491 if (sender == save_button_) { | |
| 492 parent_->model()->OnSaveClicked(); | |
| 493 } else if (sender == no_button_) { | |
| 494 parent_->model()->OnNopeClicked(); | |
| 495 } else { | |
| 496 NOTREACHED(); | |
| 497 } | |
|
Mike West
2015/03/19 12:50:24
Nit: Don't need {} here.
vasilii
2015/03/19 14:48:57
Done.
| |
| 498 parent_->Close(); | |
| 499 } | |
| 500 | |
| 501 void ManagePasswordsBubbleView::SaveAccountView::OnPerformAction( | |
| 502 views::Combobox* source) { | |
| 503 DCHECK_EQ(source, more_combobox_); | |
| 504 switch (more_combobox_->selected_index()) { | |
| 505 case SaveAccountMoreComboboxModel::INDEX_MORE: | |
| 506 break; | |
| 507 case SaveAccountMoreComboboxModel::INDEX_NEVER_FOR_THIS_SITE: | |
| 508 parent_->NotifyNeverForThisSiteClicked(); | |
| 509 break; | |
| 510 case SaveAccountMoreComboboxModel::INDEX_SETTINGS: | |
| 511 parent_->model()->OnManageLinkClicked(); | |
| 512 parent_->Close(); | |
| 513 break; | |
| 514 } | |
| 515 } | |
| 516 | |
| 517 // ManagePasswordsBubbleView::ConfirmNeverView -------------------------------- | |
| 391 | 518 |
| 392 // A view offering the user the ability to undo her decision to never save | 519 // A view offering the user the ability to undo her decision to never save |
| 393 // passwords for a particular site. | 520 // passwords for a particular site. |
| 394 class ManagePasswordsBubbleView::ConfirmNeverView | 521 class ManagePasswordsBubbleView::ConfirmNeverView |
| 395 : public views::View, | 522 : public views::View, |
| 396 public views::ButtonListener { | 523 public views::ButtonListener { |
| 397 public: | 524 public: |
| 398 explicit ConfirmNeverView(ManagePasswordsBubbleView* parent); | 525 explicit ConfirmNeverView(ManagePasswordsBubbleView* parent); |
| 399 ~ConfirmNeverView() override; | 526 ~ConfirmNeverView() override; |
| 400 | 527 |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 | 1102 |
| 976 void ManagePasswordsBubbleView::OnWidgetClosing(views::Widget* /*widget*/) { | 1103 void ManagePasswordsBubbleView::OnWidgetClosing(views::Widget* /*widget*/) { |
| 977 if (anchor_view_) | 1104 if (anchor_view_) |
| 978 anchor_view_->SetActive(false); | 1105 anchor_view_->SetActive(false); |
| 979 } | 1106 } |
| 980 | 1107 |
| 981 void ManagePasswordsBubbleView::Refresh() { | 1108 void ManagePasswordsBubbleView::Refresh() { |
| 982 RemoveAllChildViews(true); | 1109 RemoveAllChildViews(true); |
| 983 initially_focused_view_ = NULL; | 1110 initially_focused_view_ = NULL; |
| 984 if (model()->state() == password_manager::ui::PENDING_PASSWORD_STATE) { | 1111 if (model()->state() == password_manager::ui::PENDING_PASSWORD_STATE) { |
| 985 if (model()->never_save_passwords()) | 1112 if (model()->never_save_passwords()) { |
| 986 AddChildView(new ConfirmNeverView(this)); | 1113 AddChildView(new ConfirmNeverView(this)); |
| 987 else | 1114 } else { |
| 988 AddChildView(new PendingView(this)); | 1115 if (model()->IsNewUIActive()) |
| 1116 AddChildView(new SaveAccountView(this)); | |
| 1117 else | |
| 1118 AddChildView(new PendingView(this)); | |
| 1119 } | |
| 989 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { | 1120 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { |
| 990 AddChildView(new BlacklistedView(this)); | 1121 AddChildView(new BlacklistedView(this)); |
| 991 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { | 1122 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { |
| 992 AddChildView(new SaveConfirmationView(this)); | 1123 AddChildView(new SaveConfirmationView(this)); |
| 993 } else if (model()->state() == | 1124 } else if (model()->state() == |
| 994 password_manager::ui::CREDENTIAL_REQUEST_STATE) { | 1125 password_manager::ui::CREDENTIAL_REQUEST_STATE) { |
| 995 AddChildView(new AccountChooserView(this)); | 1126 AddChildView(new AccountChooserView(this)); |
| 996 } else if (model()->state() == password_manager::ui::AUTO_SIGNIN_STATE) { | 1127 } else if (model()->state() == password_manager::ui::AUTO_SIGNIN_STATE) { |
| 997 AddChildView(new AutoSigninView(this)); | 1128 AddChildView(new AutoSigninView(this)); |
| 998 } else { | 1129 } else { |
| 999 if (model()->IsNewUIActive()) | 1130 if (model()->IsNewUIActive()) |
| 1000 AddChildView(new ManageAccountsView(this)); | 1131 AddChildView(new ManageAccountsView(this)); |
| 1001 else | 1132 else |
| 1002 AddChildView(new ManageView(this)); | 1133 AddChildView(new ManageView(this)); |
| 1003 } | 1134 } |
| 1004 GetLayoutManager()->Layout(this); | 1135 GetLayoutManager()->Layout(this); |
| 1005 } | 1136 } |
| 1006 | 1137 |
| 1007 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() { | 1138 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() { |
| 1008 model()->OnNeverForThisSiteClicked(); | 1139 model()->OnNeverForThisSiteClicked(); |
| 1009 Close(); | 1140 Close(); |
| 1010 } | 1141 } |
| 1011 | 1142 |
| 1012 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() { | 1143 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() { |
| 1013 model()->OnUndoNeverForThisSite(); | 1144 model()->OnUndoNeverForThisSite(); |
| 1014 Refresh(); | 1145 Refresh(); |
| 1146 SizeToContents(); | |
| 1015 } | 1147 } |
| 1016 | 1148 |
| 1017 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { | 1149 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { |
| 1018 if (model()->local_credentials().empty()) { | 1150 if (model()->local_credentials().empty()) { |
| 1019 // Skip confirmation if there are no existing passwords for this site. | 1151 // Skip confirmation if there are no existing passwords for this site. |
| 1020 NotifyConfirmedNeverForThisSite(); | 1152 NotifyConfirmedNeverForThisSite(); |
| 1021 } else { | 1153 } else { |
| 1022 model()->OnConfirmationForNeverForThisSite(); | 1154 model()->OnConfirmationForNeverForThisSite(); |
| 1023 Refresh(); | 1155 Refresh(); |
| 1156 SizeToContents(); | |
| 1024 } | 1157 } |
| 1025 } | 1158 } |
| OLD | NEW |