| 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 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 if (CanPasteAndGo(text)) | 967 if (CanPasteAndGo(text)) |
| 958 model_->PasteAndGo(); | 968 model_->PasteAndGo(); |
| 959 } | 969 } |
| 960 | 970 |
| 961 bool AutocompleteEditViewWin::SkipDefaultKeyEventProcessing( | 971 bool AutocompleteEditViewWin::SkipDefaultKeyEventProcessing( |
| 962 const views::KeyEvent& e) { | 972 const views::KeyEvent& e) { |
| 963 ui::KeyboardCode key = e.GetKeyCode(); | 973 ui::KeyboardCode key = e.GetKeyCode(); |
| 964 // We don't process ALT + numpad digit as accelerators, they are used for | 974 // We don't process ALT + numpad digit as accelerators, they are used for |
| 965 // entering special characters. We do translate alt-home. | 975 // entering special characters. We do translate alt-home. |
| 966 if (e.IsAltDown() && (key != ui::VKEY_HOME) && | 976 if (e.IsAltDown() && (key != ui::VKEY_HOME) && |
| 967 app::win::IsNumPadDigit(key, e.IsExtendedKey())) | 977 views::NativeTextfieldWin::IsNumPadDigit(key, e.IsExtendedKey())) |
| 968 return true; | 978 return true; |
| 969 | 979 |
| 970 // Skip accelerators for key combinations omnibox wants to crack. This list | 980 // Skip accelerators for key combinations omnibox wants to crack. This list |
| 971 // should be synced with OnKeyDownOnlyWritable() (but for tab which is dealt | 981 // should be synced with OnKeyDownOnlyWritable() (but for tab which is dealt |
| 972 // with above in LocationBarView::SkipDefaultKeyEventProcessing). | 982 // with above in LocationBarView::SkipDefaultKeyEventProcessing). |
| 973 // | 983 // |
| 974 // We cannot return true for all keys because we still need to handle some | 984 // We cannot return true for all keys because we still need to handle some |
| 975 // accelerators (e.g., F5 for reload the page should work even when the | 985 // accelerators (e.g., F5 for reload the page should work even when the |
| 976 // Omnibox gets focused). | 986 // Omnibox gets focused). |
| 977 switch (key) { | 987 switch (key) { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 // (as well as a matching WM_LBUTTONUP, just in case we'd be confusing some | 1463 // (as well as a matching WM_LBUTTONUP, just in case we'd be confusing some |
| 1454 // kind of state tracking otherwise). | 1464 // kind of state tracking otherwise). |
| 1455 DefWindowProc(WM_LBUTTONDOWN, keys, MAKELPARAM(point.x, point.y)); | 1465 DefWindowProc(WM_LBUTTONDOWN, keys, MAKELPARAM(point.x, point.y)); |
| 1456 DefWindowProc(WM_LBUTTONUP, keys, MAKELPARAM(point.x, point.y)); | 1466 DefWindowProc(WM_LBUTTONUP, keys, MAKELPARAM(point.x, point.y)); |
| 1457 } | 1467 } |
| 1458 | 1468 |
| 1459 // Check for triple click, then reset tracker. Should be safe to subtract | 1469 // Check for triple click, then reset tracker. Should be safe to subtract |
| 1460 // double_click_time_ from the current message's time even if the timer has | 1470 // double_click_time_ from the current message's time even if the timer has |
| 1461 // wrapped in between. | 1471 // wrapped in between. |
| 1462 const bool is_triple_click = tracking_double_click_ && | 1472 const bool is_triple_click = tracking_double_click_ && |
| 1463 app::win::IsDoubleClick(double_click_point_, point, | 1473 views::NativeTextfieldWin::IsDoubleClick(double_click_point_, point, |
| 1464 GetCurrentMessage()->time - double_click_time_); | 1474 GetCurrentMessage()->time - double_click_time_); |
| 1465 tracking_double_click_ = false; | 1475 tracking_double_click_ = false; |
| 1466 | 1476 |
| 1467 if (!gaining_focus_.get() && !is_triple_click) | 1477 if (!gaining_focus_.get() && !is_triple_click) |
| 1468 OnPossibleDrag(point); | 1478 OnPossibleDrag(point); |
| 1469 | 1479 |
| 1470 | 1480 |
| 1471 // Modifying the selection counts as accepting any inline autocompletion, so | 1481 // Modifying the selection counts as accepting any inline autocompletion, so |
| 1472 // track "changes" made by clicking the mouse button. | 1482 // track "changes" made by clicking the mouse button. |
| 1473 ScopedFreeze freeze(this, GetTextObjectModel()); | 1483 ScopedFreeze freeze(this, GetTextObjectModel()); |
| 1474 OnBeforePossibleChange(); | 1484 OnBeforePossibleChange(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 } | 1563 } |
| 1554 | 1564 |
| 1555 void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { | 1565 void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { |
| 1556 if (possible_drag_) { | 1566 if (possible_drag_) { |
| 1557 StartDragIfNecessary(point); | 1567 StartDragIfNecessary(point); |
| 1558 // Don't fall through to default mouse handling, otherwise a second | 1568 // Don't fall through to default mouse handling, otherwise a second |
| 1559 // drag session may start. | 1569 // drag session may start. |
| 1560 return; | 1570 return; |
| 1561 } | 1571 } |
| 1562 | 1572 |
| 1563 if (tracking_click_[kLeft] && !app::win::IsDrag(click_point_[kLeft], point)) | 1573 if (tracking_click_[kLeft] && !IsDrag(click_point_[kLeft], point)) |
| 1564 return; | 1574 return; |
| 1565 | 1575 |
| 1566 tracking_click_[kLeft] = false; | 1576 tracking_click_[kLeft] = false; |
| 1567 | 1577 |
| 1568 // Return quickly if this can't change the selection/cursor, so we don't | 1578 // Return quickly if this can't change the selection/cursor, so we don't |
| 1569 // create a ScopedFreeze (and thus do an UpdateWindow()) on every | 1579 // create a ScopedFreeze (and thus do an UpdateWindow()) on every |
| 1570 // WM_MOUSEMOVE. | 1580 // WM_MOUSEMOVE. |
| 1571 if (!(keys & MK_LBUTTON)) { | 1581 if (!(keys & MK_LBUTTON)) { |
| 1572 DefWindowProc(WM_MOUSEMOVE, keys, MAKELPARAM(point.x, point.y)); | 1582 DefWindowProc(WM_MOUSEMOVE, keys, MAKELPARAM(point.x, point.y)); |
| 1573 return; | 1583 return; |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 if (ole_interface) { | 2379 if (ole_interface) { |
| 2370 ole_interface.QueryInterface( | 2380 ole_interface.QueryInterface( |
| 2371 __uuidof(ITextDocument), | 2381 __uuidof(ITextDocument), |
| 2372 reinterpret_cast<void**>(&text_object_model_)); | 2382 reinterpret_cast<void**>(&text_object_model_)); |
| 2373 } | 2383 } |
| 2374 } | 2384 } |
| 2375 return text_object_model_; | 2385 return text_object_model_; |
| 2376 } | 2386 } |
| 2377 | 2387 |
| 2378 void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { | 2388 void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { |
| 2379 if (initiated_drag_ || !app::win::IsDrag(click_point_[kLeft], point)) | 2389 if (initiated_drag_ || !IsDrag(click_point_[kLeft], point)) |
| 2380 return; | 2390 return; |
| 2381 | 2391 |
| 2382 ui::OSExchangeData data; | 2392 ui::OSExchangeData data; |
| 2383 | 2393 |
| 2384 DWORD supported_modes = DROPEFFECT_COPY; | 2394 DWORD supported_modes = DROPEFFECT_COPY; |
| 2385 | 2395 |
| 2386 CHARRANGE sel; | 2396 CHARRANGE sel; |
| 2387 GetSelection(sel); | 2397 GetSelection(sel); |
| 2388 | 2398 |
| 2389 // We're about to start a drag session, but the edit is expecting a mouse up | 2399 // 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... |
| 2526 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, | 2536 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, |
| 2527 IDS_EDIT_SEARCH_ENGINES); | 2537 IDS_EDIT_SEARCH_ENGINES); |
| 2528 } | 2538 } |
| 2529 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); | 2539 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); |
| 2530 } | 2540 } |
| 2531 | 2541 |
| 2532 void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, | 2542 void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, |
| 2533 const CPoint& point) { | 2543 const CPoint& point) { |
| 2534 // When the user has clicked and released to give us focus, select all. | 2544 // When the user has clicked and released to give us focus, select all. |
| 2535 if (tracking_click_[button] && | 2545 if (tracking_click_[button] && |
| 2536 !app::win::IsDrag(click_point_[button], point)) { | 2546 !IsDrag(click_point_[button], point)) { |
| 2537 // Select all in the reverse direction so as not to scroll the caret | 2547 // Select all in the reverse direction so as not to scroll the caret |
| 2538 // into view and shift the contents jarringly. | 2548 // into view and shift the contents jarringly. |
| 2539 SelectAll(true); | 2549 SelectAll(true); |
| 2540 possible_drag_ = false; | 2550 possible_drag_ = false; |
| 2541 } | 2551 } |
| 2542 } | 2552 } |
| 2543 | 2553 |
| 2544 void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, | 2554 void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, |
| 2545 const CPoint& point) { | 2555 const CPoint& point) { |
| 2546 if (gaining_focus_.get()) { | 2556 if (gaining_focus_.get()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2561 } | 2571 } |
| 2562 | 2572 |
| 2563 int AutocompleteEditViewWin::WidthNeededToDisplay( | 2573 int AutocompleteEditViewWin::WidthNeededToDisplay( |
| 2564 const string16& text) const { | 2574 const string16& text) const { |
| 2565 // Use font_.GetStringWidth() instead of | 2575 // Use font_.GetStringWidth() instead of |
| 2566 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is | 2576 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is |
| 2567 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout, | 2577 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout, |
| 2568 // PosFromChar(i) might return 0 when i is greater than 1. | 2578 // PosFromChar(i) might return 0 when i is greater than 1. |
| 2569 return font_.GetStringWidth(text) + GetHorizontalMargin(); | 2579 return font_.GetStringWidth(text) + GetHorizontalMargin(); |
| 2570 } | 2580 } |
| OLD | NEW |