OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #define INITGUID // required for GUID_PROP_INPUTSCOPE | 5 #define INITGUID // required for GUID_PROP_INPUTSCOPE |
6 #include "ui/base/ime/win/tsf_text_store.h" | 6 #include "ui/base/ime/win/tsf_text_store.h" |
7 | 7 |
8 #include <InputScope.h> | 8 #include <InputScope.h> |
9 #include <OleCtl.h> | 9 #include <OleCtl.h> |
10 | 10 |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 } | 824 } |
825 | 825 |
826 void TSFTextStore::RemoveFocusedTextInputClient( | 826 void TSFTextStore::RemoveFocusedTextInputClient( |
827 TextInputClient* text_input_client) { | 827 TextInputClient* text_input_client) { |
828 if (text_input_client_ == text_input_client) { | 828 if (text_input_client_ == text_input_client) { |
829 window_handle_ = NULL; | 829 window_handle_ = NULL; |
830 text_input_client_ = NULL; | 830 text_input_client_ = NULL; |
831 } | 831 } |
832 } | 832 } |
833 | 833 |
| 834 bool TSFTextStore::CancelComposition() { |
| 835 // There is an on-going document lock. We must not edit the text! |
| 836 if (!edit_flag_) |
| 837 return false; |
| 838 |
| 839 if (string_buffer_.empty()) |
| 840 return true; |
| 841 |
| 842 // Unlike ImmNotifyIME(NI_COMPOSITIONSTR, CPS_CANCEL, 0) in IMM32, TSF does |
| 843 // not have a dedicated method to cancel composition. However, CUAS actually |
| 844 // has a protocol conversion from CPS_CANCEL into TSF operations. According |
| 845 // to the observations on Windows 7, TIPs are expected to cancel composition |
| 846 // when an on-going composition text is replaced with an empty string. So |
| 847 // we use the same operation to cancel composition here to minimize the risk |
| 848 // of potential compatibility issues. |
| 849 |
| 850 const size_t previous_buffer_size = string_buffer_.size(); |
| 851 string_buffer_.clear(); |
| 852 committed_size_ = 0; |
| 853 selection_.set_start(0); |
| 854 selection_.set_end(0); |
| 855 if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) |
| 856 text_store_acp_sink_->OnSelectionChange(); |
| 857 if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) |
| 858 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
| 859 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { |
| 860 TS_TEXTCHANGE textChange = {}; |
| 861 textChange.acpStart = 0; |
| 862 textChange.acpOldEnd = previous_buffer_size; |
| 863 textChange.acpNewEnd = 0; |
| 864 text_store_acp_sink_->OnTextChange(0, &textChange); |
| 865 } |
| 866 return true; |
| 867 } |
| 868 |
| 869 bool TSFTextStore::ConfirmComposition() { |
| 870 // There is an on-going document lock. We must not edit the text! |
| 871 if (!edit_flag_) |
| 872 return false; |
| 873 |
| 874 if (string_buffer_.empty()) |
| 875 return true; |
| 876 |
| 877 // See the comment in TSFTextStore::CancelComposition. |
| 878 // This logic is based on the observation about how to emulate |
| 879 // ImmNotifyIME(NI_COMPOSITIONSTR, CPS_COMPLETE, 0) by CUAS. |
| 880 |
| 881 const string16& composition_text = string_buffer_.substr(committed_size_); |
| 882 if (!composition_text.empty()) |
| 883 text_input_client_->InsertText(composition_text); |
| 884 |
| 885 const size_t previous_buffer_size = string_buffer_.size(); |
| 886 string_buffer_.clear(); |
| 887 committed_size_ = 0; |
| 888 selection_.set_start(0); |
| 889 selection_.set_end(0); |
| 890 if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) |
| 891 text_store_acp_sink_->OnSelectionChange(); |
| 892 if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) |
| 893 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
| 894 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { |
| 895 TS_TEXTCHANGE textChange = {}; |
| 896 textChange.acpStart = 0; |
| 897 textChange.acpOldEnd = previous_buffer_size; |
| 898 textChange.acpNewEnd = 0; |
| 899 text_store_acp_sink_->OnTextChange(0, &textChange); |
| 900 } |
| 901 return true; |
| 902 } |
| 903 |
834 void TSFTextStore::SendOnLayoutChange() { | 904 void TSFTextStore::SendOnLayoutChange() { |
835 if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) | 905 if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) |
836 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); | 906 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
837 } | 907 } |
838 | 908 |
839 bool TSFTextStore::HasReadLock() const { | 909 bool TSFTextStore::HasReadLock() const { |
840 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; | 910 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; |
841 } | 911 } |
842 | 912 |
843 bool TSFTextStore::HasReadWriteLock() const { | 913 bool TSFTextStore::HasReadWriteLock() const { |
844 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; | 914 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; |
845 } | 915 } |
846 | 916 |
847 } // namespace ui | 917 } // namespace ui |
OLD | NEW |