OLD | NEW |
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" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 // TODO(shess): Figure out how this case is used, to make sure | 236 // TODO(shess): Figure out how this case is used, to make sure |
237 // we're getting the selection and popup right. | 237 // we're getting the selection and popup right. |
238 | 238 |
239 } else { | 239 } else { |
240 // TODO(shess): This corresponds to _win and _gtk, except those | 240 // TODO(shess): This corresponds to _win and _gtk, except those |
241 // guard it with a test for whether the security level changed. | 241 // guard it with a test for whether the security level changed. |
242 // But AFAICT, that can only change if the text changed, and that | 242 // But AFAICT, that can only change if the text changed, and that |
243 // code compares the toolbar_model_ security level with the local | 243 // code compares the toolbar_model_ security level with the local |
244 // security level. Dig in and figure out why this isn't a no-op | 244 // security level. Dig in and figure out why this isn't a no-op |
245 // that should go away. | 245 // that should go away. |
246 UpdateAndStyleText(GetText()); | 246 EmphasizeURLComponents(); |
247 } | 247 } |
248 } | 248 } |
249 | 249 |
250 void AutocompleteEditViewMac::OpenURL(const GURL& url, | 250 void AutocompleteEditViewMac::OpenURL(const GURL& url, |
251 WindowOpenDisposition disposition, | 251 WindowOpenDisposition disposition, |
252 PageTransition::Type transition, | 252 PageTransition::Type transition, |
253 const GURL& alternate_nav_url, | 253 const GURL& alternate_nav_url, |
254 size_t selected_line, | 254 size_t selected_line, |
255 const std::wstring& keyword) { | 255 const std::wstring& keyword) { |
256 // TODO(shess): Why is the caller passing an invalid url in the | 256 // TODO(shess): Why is the caller passing an invalid url in the |
(...skipping 14 matching lines...) Expand all Loading... |
271 std::wstring AutocompleteEditViewMac::GetText() const { | 271 std::wstring AutocompleteEditViewMac::GetText() const { |
272 return base::SysNSStringToWide([field_ stringValue]); | 272 return base::SysNSStringToWide([field_ stringValue]); |
273 } | 273 } |
274 | 274 |
275 void AutocompleteEditViewMac::SetUserText(const std::wstring& text, | 275 void AutocompleteEditViewMac::SetUserText(const std::wstring& text, |
276 const std::wstring& display_text, | 276 const std::wstring& display_text, |
277 bool update_popup) { | 277 bool update_popup) { |
278 model_->SetUserText(text); | 278 model_->SetUserText(text); |
279 // TODO(shess): TODO below from gtk. | 279 // TODO(shess): TODO below from gtk. |
280 // TODO(deanm): something about selection / focus change here. | 280 // TODO(deanm): something about selection / focus change here. |
281 UpdateAndStyleText(display_text); | 281 SetText(display_text); |
282 if (update_popup) { | 282 if (update_popup) { |
283 UpdatePopup(); | 283 UpdatePopup(); |
284 } | 284 } |
285 } | 285 } |
286 | 286 |
287 NSRange AutocompleteEditViewMac::GetSelectedRange() const { | 287 NSRange AutocompleteEditViewMac::GetSelectedRange() const { |
288 DCHECK([field_ currentEditor]); | 288 DCHECK([field_ currentEditor]); |
289 return [[field_ currentEditor] selectedRange]; | 289 return [[field_ currentEditor] selectedRange]; |
290 } | 290 } |
291 | 291 |
292 void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) { | 292 void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) { |
293 if (model_->has_focus()) { | 293 if (model_->has_focus()) { |
294 // TODO(shess): This should not be necessary. Try to convert to | 294 // TODO(shess): This should not be necessary. Try to convert to |
295 // DCHECK(IsFirstResponder()). | 295 // DCHECK(IsFirstResponder()). |
296 FocusLocation(); | 296 FocusLocation(); |
297 | 297 |
298 // TODO(shess): What if it didn't get first responder, and there is | 298 // TODO(shess): What if it didn't get first responder, and there is |
299 // no field editor? This will do nothing. Well, at least it won't | 299 // no field editor? This will do nothing. Well, at least it won't |
300 // crash. Think of something more productive to do, or prove that | 300 // crash. Think of something more productive to do, or prove that |
301 // it cannot occur and DCHECK appropriately. | 301 // it cannot occur and DCHECK appropriately. |
302 [[field_ currentEditor] setSelectedRange:range]; | 302 [[field_ currentEditor] setSelectedRange:range]; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, | 306 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, |
307 size_t caret_pos) { | 307 size_t caret_pos) { |
308 DCHECK_LE(caret_pos, text.size()); | 308 DCHECK_LE(caret_pos, text.size()); |
309 UpdateAndStyleText(text); | 309 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, caret_pos)); |
310 SetSelectedRange(NSMakeRange(caret_pos, caret_pos)); | |
311 } | 310 } |
312 | 311 |
313 void AutocompleteEditViewMac::SelectAll(bool reversed) { | 312 void AutocompleteEditViewMac::SelectAll(bool reversed) { |
314 // TODO(shess): Figure out what |reversed| implies. The gtk version | 313 // TODO(shess): Figure out what |reversed| implies. The gtk version |
315 // has it imply inverting the selection front to back, but I don't | 314 // has it imply inverting the selection front to back, but I don't |
316 // even know if that makes sense for Mac. | 315 // even know if that makes sense for Mac. |
317 | 316 |
318 // TODO(shess): Verify that we should be stealing focus at this | 317 // TODO(shess): Verify that we should be stealing focus at this |
319 // point. | 318 // point. |
320 SetSelectedRange(NSMakeRange(0, GetText().size())); | 319 SetSelectedRange(NSMakeRange(0, GetText().size())); |
321 } | 320 } |
322 | 321 |
323 void AutocompleteEditViewMac::RevertAll() { | 322 void AutocompleteEditViewMac::RevertAll() { |
324 ClosePopup(); | 323 ClosePopup(); |
325 model_->Revert(); | 324 model_->Revert(); |
326 | 325 |
327 // TODO(shess): This should be a no-op, the results from GetText() | 326 // TODO(shess): This should be a no-op, the results from GetText() |
328 // could only get there via UpdateAndStyleText() in the first place. | 327 // could only get there via UpdateAndStyleText() in the first place. |
329 // Dig into where this code can be called from and see if this line | 328 // Dig into where this code can be called from and see if this line |
330 // can be removed. | 329 // can be removed. |
331 UpdateAndStyleText(GetText()); | 330 EmphasizeURLComponents(); |
332 controller_->OnChanged(); | 331 controller_->OnChanged(); |
333 } | 332 } |
334 | 333 |
335 void AutocompleteEditViewMac::UpdatePopup() { | 334 void AutocompleteEditViewMac::UpdatePopup() { |
336 model_->SetInputInProgress(true); | 335 model_->SetInputInProgress(true); |
337 if (!model_->has_focus()) | 336 if (!model_->has_focus()) |
338 return; | 337 return; |
339 | 338 |
340 // TODO(shess): | 339 // TODO(shess): |
341 // Shouldn't inline autocomplete when the caret/selection isn't at | 340 // Shouldn't inline autocomplete when the caret/selection isn't at |
342 // the end of the text. | 341 // the end of the text. |
343 // | 342 // |
344 // One option would seem to be to check for a non-nil field | 343 // One option would seem to be to check for a non-nil field |
345 // editor, and check it's selected range against its length. | 344 // editor, and check it's selected range against its length. |
346 model_->StartAutocomplete(false); | 345 model_->StartAutocomplete(false); |
347 } | 346 } |
348 | 347 |
349 void AutocompleteEditViewMac::ClosePopup() { | 348 void AutocompleteEditViewMac::ClosePopup() { |
350 popup_view_->GetModel()->StopAutocomplete(); | 349 popup_view_->GetModel()->StopAutocomplete(); |
351 } | 350 } |
352 | 351 |
353 void AutocompleteEditViewMac::UpdateAndStyleText( | 352 void AutocompleteEditViewMac::SetText(const std::wstring& display_text) { |
354 const std::wstring& display_text) { | |
355 NSString* ss = base::SysWideToNSString(display_text); | 353 NSString* ss = base::SysWideToNSString(display_text); |
356 NSMutableAttributedString* as = | 354 NSMutableAttributedString* as = |
357 [[[NSMutableAttributedString alloc] initWithString:ss] autorelease]; | 355 [[[NSMutableAttributedString alloc] initWithString:ss] autorelease]; |
358 [as addAttribute:NSFontAttributeName value:[field_ font] | 356 [as addAttribute:NSFontAttributeName value:[field_ font] |
359 range:NSMakeRange(0, [as length])]; | 357 range:NSMakeRange(0, [as length])]; |
360 | 358 |
361 url_parse::Parsed parts; | 359 url_parse::Parsed parts; |
362 AutocompleteInput::Parse(display_text, model_->GetDesiredTLD(), | 360 AutocompleteInput::Parse(display_text, model_->GetDesiredTLD(), |
363 &parts, NULL); | 361 &parts, NULL); |
364 const bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0); | 362 const bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 } else { | 394 } else { |
397 color = InsecureSchemeColor(); | 395 color = InsecureSchemeColor(); |
398 } | 396 } |
399 [as addAttribute:NSForegroundColorAttributeName value:color | 397 [as addAttribute:NSForegroundColorAttributeName value:color |
400 range:ComponentToNSRange(parts.scheme)]; | 398 range:ComponentToNSRange(parts.scheme)]; |
401 } | 399 } |
402 | 400 |
403 [field_ setObjectValue:as]; | 401 [field_ setObjectValue:as]; |
404 } | 402 } |
405 | 403 |
| 404 void AutocompleteEditViewMac::SetTextAndSelectedRange( |
| 405 const std::wstring& display_text, const NSRange range) { |
| 406 SetText(display_text); |
| 407 SetSelectedRange(range); |
| 408 } |
| 409 |
| 410 void AutocompleteEditViewMac::EmphasizeURLComponents() { |
| 411 if ([field_ currentEditor]) { |
| 412 SetTextAndSelectedRange(GetText(), GetSelectedRange()); |
| 413 } else { |
| 414 SetText(GetText()); |
| 415 } |
| 416 } |
| 417 |
406 void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged( | 418 void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged( |
407 const std::wstring& display_text, bool save_original_selection) { | 419 const std::wstring& display_text, bool save_original_selection) { |
408 // TODO(shess): I believe this is for when the user arrows around | 420 // TODO(shess): I believe this is for when the user arrows around |
409 // the popup, will be restored if they hit escape. Figure out if | 421 // the popup, will be restored if they hit escape. Figure out if |
410 // that is for certain it. | 422 // that is for certain it. |
411 if (save_original_selection) { | 423 if (save_original_selection) { |
412 saved_temporary_selection_ = GetSelectedRange(); | 424 saved_temporary_selection_ = GetSelectedRange(); |
413 saved_temporary_text_ = GetText(); | 425 saved_temporary_text_ = GetText(); |
414 } | 426 } |
415 | 427 |
416 SetWindowTextAndCaretPos(display_text, display_text.size()); | 428 SetWindowTextAndCaretPos(display_text, display_text.size()); |
417 } | 429 } |
418 | 430 |
419 bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged( | 431 bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged( |
420 const std::wstring& display_text, size_t user_text_length) { | 432 const std::wstring& display_text, size_t user_text_length) { |
421 // TODO(shess): Make sure that this actually works. The round trip | 433 // TODO(shess): Make sure that this actually works. The round trip |
422 // to native form and back may mean that it's the same but not the | 434 // to native form and back may mean that it's the same but not the |
423 // same. | 435 // same. |
424 if (display_text == GetText()) { | 436 if (display_text == GetText()) { |
425 return false; | 437 return false; |
426 } | 438 } |
427 | 439 |
428 UpdateAndStyleText(display_text); | |
429 DCHECK_LE(user_text_length, display_text.size()); | 440 DCHECK_LE(user_text_length, display_text.size()); |
430 SetSelectedRange(NSMakeRange(user_text_length, display_text.size())); | 441 const NSRange range = NSMakeRange(user_text_length, display_text.size()); |
| 442 SetTextAndSelectedRange(display_text, range); |
| 443 |
431 return true; | 444 return true; |
432 } | 445 } |
433 | 446 |
434 void AutocompleteEditViewMac::OnRevertTemporaryText() { | 447 void AutocompleteEditViewMac::OnRevertTemporaryText() { |
435 UpdateAndStyleText(saved_temporary_text_); | 448 SetTextAndSelectedRange(saved_temporary_text_, saved_temporary_selection_); |
436 saved_temporary_text_.clear(); | 449 saved_temporary_text_.clear(); |
437 SetSelectedRange(saved_temporary_selection_); | |
438 } | 450 } |
439 | 451 |
440 bool AutocompleteEditViewMac::IsFirstResponder() const { | 452 bool AutocompleteEditViewMac::IsFirstResponder() const { |
441 return [field_ currentEditor] != nil ? true : false; | 453 return [field_ currentEditor] != nil ? true : false; |
442 } | 454 } |
443 | 455 |
444 void AutocompleteEditViewMac::OnBeforePossibleChange() { | 456 void AutocompleteEditViewMac::OnBeforePossibleChange() { |
445 // We should only arrive here when the field is focussed. | 457 // We should only arrive here when the field is focussed. |
446 DCHECK(IsFirstResponder()); | 458 DCHECK(IsFirstResponder()); |
447 | 459 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 // TODO(shess): Does this need to diver deeper to avoid flashing? | 495 // TODO(shess): Does this need to diver deeper to avoid flashing? |
484 // For instance, if the user types "/" after the hostname, will it | 496 // For instance, if the user types "/" after the hostname, will it |
485 // show as HostTextColor() for an instant before being replaced by | 497 // show as HostTextColor() for an instant before being replaced by |
486 // BaseTextColor(). This could probably be done by subclassing the | 498 // BaseTextColor(). This could probably be done by subclassing the |
487 // cell and intercepting draw requests so that we draw the right | 499 // cell and intercepting draw requests so that we draw the right |
488 // thing every time. | 500 // thing every time. |
489 // NOTE(shess): That kind of thing would also help with when the | 501 // NOTE(shess): That kind of thing would also help with when the |
490 // flashing from when the user's typing replaces the selection which | 502 // flashing from when the user's typing replaces the selection which |
491 // is then re-created with the new autocomplete results. | 503 // is then re-created with the new autocomplete results. |
492 if (something_changed) { | 504 if (something_changed) { |
493 UpdateAndStyleText(new_text); | 505 // TODO(shess) I believe that this call is needless duplication of |
494 SetSelectedRange(new_selection); | 506 // effort. As best I can tell, something_changed can only be true |
| 507 // if |model_| called UpdatePopup(), which then updated us. But |
| 508 // the state involved seems substantial. |
| 509 EmphasizeURLComponents(); |
495 } | 510 } |
496 | 511 |
497 return something_changed; | 512 return something_changed; |
498 } | 513 } |
499 | 514 |
500 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) { | 515 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) { |
501 // We should only arrive here when the field is focussed. | 516 // We should only arrive here when the field is focussed. |
502 DCHECK(IsFirstResponder()); | 517 DCHECK(IsFirstResponder()); |
503 | 518 |
504 const int count = by_page ? model_->result().size() : 1; | 519 const int count = by_page ? model_->result().size() : 1; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 // TODO(shess): Figure out where the selection belongs. On GTK, | 639 // TODO(shess): Figure out where the selection belongs. On GTK, |
625 // it's set to the start of the text. | 640 // it's set to the start of the text. |
626 } | 641 } |
627 | 642 |
628 // Signal that we've lost focus when the window resigns key. | 643 // Signal that we've lost focus when the window resigns key. |
629 - (void)windowDidResignKey:(NSNotification*)notification { | 644 - (void)windowDidResignKey:(NSNotification*)notification { |
630 edit_view_->OnDidResignKey(); | 645 edit_view_->OnDidResignKey(); |
631 } | 646 } |
632 | 647 |
633 @end | 648 @end |
OLD | NEW |