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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 | 110 |
111 // Create a button offering input suggestions. | 111 // Create a button offering input suggestions. |
112 - (MenuButton*)makeSuggestionButton; | 112 - (MenuButton*)makeSuggestionButton; |
113 | 113 |
114 // Create a view with all inputs requested by |delegate_|. Autoreleased. | 114 // Create a view with all inputs requested by |delegate_|. Autoreleased. |
115 - (LayoutView*)makeInputControls; | 115 - (LayoutView*)makeInputControls; |
116 | 116 |
117 // Refresh all field icons based on |delegate_| status. | 117 // Refresh all field icons based on |delegate_| status. |
118 - (void)updateFieldIcons; | 118 - (void)updateFieldIcons; |
119 | 119 |
| 120 // Refresh the enabled/disabled state of all input fields. |
| 121 - (void)updateEditability; |
| 122 |
120 @end | 123 @end |
121 | 124 |
122 @implementation AutofillSectionContainer | 125 @implementation AutofillSectionContainer |
123 | 126 |
124 @synthesize section = section_; | 127 @synthesize section = section_; |
125 @synthesize validationDelegate = validationDelegate_; | 128 @synthesize validationDelegate = validationDelegate_; |
126 | 129 |
127 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate | 130 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate |
128 forSection:(autofill::DialogSection)section { | 131 forSection:(autofill::DialogSection)section { |
129 if (self = [super init]) { | 132 if (self = [super init]) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 } | 278 } |
276 | 279 |
277 - (void)didChange:(id)sender { | 280 - (void)didChange:(id)sender { |
278 [self textfieldEditedOrActivated:sender edited:YES]; | 281 [self textfieldEditedOrActivated:sender edited:YES]; |
279 } | 282 } |
280 | 283 |
281 - (void)didEndEditing:(id)sender { | 284 - (void)didEndEditing:(id)sender { |
282 delegate_->FocusMoved(); | 285 delegate_->FocusMoved(); |
283 [validationDelegate_ hideErrorBubble]; | 286 [validationDelegate_ hideErrorBubble]; |
284 [self validateFor:autofill::VALIDATE_EDIT]; | 287 [self validateFor:autofill::VALIDATE_EDIT]; |
| 288 [self updateEditability]; |
285 } | 289 } |
286 | 290 |
287 - (void)updateSuggestionState { | 291 - (void)updateSuggestionState { |
288 const autofill::SuggestionState& suggestionState = | 292 const autofill::SuggestionState& suggestionState = |
289 delegate_->SuggestionStateForSection(section_); | 293 delegate_->SuggestionStateForSection(section_); |
290 // TODO(estade): use |vertically_compact_text| when it fits. | 294 // TODO(estade): use |vertically_compact_text| when it fits. |
291 const base::string16& text = suggestionState.horizontally_compact_text; | 295 const base::string16& text = suggestionState.horizontally_compact_text; |
292 showSuggestions_ = suggestionState.visible; | 296 showSuggestions_ = suggestionState.visible; |
293 | 297 |
294 [suggestContainer_ setSuggestionText:base::SysUTF16ToNSString(text) | 298 [suggestContainer_ setSuggestionText:base::SysUTF16ToNSString(text) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 376 |
373 return !messages.HasErrors(); | 377 return !messages.HasErrors(); |
374 } | 378 } |
375 | 379 |
376 - (NSString*)suggestionText { | 380 - (NSString*)suggestionText { |
377 return showSuggestions_ ? [[suggestContainer_ inputField] stringValue] : nil; | 381 return showSuggestions_ ? [[suggestContainer_ inputField] stringValue] : nil; |
378 } | 382 } |
379 | 383 |
380 - (void)addInputsToArray:(NSMutableArray*)array { | 384 - (void)addInputsToArray:(NSMutableArray*)array { |
381 [array addObjectsFromArray:[inputs_ subviews]]; | 385 [array addObjectsFromArray:[inputs_ subviews]]; |
382 [array addObject:[suggestContainer_ inputField]]; | 386 |
| 387 // Only credit card sections can have a suggestion input. |
| 388 if ([self isCreditCardSection]) |
| 389 [array addObject:[suggestContainer_ inputField]]; |
383 } | 390 } |
384 | 391 |
385 #pragma mark Internal API for AutofillSectionContainer. | 392 #pragma mark Internal API for AutofillSectionContainer. |
386 | 393 |
387 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field | 394 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
388 edited:(BOOL)edited { | 395 edited:(BOOL)edited { |
389 AutofillTextField* textfield = | 396 AutofillTextField* textfield = |
390 base::mac::ObjCCastStrict<AutofillTextField>(field); | 397 base::mac::ObjCCastStrict<AutofillTextField>(field); |
391 | 398 |
392 // This only applies to textfields. | 399 // This only applies to textfields. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 435 |
429 // If the field transitioned from invalid to valid, re-validate the group, | 436 // If the field transitioned from invalid to valid, re-validate the group, |
430 // since inter-field checks become meaningful with valid fields. | 437 // since inter-field checks become meaningful with valid fields. |
431 if (![textfield invalid]) | 438 if (![textfield invalid]) |
432 [self validateFor:autofill::VALIDATE_EDIT]; | 439 [self validateFor:autofill::VALIDATE_EDIT]; |
433 } | 440 } |
434 | 441 |
435 // Update the icon if necessary. | 442 // Update the icon if necessary. |
436 if (delegate_->FieldControlsIcons(type)) | 443 if (delegate_->FieldControlsIcons(type)) |
437 [self updateFieldIcons]; | 444 [self updateFieldIcons]; |
| 445 [self updateEditability]; |
438 } | 446 } |
439 | 447 |
440 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { | 448 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { |
441 DCHECK([control tag]); | 449 DCHECK([control tag]); |
442 return static_cast<autofill::ServerFieldType>([control tag]); | 450 return static_cast<autofill::ServerFieldType>([control tag]); |
443 } | 451 } |
444 | 452 |
445 - (const autofill::DetailInput*)detailInputForType: | 453 - (const autofill::DetailInput*)detailInputForType: |
446 (autofill::ServerFieldType)type { | 454 (autofill::ServerFieldType)type { |
447 for (size_t i = 0; i < detailInputs_.size(); ++i) { | 455 for (size_t i = 0; i < detailInputs_.size(); ++i) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 - (void)updateAndClobber:(BOOL)shouldClobber { | 490 - (void)updateAndClobber:(BOOL)shouldClobber { |
483 const autofill::DetailInputs& updatedInputs = | 491 const autofill::DetailInputs& updatedInputs = |
484 delegate_->RequestedFieldsForSection(section_); | 492 delegate_->RequestedFieldsForSection(section_); |
485 | 493 |
486 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); | 494 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); |
487 iter != updatedInputs.end(); | 495 iter != updatedInputs.end(); |
488 ++iter) { | 496 ++iter) { |
489 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; | 497 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; |
490 DCHECK(field); | 498 DCHECK(field); |
491 | 499 |
492 // TODO(groby): We need to account for the fact editability state can change | |
493 // after any input in the same section is edited by the user. | |
494 [field setEnabled:delegate_->InputIsEditable(*iter, section_)]; | |
495 | |
496 if (shouldClobber || [field isDefault]) { | 500 if (shouldClobber || [field isDefault]) { |
497 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; | 501 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; |
498 } | 502 } |
499 if (shouldClobber) | 503 if (shouldClobber) |
500 [field setValidityMessage:@""]; | 504 [field setValidityMessage:@""]; |
501 } | 505 } |
| 506 [self updateEditability]; |
502 [self updateFieldIcons]; | 507 [self updateFieldIcons]; |
503 [self modelChanged]; | 508 [self modelChanged]; |
504 } | 509 } |
505 | 510 |
506 - (BOOL)isCreditCardSection { | 511 - (BOOL)isCreditCardSection { |
507 return section_ == autofill::SECTION_CC || | 512 return section_ == autofill::SECTION_CC || |
508 section_ == autofill::SECTION_CC_BILLING; | 513 section_ == autofill::SECTION_CC_BILLING; |
509 } | 514 } |
510 | 515 |
511 - (MenuButton*)makeSuggestionButton { | 516 - (MenuButton*)makeSuggestionButton { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 625 |
621 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); | 626 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); |
622 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); | 627 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); |
623 iter!= fieldIcons.end(); ++iter) { | 628 iter!= fieldIcons.end(); ++iter) { |
624 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( | 629 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( |
625 [inputs_ viewWithTag:iter->first]); | 630 [inputs_ viewWithTag:iter->first]); |
626 [[textfield cell] setIcon:iter->second.ToNSImage()]; | 631 [[textfield cell] setIcon:iter->second.ToNSImage()]; |
627 } | 632 } |
628 } | 633 } |
629 | 634 |
| 635 - (void)updateEditability { |
| 636 |
| 637 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); |
| 638 [self addInputsToArray:controls]; |
| 639 for (NSControl<AutofillInputField>* control in controls.get()) { |
| 640 autofill::ServerFieldType type = [self fieldTypeForControl:control]; |
| 641 const autofill::DetailInput* input = [self detailInputForType:type]; |
| 642 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; |
| 643 } |
| 644 } |
| 645 |
630 @end | 646 @end |
631 | 647 |
632 | 648 |
633 @implementation AutofillSectionContainer (ForTesting) | 649 @implementation AutofillSectionContainer (ForTesting) |
634 | 650 |
635 - (NSControl*)getField:(autofill::ServerFieldType)type { | 651 - (NSControl*)getField:(autofill::ServerFieldType)type { |
636 return [inputs_ viewWithTag:type]; | 652 return [inputs_ viewWithTag:type]; |
637 } | 653 } |
638 | 654 |
639 - (void)setFieldValue:(NSString*)text | 655 - (void)setFieldValue:(NSString*)text |
(...skipping 12 matching lines...) Expand all Loading... |
652 - (void)activateFieldForInput:(const autofill::DetailInput&)input { | 668 - (void)activateFieldForInput:(const autofill::DetailInput&)input { |
653 if ([self detailInputForType:input.type] != &input) | 669 if ([self detailInputForType:input.type] != &input) |
654 return; | 670 return; |
655 | 671 |
656 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; | 672 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; |
657 [[field window] makeFirstResponder:field]; | 673 [[field window] makeFirstResponder:field]; |
658 [self textfieldEditedOrActivated:field edited:NO]; | 674 [self textfieldEditedOrActivated:field edited:NO]; |
659 } | 675 } |
660 | 676 |
661 @end | 677 @end |
OLD | NEW |