Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_win.h" | 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <locale> | 8 #include <locale> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include <richedit.h> | 11 #include <richedit.h> |
| 12 #include <textserv.h> | 12 #include <textserv.h> |
| 13 | 13 |
| 14 #include "base/auto_reset.h" | 14 #include "base/auto_reset.h" |
| 15 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
| 16 #include "base/i18n/rtl.h" | 16 #include "base/i18n/rtl.h" |
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
| 19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
| 20 #include "base/utf_string_conversions.h" | 20 #include "base/utf_string_conversions.h" |
| 21 #include "base/win/iat_patch_function.h" | 21 #include "base/win/iat_patch_function.h" |
| 22 #include "chrome/app/chrome_command_ids.h" | 22 #include "chrome/app/chrome_command_ids.h" |
| 23 #include "chrome/browser/autocomplete/autocomplete_accessibility.h" | |
| 24 #include "chrome/browser/autocomplete/autocomplete_match.h" | 23 #include "chrome/browser/autocomplete/autocomplete_match.h" |
| 25 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 24 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
| 26 #include "chrome/browser/autocomplete/keyword_provider.h" | 25 #include "chrome/browser/autocomplete/keyword_provider.h" |
| 27 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
| 28 #include "chrome/browser/command_updater.h" | 27 #include "chrome/browser/command_updater.h" |
| 29 #include "chrome/browser/net/url_fixer_upper.h" | 28 #include "chrome/browser/net/url_fixer_upper.h" |
| 30 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 31 #include "chrome/browser/ui/browser.h" | 30 #include "chrome/browser/ui/browser.h" |
| 32 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 31 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 33 #include "chrome/common/chrome_notification_types.h" | 32 #include "chrome/common/chrome_notification_types.h" |
| 34 #include "content/browser/tab_contents/tab_contents.h" | 33 #include "content/browser/tab_contents/tab_contents.h" |
| 35 #include "content/browser/user_metrics.h" | 34 #include "content/browser/user_metrics.h" |
| 36 #include "googleurl/src/url_util.h" | 35 #include "googleurl/src/url_util.h" |
| 37 #include "grit/generated_resources.h" | 36 #include "grit/generated_resources.h" |
| 38 #include "net/base/escape.h" | 37 #include "net/base/escape.h" |
| 39 #include "skia/ext/skia_utils_win.h" | 38 #include "skia/ext/skia_utils_win.h" |
| 39 #include "ui/base/accessibility/accessible_view_state.h" | |
| 40 #include "ui/base/clipboard/clipboard.h" | 40 #include "ui/base/clipboard/clipboard.h" |
| 41 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 41 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
| 42 #include "ui/base/dragdrop/drag_drop_types.h" | 42 #include "ui/base/dragdrop/drag_drop_types.h" |
| 43 #include "ui/base/dragdrop/drag_source.h" | 43 #include "ui/base/dragdrop/drag_source.h" |
| 44 #include "ui/base/dragdrop/drop_target.h" | 44 #include "ui/base/dragdrop/drop_target.h" |
| 45 #include "ui/base/dragdrop/os_exchange_data.h" | 45 #include "ui/base/dragdrop/os_exchange_data.h" |
| 46 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 46 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
| 47 #include "ui/base/events.h" | 47 #include "ui/base/events.h" |
| 48 #include "ui/base/keycodes/keyboard_codes.h" | 48 #include "ui/base/keycodes/keyboard_codes.h" |
| 49 #include "ui/base/l10n/l10n_util.h" | 49 #include "ui/base/l10n/l10n_util.h" |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 if (text_object_model_) | 299 if (text_object_model_) |
| 300 text_object_model_->Undo(tomSuspend, NULL); | 300 text_object_model_->Undo(tomSuspend, NULL); |
| 301 } | 301 } |
| 302 | 302 |
| 303 OmniboxViewWin::ScopedSuspendUndo::~ScopedSuspendUndo() { | 303 OmniboxViewWin::ScopedSuspendUndo::~ScopedSuspendUndo() { |
| 304 // Resume Undo processing. | 304 // Resume Undo processing. |
| 305 if (text_object_model_) | 305 if (text_object_model_) |
| 306 text_object_model_->Undo(tomResume, NULL); | 306 text_object_model_->Undo(tomResume, NULL); |
| 307 } | 307 } |
| 308 | 308 |
| 309 // A subclass of NativeViewHost that provides accessibility info for the | |
| 310 // underlying Omnibox view. | |
| 311 class OmniboxViewWrapper : public views::NativeViewHost { | |
| 312 public: | |
| 313 explicit OmniboxViewWrapper(OmniboxViewWin* omnibox_view_win) | |
| 314 : omnibox_view_win_(omnibox_view_win) { } | |
|
sky
2011/10/26 21:16:33
nit: '{ }' -> '{}'
| |
| 315 | |
| 316 gfx::NativeViewAccessible GetNativeViewAccessible() { | |
| 317 // This forces it to use NativeViewAccessibilityWin rather than | |
| 318 // any accessibility provided natively by the HWND. | |
| 319 return View::GetNativeViewAccessible(); | |
| 320 } | |
| 321 | |
| 322 // views::View | |
| 323 virtual void GetAccessibleState(ui::AccessibleViewState* state) { | |
| 324 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); | |
| 325 state->role = ui::AccessibilityTypes::ROLE_TEXT; | |
| 326 state->value = omnibox_view_win_->GetText(); | |
| 327 state->state = ui::AccessibilityTypes::STATE_EDITABLE; | |
| 328 size_t sel_start; | |
| 329 size_t sel_end; | |
| 330 omnibox_view_win_->GetSelectionBounds(&sel_start, &sel_end); | |
| 331 state->selection_start = sel_start; | |
| 332 state->selection_end = sel_end; | |
| 333 } | |
| 334 | |
| 335 private: | |
| 336 OmniboxViewWin* omnibox_view_win_; | |
| 337 | |
| 338 DISALLOW_COPY_AND_ASSIGN(OmniboxViewWrapper); | |
| 339 }; | |
| 340 | |
| 309 /////////////////////////////////////////////////////////////////////////////// | 341 /////////////////////////////////////////////////////////////////////////////// |
| 310 // OmniboxViewWin | 342 // OmniboxViewWin |
| 311 | 343 |
| 312 namespace { | 344 namespace { |
| 313 | 345 |
| 314 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and | 346 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and |
| 315 // EndPaint() and provide a memory DC instead. See OnPaint(). | 347 // EndPaint() and provide a memory DC instead. See OnPaint(). |
| 316 HWND edit_hwnd = NULL; | 348 HWND edit_hwnd = NULL; |
| 317 PAINTSTRUCT paint_struct; | 349 PAINTSTRUCT paint_struct; |
| 318 | 350 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 CHARRANGE selection; | 692 CHARRANGE selection; |
| 661 GetSel(selection); | 693 GetSel(selection); |
| 662 return IsSelectAllForRange(selection); | 694 return IsSelectAllForRange(selection); |
| 663 } | 695 } |
| 664 | 696 |
| 665 bool OmniboxViewWin::DeleteAtEndPressed() { | 697 bool OmniboxViewWin::DeleteAtEndPressed() { |
| 666 return delete_at_end_pressed_; | 698 return delete_at_end_pressed_; |
| 667 } | 699 } |
| 668 | 700 |
| 669 void OmniboxViewWin::GetSelectionBounds(string16::size_type* start, | 701 void OmniboxViewWin::GetSelectionBounds(string16::size_type* start, |
| 670 string16::size_type* end) { | 702 string16::size_type* end) const { |
| 671 CHARRANGE selection; | 703 CHARRANGE selection; |
| 672 GetSel(selection); | 704 GetSel(selection); |
| 673 *start = static_cast<size_t>(selection.cpMin); | 705 *start = static_cast<size_t>(selection.cpMin); |
| 674 *end = static_cast<size_t>(selection.cpMax); | 706 *end = static_cast<size_t>(selection.cpMax); |
| 675 } | 707 } |
| 676 | 708 |
| 677 void OmniboxViewWin::SelectAll(bool reversed) { | 709 void OmniboxViewWin::SelectAll(bool reversed) { |
| 678 if (reversed) | 710 if (reversed) |
| 679 SetSelection(GetTextLength(), 0); | 711 SetSelection(GetTextLength(), 0); |
| 680 else | 712 else |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 717 } | 749 } |
| 718 | 750 |
| 719 void OmniboxViewWin::ClosePopup() { | 751 void OmniboxViewWin::ClosePopup() { |
| 720 model_->StopAutocomplete(); | 752 model_->StopAutocomplete(); |
| 721 } | 753 } |
| 722 | 754 |
| 723 void OmniboxViewWin::SetFocus() { | 755 void OmniboxViewWin::SetFocus() { |
| 724 ::SetFocus(m_hWnd); | 756 ::SetFocus(m_hWnd); |
| 725 } | 757 } |
| 726 | 758 |
| 727 IAccessible* OmniboxViewWin::GetIAccessible() { | |
| 728 if (!autocomplete_accessibility_) { | |
| 729 CComObject<AutocompleteAccessibility>* accessibility = NULL; | |
| 730 if (!SUCCEEDED(CComObject<AutocompleteAccessibility>::CreateInstance( | |
| 731 &accessibility)) || !accessibility) | |
| 732 return NULL; | |
| 733 | |
| 734 // Wrap the created object in a smart pointer so it won't leak. | |
| 735 base::win::ScopedComPtr<IAccessible> accessibility_comptr(accessibility); | |
| 736 if (!SUCCEEDED(accessibility->Initialize(this))) | |
| 737 return NULL; | |
| 738 | |
| 739 // Copy to the class smart pointer, and notify that an instance of | |
| 740 // IAccessible was allocated for m_hWnd. | |
| 741 autocomplete_accessibility_ = accessibility_comptr; | |
| 742 NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT, CHILDID_SELF); | |
| 743 } | |
| 744 // Detach to leave ref counting to the caller. | |
| 745 return autocomplete_accessibility_.Detach(); | |
| 746 } | |
| 747 | |
| 748 void OmniboxViewWin::SetDropHighlightPosition(int position) { | 759 void OmniboxViewWin::SetDropHighlightPosition(int position) { |
| 749 if (drop_highlight_position_ != position) { | 760 if (drop_highlight_position_ != position) { |
| 750 RepaintDropHighlight(drop_highlight_position_); | 761 RepaintDropHighlight(drop_highlight_position_); |
| 751 drop_highlight_position_ = position; | 762 drop_highlight_position_ = position; |
| 752 RepaintDropHighlight(drop_highlight_position_); | 763 RepaintDropHighlight(drop_highlight_position_); |
| 753 } | 764 } |
| 754 } | 765 } |
| 755 | 766 |
| 756 void OmniboxViewWin::MoveSelectedText(int new_position) { | 767 void OmniboxViewWin::MoveSelectedText(int new_position) { |
| 757 const string16 selected_text(GetSelectedText()); | 768 const string16 selected_text(GetSelectedText()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 | 889 |
| 879 if (selection_differs) | 890 if (selection_differs) |
| 880 controller_->OnSelectionBoundsChanged(); | 891 controller_->OnSelectionBoundsChanged(); |
| 881 | 892 |
| 882 if (something_changed && text_differs) | 893 if (something_changed && text_differs) |
| 883 TextChanged(); | 894 TextChanged(); |
| 884 | 895 |
| 885 if (text_differs) { | 896 if (text_differs) { |
| 886 // Note that a TEXT_CHANGED event implies that the cursor/selection | 897 // Note that a TEXT_CHANGED event implies that the cursor/selection |
| 887 // probably changed too, so we don't need to send both. | 898 // probably changed too, so we don't need to send both. |
| 888 parent_view_->GetWidget()->NotifyAccessibilityEvent( | 899 native_view_host_->GetWidget()->NotifyAccessibilityEvent( |
| 889 parent_view_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); | 900 native_view_host_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); |
| 890 } else if (selection_differs) { | 901 } else if (selection_differs) { |
| 891 // Notify assistive technology that the cursor or selection changed. | 902 // Notify assistive technology that the cursor or selection changed. |
| 892 parent_view_->GetWidget()->NotifyAccessibilityEvent( | 903 native_view_host_->GetWidget()->NotifyAccessibilityEvent( |
| 893 parent_view_, ui::AccessibilityTypes::EVENT_SELECTION_CHANGED, true); | 904 native_view_host_, |
| 905 ui::AccessibilityTypes::EVENT_SELECTION_CHANGED, | |
| 906 true); | |
| 894 } else if (delete_at_end_pressed_) { | 907 } else if (delete_at_end_pressed_) { |
| 895 model_->OnChanged(); | 908 model_->OnChanged(); |
| 896 } | 909 } |
| 897 | 910 |
| 898 return something_changed; | 911 return something_changed; |
| 899 } | 912 } |
| 900 | 913 |
| 901 gfx::NativeView OmniboxViewWin::GetNativeView() const { | 914 gfx::NativeView OmniboxViewWin::GetNativeView() const { |
| 902 return m_hWnd; | 915 return m_hWnd; |
| 903 } | 916 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 bool ime_composing = false; | 953 bool ime_composing = false; |
| 941 HIMC context = ImmGetContext(m_hWnd); | 954 HIMC context = ImmGetContext(m_hWnd); |
| 942 if (context) { | 955 if (context) { |
| 943 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); | 956 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); |
| 944 ImmReleaseContext(m_hWnd, context); | 957 ImmReleaseContext(m_hWnd, context); |
| 945 } | 958 } |
| 946 return ime_composing; | 959 return ime_composing; |
| 947 } | 960 } |
| 948 | 961 |
| 949 views::View* OmniboxViewWin::AddToView(views::View* parent) { | 962 views::View* OmniboxViewWin::AddToView(views::View* parent) { |
| 950 views::NativeViewHost* host = new views::NativeViewHost; | 963 native_view_host_ = new OmniboxViewWrapper(this); |
| 951 parent->AddChildView(host); | 964 parent->AddChildView(native_view_host_); |
| 952 host->set_focus_view(parent); | 965 native_view_host_->set_focus_view(parent); |
| 953 host->Attach(GetNativeView()); | 966 native_view_host_->Attach(GetNativeView()); |
| 954 return host; | 967 return native_view_host_; |
| 955 } | 968 } |
| 956 | 969 |
| 957 int OmniboxViewWin::OnPerformDrop(const views::DropTargetEvent& event) { | 970 int OmniboxViewWin::OnPerformDrop(const views::DropTargetEvent& event) { |
| 958 return OnPerformDropImpl(event, false); | 971 return OnPerformDropImpl(event, false); |
| 959 } | 972 } |
| 960 | 973 |
| 961 int OmniboxViewWin::OnPerformDropImpl(const views::DropTargetEvent& event, | 974 int OmniboxViewWin::OnPerformDropImpl(const views::DropTargetEvent& event, |
| 962 bool in_drag) { | 975 bool in_drag) { |
| 963 const ui::OSExchangeData& data = event.data(); | 976 const ui::OSExchangeData& data = event.data(); |
| 964 | 977 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 } | 1336 } |
| 1324 | 1337 |
| 1325 void OmniboxViewWin::OnCut() { | 1338 void OmniboxViewWin::OnCut() { |
| 1326 OnCopy(); | 1339 OnCopy(); |
| 1327 | 1340 |
| 1328 // This replace selection will have no effect (even on the undo stack) if the | 1341 // This replace selection will have no effect (even on the undo stack) if the |
| 1329 // current selection is empty. | 1342 // current selection is empty. |
| 1330 ReplaceSel(L"", true); | 1343 ReplaceSel(L"", true); |
| 1331 } | 1344 } |
| 1332 | 1345 |
| 1333 LRESULT OmniboxViewWin::OnGetObject(UINT uMsg, | 1346 LRESULT OmniboxViewWin::OnGetObject(UINT message, |
| 1334 WPARAM wparam, | 1347 WPARAM wparam, |
| 1335 LPARAM lparam) { | 1348 LPARAM lparam) { |
| 1336 // Accessibility readers will send an OBJID_CLIENT message. | 1349 // This is a request for the native accessibility object. |
| 1337 if (lparam == OBJID_CLIENT) { | 1350 if (lparam == OBJID_CLIENT) { |
| 1338 // Re-attach for internal re-usage of accessibility pointer. | 1351 return LresultFromObject(IID_IAccessible, wparam, |
| 1339 autocomplete_accessibility_.Attach(GetIAccessible()); | 1352 native_view_host_->GetNativeViewAccessible()); |
| 1340 | |
| 1341 if (autocomplete_accessibility_) { | |
| 1342 return LresultFromObject(IID_IAccessible, wparam, | |
| 1343 autocomplete_accessibility_); | |
| 1344 } | |
| 1345 } | 1353 } |
| 1346 return 0; | 1354 return 0; |
| 1347 } | 1355 } |
| 1348 | 1356 |
| 1349 LRESULT OmniboxViewWin::OnImeComposition(UINT message, | 1357 LRESULT OmniboxViewWin::OnImeComposition(UINT message, |
| 1350 WPARAM wparam, | 1358 WPARAM wparam, |
| 1351 LPARAM lparam) { | 1359 LPARAM lparam) { |
| 1352 if (ignore_ime_messages_) { | 1360 if (ignore_ime_messages_) { |
| 1353 // This message was sent while we're in the middle of meddling with the | 1361 // This message was sent while we're in the middle of meddling with the |
| 1354 // underlying edit control. If we handle it below, OnAfterPossibleChange() | 1362 // underlying edit control. If we handle it below, OnAfterPossibleChange() |
| (...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2612 // PosFromChar(i) might return 0 when i is greater than 1. | 2620 // PosFromChar(i) might return 0 when i is greater than 1. |
| 2613 return font_.GetStringWidth(text) + GetHorizontalMargin(); | 2621 return font_.GetStringWidth(text) + GetHorizontalMargin(); |
| 2614 } | 2622 } |
| 2615 | 2623 |
| 2616 bool OmniboxViewWin::IsCaretAtEnd() const { | 2624 bool OmniboxViewWin::IsCaretAtEnd() const { |
| 2617 long length = GetTextLength(); | 2625 long length = GetTextLength(); |
| 2618 CHARRANGE sel; | 2626 CHARRANGE sel; |
| 2619 GetSelection(sel); | 2627 GetSelection(sel); |
| 2620 return sel.cpMin == sel.cpMax && sel.cpMin == length; | 2628 return sel.cpMin == sel.cpMax && sel.cpMin == length; |
| 2621 } | 2629 } |
| OLD | NEW |