| Index: components/autofill/core/browser/address_combobox_model.cc
|
| diff --git a/components/autofill/core/browser/address_combobox_model.cc b/components/autofill/core/browser/address_combobox_model.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..21559089ec834a60f12d123e1d67d33713cea7ba
|
| --- /dev/null
|
| +++ b/components/autofill/core/browser/address_combobox_model.cc
|
| @@ -0,0 +1,130 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/autofill/core/browser/address_combobox_model.h"
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "components/autofill/core/browser/autofill_profile.h"
|
| +#include "components/autofill/core/browser/personal_data_manager.h"
|
| +#include "components/strings/grit/components_strings.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/models/combobox_model_observer.h"
|
| +#include "ui/gfx/text_elider.h"
|
| +
|
| +namespace autofill {
|
| +
|
| +namespace {
|
| +// There's one header entry to prompt the user to select an address, and a
|
| +// separator.
|
| +int kNbHeaderEntries = 2;
|
| +} // namespace
|
| +
|
| +AddressComboboxModel::AddressComboboxModel(
|
| + const PersonalDataManager& personal_data_manager,
|
| + const std::string& app_locale)
|
| + : app_locale_(app_locale) {
|
| + for (const auto* profile : personal_data_manager.GetProfilesToSuggest()) {
|
| + profiles_cache_.push_back(base::MakeUnique<AutofillProfile>(*profile));
|
| + }
|
| + UpdateAddresses();
|
| +}
|
| +
|
| +AddressComboboxModel::~AddressComboboxModel() {}
|
| +
|
| +int AddressComboboxModel::GetItemCount() const {
|
| + // When there are not addresses, a special entry is shown to prompt the user
|
| + // to add addresses, but nothing else is shown, since there are no address to
|
| + // select from, and no need for a separator.
|
| + if (addresses_.size() == 0)
|
| + return 1;
|
| + // If there are addresses to choose from, but none is selected, add extra
|
| + // items for the "Select" entry and a separator.
|
| + return addresses_.size() + kNbHeaderEntries;
|
| +}
|
| +
|
| +base::string16 AddressComboboxModel::GetItemAt(int index) {
|
| + DCHECK_GE(index, 0);
|
| + // A special entry is always added at index 0 and a separator at index 1.
|
| + DCHECK_LT(static_cast<size_t>(index), addresses_.size() + kNbHeaderEntries);
|
| +
|
| + // Special entry when no profiles have been created yet.
|
| + if (addresses_.empty())
|
| + return l10n_util::GetStringUTF16(IDS_AUTOFILL_ADD_BILLING_ADDRESS);
|
| +
|
| + // Always show the "Select" entry at the top, default selection position.
|
| + if (index == 0)
|
| + return l10n_util::GetStringUTF16(IDS_AUTOFILL_SELECT);
|
| +
|
| + // Always show the "Select" entry at the top, default selection position.
|
| + if (index == 1)
|
| + return base::ASCIIToUTF16("---");
|
| +
|
| + return addresses_[index - kNbHeaderEntries].second;
|
| +}
|
| +
|
| +bool AddressComboboxModel::IsItemSeparatorAt(int index) {
|
| + // The only separator is between the "Select" entry at 0 and the first address
|
| + // at index 2. So there must be at least one address for a separator to be
|
| + // shown.
|
| + DCHECK(index <= kNbHeaderEntries || !addresses_.empty());
|
| + return index == 1;
|
| +}
|
| +
|
| +void AddressComboboxModel::AddObserver(ui::ComboboxModelObserver* observer) {
|
| + observers_.AddObserver(observer);
|
| +}
|
| +
|
| +void AddressComboboxModel::RemoveObserver(ui::ComboboxModelObserver* observer) {
|
| + observers_.RemoveObserver(observer);
|
| +}
|
| +
|
| +int AddressComboboxModel::AddNewProfile(const AutofillProfile& profile) {
|
| + profiles_cache_.push_back(base::MakeUnique<AutofillProfile>(profile));
|
| + UpdateAddresses();
|
| + DCHECK_GT(addresses_.size(), 0UL);
|
| + return addresses_.size() + kNbHeaderEntries - 1;
|
| +}
|
| +
|
| +std::string AddressComboboxModel::GetItemIdentifierAt(int index) {
|
| + // The first two indices are special entries, with no addresses.
|
| + if (index < kNbHeaderEntries)
|
| + return std::string();
|
| + DCHECK_LT(static_cast<size_t>(index), addresses_.size() + kNbHeaderEntries);
|
| + return addresses_[index - kNbHeaderEntries].first;
|
| +}
|
| +
|
| +int AddressComboboxModel::GetIndexOfIdentifier(const std::string& identifier) {
|
| + for (size_t i = 0; i < addresses_.size(); ++i) {
|
| + if (addresses_[i].first == identifier)
|
| + return i + kNbHeaderEntries;
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +void AddressComboboxModel::UpdateAddresses() {
|
| + addresses_.clear();
|
| + std::vector<base::string16> labels;
|
| + // CreateDifferentiatingLabels is expecting a pointer vector and we keep
|
| + // profiles as unique_ptr.
|
| + std::vector<AutofillProfile*> profiles;
|
| + for (const auto& profile : profiles_cache_) {
|
| + profiles.push_back(profile.get());
|
| + }
|
| + AutofillProfile::CreateDifferentiatingLabels(profiles, app_locale_, &labels);
|
| + DCHECK_EQ(labels.size(), profiles_cache_.size());
|
| +
|
| + for (size_t i = 0; i < profiles_cache_.size(); ++i) {
|
| + // Skip showing auxiliary profiles (e.g. Mac Contacts).
|
| + if (profiles_cache_[i]->record_type() == AutofillProfile::AUXILIARY_PROFILE)
|
| + continue;
|
| +
|
| + addresses_.push_back(std::make_pair(profiles_cache_[i]->guid(), labels[i]));
|
| + }
|
| +
|
| + for (auto& observer : observers_) {
|
| + observer.OnComboboxModelChanged(this);
|
| + }
|
| +}
|
| +} // namespace autofill
|
|
|