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/ui/browser.h" | 7 #include "chrome/browser/ui/browser.h" |
8 #include "chrome/browser/ui/browser_finder.h" | 8 #include "chrome/browser/ui/browser_finder.h" |
9 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" | 9 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" |
10 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" | 10 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" |
11 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h" | 11 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h" |
12 #include "chrome/browser/ui/views/frame/browser_view.h" | 12 #include "chrome/browser/ui/views/frame/browser_view.h" |
13 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 13 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
14 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h" | 14 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h" |
15 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" | 15 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" |
16 #include "chrome/grit/generated_resources.h" | 16 #include "chrome/grit/generated_resources.h" |
17 #include "content/public/browser/render_view_host.h" | 17 #include "content/public/browser/render_view_host.h" |
18 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
19 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
20 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
21 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
22 #include "ui/compositor/layer_animation_observer.h" | |
23 #include "ui/compositor/scoped_layer_animation_settings.h" | |
24 #include "ui/views/controls/button/blue_button.h" | 22 #include "ui/views/controls/button/blue_button.h" |
25 #include "ui/views/controls/button/label_button.h" | 23 #include "ui/views/controls/button/label_button.h" |
26 #include "ui/views/controls/combobox/combobox.h" | 24 #include "ui/views/controls/combobox/combobox.h" |
27 #include "ui/views/controls/combobox/combobox_listener.h" | 25 #include "ui/views/controls/combobox/combobox_listener.h" |
28 #include "ui/views/controls/link.h" | 26 #include "ui/views/controls/link.h" |
29 #include "ui/views/controls/link_listener.h" | 27 #include "ui/views/controls/link_listener.h" |
30 #include "ui/views/controls/styled_label.h" | 28 #include "ui/views/controls/styled_label.h" |
31 #include "ui/views/controls/styled_label_listener.h" | 29 #include "ui/views/controls/styled_label_listener.h" |
32 #include "ui/views/layout/fill_layout.h" | 30 #include "ui/views/layout/fill_layout.h" |
33 #include "ui/views/layout/grid_layout.h" | 31 #include "ui/views/layout/grid_layout.h" |
34 #include "ui/views/layout/layout_constants.h" | 32 #include "ui/views/layout/layout_constants.h" |
35 | 33 |
36 | 34 |
37 // Helpers -------------------------------------------------------------------- | 35 // Helpers -------------------------------------------------------------------- |
38 | 36 |
39 namespace { | 37 namespace { |
40 | 38 |
41 // The number of seconds the bubble needs to fade out. | |
42 const int kBubbleFadeDelay = 2; | |
43 | |
44 const int kDesiredBubbleWidth = 370; | 39 const int kDesiredBubbleWidth = 370; |
45 | 40 |
46 enum ColumnSetType { | 41 enum ColumnSetType { |
47 // | | (FILL, FILL) | | | 42 // | | (FILL, FILL) | | |
48 // Used for the bubble's header, the credentials list, and for simple | 43 // Used for the bubble's header, the credentials list, and for simple |
49 // messages like "No passwords". | 44 // messages like "No passwords". |
50 SINGLE_VIEW_COLUMN_SET = 0, | 45 SINGLE_VIEW_COLUMN_SET = 0, |
51 | 46 |
52 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | | 47 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | |
53 // Used for buttons at the bottom of the bubble which should nest at the | 48 // Used for buttons at the bottom of the bubble which should nest at the |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 if (aura::Window* window = GetWebContentsWindow()) | 669 if (aura::Window* window = GetWebContentsWindow()) |
675 window->RemovePreTargetHandler(this); | 670 window->RemovePreTargetHandler(this); |
676 } | 671 } |
677 | 672 |
678 void ManagePasswordsBubbleView::WebContentMouseHandler::OnKeyEvent( | 673 void ManagePasswordsBubbleView::WebContentMouseHandler::OnKeyEvent( |
679 ui::KeyEvent* event) { | 674 ui::KeyEvent* event) { |
680 content::WebContents* web_contents = bubble_->model()->web_contents(); | 675 content::WebContents* web_contents = bubble_->model()->web_contents(); |
681 content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); | 676 content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); |
682 if (rvh->IsFocusedElementEditable() && | 677 if (rvh->IsFocusedElementEditable() && |
683 event->type() == ui::ET_KEY_PRESSED) | 678 event->type() == ui::ET_KEY_PRESSED) |
684 bubble_->StartFadingOut(); | 679 bubble_->Close(); |
685 } | 680 } |
686 | 681 |
687 void ManagePasswordsBubbleView::WebContentMouseHandler::OnMouseEvent( | 682 void ManagePasswordsBubbleView::WebContentMouseHandler::OnMouseEvent( |
688 ui::MouseEvent* event) { | 683 ui::MouseEvent* event) { |
689 if (event->type() == ui::ET_MOUSE_PRESSED) | 684 if (event->type() == ui::ET_MOUSE_PRESSED) |
690 bubble_->StartFadingOut(); | 685 bubble_->Close(); |
691 } | 686 } |
692 | 687 |
693 aura::Window* | 688 aura::Window* |
694 ManagePasswordsBubbleView::WebContentMouseHandler::GetWebContentsWindow() { | 689 ManagePasswordsBubbleView::WebContentMouseHandler::GetWebContentsWindow() { |
695 content::WebContents* web_contents = bubble_->model()->web_contents(); | 690 content::WebContents* web_contents = bubble_->model()->web_contents(); |
696 return web_contents ? web_contents->GetNativeView() : NULL; | 691 return web_contents ? web_contents->GetNativeView() : NULL; |
697 } | 692 } |
698 | 693 |
699 // ManagePasswordsBubbleView::FadeOutObserver --------------------------------- | |
700 | |
701 // The class notifies the bubble when it faded out completely. | |
702 class ManagePasswordsBubbleView::FadeOutObserver | |
703 : public ui::ImplicitAnimationObserver { | |
704 public: | |
705 explicit FadeOutObserver(ManagePasswordsBubbleView* bubble) | |
706 : bubble_(bubble) { | |
707 } | |
708 | |
709 virtual void OnImplicitAnimationsCompleted() OVERRIDE { | |
710 bubble_->OnBubbleDisappeared(); | |
711 } | |
712 | |
713 private: | |
714 ManagePasswordsBubbleView* bubble_; | |
715 | |
716 DISALLOW_COPY_AND_ASSIGN(FadeOutObserver); | |
717 }; | |
718 | |
719 // ManagePasswordsBubbleView -------------------------------------------------- | 694 // ManagePasswordsBubbleView -------------------------------------------------- |
720 | 695 |
721 // static | 696 // static |
722 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ = | 697 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ = |
723 NULL; | 698 NULL; |
724 | 699 |
725 // static | 700 // static |
726 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents, | 701 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents, |
727 DisplayReason reason) { | 702 DisplayReason reason) { |
728 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); | 703 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 DisplayReason reason) | 765 DisplayReason reason) |
791 : ManagePasswordsBubble(web_contents, reason), | 766 : ManagePasswordsBubble(web_contents, reason), |
792 BubbleDelegateView(anchor_view, | 767 BubbleDelegateView(anchor_view, |
793 anchor_view ? views::BubbleBorder::TOP_RIGHT | 768 anchor_view ? views::BubbleBorder::TOP_RIGHT |
794 : views::BubbleBorder::NONE), | 769 : views::BubbleBorder::NONE), |
795 anchor_view_(anchor_view), | 770 anchor_view_(anchor_view), |
796 never_save_passwords_(false), | 771 never_save_passwords_(false), |
797 initially_focused_view_(NULL) { | 772 initially_focused_view_(NULL) { |
798 // Compensate for built-in vertical padding in the anchor view's image. | 773 // Compensate for built-in vertical padding in the anchor view's image. |
799 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); | 774 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); |
800 set_notify_enter_exit_on_child(true); | |
801 if (anchor_view) | 775 if (anchor_view) |
802 anchor_view->SetActive(true); | 776 anchor_view->SetActive(true); |
803 mouse_handler_.reset(new WebContentMouseHandler(this)); | 777 mouse_handler_.reset(new WebContentMouseHandler(this)); |
804 } | 778 } |
805 | 779 |
806 ManagePasswordsBubbleView::~ManagePasswordsBubbleView() { | 780 ManagePasswordsBubbleView::~ManagePasswordsBubbleView() { |
807 if (anchor_view_) | 781 if (anchor_view_) |
808 anchor_view_->SetActive(false); | 782 anchor_view_->SetActive(false); |
809 } | 783 } |
810 | 784 |
811 void ManagePasswordsBubbleView::AdjustForFullscreen( | 785 void ManagePasswordsBubbleView::AdjustForFullscreen( |
812 const gfx::Rect& screen_bounds) { | 786 const gfx::Rect& screen_bounds) { |
813 if (GetAnchorView()) | 787 if (GetAnchorView()) |
814 return; | 788 return; |
815 | 789 |
816 // The bubble's padding from the screen edge, used in fullscreen. | 790 // The bubble's padding from the screen edge, used in fullscreen. |
817 const int kFullscreenPaddingEnd = 20; | 791 const int kFullscreenPaddingEnd = 20; |
818 const size_t bubble_half_width = width() / 2; | 792 const size_t bubble_half_width = width() / 2; |
819 const int x_pos = base::i18n::IsRTL() ? | 793 const int x_pos = base::i18n::IsRTL() ? |
820 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : | 794 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : |
821 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; | 795 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; |
822 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); | 796 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); |
823 } | 797 } |
824 | 798 |
825 void ManagePasswordsBubbleView::Close() { | 799 void ManagePasswordsBubbleView::Close() { |
826 fadeout_observer_.reset(); | |
827 mouse_handler_.reset(); | 800 mouse_handler_.reset(); |
828 GetWidget()->Close(); | 801 GetWidget()->Close(); |
829 } | 802 } |
830 | 803 |
831 void ManagePasswordsBubbleView::Refresh() { | 804 void ManagePasswordsBubbleView::Refresh() { |
832 RemoveAllChildViews(true); | 805 RemoveAllChildViews(true); |
833 initially_focused_view_ = NULL; | 806 initially_focused_view_ = NULL; |
834 if (password_manager::ui::IsPendingState(model()->state())) { | 807 if (password_manager::ui::IsPendingState(model()->state())) { |
835 if (never_save_passwords_) | 808 if (never_save_passwords_) |
836 AddChildView(new ConfirmNeverView(this)); | 809 AddChildView(new ConfirmNeverView(this)); |
837 else | 810 else |
838 AddChildView(new PendingView(this)); | 811 AddChildView(new PendingView(this)); |
839 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { | 812 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { |
840 AddChildView(new BlacklistedView(this)); | 813 AddChildView(new BlacklistedView(this)); |
841 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { | 814 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { |
842 AddChildView(new SaveConfirmationView(this)); | 815 AddChildView(new SaveConfirmationView(this)); |
843 } else { | 816 } else { |
844 AddChildView(new ManageView(this)); | 817 AddChildView(new ManageView(this)); |
845 } | 818 } |
846 GetLayoutManager()->Layout(this); | 819 GetLayoutManager()->Layout(this); |
847 CancelFadingOut(); | |
848 } | 820 } |
849 | 821 |
850 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { | 822 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { |
851 if (model()->best_matches().empty()) { | 823 if (model()->best_matches().empty()) { |
852 // Skip confirmation if there are no existing passwords for this site. | 824 // Skip confirmation if there are no existing passwords for this site. |
853 NotifyConfirmedNeverForThisSite(); | 825 NotifyConfirmedNeverForThisSite(); |
854 } else { | 826 } else { |
855 never_save_passwords_ = true; | 827 never_save_passwords_ = true; |
856 Refresh(); | 828 Refresh(); |
857 } | 829 } |
(...skipping 16 matching lines...) Expand all Loading... |
874 Refresh(); | 846 Refresh(); |
875 } | 847 } |
876 | 848 |
877 void ManagePasswordsBubbleView::WindowClosing() { | 849 void ManagePasswordsBubbleView::WindowClosing() { |
878 // Close() closes the window asynchronously, so by the time we reach here, | 850 // Close() closes the window asynchronously, so by the time we reach here, |
879 // |manage_passwords_bubble_| may have already been reset. | 851 // |manage_passwords_bubble_| may have already been reset. |
880 if (manage_passwords_bubble_ == this) | 852 if (manage_passwords_bubble_ == this) |
881 manage_passwords_bubble_ = NULL; | 853 manage_passwords_bubble_ = NULL; |
882 } | 854 } |
883 | 855 |
884 void ManagePasswordsBubbleView::OnWidgetActivationChanged(views::Widget* widget, | |
885 bool active) { | |
886 if (active && widget == GetWidget()) | |
887 CancelFadingOut(); | |
888 BubbleDelegateView::OnWidgetActivationChanged(widget, active); | |
889 } | |
890 | |
891 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() { | 856 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() { |
892 return initially_focused_view_; | 857 return initially_focused_view_; |
893 } | 858 } |
894 | |
895 void ManagePasswordsBubbleView::OnMouseEntered(const ui::MouseEvent& event) { | |
896 CancelFadingOut(); | |
897 } | |
898 | |
899 void ManagePasswordsBubbleView::StartFadingOut() { | |
900 if (fadeout_observer_) | |
901 return; | |
902 aura::Window* window = GetWidget()->GetNativeView(); | |
903 ui::ScopedLayerAnimationSettings animator(window->layer()->GetAnimator()); | |
904 fadeout_observer_.reset(new FadeOutObserver(this)); | |
905 animator.AddObserver(fadeout_observer_.get()); | |
906 animator.SetTransitionDuration( | |
907 base::TimeDelta::FromSeconds(kBubbleFadeDelay)); | |
908 window->layer()->SetOpacity(0); | |
909 } | |
910 | |
911 void ManagePasswordsBubbleView::CancelFadingOut() { | |
912 if (!fadeout_observer_) | |
913 return; | |
914 fadeout_observer_.reset(); | |
915 aura::Window* window = GetWidget()->GetNativeView(); | |
916 window->layer()->SetOpacity(1); | |
917 } | |
918 | |
919 void ManagePasswordsBubbleView::OnBubbleDisappeared() { | |
920 Close(); | |
921 } | |
OLD | NEW |