| 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 |