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 "chrome/browser/chrome_notification_types.h" | 7 #include "chrome/browser/chrome_notification_types.h" |
8 #include "chrome/browser/ui/browser.h" | 8 #include "chrome/browser/ui/browser.h" |
9 #include "chrome/browser/ui/browser_finder.h" | 9 #include "chrome/browser/ui/browser_finder.h" |
10 #include "chrome/browser/ui/browser_window.h" | 10 #include "chrome/browser/ui/browser_window.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "ui/views/controls/styled_label.h" | 27 #include "ui/views/controls/styled_label.h" |
28 #include "ui/views/layout/fill_layout.h" | 28 #include "ui/views/layout/fill_layout.h" |
29 #include "ui/views/layout/grid_layout.h" | 29 #include "ui/views/layout/grid_layout.h" |
30 #include "ui/views/layout/layout_constants.h" | 30 #include "ui/views/layout/layout_constants.h" |
31 | 31 |
32 | 32 |
33 // Helpers -------------------------------------------------------------------- | 33 // Helpers -------------------------------------------------------------------- |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
| 37 // The number of seconds the inactive bubble should stay alive. |
| 38 const int kBubbleCloseDelay = 15; |
| 39 |
37 const int kDesiredBubbleWidth = 370; | 40 const int kDesiredBubbleWidth = 370; |
38 | 41 |
39 enum ColumnSetType { | 42 enum ColumnSetType { |
40 // | | (FILL, FILL) | | | 43 // | | (FILL, FILL) | | |
41 // Used for the bubble's header, the credentials list, and for simple | 44 // Used for the bubble's header, the credentials list, and for simple |
42 // messages like "No passwords". | 45 // messages like "No passwords". |
43 SINGLE_VIEW_COLUMN_SET = 0, | 46 SINGLE_VIEW_COLUMN_SET = 0, |
44 | 47 |
45 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | | 48 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | |
46 // Used for buttons at the bottom of the bubble which should nest at the | 49 // Used for buttons at the bottom of the bubble which should nest at the |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 547 |
545 // Adjust for fullscreen after creation as it relies on the content size. | 548 // Adjust for fullscreen after creation as it relies on the content size. |
546 if (is_fullscreen) { | 549 if (is_fullscreen) { |
547 manage_passwords_bubble_->AdjustForFullscreen( | 550 manage_passwords_bubble_->AdjustForFullscreen( |
548 browser_view->GetBoundsInScreen()); | 551 browser_view->GetBoundsInScreen()); |
549 } | 552 } |
550 if (reason == AUTOMATIC) | 553 if (reason == AUTOMATIC) |
551 manage_passwords_bubble_->GetWidget()->ShowInactive(); | 554 manage_passwords_bubble_->GetWidget()->ShowInactive(); |
552 else | 555 else |
553 manage_passwords_bubble_->GetWidget()->Show(); | 556 manage_passwords_bubble_->GetWidget()->Show(); |
| 557 manage_passwords_bubble_->StartTimerIfNecessary(); |
554 } | 558 } |
555 | 559 |
556 // static | 560 // static |
557 void ManagePasswordsBubbleView::CloseBubble() { | 561 void ManagePasswordsBubbleView::CloseBubble() { |
558 if (manage_passwords_bubble_) | 562 if (manage_passwords_bubble_) |
559 manage_passwords_bubble_->Close(); | 563 manage_passwords_bubble_->Close(); |
560 } | 564 } |
561 | 565 |
562 // static | 566 // static |
563 bool ManagePasswordsBubbleView::IsShowing() { | 567 bool ManagePasswordsBubbleView::IsShowing() { |
564 // The bubble may be in the process of closing. | 568 // The bubble may be in the process of closing. |
565 return (manage_passwords_bubble_ != NULL) && | 569 return (manage_passwords_bubble_ != NULL) && |
566 manage_passwords_bubble_->GetWidget()->IsVisible(); | 570 manage_passwords_bubble_->GetWidget()->IsVisible(); |
567 } | 571 } |
568 | 572 |
569 ManagePasswordsBubbleView::ManagePasswordsBubbleView( | 573 ManagePasswordsBubbleView::ManagePasswordsBubbleView( |
570 content::WebContents* web_contents, | 574 content::WebContents* web_contents, |
571 ManagePasswordsIconView* anchor_view, | 575 ManagePasswordsIconView* anchor_view, |
572 DisplayReason reason) | 576 DisplayReason reason) |
573 : ManagePasswordsBubble(web_contents, reason), | 577 : ManagePasswordsBubble(web_contents, reason), |
574 BubbleDelegateView(anchor_view, | 578 BubbleDelegateView(anchor_view, |
575 anchor_view ? views::BubbleBorder::TOP_RIGHT | 579 anchor_view ? views::BubbleBorder::TOP_RIGHT |
576 : views::BubbleBorder::NONE), | 580 : views::BubbleBorder::NONE), |
577 anchor_view_(anchor_view), | 581 anchor_view_(anchor_view), |
578 never_save_passwords_(false), | 582 never_save_passwords_(false), |
579 initially_focused_view_(NULL) { | 583 initially_focused_view_(NULL) { |
580 // Compensate for built-in vertical padding in the anchor view's image. | 584 // Compensate for built-in vertical padding in the anchor view's image. |
581 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); | 585 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); |
| 586 set_notify_enter_exit_on_child(true); |
582 if (anchor_view) | 587 if (anchor_view) |
583 anchor_view->SetActive(true); | 588 anchor_view->SetActive(true); |
584 } | 589 } |
585 | 590 |
586 ManagePasswordsBubbleView::~ManagePasswordsBubbleView() { | 591 ManagePasswordsBubbleView::~ManagePasswordsBubbleView() { |
587 if (anchor_view_) | 592 if (anchor_view_) |
588 anchor_view_->SetActive(false); | 593 anchor_view_->SetActive(false); |
589 } | 594 } |
590 | 595 |
591 void ManagePasswordsBubbleView::AdjustForFullscreen( | 596 void ManagePasswordsBubbleView::AdjustForFullscreen( |
(...skipping 21 matching lines...) Expand all Loading... |
613 Refresh(); | 618 Refresh(); |
614 } | 619 } |
615 | 620 |
616 void ManagePasswordsBubbleView::WindowClosing() { | 621 void ManagePasswordsBubbleView::WindowClosing() { |
617 // Close() closes the window asynchronously, so by the time we reach here, | 622 // Close() closes the window asynchronously, so by the time we reach here, |
618 // |manage_passwords_bubble_| may have already been reset. | 623 // |manage_passwords_bubble_| may have already been reset. |
619 if (manage_passwords_bubble_ == this) | 624 if (manage_passwords_bubble_ == this) |
620 manage_passwords_bubble_ = NULL; | 625 manage_passwords_bubble_ = NULL; |
621 } | 626 } |
622 | 627 |
| 628 void ManagePasswordsBubbleView::OnWidgetActivationChanged(views::Widget* widget, |
| 629 bool active) { |
| 630 if (active && widget == GetWidget()) |
| 631 timer_.Stop(); |
| 632 BubbleDelegateView::OnWidgetActivationChanged(widget, active); |
| 633 } |
| 634 |
623 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() { | 635 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() { |
624 return initially_focused_view_; | 636 return initially_focused_view_; |
625 } | 637 } |
626 | 638 |
| 639 void ManagePasswordsBubbleView::OnMouseEntered(const ui::MouseEvent& event) { |
| 640 timer_.Stop(); |
| 641 } |
| 642 |
| 643 void ManagePasswordsBubbleView::OnMouseExited(const ui::MouseEvent& event) { |
| 644 StartTimerIfNecessary(); |
| 645 } |
| 646 |
627 void ManagePasswordsBubbleView::Refresh() { | 647 void ManagePasswordsBubbleView::Refresh() { |
628 RemoveAllChildViews(true); | 648 RemoveAllChildViews(true); |
629 initially_focused_view_ = NULL; | 649 initially_focused_view_ = NULL; |
630 if (password_manager::ui::IsPendingState(model()->state())) { | 650 if (password_manager::ui::IsPendingState(model()->state())) { |
631 if (never_save_passwords_) | 651 if (never_save_passwords_) |
632 AddChildView(new ConfirmNeverView(this)); | 652 AddChildView(new ConfirmNeverView(this)); |
633 else | 653 else |
634 AddChildView(new PendingView(this)); | 654 AddChildView(new PendingView(this)); |
635 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { | 655 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { |
636 AddChildView(new BlacklistedView(this)); | 656 AddChildView(new BlacklistedView(this)); |
637 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { | 657 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { |
638 AddChildView(new SaveConfirmationView(this)); | 658 AddChildView(new SaveConfirmationView(this)); |
639 } else { | 659 } else { |
640 AddChildView(new ManageView(this)); | 660 AddChildView(new ManageView(this)); |
641 } | 661 } |
642 GetLayoutManager()->Layout(this); | 662 GetLayoutManager()->Layout(this); |
| 663 // If we refresh the existing bubble we may want to restart the timer. |
| 664 if (GetWidget()) |
| 665 StartTimerIfNecessary(); |
643 } | 666 } |
644 | 667 |
645 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { | 668 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { |
646 if (model()->best_matches().empty()) { | 669 if (model()->best_matches().empty()) { |
647 // Skip confirmation if there are no existing passwords for this site. | 670 // Skip confirmation if there are no existing passwords for this site. |
648 NotifyConfirmedNeverForThisSite(); | 671 NotifyConfirmedNeverForThisSite(); |
649 } else { | 672 } else { |
650 never_save_passwords_ = true; | 673 never_save_passwords_ = true; |
651 Refresh(); | 674 Refresh(); |
652 } | 675 } |
653 } | 676 } |
654 | 677 |
655 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() { | 678 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() { |
656 model()->OnNeverForThisSiteClicked(); | 679 model()->OnNeverForThisSiteClicked(); |
657 Close(); | 680 Close(); |
658 } | 681 } |
659 | 682 |
660 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() { | 683 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() { |
661 never_save_passwords_ = false; | 684 never_save_passwords_ = false; |
662 Refresh(); | 685 Refresh(); |
663 } | 686 } |
| 687 |
| 688 void ManagePasswordsBubbleView::StartTimerIfNecessary() { |
| 689 // Active bubble will stay visible until it loses focus. |
| 690 if (GetWidget()->IsActive()) |
| 691 return; |
| 692 timer_.Start(FROM_HERE, |
| 693 base::TimeDelta::FromSeconds(kBubbleCloseDelay), |
| 694 this, |
| 695 &ManagePasswordsBubbleView::Close); |
| 696 } |
OLD | NEW |