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 |