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

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit_view_mac.mm

Issue 113479: Mac: Style the omnibox URL. (Closed)
Patch Set: Fix a couple comments, and saving across popup navigation. Created 11 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h"
6 6
7 #include "base/sys_string_conversions.h" 7 #include "base/sys_string_conversions.h"
8 #include "chrome/browser/autocomplete/autocomplete_edit.h" 8 #include "chrome/browser/autocomplete/autocomplete_edit.h"
9 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" 9 #include "chrome/browser/autocomplete/autocomplete_popup_model.h"
10 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" 10 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h"
11 #include "chrome/browser/tab_contents/tab_contents.h" 11 #include "chrome/browser/tab_contents/tab_contents.h"
12 12
13 namespace { 13 namespace {
14 14
15 // TODO(shess): This is ugly, find a better way. Using it right now
16 // so that I can crib from gtk and still be able to see that I'm using
17 // the same values easily.
18 const NSColor* ColorWithRGBBytes(int rr, int gg, int bb) {
19 DCHECK_LE(rr, 255);
20 DCHECK_LE(bb, 255);
21 DCHECK_LE(gg, 255);
22 return [NSColor colorWithCalibratedRed:static_cast<float>(rr)/255.0
23 green:static_cast<float>(gg)/255.0
24 blue:static_cast<float>(bb)/255.0
25 alpha:1.0];
26 }
27 const NSColor* SecureBackgroundColor() {
28 return ColorWithRGBBytes(255, 245, 195); // Yellow
29 }
30 const NSColor* NormalBackgroundColor() {
31 return [NSColor controlBackgroundColor];
32 }
33 const NSColor* InsecureBackgroundColor() {
34 return [NSColor controlBackgroundColor];
35 }
36
37 const NSColor* HostTextColor() {
38 return [NSColor blackColor];
39 }
40 const NSColor* BaseTextColor() {
41 return [NSColor darkGrayColor];
42 }
43 const NSColor* SecureSchemeColor() {
44 return ColorWithRGBBytes(0x00, 0x96, 0x14);
45 }
46 const NSColor* InsecureSchemeColor() {
47 return ColorWithRGBBytes(0xc8, 0x00, 0x00);
48 }
49
15 // Store's the model and view state across tab switches. 50 // Store's the model and view state across tab switches.
16 struct AutocompleteEditViewMacState { 51 struct AutocompleteEditViewMacState {
17 AutocompleteEditViewMacState(const AutocompleteEditModel::State model_state, 52 AutocompleteEditViewMacState(const AutocompleteEditModel::State model_state,
18 const bool has_focus, const NSRange& selection) 53 const bool has_focus, const NSRange& selection)
19 : model_state(model_state), 54 : model_state(model_state),
20 has_focus(has_focus), 55 has_focus(has_focus),
21 selection(selection) { 56 selection(selection) {
22 } 57 }
23 58
24 const AutocompleteEditModel::State model_state; 59 const AutocompleteEditModel::State model_state;
(...skipping 12 matching lines...) Expand all
37 72
38 // Accessors for storing and getting the state from the tab. 73 // Accessors for storing and getting the state from the tab.
39 void StoreStateToTab(TabContents* tab, 74 void StoreStateToTab(TabContents* tab,
40 const AutocompleteEditViewMacState& state) { 75 const AutocompleteEditViewMacState& state) {
41 GetStateAccessor()->SetProperty(tab->property_bag(), state); 76 GetStateAccessor()->SetProperty(tab->property_bag(), state);
42 } 77 }
43 const AutocompleteEditViewMacState* GetStateFromTab(const TabContents* tab) { 78 const AutocompleteEditViewMacState* GetStateFromTab(const TabContents* tab) {
44 return GetStateAccessor()->GetProperty(tab->property_bag()); 79 return GetStateAccessor()->GetProperty(tab->property_bag());
45 } 80 }
46 81
82 // Helper to make converting url_parse ranges to NSRange easier to
83 // read.
84 NSRange ComponentToNSRange(const url_parse::Component& component) {
85 return NSMakeRange(static_cast<NSInteger>(component.begin),
86 static_cast<NSInteger>(component.len));
87 }
88
47 } // namespace 89 } // namespace
48 90
49 // Thin Obj-C bridge class that is the delegate of the omnibox field. 91 // Thin Obj-C bridge class that is the delegate of the omnibox field.
50 // It intercepts various control delegate methods and vectors them to 92 // It intercepts various control delegate methods and vectors them to
51 // the edit view. 93 // the edit view.
52 94
53 @interface AutocompleteFieldDelegate : NSObject { 95 @interface AutocompleteFieldDelegate : NSObject {
54 @private 96 @private
55 AutocompleteEditViewMac* edit_view_; // weak, owns us. 97 AutocompleteEditViewMac* edit_view_; // weak, owns us.
56 } 98 }
(...skipping 13 matching lines...) Expand all
70 toolbar_model_(toolbar_model), 112 toolbar_model_(toolbar_model),
71 command_updater_(command_updater), 113 command_updater_(command_updater),
72 field_(field), 114 field_(field),
73 edit_helper_([[AutocompleteFieldDelegate alloc] initWithEditView:this]) { 115 edit_helper_([[AutocompleteFieldDelegate alloc] initWithEditView:this]) {
74 DCHECK(controller); 116 DCHECK(controller);
75 DCHECK(toolbar_model); 117 DCHECK(toolbar_model);
76 DCHECK(profile); 118 DCHECK(profile);
77 DCHECK(command_updater); 119 DCHECK(command_updater);
78 DCHECK(field); 120 DCHECK(field);
79 [field_ setDelegate:edit_helper_]; 121 [field_ setDelegate:edit_helper_];
122
123 // Needed so that editing doesn't lose the styling.
124 [field_ setAllowsEditingTextAttributes:YES];
80 } 125 }
81 126
82 AutocompleteEditViewMac::~AutocompleteEditViewMac() { 127 AutocompleteEditViewMac::~AutocompleteEditViewMac() {
83 // TODO(shess): Having to be aware of destructor ordering in this 128 // TODO(shess): Having to be aware of destructor ordering in this
84 // way seems brittle. There must be a better way. 129 // way seems brittle. There must be a better way.
85 130
86 // Destroy popup view before this object in case it tries to call us 131 // Destroy popup view before this object in case it tries to call us
87 // back in the destructor. Likewise for destroying the model before 132 // back in the destructor. Likewise for destroying the model before
88 // this object. 133 // this object.
89 popup_view_.reset(); 134 popup_view_.reset();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // Should restore the user's text via SetUserText(). 175 // Should restore the user's text via SetUserText().
131 model_->RestoreState(state->model_state); 176 model_->RestoreState(state->model_state);
132 177
133 // Restore user's selection. 178 // Restore user's selection.
134 // TODO(shess): The model_ does not restore the focus state. If 179 // TODO(shess): The model_ does not restore the focus state. If
135 // field_ was in focus when we switched away, I presume it 180 // field_ was in focus when we switched away, I presume it
136 // should be in focus when we switch back. Figure out if model_ 181 // should be in focus when we switch back. Figure out if model_
137 // not restoring focus is an oversight, or intentional for some 182 // not restoring focus is an oversight, or intentional for some
138 // subtle reason. 183 // subtle reason.
139 if (state->has_focus) { 184 if (state->has_focus) {
140 FocusLocation(); 185 SetSelectedRange(state->selection);
141 DCHECK([field_ currentEditor]);
142 [[field_ currentEditor] setSelectedRange:state->selection];
143 } 186 }
144 } 187 }
145 } else if (user_visible) { 188 } else if (user_visible) {
146 // Restore everything to the baseline look. 189 // Restore everything to the baseline look.
147 RevertAll(); 190 RevertAll();
148 // TODO(shess): Figure out how this case is used, to make sure 191 // TODO(shess): Figure out how this case is used, to make sure
149 // we're getting the selection and popup right. 192 // we're getting the selection and popup right.
150 193
151 } else { 194 } else {
152 // TODO(shess): Figure out how this case is used, to make sure 195 // TODO(shess): Figure out how this case is used, to make sure
153 // we're getting the selection and popup right. 196 // we're getting the selection and popup right.
154 // UpdateAndStyleText() approximates the inner part of Revertall() 197 UpdateAndStyleText(text);
155 // which under GTK is called EmphasizeURLComponents(), and is
156 // expected to change when I start feeding in the styling code.
157 UpdateAndStyleText(text, 0);
158 } 198 }
159 } 199 }
160 200
161 void AutocompleteEditViewMac::OpenURL(const GURL& url, 201 void AutocompleteEditViewMac::OpenURL(const GURL& url,
162 WindowOpenDisposition disposition, 202 WindowOpenDisposition disposition,
163 PageTransition::Type transition, 203 PageTransition::Type transition,
164 const GURL& alternate_nav_url, 204 const GURL& alternate_nav_url,
165 size_t selected_line, 205 size_t selected_line,
166 const std::wstring& keyword) { 206 const std::wstring& keyword) {
167 // TODO(shess): Why is the caller passing an invalid url in the 207 // TODO(shess): Why is the caller passing an invalid url in the
(...skipping 12 matching lines...) Expand all
180 } 220 }
181 221
182 std::wstring AutocompleteEditViewMac::GetText() const { 222 std::wstring AutocompleteEditViewMac::GetText() const {
183 return base::SysNSStringToWide([field_ stringValue]); 223 return base::SysNSStringToWide([field_ stringValue]);
184 } 224 }
185 225
186 void AutocompleteEditViewMac::SetUserText(const std::wstring& text, 226 void AutocompleteEditViewMac::SetUserText(const std::wstring& text,
187 const std::wstring& display_text, 227 const std::wstring& display_text,
188 bool update_popup) { 228 bool update_popup) {
189 model_->SetUserText(text); 229 model_->SetUserText(text);
190 UpdateAndStyleText(display_text, display_text.size()); 230 // TODO(shess): TODO below from gtk.
231 // TODO(deanm): something about selection / focus change here.
232 UpdateAndStyleText(display_text);
191 if (update_popup) { 233 if (update_popup) {
192 UpdatePopup(); 234 UpdatePopup();
193 } 235 }
194 } 236 }
195 237
196 NSRange AutocompleteEditViewMac::GetSelectedRange() const { 238 NSRange AutocompleteEditViewMac::GetSelectedRange() const {
197 DCHECK([field_ currentEditor]); 239 DCHECK([field_ currentEditor]);
198 return [[field_ currentEditor] selectedRange]; 240 return [[field_ currentEditor] selectedRange];
199 } 241 }
200 242
243 void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) {
244 // TODO(shess): Check if we should steal focus or not. We can't set
245 // the selection without focus, though.
246 FocusLocation();
247
248 // TODO(shess): What if it didn't get first responder, and there is
249 // no field editor? This will do nothing. Well, at least it won't
250 // crash. Think of something more productive to do, or prove that
251 // it cannot occur and DCHECK appropriately.
252 [[field_ currentEditor] setSelectedRange:range];
253 }
254
201 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, 255 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text,
202 size_t caret_pos) { 256 size_t caret_pos) {
203 UpdateAndStyleText(text, text.size()); 257 DCHECK_LE(caret_pos, text.size());
258 UpdateAndStyleText(text);
259 SetSelectedRange(NSMakeRange(caret_pos, caret_pos));
204 } 260 }
205 261
206 void AutocompleteEditViewMac::SelectAll(bool reversed) { 262 void AutocompleteEditViewMac::SelectAll(bool reversed) {
207 // TODO(shess): Figure out what reversed implies. The gtk version 263 // TODO(shess): Figure out what |reversed| implies. The gtk version
208 // has it imply inverting the selection front to back, but I don't 264 // has it imply inverting the selection front to back, but I don't
209 // even know if that makes sense for Mac. 265 // even know if that makes sense for Mac.
210 UpdateAndStyleText(GetText(), 0); 266
267 // TODO(shess): Verify that we should be stealing focus at this
268 // point.
269 SetSelectedRange(NSMakeRange(0, GetText().size()));
211 } 270 }
212 271
213 void AutocompleteEditViewMac::RevertAll() { 272 void AutocompleteEditViewMac::RevertAll() {
214 ClosePopup(); 273 ClosePopup();
215 model_->Revert(); 274 model_->Revert();
216 275
217 std::wstring tt = GetText(); 276 UpdateAndStyleText(GetText());
218 UpdateAndStyleText(tt, 0);
219 controller_->OnChanged(); 277 controller_->OnChanged();
220 } 278 }
221 279
222 void AutocompleteEditViewMac::UpdatePopup() { 280 void AutocompleteEditViewMac::UpdatePopup() {
223 model_->SetInputInProgress(true); 281 model_->SetInputInProgress(true);
224 if (!model_->has_focus()) 282 if (!model_->has_focus())
225 return; 283 return;
226 284
227 // TODO(shess): 285 // TODO(shess):
228 // Shouldn't inline autocomplete when the caret/selection isn't at 286 // Shouldn't inline autocomplete when the caret/selection isn't at
229 // the end of the text. 287 // the end of the text.
230 // 288 //
231 // One option would seem to be to check for a non-nil field 289 // One option would seem to be to check for a non-nil field
232 // editor, and check it's selected range against its length. 290 // editor, and check it's selected range against its length.
233 model_->StartAutocomplete(false); 291 model_->StartAutocomplete(false);
234 } 292 }
235 293
236 void AutocompleteEditViewMac::ClosePopup() { 294 void AutocompleteEditViewMac::ClosePopup() {
237 popup_view_->GetModel()->StopAutocomplete(); 295 popup_view_->GetModel()->StopAutocomplete();
238 } 296 }
239 297
240 void AutocompleteEditViewMac::UpdateAndStyleText( 298 void AutocompleteEditViewMac::UpdateAndStyleText(
241 const std::wstring& display_text, size_t user_text_length) { 299 const std::wstring& display_text) {
242 NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
243 [field_ font], NSFontAttributeName,
244 nil];
245 NSString* ss = base::SysWideToNSString(display_text); 300 NSString* ss = base::SysWideToNSString(display_text);
246 NSMutableAttributedString* as = 301 NSMutableAttributedString* as =
247 [[[NSMutableAttributedString alloc] initWithString:ss 302 [[[NSMutableAttributedString alloc] initWithString:ss] autorelease];
248 attributes:attributes] 303 [as addAttribute:NSFontAttributeName value:[field_ font]
249 autorelease]; 304 range:NSMakeRange(0, [as length])];
250 305
251 url_parse::Parsed parts; 306 url_parse::Parsed parts;
252 AutocompleteInput::Parse(display_text, model_->GetDesiredTLD(), 307 AutocompleteInput::Parse(display_text, model_->GetDesiredTLD(),
253 &parts, NULL); 308 &parts, NULL);
254 bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0); 309 const bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0);
255 if (emphasize) { 310 if (emphasize) {
256 // TODO(shess): Pull color out as a constant. 311 [as addAttribute:NSForegroundColorAttributeName value:BaseTextColor()
257 [as addAttribute:NSForegroundColorAttributeName 312 range:NSMakeRange(0, [as length])];
258 value:[NSColor greenColor] 313
259 range:NSMakeRange((NSInteger)parts.host.begin, 314 [as addAttribute:NSForegroundColorAttributeName value:HostTextColor()
260 (NSInteger)parts.host.len)]; 315 range:ComponentToNSRange(parts.host)];
261 } 316 }
262 317
263 // TODO(shess): GTK has this as a member var, figure out why. 318 // TODO(shess): GTK has this as a member var, figure out why.
264 ToolbarModel::SecurityLevel scheme_security_level = 319 // [Could it be to not change if no change? If so, I'm guessing
320 // AppKit may already handle that.]
321 const ToolbarModel::SecurityLevel scheme_security_level =
265 toolbar_model_->GetSchemeSecurityLevel(); 322 toolbar_model_->GetSchemeSecurityLevel();
266 323
324 if (scheme_security_level == ToolbarModel::SECURE) {
325 [field_ setBackgroundColor:SecureBackgroundColor()];
326 } else if (scheme_security_level == ToolbarModel::NORMAL) {
327 [field_ setBackgroundColor:NormalBackgroundColor()];
328 } else if (scheme_security_level == ToolbarModel::INSECURE) {
329 [field_ setBackgroundColor:InsecureBackgroundColor()];
330 } else {
331 NOTREACHED() << "Unexpected scheme_security_level: "
332 << scheme_security_level;
333 }
334
267 // Emphasize the scheme for security UI display purposes (if necessary). 335 // Emphasize the scheme for security UI display purposes (if necessary).
268 if (!model_->user_input_in_progress() && parts.scheme.is_nonempty() && 336 if (!model_->user_input_in_progress() && parts.scheme.is_nonempty() &&
269 (scheme_security_level != ToolbarModel::NORMAL)) { 337 (scheme_security_level != ToolbarModel::NORMAL)) {
270 // TODO(shess): Pull colors out as constants.
271 NSColor* color; 338 NSColor* color;
272 if (scheme_security_level == ToolbarModel::SECURE) { 339 if (scheme_security_level == ToolbarModel::SECURE) {
273 color = [NSColor blueColor]; 340 color = SecureSchemeColor();
274 } else { 341 } else {
275 color = [NSColor blackColor]; 342 color = InsecureSchemeColor();
276 } 343 }
277 [as addAttribute:NSForegroundColorAttributeName value:color 344 [as addAttribute:NSForegroundColorAttributeName value:color
278 range:NSMakeRange((NSInteger)parts.scheme.begin, 345 range:ComponentToNSRange(parts.scheme)];
279 (NSInteger)parts.scheme.len)];
280 } 346 }
281 347
282 // TODO(shess): Check that this updates the model's sense of focus
283 // correctly.
284 [field_ setObjectValue:as]; 348 [field_ setObjectValue:as];
285 if (![field_ currentEditor]) {
286 [field_ becomeFirstResponder];
287 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]);
288 }
289
290 NSRange selected_range = NSMakeRange(user_text_length, [as length]);
291 // TODO(shess): What if it didn't get first responder, and there is
292 // no field editor? This will do nothing. Well, at least it won't
293 // crash. Think of something more productive to do, or prove that
294 // it cannot occur and DCHECK appropriately.
295 [[field_ currentEditor] setSelectedRange:selected_range];
296 } 349 }
297 350
298 void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged( 351 void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged(
299 const std::wstring& display_text, bool save_original_selection) { 352 const std::wstring& display_text, bool save_original_selection) {
300 // TODO(shess): I believe this is for when the user arrows around 353 // TODO(shess): I believe this is for when the user arrows around
301 // the popup, will be restored if they hit escape. Figure out if 354 // the popup, will be restored if they hit escape. Figure out if
302 // that is for certain it. 355 // that is for certain it.
303 if (save_original_selection) { 356 if (save_original_selection) {
357 saved_temporary_selection_ = GetSelectedRange();
304 saved_temporary_text_ = GetText(); 358 saved_temporary_text_ = GetText();
305 } 359 }
306 360
307 UpdateAndStyleText(display_text, display_text.size()); 361 SetWindowTextAndCaretPos(display_text, display_text.size());
308 } 362 }
309 363
310 bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged( 364 bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged(
311 const std::wstring& display_text, size_t user_text_length) { 365 const std::wstring& display_text, size_t user_text_length) {
312 // TODO(shess): Make sure that this actually works. The round trip 366 // TODO(shess): Make sure that this actually works. The round trip
313 // to native form and back may mean that it's the same but not the 367 // to native form and back may mean that it's the same but not the
314 // same. 368 // same.
315 if (display_text == GetText()) { 369 if (display_text == GetText()) {
316 return false; 370 return false;
317 } 371 }
318 372
319 UpdateAndStyleText(display_text, user_text_length); 373 UpdateAndStyleText(display_text);
374 DCHECK_LE(user_text_length, display_text.size());
375 SetSelectedRange(NSMakeRange(user_text_length, display_text.size()));
320 return true; 376 return true;
321 } 377 }
322 378
323 void AutocompleteEditViewMac::OnRevertTemporaryText() { 379 void AutocompleteEditViewMac::OnRevertTemporaryText() {
324 UpdateAndStyleText(saved_temporary_text_, saved_temporary_text_.size()); 380 UpdateAndStyleText(saved_temporary_text_);
325 saved_temporary_text_.clear(); 381 saved_temporary_text_.clear();
382 SetSelectedRange(saved_temporary_selection_);
326 } 383 }
327 384
328 void AutocompleteEditViewMac::OnBeforePossibleChange() { 385 void AutocompleteEditViewMac::OnBeforePossibleChange() {
329 selection_before_change_ = GetSelectedRange(); 386 selection_before_change_ = GetSelectedRange();
330 text_before_change_ = GetText(); 387 text_before_change_ = GetText();
331 } 388 }
332 389
333 bool AutocompleteEditViewMac::OnAfterPossibleChange() { 390 bool AutocompleteEditViewMac::OnAfterPossibleChange() {
334 NSRange new_selection(GetSelectedRange()); 391 const NSRange new_selection(GetSelectedRange());
335 std::wstring new_text(GetText()); 392 const std::wstring new_text(GetText());
336 const size_t length = new_text.length(); 393 const size_t length = new_text.length();
337 394
338 bool selection_differs = !NSEqualRanges(new_selection, 395 const bool selection_differs = !NSEqualRanges(new_selection,
339 selection_before_change_); 396 selection_before_change_);
340 bool at_end_of_edit = (length == new_selection.location); 397 const bool at_end_of_edit = (length == new_selection.location);
341 bool text_differs = (new_text != text_before_change_); 398 const bool text_differs = (new_text != text_before_change_);
342 399
343 // When the user has deleted text, we don't allow inline 400 // When the user has deleted text, we don't allow inline
344 // autocomplete. This is assumed if the text has gotten shorter AND 401 // autocomplete. This is assumed if the text has gotten shorter AND
345 // the selection has shifted towards the front of the text. During 402 // the selection has shifted towards the front of the text. During
346 // normal typing the text will almost always be shorter (as the new 403 // normal typing the text will almost always be shorter (as the new
347 // input replaces the autocomplete suggestion), but in that case the 404 // input replaces the autocomplete suggestion), but in that case the
348 // selection point will have moved towards the end of the text. 405 // selection point will have moved towards the end of the text.
349 // TODO(shess): In our implementation, we can catch -deleteBackward: 406 // TODO(shess): In our implementation, we can catch -deleteBackward:
350 // and other methods to provide positive knowledge that a delete 407 // and other methods to provide positive knowledge that a delete
351 // occured, rather than intuiting it from context. Consider whether 408 // occured, rather than intuiting it from context. Consider whether
352 // that would be a stronger approach. 409 // that would be a stronger approach.
353 bool just_deleted_text = 410 const bool just_deleted_text =
354 (length < text_before_change_.length() && 411 (length < text_before_change_.length() &&
355 new_selection.location <= selection_before_change_.location); 412 new_selection.location <= selection_before_change_.location);
356 413
357 bool something_changed = model_->OnAfterPossibleChange(new_text, 414 const bool something_changed = model_->OnAfterPossibleChange(new_text,
358 selection_differs, text_differs, just_deleted_text, at_end_of_edit); 415 selection_differs, text_differs, just_deleted_text, at_end_of_edit);
359 416
360 // TODO(shess): Restyle the text if something_changed. Not fixing 417 // Restyle if the user changed something.
361 // now because styling is currently broken. 418 // TODO(shess): Does this need to diver deeper to avoid flashing?
419 // For instance, if the user types "/" after the hostname, will it
420 // show as HostTextColor() for an instant before being replaced by
421 // BaseTextColor(). This could probably be done by subclassing the
422 // cell and intercepting draw requests so that we draw the right
423 // thing every time.
424 // NOTE(shess): That kind of thing would also help with when the
425 // flashing from when the user's typing replaces the selection which
426 // is then re-created with the new autocomplete results.
427 if (something_changed) {
428 UpdateAndStyleText(new_text);
429 SetSelectedRange(new_selection);
430 }
362 431
363 return something_changed; 432 return something_changed;
364 } 433 }
365 434
366 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) { 435 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) {
367 int count = by_page ? model_->result().size() : 1; 436 const int count = by_page ? model_->result().size() : 1;
368 model_->OnUpOrDownKeyPressed(up ? -count : count); 437 model_->OnUpOrDownKeyPressed(up ? -count : count);
369 } 438 }
370 void AutocompleteEditViewMac::OnEscapeKeyPressed() { 439 void AutocompleteEditViewMac::OnEscapeKeyPressed() {
371 model_->OnEscapeKeyPressed(); 440 model_->OnEscapeKeyPressed();
372 } 441 }
373 void AutocompleteEditViewMac::OnSetFocus(bool f) { 442 void AutocompleteEditViewMac::OnSetFocus(bool f) {
374 model_->OnSetFocus(f); 443 model_->OnSetFocus(f);
375 } 444 }
376 void AutocompleteEditViewMac::OnKillFocus() { 445 void AutocompleteEditViewMac::OnKillFocus() {
377 model_->OnKillFocus(); 446 model_->OnKillFocus();
378 } 447 }
379 void AutocompleteEditViewMac::AcceptInput( 448 void AutocompleteEditViewMac::AcceptInput(
380 WindowOpenDisposition disposition, bool for_drop) { 449 WindowOpenDisposition disposition, bool for_drop) {
381 model_->AcceptInput(disposition, for_drop); 450 model_->AcceptInput(disposition, for_drop);
382 } 451 }
383 452
384 void AutocompleteEditViewMac::FocusLocation() { 453 void AutocompleteEditViewMac::FocusLocation() {
385 // -makeFirstResponder: will select the entire field_. If we're 454 // -makeFirstResponder: will select the entire field_. If we're
386 // already firstResponder, it's likely that we want to retain the 455 // already firstResponder, it's likely that we want to retain the
387 // current selection. 456 // current selection.
388 if (![field_ currentEditor]) { 457 if (![field_ currentEditor]) {
389 [[field_ window] makeFirstResponder:field_]; 458 [[field_ window] makeFirstResponder:field_];
459 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]);
390 } 460 }
391 } 461 }
392 462
393 @implementation AutocompleteFieldDelegate 463 @implementation AutocompleteFieldDelegate
394 464
395 - initWithEditView:(AutocompleteEditViewMac*)view { 465 - initWithEditView:(AutocompleteEditViewMac*)view {
396 self = [super init]; 466 self = [super init];
397 if (self) { 467 if (self) {
398 edit_view_ = view; 468 edit_view_ = view;
399 } 469 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 525 }
456 526
457 - (void)controlTextDidEndEditing:(NSNotification*)aNotification { 527 - (void)controlTextDidEndEditing:(NSNotification*)aNotification {
458 edit_view_->OnKillFocus(); 528 edit_view_->OnKillFocus();
459 529
460 // TODO(shess): Figure out where the selection belongs. On GTK, 530 // TODO(shess): Figure out where the selection belongs. On GTK,
461 // it's set to the start of the text. 531 // it's set to the start of the text.
462 } 532 }
463 533
464 @end 534 @end
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698