summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/AutoFillDialog.xib84
-rw-r--r--chrome/browser/autofill/autofill_dialog_controller_mac.h14
-rw-r--r--chrome/browser/autofill/autofill_dialog_controller_mac.mm93
-rw-r--r--chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm60
4 files changed, 184 insertions, 67 deletions
diff --git a/chrome/app/nibs/AutoFillDialog.xib b/chrome/app/nibs/AutoFillDialog.xib
index 9b7d996..f7edaa9 100644
--- a/chrome/app/nibs/AutoFillDialog.xib
+++ b/chrome/app/nibs/AutoFillDialog.xib
@@ -181,7 +181,7 @@
</object>
</object>
<double key="NSRowHeight">17</double>
- <int key="NSTvFlags">306184192</int>
+ <int key="NSTvFlags">440401920</int>
<reference key="NSDelegate"/>
<reference key="NSDataSource"/>
<int key="NSColumnAutoresizingStyle">4</int>
@@ -670,7 +670,7 @@
<string key="label">enabled2: autoFillEnabled</string>
<reference key="source" ref="457244217"/>
<reference key="destination" ref="1001"/>
- <object class="NSNibBindingConnector" key="connector">
+ <object class="NSNibBindingConnector" key="connector" id="270191331">
<reference key="NSSource" ref="457244217"/>
<reference key="NSDestination" ref="1001"/>
<string key="NSLabel">enabled2: autoFillEnabled</string>
@@ -749,6 +749,50 @@
</object>
<int key="connectionID">215</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">enabled3: multipleSelected</string>
+ <reference key="source" ref="457244217"/>
+ <reference key="destination" ref="1001"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="457244217"/>
+ <reference key="NSDestination" ref="1001"/>
+ <string key="NSLabel">enabled3: multipleSelected</string>
+ <string key="NSBinding">enabled3</string>
+ <string key="NSKeyPath">multipleSelected</string>
+ <object class="NSDictionary" key="NSOptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSMultipleValuesPlaceholder</string>
+ <string>NSNoSelectionPlaceholder</string>
+ <string>NSNotApplicablePlaceholder</string>
+ <string>NSNullPlaceholder</string>
+ <string>NSValueTransformerName</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="-1"/>
+ <integer value="-1"/>
+ <integer value="-1"/>
+ <integer value="-1"/>
+ <string>NSNegateBoolean</string>
+ </object>
+ </object>
+ <reference key="NSPreviousConnector" ref="270191331"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">218</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">editButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="457244217"/>
+ </object>
+ <int key="connectionID">219</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -1108,7 +1152,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">215</int>
+ <int key="maxID">219</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1140,8 +1184,17 @@
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">tableView_</string>
- <string key="NS.object.0">AutoFillTableView</string>
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>editButton_</string>
+ <string>tableView_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSButton</string>
+ <string>AutoFillTableView</string>
+ </object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
@@ -1798,27 +1851,6 @@
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzCore.framework/Headers/CIImageProvider.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">SecurityInterface.framework/Headers/SFAuthorizationView.h</string>
</object>
</object>
diff --git a/chrome/browser/autofill/autofill_dialog_controller_mac.h b/chrome/browser/autofill/autofill_dialog_controller_mac.h
index 3318443..7a7faa7 100644
--- a/chrome/browser/autofill/autofill_dialog_controller_mac.h
+++ b/chrome/browser/autofill/autofill_dialog_controller_mac.h
@@ -34,6 +34,9 @@ class Profile;
// cards with section headers for both.
IBOutlet AutoFillTableView* tableView_;
+ // Outlet to "Edit..." button. Here for unit testing purposes.
+ IBOutlet NSButton* editButton_;
+
// This observer is passed in by the caller of the dialog. When the dialog
// is dismissed |observer_| is called with new values for the addresses and
// credit cards.
@@ -68,6 +71,10 @@ class Profile;
// "Remove" buttons.
BOOL itemIsSelected_;
+ // State for |multipleSelected| property used in bindings for "Edit..."
+ // button.
+ BOOL multipleSelected_;
+
// Utility object to save and restore dialog position.
scoped_nsobject<WindowSizeAutosaver> sizeSaver_;
@@ -97,6 +104,10 @@ class Profile;
// edit and delete buttons are bound to this property.
@property (nonatomic) BOOL itemIsSelected;
+// Property representing multiple selection state in |tableView_|. Enabled
+// state of edit button is bound to this property.
+@property (nonatomic) BOOL multipleSelected;
+
// Main interface for displaying an application modal AutoFill dialog on screen.
// This class method creates a new |AutoFillDialogController| and runs it as a
// modal dialog. The controller autoreleases itself when the dialog is closed.
@@ -168,6 +179,9 @@ class Profile;
- (AutoFillCreditCardSheetController*)creditCardSheetController;
- (void)selectAddressAtIndex:(size_t)i;
- (void)selectCreditCardAtIndex:(size_t)i;
+- (void)addSelectedAddressAtIndex:(size_t)i;
+- (void)addSelectedCreditCardAtIndex:(size_t)i;
+- (BOOL)editButtonEnabled;
@end
#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_DIALOG_CONTROLLER_MAC_
diff --git a/chrome/browser/autofill/autofill_dialog_controller_mac.mm b/chrome/browser/autofill/autofill_dialog_controller_mac.mm
index 377e1cd..d0e16ae 100644
--- a/chrome/browser/autofill/autofill_dialog_controller_mac.mm
+++ b/chrome/browser/autofill/autofill_dialog_controller_mac.mm
@@ -191,6 +191,7 @@ void PersonalDataManagerObserver::OnPersonalDataLoaded() {
@synthesize autoFillEnabled = autoFillEnabled_;
@synthesize auxiliaryEnabled = auxiliaryEnabled_;
@synthesize itemIsSelected = itemIsSelected_;
+@synthesize multipleSelected = multipleSelected_;
+ (void)showAutoFillDialogWithObserver:(AutoFillDialogObserver*)observer
profile:(Profile*)profile
@@ -356,43 +357,45 @@ void PersonalDataManagerObserver::OnPersonalDataLoaded() {
creditCardSheetController.reset(nil);
}
-// Deletes selected item, either address or credit card depending on the item
-// selected.
+// Deletes selected items; either addresses, credit cards, or a mixture of the
+// two depending on the items selected.
- (IBAction)deleteSelection:(id)sender {
+ NSIndexSet* selectedRows = [tableView_ selectedRowIndexes];
NSInteger selectedRow = [tableView_ selectedRow];
- if ([self isProfileRow:selectedRow]) {
- profiles_.erase(profiles_.begin() + [self profileIndexFromRow:selectedRow]);
-
- // Select the previous row if possible, else current row, else deselect all.
- if ([self tableView:tableView_ shouldSelectRow:selectedRow-1]) {
- [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow-1]
- byExtendingSelection:NO];
- } else if ([self tableView:tableView_ shouldSelectRow:selectedRow]) {
- [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow]
- byExtendingSelection:NO];
- } else {
- [tableView_ selectRowIndexes:[NSIndexSet indexSet]
- byExtendingSelection:NO];
+ NSInteger rowCount = [tableView_ numberOfRows];
+
+ // Loop through from last to first deleting selected items as we go.
+ for (NSInteger i = rowCount-1; i>=0; --i) {
+ if (![selectedRows containsIndex:i])
+ continue;
+
+ // We keep track of the "top most" selection in the list so we know where
+ // to to set new selection below.
+ if (i < selectedRow)
+ selectedRow = i;
+
+ if ([self isProfileRow:i]) {
+ profiles_.erase(
+ profiles_.begin() + [self profileIndexFromRow:i]);
+ } else if ([self isCreditCardRow:i]) {
+ creditCards_.erase(
+ creditCards_.begin() + [self creditCardIndexFromRow:i]);
}
- UpdateProfileLabels(&profiles_);
- [tableView_ reloadData];
- } else if ([self isCreditCardRow:selectedRow]) {
- creditCards_.erase(
- creditCards_.begin() + [self creditCardIndexFromRow:selectedRow]);
-
- // Select the previous row if possible, else current row, else deselect all.
- if ([self tableView:tableView_ shouldSelectRow:selectedRow-1]) {
- [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow-1]
- byExtendingSelection:NO];
- } else if ([self tableView:tableView_ shouldSelectRow:selectedRow]) {
- [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow]
- byExtendingSelection:NO];
- } else {
- [tableView_ selectRowIndexes:[NSIndexSet indexSet]
- byExtendingSelection:NO];
- }
- [tableView_ reloadData];
}
+
+ // Select the previous row if possible, else current row, else deselect all.
+ if ([self tableView:tableView_ shouldSelectRow:selectedRow-1]) {
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow-1]
+ byExtendingSelection:NO];
+ } else if ([self tableView:tableView_ shouldSelectRow:selectedRow]) {
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow]
+ byExtendingSelection:NO];
+ } else {
+ [tableView_ selectRowIndexes:[NSIndexSet indexSet] byExtendingSelection:NO];
+ }
+
+ UpdateProfileLabels(&profiles_);
+ [tableView_ reloadData];
}
// Edits the selected item, either address or credit card depending on the item
@@ -542,14 +545,18 @@ void PersonalDataManagerObserver::OnPersonalDataLoaded() {
return @"";
}
-// We implement this delegate method to update our |itemIsSelected| property.
+// We implement this delegate method to update our |itemIsSelected| and
+// |multipleSelected| properties.
// The "Edit..." and "Remove" buttons' enabled state depends on having a
-// valid selection in the table.
+// valid selection in the table. The "Edit..." button depends on having
+// exactly one item selected.
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
if ([tableView_ selectedRow] >= 0)
[self setItemIsSelected:YES];
else
[self setItemIsSelected:NO];
+
+ [self setMultipleSelected:([[tableView_ selectedRowIndexes] count] > 1UL)];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
@@ -654,6 +661,22 @@ void PersonalDataManagerObserver::OnPersonalDataLoaded() {
byExtendingSelection:NO];
}
+- (void)addSelectedAddressAtIndex:(size_t)i {
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:
+ [self rowFromProfileIndex:i]]
+ byExtendingSelection:YES];
+}
+
+- (void)addSelectedCreditCardAtIndex:(size_t)i {
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:
+ [self rowFromCreditCardIndex:i]]
+ byExtendingSelection:YES];
+}
+
+- (BOOL)editButtonEnabled {
+ return [editButton_ isEnabled];
+}
+
@end
@implementation AutoFillDialogController (PrivateMethods)
diff --git a/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm b/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm
index d3e2550..80678077 100644
--- a/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm
+++ b/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm
@@ -389,7 +389,7 @@ TEST_F(AutoFillDialogControllerTest, AddNewProfile) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 2.
+ // Sizes should be different. New size should be 2.
ASSERT_NE(observer_.profiles_.size(), profiles().size());
ASSERT_EQ(observer_.profiles_.size(), 2UL);
@@ -413,7 +413,7 @@ TEST_F(AutoFillDialogControllerTest, AddNewCreditCard) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 2.
+ // Sizes should be different. New size should be 2.
ASSERT_NE(observer_.credit_cards_.size(), credit_cards().size());
ASSERT_EQ(observer_.credit_cards_.size(), 2UL);
@@ -434,7 +434,7 @@ TEST_F(AutoFillDialogControllerTest, DeleteProfile) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 0.
+ // Sizes should be different. New size should be 0.
ASSERT_NE(observer_.profiles_.size(), profiles().size());
ASSERT_EQ(observer_.profiles_.size(), 0UL);
}
@@ -451,7 +451,7 @@ TEST_F(AutoFillDialogControllerTest, DeleteCreditCard) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 0.
+ // Sizes should be different. New size should be 0.
ASSERT_NE(observer_.credit_cards_.size(), credit_cards().size());
ASSERT_EQ(observer_.credit_cards_.size(), 0UL);
}
@@ -471,7 +471,7 @@ TEST_F(AutoFillDialogControllerTest, TwoProfilesDeleteOne) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 0.
+ // Sizes should be different. New size should be 1.
ASSERT_NE(observer_.profiles_.size(), profiles().size());
ASSERT_EQ(observer_.profiles_.size(), 1UL);
@@ -499,7 +499,7 @@ TEST_F(AutoFillDialogControllerTest, TwoCreditCardsDeleteOne) {
// Should hit our observer.
ASSERT_TRUE(observer_.hit_);
- // Sizes should match be different. New size should be 0.
+ // Sizes should be different. New size should be 1.
ASSERT_NE(observer_.credit_cards_.size(), credit_cards().size());
ASSERT_EQ(observer_.credit_cards_.size(), 1UL);
@@ -508,6 +508,54 @@ TEST_F(AutoFillDialogControllerTest, TwoCreditCardsDeleteOne) {
ASSERT_EQ(observer_.credit_cards_[0], credit_card);
}
+TEST_F(AutoFillDialogControllerTest, DeleteMultiple) {
+ AutoFillProfile profile(ASCIIToUTF16("One"), 1);
+ profile.SetInfo(AutoFillType(NAME_FIRST), ASCIIToUTF16("Joe"));
+ profiles().push_back(&profile);
+ AutoFillProfile profile2(ASCIIToUTF16("Two"), 2);
+ profile2.SetInfo(AutoFillType(NAME_FIRST), ASCIIToUTF16("Bob"));
+ profiles().push_back(&profile2);
+
+ CreditCard credit_card(ASCIIToUTF16("Visa"), 1);
+ credit_card.SetInfo(AutoFillType(CREDIT_CARD_NAME), ASCIIToUTF16("Joe"));
+ credit_cards().push_back(&credit_card);
+ CreditCard credit_card2(ASCIIToUTF16("Mastercard"), 2);
+ credit_card2.SetInfo(AutoFillType(CREDIT_CARD_NAME), ASCIIToUTF16("Bob"));
+ credit_cards().push_back(&credit_card2);
+
+ LoadDialog();
+ [controller_ selectAddressAtIndex:1];
+ [controller_ addSelectedCreditCardAtIndex:0];
+ ASSERT_FALSE([controller_ editButtonEnabled]);
+ [controller_ deleteSelection:nil];
+ [controller_ selectAddressAtIndex:0];
+ ASSERT_TRUE([controller_ editButtonEnabled]);
+ [controller_ save:nil];
+
+ // Should hit our observer.
+ ASSERT_TRUE(observer_.hit_);
+
+ // Sizes should be different. New size should be 1.
+ ASSERT_NE(observer_.profiles_.size(), profiles().size());
+ ASSERT_EQ(observer_.profiles_.size(), 1UL);
+
+ // Sizes should be different. New size should be 1.
+ ASSERT_NE(observer_.credit_cards_.size(), credit_cards().size());
+ ASSERT_EQ(observer_.credit_cards_.size(), 1UL);
+
+ // First address should match.
+ profiles()[0]->set_unique_id(observer_.profiles_[0].unique_id());
+
+ // Do not compare labels. Label is a derived field.
+ observer_.profiles_[0].set_label(string16());
+ profile.set_label(string16());
+ ASSERT_EQ(observer_.profiles_[0], profile);
+
+ // Second credit card should match.
+ credit_cards()[0]->set_unique_id(observer_.credit_cards_[0].unique_id());
+ ASSERT_EQ(observer_.credit_cards_[0], credit_card2);
+}
+
// Auxilliary profiles are enabled by default.
TEST_F(AutoFillDialogControllerTest, AuxiliaryProfilesTrue) {
LoadDialog();