Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
| 6 | 6 |
| 7 #include <locale> | 7 #include <locale> |
| 8 | 8 |
| 9 #include "base/base_drag_source.h" | 9 #include "base/base_drag_source.h" |
| 10 #include "base/clipboard.h" | 10 #include "base/clipboard.h" |
| 11 #include "base/iat_patch.h" | 11 #include "base/iat_patch.h" |
| 12 #include "base/lazy_instance.h" | |
| 12 #include "base/ref_counted.h" | 13 #include "base/ref_counted.h" |
| 13 #include "base/scoped_clipboard_writer.h" | 14 #include "base/scoped_clipboard_writer.h" |
| 14 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 15 #include "chrome/app/chrome_dll_resource.h" | 16 #include "chrome/app/chrome_dll_resource.h" |
| 16 #include "chrome/browser/autocomplete/autocomplete_accessibility.h" | 17 #include "chrome/browser/autocomplete/autocomplete_accessibility.h" |
| 17 #include "chrome/browser/autocomplete/autocomplete_popup.h" | 18 #include "chrome/browser/autocomplete/autocomplete_popup.h" |
| 18 #include "chrome/browser/autocomplete/edit_drop_target.h" | 19 #include "chrome/browser/autocomplete/edit_drop_target.h" |
| 19 #include "chrome/browser/autocomplete/keyword_provider.h" | 20 #include "chrome/browser/autocomplete/keyword_provider.h" |
| 20 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
| 21 #include "chrome/browser/command_updater.h" | 22 #include "chrome/browser/command_updater.h" |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 if (text_object_model_) | 627 if (text_object_model_) |
| 627 text_object_model_->Undo(tomResume, NULL); | 628 text_object_model_->Undo(tomResume, NULL); |
| 628 } | 629 } |
| 629 | 630 |
| 630 /////////////////////////////////////////////////////////////////////////////// | 631 /////////////////////////////////////////////////////////////////////////////// |
| 631 // AutocompleteEditView | 632 // AutocompleteEditView |
| 632 | 633 |
| 633 // TODO (jcampan): these colors should be derived from the system colors to | 634 // TODO (jcampan): these colors should be derived from the system colors to |
| 634 // ensure they show properly. Bug #948807. | 635 // ensure they show properly. Bug #948807. |
| 635 // Colors used to emphasize the scheme in the URL. | 636 // Colors used to emphasize the scheme in the URL. |
| 636 static const COLORREF kSecureSchemeColor = RGB(0, 150, 20); | 637 |
| 637 static const COLORREF kInsecureSchemeColor = RGB(200, 0, 0); | 638 namespace { |
| 639 | |
| 640 const COLORREF kSecureSchemeColor = RGB(0, 150, 20); | |
| 641 const COLORREF kInsecureSchemeColor = RGB(200, 0, 0); | |
| 638 | 642 |
| 639 // Colors used to strike-out the scheme when it is insecure. | 643 // Colors used to strike-out the scheme when it is insecure. |
| 640 static const SkColor kSchemeStrikeoutColor = SkColorSetRGB(210, 0, 0); | 644 const SkColor kSchemeStrikeoutColor = SkColorSetRGB(210, 0, 0); |
| 641 static const SkColor kSchemeSelectedStrikeoutColor = | 645 const SkColor kSchemeSelectedStrikeoutColor = |
| 642 SkColorSetRGB(255, 255, 255); | 646 SkColorSetRGB(255, 255, 255); |
| 643 | 647 |
| 644 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and | 648 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and |
| 645 // EndPaint() and provide a memory DC instead. See OnPaint(). | 649 // EndPaint() and provide a memory DC instead. See OnPaint(). |
| 646 static HWND edit_hwnd = NULL; | 650 HWND edit_hwnd = NULL; |
| 647 static PAINTSTRUCT paint_struct; | 651 PAINTSTRUCT paint_struct; |
| 652 | |
| 653 HDC BeginPaintIntercept(HWND hWnd, LPPAINTSTRUCT lpPaint) { | |
| 654 if (!edit_hwnd || (hWnd != edit_hwnd)) | |
| 655 return ::BeginPaint(hWnd, lpPaint); | |
| 656 | |
| 657 *lpPaint = paint_struct; | |
| 658 return paint_struct.hdc; | |
| 659 } | |
| 660 | |
| 661 BOOL EndPaintIntercept(HWND hWnd, const PAINTSTRUCT* lpPaint) { | |
| 662 return (edit_hwnd && (hWnd == edit_hwnd)) ? | |
| 663 true : ::EndPaint(hWnd, lpPaint); | |
| 664 } | |
| 648 | 665 |
| 649 // Returns a lazily initialized property bag accessor for saving our state in a | 666 // Returns a lazily initialized property bag accessor for saving our state in a |
| 650 // TabContents. | 667 // TabContents. |
| 651 static PropertyAccessor<AutocompleteEditState>* GetStateAccessor() { | 668 PropertyAccessor<AutocompleteEditState>* GetStateAccessor() { |
| 652 static PropertyAccessor<AutocompleteEditState> state; | 669 static PropertyAccessor<AutocompleteEditState> state; |
| 653 return &state; | 670 return &state; |
| 654 } | 671 } |
| 655 | 672 |
| 673 class PaintPatcher { | |
|
amit
2009/02/26 15:00:32
maybe derive privately from RefCounted and just ca
| |
| 674 public: | |
| 675 PaintPatcher() : refcount_(0) { } | |
| 676 ~PaintPatcher() { DCHECK(refcount_ == 0); } | |
| 677 | |
| 678 void RefPatch() { | |
| 679 if (refcount_ == 0) { | |
| 680 DCHECK(!begin_paint_.is_patched()); | |
| 681 DCHECK(!end_paint_.is_patched()); | |
| 682 begin_paint_.Patch(L"riched20.dll", "user32.dll", "BeginPaint", | |
| 683 &BeginPaintIntercept); | |
| 684 end_paint_.Patch(L"riched20.dll", "user32.dll", "EndPaint", | |
| 685 &EndPaintIntercept); | |
| 686 } | |
| 687 ++refcount_; | |
| 688 } | |
| 689 | |
| 690 void DerefPatch() { | |
| 691 DCHECK(begin_paint_.is_patched()); | |
| 692 DCHECK(end_paint_.is_patched()); | |
| 693 --refcount_; | |
| 694 if (refcount_ == 0) { | |
| 695 begin_paint_.Unpatch(); | |
| 696 end_paint_.Unpatch(); | |
| 697 } | |
| 698 } | |
| 699 | |
| 700 private: | |
|
amit
2009/02/26 15:00:32
DISABLE_COPY_AND_ASSIGN
| |
| 701 size_t refcount_; | |
| 702 iat_patch::IATPatchFunction begin_paint_; | |
| 703 iat_patch::IATPatchFunction end_paint_; | |
| 704 }; | |
| 705 | |
| 706 base::LazyInstance<PaintPatcher> g_paint_patcher(base::LINKER_INITIALIZED); | |
| 707 | |
| 708 } // namespace | |
| 709 | |
| 656 AutocompleteEditView::AutocompleteEditView( | 710 AutocompleteEditView::AutocompleteEditView( |
| 657 const ChromeFont& font, | 711 const ChromeFont& font, |
| 658 AutocompleteEditController* controller, | 712 AutocompleteEditController* controller, |
| 659 ToolbarModel* toolbar_model, | 713 ToolbarModel* toolbar_model, |
| 660 views::View* parent_view, | 714 views::View* parent_view, |
| 661 HWND hwnd, | 715 HWND hwnd, |
| 662 Profile* profile, | 716 Profile* profile, |
| 663 CommandUpdater* command_updater, | 717 CommandUpdater* command_updater, |
| 664 bool popup_window_mode) | 718 bool popup_window_mode) |
| 665 : model_(new AutocompleteEditModel(this, controller, profile)), | 719 : model_(new AutocompleteEditModel(this, controller, profile)), |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 678 possible_drag_(false), | 732 possible_drag_(false), |
| 679 in_drag_(false), | 733 in_drag_(false), |
| 680 initiated_drag_(false), | 734 initiated_drag_(false), |
| 681 drop_highlight_position_(-1), | 735 drop_highlight_position_(-1), |
| 682 background_color_(0), | 736 background_color_(0), |
| 683 scheme_security_level_(ToolbarModel::NORMAL) { | 737 scheme_security_level_(ToolbarModel::NORMAL) { |
| 684 model_->set_popup_model(popup_model_.get()); | 738 model_->set_popup_model(popup_model_.get()); |
| 685 | 739 |
| 686 saved_selection_for_focus_change_.cpMin = -1; | 740 saved_selection_for_focus_change_.cpMin = -1; |
| 687 | 741 |
| 688 // Statics used for global patching of riched20.dll. | 742 g_paint_patcher.Pointer()->RefPatch(); |
| 689 static HMODULE richedit_module = NULL; | |
| 690 static iat_patch::IATPatchFunction patch_begin_paint; | |
| 691 static iat_patch::IATPatchFunction patch_end_paint; | |
| 692 | |
| 693 if (!richedit_module) { | |
| 694 richedit_module = LoadLibrary(L"riched20.dll"); | |
| 695 if (richedit_module) { | |
| 696 DCHECK(!patch_begin_paint.is_patched()); | |
| 697 patch_begin_paint.Patch(richedit_module, "user32.dll", "BeginPaint", | |
| 698 &BeginPaintIntercept); | |
| 699 DCHECK(!patch_end_paint.is_patched()); | |
| 700 patch_end_paint.Patch(richedit_module, "user32.dll", "EndPaint", | |
| 701 &EndPaintIntercept); | |
| 702 } | |
| 703 } | |
| 704 | 743 |
| 705 Create(hwnd, 0, 0, 0, l10n_util::GetExtendedStyles()); | 744 Create(hwnd, 0, 0, 0, l10n_util::GetExtendedStyles()); |
| 706 SetReadOnly(popup_window_mode_); | 745 SetReadOnly(popup_window_mode_); |
| 707 SetFont(font_.hfont()); | 746 SetFont(font_.hfont()); |
| 708 | 747 |
| 709 // NOTE: Do not use SetWordBreakProcEx() here, that is no longer supported as | 748 // NOTE: Do not use SetWordBreakProcEx() here, that is no longer supported as |
| 710 // of Rich Edit 2.0 onward. | 749 // of Rich Edit 2.0 onward. |
| 711 SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, | 750 SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, |
| 712 reinterpret_cast<LPARAM>(&WordBreakProc)); | 751 reinterpret_cast<LPARAM>(&WordBreakProc)); |
| 713 | 752 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 scoped_refptr<EditDropTarget> drop_target = new EditDropTarget(this); | 819 scoped_refptr<EditDropTarget> drop_target = new EditDropTarget(this); |
| 781 RegisterDragDrop(m_hWnd, drop_target.get()); | 820 RegisterDragDrop(m_hWnd, drop_target.get()); |
| 782 } | 821 } |
| 783 } | 822 } |
| 784 | 823 |
| 785 AutocompleteEditView::~AutocompleteEditView() { | 824 AutocompleteEditView::~AutocompleteEditView() { |
| 786 NotificationService::current()->Notify( | 825 NotificationService::current()->Notify( |
| 787 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, | 826 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, |
| 788 Source<AutocompleteEditView>(this), | 827 Source<AutocompleteEditView>(this), |
| 789 NotificationService::NoDetails()); | 828 NotificationService::NoDetails()); |
| 829 | |
| 830 // We balance our reference count and unpatch when the last instance has | |
| 831 // been destroyed. This prevents us from relying on the AtExit or static | |
| 832 // destructor sequence to do our unpatching, which is generally fragile. | |
| 833 g_paint_patcher.Pointer()->DerefPatch(); | |
| 790 } | 834 } |
| 791 | 835 |
| 792 void AutocompleteEditView::SaveStateToTab(TabContents* tab) { | 836 void AutocompleteEditView::SaveStateToTab(TabContents* tab) { |
| 793 DCHECK(tab); | 837 DCHECK(tab); |
| 794 | 838 |
| 795 const AutocompleteEditModel::State model_state( | 839 const AutocompleteEditModel::State model_state( |
| 796 model_->GetStateForTabSwitch()); | 840 model_->GetStateForTabSwitch()); |
| 797 | 841 |
| 798 CHARRANGE selection; | 842 CHARRANGE selection; |
| 799 GetSelection(selection); | 843 GetSelection(selection); |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1367 bool AutocompleteEditView::SchemeEnd(LPTSTR edit_text, | 1411 bool AutocompleteEditView::SchemeEnd(LPTSTR edit_text, |
| 1368 int current_pos, | 1412 int current_pos, |
| 1369 int length) { | 1413 int length) { |
| 1370 return (current_pos >= 0) && | 1414 return (current_pos >= 0) && |
| 1371 ((length - current_pos) > 2) && | 1415 ((length - current_pos) > 2) && |
| 1372 (edit_text[current_pos] == ':') && | 1416 (edit_text[current_pos] == ':') && |
| 1373 (edit_text[current_pos + 1] == '/') && | 1417 (edit_text[current_pos + 1] == '/') && |
| 1374 (edit_text[current_pos + 2] == '/'); | 1418 (edit_text[current_pos + 2] == '/'); |
| 1375 } | 1419 } |
| 1376 | 1420 |
| 1377 // static | |
| 1378 HDC AutocompleteEditView::BeginPaintIntercept(HWND hWnd, | |
| 1379 LPPAINTSTRUCT lpPaint) { | |
| 1380 if (!edit_hwnd || (hWnd != edit_hwnd)) | |
| 1381 return ::BeginPaint(hWnd, lpPaint); | |
| 1382 | |
| 1383 *lpPaint = paint_struct; | |
| 1384 return paint_struct.hdc; | |
| 1385 } | |
| 1386 | |
| 1387 // static | |
| 1388 BOOL AutocompleteEditView::EndPaintIntercept(HWND hWnd, | |
| 1389 const PAINTSTRUCT* lpPaint) { | |
| 1390 return (edit_hwnd && (hWnd == edit_hwnd)) ? | |
| 1391 true : ::EndPaint(hWnd, lpPaint); | |
| 1392 } | |
| 1393 | |
| 1394 void AutocompleteEditView::OnChar(TCHAR ch, UINT repeat_count, UINT flags) { | 1421 void AutocompleteEditView::OnChar(TCHAR ch, UINT repeat_count, UINT flags) { |
| 1395 // Don't let alt-enter beep. Not sure this is necessary, as the standard | 1422 // Don't let alt-enter beep. Not sure this is necessary, as the standard |
| 1396 // alt-enter will hit DiscardWMSysChar() and get thrown away, and | 1423 // alt-enter will hit DiscardWMSysChar() and get thrown away, and |
| 1397 // ctrl-alt-enter doesn't seem to reach here for some reason? At least not on | 1424 // ctrl-alt-enter doesn't seem to reach here for some reason? At least not on |
| 1398 // my system... still, this is harmless and maybe necessary in other locales. | 1425 // my system... still, this is harmless and maybe necessary in other locales. |
| 1399 if (ch == VK_RETURN && (flags & KF_ALTDOWN)) | 1426 if (ch == VK_RETURN && (flags & KF_ALTDOWN)) |
| 1400 return; | 1427 return; |
| 1401 | 1428 |
| 1402 // Escape is processed in OnKeyDown. Don't let any WM_CHAR messages propagate | 1429 // Escape is processed in OnKeyDown. Don't let any WM_CHAR messages propagate |
| 1403 // as we don't want the RichEdit to do anything funky. | 1430 // as we don't want the RichEdit to do anything funky. |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2458 } | 2485 } |
| 2459 | 2486 |
| 2460 void AutocompleteEditView::RepaintDropHighlight(int position) { | 2487 void AutocompleteEditView::RepaintDropHighlight(int position) { |
| 2461 if ((position != -1) && (position <= GetTextLength())) { | 2488 if ((position != -1) && (position <= GetTextLength())) { |
| 2462 const POINT min_loc(PosFromChar(position)); | 2489 const POINT min_loc(PosFromChar(position)); |
| 2463 const RECT highlight_bounds = {min_loc.x - 1, font_y_adjustment_, | 2490 const RECT highlight_bounds = {min_loc.x - 1, font_y_adjustment_, |
| 2464 min_loc.x + 2, font_ascent_ + font_descent_ + font_y_adjustment_}; | 2491 min_loc.x + 2, font_ascent_ + font_descent_ + font_y_adjustment_}; |
| 2465 InvalidateRect(&highlight_bounds, false); | 2492 InvalidateRect(&highlight_bounds, false); |
| 2466 } | 2493 } |
| 2467 } | 2494 } |
| OLD | NEW |