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

Unified Diff: chrome/browser/ui/cocoa/autofill/autofill_section_container.mm

Issue 1931043002: Remove requestAutocomplete (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
deleted file mode 100644
index b6f96d8f9df3725b8de77f90880a8a5725758802..0000000000000000000000000000000000000000
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
+++ /dev/null
@@ -1,759 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
-
-#include <stddef.h>
-
-#include <algorithm>
-
-#include "base/mac/foundation_util.h"
-#include "base/mac/sdk_forward_declarations.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
-#include "chrome/browser/ui/chrome_style.h"
-#import "chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h"
-#import "chrome/browser/ui/cocoa/autofill/autofill_section_view.h"
-#import "chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h"
-#import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
-#import "chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.h"
-#import "chrome/browser/ui/cocoa/autofill/layout_view.h"
-#include "chrome/browser/ui/cocoa/autofill/simple_grid_layout.h"
-#import "chrome/browser/ui/cocoa/image_button_cell.h"
-#import "chrome/browser/ui/cocoa/menu_button.h"
-#include "components/autofill/core/browser/autofill_type.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-#include "grit/components_scaled_resources.h"
-#include "grit/theme_resources.h"
-#import "ui/base/cocoa/menu_controller.h"
-#include "ui/base/l10n/l10n_util_mac.h"
-#include "ui/base/models/combobox_model.h"
-#include "ui/base/resource/resource_bundle.h"
-
-namespace {
-
-// Constants used for layouting controls. These variables are copied from
-// "ui/views/layout/layout_constants.h".
-
-// Horizontal spacing between controls that are logically related.
-const int kRelatedControlHorizontalSpacing = 8;
-
-// Vertical spacing between controls that are logically related.
-const int kRelatedControlVerticalSpacing = 8;
-
-// TODO(estade): pull out these constants, and figure out better values
-// for them. Note: These are duplicated from Views code.
-
-// Fixed width for the details section.
-const int kDetailsWidth = 440;
-
-// Top/bottom inset for contents of a detail section.
-const size_t kDetailSectionInset = 10;
-
-// Vertical padding around the section header.
-const CGFloat kVerticalHeaderPadding = 6;
-
-// If the Autofill data comes from a credit card, make sure to overwrite the
-// CC comboboxes (even if they already have something in them). If the
-// Autofill data comes from an AutofillProfile, leave the comboboxes alone.
-// TODO(groby): This kind of logic should _really_ live on the delegate.
-bool ShouldOverwriteComboboxes(autofill::DialogSection section,
- autofill::ServerFieldType type) {
- if (autofill::AutofillType(type).group() != autofill::CREDIT_CARD) {
- return false;
- }
-
- return section == autofill::SECTION_CC;
-}
-
-} // namespace
-
-@interface AutofillSectionContainer ()
-
-// An input field has been edited or activated - inform the delegate and
-// possibly reset the validity of the input (if it's a textfield).
-- (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field
- edited:(BOOL)edited;
-
-// Convenience method to retrieve a field type via the control's tag.
-- (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control;
-
-// Find the DetailInput* associated with a field type.
-- (const autofill::DetailInput*)detailInputForType:
- (autofill::ServerFieldType)type;
-
-// Takes an NSArray of controls and builds a FieldValueMap from them.
-// Translates between Cocoa code and delegate, essentially.
-// All controls must inherit from NSControl and conform to AutofillInputView.
-- (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs
- fromControls:(NSArray*)controls;
-
-// Updates input fields based on delegate status. If |shouldClobber| is YES,
-// will clobber existing data and reset fields to the initial values.
-- (void)updateAndClobber:(BOOL)shouldClobber;
-
-// Return YES if this is a section that contains CC info. (And, more
-// importantly, a potential CVV field)
-- (BOOL)isCreditCardSection;
-
-// Create properly styled label for section. Autoreleased.
-- (NSTextField*)makeDetailSectionLabel:(NSString*)labelText;
-
-// Create a button offering input suggestions.
-- (MenuButton*)makeSuggestionButton;
-
-// Create a view with all inputs requested by |delegate_| and resets |input_|.
-- (void)makeInputControls;
-
-// Refresh all field icons based on |delegate_| status.
-- (void)updateFieldIcons;
-
-@end
-
-@implementation AutofillSectionContainer
-
-@synthesize section = section_;
-@synthesize validationDelegate = validationDelegate_;
-
-- (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate
- forSection:(autofill::DialogSection)section {
- if (self = [super init]) {
- section_ = section;
- delegate_ = delegate;
- }
- return self;
-}
-
-- (void)getInputs:(autofill::FieldValueMap*)output {
- [self fillDetailOutputs:output fromControls:[inputs_ subviews]];
-}
-
-// Note: This corresponds to Views' "UpdateDetailsGroupState".
-- (void)modelChanged {
- ui::MenuModel* suggestionModel = delegate_->MenuModelForSection(section_);
- menuController_.reset([[MenuController alloc] initWithModel:suggestionModel
- useWithPopUpButtonCell:YES]);
- NSMenu* menu = [menuController_ menu];
-
- const BOOL hasSuggestions = [menu numberOfItems] > 0;
- [suggestButton_ setHidden:!hasSuggestions];
-
- [suggestButton_ setAttachedMenu:menu];
-
- [self updateSuggestionState];
-
- if (![[self view] isHidden])
- [self validateFor:autofill::VALIDATE_EDIT];
-
- // Always request re-layout on state change.
- [self requestRelayout];
-}
-
-- (void)requestRelayout {
- id delegate = [[view_ window] windowController];
- if ([delegate respondsToSelector:@selector(requestRelayout)])
- [delegate performSelector:@selector(requestRelayout)];
-}
-
-- (void)loadView {
- [self makeInputControls];
-
- base::string16 labelText = delegate_->LabelForSection(section_);
- label_.reset(
- [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)]
- retain]);
-
- suggestButton_.reset([[self makeSuggestionButton] retain]);
- suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]);
-
- view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]);
- [self setView:view_];
- [view_ setSubviews:
- @[label_, inputs_, [suggestContainer_ view], suggestButton_]];
- if (tooltipController_) {
- [view_ addSubview:[tooltipController_ view]
- positioned:NSWindowAbove
- relativeTo:inputs_];
- }
-
- if ([self isCreditCardSection]) {
- // Credit card sections *MUST* have a CREDIT_CARD_VERIFICATION_CODE input.
- DCHECK([self detailInputForType:autofill::CREDIT_CARD_VERIFICATION_CODE]);
- [[suggestContainer_ inputField] setTag:
- autofill::CREDIT_CARD_VERIFICATION_CODE];
- [[suggestContainer_ inputField] setInputDelegate:self];
- }
-
- [self modelChanged];
-}
-
-- (NSSize)preferredSize {
- if ([view_ isHidden])
- return NSZeroSize;
-
- NSSize labelSize = [label_ frame].size; // Assumes sizeToFit was called.
- CGFloat controlHeight = [inputs_ preferredHeightForWidth:kDetailsWidth];
- if (showSuggestions_)
- controlHeight = [suggestContainer_ preferredSize].height;
-
- return NSMakeSize(kDetailsWidth + 2 * chrome_style::kHorizontalPadding,
- labelSize.height + kVerticalHeaderPadding +
- controlHeight + 2 * kDetailSectionInset);
-}
-
-- (void)performLayout {
- if ([view_ isHidden])
- return;
-
- NSSize buttonSize = [suggestButton_ frame].size; // Assume sizeToFit.
- NSSize labelSize = [label_ frame].size; // Assumes sizeToFit was called.
- CGFloat controlHeight = [inputs_ preferredHeightForWidth:kDetailsWidth];
- if (showSuggestions_)
- controlHeight = [suggestContainer_ preferredSize].height;
-
- NSRect viewFrame = NSZeroRect;
- viewFrame.size = [self preferredSize];
-
- NSRect contentFrame = NSInsetRect(viewFrame,
- chrome_style::kHorizontalPadding,
- kDetailSectionInset);
- NSRect controlFrame, labelFrame, buttonFrame;
-
- // Label is top left, suggestion button is top right, controls are below that.
- NSDivideRect(contentFrame, &labelFrame, &controlFrame,
- kVerticalHeaderPadding + labelSize.height, NSMaxYEdge);
- NSDivideRect(labelFrame, &buttonFrame, &labelFrame,
- buttonSize.width, NSMaxXEdge);
-
- labelFrame = NSOffsetRect(labelFrame, 0, kVerticalHeaderPadding);
- labelFrame.size = labelSize;
-
- buttonFrame = NSOffsetRect(buttonFrame, 0, 5);
- buttonFrame.size = buttonSize;
-
- if (showSuggestions_) {
- [[suggestContainer_ view] setFrame:controlFrame];
- [suggestContainer_ performLayout];
- } else {
- [inputs_ setFrame:controlFrame];
- }
- [label_ setFrame:labelFrame];
- [suggestButton_ setFrame:buttonFrame];
- [inputs_ setHidden:showSuggestions_];
- [[suggestContainer_ view] setHidden:!showSuggestions_];
- [view_ setFrameSize:viewFrame.size];
- if (tooltipController_) {
- [[tooltipController_ view] setHidden:showSuggestions_];
- NSRect tooltipIconFrame = [tooltipField_ decorationFrame];
- tooltipIconFrame.origin =
- [[self view] convertPoint:tooltipIconFrame.origin
- fromView:[tooltipField_ superview]];
- [[tooltipController_ view] setFrame:tooltipIconFrame];
- }
-}
-
-- (KeyEventHandled)keyEvent:(NSEvent*)event forInput:(id)sender {
- content::NativeWebKeyboardEvent webEvent(event);
-
- // Only handle keyDown, to handle key repeats without duplicates.
- if (webEvent.type != content::NativeWebKeyboardEvent::RawKeyDown)
- return kKeyEventNotHandled;
-
- // Allow the delegate to intercept key messages.
- if (delegate_->HandleKeyPressEventInInput(webEvent))
- return kKeyEventHandled;
- return kKeyEventNotHandled;
-}
-
-- (void)onMouseDown:(NSControl<AutofillInputField>*)field {
- [self fieldEditedOrActivated:field edited:NO];
- [validationDelegate_ updateMessageForField:field];
-}
-
-- (void)fieldBecameFirstResponder:(NSControl<AutofillInputField>*)field {
- [validationDelegate_ updateMessageForField:field];
-}
-
-- (void)didChange:(id)sender {
- [self fieldEditedOrActivated:sender edited:YES];
-}
-
-- (void)didEndEditing:(id)sender {
- delegate_->FocusMoved();
- [validationDelegate_ hideErrorBubble];
- [self validateFor:autofill::VALIDATE_EDIT];
-}
-
-- (void)updateSuggestionState {
- const autofill::SuggestionState& suggestionState =
- delegate_->SuggestionStateForSection(section_);
- showSuggestions_ = suggestionState.visible;
-
- if (!suggestionState.extra_text.empty()) {
- NSString* extraText =
- base::SysUTF16ToNSString(suggestionState.extra_text);
- NSImage* extraIcon = suggestionState.extra_icon.AsNSImage();
- [suggestContainer_ showInputField:extraText withIcon:extraIcon];
- }
-
- // NOTE: It's important to set the input field, if there is one, _before_
- // setting the suggestion text, since the suggestion container needs to
- // account for the input field's width when deciding which of the two string
- // representations to use.
- NSString* verticallyCompactText =
- base::SysUTF16ToNSString(suggestionState.vertically_compact_text);
- NSString* horizontallyCompactText =
- base::SysUTF16ToNSString(suggestionState.horizontally_compact_text);
- [suggestContainer_
- setSuggestionWithVerticallyCompactText:verticallyCompactText
- horizontallyCompactText:horizontallyCompactText
- icon:suggestionState.icon.AsNSImage()
- maxWidth:kDetailsWidth];
-
- [view_ setShouldHighlightOnHover:showSuggestions_];
- if (showSuggestions_)
- [view_ setClickTarget:suggestButton_];
- else
- [view_ setClickTarget:nil];
- [view_ setHidden:!delegate_->SectionIsActive(section_)];
-}
-
-- (void)update {
- [self updateAndClobber:YES];
- [view_ updateHoverState];
-}
-
-- (void)fillForType:(const autofill::ServerFieldType)type {
- // Make sure to overwrite the originating input if it is a text field.
- AutofillTextField* field =
- base::mac::ObjCCast<AutofillTextField>([inputs_ viewWithTag:type]);
- [field setFieldValue:@""];
-
- if (ShouldOverwriteComboboxes(section_, type)) {
- for (NSControl* control in [inputs_ subviews]) {
- AutofillPopUpButton* popup =
- base::mac::ObjCCast<AutofillPopUpButton>(control);
- if (popup) {
- autofill::ServerFieldType fieldType =
- [self fieldTypeForControl:popup];
- if (autofill::AutofillType(fieldType).group() ==
- autofill::CREDIT_CARD) {
- ui::ComboboxModel* model =
- delegate_->ComboboxModelForAutofillType(fieldType);
- DCHECK(model);
- [popup selectItemAtIndex:model->GetDefaultIndex()];
- }
- }
- }
- }
-
- [self updateAndClobber:NO];
-}
-
-- (BOOL)validateFor:(autofill::ValidationType)validationType {
- NSArray* fields = nil;
- if (!showSuggestions_) {
- fields = [inputs_ subviews];
- } else if ([self isCreditCardSection]) {
- if (![[suggestContainer_ inputField] isHidden])
- fields = @[ [suggestContainer_ inputField] ];
- }
-
- // Ensure only editable fields are validated.
- fields = [fields filteredArrayUsingPredicate:
- [NSPredicate predicateWithBlock:
- ^BOOL(NSControl<AutofillInputField>* field, NSDictionary* bindings) {
- return [field isEnabled];
- }]];
-
- autofill::FieldValueMap detailOutputs;
- [self fillDetailOutputs:&detailOutputs fromControls:fields];
- autofill::ValidityMessages messages = delegate_->InputsAreValid(
- section_, detailOutputs);
-
- for (NSControl<AutofillInputField>* input in fields) {
- const autofill::ValidityMessage& message =
- messages.GetMessageOrDefault([self fieldTypeForControl:input]);
- if (validationType != autofill::VALIDATE_FINAL && !message.sure)
- continue;
- [input setValidityMessage:base::SysUTF16ToNSString(message.text)];
- [validationDelegate_ updateMessageForField:input];
- }
-
- return !messages.HasErrors();
-}
-
-- (NSString*)suggestionText {
- return showSuggestions_ ? [[suggestContainer_ inputField] stringValue] : nil;
-}
-
-- (void)addInputsToArray:(NSMutableArray*)array {
- [array addObjectsFromArray:[inputs_ subviews]];
-
- // Only credit card sections can have a suggestion input.
- if ([self isCreditCardSection])
- [array addObject:[suggestContainer_ inputField]];
-}
-
-#pragma mark Internal API for AutofillSectionContainer.
-
-- (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field
- edited:(BOOL)edited {
- autofill::ServerFieldType type = [self fieldTypeForControl:field];
- base::string16 fieldValue = base::SysNSStringToUTF16([field fieldValue]);
-
- // Get the frame rectangle for the designated field, in screen coordinates.
- NSRect textFrameInScreen = [field convertRect:[field bounds] toView:nil];
- textFrameInScreen = [[field window] convertRectToScreen:textFrameInScreen];
-
- // And adjust for gfx::Rect being flipped compared to OSX coordinates.
- NSScreen* screen = [[NSScreen screens] firstObject];
- textFrameInScreen.origin.y =
- NSMaxY([screen frame]) - NSMaxY(textFrameInScreen);
- gfx::Rect textFrameRect(NSRectToCGRect(textFrameInScreen));
-
- delegate_->UserEditedOrActivatedInput(section_,
- type,
- [self view],
- textFrameRect,
- fieldValue,
- edited);
-
- AutofillTextField* textfield = base::mac::ObjCCast<AutofillTextField>(field);
- if (!textfield)
- return;
-
- // If the field is marked as invalid, check if the text is now valid. Many
- // fields (i.e. CC#) are invalid for most of the duration of editing, so
- // flagging them as invalid prematurely is not helpful. However, correcting a
- // minor mistake (i.e. a wrong CC digit) should immediately result in
- // validation - positive user feedback.
- if ([textfield invalid] && edited) {
- base::string16 message = delegate_->InputValidityMessage(section_,
- type,
- fieldValue);
- [textfield setValidityMessage:base::SysUTF16ToNSString(message)];
-
- // If the field transitioned from invalid to valid, re-validate the group,
- // since inter-field checks become meaningful with valid fields.
- if (![textfield invalid])
- [self validateFor:autofill::VALIDATE_EDIT];
-
- // The validity message has potentially changed - notify the error bubble.
- [validationDelegate_ updateMessageForField:textfield];
- }
-
- // Update the icon if necessary.
- if (delegate_->FieldControlsIcons(type))
- [self updateFieldIcons];
-}
-
-- (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control {
- DCHECK([control tag]);
- return static_cast<autofill::ServerFieldType>([control tag]);
-}
-
-- (const autofill::DetailInput*)detailInputForType:
- (autofill::ServerFieldType)type {
- for (size_t i = 0; i < detailInputs_.size(); ++i) {
- if (detailInputs_[i]->type == type)
- return detailInputs_[i];
- }
- // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests
- // blindly call setFieldValue:forType:, even for non-existing inputs.
- return NULL;
-}
-
-- (void)fillDetailOutputs:(autofill::FieldValueMap*)outputs
- fromControls:(NSArray*)controls {
- for (NSControl<AutofillInputField>* input in controls) {
- DCHECK([input isKindOfClass:[NSControl class]]);
- DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]);
- outputs->insert(std::make_pair(
- [self fieldTypeForControl:input],
- base::SysNSStringToUTF16([input fieldValue])));
- }
-}
-
-- (NSTextField*)makeDetailSectionLabel:(NSString*)labelText {
- base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
- [label setFont:
- [[NSFontManager sharedFontManager] convertFont:[label font]
- toHaveTrait:NSBoldFontMask]];
- [label setStringValue:labelText];
- [label setEditable:NO];
- [label setBordered:NO];
- [label setDrawsBackground:NO];
- [label sizeToFit];
- return label.autorelease();
-}
-
-- (void)updateAndClobber:(BOOL)shouldClobber {
- if (shouldClobber) {
- // Remember which one of the inputs was first responder so focus can be
- // restored after the inputs are rebuilt.
- NSView* firstResponderView =
- base::mac::ObjCCast<NSView>([[inputs_ window] firstResponder]);
- autofill::ServerFieldType type = autofill::UNKNOWN_TYPE;
- for (NSControl* field in [inputs_ subviews]) {
- if ([firstResponderView isDescendantOf:field]) {
- type = [self fieldTypeForControl:field];
- break;
- }
- }
-
- [self makeInputControls];
-
- if (type != autofill::UNKNOWN_TYPE) {
- NSView* view = [inputs_ viewWithTag:type];
- if (view)
- [[inputs_ window] makeFirstResponder:view];
- }
- } else {
- const autofill::DetailInputs& updatedInputs =
- delegate_->RequestedFieldsForSection(section_);
-
- for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin();
- iter != updatedInputs.end();
- ++iter) {
- NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type];
- DCHECK(field);
- if ([field isDefault])
- [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)];
- }
- [self updateFieldIcons];
- }
-
- [self modelChanged];
-}
-
-- (BOOL)isCreditCardSection {
- return section_ == autofill::SECTION_CC;
-}
-
-- (MenuButton*)makeSuggestionButton {
- base::scoped_nsobject<MenuButton> button([[MenuButton alloc] init]);
-
- [button setOpenMenuOnClick:YES];
- [button setBordered:NO];
- [button setShowsBorderOnlyWhileMouseInside:YES];
-
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- NSImage* image =
- rb.GetNativeImageNamed(IDR_AUTOFILL_DIALOG_MENU_BUTTON).ToNSImage();
- [[button cell] setImage:image
- forButtonState:image_button_cell::kDefaultState];
- image = rb.GetNativeImageNamed(IDR_AUTOFILL_DIALOG_MENU_BUTTON_H).
- ToNSImage();
- [[button cell] setImage:image
- forButtonState:image_button_cell::kHoverState];
- image = rb.GetNativeImageNamed(IDR_AUTOFILL_DIALOG_MENU_BUTTON_P).
- ToNSImage();
- [[button cell] setImage:image
- forButtonState:image_button_cell::kPressedState];
- image = rb.GetNativeImageNamed(IDR_AUTOFILL_DIALOG_MENU_BUTTON_D).
- ToNSImage();
- [[button cell] setImage:image
- forButtonState:image_button_cell::kDisabledState];
-
- // ImageButtonCell's cellSize is not working. (http://crbug.com/298501)
- [button setFrameSize:[image size]];
- return button.autorelease();
-}
-
-// TODO(estade): we should be using Chrome-style constrained window padding
-// values.
-- (void)makeInputControls {
- if (inputs_) {
- // When |inputs_| is replaced in response to a country change, there's a
- // didEndEditing dispatched that segfaults or DCHECKS() as it's operating on
- // stale input fields. Nil out the input delegate so this doesn't happen.
- for (NSControl<AutofillInputField>* input in [inputs_ subviews]) {
- [input setInputDelegate:nil];
- }
- }
-
- detailInputs_.clear();
-
- // Keep a list of weak pointers to DetailInputs.
- const autofill::DetailInputs& inputs =
- delegate_->RequestedFieldsForSection(section_);
-
- // Reverse the order of all the inputs.
- for (int i = inputs.size() - 1; i >= 0; --i) {
- detailInputs_.push_back(&(inputs[i]));
- }
-
- // Then right the reversal in each row.
- std::vector<const autofill::DetailInput*>::iterator it;
- for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) {
- std::vector<const autofill::DetailInput*>::iterator start = it;
- while (it != detailInputs_.end() &&
- (*it)->length != autofill::DetailInput::LONG) {
- ++it;
- }
- std::reverse(start, it);
- }
-
- base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]);
- [view setLayoutManager:std::unique_ptr<SimpleGridLayout>(
- new SimpleGridLayout(view))];
- SimpleGridLayout* layout = [view layoutManager];
-
- int column_set_id = 0;
- for (size_t i = 0; i < detailInputs_.size(); ++i) {
- const autofill::DetailInput& input = *detailInputs_[i];
-
- if (input.length == autofill::DetailInput::LONG)
- ++column_set_id;
-
- int kColumnSetId =
- input.length == autofill::DetailInput::NONE ? -1 : column_set_id;
-
- ColumnSet* columnSet = layout->GetColumnSet(kColumnSetId);
- if (!columnSet) {
- // Create a new column set and row.
- columnSet = layout->AddColumnSet(kColumnSetId);
- if (i != 0 && kColumnSetId != -1)
- layout->AddPaddingRow(kRelatedControlVerticalSpacing);
- layout->StartRow(0, kColumnSetId);
- } else {
- // Add a new column to existing row.
- columnSet->AddPaddingColumn(kRelatedControlHorizontalSpacing);
- // Must explicitly skip the padding column since we've already started
- // adding views.
- layout->SkipColumns(1);
- }
-
- columnSet->AddColumn(input.expand_weight ? input.expand_weight : 1.0f);
-
- ui::ComboboxModel* inputModel =
- delegate_->ComboboxModelForAutofillType(input.type);
- base::scoped_nsprotocol<NSControl<AutofillInputField>*> control;
- if (inputModel) {
- base::scoped_nsobject<AutofillPopUpButton> popup(
- [[AutofillPopUpButton alloc] initWithFrame:NSZeroRect pullsDown:NO]);
- for (int i = 0; i < inputModel->GetItemCount(); ++i) {
- if (!inputModel->IsItemSeparatorAt(i)) {
- // Currently, the first item in |inputModel| is duplicated later in
- // the list. The second item is a separator. Because NSPopUpButton
- // de-duplicates, the menu's just left with a separator on the top of
- // the list (with nothing it's separating). For that reason,
- // separators are ignored on Mac for now. http://crbug.com/347653
- [popup addItemWithTitle:
- base::SysUTF16ToNSString(inputModel->GetItemAt(i))];
- }
- }
- [popup setDefaultValue:base::SysUTF16ToNSString(
- inputModel->GetItemAt(inputModel->GetDefaultIndex()))];
- control.reset(popup.release());
- } else {
- base::scoped_nsobject<AutofillTextField> field(
- [[AutofillTextField alloc] init]);
- [field setIsMultiline:input.IsMultiline()];
- [[field cell] setLineBreakMode:NSLineBreakByClipping];
- [[field cell] setScrollable:YES];
- [[field cell] setPlaceholderString:
- l10n_util::FixUpWindowsStyleLabel(input.placeholder_text)];
- NSString* tooltipText =
- base::SysUTF16ToNSString(delegate_->TooltipForField(input.type));
- // VoiceOver onlys seems to pick up the help message on [field cell]
- // (rather than just field).
- BOOL success = [[field cell]
- accessibilitySetOverrideValue:tooltipText
- forAttribute:NSAccessibilityHelpAttribute];
- DCHECK(success);
- if ([tooltipText length] > 0) {
- if (!tooltipController_) {
- tooltipController_.reset(
- [[AutofillTooltipController alloc]
- initWithArrowLocation:info_bubble::kTopRight]);
- }
- tooltipField_ = field.get();
- NSImage* icon =
- ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
- IDR_AUTOFILL_TOOLTIP_ICON).ToNSImage();
- [tooltipController_ setImage:icon];
- [tooltipController_ setMessage:tooltipText];
- [[field cell] setDecorationSize:[icon size]];
- }
- [field setDefaultValue:@""];
- control.reset(field.release());
- }
- [control setTag:input.type];
- [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)];
- [control sizeToFit];
- [control setFrame:NSIntegralRect([control frame])];
- [control setInputDelegate:self];
- // Hide away fields that cannot be edited.
- if (kColumnSetId == -1) {
- [control setFrame:NSZeroRect];
- [control setHidden:YES];
- }
- layout->AddView(control);
-
- if (input.length == autofill::DetailInput::LONG ||
- input.length == autofill::DetailInput::SHORT_EOL) {
- ++column_set_id;
- }
- }
-
- if (inputs_) {
- [[self view] replaceSubview:inputs_ with:view];
- [self requestRelayout];
- }
-
- inputs_ = view;
- [self updateFieldIcons];
-}
-
-- (void)updateFieldIcons {
- autofill::FieldValueMap fieldValues;
- for (NSControl<AutofillInputField>* input in [inputs_ subviews]) {
- DCHECK([input isKindOfClass:[NSControl class]]);
- DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]);
- autofill::ServerFieldType fieldType = [self fieldTypeForControl:input];
- NSString* value = [input fieldValue];
- fieldValues[fieldType] = base::SysNSStringToUTF16(value);
- }
-
- autofill::FieldIconMap fieldIcons = delegate_->IconsForFields(fieldValues);
- for (autofill::FieldIconMap::const_iterator iter = fieldIcons.begin();
- iter!= fieldIcons.end(); ++iter) {
- AutofillTextField* textfield = base::mac::ObjCCastStrict<AutofillTextField>(
- [inputs_ viewWithTag:iter->first]);
- [[textfield cell] setIcon:iter->second.ToNSImage()];
- }
-}
-
-@end
-
-
-@implementation AutofillSectionContainer (ForTesting)
-
-- (NSControl*)getField:(autofill::ServerFieldType)type {
- return [inputs_ viewWithTag:type];
-}
-
-- (void)setFieldValue:(NSString*)text
- forType:(autofill::ServerFieldType)type {
- NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type];
- if (field)
- [field setFieldValue:text];
-}
-
-- (void)setSuggestionFieldValue:(NSString*)text {
- [[suggestContainer_ inputField] setFieldValue:text];
-}
-
-- (void)activateFieldForType:(autofill::ServerFieldType)type {
- NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type];
- if (field) {
- [[field window] makeFirstResponder:field];
- [self fieldEditedOrActivated:field edited:NO];
- }
-}
-
-@end

Powered by Google App Engine
This is Rietveld 408576698