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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 // Return YES if this is a section that contains CC info. (And, more | 96 // Return YES if this is a section that contains CC info. (And, more |
97 // importantly, a potential CVV field) | 97 // importantly, a potential CVV field) |
98 - (BOOL)isCreditCardSection; | 98 - (BOOL)isCreditCardSection; |
99 | 99 |
100 // Create properly styled label for section. Autoreleased. | 100 // Create properly styled label for section. Autoreleased. |
101 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText; | 101 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText; |
102 | 102 |
103 // Create a button offering input suggestions. | 103 // Create a button offering input suggestions. |
104 - (MenuButton*)makeSuggestionButton; | 104 - (MenuButton*)makeSuggestionButton; |
105 | 105 |
106 // Create a view with all inputs requested by |delegate_|. Autoreleased. | 106 // Create a view with all inputs requested by |delegate_| and resets |input_|. |
groby-ooo-7-16
2013/12/05 02:56:10
Should probably mention that it replaces the old i
| |
107 - (LayoutView*)makeInputControls; | 107 - (void)makeInputControls; |
108 | 108 |
109 // Refresh all field icons based on |delegate_| status. | 109 // Refresh all field icons based on |delegate_| status. |
110 - (void)updateFieldIcons; | 110 - (void)updateFieldIcons; |
111 | 111 |
112 // Refresh the enabled/disabled state of all input fields. | 112 // Refresh the enabled/disabled state of all input fields. |
113 - (void)updateEditability; | 113 - (void)updateEditability; |
114 | 114 |
115 @end | 115 @end |
116 | 116 |
117 @implementation AutofillSectionContainer | 117 @implementation AutofillSectionContainer |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 if (![[self view] isHidden]) | 151 if (![[self view] isHidden]) |
152 [self validateFor:autofill::VALIDATE_EDIT]; | 152 [self validateFor:autofill::VALIDATE_EDIT]; |
153 | 153 |
154 // Always request re-layout on state change. | 154 // Always request re-layout on state change. |
155 id delegate = [[view_ window] windowController]; | 155 id delegate = [[view_ window] windowController]; |
156 if ([delegate respondsToSelector:@selector(requestRelayout)]) | 156 if ([delegate respondsToSelector:@selector(requestRelayout)]) |
157 [delegate performSelector:@selector(requestRelayout)]; | 157 [delegate performSelector:@selector(requestRelayout)]; |
158 } | 158 } |
159 | 159 |
160 - (void)loadView { | 160 - (void)loadView { |
161 // Keep a list of weak pointers to DetailInputs. | 161 [self makeInputControls]; |
162 const autofill::DetailInputs& inputs = | |
163 delegate_->RequestedFieldsForSection(section_); | |
164 | |
165 // Reverse the order of all the inputs. | |
166 for (int i = inputs.size() - 1; i >= 0; --i) { | |
167 detailInputs_.push_back(&(inputs[i])); | |
168 } | |
169 | |
170 // Then right the reversal in each row. | |
171 std::vector<const autofill::DetailInput*>::iterator it; | |
172 for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) { | |
173 std::vector<const autofill::DetailInput*>::iterator start = it; | |
174 while (it != detailInputs_.end() && | |
175 (*it)->length != autofill::DetailInput::LONG) { | |
176 ++it; | |
177 } | |
178 std::reverse(start, it); | |
179 } | |
180 | |
181 inputs_.reset([[self makeInputControls] retain]); | |
182 string16 labelText = delegate_->LabelForSection(section_); | 162 string16 labelText = delegate_->LabelForSection(section_); |
183 label_.reset( | 163 label_.reset( |
184 [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)] | 164 [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)] |
185 retain]); | 165 retain]); |
186 | 166 |
187 suggestButton_.reset([[self makeSuggestionButton] retain]); | 167 suggestButton_.reset([[self makeSuggestionButton] retain]); |
188 suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]); | 168 suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]); |
189 | 169 |
190 view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]); | 170 view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]); |
191 [self setView:view_]; | 171 [self setView:view_]; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 [validationDelegate_ updateMessageForField:field]; | 262 [validationDelegate_ updateMessageForField:field]; |
283 } | 263 } |
284 | 264 |
285 - (void)didChange:(id)sender { | 265 - (void)didChange:(id)sender { |
286 [self textfieldEditedOrActivated:sender edited:YES]; | 266 [self textfieldEditedOrActivated:sender edited:YES]; |
287 } | 267 } |
288 | 268 |
289 - (void)didEndEditing:(id)sender { | 269 - (void)didEndEditing:(id)sender { |
290 delegate_->FocusMoved(); | 270 delegate_->FocusMoved(); |
291 [validationDelegate_ hideErrorBubble]; | 271 [validationDelegate_ hideErrorBubble]; |
272 | |
273 AutofillPopUpButton* popup = base::mac::ObjCCast<AutofillPopUpButton>(sender); | |
274 if (popup) { | |
275 // Add one to account for the spacer at the top of the list. | |
276 int index = [popup indexOfSelectedItem] + 1; | |
277 delegate_->ComboboxItemSelected([self fieldTypeForControl:popup], index); | |
278 } | |
279 | |
292 [self validateFor:autofill::VALIDATE_EDIT]; | 280 [self validateFor:autofill::VALIDATE_EDIT]; |
293 [self updateEditability]; | 281 [self updateEditability]; |
294 } | 282 } |
295 | 283 |
296 - (void)updateSuggestionState { | 284 - (void)updateSuggestionState { |
297 const autofill::SuggestionState& suggestionState = | 285 const autofill::SuggestionState& suggestionState = |
298 delegate_->SuggestionStateForSection(section_); | 286 delegate_->SuggestionStateForSection(section_); |
299 // TODO(estade): use |vertically_compact_text| when it fits. | 287 // TODO(estade): use |vertically_compact_text| when it fits. |
300 const base::string16& text = suggestionState.horizontally_compact_text; | 288 const base::string16& text = suggestionState.horizontally_compact_text; |
301 showSuggestions_ = suggestionState.visible; | 289 showSuggestions_ = suggestionState.visible; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
483 toHaveTrait:NSBoldFontMask]]; | 471 toHaveTrait:NSBoldFontMask]]; |
484 [label setStringValue:labelText]; | 472 [label setStringValue:labelText]; |
485 [label setEditable:NO]; | 473 [label setEditable:NO]; |
486 [label setBordered:NO]; | 474 [label setBordered:NO]; |
487 [label setDrawsBackground:NO]; | 475 [label setDrawsBackground:NO]; |
488 [label sizeToFit]; | 476 [label sizeToFit]; |
489 return label.autorelease(); | 477 return label.autorelease(); |
490 } | 478 } |
491 | 479 |
492 - (void)updateAndClobber:(BOOL)shouldClobber { | 480 - (void)updateAndClobber:(BOOL)shouldClobber { |
481 if (shouldClobber) | |
482 [self makeInputControls]; | |
483 | |
493 const autofill::DetailInputs& updatedInputs = | 484 const autofill::DetailInputs& updatedInputs = |
494 delegate_->RequestedFieldsForSection(section_); | 485 delegate_->RequestedFieldsForSection(section_); |
495 | 486 |
496 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); | 487 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); |
497 iter != updatedInputs.end(); | 488 iter != updatedInputs.end(); |
498 ++iter) { | 489 ++iter) { |
499 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; | 490 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; |
500 DCHECK(field); | 491 DCHECK(field); |
501 | 492 |
502 if (shouldClobber || [field isDefault]) { | 493 if (shouldClobber || [field isDefault]) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
540 [[button cell] setImage:image | 531 [[button cell] setImage:image |
541 forButtonState:image_button_cell::kDisabledState]; | 532 forButtonState:image_button_cell::kDisabledState]; |
542 | 533 |
543 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501) | 534 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501) |
544 [button setFrameSize:[image size]]; | 535 [button setFrameSize:[image size]]; |
545 return button.autorelease(); | 536 return button.autorelease(); |
546 } | 537 } |
547 | 538 |
548 // TODO(estade): we should be using Chrome-style constrained window padding | 539 // TODO(estade): we should be using Chrome-style constrained window padding |
549 // values. | 540 // values. |
550 - (LayoutView*)makeInputControls { | 541 - (void)makeInputControls { |
542 detailInputs_.clear(); | |
543 | |
544 // Keep a list of weak pointers to DetailInputs. | |
545 const autofill::DetailInputs& inputs = | |
546 delegate_->RequestedFieldsForSection(section_); | |
547 | |
548 // Reverse the order of all the inputs. | |
549 for (int i = inputs.size() - 1; i >= 0; --i) { | |
550 detailInputs_.push_back(&(inputs[i])); | |
551 } | |
552 | |
553 // Then right the reversal in each row. | |
554 std::vector<const autofill::DetailInput*>::iterator it; | |
555 for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) { | |
556 std::vector<const autofill::DetailInput*>::iterator start = it; | |
557 while (it != detailInputs_.end() && | |
558 (*it)->length != autofill::DetailInput::LONG) { | |
559 ++it; | |
560 } | |
561 std::reverse(start, it); | |
562 } | |
563 | |
551 base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]); | 564 base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]); |
552 [view setLayoutManager: | 565 [view setLayoutManager: |
553 scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))]; | 566 scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))]; |
554 SimpleGridLayout* layout = [view layoutManager]; | 567 SimpleGridLayout* layout = [view layoutManager]; |
555 | 568 |
556 int column_set_id = 0; | 569 int column_set_id = 0; |
557 for (size_t i = 0; i < detailInputs_.size(); ++i) { | 570 for (size_t i = 0; i < detailInputs_.size(); ++i) { |
558 const autofill::DetailInput& input = *detailInputs_[i]; | 571 const autofill::DetailInput& input = *detailInputs_[i]; |
559 | 572 |
560 if (input.length == autofill::DetailInput::LONG) | 573 if (input.length == autofill::DetailInput::LONG) |
(...skipping 29 matching lines...) Expand all Loading... | |
590 [popup addItemWithTitle: | 603 [popup addItemWithTitle: |
591 base::SysUTF16ToNSString(inputModel->GetItemAt(i))]; | 604 base::SysUTF16ToNSString(inputModel->GetItemAt(i))]; |
592 } | 605 } |
593 [popup setDefaultValue:base::SysUTF16ToNSString( | 606 [popup setDefaultValue:base::SysUTF16ToNSString( |
594 inputModel->GetItemAt(inputModel->GetDefaultIndex()))]; | 607 inputModel->GetItemAt(inputModel->GetDefaultIndex()))]; |
595 control.reset(popup.release()); | 608 control.reset(popup.release()); |
596 } else { | 609 } else { |
597 base::scoped_nsobject<AutofillTextField> field( | 610 base::scoped_nsobject<AutofillTextField> field( |
598 [[AutofillTextField alloc] init]); | 611 [[AutofillTextField alloc] init]); |
599 [[field cell] setPlaceholderString: | 612 [[field cell] setPlaceholderString: |
600 l10n_util::GetNSStringWithFixup(input.placeholder_text_rid)]; | 613 base::SysUTF16ToNSString(input.placeholder_text)]; |
601 [field setDefaultValue:@""]; | 614 [field setDefaultValue:@""]; |
602 control.reset(field.release()); | 615 control.reset(field.release()); |
603 } | 616 } |
604 [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)]; | 617 [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)]; |
605 [control sizeToFit]; | 618 [control sizeToFit]; |
606 [control setTag:input.type]; | 619 [control setTag:input.type]; |
607 [control setInputDelegate:self]; | 620 [control setInputDelegate:self]; |
608 // Hide away fields that cannot be edited. | 621 // Hide away fields that cannot be edited. |
609 if (kColumnSetId == -1) { | 622 if (kColumnSetId == -1) { |
610 [control setFrame:NSZeroRect]; | 623 [control setFrame:NSZeroRect]; |
611 [control setHidden:YES]; | 624 [control setHidden:YES]; |
612 } | 625 } |
613 layout->AddView(control); | 626 layout->AddView(control); |
614 | 627 |
615 if (input.length == autofill::DetailInput::LONG) | 628 if (input.length == autofill::DetailInput::LONG || |
629 input.length == autofill::DetailInput::SHORT_EOL) { | |
616 ++column_set_id; | 630 ++column_set_id; |
631 } | |
617 } | 632 } |
618 | 633 |
619 [self updateFieldIcons]; | 634 [self updateFieldIcons]; |
groby-ooo-7-16
2013/12/05 02:56:10
This must be called _after_ updating inputs_ - upd
| |
620 return view.autorelease(); | 635 |
636 if (inputs_) | |
637 [[self view] replaceSubview:inputs_ with:view]; | |
638 | |
639 inputs_ = view; | |
621 } | 640 } |
622 | 641 |
623 - (void)updateFieldIcons { | 642 - (void)updateFieldIcons { |
624 autofill::FieldValueMap fieldValues; | 643 autofill::FieldValueMap fieldValues; |
625 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { | 644 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { |
626 DCHECK([input isKindOfClass:[NSControl class]]); | 645 DCHECK([input isKindOfClass:[NSControl class]]); |
627 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); | 646 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); |
628 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; | 647 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; |
629 NSString* value = [input fieldValue]; | 648 NSString* value = [input fieldValue]; |
630 fieldValues[fieldType] = base::SysNSStringToUTF16(value); | 649 fieldValues[fieldType] = base::SysNSStringToUTF16(value); |
631 } | 650 } |
632 | 651 |
633 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); | 652 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); |
634 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); | 653 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); |
635 iter!= fieldIcons.end(); ++iter) { | 654 iter!= fieldIcons.end(); ++iter) { |
636 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( | 655 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( |
637 [inputs_ viewWithTag:iter->first]); | 656 [inputs_ viewWithTag:iter->first]); |
638 [[textfield cell] setIcon:iter->second.ToNSImage()]; | 657 [[textfield cell] setIcon:iter->second.ToNSImage()]; |
639 } | 658 } |
640 } | 659 } |
641 | 660 |
642 - (void)updateEditability { | 661 - (void)updateEditability { |
643 | 662 |
644 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); | 663 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); |
645 [self addInputsToArray:controls]; | 664 [self addInputsToArray:controls]; |
646 for (NSControl<AutofillInputField>* control in controls.get()) { | 665 for (NSControl<AutofillInputField>* control in controls.get()) { |
647 autofill::ServerFieldType type = [self fieldTypeForControl:control]; | 666 autofill::ServerFieldType type = [self fieldTypeForControl:control]; |
648 const autofill::DetailInput* input = [self detailInputForType:type]; | 667 const autofill::DetailInput* input = [self detailInputForType:type]; |
groby-ooo-7-16
2013/12/05 02:56:10
Why can this now be zero?
| |
649 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; | 668 if (input) |
669 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; | |
650 } | 670 } |
651 } | 671 } |
652 | 672 |
653 @end | 673 @end |
654 | 674 |
655 | 675 |
656 @implementation AutofillSectionContainer (ForTesting) | 676 @implementation AutofillSectionContainer (ForTesting) |
657 | 677 |
658 - (NSControl*)getField:(autofill::ServerFieldType)type { | 678 - (NSControl*)getField:(autofill::ServerFieldType)type { |
659 return [inputs_ viewWithTag:type]; | 679 return [inputs_ viewWithTag:type]; |
(...skipping 15 matching lines...) Expand all Loading... | |
675 - (void)activateFieldForInput:(const autofill::DetailInput&)input { | 695 - (void)activateFieldForInput:(const autofill::DetailInput&)input { |
676 if ([self detailInputForType:input.type] != &input) | 696 if ([self detailInputForType:input.type] != &input) |
677 return; | 697 return; |
678 | 698 |
679 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; | 699 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:input.type]; |
680 [[field window] makeFirstResponder:field]; | 700 [[field window] makeFirstResponder:field]; |
681 [self textfieldEditedOrActivated:field edited:NO]; | 701 [self textfieldEditedOrActivated:field edited:NO]; |
682 } | 702 } |
683 | 703 |
684 @end | 704 @end |
OLD | NEW |