Index: ui/base/ime/win/tsf_event_router.cc |
diff --git a/ui/base/ime/win/tsf_event_router.cc b/ui/base/ime/win/tsf_event_router.cc |
deleted file mode 100644 |
index 4f34a048eec760092f6219c737ffa5306809c770..0000000000000000000000000000000000000000 |
--- a/ui/base/ime/win/tsf_event_router.cc |
+++ /dev/null |
@@ -1,307 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "ui/base/ime/win/tsf_event_router.h" |
- |
-#include <msctf.h> |
-#include <set> |
-#include <utility> |
- |
-#include "base/bind.h" |
-#include "base/win/scoped_comptr.h" |
-#include "base/win/metro.h" |
-#include "ui/base/win/atl_module.h" |
-#include "ui/gfx/range/range.h" |
- |
-namespace ui { |
- |
- |
-// TSFEventRouter::Delegate ------------------------------------ |
- |
-// The implementation class of ITfUIElementSink, whose member functions will be |
-// called back by TSF when the UI element status is changed, for example when |
-// the candidate window is opened or closed. This class also implements |
-// ITfTextEditSink, whose member function is called back by TSF when the text |
-// editting session is finished. |
-class ATL_NO_VTABLE TSFEventRouter::Delegate |
- : public ATL::CComObjectRootEx<CComSingleThreadModel>, |
- public ITfUIElementSink, |
- public ITfTextEditSink { |
- public: |
- BEGIN_COM_MAP(Delegate) |
- COM_INTERFACE_ENTRY(ITfUIElementSink) |
- COM_INTERFACE_ENTRY(ITfTextEditSink) |
- END_COM_MAP() |
- |
- Delegate(); |
- ~Delegate(); |
- |
- // ITfTextEditSink: |
- STDMETHOD(OnEndEdit)(ITfContext* context, TfEditCookie read_only_cookie, |
- ITfEditRecord* edit_record) OVERRIDE; |
- |
- // ITfUiElementSink: |
- STDMETHOD(BeginUIElement)(DWORD element_id, BOOL* is_show) OVERRIDE; |
- STDMETHOD(UpdateUIElement)(DWORD element_id) OVERRIDE; |
- STDMETHOD(EndUIElement)(DWORD element_id) OVERRIDE; |
- |
- // Sets |thread_manager| to be monitored. |thread_manager| can be NULL. |
- void SetManager(ITfThreadMgr* thread_manager); |
- |
- // Returns true if the IME is composing text. |
- bool IsImeComposing(); |
- |
- // Sets |router| to be forwarded TSF-related events. |
- void SetRouter(TSFEventRouter* router); |
- |
- private: |
- // Returns current composition range. Returns gfx::Range::InvalidRange if |
- // there is no composition. |
- static gfx::Range GetCompositionRange(ITfContext* context); |
- |
- // Returns true if the given |element_id| represents the candidate window. |
- bool IsCandidateWindowInternal(DWORD element_id); |
- |
- // A context associated with this class. |
- base::win::ScopedComPtr<ITfContext> context_; |
- |
- // The ITfSource associated with |context_|. |
- base::win::ScopedComPtr<ITfSource> context_source_; |
- |
- // The cookie for |context_source_|. |
- DWORD context_source_cookie_; |
- |
- // A UIElementMgr associated with this class. |
- base::win::ScopedComPtr<ITfUIElementMgr> ui_element_manager_; |
- |
- // The ITfSouce associated with |ui_element_manager_|. |
- base::win::ScopedComPtr<ITfSource> ui_source_; |
- |
- // The set of currently opened candidate window ids. |
- std::set<DWORD> open_candidate_window_ids_; |
- |
- // The cookie for |ui_source_|. |
- DWORD ui_source_cookie_; |
- |
- TSFEventRouter* router_; |
- gfx::Range previous_composition_range_; |
- |
- DISALLOW_COPY_AND_ASSIGN(Delegate); |
-}; |
- |
-TSFEventRouter::Delegate::Delegate() |
- : context_source_cookie_(TF_INVALID_COOKIE), |
- ui_source_cookie_(TF_INVALID_COOKIE), |
- router_(NULL), |
- previous_composition_range_(gfx::Range::InvalidRange()) { |
-} |
- |
-TSFEventRouter::Delegate::~Delegate() {} |
- |
-void TSFEventRouter::Delegate::SetRouter(TSFEventRouter* router) { |
- router_ = router; |
-} |
- |
-STDMETHODIMP TSFEventRouter::Delegate::OnEndEdit(ITfContext* context, |
- TfEditCookie read_only_cookie, |
- ITfEditRecord* edit_record) { |
- if (!edit_record || !context) |
- return E_INVALIDARG; |
- if (!router_) |
- return S_OK; |
- |
- // |edit_record| can be used to obtain updated ranges in terms of text |
- // contents and/or text attributes. Here we are interested only in text update |
- // so we use TF_GTP_INCL_TEXT and check if there is any range which contains |
- // updated text. |
- base::win::ScopedComPtr<IEnumTfRanges> ranges; |
- if (FAILED(edit_record->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, |
- ranges.Receive()))) |
- return S_OK; // Don't care about failures. |
- |
- ULONG fetched_count = 0; |
- base::win::ScopedComPtr<ITfRange> range; |
- if (FAILED(ranges->Next(1, range.Receive(), &fetched_count))) |
- return S_OK; // Don't care about failures. |
- |
- const gfx::Range composition_range = GetCompositionRange(context); |
- |
- if (!previous_composition_range_.IsValid() && composition_range.IsValid()) |
- router_->OnTSFStartComposition(); |
- |
- // |fetched_count| != 0 means there is at least one range that contains |
- // updated text. |
- if (fetched_count != 0) |
- router_->OnTextUpdated(composition_range); |
- |
- if (previous_composition_range_.IsValid() && !composition_range.IsValid()) |
- router_->OnTSFEndComposition(); |
- |
- previous_composition_range_ = composition_range; |
- return S_OK; |
-} |
- |
-STDMETHODIMP TSFEventRouter::Delegate::BeginUIElement(DWORD element_id, |
- BOOL* is_show) { |
- if (is_show) |
- *is_show = TRUE; // Without this the UI element will not be shown. |
- |
- if (!IsCandidateWindowInternal(element_id)) |
- return S_OK; |
- |
- std::pair<std::set<DWORD>::iterator, bool> insert_result = |
- open_candidate_window_ids_.insert(element_id); |
- // Don't call if |router_| is null or |element_id| is already handled. |
- if (router_ && insert_result.second) |
- router_->OnCandidateWindowCountChanged(open_candidate_window_ids_.size()); |
- |
- return S_OK; |
-} |
- |
-STDMETHODIMP TSFEventRouter::Delegate::UpdateUIElement( |
- DWORD element_id) { |
- return S_OK; |
-} |
- |
-STDMETHODIMP TSFEventRouter::Delegate::EndUIElement( |
- DWORD element_id) { |
- if ((open_candidate_window_ids_.erase(element_id) != 0) && router_) |
- router_->OnCandidateWindowCountChanged(open_candidate_window_ids_.size()); |
- return S_OK; |
-} |
- |
-void TSFEventRouter::Delegate::SetManager( |
- ITfThreadMgr* thread_manager) { |
- context_.Release(); |
- |
- if (context_source_) { |
- context_source_->UnadviseSink(context_source_cookie_); |
- context_source_.Release(); |
- } |
- context_source_cookie_ = TF_INVALID_COOKIE; |
- |
- ui_element_manager_.Release(); |
- if (ui_source_) { |
- ui_source_->UnadviseSink(ui_source_cookie_); |
- ui_source_.Release(); |
- } |
- ui_source_cookie_ = TF_INVALID_COOKIE; |
- |
- if (!thread_manager) |
- return; |
- |
- base::win::ScopedComPtr<ITfDocumentMgr> document_manager; |
- if (FAILED(thread_manager->GetFocus(document_manager.Receive())) || |
- !document_manager.get() || |
- FAILED(document_manager->GetBase(context_.Receive())) || |
- FAILED(context_source_.QueryFrom(context_))) |
- return; |
- context_source_->AdviseSink(IID_ITfTextEditSink, |
- static_cast<ITfTextEditSink*>(this), |
- &context_source_cookie_); |
- |
- if (FAILED(ui_element_manager_.QueryFrom(thread_manager)) || |
- FAILED(ui_source_.QueryFrom(ui_element_manager_))) |
- return; |
- ui_source_->AdviseSink(IID_ITfUIElementSink, |
- static_cast<ITfUIElementSink*>(this), |
- &ui_source_cookie_); |
-} |
- |
-bool TSFEventRouter::Delegate::IsImeComposing() { |
- return context_ && GetCompositionRange(context_).IsValid(); |
-} |
- |
-// static |
-gfx::Range TSFEventRouter::Delegate::GetCompositionRange( |
- ITfContext* context) { |
- DCHECK(context); |
- base::win::ScopedComPtr<ITfContextComposition> context_composition; |
- if (FAILED(context_composition.QueryFrom(context))) |
- return gfx::Range::InvalidRange(); |
- base::win::ScopedComPtr<IEnumITfCompositionView> enum_composition_view; |
- if (FAILED(context_composition->EnumCompositions( |
- enum_composition_view.Receive()))) |
- return gfx::Range::InvalidRange(); |
- base::win::ScopedComPtr<ITfCompositionView> composition_view; |
- if (enum_composition_view->Next(1, composition_view.Receive(), |
- NULL) != S_OK) |
- return gfx::Range::InvalidRange(); |
- |
- base::win::ScopedComPtr<ITfRange> range; |
- if (FAILED(composition_view->GetRange(range.Receive()))) |
- return gfx::Range::InvalidRange(); |
- |
- base::win::ScopedComPtr<ITfRangeACP> range_acp; |
- if (FAILED(range_acp.QueryFrom(range))) |
- return gfx::Range::InvalidRange(); |
- |
- LONG start = 0; |
- LONG length = 0; |
- if (FAILED(range_acp->GetExtent(&start, &length))) |
- return gfx::Range::InvalidRange(); |
- |
- return gfx::Range(start, start + length); |
-} |
- |
-bool TSFEventRouter::Delegate::IsCandidateWindowInternal(DWORD element_id) { |
- DCHECK(ui_element_manager_.get()); |
- base::win::ScopedComPtr<ITfUIElement> ui_element; |
- if (FAILED(ui_element_manager_->GetUIElement(element_id, |
- ui_element.Receive()))) |
- return false; |
- base::win::ScopedComPtr<ITfCandidateListUIElement> candidate_list_ui_element; |
- return SUCCEEDED(candidate_list_ui_element.QueryFrom(ui_element)); |
-} |
- |
- |
-// TSFEventRouter ------------------------------------------------------------ |
- |
-TSFEventRouter::TSFEventRouter(TSFEventRouterObserver* observer) |
- : observer_(observer), |
- delegate_(NULL) { |
- DCHECK(base::win::IsTSFAwareRequired()) |
- << "Do not use TSFEventRouter without TSF environment."; |
- DCHECK(observer_); |
- CComObject<Delegate>* delegate; |
- ui::win::CreateATLModuleIfNeeded(); |
- if (SUCCEEDED(CComObject<Delegate>::CreateInstance(&delegate))) { |
- delegate->AddRef(); |
- delegate_.Attach(delegate); |
- delegate_->SetRouter(this); |
- } |
-} |
- |
-TSFEventRouter::~TSFEventRouter() { |
- if (delegate_) { |
- delegate_->SetManager(NULL); |
- delegate_->SetRouter(NULL); |
- } |
-} |
- |
-bool TSFEventRouter::IsImeComposing() { |
- return delegate_->IsImeComposing(); |
-} |
- |
-void TSFEventRouter::OnCandidateWindowCountChanged(size_t window_count) { |
- observer_->OnCandidateWindowCountChanged(window_count); |
-} |
- |
-void TSFEventRouter::OnTSFStartComposition() { |
- observer_->OnTSFStartComposition(); |
-} |
- |
-void TSFEventRouter::OnTextUpdated(const gfx::Range& composition_range) { |
- observer_->OnTextUpdated(composition_range); |
-} |
- |
-void TSFEventRouter::OnTSFEndComposition() { |
- observer_->OnTSFEndComposition(); |
-} |
- |
-void TSFEventRouter::SetManager(ITfThreadMgr* thread_manager) { |
- delegate_->SetManager(thread_manager); |
-} |
- |
-} // namespace ui |