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/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "chrome/browser/chrome_notification_types.h" | 8 #include "chrome/browser/chrome_notification_types.h" |
9 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
10 #include "chrome/browser/ui/browser_finder.h" | 10 #include "chrome/browser/ui/browser_finder.h" |
11 #include "chrome/browser/ui/browser_window.h" | 11 #include "chrome/browser/ui/browser_window.h" |
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" | 12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" |
13 #include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h" | 13 #include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h" |
14 #include "chrome/browser/ui/views/frame/browser_view.h" | 14 #include "chrome/browser/ui/views/frame/browser_view.h" |
15 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 15 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
16 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h" | 16 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h" |
17 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" | 17 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" |
18 #include "content/public/browser/notification_source.h" | 18 #include "content/public/browser/notification_source.h" |
19 #include "content/public/browser/web_contents_view.h" | 19 #include "content/public/browser/web_contents_view.h" |
20 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
21 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
22 #include "ui/base/models/combobox_model.h" | 22 #include "ui/base/models/combobox_model.h" |
23 #include "ui/base/resource/resource_bundle.h" | 23 #include "ui/base/resource/resource_bundle.h" |
24 #include "ui/gfx/text_utils.h" | 24 #include "ui/gfx/text_utils.h" |
25 #include "ui/views/controls/button/blue_button.h" | 25 #include "ui/views/controls/button/blue_button.h" |
26 #include "ui/views/controls/button/label_button.h" | 26 #include "ui/views/controls/button/label_button.h" |
27 #include "ui/views/controls/combobox/combobox.h" | 27 #include "ui/views/controls/combobox/combobox.h" |
28 #include "ui/views/layout/fill_layout.h" | |
28 #include "ui/views/layout/grid_layout.h" | 29 #include "ui/views/layout/grid_layout.h" |
29 #include "ui/views/layout/layout_constants.h" | 30 #include "ui/views/layout/layout_constants.h" |
30 | 31 |
31 | 32 |
32 // Helpers -------------------------------------------------------------------- | 33 // Helpers -------------------------------------------------------------------- |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
36 enum FieldType { USERNAME_FIELD, PASSWORD_FIELD }; | |
37 | |
38 // Upper limit on the size of the username and password fields. | |
39 const int kUsernameFieldSize = 30; | |
40 const int kPasswordFieldSize = 22; | |
41 | |
42 // Returns the width of |type| field. | |
43 int GetFieldWidth(FieldType type) { | |
44 return ui::ResourceBundle::GetSharedInstance() | |
45 .GetFontList(ui::ResourceBundle::SmallFont) | |
46 .GetExpectedTextWidth(type == USERNAME_FIELD ? kUsernameFieldSize | |
47 : kPasswordFieldSize); | |
48 } | |
49 | |
50 class SavePasswordRefusalComboboxModel : public ui::ComboboxModel { | 37 class SavePasswordRefusalComboboxModel : public ui::ComboboxModel { |
51 public: | 38 public: |
52 enum { INDEX_NOPE = 0, INDEX_NEVER_FOR_THIS_SITE = 1, }; | 39 enum { INDEX_NOPE = 0, INDEX_NEVER_FOR_THIS_SITE = 1, }; |
53 | 40 |
54 SavePasswordRefusalComboboxModel() { | 41 SavePasswordRefusalComboboxModel() { |
55 items_.push_back( | 42 items_.push_back( |
56 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CANCEL_BUTTON)); | 43 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CANCEL_BUTTON)); |
57 items_.push_back( | 44 items_.push_back( |
58 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON)); | 45 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON)); |
59 } | 46 } |
(...skipping 25 matching lines...) Expand all Loading... | |
85 ManagePasswordsBubbleUIController::FromWebContents(web_contents); | 72 ManagePasswordsBubbleUIController::FromWebContents(web_contents); |
86 ManagePasswordsBubbleView::ShowBubble( | 73 ManagePasswordsBubbleView::ShowBubble( |
87 web_contents, | 74 web_contents, |
88 controller->manage_passwords_bubble_needs_showing() | 75 controller->manage_passwords_bubble_needs_showing() |
89 ? ManagePasswordsBubbleView::AUTOMATIC | 76 ? ManagePasswordsBubbleView::AUTOMATIC |
90 : ManagePasswordsBubbleView::USER_ACTION); | 77 : ManagePasswordsBubbleView::USER_ACTION); |
91 } | 78 } |
92 | 79 |
93 } // namespace chrome | 80 } // namespace chrome |
94 | 81 |
82 // ManagePasswordsBubbleView::PendingView ------------------------------------- | |
83 | |
84 ManagePasswordsBubbleView::PendingView::PendingView( | |
85 ManagePasswordsBubbleView* parent) | |
86 : parent_(parent) { | |
87 views::GridLayout* layout = new views::GridLayout(this); | |
88 SetLayoutManager(layout); | |
89 | |
90 // Create the pending credential item, save button and refusal combobox. | |
91 ManagePasswordItemView* item = | |
92 new ManagePasswordItemView(parent->model(), | |
93 parent->model()->pending_credentials(), | |
94 ManagePasswordItemView::FIRST_ITEM); | |
95 save_button_ = new views::BlueButton( | |
96 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); | |
97 refuse_combobox_ = | |
98 new views::Combobox(new SavePasswordRefusalComboboxModel()); | |
99 refuse_combobox_->set_listener(this); | |
100 refuse_combobox_->SetStyle(views::Combobox::STYLE_ACTION); | |
101 | |
102 // Title row. | |
103 parent->BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); | |
markusheintz_
2014/04/29 07:51:38
It seems like this method is not used on the paren
| |
104 parent->AddTitleRow(layout); | |
markusheintz_
2014/04/29 07:51:38
The same as above seems to hold for this one.
| |
105 | |
106 // Credential row. | |
107 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
108 layout->AddView(item); | |
109 | |
110 // Button row. | |
111 parent->BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET); | |
112 layout->StartRowWithPadding( | |
113 0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing); | |
114 layout->AddView(save_button_); | |
115 layout->AddView(refuse_combobox_); | |
116 | |
117 // Extra padding for visual awesomeness. | |
118 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
119 } | |
120 | |
121 ManagePasswordsBubbleView::PendingView::~PendingView() { | |
122 } | |
123 | |
124 void ManagePasswordsBubbleView::PendingView::ButtonPressed( | |
125 views::Button* sender, | |
126 const ui::Event& event) { | |
127 DCHECK(sender == save_button_); | |
128 parent_->model()->OnSaveClicked(); | |
129 parent_->Close(); | |
130 } | |
131 | |
132 void ManagePasswordsBubbleView::PendingView::OnPerformAction( | |
133 views::Combobox* source) { | |
134 DCHECK_EQ(source, refuse_combobox_); | |
135 switch (refuse_combobox_->selected_index()) { | |
136 case SavePasswordRefusalComboboxModel::INDEX_NOPE: | |
137 parent_->model()->OnNopeClicked(); | |
138 break; | |
139 case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE: | |
140 parent_->model()->OnNeverForThisSiteClicked(); | |
141 break; | |
142 } | |
143 parent_->Close(); | |
144 } | |
145 | |
146 // ManagePasswordsBubbleView::ManageView -------------------------------------- | |
147 | |
148 ManagePasswordsBubbleView::ManageView::ManageView( | |
149 ManagePasswordsBubbleView* parent) | |
150 : parent_(parent) { | |
151 views::GridLayout* layout = new views::GridLayout(this); | |
152 SetLayoutManager(layout); | |
153 | |
154 // Add the title. | |
155 parent->BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); | |
156 parent->AddTitleRow(layout); | |
157 | |
158 // If we have a list of passwords to store for the current site, display | |
159 // them to the user for management. Otherwise, render a "No passwords for | |
160 // this site" message. | |
161 if (!parent_->model()->best_matches().empty()) { | |
162 for (autofill::PasswordFormMap::const_iterator i( | |
163 parent_->model()->best_matches().begin()); | |
164 i != parent_->model()->best_matches().end(); | |
165 ++i) { | |
166 ManagePasswordItemView* item = new ManagePasswordItemView( | |
167 parent_->model(), | |
168 *i->second, | |
169 i == parent_->model()->best_matches().begin() | |
170 ? ManagePasswordItemView::FIRST_ITEM | |
171 : ManagePasswordItemView::SUBSEQUENT_ITEM); | |
172 | |
173 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
174 layout->AddView(item); | |
175 } | |
176 } else { | |
177 views::Label* empty_label = new views::Label( | |
178 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_NO_PASSWORDS)); | |
179 empty_label->SetMultiLine(true); | |
180 | |
181 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
182 layout->AddView(empty_label); | |
183 } | |
184 | |
185 // Then add the "manage passwords" link and "Done" button. | |
186 manage_link_ = new views::Link(parent_->model()->manage_link()); | |
187 manage_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
188 manage_link_->SetUnderline(false); | |
189 manage_link_->set_listener(this); | |
190 | |
191 done_button_ = | |
192 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_DONE)); | |
193 done_button_->SetStyle(views::Button::STYLE_BUTTON); | |
194 | |
195 parent->BuildColumnSet(layout, LINK_BUTTON_COLUMN_SET); | |
196 layout->StartRowWithPadding( | |
197 0, LINK_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing); | |
198 layout->AddView(manage_link_); | |
199 layout->AddView(done_button_); | |
200 | |
201 // Extra padding for visual awesomeness. | |
202 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
203 } | |
204 | |
205 ManagePasswordsBubbleView::ManageView::~ManageView() { | |
206 } | |
207 | |
208 void ManagePasswordsBubbleView::ManageView::ButtonPressed( | |
209 views::Button* sender, | |
210 const ui::Event& event) { | |
211 DCHECK(sender == done_button_); | |
212 parent_->model()->OnDoneClicked(); | |
213 parent_->Close(); | |
214 } | |
215 | |
216 void ManagePasswordsBubbleView::ManageView::LinkClicked(views::Link* source, | |
217 int event_flags) { | |
218 DCHECK_EQ(source, manage_link_); | |
219 parent_->model()->OnManageLinkClicked(); | |
220 parent_->Close(); | |
221 } | |
222 | |
95 // ManagePasswordsBubbleView -------------------------------------------------- | 223 // ManagePasswordsBubbleView -------------------------------------------------- |
96 | 224 |
97 // static | 225 // static |
98 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ = | 226 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ = |
99 NULL; | 227 NULL; |
100 | 228 |
101 // static | 229 // static |
102 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents, | 230 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents, |
103 DisplayReason reason) { | 231 DisplayReason reason) { |
104 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); | 232 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 views::GridLayout::CENTER, | 329 views::GridLayout::CENTER, |
202 0, | 330 0, |
203 views::GridLayout::USE_PREF, | 331 views::GridLayout::USE_PREF, |
204 0, | 332 0, |
205 0); | 333 0); |
206 break; | 334 break; |
207 } | 335 } |
208 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); | 336 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); |
209 } | 337 } |
210 | 338 |
339 void ManagePasswordsBubbleView::AddTitleRow(views::GridLayout* layout) const { | |
340 // Build the title label, and populate it with whatever title our model feels | |
341 // is appropriate for the bubble's state. | |
342 views::Label* title_label = new views::Label(model()->title()); | |
343 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
344 title_label->SetMultiLine(true); | |
345 title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( | |
346 ui::ResourceBundle::MediumFont)); | |
347 | |
348 // Add the title to the layout with appropriate padding. | |
349 layout->StartRowWithPadding( | |
350 0, SINGLE_VIEW_COLUMN_SET, 0, views::kRelatedControlSmallVerticalSpacing); | |
351 layout->AddView(title_label); | |
352 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
353 } | |
354 | |
211 void ManagePasswordsBubbleView::AdjustForFullscreen( | 355 void ManagePasswordsBubbleView::AdjustForFullscreen( |
212 const gfx::Rect& screen_bounds) { | 356 const gfx::Rect& screen_bounds) { |
213 if (GetAnchorView()) | 357 if (GetAnchorView()) |
214 return; | 358 return; |
215 | 359 |
216 // The bubble's padding from the screen edge, used in fullscreen. | 360 // The bubble's padding from the screen edge, used in fullscreen. |
217 const int kFullscreenPaddingEnd = 20; | 361 const int kFullscreenPaddingEnd = 20; |
218 const size_t bubble_half_width = width() / 2; | 362 const size_t bubble_half_width = width() / 2; |
219 const int x_pos = base::i18n::IsRTL() ? | 363 const int x_pos = base::i18n::IsRTL() ? |
220 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : | 364 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : |
221 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; | 365 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; |
222 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); | 366 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); |
223 } | 367 } |
224 | 368 |
225 void ManagePasswordsBubbleView::Close() { | 369 void ManagePasswordsBubbleView::Close() { |
226 GetWidget()->Close(); | 370 GetWidget()->Close(); |
227 } | 371 } |
228 | 372 |
229 void ManagePasswordsBubbleView::CloseWithoutLogging() { | 373 void ManagePasswordsBubbleView::CloseWithoutLogging() { |
230 model()->OnCloseWithoutLogging(); | 374 model()->OnCloseWithoutLogging(); |
231 GetWidget()->Close(); | 375 GetWidget()->Close(); |
232 } | 376 } |
233 | 377 |
234 void ManagePasswordsBubbleView::Init() { | 378 void ManagePasswordsBubbleView::Init() { |
235 using views::GridLayout; | 379 views::FillLayout* layout = new views::FillLayout(); |
380 SetLayoutManager(layout); | |
381 SetFocusable(true); | |
236 | 382 |
237 GridLayout* layout = new GridLayout(this); | 383 if (model()->WaitingToSavePassword()) |
238 SetFocusable(true); | 384 AddChildView(new PendingView(this)); |
239 SetLayoutManager(layout); | 385 else |
240 BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET); | 386 AddChildView(new ManageView(this)); |
241 BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET); | |
242 BuildColumnSet(layout, LINK_BUTTON_COLUMN_SET); | |
243 | |
244 // This calculates the necessary widths for credential columns in the bubble. | |
245 const int first_field_width = std::max( | |
246 GetFieldWidth(USERNAME_FIELD), | |
247 views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED)) | |
248 .GetPreferredSize() | |
249 .width()); | |
250 | |
251 const int second_field_width = std::max( | |
252 GetFieldWidth(PASSWORD_FIELD), | |
253 views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO)) | |
254 .GetPreferredSize() | |
255 .width()); | |
256 | |
257 // Build and populate the header. | |
258 views::Label* title_label = new views::Label(model()->title()); | |
259 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
260 title_label->SetMultiLine(true); | |
261 title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( | |
262 ui::ResourceBundle::MediumFont)); | |
263 | |
264 layout->StartRowWithPadding( | |
265 0, SINGLE_VIEW_COLUMN_SET, 0, views::kRelatedControlSmallVerticalSpacing); | |
266 layout->AddView(title_label); | |
267 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
268 | |
269 if (model()->WaitingToSavePassword()) { | |
270 // If we've got a password that we're deciding whether or not to save, | |
271 // then we need to display a single-view columnset containing the | |
272 // ManagePasswordItemView, followed by double-view columnset containing | |
273 // a "Save" and "Reject" button. | |
274 ManagePasswordItemView* item = | |
275 new ManagePasswordItemView(model(), | |
276 model()->pending_credentials(), | |
277 first_field_width, | |
278 second_field_width, | |
279 ManagePasswordItemView::FIRST_ITEM); | |
280 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
281 layout->AddView(item); | |
282 | |
283 refuse_combobox_ = | |
284 new views::Combobox(new SavePasswordRefusalComboboxModel()); | |
285 refuse_combobox_->set_listener(this); | |
286 refuse_combobox_->SetStyle(views::Combobox::STYLE_ACTION); | |
287 | |
288 save_button_ = new views::BlueButton( | |
289 this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); | |
290 | |
291 layout->StartRowWithPadding( | |
292 0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing); | |
293 layout->AddView(save_button_); | |
294 layout->AddView(refuse_combobox_); | |
295 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
296 } else { | |
297 // If we have a list of passwords to store for the current site, display | |
298 // them to the user for management. Otherwise, render a "No passwords for | |
299 // this site" message. | |
300 // | |
301 // TODO(mkwst): Do we really want the "No passwords" case? It would probably | |
302 // be better to only clear the pending password upon navigation, rather than | |
303 // as soon as the bubble closes. | |
304 if (!model()->best_matches().empty()) { | |
305 for (autofill::PasswordFormMap::const_iterator i( | |
306 model()->best_matches().begin()); | |
307 i != model()->best_matches().end(); | |
308 ++i) { | |
309 ManagePasswordItemView* item = new ManagePasswordItemView( | |
310 model(), | |
311 *i->second, | |
312 first_field_width, | |
313 second_field_width, | |
314 i == model()->best_matches().begin() | |
315 ? ManagePasswordItemView::FIRST_ITEM | |
316 : ManagePasswordItemView::SUBSEQUENT_ITEM); | |
317 | |
318 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
319 layout->AddView(item); | |
320 } | |
321 } else { | |
322 views::Label* empty_label = new views::Label( | |
323 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_NO_PASSWORDS)); | |
324 empty_label->SetMultiLine(true); | |
325 | |
326 layout->StartRow(0, SINGLE_VIEW_COLUMN_SET); | |
327 layout->AddView(empty_label); | |
328 } | |
329 | |
330 // Build a "manage" link and "done" button, and throw them both into a new | |
331 // row | |
332 // containing a double-view columnset. | |
333 manage_link_ = new views::Link(model()->manage_link()); | |
334 manage_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
335 manage_link_->SetUnderline(false); | |
336 manage_link_->set_listener(this); | |
337 | |
338 done_button_ = | |
339 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_DONE)); | |
340 done_button_->SetStyle(views::Button::STYLE_BUTTON); | |
341 | |
342 layout->StartRowWithPadding( | |
343 0, LINK_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing); | |
344 layout->AddView(manage_link_); | |
345 layout->AddView(done_button_); | |
346 } | |
347 } | 387 } |
348 | 388 |
349 void ManagePasswordsBubbleView::WindowClosing() { | 389 void ManagePasswordsBubbleView::WindowClosing() { |
350 // Close() closes the window asynchronously, so by the time we reach here, | 390 // Close() closes the window asynchronously, so by the time we reach here, |
351 // |manage_passwords_bubble_| may have already been reset. | 391 // |manage_passwords_bubble_| may have already been reset. |
352 if (manage_passwords_bubble_ == this) | 392 if (manage_passwords_bubble_ == this) |
353 manage_passwords_bubble_ = NULL; | 393 manage_passwords_bubble_ = NULL; |
354 } | 394 } |
355 | |
356 void ManagePasswordsBubbleView::ButtonPressed(views::Button* sender, | |
357 const ui::Event& event) { | |
358 DCHECK(sender == save_button_ || sender == done_button_); | |
359 | |
360 if (sender == save_button_) | |
361 model()->OnSaveClicked(); | |
362 else | |
363 model()->OnDoneClicked(); | |
364 Close(); | |
365 } | |
366 | |
367 void ManagePasswordsBubbleView::LinkClicked(views::Link* source, | |
368 int event_flags) { | |
369 DCHECK_EQ(source, manage_link_); | |
370 model()->OnManageLinkClicked(); | |
371 Close(); | |
372 } | |
373 | |
374 void ManagePasswordsBubbleView::OnPerformAction(views::Combobox* source) { | |
375 DCHECK_EQ(source, refuse_combobox_); | |
376 switch (refuse_combobox_->selected_index()) { | |
377 case SavePasswordRefusalComboboxModel::INDEX_NOPE: | |
378 model()->OnNopeClicked(); | |
379 break; | |
380 case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE: | |
381 model()->OnNeverForThisSiteClicked(); | |
382 break; | |
383 default: | |
384 NOTREACHED(); | |
385 break; | |
386 } | |
387 Close(); | |
388 } | |
OLD | NEW |