OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/omnibox/omnibox_view_views.h" | 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 } | 334 } |
335 #endif | 335 #endif |
336 model()->OnWillKillFocus(native_view); | 336 model()->OnWillKillFocus(native_view); |
337 // Close the popup. | 337 // Close the popup. |
338 CloseOmniboxPopup(); | 338 CloseOmniboxPopup(); |
339 // Tell the model to reset itself. | 339 // Tell the model to reset itself. |
340 model()->OnKillFocus(); | 340 model()->OnKillFocus(); |
341 controller()->OnKillFocus(); | 341 controller()->OnKillFocus(); |
342 | 342 |
343 // Make sure the beginning of the text is visible. | 343 // Make sure the beginning of the text is visible. |
344 SelectRange(ui::Range(0)); | 344 SelectRange(gfx::Range(0)); |
345 } | 345 } |
346 | 346 |
347 //////////////////////////////////////////////////////////////////////////////// | 347 //////////////////////////////////////////////////////////////////////////////// |
348 // OmniboxViewViews, OmniboxView implementation: | 348 // OmniboxViewViews, OmniboxView implementation: |
349 | 349 |
350 void OmniboxViewViews::SaveStateToTab(content::WebContents* tab) { | 350 void OmniboxViewViews::SaveStateToTab(content::WebContents* tab) { |
351 DCHECK(tab); | 351 DCHECK(tab); |
352 | 352 |
353 // We don't want to keep the IME status, so force quit the current | 353 // We don't want to keep the IME status, so force quit the current |
354 // session here. It may affect the selection status, so order is | 354 // session here. It may affect the selection status, so order is |
(...skipping 24 matching lines...) Expand all Loading... |
379 | 379 |
380 void OmniboxViewViews::Update() { | 380 void OmniboxViewViews::Update() { |
381 const ToolbarModel::SecurityLevel old_security_level = security_level_; | 381 const ToolbarModel::SecurityLevel old_security_level = security_level_; |
382 security_level_ = controller()->GetToolbarModel()->GetSecurityLevel(false); | 382 security_level_ = controller()->GetToolbarModel()->GetSecurityLevel(false); |
383 if (model()->UpdatePermanentText()) { | 383 if (model()->UpdatePermanentText()) { |
384 // Tweak: if the user had all the text selected, select all the new text. | 384 // Tweak: if the user had all the text selected, select all the new text. |
385 // This makes one particular case better: the user clicks in the box to | 385 // This makes one particular case better: the user clicks in the box to |
386 // change it right before the permanent URL is changed. Since the new URL | 386 // change it right before the permanent URL is changed. Since the new URL |
387 // is still fully selected, the user's typing will replace the edit contents | 387 // is still fully selected, the user's typing will replace the edit contents |
388 // as they'd intended. | 388 // as they'd intended. |
389 const ui::Range range(GetSelectedRange()); | 389 const gfx::Range range(GetSelectedRange()); |
390 const bool was_select_all = (range.length() == text().length()); | 390 const bool was_select_all = (range.length() == text().length()); |
391 | 391 |
392 RevertAll(); | 392 RevertAll(); |
393 | 393 |
394 // Only select all when we have focus. If we don't have focus, selecting | 394 // Only select all when we have focus. If we don't have focus, selecting |
395 // all is unnecessary since the selection will change on regaining focus, | 395 // all is unnecessary since the selection will change on regaining focus, |
396 // and can in fact cause artifacts, e.g. if the user is on the NTP and | 396 // and can in fact cause artifacts, e.g. if the user is on the NTP and |
397 // clicks a link to navigate, causing |was_select_all| to be vacuously true | 397 // clicks a link to navigate, causing |was_select_all| to be vacuously true |
398 // for the empty omnibox, and we then select all here, leading to the | 398 // for the empty omnibox, and we then select all here, leading to the |
399 // trailing portion of a long URL being scrolled into view. We could try | 399 // trailing portion of a long URL being scrolled into view. We could try |
400 // and address cases like this, but it seems better to just not muck with | 400 // and address cases like this, but it seems better to just not muck with |
401 // things when the omnibox isn't focused to begin with. | 401 // things when the omnibox isn't focused to begin with. |
402 if (was_select_all && model()->has_focus()) | 402 if (was_select_all && model()->has_focus()) |
403 SelectAll(range.is_reversed()); | 403 SelectAll(range.is_reversed()); |
404 } else if (old_security_level != security_level_) { | 404 } else if (old_security_level != security_level_) { |
405 EmphasizeURLComponents(); | 405 EmphasizeURLComponents(); |
406 } | 406 } |
407 } | 407 } |
408 | 408 |
409 string16 OmniboxViewViews::GetText() const { | 409 string16 OmniboxViewViews::GetText() const { |
410 // TODO(oshima): IME support | 410 // TODO(oshima): IME support |
411 return text(); | 411 return text(); |
412 } | 412 } |
413 | 413 |
414 void OmniboxViewViews::SetWindowTextAndCaretPos(const string16& text, | 414 void OmniboxViewViews::SetWindowTextAndCaretPos(const string16& text, |
415 size_t caret_pos, | 415 size_t caret_pos, |
416 bool update_popup, | 416 bool update_popup, |
417 bool notify_text_changed) { | 417 bool notify_text_changed) { |
418 const ui::Range range(caret_pos, caret_pos); | 418 const gfx::Range range(caret_pos, caret_pos); |
419 SetTextAndSelectedRange(text, range); | 419 SetTextAndSelectedRange(text, range); |
420 | 420 |
421 if (update_popup) | 421 if (update_popup) |
422 UpdatePopup(); | 422 UpdatePopup(); |
423 | 423 |
424 if (notify_text_changed) | 424 if (notify_text_changed) |
425 TextChanged(); | 425 TextChanged(); |
426 } | 426 } |
427 | 427 |
428 void OmniboxViewViews::SetForcedQuery() { | 428 void OmniboxViewViews::SetForcedQuery() { |
429 const string16 current_text(text()); | 429 const string16 current_text(text()); |
430 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); | 430 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); |
431 if (start == string16::npos || (current_text[start] != '?')) | 431 if (start == string16::npos || (current_text[start] != '?')) |
432 SetUserText(ASCIIToUTF16("?")); | 432 SetUserText(ASCIIToUTF16("?")); |
433 else | 433 else |
434 SelectRange(ui::Range(current_text.size(), start + 1)); | 434 SelectRange(gfx::Range(current_text.size(), start + 1)); |
435 } | 435 } |
436 | 436 |
437 bool OmniboxViewViews::IsSelectAll() const { | 437 bool OmniboxViewViews::IsSelectAll() const { |
438 // TODO(oshima): IME support. | 438 // TODO(oshima): IME support. |
439 return text() == GetSelectedText(); | 439 return text() == GetSelectedText(); |
440 } | 440 } |
441 | 441 |
442 bool OmniboxViewViews::DeleteAtEndPressed() { | 442 bool OmniboxViewViews::DeleteAtEndPressed() { |
443 return delete_at_end_pressed_; | 443 return delete_at_end_pressed_; |
444 } | 444 } |
445 | 445 |
446 void OmniboxViewViews::GetSelectionBounds(string16::size_type* start, | 446 void OmniboxViewViews::GetSelectionBounds(string16::size_type* start, |
447 string16::size_type* end) const { | 447 string16::size_type* end) const { |
448 const ui::Range range = GetSelectedRange(); | 448 const gfx::Range range = GetSelectedRange(); |
449 *start = static_cast<size_t>(range.start()); | 449 *start = static_cast<size_t>(range.start()); |
450 *end = static_cast<size_t>(range.end()); | 450 *end = static_cast<size_t>(range.end()); |
451 } | 451 } |
452 | 452 |
453 void OmniboxViewViews::SelectAll(bool reversed) { | 453 void OmniboxViewViews::SelectAll(bool reversed) { |
454 views::Textfield::SelectAll(reversed); | 454 views::Textfield::SelectAll(reversed); |
455 } | 455 } |
456 | 456 |
457 void OmniboxViewViews::UpdatePopup() { | 457 void OmniboxViewViews::UpdatePopup() { |
458 model()->SetInputInProgress(true); | 458 model()->SetInputInProgress(true); |
459 if (!model()->has_focus()) | 459 if (!model()->has_focus()) |
460 return; | 460 return; |
461 | 461 |
462 // Hide the inline autocompletion for IME users. | 462 // Hide the inline autocompletion for IME users. |
463 location_bar_view_->SetImeInlineAutocompletion(string16()); | 463 location_bar_view_->SetImeInlineAutocompletion(string16()); |
464 | 464 |
465 // Prevent inline autocomplete when the caret isn't at the end of the text, | 465 // Prevent inline autocomplete when the caret isn't at the end of the text, |
466 // and during IME composition editing unless | 466 // and during IME composition editing unless |
467 // |kEnableOmniboxAutoCompletionForIme| is enabled. | 467 // |kEnableOmniboxAutoCompletionForIme| is enabled. |
468 const ui::Range sel = GetSelectedRange(); | 468 const gfx::Range sel = GetSelectedRange(); |
469 model()->StartAutocomplete( | 469 model()->StartAutocomplete( |
470 !sel.is_empty(), | 470 !sel.is_empty(), |
471 sel.GetMax() < text().length() || | 471 sel.GetMax() < text().length() || |
472 (IsIMEComposing() && !IsOmniboxAutoCompletionForImeEnabled())); | 472 (IsIMEComposing() && !IsOmniboxAutoCompletionForImeEnabled())); |
473 } | 473 } |
474 | 474 |
475 void OmniboxViewViews::SetFocus() { | 475 void OmniboxViewViews::SetFocus() { |
476 RequestFocus(); | 476 RequestFocus(); |
477 // Restore caret visibility if focus is explicitly requested. This is | 477 // Restore caret visibility if focus is explicitly requested. This is |
478 // necessary because if we already have invisible focus, the RequestFocus() | 478 // necessary because if we already have invisible focus, the RequestFocus() |
(...skipping 21 matching lines...) Expand all Loading... |
500 bool OmniboxViewViews::OnInlineAutocompleteTextMaybeChanged( | 500 bool OmniboxViewViews::OnInlineAutocompleteTextMaybeChanged( |
501 const string16& display_text, | 501 const string16& display_text, |
502 size_t user_text_length) { | 502 size_t user_text_length) { |
503 if (display_text == text()) | 503 if (display_text == text()) |
504 return false; | 504 return false; |
505 | 505 |
506 if (IsIMEComposing()) { | 506 if (IsIMEComposing()) { |
507 location_bar_view_->SetImeInlineAutocompletion( | 507 location_bar_view_->SetImeInlineAutocompletion( |
508 display_text.substr(user_text_length)); | 508 display_text.substr(user_text_length)); |
509 } else { | 509 } else { |
510 ui::Range range(display_text.size(), user_text_length); | 510 gfx::Range range(display_text.size(), user_text_length); |
511 SetTextAndSelectedRange(display_text, range); | 511 SetTextAndSelectedRange(display_text, range); |
512 } | 512 } |
513 TextChanged(); | 513 TextChanged(); |
514 return true; | 514 return true; |
515 } | 515 } |
516 | 516 |
517 void OmniboxViewViews::OnRevertTemporaryText() { | 517 void OmniboxViewViews::OnRevertTemporaryText() { |
518 SelectRange(saved_temporary_selection_); | 518 SelectRange(saved_temporary_selection_); |
519 // We got here because the user hit the Escape key. We explicitly don't call | 519 // We got here because the user hit the Escape key. We explicitly don't call |
520 // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already | 520 // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already |
521 // been called by now, and it would've called TextChanged() if it was | 521 // been called by now, and it would've called TextChanged() if it was |
522 // warranted. | 522 // warranted. |
523 } | 523 } |
524 | 524 |
525 void OmniboxViewViews::OnBeforePossibleChange() { | 525 void OmniboxViewViews::OnBeforePossibleChange() { |
526 // Record our state. | 526 // Record our state. |
527 text_before_change_ = text(); | 527 text_before_change_ = text(); |
528 sel_before_change_ = GetSelectedRange(); | 528 sel_before_change_ = GetSelectedRange(); |
529 ime_composing_before_change_ = IsIMEComposing(); | 529 ime_composing_before_change_ = IsIMEComposing(); |
530 } | 530 } |
531 | 531 |
532 bool OmniboxViewViews::OnAfterPossibleChange() { | 532 bool OmniboxViewViews::OnAfterPossibleChange() { |
533 // See if the text or selection have changed since OnBeforePossibleChange(). | 533 // See if the text or selection have changed since OnBeforePossibleChange(). |
534 const string16 new_text = text(); | 534 const string16 new_text = text(); |
535 const ui::Range new_sel = GetSelectedRange(); | 535 const gfx::Range new_sel = GetSelectedRange(); |
536 const bool text_changed = (new_text != text_before_change_) || | 536 const bool text_changed = (new_text != text_before_change_) || |
537 (ime_composing_before_change_ != IsIMEComposing()); | 537 (ime_composing_before_change_ != IsIMEComposing()); |
538 const bool selection_differs = | 538 const bool selection_differs = |
539 !((sel_before_change_.is_empty() && new_sel.is_empty()) || | 539 !((sel_before_change_.is_empty() && new_sel.is_empty()) || |
540 sel_before_change_.EqualsIgnoringDirection(new_sel)); | 540 sel_before_change_.EqualsIgnoringDirection(new_sel)); |
541 | 541 |
542 // When the user has deleted text, we don't allow inline autocomplete. Make | 542 // When the user has deleted text, we don't allow inline autocomplete. Make |
543 // sure to not flag cases like selecting part of the text and then pasting | 543 // sure to not flag cases like selecting part of the text and then pasting |
544 // (or typing) the prefix of that selection. (We detect these by making | 544 // (or typing) the prefix of that selection. (We detect these by making |
545 // sure the caret, which should be after any insertion, hasn't moved | 545 // sure the caret, which should be after any insertion, hasn't moved |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 bool grey_out_url = text().substr(scheme.begin, scheme.len) == | 851 bool grey_out_url = text().substr(scheme.begin, scheme.len) == |
852 UTF8ToUTF16(extensions::kExtensionScheme); | 852 UTF8ToUTF16(extensions::kExtensionScheme); |
853 bool grey_base = model()->CurrentTextIsURL() && | 853 bool grey_base = model()->CurrentTextIsURL() && |
854 (host.is_nonempty() || grey_out_url); | 854 (host.is_nonempty() || grey_out_url); |
855 SetColor(location_bar_view_->GetColor( | 855 SetColor(location_bar_view_->GetColor( |
856 security_level_, | 856 security_level_, |
857 grey_base ? LocationBarView::DEEMPHASIZED_TEXT : LocationBarView::TEXT)); | 857 grey_base ? LocationBarView::DEEMPHASIZED_TEXT : LocationBarView::TEXT)); |
858 if (grey_base && !grey_out_url) { | 858 if (grey_base && !grey_out_url) { |
859 ApplyColor( | 859 ApplyColor( |
860 location_bar_view_->GetColor(security_level_, LocationBarView::TEXT), | 860 location_bar_view_->GetColor(security_level_, LocationBarView::TEXT), |
861 ui::Range(host.begin, host.end())); | 861 gfx::Range(host.begin, host.end())); |
862 } | 862 } |
863 | 863 |
864 // Emphasize the scheme for security UI display purposes (if necessary). | 864 // Emphasize the scheme for security UI display purposes (if necessary). |
865 // Note that we check CurrentTextIsURL() because if we're replacing search | 865 // Note that we check CurrentTextIsURL() because if we're replacing search |
866 // URLs with search terms, we may have a non-URL even when the user is not | 866 // URLs with search terms, we may have a non-URL even when the user is not |
867 // editing; and in some cases, e.g. for "site:foo.com" searches, the parser | 867 // editing; and in some cases, e.g. for "site:foo.com" searches, the parser |
868 // may have incorrectly identified a qualifier as a scheme. | 868 // may have incorrectly identified a qualifier as a scheme. |
869 SetStyle(gfx::DIAGONAL_STRIKE, false); | 869 SetStyle(gfx::DIAGONAL_STRIKE, false); |
870 if (!model()->user_input_in_progress() && model()->CurrentTextIsURL() && | 870 if (!model()->user_input_in_progress() && model()->CurrentTextIsURL() && |
871 scheme.is_nonempty() && (security_level_ != ToolbarModel::NONE)) { | 871 scheme.is_nonempty() && (security_level_ != ToolbarModel::NONE)) { |
872 SkColor security_color = location_bar_view_->GetColor( | 872 SkColor security_color = location_bar_view_->GetColor( |
873 security_level_, LocationBarView::SECURITY_TEXT); | 873 security_level_, LocationBarView::SECURITY_TEXT); |
874 const bool strike = (security_level_ == ToolbarModel::SECURITY_ERROR); | 874 const bool strike = (security_level_ == ToolbarModel::SECURITY_ERROR); |
875 const ui::Range scheme_range(scheme.begin, scheme.end()); | 875 const gfx::Range scheme_range(scheme.begin, scheme.end()); |
876 ApplyColor(security_color, scheme_range); | 876 ApplyColor(security_color, scheme_range); |
877 ApplyStyle(gfx::DIAGONAL_STRIKE, strike, scheme_range); | 877 ApplyStyle(gfx::DIAGONAL_STRIKE, strike, scheme_range); |
878 } | 878 } |
879 } | 879 } |
880 | 880 |
881 void OmniboxViewViews::SetTextAndSelectedRange(const string16& text, | 881 void OmniboxViewViews::SetTextAndSelectedRange(const string16& text, |
882 const ui::Range& range) { | 882 const gfx::Range& range) { |
883 SetText(text); | 883 SetText(text); |
884 SelectRange(range); | 884 SelectRange(range); |
885 } | 885 } |
886 | 886 |
887 string16 OmniboxViewViews::GetSelectedText() const { | 887 string16 OmniboxViewViews::GetSelectedText() const { |
888 // TODO(oshima): Support IME. | 888 // TODO(oshima): Support IME. |
889 return views::Textfield::GetSelectedText(); | 889 return views::Textfield::GetSelectedText(); |
890 } | 890 } |
891 | 891 |
892 void OmniboxViewViews::OnPaste() { | 892 void OmniboxViewViews::OnPaste() { |
893 const string16 text(GetClipboardText()); | 893 const string16 text(GetClipboardText()); |
894 if (!text.empty()) { | 894 if (!text.empty()) { |
895 // Record this paste, so we can do different behavior. | 895 // Record this paste, so we can do different behavior. |
896 model()->on_paste(); | 896 model()->on_paste(); |
897 // Force a Paste operation to trigger the text_changed code in | 897 // Force a Paste operation to trigger the text_changed code in |
898 // OnAfterPossibleChange(), even if identical contents are pasted. | 898 // OnAfterPossibleChange(), even if identical contents are pasted. |
899 text_before_change_.clear(); | 899 text_before_change_.clear(); |
900 InsertOrReplaceText(text); | 900 InsertOrReplaceText(text); |
901 } | 901 } |
902 } | 902 } |
OLD | NEW |