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

Side by Side Diff: chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc

Issue 1001553005: New "Save password" bubble for the Credential Manager API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix android Created 5 years, 9 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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698