manage_passwords_bubble_view.h revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_VIEW_H_
7
8#include "base/basictypes.h"
9#include "base/timer/timer.h"
10#include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
11#include "chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h"
12#include "ui/views/bubble/bubble_delegate.h"
13#include "ui/views/controls/button/button.h"
14#include "ui/views/controls/combobox/combobox.h"
15#include "ui/views/controls/combobox/combobox_listener.h"
16#include "ui/views/controls/link.h"
17#include "ui/views/controls/link_listener.h"
18#include "ui/views/controls/styled_label_listener.h"
19
20class ManagePasswordsIconView;
21
22namespace content {
23class WebContents;
24}
25
26namespace views {
27class BlueButton;
28class LabelButton;
29class GridLayout;
30}
31
32// The ManagePasswordsBubbleView controls the contents of the bubble which
33// pops up when Chrome offers to save a user's password, or when the user
34// interacts with the Omnibox icon. It has two distinct states:
35//
36// 1. PendingView: Offers the user the possibility of saving credentials.
37// 2. ManageView: Displays the current page's saved credentials.
38// 3. BlacklistedView: Informs the user that the current page is blacklisted.
39//
40class ManagePasswordsBubbleView : public ManagePasswordsBubble,
41                                  public views::BubbleDelegateView {
42 public:
43  // A view offering the user the ability to save credentials. Contains a
44  // single ManagePasswordItemView, along with a "Save Passwords" button
45  // and a rejection combobox.
46  class PendingView : public views::View,
47                      public views::ButtonListener,
48                      public views::ComboboxListener {
49   public:
50    explicit PendingView(ManagePasswordsBubbleView* parent);
51    virtual ~PendingView();
52
53   private:
54    // views::ButtonListener:
55    virtual void ButtonPressed(views::Button* sender,
56                               const ui::Event& event) OVERRIDE;
57
58    // Handles the event when the user changes an index of a combobox.
59    virtual void OnPerformAction(views::Combobox* source) OVERRIDE;
60
61    ManagePasswordsBubbleView* parent_;
62
63    views::BlueButton* save_button_;
64
65    // The combobox doesn't take ownership of its model. If we created a
66    // combobox we need to ensure that we delete the model here, and because the
67    // combobox uses the model in it's destructor, we need to make sure we
68    // delete the model _after_ the combobox itself is deleted.
69    scoped_ptr<SavePasswordRefusalComboboxModel> combobox_model_;
70    scoped_ptr<views::Combobox> refuse_combobox_;
71  };
72
73  // A view offering the user the ability to undo her decision to never save
74  // passwords for a particular site.
75  class ConfirmNeverView : public views::View, public views::ButtonListener {
76   public:
77    explicit ConfirmNeverView(ManagePasswordsBubbleView* parent);
78    virtual ~ConfirmNeverView();
79
80   private:
81    // views::ButtonListener:
82    virtual void ButtonPressed(views::Button* sender,
83                               const ui::Event& event) OVERRIDE;
84
85    ManagePasswordsBubbleView* parent_;
86
87    views::LabelButton* confirm_button_;
88    views::LabelButton* undo_button_;
89  };
90
91  // A view offering the user a list of her currently saved credentials
92  // for the current page, along with a "Manage passwords" link and a
93  // "Done" button.
94  class ManageView : public views::View,
95                     public views::ButtonListener,
96                     public views::LinkListener {
97   public:
98    explicit ManageView(ManagePasswordsBubbleView* parent);
99    virtual ~ManageView();
100
101   private:
102    // views::ButtonListener:
103    virtual void ButtonPressed(views::Button* sender,
104                               const ui::Event& event) OVERRIDE;
105
106    // views::LinkListener:
107    virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
108
109    ManagePasswordsBubbleView* parent_;
110
111    views::Link* manage_link_;
112    views::LabelButton* done_button_;
113  };
114
115  // A view offering the user the ability to re-enable the password manager for
116  // a specific site after she's decided to "never save passwords".
117  class BlacklistedView : public views::View, public views::ButtonListener {
118   public:
119    explicit BlacklistedView(ManagePasswordsBubbleView* parent);
120    virtual ~BlacklistedView();
121
122   private:
123    // views::ButtonListener:
124    virtual void ButtonPressed(views::Button* sender,
125                               const ui::Event& event) OVERRIDE;
126
127    ManagePasswordsBubbleView* parent_;
128
129    views::BlueButton* unblacklist_button_;
130    views::LabelButton* done_button_;
131  };
132
133  // A view confirming to the user that a password was saved and offering a link
134  // to the Google account manager.
135  class SaveConfirmationView : public views::View,
136                               public views::ButtonListener,
137                               public views::StyledLabelListener {
138   public:
139    explicit SaveConfirmationView(ManagePasswordsBubbleView* parent);
140    virtual ~SaveConfirmationView();
141
142   private:
143    // views::ButtonListener:
144    virtual void ButtonPressed(views::Button* sender,
145                               const ui::Event& event) OVERRIDE;
146
147    // views::StyledLabelListener implementation
148    virtual void StyledLabelLinkClicked(const gfx::Range& range,
149                                        int event_flags) OVERRIDE;
150
151    ManagePasswordsBubbleView* parent_;
152
153    views::LabelButton* ok_button_;
154  };
155
156  // Shows the bubble.
157  static void ShowBubble(content::WebContents* web_contents,
158                         DisplayReason reason);
159
160  // Closes any existing bubble.
161  static void CloseBubble();
162
163  // Makes the bubble the foreground window.
164  static void ActivateBubble();
165
166  // Whether the bubble is currently showing.
167  static bool IsShowing();
168
169  // Returns a pointer to the bubble.
170  static const ManagePasswordsBubbleView* manage_password_bubble() {
171    return manage_passwords_bubble_;
172  }
173
174  const View* initially_focused_view() const {
175    return initially_focused_view_;
176  }
177
178  bool IsTimerRunning() const {
179    return timer_.IsRunning();
180  }
181
182 private:
183  ManagePasswordsBubbleView(content::WebContents* web_contents,
184                            ManagePasswordsIconView* anchor_view,
185                            DisplayReason reason);
186  virtual ~ManagePasswordsBubbleView();
187
188  // If the bubble is not anchored to a view, places the bubble in the top
189  // right (left in RTL) of the |screen_bounds| that contain |web_contents_|'s
190  // browser window. Because the positioning is based on the size of the
191  // bubble, this must be called after the bubble is created.
192  void AdjustForFullscreen(const gfx::Rect& screen_bounds);
193
194  // Close the bubble.
195  void Close();
196
197  // Refreshes the bubble's state: called to display a confirmation screen after
198  // a user selects "Never for this site", for instance.
199  void Refresh();
200
201  // Called from PendingView if the user clicks on "Never for this site" in
202  // order to display a confirmation screen.
203  void NotifyNeverForThisSiteClicked();
204
205  // Called from ConfirmNeverView if the user confirms her intention to never
206  // save passwords, and remove existing passwords, for a site.
207  void NotifyConfirmedNeverForThisSite();
208
209  // Called from ConfirmNeverView if the user clicks on "Undo" in order to
210  // undo the action and refresh to PendingView.
211  void NotifyUndoNeverForThisSite();
212
213  // Starts a timer which will close the bubble if it's inactive.
214  void StartTimerIfNecessary();
215
216  // views::BubbleDelegateView:
217  virtual void Init() OVERRIDE;
218  virtual void WindowClosing() OVERRIDE;
219  virtual void OnWidgetActivationChanged(views::Widget* widget,
220                                         bool active) OVERRIDE;
221
222  // views::WidgetDelegate
223  virtual views::View* GetInitiallyFocusedView() OVERRIDE;
224
225  // views::View methods.
226  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
227  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
228
229  void set_initially_focused_view(views::View* view) {
230    DCHECK(!initially_focused_view_);
231    initially_focused_view_ = view;
232  }
233
234  // Singleton instance of the Password bubble. The Password bubble can only be
235  // shown on the active browser window, so there is no case in which it will be
236  // shown twice at the same time.
237  static ManagePasswordsBubbleView* manage_passwords_bubble_;
238
239  ManagePasswordsIconView* anchor_view_;
240
241  // If true upon destruction, the user has confirmed that she never wants to
242  // save passwords for a particular site.
243  bool never_save_passwords_;
244
245  views::View* initially_focused_view_;
246
247  // Timer used to close the bubble after timeout.
248  base::OneShotTimer<ManagePasswordsBubbleView> timer_;
249
250  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleView);
251};
252
253#endif  // CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_VIEW_H_
254