[go: nahoru, domu]

blob: 75b165993286ded73f83f9e8b3cc23d732ea4a07 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.h"
#import "base/apple/foundation_util.h"
#import "base/check.h"
#import "base/i18n/message_formatter.h"
#import "base/metrics/user_metrics.h"
#import "base/metrics/user_metrics_action.h"
#import "base/strings/sys_string_conversions.h"
#import "base/strings/utf_string_conversions.h"
#import "components/autofill/core/browser/personal_data_manager.h"
#import "components/autofill/core/browser/profile_requirement_utils.h"
#import "components/autofill/core/common/autofill_features.h"
#import "components/autofill/core/common/autofill_prefs.h"
#import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h"
#import "components/password_manager/core/common/password_manager_features.h"
#import "components/prefs/pref_service.h"
#import "components/strings/grit/components_strings.h"
#import "components/sync/base/features.h"
#import "components/sync/service/sync_user_settings.h"
#import "ios/chrome/browser/autofill/personal_data_manager_factory.h"
#import "ios/chrome/browser/net/crurl.h"
#import "ios/chrome/browser/shared/coordinator/alert/action_sheet_coordinator.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/shared/ui/symbols/symbols.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_detail_text_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_info_button_cell.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_info_button_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_cell.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_header_footer_item.h"
#import "ios/chrome/browser/shared/ui/table_view/table_view_model.h"
#import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
#import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/signin/authentication_service.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_constants.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_coordinator.h"
#import "ios/chrome/browser/ui/settings/autofill/cells/autofill_address_profile_source.h"
#import "ios/chrome/browser/ui/settings/autofill/cells/autofill_profile_item.h"
#import "ios/chrome/browser/ui/settings/elements/enterprise_info_popover_view_controller.h"
#import "ios/chrome/common/ui/colors/semantic_color_names.h"
#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
#import "ios/chrome/grit/ios_strings.h"
#import "net/base/mac/url_conversions.h"
#import "ui/base/l10n/l10n_util.h"
#import "ui/strings/grit/ui_strings.h"
namespace {
typedef NS_ENUM(NSInteger, SectionIdentifier) {
SectionIdentifierSwitches = kSectionIdentifierEnumZero,
SectionIdentifierProfiles,
};
typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeAutofillAddressSwitch = kItemTypeEnumZero,
ItemTypeAutofillAddressManaged,
ItemTypeAddress,
ItemTypeHeader,
ItemTypeFooter,
};
} // namespace
#pragma mark - AutofillProfileTableViewController
@interface AutofillProfileTableViewController () <
AutofillProfileEditCoordinatorDelegate,
PersonalDataManagerObserver,
PopoverLabelViewControllerDelegate> {
autofill::PersonalDataManager* _personalDataManager;
Browser* _browser;
std::unique_ptr<autofill::PersonalDataManagerObserverBridge> _observer;
// Deleting profiles updates PersonalDataManager resulting in an observer
// callback, which handles general data updates with a reloadData.
// It is better to handle user-initiated changes with more specific actions
// such as inserting or removing items/sections. This boolean is used to
// stop the observer callback from acting on user-initiated changes.
BOOL _deletionInProgress;
// Whether Settings have been dismissed.
BOOL _settingsAreDismissed;
}
@property(nonatomic, getter=isAutofillProfileEnabled)
BOOL autofillProfileEnabled;
// The account email of the signed-in user, or nil if there is no
// signed-in user.
@property(nonatomic, strong) NSString* userEmail;
// Default NO. YES, when the autofill syncing is enabled.
@property(nonatomic, assign, getter=isSyncEnabled) BOOL syncEnabled;
// Coordinator that managers a UIAlertController to delete addresses.
@property(nonatomic, strong) ActionSheetCoordinator* deletionSheetCoordinator;
// Coordinator to view/edit profile details.
@property(nonatomic, strong)
AutofillProfileEditCoordinator* autofillProfileEditCoordinator;
@end
@implementation AutofillProfileTableViewController
- (instancetype)initWithBrowser:(Browser*)browser {
DCHECK(browser);
self = [super initWithStyle:ChromeTableViewStyle()];
if (self) {
self.title = l10n_util::GetNSString(IDS_AUTOFILL_ADDRESSES_SETTINGS_TITLE);
self.shouldDisableDoneButtonOnEdit = YES;
_browser = browser;
_personalDataManager =
autofill::PersonalDataManagerFactory::GetForBrowserState(
_browser->GetBrowserState());
_observer.reset(new autofill::PersonalDataManagerObserverBridge(self));
_personalDataManager->AddObserver(_observer.get());
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.allowsMultipleSelectionDuringEditing = YES;
self.tableView.accessibilityIdentifier = kAutofillProfileTableViewID;
self.tableView.estimatedSectionFooterHeight =
kTableViewHeaderFooterViewHeight;
[self determineUserEmail];
[self updateUIForEditState];
[self loadModel];
}
- (void)loadModel {
[super loadModel];
if (_settingsAreDismissed)
return;
TableViewModel* model = self.tableViewModel;
[model addSectionWithIdentifier:SectionIdentifierSwitches];
if (_browser->GetBrowserState()->GetPrefs()->IsManagedPreference(
autofill::prefs::kAutofillProfileEnabled)) {
[model addItem:[self managedAddressItem]
toSectionWithIdentifier:SectionIdentifierSwitches];
} else {
[model addItem:[self addressSwitchItem]
toSectionWithIdentifier:SectionIdentifierSwitches];
}
[model setFooter:[self addressSwitchFooter]
forSectionWithIdentifier:SectionIdentifierSwitches];
[self populateProfileSection];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.toolbarHidden = NO;
}
#pragma mark - LoadModel Helpers
// Populates profile section using personalDataManager.
- (void)populateProfileSection {
if (_settingsAreDismissed)
return;
TableViewModel* model = self.tableViewModel;
const std::vector<autofill::AutofillProfile*> autofillProfiles =
_personalDataManager->GetProfilesForSettings();
if (!autofillProfiles.empty()) {
[model addSectionWithIdentifier:SectionIdentifierProfiles];
[model setHeader:[self profileSectionHeader]
forSectionWithIdentifier:SectionIdentifierProfiles];
for (autofill::AutofillProfile* autofillProfile : autofillProfiles) {
DCHECK(autofillProfile);
[model addItem:[self itemForProfile:*autofillProfile]
toSectionWithIdentifier:SectionIdentifierProfiles];
}
}
}
- (TableViewItem*)addressSwitchItem {
TableViewSwitchItem* switchItem =
[[TableViewSwitchItem alloc] initWithType:ItemTypeAutofillAddressSwitch];
switchItem.text =
l10n_util::GetNSString(IDS_AUTOFILL_ENABLE_PROFILES_TOGGLE_LABEL);
switchItem.on = [self isAutofillProfileEnabled];
switchItem.accessibilityIdentifier = kAutofillAddressSwitchViewId;
return switchItem;
}
- (TableViewInfoButtonItem*)managedAddressItem {
TableViewInfoButtonItem* managedAddressItem = [[TableViewInfoButtonItem alloc]
initWithType:ItemTypeAutofillAddressManaged];
managedAddressItem.text =
l10n_util::GetNSString(IDS_AUTOFILL_ENABLE_PROFILES_TOGGLE_LABEL);
// The status could only be off when the pref is managed.
managedAddressItem.statusText = l10n_util::GetNSString(IDS_IOS_SETTING_OFF);
managedAddressItem.accessibilityHint =
l10n_util::GetNSString(IDS_IOS_TOGGLE_SETTING_MANAGED_ACCESSIBILITY_HINT);
managedAddressItem.accessibilityIdentifier = kAutofillAddressManagedViewId;
return managedAddressItem;
}
- (TableViewHeaderFooterItem*)addressSwitchFooter {
TableViewLinkHeaderFooterItem* footer =
[[TableViewLinkHeaderFooterItem alloc] initWithType:ItemTypeFooter];
footer.text =
l10n_util::GetNSString(IDS_AUTOFILL_ENABLE_PROFILES_TOGGLE_SUBLABEL);
return footer;
}
- (TableViewHeaderFooterItem*)profileSectionHeader {
TableViewTextHeaderFooterItem* header =
[[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
header.text = l10n_util::GetNSString(IDS_AUTOFILL_ADDRESSES);
return header;
}
- (TableViewItem*)itemForProfile:
(const autofill::AutofillProfile&)autofillProfile {
assert(autofillProfile.record_type() ==
autofill::AutofillProfile::LOCAL_PROFILE);
std::string guid(autofillProfile.guid());
NSString* title = base::SysUTF16ToNSString(
autofillProfile.GetInfo(autofill::AutofillType(autofill::NAME_FULL),
GetApplicationContext()->GetApplicationLocale()));
NSString* subTitle = base::SysUTF16ToNSString(autofillProfile.GetInfo(
autofill::AutofillType(autofill::ADDRESS_HOME_LINE1),
GetApplicationContext()->GetApplicationLocale()));
AutofillProfileItem* item =
[[AutofillProfileItem alloc] initWithType:ItemTypeAddress];
item.title = title;
item.detailText = subTitle;
item.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
item.accessibilityIdentifier = title;
item.GUID = guid;
item.showMigrateToAccountButton = NO;
if (autofillProfile.source() == autofill::AutofillProfile::Source::kAccount) {
item.autofillProfileSource =
AutofillAddressProfileSource::AutofillAccountProfile;
} else if (self.syncEnabled) {
item.autofillProfileSource =
AutofillAddressProfileSource::AutofillSyncableProfile;
} else {
item.autofillProfileSource = AutofillLocalProfile;
if ([self shouldShowCloudOffIconForProfile:autofillProfile]) {
item.showMigrateToAccountButton = YES;
item.image = CustomSymbolTemplateWithPointSize(
kCloudSlashSymbol, kCloudSlashSymbolPointSize);
}
}
return item;
}
- (BOOL)localProfilesExist {
return !_settingsAreDismissed &&
!_personalDataManager->GetProfilesForSettings().empty();
}
#pragma mark - SettingsControllerProtocol
- (void)reportDismissalUserAction {
base::RecordAction(base::UserMetricsAction("MobileAddressesSettingsClose"));
}
- (void)reportBackUserAction {
base::RecordAction(base::UserMetricsAction("MobileAddressesSettingsBack"));
}
- (void)settingsWillBeDismissed {
DCHECK(!_settingsAreDismissed);
[self stopAutofillProfileEditCoordinator];
_personalDataManager->RemoveObserver(_observer.get());
[self dismissDeletionSheet];
// Remove observer bridges.
_observer.reset();
// Clear C++ ivars.
_personalDataManager = nullptr;
_browser = nullptr;
_settingsAreDismissed = YES;
}
#pragma mark - SettingsRootTableViewController
- (BOOL)editButtonEnabled {
return [self localProfilesExist];
}
- (BOOL)shouldHideToolbar {
// Hide the toolbar if the visible view controller is not the current view
// controller or the `deletionSheetCoordinator` is shown.
if (self.navigationController.visibleViewController == self) {
return NO;
} else if (self.deletionSheetCoordinator != nil) {
return ![self.deletionSheetCoordinator isVisible];
}
return YES;
}
- (BOOL)shouldShowEditDoneButton {
return NO;
}
- (void)updateUIForEditState {
[super updateUIForEditState];
[self setSwitchItemEnabled:!self.tableView.editing
itemType:ItemTypeAutofillAddressSwitch];
[self updatedToolbarForEditState];
}
// Override.
- (void)deleteItems:(NSArray<NSIndexPath*>*)indexPaths {
[self showDeletionConfirmationForIndexPaths:indexPaths];
}
#pragma mark - UITableViewDelegate
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (_settingsAreDismissed)
return;
[self updateUIForEditState];
}
- (void)tableView:(UITableView*)tableView
didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
if (_settingsAreDismissed)
return;
// Edit mode is the state where the user can select and delete entries. In
// edit mode, selection is handled by the superclass. When not in edit mode
// selection presents the editing controller for the selected entry.
if ([self.tableView isEditing]) {
self.deleteButton.enabled = YES;
return;
}
if (![self isItemTypeForIndexPathAddress:indexPath]) {
return;
}
AutofillProfileItem* item = base::apple::ObjCCastStrict<AutofillProfileItem>(
[self.tableViewModel itemAtIndexPath:indexPath]);
[self
showAddressProfileDetailsPageForProfile:_personalDataManager
->GetProfileByGUID(item.GUID)
withMigrateToAccountButton:item.showMigrateToAccountButton];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView*)tableView
didDeselectRowAtIndexPath:(NSIndexPath*)indexPath {
[super tableView:tableView didDeselectRowAtIndexPath:indexPath];
if (_settingsAreDismissed || !self.tableView.editing)
return;
if (self.tableView.indexPathsForSelectedRows.count == 0)
self.deleteButton.enabled = NO;
}
#pragma mark - Actions
// Called when the user clicks on the information button of the managed
// setting's UI. Shows a textual bubble with the information of the enterprise.
- (void)didTapManagedUIInfoButton:(UIButton*)buttonView {
if (_settingsAreDismissed)
return;
EnterpriseInfoPopoverViewController* bubbleViewController =
[[EnterpriseInfoPopoverViewController alloc] initWithEnterpriseName:nil];
bubbleViewController.delegate = self;
[self presentViewController:bubbleViewController animated:YES completion:nil];
// Disable the button when showing the bubble.
buttonView.enabled = NO;
// Set the anchor and arrow direction of the bubble.
bubbleViewController.popoverPresentationController.sourceView = buttonView;
bubbleViewController.popoverPresentationController.sourceRect =
buttonView.bounds;
bubbleViewController.popoverPresentationController.permittedArrowDirections =
UIPopoverArrowDirectionAny;
}
#pragma mark - UITableViewDataSource
- (BOOL)tableView:(UITableView*)tableView
canEditRowAtIndexPath:(NSIndexPath*)indexPath {
if (_settingsAreDismissed)
return NO;
// Only profile data cells are editable.
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
return [item isKindOfClass:[AutofillProfileItem class]];
}
- (void)tableView:(UITableView*)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath*)indexPath {
if (editingStyle != UITableViewCellEditingStyleDelete ||
_settingsAreDismissed)
return;
[self deleteItems:@[ indexPath ]];
}
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell* cell = [super tableView:tableView
cellForRowAtIndexPath:indexPath];
if (_settingsAreDismissed)
return cell;
switch (static_cast<ItemType>(
[self.tableViewModel itemTypeForIndexPath:indexPath])) {
case ItemTypeAddress:
case ItemTypeHeader:
case ItemTypeFooter:
break;
case ItemTypeAutofillAddressSwitch: {
TableViewSwitchCell* switchCell =
base::apple::ObjCCastStrict<TableViewSwitchCell>(cell);
[switchCell.switchView addTarget:self
action:@selector(autofillAddressSwitchChanged:)
forControlEvents:UIControlEventValueChanged];
break;
}
case ItemTypeAutofillAddressManaged: {
TableViewInfoButtonCell* managedCell =
base::apple::ObjCCastStrict<TableViewInfoButtonCell>(cell);
[managedCell.trailingButton
addTarget:self
action:@selector(didTapManagedUIInfoButton:)
forControlEvents:UIControlEventTouchUpInside];
break;
}
}
return cell;
}
#pragma mark - Switch Callbacks
- (void)autofillAddressSwitchChanged:(UISwitch*)switchView {
[self setSwitchItemOn:[switchView isOn]
itemType:ItemTypeAutofillAddressSwitch];
[self setAutofillProfileEnabled:[switchView isOn]];
}
#pragma mark - Switch Helpers
// Sets switchItem's state to `on`. It is important that there is only one item
// of `switchItemType` in SectionIdentifierSwitches.
- (void)setSwitchItemOn:(BOOL)on itemType:(ItemType)switchItemType {
NSIndexPath* switchPath =
[self.tableViewModel indexPathForItemType:switchItemType
sectionIdentifier:SectionIdentifierSwitches];
TableViewSwitchItem* switchItem =
base::apple::ObjCCastStrict<TableViewSwitchItem>(
[self.tableViewModel itemAtIndexPath:switchPath]);
switchItem.on = on;
}
// Sets switchItem's enabled status to `enabled` and reconfigures the
// corresponding cell. It is important that there is no more than one item of
// `switchItemType` in SectionIdentifierSwitches.
- (void)setSwitchItemEnabled:(BOOL)enabled itemType:(ItemType)switchItemType {
TableViewModel* model = self.tableViewModel;
if (![model hasItemForItemType:switchItemType
sectionIdentifier:SectionIdentifierSwitches]) {
return;
}
NSIndexPath* switchPath =
[model indexPathForItemType:switchItemType
sectionIdentifier:SectionIdentifierSwitches];
TableViewSwitchItem* switchItem =
base::apple::ObjCCastStrict<TableViewSwitchItem>(
[model itemAtIndexPath:switchPath]);
[switchItem setEnabled:enabled];
[self reconfigureCellsForItems:@[ switchItem ]];
}
#pragma mark - PersonalDataManagerObserver
- (void)onPersonalDataChanged {
if (_deletionInProgress)
return;
if ([self.tableView isEditing]) {
// Turn off edit mode.
[self setEditing:NO animated:NO];
}
[self determineUserEmail];
[self updateUIForEditState];
[self reloadData];
}
#pragma mark - Getters and Setter
- (BOOL)isAutofillProfileEnabled {
return autofill::prefs::IsAutofillProfileEnabled(
_browser->GetBrowserState()->GetPrefs());
}
- (void)setAutofillProfileEnabled:(BOOL)isEnabled {
return autofill::prefs::SetAutofillProfileEnabled(
_browser->GetBrowserState()->GetPrefs(), isEnabled);
}
- (void)determineUserEmail {
self.syncEnabled = NO;
self.userEmail = nil;
AuthenticationService* authenticationService =
AuthenticationServiceFactory::GetForBrowserState(
_browser->GetBrowserState());
CHECK(authenticationService);
id<SystemIdentity> identity =
authenticationService->GetPrimaryIdentity(signin::ConsentLevel::kSignin);
if (identity) {
self.userEmail = identity.userEmail;
self.syncEnabled = _personalDataManager->IsSyncEnabledFor(
syncer::UserSelectableType::kAutofill);
}
}
#pragma mark - PopoverLabelViewControllerDelegate
- (void)didTapLinkURL:(NSURL*)URL {
[self view:nil didTapLinkURL:[[CrURL alloc] initWithNSURL:URL]];
}
#pragma mark - AutofillProfileEditCoordinatorDelegate
- (void)autofillProfileEditCoordinatorTableViewControllerDidFinish:
(AutofillProfileEditCoordinator*)coordinator {
DCHECK_EQ(self.autofillProfileEditCoordinator, coordinator);
[self stopAutofillProfileEditCoordinator];
}
#pragma mark - Private
- (void)dismissDeletionSheet {
[self.deletionSheetCoordinator stop];
self.deletionSheetCoordinator = nil;
}
- (void)stopAutofillProfileEditCoordinator {
self.autofillProfileEditCoordinator.delegate = nil;
[self.autofillProfileEditCoordinator stop];
self.autofillProfileEditCoordinator = nil;
}
// Removes the item from the personal data manager model.
- (void)willDeleteItemsAtIndexPaths:(NSArray*)indexPaths {
if (_settingsAreDismissed)
return;
_deletionInProgress = YES;
for (NSIndexPath* indexPath in indexPaths) {
AutofillProfileItem* item =
base::apple::ObjCCastStrict<AutofillProfileItem>(
[self.tableViewModel itemAtIndexPath:indexPath]);
_personalDataManager->RemoveByGUID([item GUID]);
}
[self.tableView
performBatchUpdates:^{
[self removeFromModelItemAtIndexPaths:indexPaths];
[self.tableView
deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationAutomatic];
}
completion:nil];
}
// Remove the section from the model and collectionView if there are no more
// items in the section.
- (void)removeSectionIfEmptyForSectionWithIdentifier:
(SectionIdentifier)sectionIdentifier {
if (_settingsAreDismissed ||
![self.tableViewModel hasSectionForSectionIdentifier:sectionIdentifier]) {
_deletionInProgress = NO;
return;
}
NSInteger section =
[self.tableViewModel sectionForSectionIdentifier:sectionIdentifier];
if ([self.tableView numberOfRowsInSection:section] == 0) {
// Avoid reference cycle in block.
__weak AutofillProfileTableViewController* weakSelf = self;
[self.tableView
performBatchUpdates:^{
// Obtain strong reference again.
AutofillProfileTableViewController* strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// Remove section from model and collectionView.
[[strongSelf tableViewModel]
removeSectionWithIdentifier:sectionIdentifier];
[[strongSelf tableView]
deleteSections:[NSIndexSet indexSetWithIndex:section]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
completion:^(BOOL finished) {
// Obtain strong reference again.
AutofillProfileTableViewController* strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// Turn off edit mode if there is nothing to edit.
if (![strongSelf localProfilesExist] &&
[strongSelf.tableView isEditing]) {
[strongSelf setEditing:NO animated:YES];
}
[strongSelf updateUIForEditState];
strongSelf->_deletionInProgress = NO;
}];
} else {
_deletionInProgress = NO;
}
}
// Shows the action sheet asking for the confirmation on delete from the user.
- (void)showDeletionConfirmationForIndexPaths:
(NSArray<NSIndexPath*>*)indexPaths {
BOOL accountProfiles = NO;
BOOL syncProfiles = NO;
int profileCount = 0;
for (NSIndexPath* indexPath in indexPaths) {
if (![self isItemTypeForIndexPathAddress:indexPath]) {
continue;
}
profileCount++;
AutofillProfileItem* item =
base::apple::ObjCCastStrict<AutofillProfileItem>(
[self.tableViewModel itemAtIndexPath:indexPath]);
switch (item.autofillProfileSource) {
case AutofillAccountProfile:
accountProfiles = YES;
break;
case AutofillSyncableProfile:
syncProfiles = YES;
break;
case AutofillLocalProfile:
break;
}
}
// Can happen if user presses delete in quick succesion.
if (!profileCount) {
return;
}
NSString* deletionConfirmationString =
[self getDeletionConfirmationStringUsingProfileCount:profileCount
accountProfiles:accountProfiles
syncProfiles:syncProfiles];
self.deletionSheetCoordinator = [[ActionSheetCoordinator alloc]
initWithBaseViewController:self
browser:_browser
title:deletionConfirmationString
message:nil
barButtonItem:self.deleteButton];
if (UIContentSizeCategoryIsAccessibilityCategory(
UIApplication.sharedApplication.preferredContentSizeCategory)) {
self.deletionSheetCoordinator.alertStyle = UIAlertControllerStyleAlert;
}
self.deletionSheetCoordinator.popoverArrowDirection =
UIPopoverArrowDirectionAny;
__weak AutofillProfileTableViewController* weakSelf = self;
[self.deletionSheetCoordinator
addItemWithTitle:
l10n_util::GetPluralNSStringF(
IDS_IOS_SETTINGS_AUTOFILL_DELETE_ADDRESS_CONFIRMATION_BUTTON,
profileCount)
action:^{
[weakSelf willDeleteItemsAtIndexPaths:indexPaths];
// TODO(crbug.com/650390) Generalize removing empty sections
[weakSelf removeSectionIfEmptyForSectionWithIdentifier:
SectionIdentifierProfiles];
[weakSelf dismissDeletionSheet];
}
style:UIAlertActionStyleDestructive];
[self.deletionSheetCoordinator
addItemWithTitle:l10n_util::GetNSString(IDS_APP_CANCEL)
action:^{
[weakSelf dismissDeletionSheet];
}
style:UIAlertActionStyleCancel];
[self.deletionSheetCoordinator start];
}
// Returns the deletion confirmation message string based on
// `profileCount` and if it the source has any `accountProfiles` or
// `syncProfiles`.
- (NSString*)getDeletionConfirmationStringUsingProfileCount:(int)profileCount
accountProfiles:
(BOOL)accountProfiles
syncProfiles:(BOOL)syncProfiles {
if (accountProfiles) {
std::u16string pattern = l10n_util::GetStringUTF16(
IDS_IOS_SETTINGS_AUTOFILL_DELETE_ACCOUNT_ADDRESS_CONFIRMATION_TITLE);
std::u16string confirmationString =
base::i18n::MessageFormatter::FormatWithNamedArgs(
pattern, "email", base::SysNSStringToUTF16(self.userEmail), "count",
profileCount);
return base::SysUTF16ToNSString(confirmationString);
}
if (syncProfiles) {
return l10n_util::GetPluralNSStringF(
IDS_IOS_SETTINGS_AUTOFILL_DELETE_SYNC_ADDRESS_CONFIRMATION_TITLE,
profileCount);
}
return l10n_util::GetPluralNSStringF(
IDS_IOS_SETTINGS_AUTOFILL_DELETE_LOCAL_ADDRESS_CONFIRMATION_TITLE,
profileCount);
}
// Returns true when the item type for `indexPath` is Address.
- (BOOL)isItemTypeForIndexPathAddress:(NSIndexPath*)indexPath {
return
[self.tableViewModel itemTypeForIndexPath:indexPath] == ItemTypeAddress;
}
- (void)showAddressProfileDetailsPageForProfile:
(autofill::AutofillProfile*)profile
withMigrateToAccountButton:(BOOL)migrateToAccountButton {
self.autofillProfileEditCoordinator = [[AutofillProfileEditCoordinator alloc]
initWithBaseNavigationController:self.navigationController
browser:_browser
profile:*profile
migrateToAccountButton:migrateToAccountButton];
self.autofillProfileEditCoordinator.delegate = self;
[self.autofillProfileEditCoordinator start];
}
// Returns YES if the cloud off icon should be shown next to the profile. Only
// those profiles, that are eligible for the migration to Account show cloud off
// icon.
- (BOOL)shouldShowCloudOffIconForProfile:
(const autofill::AutofillProfile&)profile {
return IsEligibleForMigrationToAccount(*_personalDataManager, profile) &&
base::FeatureList::IsEnabled(
syncer::kSyncEnableContactInfoDataTypeInTransportMode) &&
self.userEmail != nil;
}
@end