Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: chrome/browser/ui/cocoa/autofill/autofill_section_container.mm

Issue 124533003: Add country combobox to change country and rebuild address inputs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mac Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
65 return true; 65 return true;
66 } 66 }
67 67
68 return section == autofill::SECTION_CC_BILLING; 68 return section == autofill::SECTION_CC_BILLING;
69 } 69 }
70 70
71 } // namespace 71 } // namespace
72 72
73 @interface AutofillSectionContainer () 73 @interface AutofillSectionContainer ()
74 74
75 // A text field has been edited or activated - inform the delegate that it's 75 // An input field has been edited or activated - inform the delegate and
76 // time to show a suggestion popup & possibly reset the validity of the input. 76 // possibly reset the validity of the input (if it's a textfield).
77 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field 77 - (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field
78 edited:(BOOL)edited; 78 edited:(BOOL)edited;
79 79
80 // Convenience method to retrieve a field type via the control's tag. 80 // Convenience method to retrieve a field type via the control's tag.
81 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control; 81 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control;
82 82
83 // Find the DetailInput* associated with a field type. 83 // Find the DetailInput* associated with a field type.
84 - (const autofill::DetailInput*)detailInputForType: 84 - (const autofill::DetailInput*)detailInputForType:
85 (autofill::ServerFieldType)type; 85 (autofill::ServerFieldType)type;
86 86
87 // Takes an NSArray of controls and builds a FieldValueMap from them. 87 // Takes an NSArray of controls and builds a FieldValueMap from them.
88 // Translates between Cocoa code and delegate, essentially. 88 // Translates between Cocoa code and delegate, essentially.
89 // All controls must inherit from NSControl and conform to AutofillInputView. 89 // All controls must inherit from NSControl and conform to AutofillInputView.
90 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs 90 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs
91 fromControls:(NSArray*)controls; 91 fromControls:(NSArray*)controls;
92 92
93 // Updates input fields based on delegate status. If |shouldClobber| is YES, 93 // Updates input fields based on delegate status. If |shouldClobber| is YES,
94 // will clobber existing data and reset fields to the initial values. 94 // will clobber existing data and reset fields to the initial values.
95 - (void)updateAndClobber:(BOOL)shouldClobber; 95 - (void)updateAndClobber:(BOOL)shouldClobber;
96 96
97 // Return YES if this is a section that contains CC info. (And, more 97 // Return YES if this is a section that contains CC info. (And, more
98 // importantly, a potential CVV field) 98 // importantly, a potential CVV field)
99 - (BOOL)isCreditCardSection; 99 - (BOOL)isCreditCardSection;
100 100
101 // Create properly styled label for section. Autoreleased. 101 // Create properly styled label for section. Autoreleased.
102 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText; 102 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText;
103 103
104 // Create a button offering input suggestions. 104 // Create a button offering input suggestions.
105 - (MenuButton*)makeSuggestionButton; 105 - (MenuButton*)makeSuggestionButton;
106 106
107 // Create a view with all inputs requested by |delegate_|. Autoreleased. 107 // Create a view with all inputs requested by |delegate_| and resets |input_|.
108 - (LayoutView*)makeInputControls; 108 - (void)makeInputControls;
109 109
110 // Refresh all field icons based on |delegate_| status. 110 // Refresh all field icons based on |delegate_| status.
111 - (void)updateFieldIcons; 111 - (void)updateFieldIcons;
112 112
113 // Refresh the enabled/disabled state of all input fields. 113 // Refresh the enabled/disabled state of all input fields.
114 - (void)updateEditability; 114 - (void)updateEditability;
115 115
116 @end 116 @end
117 117
118 @implementation AutofillSectionContainer 118 @implementation AutofillSectionContainer
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 if (![[self view] isHidden]) 152 if (![[self view] isHidden])
153 [self validateFor:autofill::VALIDATE_EDIT]; 153 [self validateFor:autofill::VALIDATE_EDIT];
154 154
155 // Always request re-layout on state change. 155 // Always request re-layout on state change.
156 id delegate = [[view_ window] windowController]; 156 id delegate = [[view_ window] windowController];
157 if ([delegate respondsToSelector:@selector(requestRelayout)]) 157 if ([delegate respondsToSelector:@selector(requestRelayout)])
158 [delegate performSelector:@selector(requestRelayout)]; 158 [delegate performSelector:@selector(requestRelayout)];
159 } 159 }
160 160
161 - (void)loadView { 161 - (void)loadView {
162 // Keep a list of weak pointers to DetailInputs. 162 [self makeInputControls];
163 const autofill::DetailInputs& inputs =
164 delegate_->RequestedFieldsForSection(section_);
165 163
166 // Reverse the order of all the inputs.
167 for (int i = inputs.size() - 1; i >= 0; --i) {
168 detailInputs_.push_back(&(inputs[i]));
169 }
170
171 // Then right the reversal in each row.
172 std::vector<const autofill::DetailInput*>::iterator it;
173 for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) {
174 std::vector<const autofill::DetailInput*>::iterator start = it;
175 while (it != detailInputs_.end() &&
176 (*it)->length != autofill::DetailInput::LONG) {
177 ++it;
178 }
179 std::reverse(start, it);
180 }
181
182 inputs_.reset([[self makeInputControls] retain]);
183 base::string16 labelText = delegate_->LabelForSection(section_); 164 base::string16 labelText = delegate_->LabelForSection(section_);
184 label_.reset( 165 label_.reset(
185 [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)] 166 [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)]
186 retain]); 167 retain]);
187 168
188 suggestButton_.reset([[self makeSuggestionButton] retain]); 169 suggestButton_.reset([[self makeSuggestionButton] retain]);
189 suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]); 170 suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]);
190 171
191 view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]); 172 view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]);
192 [self setView:view_]; 173 [self setView:view_];
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 if (webEvent.type != content::NativeWebKeyboardEvent::RawKeyDown) 262 if (webEvent.type != content::NativeWebKeyboardEvent::RawKeyDown)
282 return kKeyEventNotHandled; 263 return kKeyEventNotHandled;
283 264
284 // Allow the delegate to intercept key messages. 265 // Allow the delegate to intercept key messages.
285 if (delegate_->HandleKeyPressEventInInput(webEvent)) 266 if (delegate_->HandleKeyPressEventInInput(webEvent))
286 return kKeyEventHandled; 267 return kKeyEventHandled;
287 return kKeyEventNotHandled; 268 return kKeyEventNotHandled;
288 } 269 }
289 270
290 - (void)onMouseDown:(NSControl<AutofillInputField>*)field { 271 - (void)onMouseDown:(NSControl<AutofillInputField>*)field {
291 [self textfieldEditedOrActivated:field edited:NO]; 272 [self fieldEditedOrActivated:field edited:NO];
292 [validationDelegate_ updateMessageForField:field]; 273 [validationDelegate_ updateMessageForField:field];
293 } 274 }
294 275
295 - (void)fieldBecameFirstResponder:(NSControl<AutofillInputField>*)field { 276 - (void)fieldBecameFirstResponder:(NSControl<AutofillInputField>*)field {
296 [validationDelegate_ updateMessageForField:field]; 277 [validationDelegate_ updateMessageForField:field];
297 } 278 }
298 279
299 - (void)didChange:(id)sender { 280 - (void)didChange:(id)sender {
300 [self textfieldEditedOrActivated:sender edited:YES]; 281 [self fieldEditedOrActivated:sender edited:YES];
301 } 282 }
302 283
303 - (void)didEndEditing:(id)sender { 284 - (void)didEndEditing:(id)sender {
304 delegate_->FocusMoved(); 285 delegate_->FocusMoved();
305 [validationDelegate_ hideErrorBubble]; 286 [validationDelegate_ hideErrorBubble];
306 [self validateFor:autofill::VALIDATE_EDIT]; 287 [self validateFor:autofill::VALIDATE_EDIT];
307 [self updateEditability]; 288 [self updateEditability];
308 } 289 }
309 290
310 - (void)updateSuggestionState { 291 - (void)updateSuggestionState {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 - (void)addInputsToArray:(NSMutableArray*)array { 393 - (void)addInputsToArray:(NSMutableArray*)array {
413 [array addObjectsFromArray:[inputs_ subviews]]; 394 [array addObjectsFromArray:[inputs_ subviews]];
414 395
415 // Only credit card sections can have a suggestion input. 396 // Only credit card sections can have a suggestion input.
416 if ([self isCreditCardSection]) 397 if ([self isCreditCardSection])
417 [array addObject:[suggestContainer_ inputField]]; 398 [array addObject:[suggestContainer_ inputField]];
418 } 399 }
419 400
420 #pragma mark Internal API for AutofillSectionContainer. 401 #pragma mark Internal API for AutofillSectionContainer.
421 402
422 - (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field 403 - (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field
423 edited:(BOOL)edited { 404 edited:(BOOL)edited {
424 AutofillTextField* textfield =
425 base::mac::ObjCCastStrict<AutofillTextField>(field);
426
427 // This only applies to textfields.
428 if (!textfield)
429 return;
430
431 autofill::ServerFieldType type = [self fieldTypeForControl:field]; 405 autofill::ServerFieldType type = [self fieldTypeForControl:field];
432 base::string16 fieldValue = base::SysNSStringToUTF16([textfield fieldValue]); 406 base::string16 fieldValue = base::SysNSStringToUTF16([field fieldValue]);
433 407
434 // Get the frame rectangle for the designated field, in screen coordinates. 408 // Get the frame rectangle for the designated field, in screen coordinates.
435 NSRect textFrameInScreen = [field convertRect:[field bounds] toView:nil]; 409 NSRect textFrameInScreen = [field convertRect:[field bounds] toView:nil];
436 textFrameInScreen.origin = 410 textFrameInScreen.origin =
437 [[field window] convertBaseToScreen:textFrameInScreen.origin]; 411 [[field window] convertBaseToScreen:textFrameInScreen.origin];
438 412
439 // And adjust for gfx::Rect being flipped compared to OSX coordinates. 413 // And adjust for gfx::Rect being flipped compared to OSX coordinates.
440 NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; 414 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
441 textFrameInScreen.origin.y = 415 textFrameInScreen.origin.y =
442 NSMaxY([screen frame]) - NSMaxY(textFrameInScreen); 416 NSMaxY([screen frame]) - NSMaxY(textFrameInScreen);
443 gfx::Rect textFrameRect(NSRectToCGRect(textFrameInScreen)); 417 gfx::Rect textFrameRect(NSRectToCGRect(textFrameInScreen));
444 418
445 delegate_->UserEditedOrActivatedInput(section_, 419 delegate_->UserEditedOrActivatedInput(section_,
446 type, 420 type,
447 [self view], 421 [self view],
448 textFrameRect, 422 textFrameRect,
449 fieldValue, 423 fieldValue,
450 edited); 424 edited);
451 425
452 // If the field is marked as invalid, check if the text is now valid. 426 AutofillTextField* textfield = base::mac::ObjCCast<AutofillTextField>(field);
453 // Many fields (i.e. CC#) are invalid for most of the duration of editing,
454 // so flagging them as invalid prematurely is not helpful. However,
455 // correcting a minor mistake (i.e. a wrong CC digit) should immediately
456 // result in validation - positive user feedback.
457 if ([textfield invalid] && edited) {
458 base::string16 message = delegate_->InputValidityMessage(section_,
459 type,
460 fieldValue);
461 [textfield setValidityMessage:base::SysUTF16ToNSString(message)];
462 [validationDelegate_ updateMessageForField:textfield];
463 427
464 // If the field transitioned from invalid to valid, re-validate the group, 428 // This only applies to textfields.
465 // since inter-field checks become meaningful with valid fields. 429 if (textfield) {
groby-ooo-7-16 2014/01/14 19:37:07 You can skip this if - [textfield invalid] will ev
Dan Beam 2014/01/15 03:10:48 we talked about this offline and will change after
466 if (![textfield invalid]) 430 // If the field is marked as invalid, check if the text is now valid.
467 [self validateFor:autofill::VALIDATE_EDIT]; 431 // Many fields (i.e. CC#) are invalid for most of the duration of editing,
432 // so flagging them as invalid prematurely is not helpful. However,
433 // correcting a minor mistake (i.e. a wrong CC digit) should immediately
434 // result in validation - positive user feedback.
435 if ([textfield invalid] && edited) {
436 base::string16 message = delegate_->InputValidityMessage(section_,
437 type,
438 fieldValue);
439 [textfield setValidityMessage:base::SysUTF16ToNSString(message)];
440 [validationDelegate_ updateMessageForField:textfield];
441
442 // If the field transitioned from invalid to valid, re-validate the group,
443 // since inter-field checks become meaningful with valid fields.
444 if (![textfield invalid])
445 [self validateFor:autofill::VALIDATE_EDIT];
446 }
468 } 447 }
469 448
470 // Update the icon if necessary. 449 // Update the icon if necessary.
471 if (delegate_->FieldControlsIcons(type)) 450 if (delegate_->FieldControlsIcons(type))
472 [self updateFieldIcons]; 451 [self updateFieldIcons];
473 [self updateEditability]; 452 [self updateEditability];
474 } 453 }
475 454
476 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { 455 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control {
477 DCHECK([control tag]); 456 DCHECK([control tag]);
478 return static_cast<autofill::ServerFieldType>([control tag]); 457 return static_cast<autofill::ServerFieldType>([control tag]);
479 } 458 }
480 459
481 - (const autofill::DetailInput*)detailInputForType: 460 - (const autofill::DetailInput*)detailInputForType:
482 (autofill::ServerFieldType)type { 461 (autofill::ServerFieldType)type {
483 for (size_t i = 0; i < detailInputs_.size(); ++i) { 462 for (size_t i = 0; i < detailInputs_.size(); ++i) {
484 if (detailInputs_[i]->type == type) 463 if (detailInputs_[i]->type == type)
485 return detailInputs_[i]; 464 return detailInputs_[i];
486 } 465 }
487 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests 466 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests
488 // blindly call setFieldValue:forInput:, even for non-existing inputs. 467 // blindly call setFieldValue:forType:, even for non-existing inputs.
489 return NULL; 468 return NULL;
490 } 469 }
491 470
492 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs 471 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs
493 fromControls:(NSArray*)controls { 472 fromControls:(NSArray*)controls {
494 for (NSControl<AutofillInputField>* input in controls) { 473 for (NSControl<AutofillInputField>* input in controls) {
495 DCHECK([input isKindOfClass:[NSControl class]]); 474 DCHECK([input isKindOfClass:[NSControl class]]);
496 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); 475 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]);
497 outputs->insert(std::make_pair( 476 outputs->insert(std::make_pair(
498 [self fieldTypeForControl:input], 477 [self fieldTypeForControl:input],
499 base::SysNSStringToUTF16([input fieldValue]))); 478 base::SysNSStringToUTF16([input fieldValue])));
500 } 479 }
501 } 480 }
502 481
503 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText { 482 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText {
504 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]); 483 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
505 [label setFont: 484 [label setFont:
506 [[NSFontManager sharedFontManager] convertFont:[label font] 485 [[NSFontManager sharedFontManager] convertFont:[label font]
507 toHaveTrait:NSBoldFontMask]]; 486 toHaveTrait:NSBoldFontMask]];
508 [label setStringValue:labelText]; 487 [label setStringValue:labelText];
509 [label setEditable:NO]; 488 [label setEditable:NO];
510 [label setBordered:NO]; 489 [label setBordered:NO];
511 [label setDrawsBackground:NO]; 490 [label setDrawsBackground:NO];
512 [label sizeToFit]; 491 [label sizeToFit];
513 return label.autorelease(); 492 return label.autorelease();
514 } 493 }
515 494
516 - (void)updateAndClobber:(BOOL)shouldClobber { 495 - (void)updateAndClobber:(BOOL)shouldClobber {
517 const autofill::DetailInputs& updatedInputs = 496 if (shouldClobber) {
518 delegate_->RequestedFieldsForSection(section_); 497 [self makeInputControls];
519 498
520 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); 499 id delegate = [[view_ window] windowController];
521 iter != updatedInputs.end(); 500 if ([delegate respondsToSelector:@selector(requestRelayout)]) {
522 ++iter) { 501 [delegate performSelector:@selector(requestRelayout)];
523 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; 502 }
524 DCHECK(field); 503 } else {
504 const autofill::DetailInputs& updatedInputs =
505 delegate_->RequestedFieldsForSection(section_);
525 506
526 if (shouldClobber || [field isDefault]) { 507 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin();
527 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; 508 iter != updatedInputs.end();
509 ++iter) {
510 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type];
511 DCHECK(field);
512 if ([field isDefault])
513 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)];
528 } 514 }
529 if (shouldClobber) 515 [self updateFieldIcons];
530 [field setValidityMessage:@""];
531 } 516 }
517
532 [self updateEditability]; 518 [self updateEditability];
533 [self updateFieldIcons];
534 [self modelChanged]; 519 [self modelChanged];
535 } 520 }
536 521
537 - (BOOL)isCreditCardSection { 522 - (BOOL)isCreditCardSection {
538 return section_ == autofill::SECTION_CC || 523 return section_ == autofill::SECTION_CC ||
539 section_ == autofill::SECTION_CC_BILLING; 524 section_ == autofill::SECTION_CC_BILLING;
540 } 525 }
541 526
542 - (MenuButton*)makeSuggestionButton { 527 - (MenuButton*)makeSuggestionButton {
543 base::scoped_nsobject<MenuButton> button([[MenuButton alloc] init]); 528 base::scoped_nsobject<MenuButton> button([[MenuButton alloc] init]);
(...skipping 20 matching lines...) Expand all
564 [[button cell] setImage:image 549 [[button cell] setImage:image
565 forButtonState:image_button_cell::kDisabledState]; 550 forButtonState:image_button_cell::kDisabledState];
566 551
567 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501) 552 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501)
568 [button setFrameSize:[image size]]; 553 [button setFrameSize:[image size]];
569 return button.autorelease(); 554 return button.autorelease();
570 } 555 }
571 556
572 // TODO(estade): we should be using Chrome-style constrained window padding 557 // TODO(estade): we should be using Chrome-style constrained window padding
573 // values. 558 // values.
574 - (LayoutView*)makeInputControls { 559 - (void)makeInputControls {
560 detailInputs_.clear();
561
562 // Keep a list of weak pointers to DetailInputs.
563 const autofill::DetailInputs& inputs =
564 delegate_->RequestedFieldsForSection(section_);
565
566 // Reverse the order of all the inputs.
567 for (int i = inputs.size() - 1; i >= 0; --i) {
568 detailInputs_.push_back(&(inputs[i]));
569 }
570
571 // Then right the reversal in each row.
572 std::vector<const autofill::DetailInput*>::iterator it;
573 for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) {
574 std::vector<const autofill::DetailInput*>::iterator start = it;
575 while (it != detailInputs_.end() &&
576 (*it)->length != autofill::DetailInput::LONG) {
577 ++it;
578 }
579 std::reverse(start, it);
580 }
581
575 base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]); 582 base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]);
576 [view setLayoutManager: 583 [view setLayoutManager:
577 scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))]; 584 scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))];
578 SimpleGridLayout* layout = [view layoutManager]; 585 SimpleGridLayout* layout = [view layoutManager];
579 586
580 int column_set_id = 0; 587 int column_set_id = 0;
581 for (size_t i = 0; i < detailInputs_.size(); ++i) { 588 for (size_t i = 0; i < detailInputs_.size(); ++i) {
582 const autofill::DetailInput& input = *detailInputs_[i]; 589 const autofill::DetailInput& input = *detailInputs_[i];
583 590
584 if (input.length == autofill::DetailInput::LONG) 591 if (input.length == autofill::DetailInput::LONG)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 inputModel->GetItemAt(inputModel->GetDefaultIndex()))]; 625 inputModel->GetItemAt(inputModel->GetDefaultIndex()))];
619 control.reset(popup.release()); 626 control.reset(popup.release());
620 } else { 627 } else {
621 base::scoped_nsobject<AutofillTextField> field( 628 base::scoped_nsobject<AutofillTextField> field(
622 [[AutofillTextField alloc] init]); 629 [[AutofillTextField alloc] init]);
623 [[field cell] setPlaceholderString: 630 [[field cell] setPlaceholderString:
624 l10n_util::FixUpWindowsStyleLabel(input.placeholder_text)]; 631 l10n_util::FixUpWindowsStyleLabel(input.placeholder_text)];
625 NSString* tooltipText = 632 NSString* tooltipText =
626 base::SysUTF16ToNSString(delegate_->TooltipForField(input.type)); 633 base::SysUTF16ToNSString(delegate_->TooltipForField(input.type));
627 if ([tooltipText length] > 0) { 634 if ([tooltipText length] > 0) {
628 DCHECK(!tooltipController_); 635 if (!tooltipController_) {
629 DCHECK(!tooltipField_); 636 tooltipController_.reset(
630 tooltipController_.reset( 637 [[AutofillTooltipController alloc]
631 [[AutofillTooltipController alloc] 638 initWithArrowLocation:info_bubble::kTopRight]);
632 initWithArrowLocation:info_bubble::kTopRight]); 639 }
633 tooltipField_ = field.get(); 640 tooltipField_ = field.get();
634 NSImage* icon = 641 NSImage* icon =
635 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( 642 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
636 IDR_AUTOFILL_TOOLTIP_ICON).ToNSImage(); 643 IDR_AUTOFILL_TOOLTIP_ICON).ToNSImage();
637 [tooltipController_ setImage:icon]; 644 [tooltipController_ setImage:icon];
638 [tooltipController_ setMessage:tooltipText]; 645 [tooltipController_ setMessage:tooltipText];
639 [[field cell] setDecorationSize:[icon size]]; 646 [[field cell] setDecorationSize:[icon size]];
640 } 647 }
641 [field setDefaultValue:@""]; 648 [field setDefaultValue:@""];
642 control.reset(field.release()); 649 control.reset(field.release());
643 } 650 }
644 [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)]; 651 [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)];
645 [control sizeToFit]; 652 [control sizeToFit];
646 [control setTag:input.type]; 653 [control setTag:input.type];
647 [control setInputDelegate:self]; 654 [control setInputDelegate:self];
648 // Hide away fields that cannot be edited. 655 // Hide away fields that cannot be edited.
649 if (kColumnSetId == -1) { 656 if (kColumnSetId == -1) {
650 [control setFrame:NSZeroRect]; 657 [control setFrame:NSZeroRect];
651 [control setHidden:YES]; 658 [control setHidden:YES];
652 } 659 }
653 layout->AddView(control); 660 layout->AddView(control);
654 661
655 if (input.length == autofill::DetailInput::LONG || 662 if (input.length == autofill::DetailInput::LONG ||
656 input.length == autofill::DetailInput::SHORT_EOL) { 663 input.length == autofill::DetailInput::SHORT_EOL) {
657 ++column_set_id; 664 ++column_set_id;
658 } 665 }
659 } 666 }
660 667
661 [self updateFieldIcons]; 668 [self updateFieldIcons];
662 return view.autorelease(); 669
670 if (inputs_)
671 [[self view] replaceSubview:inputs_ with:view];
groby-ooo-7-16 2014/01/14 19:37:07 I'd post requestRelayout from here.
Dan Beam 2014/01/15 03:10:48 Done.
672
673 inputs_ = view;
663 } 674 }
664 675
665 - (void)updateFieldIcons { 676 - (void)updateFieldIcons {
666 autofill::FieldValueMap fieldValues; 677 autofill::FieldValueMap fieldValues;
667 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { 678 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) {
668 DCHECK([input isKindOfClass:[NSControl class]]); 679 DCHECK([input isKindOfClass:[NSControl class]]);
669 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); 680 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]);
670 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; 681 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input];
671 NSString* value = [input fieldValue]; 682 NSString* value = [input fieldValue];
672 fieldValues[fieldType] = base::SysNSStringToUTF16(value); 683 fieldValues[fieldType] = base::SysNSStringToUTF16(value);
673 } 684 }
674 685
675 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); 686 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues);
676 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); 687 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin();
677 iter!= fieldIcons.end(); ++iter) { 688 iter!= fieldIcons.end(); ++iter) {
678 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( 689 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>(
679 [inputs_ viewWithTag:iter->first]); 690 [inputs_ viewWithTag:iter->first]);
680 [[textfield cell] setIcon:iter->second.ToNSImage()]; 691 [[textfield cell] setIcon:iter->second.ToNSImage()];
681 } 692 }
682 } 693 }
683 694
684 - (void)updateEditability { 695 - (void)updateEditability {
685
686 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); 696 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]);
687 [self addInputsToArray:controls]; 697 [self addInputsToArray:controls];
688 for (NSControl<AutofillInputField>* control in controls.get()) { 698 for (NSControl<AutofillInputField>* control in controls.get()) {
689 autofill::ServerFieldType type = [self fieldTypeForControl:control]; 699 autofill::ServerFieldType type = [self fieldTypeForControl:control];
690 const autofill::DetailInput* input = [self detailInputForType:type]; 700 const autofill::DetailInput* input = [self detailInputForType:type];
691 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; 701 if (input)
702 [control setEnabled:delegate_->InputIsEditable(*input, section_)];
692 } 703 }
693 } 704 }
694 705
695 @end 706 @end
696 707
697 708
698 @implementation AutofillSectionContainer (ForTesting) 709 @implementation AutofillSectionContainer (ForTesting)
699 710
700 - (NSControl*)getField:(autofill::ServerFieldType)type { 711 - (NSControl*)getField:(autofill::ServerFieldType)type {
701 return [inputs_ viewWithTag:type]; 712 return [inputs_ viewWithTag:type];
702 } 713 }
703 714
704 - (void)setFieldValue:(NSString*)text 715 - (void)setFieldValue:(NSString*)text
705 forType:(autofill::ServerFieldType)type { 716 forType:(autofill::ServerFieldType)type {
706 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type]; 717 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type];
707 if (field) 718 if (field)
708 [field setFieldValue:text]; 719 [field setFieldValue:text];
709 } 720 }
710 721
711 - (void)setSuggestionFieldValue:(NSString*)text { 722 - (void)setSuggestionFieldValue:(NSString*)text {
712 [[suggestContainer_ inputField] setFieldValue:text]; 723 [[suggestContainer_ inputField] setFieldValue:text];
713 } 724 }
714 725
715 - (void)activateFieldForType:(autofill::ServerFieldType)type { 726 - (void)activateFieldForType:(autofill::ServerFieldType)type {
716 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type]; 727 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type];
717 if (field) { 728 if (field) {
718 [[field window] makeFirstResponder:field]; 729 [[field window] makeFirstResponder:field];
719 [self textfieldEditedOrActivated:field edited:NO]; 730 [self fieldEditedOrActivated:field edited:NO];
720 } 731 }
721 } 732 }
722 733
723 @end 734 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698