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/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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |