|
|
//
// rprange.cpp
//
#include "private.h"
#include "ic.h"
#include "rprop.h"
#include "range.h"
#include "tim.h"
#include "rngsink.h"
#include "immxutil.h"
//+---------------------------------------------------------------------------
//
// GetData
//
//----------------------------------------------------------------------------
HRESULT CProperty::_GetDataInternal(IAnchor *paStart, IAnchor *paEnd, VARIANT *pvarValue) { HRESULT hr; PROPERTYLIST *pPropList;
if (pvarValue == NULL) return E_INVALIDARG;
QuickVariantInit(pvarValue);
pPropList = _FindPropList(paStart, paEnd);
if (pPropList) { if (!pPropList->_pPropStore) { if (FAILED(hr = LoadData(pPropList))) goto Exit; }
hr = pPropList->_pPropStore->GetData(pvarValue); } else { // property has no value over the range
hr = S_FALSE; }
Exit: return hr; }
//+---------------------------------------------------------------------------
//
// _SetStoreInternal
//
//----------------------------------------------------------------------------
HRESULT CProperty::_SetStoreInternal(TfEditCookie ec, CRange *pRange, ITfPropertyStore *pPropStore, BOOL fInternal) { GUID guidStore;
if (pPropStore == NULL) return E_INVALIDARG;
if (!fInternal) { //
// Make sure this property is not using System's StaticPropStore.
//
if (GetPropStyle() != TFPROPSTYLE_CUSTOM && GetPropStyle() != TFPROPSTYLE_CUSTOM_COMPACT) return E_FAIL; }
if (IsEqualAnchor(pRange->_GetStart(), pRange->_GetEnd())) return E_INVALIDARG;
//
// Check type of PropertyStore.
//
if (FAILED(pPropStore->GetType(&guidStore))) return E_FAIL;
if (!MyIsEqualTfGuidAtom(GetPropGuidAtom(), guidStore)) return E_FAIL;
return Set(pRange->_GetStart(), pRange->_GetEnd(), pPropStore); }
//+---------------------------------------------------------------------------
//
// _SetDataInternal
//
//----------------------------------------------------------------------------
HRESULT CProperty::_SetDataInternal(TfEditCookie ec, IAnchor *paStart, IAnchor *paEnd, const VARIANT *pvarValue) { CGeneralPropStore *store; HRESULT hr;
Assert(!IsEqualAnchor(paStart, paEnd)); // caller should have checked
switch (GetPropStyle()) { case TFPROPSTYLE_STATIC: case TFPROPSTYLE_STATICCOMPACT: if ((store = new CStaticPropStore) == NULL) return E_OUTOFMEMORY;
break;
case TFPROPSTYLE_CUSTOM: case TFPROPSTYLE_CUSTOM_COMPACT: //
// This property is not using System's StaticPropStore.
// so we use a default range property sink.
//
if ((store = new CGeneralPropStore) == NULL) return E_OUTOFMEMORY;
break;
default: Assert(0); // bogus style!
return E_UNEXPECTED; }
if (!store->_Init(GetPropGuidAtom(), pvarValue, _dwPropFlags)) { store->Release(); return E_FAIL; }
hr = Set(paStart, paEnd, store); store->Release();
return hr; }
//+---------------------------------------------------------------------------
//
// ClearInternal
//
//----------------------------------------------------------------------------
HRESULT CProperty::_ClearInternal(TfEditCookie ec, IAnchor *paStart, IAnchor *paEnd) { PROPERTYLIST *pPropertyList; LONG nCur;
if (paStart != NULL) { Assert(paEnd != NULL);
if (IsEqualAnchor(paStart, paEnd)) return S_OK;
Clear(paStart, paEnd, 0, FALSE);
Find(paStart, &nCur, FALSE); if (nCur >= 0) _DefragAfterThis(nCur); } else { // Clear(NULL, NULL) means wipe all instances
for (nCur=0; nCur<_rgProp.Count(); nCur++) { pPropertyList = _rgProp.Get(nCur);
if (CompareAnchors(pPropertyList->_paStart, pPropertyList->_paEnd) <= 0) { PropertyUpdated(pPropertyList->_paStart, pPropertyList->_paEnd); } else { // crossed anchors
PropertyUpdated(pPropertyList->_paEnd, pPropertyList->_paEnd); } _FreePropertyList(pPropertyList); } _rgProp.Clear(); }
return S_OK; }
//+---------------------------------------------------------------------------
//
// _FindPropList
//
//----------------------------------------------------------------------------
PROPERTYLIST *CProperty::_FindPropList(IAnchor *paStart, IAnchor *paEnd) { PROPERTYLIST *pPropList; LONG nCur;
if (CompareAnchors(paStart, paEnd) == 0) return NULL;
//
// The range does not have to be exactly matched.
// we can return pPropList covers the given range.
//
Find(paStart, &nCur, FALSE); if (nCur < 0) return NULL;
pPropList = SafeGetPropList(nCur); if (!pPropList) { Assert(0); return NULL; }
Assert(CompareAnchors(paStart, pPropList->_paStart) >= 0); if (CompareAnchors(paEnd, pPropList->_paEnd) <= 0) return pPropList;
return NULL; }
//+---------------------------------------------------------------------------
//
// _FindPropListAndDivide
//
//----------------------------------------------------------------------------
PROPERTYLIST *CProperty::_FindPropListAndDivide(IAnchor *paStart, IAnchor *paEnd) { PROPERTYLIST *pPropList = NULL; LONG nCur; ITfPropertyStore *pNewPropStore; IAnchor *paTmp = NULL; BOOL fExactMatch; HRESULT hr;
if (CompareAnchors(paStart, paEnd) == 0) return NULL;
fExactMatch = (Find(paStart, &nCur, FALSE) != NULL); if (nCur < 0) goto Exit;
pPropList = SafeGetPropList(nCur); if (!pPropList) { Assert(0); goto Exit; }
if (_propStyle == TFPROPSTYLE_STATICCOMPACT || _propStyle == TFPROPSTYLE_CUSTOM_COMPACT) { Assert(CompareAnchors(paStart, pPropList->_paStart) >= 0); if (CompareAnchors(paEnd, pPropList->_paEnd) <= 0) return pPropList;
pPropList = NULL; goto Exit; }
if (!fExactMatch) { if (CompareAnchors(paStart, pPropList->_paEnd) >= 0) { // query span begins at or after pPropList end-of-span
// is there a following property?
if ((pPropList = SafeGetPropList(nCur+1)) == NULL) goto Exit; // there is, does the query span cover it?
if (CompareAnchors(paEnd, pPropList->_paStart) <= 0) { pPropList = NULL; goto Exit; // nope
}
// okay, our left edge will be the start of the following property
} else { Assert(CompareAnchors(paStart, pPropList->_paStart) > 0);
pNewPropStore = NULL; hr = pPropList->_paEnd->Clone(&paTmp); if (FAILED(hr) || !paTmp) { pPropList = NULL; goto Exit; }
hr = _Divide(pPropList, paStart, paStart, &pNewPropStore); if ((hr == S_OK) && pNewPropStore) { _CreateNewProp(paStart, paTmp, pNewPropStore, NULL);
pNewPropStore->Release(); } else { pPropList = NULL; goto Exit; }
pPropList = Find(paStart, NULL, FALSE); if (!pPropList) { Assert(0); goto Exit; } } } Assert(CompareAnchors(paStart, pPropList->_paStart) == 0);
SafeReleaseClear(paTmp);
if (CompareAnchors(paEnd, pPropList->_paEnd) < 0) { pNewPropStore = NULL; hr = pPropList->_paEnd->Clone(&paTmp); if (FAILED(hr) || !paTmp) { pPropList = NULL; goto Exit; }
hr = _Divide(pPropList, paEnd, paEnd, &pNewPropStore); if ((hr == S_OK) && pNewPropStore) { _CreateNewProp(paEnd, paTmp, pNewPropStore, NULL);
pNewPropStore->Release(); } else { pPropList = NULL; goto Exit; }
pPropList = Find(paStart, NULL, FALSE); if (!pPropList) { Assert(0); goto Exit; } }
Assert(CompareAnchors(paStart, pPropList->_paStart) == 0); Assert(CompareAnchors(paEnd, pPropList->_paEnd) == 0);
Exit: SafeRelease(paTmp); return pPropList; }
//+---------------------------------------------------------------------------
//
// SetPropertyLoader
//
//----------------------------------------------------------------------------
HRESULT CProperty::_SetPropertyLoaderInternal(TfEditCookie ec, CRange *pRange, CPropertyLoad *pPropLoad) { if (IsEqualAnchor(pRange->_GetStart(), pRange->_GetEnd())) return S_OK;
return SetLoader(pRange->_GetStart(), pRange->_GetEnd(), pPropLoad); }
|