Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: chrome/browser/ui/autofill/autofill_popup_controller_impl.cc

Issue 12217024: Use WeakPtr to simplify AutofillPopupControllerImpl memory management (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments and fix test Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/autofill/autofill_popup_controller_impl.h" 5 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h" 12 #include "chrome/browser/ui/autofill/autofill_popup_delegate.h"
13 #include "chrome/browser/ui/autofill/autofill_popup_view.h" 13 #include "chrome/browser/ui/autofill/autofill_popup_view.h"
14 #include "content/public/browser/native_web_keyboard_event.h" 14 #include "content/public/browser/native_web_keyboard_event.h"
15 #include "grit/webkit_resources.h" 15 #include "grit/webkit_resources.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
17 #include "ui/base/events/event.h" 17 #include "ui/base/events/event.h"
18 #include "ui/base/text/text_elider.h" 18 #include "ui/base/text/text_elider.h"
19 #include "ui/gfx/display.h" 19 #include "ui/gfx/display.h"
20 #include "ui/gfx/screen.h" 20 #include "ui/gfx/screen.h"
21 #include "ui/gfx/vector2d.h" 21 #include "ui/gfx/vector2d.h"
22 22
23 using base::WeakPtr;
23 using WebKit::WebAutofillClient; 24 using WebKit::WebAutofillClient;
24 25
25 namespace { 26 namespace {
26 27
27 // Used to indicate that no line is currently selected by the user. 28 // Used to indicate that no line is currently selected by the user.
28 const int kNoSelection = -1; 29 const int kNoSelection = -1;
29 30
30 // Size difference between name and subtext in pixels. 31 // Size difference between name and subtext in pixels.
31 const int kLabelFontSizeDelta = -2; 32 const int kLabelFontSizeDelta = -2;
32 33
(...skipping 30 matching lines...) Expand all
63 { "genericCC", IDR_AUTOFILL_CC_GENERIC }, 64 { "genericCC", IDR_AUTOFILL_CC_GENERIC },
64 { "jcbCC", IDR_AUTOFILL_CC_JCB }, 65 { "jcbCC", IDR_AUTOFILL_CC_JCB },
65 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD }, 66 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD },
66 { "soloCC", IDR_AUTOFILL_CC_SOLO }, 67 { "soloCC", IDR_AUTOFILL_CC_SOLO },
67 { "visaCC", IDR_AUTOFILL_CC_VISA }, 68 { "visaCC", IDR_AUTOFILL_CC_VISA },
68 }; 69 };
69 70
70 } // end namespace 71 } // end namespace
71 72
72 // static 73 // static
73 AutofillPopupControllerImpl* AutofillPopupControllerImpl::GetOrCreate( 74 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetOrCreate(
74 AutofillPopupControllerImpl* previous, 75 WeakPtr<AutofillPopupControllerImpl> previous,
75 AutofillPopupDelegate* delegate, 76 AutofillPopupDelegate* delegate,
76 gfx::NativeView container_view, 77 gfx::NativeView container_view,
77 const gfx::Rect& element_bounds) { 78 const gfx::Rect& element_bounds) {
78 DCHECK(!previous || previous->delegate_ == delegate); 79 DCHECK(!previous || previous->delegate_ == delegate);
79 80
80 if (previous && 81 if (previous &&
81 previous->container_view() == container_view && 82 previous->container_view() == container_view &&
82 previous->element_bounds() == element_bounds) { 83 previous->element_bounds() == element_bounds) {
83 return previous; 84 return previous;
84 } 85 }
85 86
86 if (previous) 87 if (previous)
87 previous->Hide(); 88 previous->Hide();
88 89
89 return new AutofillPopupControllerImpl( 90 AutofillPopupControllerImpl* controller =
90 delegate, container_view, element_bounds); 91 new AutofillPopupControllerImpl(delegate, container_view, element_bounds);
92 return controller->GetWeakPtr();
91 } 93 }
92 94
93 AutofillPopupControllerImpl::AutofillPopupControllerImpl( 95 AutofillPopupControllerImpl::AutofillPopupControllerImpl(
94 AutofillPopupDelegate* delegate, 96 AutofillPopupDelegate* delegate,
95 gfx::NativeView container_view, 97 gfx::NativeView container_view,
96 const gfx::Rect& element_bounds) 98 const gfx::Rect& element_bounds)
97 : view_(NULL), 99 : view_(NULL),
98 delegate_(delegate), 100 delegate_(delegate),
99 container_view_(container_view), 101 container_view_(container_view),
100 element_bounds_(element_bounds), 102 element_bounds_(element_bounds),
101 selected_line_(kNoSelection), 103 selected_line_(kNoSelection),
102 delete_icon_hovered_(false), 104 delete_icon_hovered_(false),
103 is_hiding_(false), 105 is_hiding_(false),
104 inform_delegate_of_destruction_(true) { 106 weak_ptr_factory_(this) {
105 #if !defined(OS_ANDROID) 107 #if !defined(OS_ANDROID)
106 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta); 108 subtext_font_ = name_font_.DeriveFont(kLabelFontSizeDelta);
107 #endif 109 #endif
108 } 110 }
109 111
110 AutofillPopupControllerImpl::~AutofillPopupControllerImpl() { 112 AutofillPopupControllerImpl::~AutofillPopupControllerImpl() {}
111 if (inform_delegate_of_destruction_)
112 delegate_->ControllerDestroyed();
113 }
114 113
115 void AutofillPopupControllerImpl::Show( 114 void AutofillPopupControllerImpl::Show(
116 const std::vector<string16>& names, 115 const std::vector<string16>& names,
117 const std::vector<string16>& subtexts, 116 const std::vector<string16>& subtexts,
118 const std::vector<string16>& icons, 117 const std::vector<string16>& icons,
119 const std::vector<int>& identifiers) { 118 const std::vector<int>& identifiers) {
120 names_ = names; 119 names_ = names;
121 full_names_ = names; 120 full_names_ = names;
122 subtexts_ = subtexts; 121 subtexts_ = subtexts;
123 icons_ = icons; 122 icons_ = icons;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 ui::ELIDE_AT_END); 156 ui::ELIDE_AT_END);
158 } 157 }
159 #endif 158 #endif
160 159
161 if (!view_) { 160 if (!view_) {
162 view_ = AutofillPopupView::Create(this); 161 view_ = AutofillPopupView::Create(this);
163 ShowView(); 162 ShowView();
164 } else { 163 } else {
165 UpdateBoundsAndRedrawPopup(); 164 UpdateBoundsAndRedrawPopup();
166 } 165 }
166
167 delegate_->OnPopupShown(this);
167 } 168 }
168 169
169 void AutofillPopupControllerImpl::Hide() { 170 void AutofillPopupControllerImpl::Hide() {
170 inform_delegate_of_destruction_ = false; 171 if (is_hiding_)
171 HideInternal(); 172 return;
173 is_hiding_ = true;
174
175 SetSelectedLine(kNoSelection);
176
177 delegate_->OnPopupHidden(this);
178
179 if (view_)
180 view_->Hide();
181 else
182 delete this;
172 } 183 }
173 184
174 bool AutofillPopupControllerImpl::HandleKeyPressEvent( 185 bool AutofillPopupControllerImpl::HandleKeyPressEvent(
175 const content::NativeWebKeyboardEvent& event) { 186 const content::NativeWebKeyboardEvent& event) {
176 switch (event.windowsKeyCode) { 187 switch (event.windowsKeyCode) {
177 case ui::VKEY_UP: 188 case ui::VKEY_UP:
178 SelectPreviousLine(); 189 SelectPreviousLine();
179 return true; 190 return true;
180 case ui::VKEY_DOWN: 191 case ui::VKEY_DOWN:
181 SelectNextLine(); 192 SelectNextLine();
182 return true; 193 return true;
183 case ui::VKEY_PRIOR: // Page up. 194 case ui::VKEY_PRIOR: // Page up.
184 SetSelectedLine(0); 195 SetSelectedLine(0);
185 return true; 196 return true;
186 case ui::VKEY_NEXT: // Page down. 197 case ui::VKEY_NEXT: // Page down.
187 SetSelectedLine(names().size() - 1); 198 SetSelectedLine(names().size() - 1);
188 return true; 199 return true;
189 case ui::VKEY_ESCAPE: 200 case ui::VKEY_ESCAPE:
190 HideInternal(); 201 Hide();
191 return true; 202 return true;
192 case ui::VKEY_DELETE: 203 case ui::VKEY_DELETE:
193 return (event.modifiers & content::NativeWebKeyboardEvent::ShiftKey) && 204 return (event.modifiers & content::NativeWebKeyboardEvent::ShiftKey) &&
194 RemoveSelectedLine(); 205 RemoveSelectedLine();
195 case ui::VKEY_RETURN: 206 case ui::VKEY_RETURN:
196 return AcceptSelectedLine(); 207 return AcceptSelectedLine();
197 default: 208 default:
198 return false; 209 return false;
199 } 210 }
200 } 211 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 #endif 329 #endif
319 330
320 int AutofillPopupControllerImpl::selected_line() const { 331 int AutofillPopupControllerImpl::selected_line() const {
321 return selected_line_; 332 return selected_line_;
322 } 333 }
323 334
324 bool AutofillPopupControllerImpl::delete_icon_hovered() const { 335 bool AutofillPopupControllerImpl::delete_icon_hovered() const {
325 return delete_icon_hovered_; 336 return delete_icon_hovered_;
326 } 337 }
327 338
328 void AutofillPopupControllerImpl::HideInternal() {
329 if (is_hiding_)
330 return;
331 is_hiding_ = true;
332
333 SetSelectedLine(kNoSelection);
334
335 if (view_)
336 view_->Hide();
337 else
338 delete this;
339 }
340
341 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) { 339 void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) {
342 if (selected_line_ == selected_line) 340 if (selected_line_ == selected_line)
343 return; 341 return;
344 342
345 if (selected_line_ != kNoSelection) 343 if (selected_line_ != kNoSelection)
346 InvalidateRow(selected_line_); 344 InvalidateRow(selected_line_);
347 345
348 if (selected_line != kNoSelection) 346 if (selected_line != kNoSelection)
349 InvalidateRow(selected_line); 347 InvalidateRow(selected_line);
350 348
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 subtexts_.erase(subtexts_.begin() + selected_line_); 417 subtexts_.erase(subtexts_.begin() + selected_line_);
420 icons_.erase(icons_.begin() + selected_line_); 418 icons_.erase(icons_.begin() + selected_line_);
421 identifiers_.erase(identifiers_.begin() + selected_line_); 419 identifiers_.erase(identifiers_.begin() + selected_line_);
422 420
423 SetSelectedLine(kNoSelection); 421 SetSelectedLine(kNoSelection);
424 422
425 if (HasSuggestions()) { 423 if (HasSuggestions()) {
426 delegate_->ClearPreviewedForm(); 424 delegate_->ClearPreviewedForm();
427 UpdateBoundsAndRedrawPopup(); 425 UpdateBoundsAndRedrawPopup();
428 } else { 426 } else {
429 HideInternal(); 427 Hide();
430 } 428 }
431 429
432 return true; 430 return true;
433 } 431 }
434 432
435 int AutofillPopupControllerImpl::LineFromY(int y) { 433 int AutofillPopupControllerImpl::LineFromY(int y) {
436 int current_height = 0; 434 int current_height = 0;
437 435
438 for (size_t i = 0; i < identifiers().size(); ++i) { 436 for (size_t i = 0; i < identifiers().size(); ++i) {
439 current_height += GetRowHeightFromId(identifiers()[i]); 437 current_height += GetRowHeightFromId(identifiers()[i]);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { 519 int AutofillPopupControllerImpl::GetDesiredPopupHeight() const {
522 int popup_height = 0; 520 int popup_height = 0;
523 521
524 for (size_t i = 0; i < identifiers().size(); ++i) { 522 for (size_t i = 0; i < identifiers().size(); ++i) {
525 popup_height += GetRowHeightFromId(identifiers()[i]); 523 popup_height += GetRowHeightFromId(identifiers()[i]);
526 } 524 }
527 525
528 return popup_height; 526 return popup_height;
529 } 527 }
530 528
529 WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() {
530 return weak_ptr_factory_.GetWeakPtr();
531 }
532
531 int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const { 533 int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const {
532 int row_size = kEndPadding + kNamePadding; 534 int row_size = kEndPadding + kNamePadding;
533 535
534 // Add the Autofill icon size, if required. 536 // Add the Autofill icon size, if required.
535 if (!icons_[row].empty()) 537 if (!icons_[row].empty())
536 row_size += kAutofillIconWidth + kIconPadding; 538 row_size += kAutofillIconWidth + kIconPadding;
537 539
538 // Add the delete icon size, if required. 540 // Add the delete icon size, if required.
539 if (CanDelete(row)) 541 if (CanDelete(row))
540 row_size += kDeleteIconWidth + kIconPadding; 542 row_size += kDeleteIconWidth + kIconPadding;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 if (bottom_available >= popup_required_height || 645 if (bottom_available >= popup_required_height ||
644 bottom_available >= top_available) { 646 bottom_available >= top_available) {
645 // The popup can appear below the field. 647 // The popup can appear below the field.
646 return std::make_pair(bottom_growth_start, popup_required_height); 648 return std::make_pair(bottom_growth_start, popup_required_height);
647 } else { 649 } else {
648 // The popup must appear above the field. 650 // The popup must appear above the field.
649 return std::make_pair(top_growth_end - popup_required_height, 651 return std::make_pair(top_growth_end - popup_required_height,
650 popup_required_height); 652 popup_required_height);
651 } 653 }
652 } 654 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698