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.
317 lines
9.7 KiB
317 lines
9.7 KiB
//
|
|
// 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<PROPERTYLIST> _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
|