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

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: Moved standalone functions out of anonymous namespace & did some more fixing. 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;
281 302
282 ManagePasswordsBubbleView* parent_; 303 ManagePasswordsBubbleView* parent_;
283 304
284 views::Button* edit_button_; 305 views::Button* edit_button_;
285 views::Button* save_button_; 306 views::Button* save_button_;
286 views::Button* never_button_; 307 views::Button* never_button_;
308 views::View* username_field_;
309 views::View* password_field_;
310
311 bool editing_;
287 312
288 DISALLOW_COPY_AND_ASSIGN(PendingView); 313 DISALLOW_COPY_AND_ASSIGN(PendingView);
289 }; 314 };
290 315
291 ManagePasswordsBubbleView::PendingView::PendingView( 316 ManagePasswordsBubbleView::PendingView::PendingView(
292 ManagePasswordsBubbleView* parent) 317 ManagePasswordsBubbleView* parent)
293 : parent_(parent), edit_button_(nullptr) { 318 : parent_(parent),
319 edit_button_(nullptr),
320 save_button_(nullptr),
321 never_button_(nullptr),
322 username_field_(nullptr),
323 password_field_(nullptr),
324 editing_(false) {
325 CreateAndSetLayout();
326 parent_->set_initially_focused_view(save_button_);
327 }
328
329 void ManagePasswordsBubbleView::PendingView::CreateAndSetLayout() {
294 views::GridLayout* layout = new views::GridLayout(this); 330 views::GridLayout* layout = new views::GridLayout(this);
295 layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0)); 331 layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
296 SetLayoutManager(layout); 332 SetLayoutManager(layout);
297 333
298 // Create the pending credential item, save button and refusal combobox. 334 // Create the edit, save and never buttons.
299 ManagePasswordItemsView* item = nullptr; 335 if (!edit_button_ &&
300 if (!parent->model()->pending_password().username_value.empty()) { 336 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)) { 337 password_manager::features::kEnableUsernameCorrection)) {
306 edit_button_ = views::MdTextButton::CreateSecondaryUiButton( 338 edit_button_ = views::MdTextButton::CreateSecondaryUiButton(
307 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EDIT_BUTTON)); 339 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EDIT_BUTTON));
308 } 340 }
309 save_button_ = views::MdTextButton::CreateSecondaryUiBlueButton( 341 if (!save_button_) {
310 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); 342 save_button_ = views::MdTextButton::CreateSecondaryUiBlueButton(
311 never_button_ = views::MdTextButton::CreateSecondaryUiButton( 343 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON));
312 this, 344 }
313 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BUBBLE_BLACKLIST_BUTTON)); 345 if (!never_button_) {
346 never_button_ = views::MdTextButton::CreateSecondaryUiButton(
347 this, l10n_util::GetStringUTF16(
348 IDS_PASSWORD_MANAGER_BUBBLE_BLACKLIST_BUTTON));
349 }
314 350
315 BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); 351 // Credentials row.
316 352 BuildColumnSet(layout, DOUBLE_VIEW_COLUMN_SET);
317 // Credential row. 353 if (!parent_->model()->pending_password().username_value.empty() ||
318 if (item) { 354 edit_button_) {
319 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); 355 layout->StartRow(0, DOUBLE_VIEW_COLUMN_SET);
320 layout->AddView(item); 356 const autofill::PasswordForm* password_form =
357 &parent_->model()->pending_password();
358 if (editing_) {
359 DCHECK_EQ(username_field_, nullptr);
vasilii 2017/07/06 11:59:32 Seems like it's true for both editing_ and !editin
irmakk 2017/07/06 12:53:14 Done.
360 username_field_ = GenerateUsernameEditable(*password_form).release();
361 } else {
362 username_field_ = GenerateUsernameLabel(*password_form).release();
363 }
364 if (!password_field_) {
365 password_field_ = GeneratePasswordLabel(*password_form).release();
366 }
367 layout->AddView(username_field_);
368 layout->AddView(password_field_);
321 layout->AddPaddingRow(0, 369 layout->AddPaddingRow(0,
322 ChromeLayoutProvider::Get() 370 ChromeLayoutProvider::Get()
323 ->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS) 371 ->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS)
324 .bottom()); 372 .bottom());
325 } 373 }
326
327 // Button row. 374 // Button row.
328 ColumnSetType column_set_type = 375 ColumnSetType column_set_type =
329 edit_button_ ? TRIPLE_BUTTON_COLUMN_SET : DOUBLE_BUTTON_COLUMN_SET; 376 edit_button_ ? TRIPLE_BUTTON_COLUMN_SET : DOUBLE_BUTTON_COLUMN_SET;
330 BuildColumnSet(layout, column_set_type); 377 BuildColumnSet(layout, column_set_type);
331 layout->StartRow(0, column_set_type); 378 layout->StartRow(0, column_set_type);
332 if (column_set_type == TRIPLE_BUTTON_COLUMN_SET) { 379 if (column_set_type == TRIPLE_BUTTON_COLUMN_SET) {
333 layout->AddView(edit_button_); 380 layout->AddView(edit_button_);
334 } 381 }
335 layout->AddView(save_button_); 382 layout->AddView(save_button_);
336 layout->AddView(never_button_); 383 layout->AddView(never_button_);
337 384
338 parent_->set_initially_focused_view(save_button_); 385 layout->Layout(this);
vasilii 2017/07/06 11:59:32 Move it to where you switch the state. There is no
irmakk 2017/07/06 12:53:14 Done.
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 edit_button_->SetEnabled(false);
397 editing_ = true;
398 this->RemoveChildView(username_field_);
vasilii 2017/07/06 11:59:32 Is there a good reason to use "this->"?
irmakk 2017/07/06 12:53:13 Done.
399 username_field_ = nullptr;
400 CreateAndSetLayout();
401 this->GetFocusManager()->SetFocusedView(username_field_);
402 parent_->GetFocusManager()->AddFocusChangeListener(this);
vasilii 2017/07/06 11:59:32 It's confusing because this->GetFocusManager() and
irmakk 2017/07/06 12:53:14 Oh, i didnt know it was inherited. Removing, thank
403 parent_->SizeToContents();
349 return; 404 return;
350 } else if (sender == save_button_) { 405 }
406 if (sender == save_button_) {
351 parent_->model()->OnSaveClicked(); 407 parent_->model()->OnSaveClicked();
352 if (parent_->model()->ReplaceToShowPromotionIfNeeded()) { 408 if (parent_->model()->ReplaceToShowPromotionIfNeeded()) {
353 parent_->Refresh(); 409 parent_->Refresh();
354 return; 410 return;
355 } 411 }
356 } else if (sender == never_button_) { 412 } else if (sender == never_button_) {
357 parent_->model()->OnNeverForThisSiteClicked(); 413 parent_->model()->OnNeverForThisSiteClicked();
358 } else { 414 } else {
359 NOTREACHED(); 415 NOTREACHED();
360 } 416 }
361 417
362 parent_->CloseBubble(); 418 parent_->CloseBubble();
363 } 419 }
364 420
421 void ManagePasswordsBubbleView::PendingView::OnWillChangeFocus(
422 View* focused_before,
423 View* focused_now) {
424 // Nothing to do here.
425 }
426
427 void ManagePasswordsBubbleView::PendingView::OnDidChangeFocus(
428 View* focused_before,
429 View* focused_now) {
430 if (editing_ && focused_before == username_field_) {
431 editing_ = false;
432 this->RemoveChildView(username_field_);
433 CreateAndSetLayout();
434 edit_button_->SetEnabled(true);
435 this->GetFocusManager()->SetFocusedView(save_button_);
436 parent_->SizeToContents();
437 this->GetFocusManager()->RemoveFocusChangeListener(this);
438 }
439 }
440
441 bool ManagePasswordsBubbleView::PendingView::OnKeyPressed(
442 const ui::KeyEvent& event) {
443 if (editing_ && (event.key_code() == ui::KeyboardCode::VKEY_RETURN ||
444 event.key_code() == ui::KeyboardCode::VKEY_ESCAPE)) {
445 editing_ = false;
446 this->RemoveChildView(username_field_);
447 username_field_ = nullptr;
448 CreateAndSetLayout();
449 edit_button_->SetEnabled(true);
450 this->GetFocusManager()->SetFocusedView(save_button_);
451 parent_->SizeToContents();
452 this->GetFocusManager()->RemoveFocusChangeListener(this);
vasilii 2017/07/06 11:59:32 This is a copy/paste from OnDidChangeFocus(). Ther
irmakk 2017/07/06 12:53:14 Done.
453 return true;
454 }
455 return false;
456 }
457
365 // ManagePasswordsBubbleView::ManageView -------------------------------------- 458 // ManagePasswordsBubbleView::ManageView --------------------------------------
366 459
367 // A view offering the user a list of their currently saved credentials 460 // 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 461 // for the current page, along with a "Manage passwords" link and a
369 // "Done" button. 462 // "Done" button.
370 class ManagePasswordsBubbleView::ManageView : public views::View, 463 class ManagePasswordsBubbleView::ManageView : public views::View,
371 public views::ButtonListener, 464 public views::ButtonListener,
372 public views::LinkListener { 465 public views::LinkListener {
373 public: 466 public:
374 explicit ManageView(ManagePasswordsBubbleView* parent); 467 explicit ManageView(ManagePasswordsBubbleView* parent);
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 } else if (model_.state() == 972 } else if (model_.state() ==
880 password_manager::ui::CHROME_DESKTOP_IOS_PROMO_STATE) { 973 password_manager::ui::CHROME_DESKTOP_IOS_PROMO_STATE) {
881 AddChildView(new DesktopIOSPromotionBubbleView( 974 AddChildView(new DesktopIOSPromotionBubbleView(
882 model_.GetProfile(), 975 model_.GetProfile(),
883 desktop_ios_promotion::PromotionEntryPoint::SAVE_PASSWORD_BUBBLE)); 976 desktop_ios_promotion::PromotionEntryPoint::SAVE_PASSWORD_BUBBLE));
884 #endif 977 #endif
885 } else { 978 } else {
886 AddChildView(new ManageView(this)); 979 AddChildView(new ManageView(this));
887 } 980 }
888 } 981 }
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