Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.5 KiB

  1. //
  2. // editsink.cpp
  3. //
  4. // ITfTextEditSink implementation.
  5. //
  6. #include "globals.h"
  7. #include "mark.h"
  8. //+---------------------------------------------------------------------------
  9. //
  10. // OnEndEdit
  11. //
  12. // Called by the system whenever anyone releases a write-access document lock.
  13. //----------------------------------------------------------------------------
  14. STDAPI CMarkTextService::OnEndEdit(ITfContext *pContext, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
  15. {
  16. ITfRange *pRangeComposition;
  17. IEnumTfRanges *pEnumRanges;
  18. ITfRange *pRange;
  19. ITfContext *pCompositionContext;
  20. TF_SELECTION tfSelection;
  21. BOOL fResult;
  22. BOOL fCancelComposition;
  23. ULONG cFetched;
  24. if (_pComposition == NULL)
  25. return S_OK;
  26. // are we responsible for the edit?
  27. if (pContext->InWriteSession(_tfClientId, &fResult) == S_OK && fResult)
  28. return S_OK;
  29. // is this the context our composition lives in?
  30. if (_pComposition->GetRange(&pRangeComposition) != S_OK)
  31. return S_OK;
  32. if (pRangeComposition->GetContext(&pCompositionContext) != S_OK)
  33. goto Exit;
  34. fResult = IsEqualUnknown(pCompositionContext, pContext);
  35. pCompositionContext->Release();
  36. if (!fResult)
  37. goto Exit; // different context
  38. fCancelComposition = FALSE;
  39. // we're composing in this context, cancel the composition if anything suspicious happened
  40. // did the selection move outside the composition?
  41. if (pEditRecord->GetSelectionStatus(&fResult) == S_OK && fResult)
  42. {
  43. if (pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) == S_OK &&
  44. cFetched == 1)
  45. {
  46. if (_pComposition->GetRange(&pRangeComposition) == S_OK)
  47. {
  48. fResult = IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition);
  49. pRangeComposition->Release();
  50. if (!fResult)
  51. {
  52. fCancelComposition = TRUE;
  53. }
  54. }
  55. tfSelection.range->Release();
  56. }
  57. }
  58. if (fCancelComposition)
  59. goto CancelComposition;
  60. // did someone else edit the document text?
  61. if (pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, &pEnumRanges) == S_OK)
  62. {
  63. // is the enumerator empty?
  64. if (pEnumRanges->Next(1, &pRange, NULL) == S_OK)
  65. {
  66. pRange->Release();
  67. fCancelComposition = TRUE;
  68. }
  69. pEnumRanges->Release();
  70. }
  71. if (fCancelComposition)
  72. {
  73. CancelComposition:
  74. // we need a write edit session to cancel the composition
  75. _TerminateCompositionInContext(pContext);
  76. }
  77. Exit:
  78. pRangeComposition->Release();
  79. return S_OK;
  80. }
  81. //+---------------------------------------------------------------------------
  82. //
  83. // _InitTextEditSink
  84. //
  85. // Init a text edit sink on the topmost context of the document.
  86. // Always release any previous sink.
  87. //----------------------------------------------------------------------------
  88. BOOL CMarkTextService::_InitTextEditSink(ITfDocumentMgr *pDocMgr)
  89. {
  90. ITfSource *pSource;
  91. BOOL fRet;
  92. // clear out any previous sink first
  93. if (_dwTextEditSinkCookie != TF_INVALID_COOKIE)
  94. {
  95. if (_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK)
  96. {
  97. pSource->UnadviseSink(_dwTextEditSinkCookie);
  98. pSource->Release();
  99. }
  100. _pTextEditSinkContext->Release();
  101. _pTextEditSinkContext = NULL;
  102. _dwTextEditSinkCookie = TF_INVALID_COOKIE;
  103. }
  104. if (pDocMgr == NULL)
  105. return TRUE; // caller just wanted to clear the previous sink
  106. // setup a new sink advised to the topmost context of the document
  107. if (pDocMgr->GetTop(&_pTextEditSinkContext) != S_OK)
  108. return FALSE;
  109. if (_pTextEditSinkContext == NULL)
  110. return TRUE; // empty document, no sink possible
  111. fRet = FALSE;
  112. if (_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK)
  113. {
  114. if (pSource->AdviseSink(IID_ITfTextEditSink, (ITfTextEditSink *)this, &_dwTextEditSinkCookie) == S_OK)
  115. {
  116. fRet = TRUE;
  117. }
  118. else
  119. {
  120. _dwTextEditSinkCookie = TF_INVALID_COOKIE;
  121. }
  122. pSource->Release();
  123. }
  124. if (fRet == FALSE)
  125. {
  126. _pTextEditSinkContext->Release();
  127. _pTextEditSinkContext = NULL;
  128. }
  129. return fRet;
  130. }