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.
 
 
 
 
 
 

379 lines
9.6 KiB

//
// 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);
}