Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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, | 427 if (!textfield) |
| 454 // so flagging them as invalid prematurely is not helpful. However, | 428 return; |
| 455 // correcting a minor mistake (i.e. a wrong CC digit) should immediately | 429 |
| 456 // result in validation - positive user feedback. | 430 // If the field is marked as invalid, check if the text is now valid. Many |
| 431 // fields (i.e. CC#) are invalid for most of the duration of editing, so | |
| 432 // flagging them as invalid prematurely is not helpful. However, correcting a | |
| 433 // minor mistake (i.e. a wrong CC digit) should immediately result in | |
| 434 // validation - positive user feedback. | |
| 457 if ([textfield invalid] && edited) { | 435 if ([textfield invalid] && edited) { |
| 458 base::string16 message = delegate_->InputValidityMessage(section_, | 436 base::string16 message = delegate_->InputValidityMessage(section_, |
| 459 type, | 437 type, |
| 460 fieldValue); | 438 fieldValue); |
| 461 [textfield setValidityMessage:base::SysUTF16ToNSString(message)]; | 439 [textfield setValidityMessage:base::SysUTF16ToNSString(message)]; |
| 462 [validationDelegate_ updateMessageForField:textfield]; | 440 [validationDelegate_ updateMessageForField:textfield]; |
| 463 | 441 |
| 464 // If the field transitioned from invalid to valid, re-validate the group, | 442 // If the field transitioned from invalid to valid, re-validate the group, |
| 465 // since inter-field checks become meaningful with valid fields. | 443 // since inter-field checks become meaningful with valid fields. |
| 466 if (![textfield invalid]) | 444 if (![textfield invalid]) |
| 467 [self validateFor:autofill::VALIDATE_EDIT]; | 445 [self validateFor:autofill::VALIDATE_EDIT]; |
| 468 } | 446 } |
| 469 | 447 |
| 470 // Update the icon if necessary. | 448 // Update the icon if necessary. |
| 471 if (delegate_->FieldControlsIcons(type)) | 449 if (delegate_->FieldControlsIcons(type)) |
| 472 [self updateFieldIcons]; | 450 [self updateFieldIcons]; |
| 473 [self updateEditability]; | 451 [self updateEditability]; |
| 474 } | 452 } |
| 475 | 453 |
| 476 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { | 454 - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control { |
| 477 DCHECK([control tag]); | 455 DCHECK([control tag]); |
| 478 return static_cast<autofill::ServerFieldType>([control tag]); | 456 return static_cast<autofill::ServerFieldType>([control tag]); |
| 479 } | 457 } |
| 480 | 458 |
| 481 - (const autofill::DetailInput*)detailInputForType: | 459 - (const autofill::DetailInput*)detailInputForType: |
| 482 (autofill::ServerFieldType)type { | 460 (autofill::ServerFieldType)type { |
| 483 for (size_t i = 0; i < detailInputs_.size(); ++i) { | 461 for (size_t i = 0; i < detailInputs_.size(); ++i) { |
| 484 if (detailInputs_[i]->type == type) | 462 if (detailInputs_[i]->type == type) |
| 485 return detailInputs_[i]; | 463 return detailInputs_[i]; |
| 486 } | 464 } |
| 487 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests | 465 // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests |
| 488 // blindly call setFieldValue:forInput:, even for non-existing inputs. | 466 // blindly call setFieldValue:forType:, even for non-existing inputs. |
| 489 return NULL; | 467 return NULL; |
| 490 } | 468 } |
| 491 | 469 |
| 492 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs | 470 - (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs |
| 493 fromControls:(NSArray*)controls { | 471 fromControls:(NSArray*)controls { |
| 494 for (NSControl<AutofillInputField>* input in controls) { | 472 for (NSControl<AutofillInputField>* input in controls) { |
| 495 DCHECK([input isKindOfClass:[NSControl class]]); | 473 DCHECK([input isKindOfClass:[NSControl class]]); |
| 496 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); | 474 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); |
| 497 outputs->insert(std::make_pair( | 475 outputs->insert(std::make_pair( |
| 498 [self fieldTypeForControl:input], | 476 [self fieldTypeForControl:input], |
| 499 base::SysNSStringToUTF16([input fieldValue]))); | 477 base::SysNSStringToUTF16([input fieldValue]))); |
| 500 } | 478 } |
| 501 } | 479 } |
| 502 | 480 |
| 503 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText { | 481 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText { |
| 504 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]); | 482 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]); |
| 505 [label setFont: | 483 [label setFont: |
| 506 [[NSFontManager sharedFontManager] convertFont:[label font] | 484 [[NSFontManager sharedFontManager] convertFont:[label font] |
| 507 toHaveTrait:NSBoldFontMask]]; | 485 toHaveTrait:NSBoldFontMask]]; |
| 508 [label setStringValue:labelText]; | 486 [label setStringValue:labelText]; |
| 509 [label setEditable:NO]; | 487 [label setEditable:NO]; |
| 510 [label setBordered:NO]; | 488 [label setBordered:NO]; |
| 511 [label setDrawsBackground:NO]; | 489 [label setDrawsBackground:NO]; |
| 512 [label sizeToFit]; | 490 [label sizeToFit]; |
| 513 return label.autorelease(); | 491 return label.autorelease(); |
| 514 } | 492 } |
| 515 | 493 |
| 516 - (void)updateAndClobber:(BOOL)shouldClobber { | 494 - (void)updateAndClobber:(BOOL)shouldClobber { |
| 517 const autofill::DetailInputs& updatedInputs = | 495 if (shouldClobber) { |
| 518 delegate_->RequestedFieldsForSection(section_); | 496 [self makeInputControls]; |
| 497 } else { | |
| 498 const autofill::DetailInputs& updatedInputs = | |
| 499 delegate_->RequestedFieldsForSection(section_); | |
| 519 | 500 |
| 520 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); | 501 for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); |
| 521 iter != updatedInputs.end(); | 502 iter != updatedInputs.end(); |
| 522 ++iter) { | 503 ++iter) { |
| 523 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; | 504 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; |
| 524 DCHECK(field); | 505 DCHECK(field); |
| 506 if ([field isDefault]) | |
| 507 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; | |
| 508 } | |
| 509 [self updateFieldIcons]; | |
| 510 } | |
| 525 | 511 |
| 526 if (shouldClobber || [field isDefault]) { | |
| 527 [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; | |
| 528 } | |
| 529 if (shouldClobber) | |
| 530 [field setValidityMessage:@""]; | |
| 531 } | |
| 532 [self updateEditability]; | 512 [self updateEditability]; |
| 533 [self updateFieldIcons]; | |
| 534 [self modelChanged]; | 513 [self modelChanged]; |
| 535 } | 514 } |
| 536 | 515 |
| 537 - (BOOL)isCreditCardSection { | 516 - (BOOL)isCreditCardSection { |
| 538 return section_ == autofill::SECTION_CC || | 517 return section_ == autofill::SECTION_CC || |
| 539 section_ == autofill::SECTION_CC_BILLING; | 518 section_ == autofill::SECTION_CC_BILLING; |
| 540 } | 519 } |
| 541 | 520 |
| 542 - (MenuButton*)makeSuggestionButton { | 521 - (MenuButton*)makeSuggestionButton { |
| 543 base::scoped_nsobject<MenuButton> button([[MenuButton alloc] init]); | 522 base::scoped_nsobject<MenuButton> button([[MenuButton alloc] init]); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 564 [[button cell] setImage:image | 543 [[button cell] setImage:image |
| 565 forButtonState:image_button_cell::kDisabledState]; | 544 forButtonState:image_button_cell::kDisabledState]; |
| 566 | 545 |
| 567 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501) | 546 // ImageButtonCell's cellSize is not working. (http://crbug.com/298501) |
| 568 [button setFrameSize:[image size]]; | 547 [button setFrameSize:[image size]]; |
| 569 return button.autorelease(); | 548 return button.autorelease(); |
| 570 } | 549 } |
| 571 | 550 |
| 572 // TODO(estade): we should be using Chrome-style constrained window padding | 551 // TODO(estade): we should be using Chrome-style constrained window padding |
| 573 // values. | 552 // values. |
| 574 - (LayoutView*)makeInputControls { | 553 - (void)makeInputControls { |
|
groby-ooo-7-16
2014/01/17 02:56:13
Leave a comment indicating we do this so we don't
| |
| 554 if (inputs_) { | |
| 555 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { | |
| 556 [input setInputDelegate:nil]; | |
| 557 } | |
| 558 } | |
| 559 | |
| 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 Loading... | |
| 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 |
| 668 if (inputs_) { | |
| 669 [[self view] replaceSubview:inputs_ with:view]; | |
| 670 id delegate = [[view_ window] windowController]; | |
| 671 if ([delegate respondsToSelector:@selector(requestRelayout)]) | |
| 672 [delegate performSelector:@selector(requestRelayout)]; | |
| 673 } | |
| 674 | |
| 675 inputs_ = view; | |
| 661 [self updateFieldIcons]; | 676 [self updateFieldIcons]; |
| 662 return view.autorelease(); | |
| 663 } | 677 } |
| 664 | 678 |
| 665 - (void)updateFieldIcons { | 679 - (void)updateFieldIcons { |
| 666 autofill::FieldValueMap fieldValues; | 680 autofill::FieldValueMap fieldValues; |
| 667 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { | 681 for (NSControl<AutofillInputField>* input in [inputs_ subviews]) { |
| 668 DCHECK([input isKindOfClass:[NSControl class]]); | 682 DCHECK([input isKindOfClass:[NSControl class]]); |
| 669 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); | 683 DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]); |
| 670 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; | 684 autofill::ServerFieldType fieldType = [self fieldTypeForControl:input]; |
| 671 NSString* value = [input fieldValue]; | 685 NSString* value = [input fieldValue]; |
| 672 fieldValues[fieldType] = base::SysNSStringToUTF16(value); | 686 fieldValues[fieldType] = base::SysNSStringToUTF16(value); |
| 673 } | 687 } |
| 674 | 688 |
| 675 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); | 689 autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues); |
| 676 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); | 690 for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin(); |
| 677 iter!= fieldIcons.end(); ++iter) { | 691 iter!= fieldIcons.end(); ++iter) { |
| 678 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( | 692 AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>( |
| 679 [inputs_ viewWithTag:iter->first]); | 693 [inputs_ viewWithTag:iter->first]); |
| 680 [[textfield cell] setIcon:iter->second.ToNSImage()]; | 694 [[textfield cell] setIcon:iter->second.ToNSImage()]; |
| 681 } | 695 } |
| 682 } | 696 } |
| 683 | 697 |
| 684 - (void)updateEditability { | 698 - (void)updateEditability { |
| 685 | |
| 686 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); | 699 base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); |
| 687 [self addInputsToArray:controls]; | 700 [self addInputsToArray:controls]; |
| 688 for (NSControl<AutofillInputField>* control in controls.get()) { | 701 for (NSControl<AutofillInputField>* control in controls.get()) { |
| 689 autofill::ServerFieldType type = [self fieldTypeForControl:control]; | 702 autofill::ServerFieldType type = [self fieldTypeForControl:control]; |
| 690 const autofill::DetailInput* input = [self detailInputForType:type]; | 703 const autofill::DetailInput* input = [self detailInputForType:type]; |
| 691 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; | 704 [control setEnabled:delegate_->InputIsEditable(*input, section_)]; |
| 692 } | 705 } |
| 693 } | 706 } |
| 694 | 707 |
| 695 @end | 708 @end |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 709 } | 722 } |
| 710 | 723 |
| 711 - (void)setSuggestionFieldValue:(NSString*)text { | 724 - (void)setSuggestionFieldValue:(NSString*)text { |
| 712 [[suggestContainer_ inputField] setFieldValue:text]; | 725 [[suggestContainer_ inputField] setFieldValue:text]; |
| 713 } | 726 } |
| 714 | 727 |
| 715 - (void)activateFieldForType:(autofill::ServerFieldType)type { | 728 - (void)activateFieldForType:(autofill::ServerFieldType)type { |
| 716 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type]; | 729 NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type]; |
| 717 if (field) { | 730 if (field) { |
| 718 [[field window] makeFirstResponder:field]; | 731 [[field window] makeFirstResponder:field]; |
| 719 [self textfieldEditedOrActivated:field edited:NO]; | 732 [self fieldEditedOrActivated:field edited:NO]; |
| 720 } | 733 } |
| 721 } | 734 } |
| 722 | 735 |
| 723 @end | 736 @end |
| OLD | NEW |