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 |