-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTextEditSink.cpp
More file actions
151 lines (127 loc) · 4.47 KB
/
Copy pathTextEditSink.cpp
File metadata and controls
151 lines (127 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//////////////////////////////////////////////////////////////////////
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 2003 Microsoft Corporation. All rights reserved.
//
// TextEditSink.cpp
//
// ITfTextEditSink implementation.
//
//////////////////////////////////////////////////////////////////////
#include "globals.h"
#include "TextService.h"
BOOL IsRangeCovered(TfEditCookie ec, ITfRange *pRangeTest, ITfRange *pRangeCover);
//+---------------------------------------------------------------------------
//
// OnEndEdit
//
// Called by the system whenever anyone releases a write-access document lock.
//----------------------------------------------------------------------------
STDAPI CTextService::OnEndEdit(ITfContext *pContext, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
{
BOOL fSelectionChanged;
IEnumTfRanges *pEnumTextChanges;
ITfRange *pRange;
BOOL fHasTextChanges = FALSE;
if (_pendingInternalEdits > 0)
{
--_pendingInternalEdits;
return S_OK;
}
if (pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, &pEnumTextChanges) == S_OK)
{
if (pEnumTextChanges->Next(1, &pRange, NULL) == S_OK)
{
fHasTextChanges = TRUE;
pRange->Release();
}
pEnumTextChanges->Release();
}
//
// did the selection change?
// The selection change includes the movement of caret as well.
// The caret position is represent as the empty selection range when
// there is no selection.
//
if (pEditRecord->GetSelectionStatus(&fSelectionChanged) == S_OK &&
fSelectionChanged)
{
// If the selection is moved to out side of the current composition,
// we terminate the composition. This TextService supports only one
// composition in one context object.
if (_IsComposing())
{
TF_SELECTION tfSelection;
ULONG cFetched;
if (pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) == S_OK && cFetched == 1)
{
ITfRange *pRangeComposition;
// is the insertion point covered by a composition?
if (_pComposition->GetRange(&pRangeComposition) == S_OK)
{
if (!IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition) &&
!fHasTextChanges)
{
_EndComposition(pContext);
}
pRangeComposition->Release();
}
}
}
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InitTextEditSink
//
// Init a text edit sink on the topmost context of the document.
// Always release any previous sink.
//----------------------------------------------------------------------------
BOOL CTextService::_InitTextEditSink(ITfDocumentMgr *pDocMgr)
{
ITfSource *pSource;
BOOL fRet;
// clear out any previous sink first
if (_dwTextEditSinkCookie != TF_INVALID_COOKIE)
{
if (_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK)
{
pSource->UnadviseSink(_dwTextEditSinkCookie);
pSource->Release();
}
_pTextEditSinkContext->Release();
_pTextEditSinkContext = NULL;
_dwTextEditSinkCookie = TF_INVALID_COOKIE;
}
if (pDocMgr == NULL)
return TRUE; // caller just wanted to clear the previous sink
// setup a new sink advised to the topmost context of the document
if (pDocMgr->GetTop(&_pTextEditSinkContext) != S_OK)
return FALSE;
if (_pTextEditSinkContext == NULL)
return TRUE; // empty document, no sink possible
fRet = FALSE;
if (_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK)
{
if (pSource->AdviseSink(IID_ITfTextEditSink, (ITfTextEditSink *)this, &_dwTextEditSinkCookie) == S_OK)
{
fRet = TRUE;
}
else
{
_dwTextEditSinkCookie = TF_INVALID_COOKIE;
}
pSource->Release();
}
if (fRet == FALSE)
{
_pTextEditSinkContext->Release();
_pTextEditSinkContext = NULL;
}
return fRet;
}