| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "components/autofill/core/browser/region_combobox_model.h" | 5 #include "components/autofill/core/browser/region_combobox_model.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "components/strings/grit/components_strings.h" | 12 #include "components/strings/grit/components_strings.h" |
| 13 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_dat
a.h" | 13 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_dat
a.h" |
| 14 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_dat
a_builder.h" | 14 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_dat
a_builder.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
| 16 #include "ui/base/models/combobox_model_observer.h" | 16 #include "ui/base/models/combobox_model_observer.h" |
| 17 | 17 |
| 18 namespace autofill { | 18 namespace autofill { |
| 19 | 19 |
| 20 RegionComboboxModel::RegionComboboxModel( | 20 RegionComboboxModel::RegionComboboxModel( |
| 21 std::unique_ptr<const ::i18n::addressinput::Source> source, | 21 std::unique_ptr<const ::i18n::addressinput::Source> source, |
| 22 std::unique_ptr<::i18n::addressinput::Storage> storage, | 22 std::unique_ptr<::i18n::addressinput::Storage> storage, |
| 23 const std::string& app_locale, | 23 const std::string& app_locale, |
| 24 const std::string& country_code) | 24 const std::string& country_code) |
| 25 : app_locale_(app_locale), | 25 : failed_to_load_data_(false), |
| 26 pending_region_data_load_(false), |
| 27 app_locale_(app_locale), |
| 26 region_data_supplier_(source.release(), storage.release()) { | 28 region_data_supplier_(source.release(), storage.release()) { |
| 27 region_data_supplier_callback_.reset(::i18n::addressinput::BuildCallback( | 29 region_data_supplier_callback_.reset(::i18n::addressinput::BuildCallback( |
| 28 this, &RegionComboboxModel::RegionDataLoaded)); | 30 this, &RegionComboboxModel::RegionDataLoaded)); |
| 29 region_data_supplier_.LoadRules(country_code, | 31 LoadRegionData(country_code); |
| 30 *region_data_supplier_callback_.get()); | |
| 31 } | 32 } |
| 32 | 33 |
| 33 RegionComboboxModel::~RegionComboboxModel() {} | 34 RegionComboboxModel::~RegionComboboxModel() {} |
| 34 | 35 |
| 35 int RegionComboboxModel::GetItemCount() const { | 36 int RegionComboboxModel::GetItemCount() const { |
| 36 // The combobox view needs to always have at least one item. If the regions | 37 // The combobox view needs to always have at least one item. If the regions |
| 37 // have not been completely loaded yet, we display a single "loading" item. | 38 // have not been completely loaded yet, we display a single "loading" item. |
| 38 // But if we failed to load, we return 0 so that the view can be identified | 39 if (regions_.size() == 0) |
| 39 // as empty and potentially replaced by another view during ReLayout. | |
| 40 if (regions_.size() == 0 && !failed_to_load_data_) | |
| 41 return 1; | 40 return 1; |
| 42 return regions_.size(); | 41 return regions_.size(); |
| 43 } | 42 } |
| 44 | 43 |
| 45 base::string16 RegionComboboxModel::GetItemAt(int index) { | 44 base::string16 RegionComboboxModel::GetItemAt(int index) { |
| 46 DCHECK_GE(index, 0); | 45 DCHECK_GE(index, 0); |
| 47 // This might happen because of the asynchonous nature of the data. | 46 // This might happen because of the asynchonous nature of the data. |
| 48 if (static_cast<size_t>(index) >= regions_.size()) | 47 if (static_cast<size_t>(index) >= regions_.size()) |
| 49 return l10n_util::GetStringUTF16(IDS_AUTOFILL_LOADING_REGIONS); | 48 return l10n_util::GetStringUTF16(IDS_AUTOFILL_LOADING_REGIONS); |
| 50 | 49 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 65 } | 64 } |
| 66 | 65 |
| 67 void RegionComboboxModel::AddObserver(ui::ComboboxModelObserver* observer) { | 66 void RegionComboboxModel::AddObserver(ui::ComboboxModelObserver* observer) { |
| 68 observers_.AddObserver(observer); | 67 observers_.AddObserver(observer); |
| 69 } | 68 } |
| 70 | 69 |
| 71 void RegionComboboxModel::RemoveObserver(ui::ComboboxModelObserver* observer) { | 70 void RegionComboboxModel::RemoveObserver(ui::ComboboxModelObserver* observer) { |
| 72 observers_.RemoveObserver(observer); | 71 observers_.RemoveObserver(observer); |
| 73 } | 72 } |
| 74 | 73 |
| 74 void RegionComboboxModel::SetFailureModeForTests(bool failed_to_load_data) { |
| 75 failed_to_load_data_ = failed_to_load_data; |
| 76 for (auto& observer : observers_) { |
| 77 observer.OnComboboxModelChanged(this); |
| 78 } |
| 79 } |
| 80 |
| 81 void RegionComboboxModel::LoadRegionData(const std::string& country_code) { |
| 82 pending_region_data_load_ = true; |
| 83 region_data_supplier_.LoadRules(country_code, |
| 84 *region_data_supplier_callback_.get()); |
| 85 } |
| 86 |
| 75 void RegionComboboxModel::RegionDataLoaded(bool success, | 87 void RegionComboboxModel::RegionDataLoaded(bool success, |
| 76 const std::string& country_code, | 88 const std::string& country_code, |
| 77 int rule_count) { | 89 int rule_count) { |
| 90 pending_region_data_load_ = false; |
| 78 if (success) { | 91 if (success) { |
| 79 failed_to_load_data_ = false; | |
| 80 std::string best_region_tree_language_tag; | 92 std::string best_region_tree_language_tag; |
| 81 ::i18n::addressinput::RegionDataBuilder builder(®ion_data_supplier_); | 93 ::i18n::addressinput::RegionDataBuilder builder(®ion_data_supplier_); |
| 82 const std::vector<const ::i18n::addressinput::RegionData*>& regions = | 94 const std::vector<const ::i18n::addressinput::RegionData*>& regions = |
| 83 builder.Build(country_code, app_locale_, &best_region_tree_language_tag) | 95 builder.Build(country_code, app_locale_, &best_region_tree_language_tag) |
| 84 .sub_regions(); | 96 .sub_regions(); |
| 85 for (auto* const region : regions) { | 97 // Some countries expose a state field but have not region names available. |
| 86 regions_.push_back(std::make_pair(region->key(), region->name())); | 98 if (regions.size() > 0) { |
| 99 failed_to_load_data_ = false; |
| 100 for (auto* const region : regions) { |
| 101 regions_.push_back(std::make_pair(region->key(), region->name())); |
| 102 } |
| 103 } else { |
| 104 failed_to_load_data_ = true; |
| 87 } | 105 } |
| 88 } else { | 106 } else { |
| 89 // TODO(mad): Maybe use a static list as is done for countries in | 107 // TODO(mad): Maybe use a static list as is done for countries in |
| 90 // components\autofill\core\browser\country_data.cc | 108 // components\autofill\core\browser\country_data.cc |
| 91 failed_to_load_data_ = true; | 109 failed_to_load_data_ = true; |
| 92 } | 110 } |
| 93 | 111 |
| 94 for (auto& observer : observers_) { | 112 for (auto& observer : observers_) { |
| 95 observer.OnComboboxModelChanged(this); | 113 observer.OnComboboxModelChanged(this); |
| 96 } | 114 } |
| 97 } | 115 } |
| 98 | 116 |
| 99 } // namespace autofill | 117 } // namespace autofill |
| OLD | NEW |