// // rprop.h // #ifndef RPROP_H #define RPROP_H #include "private.h" #include "strary.h" #include "spans.h" #include "tfprop.h" #include "ptrary.h" // for dwPropFlags of CProperty and CGeneralPropStore #define PROPF_ACCEPTCORRECTION 0x00000001 #define PROPF_VTI4TOGUIDATOM 0x00000002 #define PROPF_MARKUP_COLLECTION 0x00000004 // property is member of a display attr markup collection class CRange; class CEnumProperties; class CPropertyLoad { public: CPropertyLoad() {} ~CPropertyLoad() { SafeRelease(_pLoader); SafeRelease(_hdr.paStart); SafeRelease(_hdr.paEnd); } BOOL _Init(const TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *phdr, ITfPersistentPropertyLoaderAnchor *pLoader) { _hdr = *phdr; _hdr.paStart = NULL; _hdr.paEnd = NULL; Assert(_pLoader == NULL); if (phdr->paStart->Clone(&_hdr.paStart) != S_OK) { _hdr.paStart = NULL; return FALSE; } if (phdr->paEnd->Clone(&_hdr.paEnd) != S_OK) { _hdr.paEnd = NULL; return FALSE; } _pLoader = pLoader; _pLoader->AddRef(); return TRUE; } TF_PERSISTENT_PROPERTY_HEADER_ANCHOR _hdr; ITfPersistentPropertyLoaderAnchor *_pLoader; }; typedef struct tag_PROPERTYLIST { IAnchor *_paStart; IAnchor *_paEnd; ITfPropertyStore *_pPropStore; CPropertyLoad *_pPropLoad; } PROPERTYLIST; const DWORD PROPA_NONE = 0; const DWORD PROPA_TEXTOWNER = 1; const DWORD PROPA_FOCUSRANGE = 2; const DWORD PROPA_READONLY = 4; const DWORD PROPA_WONT_SERIALZE = 8; // // Property Styles // typedef enum { TFPROPSTYLE_NULL = 0x0, TFPROPSTYLE_STATIC = 0x1, TFPROPSTYLE_STATICCOMPACT = 0x2, TFPROPSTYLE_CUSTOM = 0x3, TFPROPSTYLE_CUSTOM_COMPACT = 0x4 } TFPROPERTYSTYLE; class CInputContext; class CPropertySub; // nb: if anything else derived from ITfProperty ever supports // Unserialize, we'll need to have a shared abstract base class // to that privately exposed the Unserialize method (or something // equivalent...) extern const IID IID_PRIV_CPROPERTY; class CProperty : public ITfProperty2, public CComObjectRootImmx { public: CProperty(CInputContext *pic, REFGUID guidProp, TFPROPERTYSTYLE propStyle, DWORD dwAuthority, DWORD dwPropFlags); ~CProperty(); BEGIN_COM_MAP_IMMX(CProperty) COM_INTERFACE_ENTRY_IID(IID_PRIV_CPROPERTY, CProperty) COM_INTERFACE_ENTRY(ITfReadOnlyProperty) COM_INTERFACE_ENTRY(ITfProperty) COM_INTERFACE_ENTRY(ITfProperty2) END_COM_MAP_IMMX() IMMX_OBJECT_IUNKNOWN_FOR_ATL() // ITfProperty2 STDMETHODIMP EnumRanges(TfEditCookie ec, IEnumTfRanges **ppv, ITfRange *pTargetRange); STDMETHODIMP FindRange(TfEditCookie ec, ITfRange *pRange, ITfRange **ppv, TfAnchor aPos); STDMETHODIMP GetValue(TfEditCookie ec, ITfRange *pRange, VARIANT *pvarValue); STDMETHODIMP SetValueStore(TfEditCookie ec, ITfRange *pRange, ITfPropertyStore *pPropStore); STDMETHODIMP SetValue(TfEditCookie ec, ITfRange *pRange, const VARIANT *pvarValue); STDMETHODIMP Clear(TfEditCookie ec, ITfRange *pRange); STDMETHODIMP GetContext(ITfContext **ppContext); STDMETHODIMP FindNextValue(TfEditCookie ec, ITfRange *pRangeQuery, TfAnchor tfAnchorQuery, DWORD dwFlags, BOOL *pfContained, ITfRange **ppRangeNextValue); // // ITfPropertyCommon // STDMETHODIMP GetType(GUID *pType); STDMETHODIMP GetStyle(TFPROPERTYSTYLE *propStyle); // ITfSource STDMETHODIMP AdviseSink(REFIID refiid, IUnknown *punk, DWORD *pdwCookie); STDMETHODIMP UnadviseSink(DWORD dwCookie); HRESULT ForceLoad(); void Clear(IAnchor *paStart, IAnchor *paEnd, DWORD dwFlags, BOOL fTextUpdate); HRESULT SetLoader(IAnchor *paStart, IAnchor *paEnd, CPropertyLoad *pPropLoad); TFPROPERTYSTYLE GetPropStyle() {return _propStyle;} BOOL Defrag(IAnchor *paStart, IAnchor *paEnd); TfGuidAtom GetPropGuidAtom() {return _guidatom;} CProperty *_pNext; CInputContext *_pic; TFPROPERTYSTYLE _propStyle; int GetPropNum() { return _rgProp.Count(); } PROPERTYLIST * GetFirstPropList() { if (_rgProp.Count()) return _rgProp.Get(0); return NULL; } PROPERTYLIST * GetLastPropList() { int nCnt; if (nCnt = _rgProp.Count()) return _rgProp.Get(nCnt - 1); return NULL; } PROPERTYLIST *QuickGetPropList(int iIndex) { return _rgProp.Get(iIndex); } PROPERTYLIST * GetPropList(int nCnt) { if (nCnt < 0) return NULL; return _rgProp.Get(nCnt); } PROPERTYLIST *SafeGetPropList(int nCur) { int nCnt = _rgProp.Count(); if (nCur >= nCnt) { return NULL; } else if (nCur > 0) { return _rgProp.Get(nCur); } else { return _rgProp.Get(0); } } // return the property list, or NULL if the data cannot be loaded PROPERTYLIST *QuickGetAndLoadPropList(int iIndex) { PROPERTYLIST *pPropList = _rgProp.Get(iIndex); if (pPropList->_pPropStore != NULL) return pPropList; LoadData(pPropList); return (pPropList->_pPropStore != NULL) ? pPropList : NULL; } PROPERTYLIST *Find(IAnchor *pa, LONG *piOut, BOOL fEnd) { return _FindComplex(pa, piOut, fEnd, FALSE /* fTextUpdate */); } PROPERTYLIST *FindPropertyListByPos(IAnchor *paPos, BOOL fEnd); HRESULT LoadData(PROPERTYLIST *pPropList); DWORD GetValidation() {return _dwAuthority;} HRESULT _SetDataInternal(TfEditCookie ec, IAnchor *paStart, IAnchor *paEnd, const VARIANT *pvarValue); HRESULT _ClearInternal(TfEditCookie ec, IAnchor *paStart, IAnchor *paEnd); HRESULT _Serialize(CRange *pRange, TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr, IStream *pStream); HRESULT _Unserialize(const TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr, IStream *pStream, ITfPersistentPropertyLoaderAnchor *pLoader); HRESULT _InternalFindRange(CRange *pRange, CRange **ppv, TfAnchor aPos, BOOL fEnd); PROPERTYLIST *_FindPropList(IAnchor *paStart, IAnchor *paEnd); PROPERTYLIST *_FindPropListAndDivide(IAnchor *paStart, IAnchor *paEnd); HRESULT _SetStoreInternal(TfEditCookie ec, CRange *pRange, ITfPropertyStore *pPropStore, BOOL fInternal); CSpanSet *_GetSpanSet() { return _pss; } void _ClearSpanSet() { _pss = NULL; } void _ResetSpanSet() { _pss->Reset(); } HRESULT _GetDataInternal(IAnchor *paStart, IAnchor *paEnd, VARIANT *pvarValue); #ifdef DEBUG void _Dbg_AssertNoChangeHistory(); GUID _dbg_guid; #else void _Dbg_AssertNoChangeHistory() {} #endif // DEBUG private: PROPERTYLIST *_FindComplex(IAnchor *pa, LONG *piOut, BOOL fEnd, BOOL fTextUpdate); PROPERTYLIST *_FindUpdateTouchup(IAnchor *pa, int *piMid, BOOL fEnd); void _ClearOneSpan(IAnchor *paStart, IAnchor *paEnd, int iIndex, BOOL fStartMatchesSpanEnd, BOOL fEndMatchesSpanStart, DWORD dwFlags, BOOL fTextUpdate); BOOL _OnTextUpdate(DWORD dwFlags, PROPERTYLIST *pPropertyList, IAnchor *paStart, IAnchor *paEnd); void _MovePropertySpans(int iDst, int iSrc, int iCount); BOOL _ClearFirstLastSpan(BOOL fFirst, BOOL fMatchesSpanEdge, IAnchor *paStart, IAnchor *paEnd, PROPERTYLIST *pPropertyList, DWORD dwFlags, BOOL fTextUpdate, BOOL *pfSkipNextOnTextUpdate); void _ClearChangeHistory(PROPERTYLIST *prop, DWORD *pdwStartHistory, DWORD *pdwEndHistory); HRESULT Set(IAnchor *paStart, IAnchor *paEnd, ITfPropertyStore *pPropStore); CSpanSet *_CreateSpanSet() { if (_pss == NULL) { _pss = new CSpanSet; } return _pss; } BOOL _IsValidEditCookie(TfEditCookie ec, DWORD dwFlags); PROPERTYLIST *_CreateNewProp(IAnchor *paStart, IAnchor *paEnd, ITfPropertyStore *pPropStore, CPropertyLoad *pPropLoad); void _FreePropertyList(PROPERTYLIST *pProp); HRESULT _SetNewExtent(PROPERTYLIST *pProp, IAnchor *paStart, IAnchor *paEnd, BOOL fNew); HRESULT _Divide(PROPERTYLIST *pProp, IAnchor *paBreakPtStart, IAnchor *paBreakPtEnd, ITfPropertyStore **ppStore); void _RemoveProp(LONG iIndex, PROPERTYLIST *pProp); BOOL _InsertPropList(IAnchor *paStart, IAnchor *paEnd, ITfPropertyStore *pPropStore, CPropertyLoad *pPropLoad); BOOL _AddIntoProp(int nCur, IAnchor *paStart, IAnchor *paEnd, ITfPropertyStore *pPropStore); void _DefragAfterThis(int nCur); HRESULT _SetPropertyLoaderInternal(TfEditCookie ec, CRange *pRange, CPropertyLoad *pPropLoad); HRESULT _GetPropStoreFromStream(const TF_PERSISTENT_PROPERTY_HEADER_ANCHOR *pHdr, IStream *pStream, CRange *pRange, ITfPropertyStore **ppStore); HRESULT _CheckValidation(TfEditCookie ec, CRange *pRange); HRESULT _CheckOwner(TfClientId tid, IAnchor *paStart, IAnchor *paEnd); TfGuidAtom _guidatom; CPtrArray _rgProp; // // if we use CSpanSet to record the deltas. // void PropertyUpdated(IAnchor *paStart, IAnchor *paEnd); CSpanSet *_pss; DWORD _dwCookie; DWORD _dwAuthority; DWORD _dwPropFlags; #ifdef DEBUG void _Dbg_AssertProp(); #else void _Dbg_AssertProp() {} #endif DBG_ID_DECLARE; }; inline CProperty *GetCProperty(IUnknown *pProp) { CProperty *pPropP; pProp->QueryInterface(IID_PRIV_CPROPERTY, (void **)&pPropP); return pPropP; } #endif // RPROP_H