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