12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/autofill/autofill_popup_view.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/autofill/popup_constants.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_popup_delegate.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/autofill/core/browser/popup_item_ids.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "grit/components_scaled_resources.h"
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/text_elider.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector2d.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::WeakPtr;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to indicate that no line is currently selected by the user.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNoSelection = -1;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The vertical height of each row in pixels.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kRowHeight = 24;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The vertical height of a separator in pixels.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kSeparatorHeight = 1;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Size difference between name and subtext in pixels.
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const int kLabelFontSizeDelta = -2;
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const size_t kNamePadding = AutofillPopupView::kNamePadding;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kIconPadding = AutofillPopupView::kIconPadding;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kEndPadding = AutofillPopupView::kEndPadding;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DataResource {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* name;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const DataResource kDataResources[] = {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "americanExpressCC", IDR_AUTOFILL_CC_AMEX },
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "dinersCC", IDR_AUTOFILL_CC_DINERS },
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "discoverCC", IDR_AUTOFILL_CC_DISCOVER },
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "genericCC", IDR_AUTOFILL_CC_GENERIC },
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "jcbCC", IDR_AUTOFILL_CC_JCB },
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD },
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "visaCC", IDR_AUTOFILL_CC_VISA },
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS)
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  { "macContactsIcon", IDR_AUTOFILL_MAC_CONTACTS_ICON },
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetOrCreate(
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WeakPtr<AutofillPopupControllerImpl> previous,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WeakPtr<AutofillPopupDelegate> delegate,
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    content::WebContents* web_contents,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::NativeView container_view,
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const gfx::RectF& element_bounds,
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::i18n::TextDirection text_direction) {
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!previous.get() || previous->delegate_.get() == delegate.get());
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (previous.get() && previous->web_contents() == web_contents &&
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      previous->container_view() == container_view &&
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      previous->element_bounds() == element_bounds) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    previous->ClearState();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return previous;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (previous.get())
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    previous->Hide();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AutofillPopupControllerImpl* controller =
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new AutofillPopupControllerImpl(
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          delegate, web_contents, container_view, element_bounds,
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          text_direction);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return controller->GetWeakPtr();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AutofillPopupControllerImpl::AutofillPopupControllerImpl(
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::WeakPtr<AutofillPopupDelegate> delegate,
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    content::WebContents* web_contents,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::NativeView container_view,
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const gfx::RectF& element_bounds,
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::i18n::TextDirection text_direction)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : controller_common_(new PopupControllerCommon(element_bounds,
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   container_view,
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   web_contents)),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      view_(NULL),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_(delegate),
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      text_direction_(text_direction),
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_ptr_factory_(this) {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ClearState();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller_common_->SetKeyPressCallback(
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&AutofillPopupControllerImpl::HandleKeyPressEvent,
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  subtext_font_list_ = name_font_list_.DeriveWithSizeDelta(kLabelFontSizeDelta);
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_MACOSX)
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // There is no italic version of the system font.
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  warning_font_list_ = name_font_list_;
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  warning_font_list_ = name_font_list_.DeriveWithStyle(gfx::Font::ITALIC);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AutofillPopupControllerImpl::~AutofillPopupControllerImpl() {}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::Show(
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& names,
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& subtexts,
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& icons,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<int>& identifiers) {
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetValues(names, subtexts, icons, identifiers);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Android displays the long text with ellipsis using the view attributes.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdatePopupBounds();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int popup_width = popup_bounds().width();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Elide the name and subtext strings so that the popup fits in the available
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space.
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < names_.size(); ++i) {
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int name_width = gfx::GetStringWidth(names_[i], GetNameFontListForRow(i));
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int subtext_width = gfx::GetStringWidth(subtexts_[i], subtext_font_list());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int total_text_length = name_width + subtext_width;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The line can have no strings if it represents a UI element, such as
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // a separator line.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (total_text_length == 0)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int available_width = popup_width - RowWidthWithoutText(i);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Each field receives space in proportion to its length.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int name_size = available_width * name_width / total_text_length;
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    names_[i] = gfx::ElideText(names_[i], GetNameFontListForRow(i),
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               name_size, gfx::ELIDE_TAIL);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int subtext_size = available_width * subtext_width / total_text_length;
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    subtexts_[i] = gfx::ElideText(subtexts_[i], subtext_font_list(),
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  subtext_size, gfx::ELIDE_TAIL);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!view_) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view_ = AutofillPopupView::Create(this);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // It is possible to fail to create the popup, in this case
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // treat the popup as hiding right away.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!view_) {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Hide();
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShowView();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateBoundsAndRedrawPopup();
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller_common_->RegisterKeyPressCallback();
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  delegate_->OnPopupShown();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AutofillPopupControllerImpl::UpdateDataListValues(
184ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const std::vector<base::string16>& values,
185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const std::vector<base::string16>& labels) {
186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Remove all the old data list values, which should always be at the top of
187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // the list if they are present.
188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  while (!identifiers_.empty() &&
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         identifiers_[0] == POPUP_ITEM_ID_DATALIST_ENTRY) {
190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    names_.erase(names_.begin());
191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    subtexts_.erase(subtexts_.begin());
192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    icons_.erase(icons_.begin());
193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    identifiers_.erase(identifiers_.begin());
194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // If there are no new data list values, exit (clearing the separator if there
197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // is one).
198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (values.empty()) {
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!identifiers_.empty() && identifiers_[0] == POPUP_ITEM_ID_SEPARATOR) {
200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      names_.erase(names_.begin());
201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      subtexts_.erase(subtexts_.begin());
202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      icons_.erase(icons_.begin());
203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      identifiers_.erase(identifiers_.begin());
204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch     // The popup contents have changed, so either update the bounds or hide it.
207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (HasSuggestions())
208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      UpdateBoundsAndRedrawPopup();
209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    else
210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      Hide();
211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Add a separator if there are any other values.
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!identifiers_.empty() && identifiers_[0] != POPUP_ITEM_ID_SEPARATOR) {
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    names_.insert(names_.begin(), base::string16());
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    subtexts_.insert(subtexts_.begin(), base::string16());
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    icons_.insert(icons_.begin(), base::string16());
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    identifiers_.insert(identifiers_.begin(), POPUP_ITEM_ID_SEPARATOR);
221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  names_.insert(names_.begin(), values.begin(), values.end());
225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  subtexts_.insert(subtexts_.begin(), labels.begin(), labels.end());
226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Add the values that are the same for all data list elements.
228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  icons_.insert(icons_.begin(), values.size(), base::string16());
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  identifiers_.insert(
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      identifiers_.begin(), values.size(), POPUP_ITEM_ID_DATALIST_ENTRY);
231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UpdateBoundsAndRedrawPopup();
233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::Hide() {
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller_common_->RemoveKeyPressCallback();
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (delegate_)
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    delegate_->OnPopupHidden();
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (view_)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view_->Hide();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete this;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::ViewDestroyed() {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The view has already been destroyed so clear the reference to it.
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view_ = NULL;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Hide();
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AutofillPopupControllerImpl::HandleKeyPressEvent(
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NativeWebKeyboardEvent& event) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (event.windowsKeyCode) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_UP:
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SelectPreviousLine();
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_DOWN:
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SelectNextLine();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_PRIOR:  // Page up.
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetSelectedLine(0);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_NEXT:  // Page down.
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetSelectedLine(names().size() - 1);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_ESCAPE:
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Hide();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_DELETE:
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return (event.modifiers & content::NativeWebKeyboardEvent::ShiftKey) &&
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             RemoveSelectedLine();
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case ui::VKEY_TAB:
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // A tab press should cause the selected line to be accepted, but still
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // return false so the tab key press propagates and changes the cursor
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // location.
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AcceptSelectedLine();
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::VKEY_RETURN:
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AcceptSelectedLine();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::UpdateBoundsAndRedrawPopup() {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(csharp): Since UpdatePopupBounds can change the position of the popup,
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the popup could end up jumping from above the element to below it.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It is unclear if it is better to keep the popup where it was, or if it
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // should try and move to its desired position.
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdatePopupBounds();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view_->UpdateBoundsAndRedrawPopup();
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutofillPopupControllerImpl::SetSelectionAtPoint(const gfx::Point& point) {
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetSelectedLine(LineFromY(point.y()));
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool AutofillPopupControllerImpl::AcceptSelectedLine() {
304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (selected_line_ == kNoSelection)
305effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_GE(selected_line_, 0);
308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_LT(selected_line_, static_cast<int>(names_.size()));
309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!CanAccept(identifiers_[selected_line_]))
311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
313effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AcceptSuggestion(selected_line_);
314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return true;
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutofillPopupControllerImpl::SelectionCleared() {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSelectedLine(kNoSelection);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::AcceptSuggestion(size_t index) {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_->DidAcceptSuggestion(full_names_[index], identifiers_[index]);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::GetIconResourceID(
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& resource_name) const {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDataResources); ++i) {
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (resource_name == base::ASCIIToUTF16(kDataResources[i].name))
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kDataResources[i].id;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return -1;
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AutofillPopupControllerImpl::CanDelete(size_t index) const {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(isherman): Native AddressBook suggestions on Mac and Android should
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not be considered to be deleteable.
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id = identifiers_[index];
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return id > 0 || id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY ||
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         id == POPUP_ITEM_ID_PASSWORD_ENTRY;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool AutofillPopupControllerImpl::IsWarning(size_t index) const {
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return identifiers_[index] == POPUP_ITEM_ID_WARNING_MESSAGE;
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect AutofillPopupControllerImpl::GetRowBounds(size_t index) {
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int top = kPopupBorderThickness;
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < index; ++i) {
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    top += GetRowHeightFromId(identifiers()[i]);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Rect(
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kPopupBorderThickness,
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      top,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      popup_bounds_.width() - 2 * kPopupBorderThickness,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetRowHeightFromId(identifiers()[index]));
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::SetPopupBounds(const gfx::Rect& bounds) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  popup_bounds_ = bounds;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateBoundsAndRedrawPopup();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::Rect& AutofillPopupControllerImpl::popup_bounds() const {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return popup_bounds_;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::WebContents* AutofillPopupControllerImpl::web_contents() {
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return controller_common_->web_contents();
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::NativeView AutofillPopupControllerImpl::container_view() {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return controller_common_->container_view();
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::RectF& AutofillPopupControllerImpl::element_bounds() const {
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return controller_common_->element_bounds();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool AutofillPopupControllerImpl::IsRTL() const {
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return text_direction_ == base::i18n::RIGHT_TO_LEFT;
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::vector<base::string16>& AutofillPopupControllerImpl::names() const {
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return names_;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::vector<base::string16>& AutofillPopupControllerImpl::subtexts()
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return subtexts_;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::vector<base::string16>& AutofillPopupControllerImpl::icons() const {
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return icons_;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::vector<int>& AutofillPopupControllerImpl::identifiers() const {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return identifiers_;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const gfx::FontList& AutofillPopupControllerImpl::GetNameFontListForRow(
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t index) const {
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (identifiers_[index] == POPUP_ITEM_ID_WARNING_MESSAGE)
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return warning_font_list_;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return name_font_list_;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const gfx::FontList& AutofillPopupControllerImpl::subtext_font_list() const {
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return subtext_font_list_;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::selected_line() const {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return selected_line_;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (selected_line_ == selected_line)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (selected_line_ != kNoSelection &&
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<size_t>(selected_line_) < identifiers_.size())
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InvalidateRow(selected_line_);
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (selected_line != kNoSelection)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InvalidateRow(selected_line);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  selected_line_ = selected_line;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (selected_line_ != kNoSelection) {
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_->DidSelectSuggestion(names_[selected_line_],
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   identifiers_[selected_line_]);
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->ClearPreviewedForm();
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::SelectNextLine() {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int new_selected_line = selected_line_ + 1;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skip over any lines that can't be selected.
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (static_cast<size_t>(new_selected_line) < names_.size() &&
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         !CanAccept(identifiers()[new_selected_line])) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++new_selected_line;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (new_selected_line >= static_cast<int>(names_.size()))
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_selected_line = 0;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSelectedLine(new_selected_line);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::SelectPreviousLine() {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int new_selected_line = selected_line_ - 1;
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skip over any lines that can't be selected.
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (new_selected_line > kNoSelection &&
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         !CanAccept(identifiers()[new_selected_line])) {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    --new_selected_line;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_selected_line <= kNoSelection)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_selected_line = names_.size() - 1;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSelectedLine(new_selected_line);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AutofillPopupControllerImpl::RemoveSelectedLine() {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (selected_line_ == kNoSelection)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(selected_line_, 0);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(selected_line_, static_cast<int>(names_.size()));
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CanDelete(selected_line_))
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_->RemoveSuggestion(full_names_[selected_line_],
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              identifiers_[selected_line_]);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the deleted element.
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  names_.erase(names_.begin() + selected_line_);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  full_names_.erase(full_names_.begin() + selected_line_);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  subtexts_.erase(subtexts_.begin() + selected_line_);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icons_.erase(icons_.begin() + selected_line_);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  identifiers_.erase(identifiers_.begin() + selected_line_);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSelectedLine(kNoSelection);
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HasSuggestions()) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate_->ClearPreviewedForm();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateBoundsAndRedrawPopup();
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Hide();
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::LineFromY(int y) {
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int current_height = kPopupBorderThickness;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < identifiers().size(); ++i) {
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_height += GetRowHeightFromId(identifiers()[i]);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (y <= current_height)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return i;
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The y value goes beyond the popup so stop the selection at the last line.
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return identifiers().size() - 1;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::GetRowHeightFromId(int identifier) const {
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (identifier == POPUP_ITEM_ID_SEPARATOR)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kSeparatorHeight;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kRowHeight;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AutofillPopupControllerImpl::CanAccept(int id) {
525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return id != POPUP_ITEM_ID_SEPARATOR && id != POPUP_ITEM_ID_WARNING_MESSAGE;
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AutofillPopupControllerImpl::HasSuggestions() {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return identifiers_.size() != 0 &&
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         (identifiers_[0] > 0 ||
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          identifiers_[0] == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY ||
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          identifiers_[0] == POPUP_ITEM_ID_PASSWORD_ENTRY ||
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          identifiers_[0] == POPUP_ITEM_ID_DATALIST_ENTRY ||
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          identifiers_[0] == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutofillPopupControllerImpl::SetValues(
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& names,
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& subtexts,
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<base::string16>& icons,
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::vector<int>& identifiers) {
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  names_ = names;
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  full_names_ = names;
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  subtexts_ = subtexts;
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  icons_ = icons;
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  identifiers_ = identifiers;
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::ShowView() {
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view_->Show();
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::InvalidateRow(size_t row) {
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(0 <= row);
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(row < identifiers_.size());
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view_->InvalidateRow(row);
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::GetDesiredPopupWidth() const {
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int popup_width = controller_common_->RoundedElementBounds().width();
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(names().size(), subtexts().size());
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < names().size(); ++i) {
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int row_size =
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::GetStringWidth(names()[i], name_font_list_) +
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::GetStringWidth(subtexts()[i], subtext_font_list_) +
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        RowWidthWithoutText(i);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    popup_width = std::max(popup_width, row_size);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return popup_width;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::GetDesiredPopupHeight() const {
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int popup_height = 2 * kPopupBorderThickness;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < identifiers().size(); ++i) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    popup_height += GetRowHeightFromId(identifiers()[i]);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return popup_height;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const {
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int row_size = kEndPadding;
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!subtexts_[row].empty())
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    row_size += kNamePadding;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add the Autofill icon size, if required.
5920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!icons_[row].empty()) {
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int icon_width = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
5940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GetIconResourceID(icons_[row])).Width();
5950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    row_size += icon_width + kIconPadding;
5960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Add the padding at the end.
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  row_size += kEndPadding;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Add room for the popup border.
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  row_size += 2 * kPopupBorderThickness;
6031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return row_size;
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutofillPopupControllerImpl::UpdatePopupBounds() {
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int popup_width = GetDesiredPopupWidth();
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int popup_height = GetDesiredPopupHeight();
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
611116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  popup_bounds_ = controller_common_->GetPopupBounds(popup_width,
612116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                     popup_height);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(OS_ANDROID)
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() {
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutofillPopupControllerImpl::ClearState() {
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Don't clear view_, because otherwise the popup will have to get regenerated
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and this will cause flickering.
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  popup_bounds_ = gfx::Rect();
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  names_.clear();
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  subtexts_.clear();
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  icons_.clear();
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  identifiers_.clear();
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  full_names_.clear();
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  selected_line_ = kNoSelection;
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace autofill
636