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

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

Issue 2960843002: Edit button makes username editable in the password manager bubble. (Closed)
Patch Set: Added new helper function. Created 3 years, 5 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
« no previous file with comments | « chrome/browser/ui/views/passwords/manage_password_items_view.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/macros.h" 7 #include "base/macros.h"
8 #include "base/metrics/user_metrics.h" 8 #include "base/metrics/user_metrics.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "base/timer/timer.h" 10 #include "base/timer/timer.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // Helpers -------------------------------------------------------------------- 57 // Helpers --------------------------------------------------------------------
58 58
59 namespace { 59 namespace {
60 60
61 enum ColumnSetType { 61 enum ColumnSetType {
62 // | | (FILL, FILL) | | 62 // | | (FILL, FILL) | |
63 // Used for the bubble's header, the credentials list, and for simple 63 // Used for the bubble's header, the credentials list, and for simple
64 // messages like "No passwords". 64 // messages like "No passwords".
65 SINGLE_VIEW_COLUMN_SET, 65 SINGLE_VIEW_COLUMN_SET,
66 66
67 // | | (FILL, FILL) | | (FILL, FILL) | |
68 // Used for the credentials line of the bubble, for the pending view.
69 DOUBLE_VIEW_COLUMN_SET,
70
67 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | 71 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | |
68 // Used for buttons at the bottom of the bubble which should nest at the 72 // Used for buttons at the bottom of the bubble which should nest at the
69 // bottom-right corner. 73 // bottom-right corner.
70 DOUBLE_BUTTON_COLUMN_SET, 74 DOUBLE_BUTTON_COLUMN_SET,
71 75
72 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | 76 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | |
73 // Used for buttons at the bottom of the bubble which should occupy 77 // Used for buttons at the bottom of the bubble which should occupy
74 // the corners. 78 // the corners.
75 LINK_BUTTON_COLUMN_SET, 79 LINK_BUTTON_COLUMN_SET,
76 80
77 // | | (TRAILING, CENTER) | | 81 // | | (TRAILING, CENTER) | |
78 // Used when there is only one button which should next at the bottom-right 82 // Used when there is only one button which should next at the bottom-right
79 // corner. 83 // corner.
80 SINGLE_BUTTON_COLUMN_SET, 84 SINGLE_BUTTON_COLUMN_SET,
81 85
82 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | 86 // | | (LEADING, CENTER) | | (TRAILING, CENTER) | | (TRAILING, CENTER) | |
83 // Used when there are three buttons. 87 // Used when there are three buttons.
84 TRIPLE_BUTTON_COLUMN_SET, 88 TRIPLE_BUTTON_COLUMN_SET,
85 }; 89 };
86 90
87 enum TextRowType { ROW_SINGLE, ROW_MULTILINE }; 91 enum TextRowType { ROW_SINGLE, ROW_MULTILINE };
88 92
89 // Construct an appropriate ColumnSet for the given |type|, and add it 93 // Construct an appropriate ColumnSet for the given |type|, and add it
90 // to |layout|. 94 // to |layout|.
91 void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) { 95 void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) {
92 views::ColumnSet* column_set = layout->AddColumnSet(type); 96 views::ColumnSet* column_set = layout->AddColumnSet(type);
93 int full_width = ManagePasswordsBubbleView::kDesiredBubbleWidth; 97 int full_width = ManagePasswordsBubbleView::kDesiredBubbleWidth;
94 const int button_divider = ChromeLayoutProvider::Get()->GetDistanceMetric( 98 const int button_divider = ChromeLayoutProvider::Get()->GetDistanceMetric(
95 views::DISTANCE_RELATED_BUTTON_HORIZONTAL); 99 views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
100 const int column_divider = ChromeLayoutProvider::Get()->GetDistanceMetric(
101 views::DISTANCE_RELATED_CONTROL_HORIZONTAL);
96 switch (type) { 102 switch (type) {
97 case SINGLE_VIEW_COLUMN_SET: 103 case SINGLE_VIEW_COLUMN_SET:
98 column_set->AddColumn(views::GridLayout::FILL, 104 column_set->AddColumn(views::GridLayout::FILL,
99 views::GridLayout::FILL, 105 views::GridLayout::FILL,
100 0, 106 0,
101 views::GridLayout::FIXED, 107 views::GridLayout::FIXED,
102 full_width, 108 full_width,
103 0); 109 0);
104 break; 110 break;
111 case DOUBLE_VIEW_COLUMN_SET:
112 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
113 views::GridLayout::USE_PREF, 0, 0);
114 column_set->AddPaddingColumn(0, column_divider);
115 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
116 views::GridLayout::USE_PREF, 0, 0);
117 break;
105 case DOUBLE_BUTTON_COLUMN_SET: 118 case DOUBLE_BUTTON_COLUMN_SET:
106 column_set->AddColumn(views::GridLayout::TRAILING, 119 column_set->AddColumn(views::GridLayout::TRAILING,
107 views::GridLayout::CENTER, 120 views::GridLayout::CENTER,
108 1, 121 1,
109 views::GridLayout::USE_PREF, 122 views::GridLayout::USE_PREF,
110 0, 123 0,
111 0); 124 0);
112 column_set->AddPaddingColumn(0, button_divider); 125 column_set->AddPaddingColumn(0, button_divider);
113 column_set->AddColumn(views::GridLayout::TRAILING, 126 column_set->AddColumn(views::GridLayout::TRAILING,
114 views::GridLayout::CENTER, 127 views::GridLayout::CENTER,
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 void ManagePasswordsBubbleView::AutoSigninView::OnTimer() { 275 void ManagePasswordsBubbleView::AutoSigninView::OnTimer() {
263 parent_->model()->OnAutoSignInToastTimeout(); 276 parent_->model()->OnAutoSignInToastTimeout();
264 parent_->CloseBubble(); 277 parent_->CloseBubble();
265 } 278 }
266 279
267 // ManagePasswordsBubbleView::PendingView ------------------------------------- 280 // ManagePasswordsBubbleView::PendingView -------------------------------------
268 281
269 // A view offering the user the ability to save credentials. Contains a 282 // A view offering the user the ability to save credentials. Contains a
270 // single ManagePasswordItemsView, along with a "Save Passwords" button, 283 // single ManagePasswordItemsView, along with a "Save Passwords" button,
271 // a "Never" button and an "Edit" button to edit username field. 284 // a "Never" button and an "Edit" button to edit username field.
272 class ManagePasswordsBubbleView::PendingView : public views::View, 285 class ManagePasswordsBubbleView::PendingView
273 public views::ButtonListener { 286 : public views::View,
287 public views::ButtonListener,
288 public views::FocusChangeListener {
274 public: 289 public:
275 explicit PendingView(ManagePasswordsBubbleView* parent); 290 explicit PendingView(ManagePasswordsBubbleView* parent);
276 ~PendingView() override; 291 ~PendingView() override;
277 292
278 private: 293 private:
294 void CreateAndSetLayout();
279 // views::ButtonListener: 295 // views::ButtonListener:
280 void ButtonPressed(views::Button* sender, const ui::Event& event) override; 296 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
297 // views::FocusChangeListener:
298 void OnWillChangeFocus(View* focused_before, View* focused_now) override;
299 void OnDidChangeFocus(View* focused_before, View* focused_now) override;
300 // views::View:
301 bool OnKeyPressed(const ui::KeyEvent& event) override;
302
303 void UpdateUsernameField();
vasilii 2017/07/06 13:46:43 Call it "ToggleEditingState" or something
irmakk 2017/07/06 14:19:12 Done.
281 304
282 ManagePasswordsBubbleView* parent_; 305 ManagePasswordsBubbleView* parent_;
283 306
284 views::Button* edit_button_; 307 views::Button* edit_button_;
285 views::Button* save_button_; 308 views::Button* save_button_;
286 views::Button* never_button_; 309 views::Button* never_button_;
310 views::View* username_field_;
311 views::View* password_field_;
312
313 bool editing_;
287 314
288 DISALLOW_COPY_AND_ASSIGN(PendingView); 315 DISALLOW_COPY_AND_ASSIGN(PendingView);
289 }; 316 };
290 317
291 ManagePasswordsBubbleView::PendingView::PendingView( 318 ManagePasswordsBubbleView::PendingView::PendingView(
292 ManagePasswordsBubbleView* parent) 319 ManagePasswordsBubbleView* parent)
293 : parent_(parent), edit_button_(nullptr) { 320 : parent_(parent),
321 edit_button_(nullptr),
322 save_button_(nullptr),
323 never_button_(nullptr),
324 username_field_(nullptr),
325 password_field_(nullptr),
326 editing_(false) {
327 CreateAndSetLayout();
328 parent_->set_initially_focused_view(save_button_);
329 }
330
331 void ManagePasswordsBubbleView::PendingView::CreateAndSetLayout() {
294 views::GridLayout* layout = new views::GridLayout(this); 332 views::GridLayout* layout = new views::GridLayout(this);
295 layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0)); 333 layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
296 SetLayoutManager(layout); 334 SetLayoutManager(layout);
297 335
298 // Create the pending credential item, save button and refusal combobox. 336 // Create the edit, save and never buttons.
299 ManagePasswordItemsView* item = nullptr; 337 if (!edit_button_ &&
300 if (!parent->model()->pending_password().username_value.empty()) { 338 base::FeatureList::IsEnabled(
301 item = new ManagePasswordItemsView(parent_->model(),
302 &parent->model()->pending_password());
303 }
304 if (base::FeatureList::IsEnabled(
305 password_manager::features::kEnableUsernameCorrection)) { 339 password_manager::features::kEnableUsernameCorrection)) {
306 edit_button_ = views::MdTextButton::CreateSecondaryUiButton( 340 edit_button_ = views::MdTextButton::CreateSecondaryUiButton(
307 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EDIT_BUTTON)); 341 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EDIT_BUTTON));
308 } 342 }
309 save_button_ = views::MdTextButton::CreateSecondaryUiBlueButton( 343 if (!save_button_) {
310 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); 344 save_button_ = views::MdTextButton::CreateSecondaryUiBlueButton(
311 never_button_ = views::MdTextButton::CreateSecondaryUiButton( 345 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON));
312 this, 346 }
313 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BUBBLE_BLACKLIST_BUTTON)); 347 if (!never_button_) {
348 never_button_ = views::MdTextButton::CreateSecondaryUiButton(
349 this, l10n_util::GetStringUTF16(
350 IDS_PASSWORD_MANAGER_BUBBLE_BLACKLIST_BUTTON));
351 }
314 352
315 BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); 353 // Credentials row.
316 354 BuildColumnSet(layout, DOUBLE_VIEW_COLUMN_SET);
317 // Credential row. 355 if (!parent_->model()->pending_password().username_value.empty() ||
318 if (item) { 356 edit_button_) {
319 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); 357 layout->StartRow(0, DOUBLE_VIEW_COLUMN_SET);
320 layout->AddView(item); 358 const autofill::PasswordForm* password_form =
359 &parent_->model()->pending_password();
360 DCHECK_EQ(username_field_, nullptr);
vasilii 2017/07/06 13:46:43 DCHECK_EQ(nullptr, username_field_) or DCHECK(!use
irmakk 2017/07/06 14:19:12 Done.
361 if (editing_) {
362 username_field_ = GenerateUsernameEditable(*password_form).release();
363 } else {
364 username_field_ = GenerateUsernameLabel(*password_form).release();
365 }
366 if (!password_field_) {
367 password_field_ = GeneratePasswordLabel(*password_form).release();
368 }
369 layout->AddView(username_field_);
370 layout->AddView(password_field_);
321 layout->AddPaddingRow(0, 371 layout->AddPaddingRow(0,
322 ChromeLayoutProvider::Get() 372 ChromeLayoutProvider::Get()
323 ->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS) 373 ->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS)
324 .bottom()); 374 .bottom());
325 } 375 }
326
327 // Button row. 376 // Button row.
328 ColumnSetType column_set_type = 377 ColumnSetType column_set_type =
329 edit_button_ ? TRIPLE_BUTTON_COLUMN_SET : DOUBLE_BUTTON_COLUMN_SET; 378 edit_button_ ? TRIPLE_BUTTON_COLUMN_SET : DOUBLE_BUTTON_COLUMN_SET;
330 BuildColumnSet(layout, column_set_type); 379 BuildColumnSet(layout, column_set_type);
331 layout->StartRow(0, column_set_type); 380 layout->StartRow(0, column_set_type);
332 if (column_set_type == TRIPLE_BUTTON_COLUMN_SET) { 381 if (column_set_type == TRIPLE_BUTTON_COLUMN_SET) {
333 layout->AddView(edit_button_); 382 layout->AddView(edit_button_);
334 } 383 }
335 layout->AddView(save_button_); 384 layout->AddView(save_button_);
336 layout->AddView(never_button_); 385 layout->AddView(never_button_);
337
338 parent_->set_initially_focused_view(save_button_);
339 } 386 }
340 387
341 ManagePasswordsBubbleView::PendingView::~PendingView() { 388 ManagePasswordsBubbleView::PendingView::~PendingView() {
342 } 389 }
343 390
344 void ManagePasswordsBubbleView::PendingView::ButtonPressed( 391 void ManagePasswordsBubbleView::PendingView::ButtonPressed(
345 views::Button* sender, 392 views::Button* sender,
346 const ui::Event& event) { 393 const ui::Event& event) {
347 // TODO(https://crbug.com/734965): Implement edit button logic. 394 // TODO(https://crbug.com/734965): Implement edit button logic.
348 if (sender == edit_button_) { 395 if (sender == edit_button_) {
396 UpdateUsernameField();
349 return; 397 return;
350 } else if (sender == save_button_) { 398 }
399 if (sender == save_button_) {
351 parent_->model()->OnSaveClicked(); 400 parent_->model()->OnSaveClicked();
352 if (parent_->model()->ReplaceToShowPromotionIfNeeded()) { 401 if (parent_->model()->ReplaceToShowPromotionIfNeeded()) {
353 parent_->Refresh(); 402 parent_->Refresh();
354 return; 403 return;
355 } 404 }
356 } else if (sender == never_button_) { 405 } else if (sender == never_button_) {
357 parent_->model()->OnNeverForThisSiteClicked(); 406 parent_->model()->OnNeverForThisSiteClicked();
358 } else { 407 } else {
359 NOTREACHED(); 408 NOTREACHED();
360 } 409 }
361 410
362 parent_->CloseBubble(); 411 parent_->CloseBubble();
363 } 412 }
364 413
414 void ManagePasswordsBubbleView::PendingView::OnWillChangeFocus(
415 View* focused_before,
416 View* focused_now) {
417 // Nothing to do here.
418 }
419
420 void ManagePasswordsBubbleView::PendingView::OnDidChangeFocus(
421 View* focused_before,
422 View* focused_now) {
423 if (editing_ && focused_before == username_field_) {
424 UpdateUsernameField();
425 }
426 }
427
428 bool ManagePasswordsBubbleView::PendingView::OnKeyPressed(
429 const ui::KeyEvent& event) {
430 if (editing_ && (event.key_code() == ui::KeyboardCode::VKEY_RETURN ||
431 event.key_code() == ui::KeyboardCode::VKEY_ESCAPE)) {
432 UpdateUsernameField();
433 return true;
434 }
435 return false;
436 }
437
438 void ManagePasswordsBubbleView::PendingView::UpdateUsernameField() {
439 editing_ = !editing_;
440 edit_button_->SetEnabled(!editing_);
441 RemoveChildView(username_field_);
442 username_field_ = nullptr;
443 CreateAndSetLayout();
444 Layout();
445 if (editing_) {
446 GetFocusManager()->SetFocusedView(username_field_);
447 GetFocusManager()->AddFocusChangeListener(this);
448 } else {
449 GetFocusManager()->SetFocusedView(save_button_);
450 GetFocusManager()->RemoveFocusChangeListener(this);
vasilii 2017/07/06 13:46:43 I'd swap these lines to avoid unnecessary notifica
irmakk 2017/07/06 14:19:12 Done.
451 }
452 parent_->SizeToContents();
453 }
454
365 // ManagePasswordsBubbleView::ManageView -------------------------------------- 455 // ManagePasswordsBubbleView::ManageView --------------------------------------
366 456
367 // A view offering the user a list of their currently saved credentials 457 // A view offering the user a list of their currently saved credentials
368 // for the current page, along with a "Manage passwords" link and a 458 // for the current page, along with a "Manage passwords" link and a
369 // "Done" button. 459 // "Done" button.
370 class ManagePasswordsBubbleView::ManageView : public views::View, 460 class ManagePasswordsBubbleView::ManageView : public views::View,
371 public views::ButtonListener, 461 public views::ButtonListener,
372 public views::LinkListener { 462 public views::LinkListener {
373 public: 463 public:
374 explicit ManageView(ManagePasswordsBubbleView* parent); 464 explicit ManageView(ManagePasswordsBubbleView* parent);
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 } else if (model_.state() == 969 } else if (model_.state() ==
880 password_manager::ui::CHROME_DESKTOP_IOS_PROMO_STATE) { 970 password_manager::ui::CHROME_DESKTOP_IOS_PROMO_STATE) {
881 AddChildView(new DesktopIOSPromotionBubbleView( 971 AddChildView(new DesktopIOSPromotionBubbleView(
882 model_.GetProfile(), 972 model_.GetProfile(),
883 desktop_ios_promotion::PromotionEntryPoint::SAVE_PASSWORD_BUBBLE)); 973 desktop_ios_promotion::PromotionEntryPoint::SAVE_PASSWORD_BUBBLE));
884 #endif 974 #endif
885 } else { 975 } else {
886 AddChildView(new ManageView(this)); 976 AddChildView(new ManageView(this));
887 } 977 }
888 } 978 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/passwords/manage_password_items_view.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698