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 #include "ui/base/ime/win/tsf_event_router.h" | 5 #include "ui/base/ime/win/tsf_event_router.h" |
6 | 6 |
7 #include <msctf.h> | 7 #include <msctf.h> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/win/scoped_comptr.h" | 12 #include "base/win/scoped_comptr.h" |
13 #include "base/win/metro.h" | 13 #include "base/win/metro.h" |
14 #include "ui/base/range/range.h" | |
15 #include "ui/base/win/atl_module.h" | 14 #include "ui/base/win/atl_module.h" |
| 15 #include "ui/gfx/range/range.h" |
16 | 16 |
17 namespace ui { | 17 namespace ui { |
18 | 18 |
19 | 19 |
20 // TSFEventRouter::Delegate ------------------------------------ | 20 // TSFEventRouter::Delegate ------------------------------------ |
21 | 21 |
22 // The implementation class of ITfUIElementSink, whose member functions will be | 22 // The implementation class of ITfUIElementSink, whose member functions will be |
23 // called back by TSF when the UI element status is changed, for example when | 23 // called back by TSF when the UI element status is changed, for example when |
24 // the candidate window is opened or closed. This class also implements | 24 // the candidate window is opened or closed. This class also implements |
25 // ITfTextEditSink, whose member function is called back by TSF when the text | 25 // ITfTextEditSink, whose member function is called back by TSF when the text |
(...skipping 23 matching lines...) Expand all Loading... |
49 // Sets |thread_manager| to be monitored. |thread_manager| can be NULL. | 49 // Sets |thread_manager| to be monitored. |thread_manager| can be NULL. |
50 void SetManager(ITfThreadMgr* thread_manager); | 50 void SetManager(ITfThreadMgr* thread_manager); |
51 | 51 |
52 // Returns true if the IME is composing text. | 52 // Returns true if the IME is composing text. |
53 bool IsImeComposing(); | 53 bool IsImeComposing(); |
54 | 54 |
55 // Sets |router| to be forwarded TSF-related events. | 55 // Sets |router| to be forwarded TSF-related events. |
56 void SetRouter(TSFEventRouter* router); | 56 void SetRouter(TSFEventRouter* router); |
57 | 57 |
58 private: | 58 private: |
59 // Returns current composition range. Returns ui::Range::InvalidRange if there | 59 // Returns current composition range. Returns gfx::Range::InvalidRange if |
60 // is no composition. | 60 // there is no composition. |
61 static ui::Range GetCompositionRange(ITfContext* context); | 61 static gfx::Range GetCompositionRange(ITfContext* context); |
62 | 62 |
63 // Returns true if the given |element_id| represents the candidate window. | 63 // Returns true if the given |element_id| represents the candidate window. |
64 bool IsCandidateWindowInternal(DWORD element_id); | 64 bool IsCandidateWindowInternal(DWORD element_id); |
65 | 65 |
66 // A context associated with this class. | 66 // A context associated with this class. |
67 base::win::ScopedComPtr<ITfContext> context_; | 67 base::win::ScopedComPtr<ITfContext> context_; |
68 | 68 |
69 // The ITfSource associated with |context_|. | 69 // The ITfSource associated with |context_|. |
70 base::win::ScopedComPtr<ITfSource> context_source_; | 70 base::win::ScopedComPtr<ITfSource> context_source_; |
71 | 71 |
72 // The cookie for |context_source_|. | 72 // The cookie for |context_source_|. |
73 DWORD context_source_cookie_; | 73 DWORD context_source_cookie_; |
74 | 74 |
75 // A UIElementMgr associated with this class. | 75 // A UIElementMgr associated with this class. |
76 base::win::ScopedComPtr<ITfUIElementMgr> ui_element_manager_; | 76 base::win::ScopedComPtr<ITfUIElementMgr> ui_element_manager_; |
77 | 77 |
78 // The ITfSouce associated with |ui_element_manager_|. | 78 // The ITfSouce associated with |ui_element_manager_|. |
79 base::win::ScopedComPtr<ITfSource> ui_source_; | 79 base::win::ScopedComPtr<ITfSource> ui_source_; |
80 | 80 |
81 // The set of currently opened candidate window ids. | 81 // The set of currently opened candidate window ids. |
82 std::set<DWORD> open_candidate_window_ids_; | 82 std::set<DWORD> open_candidate_window_ids_; |
83 | 83 |
84 // The cookie for |ui_source_|. | 84 // The cookie for |ui_source_|. |
85 DWORD ui_source_cookie_; | 85 DWORD ui_source_cookie_; |
86 | 86 |
87 TSFEventRouter* router_; | 87 TSFEventRouter* router_; |
88 ui::Range previous_composition_range_; | 88 gfx::Range previous_composition_range_; |
89 | 89 |
90 DISALLOW_COPY_AND_ASSIGN(Delegate); | 90 DISALLOW_COPY_AND_ASSIGN(Delegate); |
91 }; | 91 }; |
92 | 92 |
93 TSFEventRouter::Delegate::Delegate() | 93 TSFEventRouter::Delegate::Delegate() |
94 : context_source_cookie_(TF_INVALID_COOKIE), | 94 : context_source_cookie_(TF_INVALID_COOKIE), |
95 ui_source_cookie_(TF_INVALID_COOKIE), | 95 ui_source_cookie_(TF_INVALID_COOKIE), |
96 router_(NULL), | 96 router_(NULL), |
97 previous_composition_range_(ui::Range::InvalidRange()) { | 97 previous_composition_range_(gfx::Range::InvalidRange()) { |
98 } | 98 } |
99 | 99 |
100 TSFEventRouter::Delegate::~Delegate() {} | 100 TSFEventRouter::Delegate::~Delegate() {} |
101 | 101 |
102 void TSFEventRouter::Delegate::SetRouter(TSFEventRouter* router) { | 102 void TSFEventRouter::Delegate::SetRouter(TSFEventRouter* router) { |
103 router_ = router; | 103 router_ = router; |
104 } | 104 } |
105 | 105 |
106 STDMETHODIMP TSFEventRouter::Delegate::OnEndEdit(ITfContext* context, | 106 STDMETHODIMP TSFEventRouter::Delegate::OnEndEdit(ITfContext* context, |
107 TfEditCookie read_only_cookie, | 107 TfEditCookie read_only_cookie, |
(...skipping 10 matching lines...) Expand all Loading... |
118 base::win::ScopedComPtr<IEnumTfRanges> ranges; | 118 base::win::ScopedComPtr<IEnumTfRanges> ranges; |
119 if (FAILED(edit_record->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, | 119 if (FAILED(edit_record->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, |
120 ranges.Receive()))) | 120 ranges.Receive()))) |
121 return S_OK; // Don't care about failures. | 121 return S_OK; // Don't care about failures. |
122 | 122 |
123 ULONG fetched_count = 0; | 123 ULONG fetched_count = 0; |
124 base::win::ScopedComPtr<ITfRange> range; | 124 base::win::ScopedComPtr<ITfRange> range; |
125 if (FAILED(ranges->Next(1, range.Receive(), &fetched_count))) | 125 if (FAILED(ranges->Next(1, range.Receive(), &fetched_count))) |
126 return S_OK; // Don't care about failures. | 126 return S_OK; // Don't care about failures. |
127 | 127 |
128 const ui::Range composition_range = GetCompositionRange(context); | 128 const gfx::Range composition_range = GetCompositionRange(context); |
129 | 129 |
130 if (!previous_composition_range_.IsValid() && composition_range.IsValid()) | 130 if (!previous_composition_range_.IsValid() && composition_range.IsValid()) |
131 router_->OnTSFStartComposition(); | 131 router_->OnTSFStartComposition(); |
132 | 132 |
133 // |fetched_count| != 0 means there is at least one range that contains | 133 // |fetched_count| != 0 means there is at least one range that contains |
134 // updated text. | 134 // updated text. |
135 if (fetched_count != 0) | 135 if (fetched_count != 0) |
136 router_->OnTextUpdated(composition_range); | 136 router_->OnTextUpdated(composition_range); |
137 | 137 |
138 if (previous_composition_range_.IsValid() && !composition_range.IsValid()) | 138 if (previous_composition_range_.IsValid() && !composition_range.IsValid()) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 ui_source_->AdviseSink(IID_ITfUIElementSink, | 207 ui_source_->AdviseSink(IID_ITfUIElementSink, |
208 static_cast<ITfUIElementSink*>(this), | 208 static_cast<ITfUIElementSink*>(this), |
209 &ui_source_cookie_); | 209 &ui_source_cookie_); |
210 } | 210 } |
211 | 211 |
212 bool TSFEventRouter::Delegate::IsImeComposing() { | 212 bool TSFEventRouter::Delegate::IsImeComposing() { |
213 return context_ && GetCompositionRange(context_).IsValid(); | 213 return context_ && GetCompositionRange(context_).IsValid(); |
214 } | 214 } |
215 | 215 |
216 // static | 216 // static |
217 ui::Range TSFEventRouter::Delegate::GetCompositionRange( | 217 gfx::Range TSFEventRouter::Delegate::GetCompositionRange( |
218 ITfContext* context) { | 218 ITfContext* context) { |
219 DCHECK(context); | 219 DCHECK(context); |
220 base::win::ScopedComPtr<ITfContextComposition> context_composition; | 220 base::win::ScopedComPtr<ITfContextComposition> context_composition; |
221 if (FAILED(context_composition.QueryFrom(context))) | 221 if (FAILED(context_composition.QueryFrom(context))) |
222 return ui::Range::InvalidRange(); | 222 return gfx::Range::InvalidRange(); |
223 base::win::ScopedComPtr<IEnumITfCompositionView> enum_composition_view; | 223 base::win::ScopedComPtr<IEnumITfCompositionView> enum_composition_view; |
224 if (FAILED(context_composition->EnumCompositions( | 224 if (FAILED(context_composition->EnumCompositions( |
225 enum_composition_view.Receive()))) | 225 enum_composition_view.Receive()))) |
226 return ui::Range::InvalidRange(); | 226 return gfx::Range::InvalidRange(); |
227 base::win::ScopedComPtr<ITfCompositionView> composition_view; | 227 base::win::ScopedComPtr<ITfCompositionView> composition_view; |
228 if (enum_composition_view->Next(1, composition_view.Receive(), | 228 if (enum_composition_view->Next(1, composition_view.Receive(), |
229 NULL) != S_OK) | 229 NULL) != S_OK) |
230 return ui::Range::InvalidRange(); | 230 return gfx::Range::InvalidRange(); |
231 | 231 |
232 base::win::ScopedComPtr<ITfRange> range; | 232 base::win::ScopedComPtr<ITfRange> range; |
233 if (FAILED(composition_view->GetRange(range.Receive()))) | 233 if (FAILED(composition_view->GetRange(range.Receive()))) |
234 return ui::Range::InvalidRange(); | 234 return gfx::Range::InvalidRange(); |
235 | 235 |
236 base::win::ScopedComPtr<ITfRangeACP> range_acp; | 236 base::win::ScopedComPtr<ITfRangeACP> range_acp; |
237 if (FAILED(range_acp.QueryFrom(range))) | 237 if (FAILED(range_acp.QueryFrom(range))) |
238 return ui::Range::InvalidRange(); | 238 return gfx::Range::InvalidRange(); |
239 | 239 |
240 LONG start = 0; | 240 LONG start = 0; |
241 LONG length = 0; | 241 LONG length = 0; |
242 if (FAILED(range_acp->GetExtent(&start, &length))) | 242 if (FAILED(range_acp->GetExtent(&start, &length))) |
243 return ui::Range::InvalidRange(); | 243 return gfx::Range::InvalidRange(); |
244 | 244 |
245 return ui::Range(start, start + length); | 245 return gfx::Range(start, start + length); |
246 } | 246 } |
247 | 247 |
248 bool TSFEventRouter::Delegate::IsCandidateWindowInternal(DWORD element_id) { | 248 bool TSFEventRouter::Delegate::IsCandidateWindowInternal(DWORD element_id) { |
249 DCHECK(ui_element_manager_.get()); | 249 DCHECK(ui_element_manager_.get()); |
250 base::win::ScopedComPtr<ITfUIElement> ui_element; | 250 base::win::ScopedComPtr<ITfUIElement> ui_element; |
251 if (FAILED(ui_element_manager_->GetUIElement(element_id, | 251 if (FAILED(ui_element_manager_->GetUIElement(element_id, |
252 ui_element.Receive()))) | 252 ui_element.Receive()))) |
253 return false; | 253 return false; |
254 base::win::ScopedComPtr<ITfCandidateListUIElement> candidate_list_ui_element; | 254 base::win::ScopedComPtr<ITfCandidateListUIElement> candidate_list_ui_element; |
255 return SUCCEEDED(candidate_list_ui_element.QueryFrom(ui_element)); | 255 return SUCCEEDED(candidate_list_ui_element.QueryFrom(ui_element)); |
(...skipping 29 matching lines...) Expand all Loading... |
285 } | 285 } |
286 | 286 |
287 void TSFEventRouter::OnCandidateWindowCountChanged(size_t window_count) { | 287 void TSFEventRouter::OnCandidateWindowCountChanged(size_t window_count) { |
288 observer_->OnCandidateWindowCountChanged(window_count); | 288 observer_->OnCandidateWindowCountChanged(window_count); |
289 } | 289 } |
290 | 290 |
291 void TSFEventRouter::OnTSFStartComposition() { | 291 void TSFEventRouter::OnTSFStartComposition() { |
292 observer_->OnTSFStartComposition(); | 292 observer_->OnTSFStartComposition(); |
293 } | 293 } |
294 | 294 |
295 void TSFEventRouter::OnTextUpdated(const ui::Range& composition_range) { | 295 void TSFEventRouter::OnTextUpdated(const gfx::Range& composition_range) { |
296 observer_->OnTextUpdated(composition_range); | 296 observer_->OnTextUpdated(composition_range); |
297 } | 297 } |
298 | 298 |
299 void TSFEventRouter::OnTSFEndComposition() { | 299 void TSFEventRouter::OnTSFEndComposition() { |
300 observer_->OnTSFEndComposition(); | 300 observer_->OnTSFEndComposition(); |
301 } | 301 } |
302 | 302 |
303 void TSFEventRouter::SetManager(ITfThreadMgr* thread_manager) { | 303 void TSFEventRouter::SetManager(ITfThreadMgr* thread_manager) { |
304 delegate_->SetManager(thread_manager); | 304 delegate_->SetManager(thread_manager); |
305 } | 305 } |
306 | 306 |
307 } // namespace ui | 307 } // namespace ui |
OLD | NEW |