| 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/autocomplete/autocomplete_edit_view_win.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit_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 "app/win/iat_patch_function.h" | 14 #include "app/win/iat_patch_function.h" |
| 15 #include "app/win/win_util.h" | |
| 16 #include "base/auto_reset.h" | 15 #include "base/auto_reset.h" |
| 17 #include "base/basictypes.h" | 16 #include "base/basictypes.h" |
| 18 #include "base/i18n/rtl.h" | 17 #include "base/i18n/rtl.h" |
| 19 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
| 20 #include "base/ref_counted.h" | 19 #include "base/ref_counted.h" |
| 21 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 22 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
| 23 #include "chrome/app/chrome_command_ids.h" | 22 #include "chrome/app/chrome_command_ids.h" |
| 24 #include "chrome/browser/autocomplete/autocomplete_accessibility.h" | 23 #include "chrome/browser/autocomplete/autocomplete_accessibility.h" |
| 25 #include "chrome/browser/autocomplete/autocomplete_match.h" | 24 #include "chrome/browser/autocomplete/autocomplete_match.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 43 #include "skia/ext/skia_utils_win.h" | 42 #include "skia/ext/skia_utils_win.h" |
| 44 #include "ui/base/clipboard/clipboard.h" | 43 #include "ui/base/clipboard/clipboard.h" |
| 45 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 44 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
| 46 #include "ui/base/dragdrop/drag_source.h" | 45 #include "ui/base/dragdrop/drag_source.h" |
| 47 #include "ui/base/dragdrop/drop_target.h" | 46 #include "ui/base/dragdrop/drop_target.h" |
| 48 #include "ui/base/dragdrop/os_exchange_data.h" | 47 #include "ui/base/dragdrop/os_exchange_data.h" |
| 49 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 48 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
| 50 #include "ui/base/keycodes/keyboard_codes.h" | 49 #include "ui/base/keycodes/keyboard_codes.h" |
| 51 #include "ui/base/l10n/l10n_util.h" | 50 #include "ui/base/l10n/l10n_util.h" |
| 52 #include "ui/base/l10n/l10n_util_win.h" | 51 #include "ui/base/l10n/l10n_util_win.h" |
| 52 #include "views/controls/textfield/native_textfield_win.h" |
| 53 #include "views/drag_utils.h" | 53 #include "views/drag_utils.h" |
| 54 #include "views/focus/focus_util_win.h" | 54 #include "views/focus/focus_util_win.h" |
| 55 #include "views/widget/widget.h" | 55 #include "views/widget/widget.h" |
| 56 | 56 |
| 57 #pragma comment(lib, "oleacc.lib") // Needed for accessibility support. | 57 #pragma comment(lib, "oleacc.lib") // Needed for accessibility support. |
| 58 #pragma comment(lib, "riched20.lib") // Needed for the richedit control. | 58 #pragma comment(lib, "riched20.lib") // Needed for the richedit control. |
| 59 | 59 |
| 60 /////////////////////////////////////////////////////////////////////////////// | 60 /////////////////////////////////////////////////////////////////////////////// |
| 61 // AutocompleteEditModel | 61 // AutocompleteEditModel |
| 62 | 62 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 AutocompleteEditState(const AutocompleteEditModel::State model_state, | 254 AutocompleteEditState(const AutocompleteEditModel::State model_state, |
| 255 const AutocompleteEditViewWin::State view_state) | 255 const AutocompleteEditViewWin::State view_state) |
| 256 : model_state(model_state), | 256 : model_state(model_state), |
| 257 view_state(view_state) { | 257 view_state(view_state) { |
| 258 } | 258 } |
| 259 | 259 |
| 260 const AutocompleteEditModel::State model_state; | 260 const AutocompleteEditModel::State model_state; |
| 261 const AutocompleteEditViewWin::State view_state; | 261 const AutocompleteEditViewWin::State view_state; |
| 262 }; | 262 }; |
| 263 | 263 |
| 264 // Returns true if the current point is far enough from the origin that it |
| 265 // would be considered a drag. |
| 266 bool IsDrag(const POINT& origin, const POINT& current) { |
| 267 // The CXDRAG and CYDRAG system metrics describe the width and height of a |
| 268 // rectangle around the origin position, inside of which motion is not |
| 269 // considered a drag. |
| 270 return (abs(current.x - origin.x) > (GetSystemMetrics(SM_CXDRAG) / 2)) || |
| 271 (abs(current.y - origin.y) > (GetSystemMetrics(SM_CYDRAG) / 2)); |
| 272 } |
| 273 |
| 264 } // namespace | 274 } // namespace |
| 265 | 275 |
| 266 /////////////////////////////////////////////////////////////////////////////// | 276 /////////////////////////////////////////////////////////////////////////////// |
| 267 // Helper classes | 277 // Helper classes |
| 268 | 278 |
| 269 AutocompleteEditViewWin::ScopedFreeze::ScopedFreeze( | 279 AutocompleteEditViewWin::ScopedFreeze::ScopedFreeze( |
| 270 AutocompleteEditViewWin* edit, | 280 AutocompleteEditViewWin* edit, |
| 271 ITextDocument* text_object_model) | 281 ITextDocument* text_object_model) |
| 272 : edit_(edit), | 282 : edit_(edit), |
| 273 text_object_model_(text_object_model) { | 283 text_object_model_(text_object_model) { |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 if (CanPasteAndGo(text)) | 966 if (CanPasteAndGo(text)) |
| 957 model_->PasteAndGo(); | 967 model_->PasteAndGo(); |
| 958 } | 968 } |
| 959 | 969 |
| 960 bool AutocompleteEditViewWin::SkipDefaultKeyEventProcessing( | 970 bool AutocompleteEditViewWin::SkipDefaultKeyEventProcessing( |
| 961 const views::KeyEvent& e) { | 971 const views::KeyEvent& e) { |
| 962 ui::KeyboardCode key = e.GetKeyCode(); | 972 ui::KeyboardCode key = e.GetKeyCode(); |
| 963 // We don't process ALT + numpad digit as accelerators, they are used for | 973 // We don't process ALT + numpad digit as accelerators, they are used for |
| 964 // entering special characters. We do translate alt-home. | 974 // entering special characters. We do translate alt-home. |
| 965 if (e.IsAltDown() && (key != ui::VKEY_HOME) && | 975 if (e.IsAltDown() && (key != ui::VKEY_HOME) && |
| 966 app::win::IsNumPadDigit(key, e.IsExtendedKey())) | 976 views::NativeTextfieldWin::IsNumPadDigit(key, e.IsExtendedKey())) |
| 967 return true; | 977 return true; |
| 968 | 978 |
| 969 // Skip accelerators for key combinations omnibox wants to crack. This list | 979 // Skip accelerators for key combinations omnibox wants to crack. This list |
| 970 // should be synced with OnKeyDownOnlyWritable() (but for tab which is dealt | 980 // should be synced with OnKeyDownOnlyWritable() (but for tab which is dealt |
| 971 // with above in LocationBarView::SkipDefaultKeyEventProcessing). | 981 // with above in LocationBarView::SkipDefaultKeyEventProcessing). |
| 972 // | 982 // |
| 973 // We cannot return true for all keys because we still need to handle some | 983 // We cannot return true for all keys because we still need to handle some |
| 974 // accelerators (e.g., F5 for reload the page should work even when the | 984 // accelerators (e.g., F5 for reload the page should work even when the |
| 975 // Omnibox gets focused). | 985 // Omnibox gets focused). |
| 976 switch (key) { | 986 switch (key) { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 // (as well as a matching WM_LBUTTONUP, just in case we'd be confusing some | 1462 // (as well as a matching WM_LBUTTONUP, just in case we'd be confusing some |
| 1453 // kind of state tracking otherwise). | 1463 // kind of state tracking otherwise). |
| 1454 DefWindowProc(WM_LBUTTONDOWN, keys, MAKELPARAM(point.x, point.y)); | 1464 DefWindowProc(WM_LBUTTONDOWN, keys, MAKELPARAM(point.x, point.y)); |
| 1455 DefWindowProc(WM_LBUTTONUP, keys, MAKELPARAM(point.x, point.y)); | 1465 DefWindowProc(WM_LBUTTONUP, keys, MAKELPARAM(point.x, point.y)); |
| 1456 } | 1466 } |
| 1457 | 1467 |
| 1458 // Check for triple click, then reset tracker. Should be safe to subtract | 1468 // Check for triple click, then reset tracker. Should be safe to subtract |
| 1459 // double_click_time_ from the current message's time even if the timer has | 1469 // double_click_time_ from the current message's time even if the timer has |
| 1460 // wrapped in between. | 1470 // wrapped in between. |
| 1461 const bool is_triple_click = tracking_double_click_ && | 1471 const bool is_triple_click = tracking_double_click_ && |
| 1462 app::win::IsDoubleClick(double_click_point_, point, | 1472 views::NativeTextfieldWin::IsDoubleClick(double_click_point_, point, |
| 1463 GetCurrentMessage()->time - double_click_time_); | 1473 GetCurrentMessage()->time - double_click_time_); |
| 1464 tracking_double_click_ = false; | 1474 tracking_double_click_ = false; |
| 1465 | 1475 |
| 1466 if (!gaining_focus_.get() && !is_triple_click) | 1476 if (!gaining_focus_.get() && !is_triple_click) |
| 1467 OnPossibleDrag(point); | 1477 OnPossibleDrag(point); |
| 1468 | 1478 |
| 1469 | 1479 |
| 1470 // Modifying the selection counts as accepting any inline autocompletion, so | 1480 // Modifying the selection counts as accepting any inline autocompletion, so |
| 1471 // track "changes" made by clicking the mouse button. | 1481 // track "changes" made by clicking the mouse button. |
| 1472 ScopedFreeze freeze(this, GetTextObjectModel()); | 1482 ScopedFreeze freeze(this, GetTextObjectModel()); |
| 1473 OnBeforePossibleChange(); | 1483 OnBeforePossibleChange(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 } | 1562 } |
| 1553 | 1563 |
| 1554 void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { | 1564 void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { |
| 1555 if (possible_drag_) { | 1565 if (possible_drag_) { |
| 1556 StartDragIfNecessary(point); | 1566 StartDragIfNecessary(point); |
| 1557 // Don't fall through to default mouse handling, otherwise a second | 1567 // Don't fall through to default mouse handling, otherwise a second |
| 1558 // drag session may start. | 1568 // drag session may start. |
| 1559 return; | 1569 return; |
| 1560 } | 1570 } |
| 1561 | 1571 |
| 1562 if (tracking_click_[kLeft] && !app::win::IsDrag(click_point_[kLeft], point)) | 1572 if (tracking_click_[kLeft] && !IsDrag(click_point_[kLeft], point)) |
| 1563 return; | 1573 return; |
| 1564 | 1574 |
| 1565 tracking_click_[kLeft] = false; | 1575 tracking_click_[kLeft] = false; |
| 1566 | 1576 |
| 1567 // Return quickly if this can't change the selection/cursor, so we don't | 1577 // Return quickly if this can't change the selection/cursor, so we don't |
| 1568 // create a ScopedFreeze (and thus do an UpdateWindow()) on every | 1578 // create a ScopedFreeze (and thus do an UpdateWindow()) on every |
| 1569 // WM_MOUSEMOVE. | 1579 // WM_MOUSEMOVE. |
| 1570 if (!(keys & MK_LBUTTON)) { | 1580 if (!(keys & MK_LBUTTON)) { |
| 1571 DefWindowProc(WM_MOUSEMOVE, keys, MAKELPARAM(point.x, point.y)); | 1581 DefWindowProc(WM_MOUSEMOVE, keys, MAKELPARAM(point.x, point.y)); |
| 1572 return; | 1582 return; |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2373 if (ole_interface) { | 2383 if (ole_interface) { |
| 2374 ole_interface.QueryInterface( | 2384 ole_interface.QueryInterface( |
| 2375 __uuidof(ITextDocument), | 2385 __uuidof(ITextDocument), |
| 2376 reinterpret_cast<void**>(&text_object_model_)); | 2386 reinterpret_cast<void**>(&text_object_model_)); |
| 2377 } | 2387 } |
| 2378 } | 2388 } |
| 2379 return text_object_model_; | 2389 return text_object_model_; |
| 2380 } | 2390 } |
| 2381 | 2391 |
| 2382 void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { | 2392 void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { |
| 2383 if (initiated_drag_ || !app::win::IsDrag(click_point_[kLeft], point)) | 2393 if (initiated_drag_ || !IsDrag(click_point_[kLeft], point)) |
| 2384 return; | 2394 return; |
| 2385 | 2395 |
| 2386 ui::OSExchangeData data; | 2396 ui::OSExchangeData data; |
| 2387 | 2397 |
| 2388 DWORD supported_modes = DROPEFFECT_COPY; | 2398 DWORD supported_modes = DROPEFFECT_COPY; |
| 2389 | 2399 |
| 2390 CHARRANGE sel; | 2400 CHARRANGE sel; |
| 2391 GetSelection(sel); | 2401 GetSelection(sel); |
| 2392 | 2402 |
| 2393 // We're about to start a drag session, but the edit is expecting a mouse up | 2403 // We're about to start a drag session, but the edit is expecting a mouse up |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2530 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, | 2540 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, |
| 2531 IDS_EDIT_SEARCH_ENGINES); | 2541 IDS_EDIT_SEARCH_ENGINES); |
| 2532 } | 2542 } |
| 2533 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); | 2543 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); |
| 2534 } | 2544 } |
| 2535 | 2545 |
| 2536 void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, | 2546 void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, |
| 2537 const CPoint& point) { | 2547 const CPoint& point) { |
| 2538 // When the user has clicked and released to give us focus, select all. | 2548 // When the user has clicked and released to give us focus, select all. |
| 2539 if (tracking_click_[button] && | 2549 if (tracking_click_[button] && |
| 2540 !app::win::IsDrag(click_point_[button], point)) { | 2550 !IsDrag(click_point_[button], point)) { |
| 2541 // Select all in the reverse direction so as not to scroll the caret | 2551 // Select all in the reverse direction so as not to scroll the caret |
| 2542 // into view and shift the contents jarringly. | 2552 // into view and shift the contents jarringly. |
| 2543 SelectAll(true); | 2553 SelectAll(true); |
| 2544 possible_drag_ = false; | 2554 possible_drag_ = false; |
| 2545 } | 2555 } |
| 2546 } | 2556 } |
| 2547 | 2557 |
| 2548 void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, | 2558 void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, |
| 2549 const CPoint& point) { | 2559 const CPoint& point) { |
| 2550 if (gaining_focus_.get()) { | 2560 if (gaining_focus_.get()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2572 // PosFromChar(i) might return 0 when i is greater than 1. | 2582 // PosFromChar(i) might return 0 when i is greater than 1. |
| 2573 return font_.GetStringWidth(text) + GetHorizontalMargin(); | 2583 return font_.GetStringWidth(text) + GetHorizontalMargin(); |
| 2574 } | 2584 } |
| 2575 | 2585 |
| 2576 bool AutocompleteEditViewWin::IsCaretAtEnd() const { | 2586 bool AutocompleteEditViewWin::IsCaretAtEnd() const { |
| 2577 long length = GetTextLength(); | 2587 long length = GetTextLength(); |
| 2578 CHARRANGE sel; | 2588 CHARRANGE sel; |
| 2579 GetSelection(sel); | 2589 GetSelection(sel); |
| 2580 return sel.cpMin == sel.cpMax && sel.cpMin == length; | 2590 return sel.cpMin == sel.cpMax && sel.cpMin == length; |
| 2581 } | 2591 } |
| OLD | NEW |