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.

225 lines
7.7 KiB

  1. //
  2. // range.h
  3. //
  4. #ifndef RANGE_H
  5. #define RANGE_H
  6. #include "private.h"
  7. #include "anchor.h"
  8. #include "sink.h"
  9. #include "ic.h"
  10. #define IGNORE_LAST_LOCKRELEASED 0xffffffff
  11. class CInputContext;
  12. class CEnumOwnedRanges;
  13. extern const IID IID_PRIV_CRANGE;
  14. inline TfGravity DCGToIMG(TsGravity dcg) { return dcg == TS_GR_FORWARD ? TF_GRAVITY_FORWARD : TF_GRAVITY_BACKWARD; }
  15. typedef enum { RINIT_DEF_GRAVITY, RINIT_GRAVITY, RINIT_NO_GRAVITY } RInit;
  16. class CRange : public ITfRangeACP,
  17. public ITfRangeAnchor,
  18. public ITfSource
  19. {
  20. public:
  21. // work around for new #define in mem.h
  22. #undef new
  23. DECLARE_CACHED_NEW;
  24. // retore mem.h trick
  25. #ifdef DEBUG
  26. #define new new(TEXT(__FILE__), __LINE__)
  27. #endif // DEBUG
  28. CRange()
  29. {
  30. Dbg_MemSetThisNameIDCounter(TEXT("CRange"), PERF_RANGE_COUNTER);
  31. _cRef = 1;
  32. }
  33. ~CRange();
  34. // NB: caller must be certain that paStart <= paEnd before calling _InitWithDefaultGravity!
  35. BOOL _InitWithDefaultGravity(CInputContext *pic, AnchorOwnership ao, IAnchor *paStart, IAnchor *paEnd)
  36. {
  37. return _Init(pic, ao, paStart, paEnd, RINIT_DEF_GRAVITY);
  38. }
  39. BOOL _InitWithAnchorGravity(CInputContext *pic, AnchorOwnership ao, IAnchor *paStart, IAnchor *paEnd)
  40. {
  41. return _Init(pic, ao, paStart, paEnd, RINIT_GRAVITY);
  42. }
  43. static void _InitClass();
  44. static void _UninitClass();
  45. //
  46. // IUnknown methods
  47. //
  48. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
  49. STDMETHODIMP_(ULONG) AddRef(void);
  50. STDMETHODIMP_(ULONG) Release(void);
  51. // ITfRange
  52. STDMETHODIMP GetText(TfEditCookie ec, DWORD dwFlags, WCHAR *pchText, ULONG cchMax, ULONG *pcch);
  53. STDMETHODIMP SetText(TfEditCookie ec, DWORD dwFlags, const WCHAR *pchText, LONG cch);
  54. STDMETHODIMP GetFormattedText(TfEditCookie ec, IDataObject **ppDataObject);
  55. STDMETHODIMP GetEmbedded(TfEditCookie ec, REFGUID rguidService, REFIID riid, IUnknown **ppunk);
  56. STDMETHODIMP InsertEmbedded(TfEditCookie ec, DWORD dwFlags, IDataObject *pDataObject);
  57. STDMETHODIMP ShiftStart(TfEditCookie ec, LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt);
  58. STDMETHODIMP ShiftEnd(TfEditCookie ec, LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt);
  59. STDMETHODIMP ShiftStartToRange(TfEditCookie ec, ITfRange *pRange, TfAnchor aPos);
  60. STDMETHODIMP ShiftEndToRange(TfEditCookie ec, ITfRange *pRange, TfAnchor aPos);
  61. STDMETHODIMP ShiftStartRegion(TfEditCookie ec, TfShiftDir dir, BOOL *pfNoRegion);
  62. STDMETHODIMP ShiftEndRegion(TfEditCookie ec, TfShiftDir dir, BOOL *pfNoRegion);
  63. STDMETHODIMP IsEmpty(TfEditCookie ec, BOOL *pfEmpty);
  64. STDMETHODIMP Collapse(TfEditCookie ec, TfAnchor aPos);
  65. STDMETHODIMP IsEqualStart(TfEditCookie ec, ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual);
  66. STDMETHODIMP IsEqualEnd(TfEditCookie ec, ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual);
  67. STDMETHODIMP CompareStart(TfEditCookie ec, ITfRange *pWith, TfAnchor aPos, LONG *plResult);
  68. STDMETHODIMP CompareEnd(TfEditCookie ec, ITfRange *pWith, TfAnchor aPos, LONG *plResult);
  69. STDMETHODIMP AdjustForInsert(TfEditCookie ec, ULONG cchInsert, BOOL *pfInsertOk);
  70. STDMETHODIMP GetGravity(TfGravity *pgStart, TfGravity *pgEnd);
  71. STDMETHODIMP SetGravity(TfEditCookie ec, TfGravity gStart, TfGravity gEnd);
  72. STDMETHODIMP Clone(ITfRange **ppClone);
  73. STDMETHODIMP GetContext(ITfContext **ppContext);
  74. // ITfRangeACP
  75. STDMETHODIMP GetExtent(LONG *pacpAnchor, LONG *pcch);
  76. STDMETHODIMP SetExtent(LONG acpAnchor, LONG cch);
  77. // ITfRangeAnchor
  78. STDMETHODIMP GetExtent(IAnchor **ppaStart, IAnchor **ppaEnd);
  79. STDMETHODIMP SetExtent(IAnchor *paStart, IAnchor *paEnd);
  80. // ITfSource
  81. STDMETHODIMP AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie);
  82. STDMETHODIMP UnadviseSink(DWORD dwCookie);
  83. CRange *_Clone()
  84. {
  85. CRange *rangeClone;
  86. if ((rangeClone = new CRange) == NULL)
  87. return NULL;
  88. if (!rangeClone->_Init(_pic, COPY_ANCHORS, _paStart, _paEnd, RINIT_NO_GRAVITY))
  89. {
  90. rangeClone->Release();
  91. return NULL;
  92. }
  93. rangeClone->_dwLastLockReleaseID = _dwLastLockReleaseID;
  94. return rangeClone;
  95. }
  96. CRange *_GetNextOnChangeRangeInIcsub() { return _nextOnChangeRangeInIcsub; }
  97. IAnchor *_GetStart() { return _paStart; }
  98. IAnchor *_GetEnd() { return _paEnd; }
  99. CInputContext *_GetContext() { return _pic; }
  100. CStructArray<GENERICSINK> *_GetChangeSinks() { return _prgChangeSinks; }
  101. void _QuickCheckCrossedAnchors()
  102. {
  103. if (_dwLastLockReleaseID != IGNORE_LAST_LOCKRELEASED)
  104. {
  105. _CheckCrossedAnchors();
  106. }
  107. }
  108. #if 0
  109. HRESULT _SnapToRegion(DWORD dwFlags);
  110. #endif
  111. BOOL _IsDirty() { return _fDirty; }
  112. void _SetDirty() { _fDirty = TRUE; }
  113. void _ClearDirty() { _fDirty = FALSE; }
  114. private:
  115. BOOL _Init(CInputContext *pic, AnchorOwnership ao, IAnchor *paStart, IAnchor *paEnd, RInit rinit);
  116. HRESULT _SetGravity(TfGravity gStart, TfGravity gEnd, BOOL fCheckCrossedAnchors);
  117. void _CheckCrossedAnchors();
  118. HRESULT _PreEditCompositionCheck(TfEditCookie ec, CComposition **ppComposition, BOOL *pfNewComposition);
  119. HRESULT _ShiftConditional(IAnchor *paStart, IAnchor *paLimit, LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt);
  120. HRESULT _IsEqualX(TfEditCookie ec, TfAnchor aPosThisRange, ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual);
  121. HRESULT _CompareX(TfEditCookie ec, TfAnchor aPosThisRange, ITfRange *pWith, TfAnchor aPos, LONG *plResult);
  122. BOOL _IsValidEditCookie(TfEditCookie ec, DWORD dwFlags);
  123. void _InitLastLockReleaseId(TsGravity gStart, TsGravity gEnd)
  124. {
  125. if (gStart == TF_GRAVITY_FORWARD && gEnd == TF_GRAVITY_BACKWARD)
  126. {
  127. // this range has the potential for crossed anchors, need to monitor
  128. // since the range may have just been cloned from a crossed range, need to
  129. // init _dwLastLockReleaseID with something that will guarantee a check
  130. _dwLastLockReleaseID = _pic->_GetLastLockReleaseID() - 1;
  131. }
  132. else
  133. {
  134. // don't bother checking for crossed anchors, since it can't happen
  135. _dwLastLockReleaseID = IGNORE_LAST_LOCKRELEASED;
  136. }
  137. }
  138. CStructArray<GENERICSINK> *_prgChangeSinks; // ITfRangeChangeSink sinks
  139. IAnchor *_paStart;
  140. IAnchor *_paEnd;
  141. CInputContext *_pic;
  142. CRange *_nextOnChangeRangeInIcsub; // perf: could use an array in the pic to save space
  143. DWORD _dwLastLockReleaseID;
  144. BOOL _fDirty : 1;
  145. long _cRef;
  146. DBG_ID_DECLARE;
  147. };
  148. // this call doesn't AddRef the object!
  149. inline CRange *GetCRange_NA(IUnknown *range)
  150. {
  151. CRange *prange;
  152. range->QueryInterface(IID_PRIV_CRANGE, (void **)&prange);
  153. return prange;
  154. }
  155. // returns TRUE if range is in the same context
  156. inline BOOL VerifySameContext(CRange *pRange1, CRange *pRange2)
  157. {
  158. Assert((pRange1->_GetContext() == pRange2->_GetContext()));
  159. return (pRange1->_GetContext() == pRange2->_GetContext());
  160. }
  161. // returns TRUE if range is in the same context
  162. inline BOOL VerifySameContext(CInputContext *pContext, CRange *pRange)
  163. {
  164. Assert((pRange->_GetContext() == pContext));
  165. return (pRange->_GetContext() == pContext);
  166. }
  167. // returns TRUE if range is in the same context
  168. inline BOOL VerifySameContext(CInputContext *pContext, ITfRange *pTargetRange)
  169. {
  170. CRange *pRange = GetCRange_NA(pTargetRange);
  171. Assert((pRange != NULL) && (pRange->_GetContext() == pContext));
  172. return (pRange != NULL) && (pRange->_GetContext() == pContext);
  173. }
  174. #endif // RANGE_H