| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" | 5 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 *line1 = text.substr(0, position); | 65 *line1 = text.substr(0, position); |
| 66 *line2 = text.substr(position + line_return.length()); | 66 *line2 = text.substr(position + line_return.length()); |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 // If the Autofill data comes from a credit card, make sure to overwrite the | 70 // If the Autofill data comes from a credit card, make sure to overwrite the |
| 71 // CC comboboxes (even if they already have something in them). If the | 71 // CC comboboxes (even if they already have something in them). If the |
| 72 // Autofill data comes from an AutofillProfile, leave the comboboxes alone. | 72 // Autofill data comes from an AutofillProfile, leave the comboboxes alone. |
| 73 // TODO(groby): This kind of logic should _really_ live on the delegate. | 73 // TODO(groby): This kind of logic should _really_ live on the delegate. |
| 74 bool ShouldOverwriteComboboxes(autofill::DialogSection section, | 74 bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| 75 autofill::AutofillFieldType type) { | 75 autofill::ServerFieldType type) { |
| 76 if (autofill::AutofillType(type).group() != autofill::CREDIT_CARD) { | 76 if (autofill::AutofillType(type).group() != autofill::CREDIT_CARD) { |
| 77 return false; | 77 return false; |
| 78 } | 78 } |
| 79 | 79 |
| 80 if (section == autofill::SECTION_CC) { | 80 if (section == autofill::SECTION_CC) { |
| 81 return true; | 81 return true; |
| 82 } | 82 } |
| 83 | 83 |
| 84 return section == autofill::SECTION_CC_BILLING; | 84 return section == autofill::SECTION_CC_BILLING; |
| 85 } | 85 } |
| 86 | 86 |
| 87 bool CompareInputRows(const autofill::DetailInput* input1, | 87 bool CompareInputRows(const autofill::DetailInput* input1, |
| 88 const autofill::DetailInput* input2) { | 88 const autofill::DetailInput* input2) { |
| 89 // Row ID -1 is sorted to the end of rows. | 89 // Row ID -1 is sorted to the end of rows. |
| 90 if (input2->row_id == -1) | 90 if (input2->row_id == -1) |
| 91 return false; | 91 return false; |
| 92 return input2->row_id < input1->row_id; | 92 return input2->row_id < input1->row_id; |
| 93 } | 93 } |
| 94 | 94 |
| 95 } | 95 } |
| 96 | 96 |
| 97 @interface AutofillSectionContainer () | 97 @interface AutofillSectionContainer () |
| 98 | 98 |
| 99 // A text field has been edited or activated - inform the delegate that it's | 99 // A text field has been edited or activated - inform the delegate that it's |
| 100 // time to show a suggestion popup & possibly reset the validity of the input. | 100 // time to show a suggestion popup & possibly reset the validity of the input. |
| 101 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field | 101 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| 102 edited:(BOOL)edited; | 102 edited:(BOOL)edited; |
| 103 | 103 |
| 104 // Convenience method to retrieve a field type via the control's tag. | 104 // Convenience method to retrieve a field type via the control's tag. |
| 105 - (autofill::AutofillFieldType)fieldTypeForControl:(NSControl*)control; | 105 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control; |
| 106 | 106 |
| 107 // Find the DetailInput* associated with a field type. | 107 // Find the DetailInput* associated with a field type. |
| 108 - (const autofill::DetailInput*)detailInputForType: | 108 - (const autofill::DetailInput*)detailInputForType: |
| 109 (autofill::AutofillFieldType)type; | 109 (autofill::ServerFieldType)type; |
| 110 | 110 |
| 111 // Takes an NSArray of controls and builds a DetailOutputMap from them. | 111 // Takes an NSArray of controls and builds a DetailOutputMap from them. |
| 112 // Translates between Cocoa code and delegate, essentially. | 112 // Translates between Cocoa code and delegate, essentially. |
| 113 // All controls must inherit from NSControl and conform to AutofillInputView. | 113 // All controls must inherit from NSControl and conform to AutofillInputView. |
| 114 - (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs | 114 - (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs |
| 115 fromControls:(NSArray*)controls; | 115 fromControls:(NSArray*)controls; |
| 116 | 116 |
| 117 // Updates input fields based on delegate status. If |shouldClobber| is YES, | 117 // Updates input fields based on delegate status. If |shouldClobber| is YES, |
| 118 // will clobber existing data and reset fields to the initial values. | 118 // will clobber existing data and reset fields to the initial values. |
| 119 - (void)updateAndClobber:(BOOL)shouldClobber; | 119 - (void)updateAndClobber:(BOOL)shouldClobber; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 // Make sure to overwrite the originating input if it is a text field. | 316 // Make sure to overwrite the originating input if it is a text field. |
| 317 AutofillTextField* field = | 317 AutofillTextField* field = |
| 318 base::mac::ObjCCast<AutofillTextField>([inputs_ viewWithTag:input.type]); | 318 base::mac::ObjCCast<AutofillTextField>([inputs_ viewWithTag:input.type]); |
| 319 [field setFieldValue:@""]; | 319 [field setFieldValue:@""]; |
| 320 | 320 |
| 321 if (ShouldOverwriteComboboxes(section_, input.type)) { | 321 if (ShouldOverwriteComboboxes(section_, input.type)) { |
| 322 for (NSControl* control in [inputs_ subviews]) { | 322 for (NSControl* control in [inputs_ subviews]) { |
| 323 AutofillPopUpButton* popup = | 323 AutofillPopUpButton* popup = |
| 324 base::mac::ObjCCast<AutofillPopUpButton>(control); | 324 base::mac::ObjCCast<AutofillPopUpButton>(control); |
| 325 if (popup) { | 325 if (popup) { |
| 326 autofill::AutofillFieldType fieldType = | 326 autofill::ServerFieldType fieldType = |
| 327 [self fieldTypeForControl:popup]; | 327 [self fieldTypeForControl:popup]; |
| 328 if (autofill::AutofillType(fieldType).group() == | 328 if (autofill::AutofillType(fieldType).group() == |
| 329 autofill::CREDIT_CARD) { | 329 autofill::CREDIT_CARD) { |
| 330 ui::ComboboxModel* model = | 330 ui::ComboboxModel* model = |
| 331 delegate_->ComboboxModelForAutofillType(fieldType); | 331 delegate_->ComboboxModelForAutofillType(fieldType); |
| 332 DCHECK(model); | 332 DCHECK(model); |
| 333 [popup selectItemAtIndex:model->GetDefaultIndex()]; | 333 [popup selectItemAtIndex:model->GetDefaultIndex()]; |
| 334 } | 334 } |
| 335 } | 335 } |
| 336 } | 336 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 356 } else if (section_ == autofill::SECTION_CC) { | 356 } else if (section_ == autofill::SECTION_CC) { |
| 357 fields = @[[suggestContainer_ inputField]]; | 357 fields = @[[suggestContainer_ inputField]]; |
| 358 } | 358 } |
| 359 | 359 |
| 360 autofill::DetailOutputMap detailOutputs; | 360 autofill::DetailOutputMap detailOutputs; |
| 361 [self fillDetailOutputs:&detailOutputs fromControls:fields]; | 361 [self fillDetailOutputs:&detailOutputs fromControls:fields]; |
| 362 autofill::ValidityData invalidInputs = delegate_->InputsAreValid( | 362 autofill::ValidityData invalidInputs = delegate_->InputsAreValid( |
| 363 section_, detailOutputs, validationType); | 363 section_, detailOutputs, validationType); |
| 364 | 364 |
| 365 for (NSControl<AutofillInputField>* input in fields) { | 365 for (NSControl<AutofillInputField>* input in fields) { |
| 366 const autofill::AutofillFieldType type = [self fieldTypeForControl:input]; | 366 const autofill::ServerFieldType type = [self fieldTypeForControl:input]; |
| 367 if (invalidInputs.count(type)) | 367 if (invalidInputs.count(type)) |
| 368 [input setValidityMessage:base::SysUTF16ToNSString(invalidInputs[type])]; | 368 [input setValidityMessage:base::SysUTF16ToNSString(invalidInputs[type])]; |
| 369 else | 369 else |
| 370 [input setValidityMessage:@""]; | 370 [input setValidityMessage:@""]; |
| 371 [validationDelegate_ updateMessageForField:input]; | 371 [validationDelegate_ updateMessageForField:input]; |
| 372 } | 372 } |
| 373 | 373 |
| 374 return invalidInputs.empty(); | 374 return invalidInputs.empty(); |
| 375 } | 375 } |
| 376 | 376 |
| 377 #pragma mark Internal API for AutofillSectionContainer. | 377 #pragma mark Internal API for AutofillSectionContainer. |
| 378 | 378 |
| 379 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field | 379 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| 380 edited:(BOOL)edited { | 380 edited:(BOOL)edited { |
| 381 AutofillTextField* textfield = | 381 AutofillTextField* textfield = |
| 382 base::mac::ObjCCastStrict<AutofillTextField>(field); | 382 base::mac::ObjCCastStrict<AutofillTextField>(field); |
| 383 | 383 |
| 384 // This only applies to textfields. | 384 // This only applies to textfields. |
| 385 if (!textfield) | 385 if (!textfield) |
| 386 return; | 386 return; |
| 387 | 387 |
| 388 autofill::AutofillFieldType type = [self fieldTypeForControl:field]; | 388 autofill::ServerFieldType type = [self fieldTypeForControl:field]; |
| 389 string16 fieldValue = base::SysNSStringToUTF16([textfield fieldValue]); | 389 string16 fieldValue = base::SysNSStringToUTF16([textfield fieldValue]); |
| 390 | 390 |
| 391 // Get the frame rectangle for the designated field, in screen coordinates. | 391 // Get the frame rectangle for the designated field, in screen coordinates. |
| 392 NSRect textFrameInScreen = [field convertRect:[field frame] toView:nil]; | 392 NSRect textFrameInScreen = [field convertRect:[field frame] toView:nil]; |
| 393 textFrameInScreen.origin = | 393 textFrameInScreen.origin = |
| 394 [[field window] convertBaseToScreen:textFrameInScreen.origin]; | 394 [[field window] convertBaseToScreen:textFrameInScreen.origin]; |
| 395 | 395 |
| 396 // And adjust for gfx::Rect being flipped compared to OSX coordinates. | 396 // And adjust for gfx::Rect being flipped compared to OSX coordinates. |
| 397 NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; | 397 NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; |
| 398 textFrameInScreen.origin.y = | 398 textFrameInScreen.origin.y = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 424 [self validateFor:autofill::VALIDATE_EDIT]; | 424 [self validateFor:autofill::VALIDATE_EDIT]; |
| 425 } | 425 } |
| 426 | 426 |
| 427 // Update the icon for the textfield. | 427 // Update the icon for the textfield. |
| 428 gfx::Image icon = delegate_->IconForField(type, fieldValue); | 428 gfx::Image icon = delegate_->IconForField(type, fieldValue); |
| 429 if (!icon.IsEmpty()) { | 429 if (!icon.IsEmpty()) { |
| 430 [[textfield cell] setIcon:icon.ToNSImage()]; | 430 [[textfield cell] setIcon:icon.ToNSImage()]; |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 | 433 |
| 434 - (autofill::AutofillFieldType)fieldTypeForControl:(NSControl*)control { | 434 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { |
| 435 DCHECK([control tag]); | 435 DCHECK([control tag]); |
| 436 return static_cast<autofill::AutofillFieldType>([control tag]); | 436 return static_cast<autofill::ServerFieldType>([control tag]); |
| 437 } | 437 } |
| 438 | 438 |
| 439 - (const autofill::DetailInput*)detailInputForType: | 439 - (const autofill::DetailInput*)detailInputForType: |
| 440 (autofill::AutofillFieldType)type { | 440 (autofill::ServerFieldType)type { |
| 441 for (size_t i = 0; i < detailInputs_.size(); ++i) { | 441 for (size_t i = 0; i < detailInputs_.size(); ++i) { |
| 442 if (detailInputs_[i]->type == type) | 442 if (detailInputs_[i]->type == type) |
| 443 return detailInputs_[i]; | 443 return detailInputs_[i]; |
| 444 } | 444 } |
| 445 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests | 445 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests |
| 446 // blindly call setFieldValue:forInput:, even for non-existing inputs. | 446 // blindly call setFieldValue:forInput:, even for non-existing inputs. |
| 447 return NULL; | 447 return NULL; |
| 448 } | 448 } |
| 449 | 449 |
| 450 - (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs | 450 - (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs |
| 451 fromControls:(NSArray*)controls { | 451 fromControls:(NSArray*)controls { |
| 452 for (NSControl<AutofillInputField>* input in controls) { | 452 for (NSControl<AutofillInputField>* input in controls) { |
| 453 DCHECK([input isKindOfClass:[NSControl class]]); | 453 DCHECK([input isKindOfClass:[NSControl class]]); |
| 454 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); | 454 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); |
| 455 autofill::AutofillFieldType fieldType = [self fieldTypeForControl:input]; | 455 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; |
| 456 DCHECK([self detailInputForType:fieldType]); | 456 DCHECK([self detailInputForType:fieldType]); |
| 457 NSString* value = [input fieldValue]; | 457 NSString* value = [input fieldValue]; |
| 458 outputs->insert(std::make_pair([self detailInputForType:fieldType], | 458 outputs->insert(std::make_pair([self detailInputForType:fieldType], |
| 459 base::SysNSStringToUTF16(value))); | 459 base::SysNSStringToUTF16(value))); |
| 460 } | 460 } |
| 461 } | 461 } |
| 462 | 462 |
| 463 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText { | 463 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText { |
| 464 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]); | 464 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]); |
| 465 [label setFont: | 465 [label setFont: |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 } | 597 } |
| 598 | 598 |
| 599 return view.autorelease(); | 599 return view.autorelease(); |
| 600 } | 600 } |
| 601 | 601 |
| 602 @end | 602 @end |
| 603 | 603 |
| 604 | 604 |
| 605 @implementation AutofillSectionContainer (ForTesting) | 605 @implementation AutofillSectionContainer (ForTesting) |
| 606 | 606 |
| 607 - (NSControl*)getField:(autofill::AutofillFieldType)type { | 607 - (NSControl*)getField:(autofill::ServerFieldType)type { |
| 608 return [inputs_ viewWithTag:type]; | 608 return [inputs_ viewWithTag:type]; |
| 609 } | 609 } |
| 610 | 610 |
| 611 - (void)setFieldValue:(NSString*)text | 611 - (void)setFieldValue:(NSString*)text |
| 612 forInput:(const autofill::DetailInput&)input { | 612 forInput:(const autofill::DetailInput&)input { |
| 613 if ([self detailInputForType:input.type] != &input) | 613 if ([self detailInputForType:input.type] != &input) |
| 614 return; | 614 return; |
| 615 | 615 |
| 616 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; | 616 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; |
| 617 [field setFieldValue:text]; | 617 [field setFieldValue:text]; |
| 618 } | 618 } |
| 619 | 619 |
| 620 - (void)setSuggestionFieldValue:(NSString*)text { | 620 - (void)setSuggestionFieldValue:(NSString*)text { |
| 621 [[suggestContainer_ inputField] setFieldValue:text]; | 621 [[suggestContainer_ inputField] setFieldValue:text]; |
| 622 } | 622 } |
| 623 | 623 |
| 624 - (void)activateFieldForInput:(const autofill::DetailInput&)input { | 624 - (void)activateFieldForInput:(const autofill::DetailInput&)input { |
| 625 if ([self detailInputForType:input.type] != &input) | 625 if ([self detailInputForType:input.type] != &input) |
| 626 return; | 626 return; |
| 627 | 627 |
| 628 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; | 628 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; |
| 629 [[field window] makeFirstResponder:field]; | 629 [[field window] makeFirstResponder:field]; |
| 630 } | 630 } |
| 631 | 631 |
| 632 @end | 632 @end |
| OLD | NEW |