| 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_details_container.h" | 5 #import "chrome/browser/ui/cocoa/autofill/autofill_details_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 "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | 10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 93 } |
| 94 return nil; | 94 return nil; |
| 95 } | 95 } |
| 96 | 96 |
| 97 - (void)modelChanged { | 97 - (void)modelChanged { |
| 98 for (AutofillSectionContainer* details in details_.get()) | 98 for (AutofillSectionContainer* details in details_.get()) |
| 99 [details modelChanged]; | 99 [details modelChanged]; |
| 100 } | 100 } |
| 101 | 101 |
| 102 - (BOOL)validate { | 102 - (BOOL)validate { |
| 103 // Account for a subtle timing issue. -validate is called from the dialog's |
| 104 // -accept. -accept then hides the dialog. If the data does not validate the |
| 105 // dialog is then reshown, focusing on the first invalid field. This happens |
| 106 // without running the message loop, so windowWillClose has not fired when |
| 107 // the dialog and error bubble is reshown, leading to a missing error bubble. |
| 108 // Resetting the anchor view here forces the bubble to show. |
| 109 errorBubbleAnchorView_ = nil; |
| 110 |
| 103 bool allValid = true; | 111 bool allValid = true; |
| 104 for (AutofillSectionContainer* details in details_.get()) { | 112 for (AutofillSectionContainer* details in details_.get()) { |
| 105 if (![[details view] isHidden]) | 113 if (![[details view] isHidden]) |
| 106 allValid = [details validateFor:autofill::VALIDATE_FINAL] && allValid; | 114 allValid = [details validateFor:autofill::VALIDATE_FINAL] && allValid; |
| 107 } | 115 } |
| 108 return allValid; | 116 return allValid; |
| 109 } | 117 } |
| 110 | 118 |
| 111 - (NSView*)firstInvalidField { | 119 - (NSView*)firstInvalidField { |
| 112 return [self firstEditableFieldMatchingBlock: | 120 return [self firstEditableFieldMatchingBlock: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 } | 157 } |
| 150 | 158 |
| 151 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { | 159 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { |
| 152 DCHECK_EQ([notification object], [errorBubbleController_ window]); | 160 DCHECK_EQ([notification object], [errorBubbleController_ window]); |
| 153 | 161 |
| 154 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 162 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
| 155 [center removeObserver:self | 163 [center removeObserver:self |
| 156 name:NSWindowWillCloseNotification | 164 name:NSWindowWillCloseNotification |
| 157 object:[errorBubbleController_ window]]; | 165 object:[errorBubbleController_ window]]; |
| 158 errorBubbleController_ = nil; | 166 errorBubbleController_ = nil; |
| 167 errorBubbleAnchorView_ = nil; |
| 159 } | 168 } |
| 160 | 169 |
| 161 - (void)showErrorBubbleForField:(NSControl<AutofillInputField>*)field { | 170 - (void)showErrorBubbleForField:(NSControl<AutofillInputField>*)field { |
| 171 // If there is already a bubble controller handling this field, reuse. |
| 172 if (errorBubbleController_ && errorBubbleAnchorView_ == field) { |
| 173 [errorBubbleController_ setMessage:[field validityMessage]]; |
| 174 |
| 175 return; |
| 176 } |
| 177 |
| 162 if (errorBubbleController_) | 178 if (errorBubbleController_) |
| 163 [errorBubbleController_ close]; | 179 [errorBubbleController_ close]; |
| 164 DCHECK(!errorBubbleController_); | 180 DCHECK(!errorBubbleController_); |
| 165 NSWindow* parentWindow = [field window]; | 181 NSWindow* parentWindow = [field window]; |
| 166 DCHECK(parentWindow); | 182 DCHECK(parentWindow); |
| 167 errorBubbleController_ = | 183 errorBubbleController_ = |
| 168 [[AutofillBubbleController alloc] | 184 [[AutofillBubbleController alloc] |
| 169 initWithParentWindow:parentWindow | 185 initWithParentWindow:parentWindow |
| 170 message:[field validityMessage]]; | 186 message:[field validityMessage]]; |
| 171 | 187 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 196 | 212 |
| 197 } else { | 213 } else { |
| 198 anchorPoint = NSMakePoint(NSMinX(viewRect), NSMinY(viewRect)); | 214 anchorPoint = NSMakePoint(NSMinX(viewRect), NSMinY(viewRect)); |
| 199 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopLeft]; | 215 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopLeft]; |
| 200 [[errorBubbleController_ bubble] setAlignment: | 216 [[errorBubbleController_ bubble] setAlignment: |
| 201 info_bubble::kAlignLeftEdgeToAnchorEdge]; | 217 info_bubble::kAlignLeftEdgeToAnchorEdge]; |
| 202 } | 218 } |
| 203 [errorBubbleController_ setAnchorPoint: | 219 [errorBubbleController_ setAnchorPoint: |
| 204 [parentWindow convertBaseToScreen:anchorPoint]]; | 220 [parentWindow convertBaseToScreen:anchorPoint]]; |
| 205 | 221 |
| 222 errorBubbleAnchorView_ = field; |
| 206 [errorBubbleController_ showWindow:self]; | 223 [errorBubbleController_ showWindow:self]; |
| 207 } | 224 } |
| 208 | 225 |
| 209 - (void)hideErrorBubble { | 226 - (void)hideErrorBubble { |
| 210 [errorBubble_ setHidden:YES]; | 227 [errorBubble_ setHidden:YES]; |
| 211 } | 228 } |
| 212 | 229 |
| 213 - (void)updateMessageForField:(NSControl<AutofillInputField>*)field { | 230 - (void)updateMessageForField:(NSControl<AutofillInputField>*)field { |
| 214 // Ignore fields that are not first responder. Testing this is a bit | 231 // Ignore fields that are not first responder. Testing this is a bit |
| 215 // convoluted, since for NSTextFields with firstResponder status, the | 232 // convoluted, since for NSTextFields with firstResponder status, the |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 280 } |
| 264 | 281 |
| 265 selectedField = field; | 282 selectedField = field; |
| 266 selectedFieldOrigin = fieldOrigin; | 283 selectedFieldOrigin = fieldOrigin; |
| 267 } | 284 } |
| 268 | 285 |
| 269 return selectedField; | 286 return selectedField; |
| 270 } | 287 } |
| 271 | 288 |
| 272 @end | 289 @end |
| OLD | NEW |