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.
 
 
 
 
 
 

501 lines
12 KiB

//
// perange.cpp
//
#include "private.h"
#include "helpers.h"
#include "ic.h"
#include "range.h"
#include "rangebk.h"
#include "rprop.h"
#include "immxutil.h"
//////////////////////////////////////////////////////////////////////////////
//
// CRangeBackup
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CRangeBackupProperty::CRangeBackupProperty(CRangeBackup *ppr, CProperty *pProp)
{
_ppr = ppr;
_pProp = pProp;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CRangeBackupProperty::~CRangeBackupProperty()
{
int i;
int nCnt = _rgPropRanges.Count();
for (i = 0; i < nCnt; i++)
{
PERSISTPROPERTYRANGE *pPropRange;
pPropRange = _rgPropRanges.GetPtr(i);
Assert(pPropRange);
Assert(pPropRange->_pPropStore);
pPropRange->_pPropStore->Release();
pPropRange->_pPropStore = NULL;
}
}
//+---------------------------------------------------------------------------
//
// Init
//
//----------------------------------------------------------------------------
BOOL CRangeBackupProperty::Init(TfEditCookie ec)
{
IEnumTfRanges *pEnum;
ITfRange *pRange;
HRESULT hr;
hr = _pProp->EnumRanges(ec, &pEnum, (ITfRangeAnchor *)_ppr->_pRange);
if (FAILED(hr) || !pEnum)
return FALSE;
while (pEnum->Next(1, &pRange, NULL) == S_OK)
{
CRange *pCRange;
pCRange = GetCRange_NA(pRange);
if (pCRange)
{
_StoreOneRange(ec, pCRange);
}
pRange->Release();
}
pEnum->Release();
return TRUE;
}
//+---------------------------------------------------------------------------
//
// StoreOneRange
//
//----------------------------------------------------------------------------
BOOL CRangeBackupProperty::_StoreOneRange(TfEditCookie ec, CRange *pCRange)
{
PROPERTYLIST *pPropList;
ULONG achStart = 0;
ULONG achEnd = 0;
if (CompareAnchors(pCRange->_GetStart(), _ppr->_pRange->_GetStart()) < 0)
{
if (CompareAnchors(pCRange->_GetEnd(), _ppr->_pRange->_GetEnd()) > 0)
{
pPropList = _pProp->_FindPropListAndDivide(_ppr->_pRange->_GetStart(), _ppr->_pRange->_GetEnd());
achStart = _GetOffset(ec, _ppr->_pRange->_GetStart());
achEnd = _GetOffset(ec, _ppr->_pRange->_GetEnd());
}
else
{
pPropList = _pProp->_FindPropListAndDivide(_ppr->_pRange->_GetStart(), pCRange->_GetEnd());
achStart = _GetOffset(ec, _ppr->_pRange->_GetStart());
achEnd = _GetOffset(ec, pCRange->_GetEnd());
}
}
else if (CompareAnchors(pCRange->_GetEnd(), _ppr->_pRange->_GetEnd()) > 0)
{
pPropList = _pProp->_FindPropListAndDivide(pCRange->_GetStart(), _ppr->_pRange->_GetEnd());
achStart = _GetOffset(ec, pCRange->_GetStart());
achEnd = _GetOffset(ec, _ppr->_pRange->_GetEnd());
}
else
{
pPropList = _pProp->_FindPropListAndDivide(pCRange->_GetStart(), pCRange->_GetEnd());
achStart = _GetOffset(ec, pCRange->_GetStart());
achEnd = _GetOffset(ec, pCRange->_GetEnd());
}
if (pPropList)
{
if (!pPropList->_pPropStore)
_pProp->LoadData(pPropList);
if (pPropList->_pPropStore)
{
HRESULT hr;
PERSISTPROPERTYRANGE *pPropRange;
ITfPropertyStore *pPropStore = NULL;
int nCnt;
hr = pPropList->_pPropStore->Clone(&pPropStore);
if (FAILED(hr) || !pPropStore)
return FALSE;
nCnt = _rgPropRanges.Count();
if (!_rgPropRanges.Insert(nCnt, 1))
{
pPropStore->Release();
return FALSE;
}
pPropRange = _rgPropRanges.GetPtr(nCnt);
pPropRange->achStart = achStart;
pPropRange->achEnd = achEnd;
pPropRange->_pPropStore = pPropStore;
}
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _GetOffset
//
//----------------------------------------------------------------------------
int CRangeBackupProperty::_GetOffset(TfEditCookie ec, IAnchor *pa)
{
CRange *pCRange;
CRange *pCRangeTmp = NULL;
ULONG cch = 0;
HRESULT hr;
BOOL fEmpty;
pCRange = new CRange;
if (!pCRange)
goto Exit;
if (!pCRange->_InitWithDefaultGravity(_ppr->_pic, COPY_ANCHORS, pa, pa))
goto Exit;
pCRangeTmp = _ppr->_pRange->_Clone();
if (!pCRangeTmp)
goto Exit;
hr = pCRangeTmp->ShiftEndToRange(ec, (ITfRangeAnchor *)pCRange, TF_ANCHOR_START);
if (FAILED(hr))
goto Exit;
fEmpty = FALSE;
while ((pCRangeTmp->IsEmpty(ec, &fEmpty) == S_OK) && !fEmpty)
{
WCHAR sz[256];
ULONG cchTmp;
pCRangeTmp->GetText(ec, TF_TF_MOVESTART, sz, ARRAYSIZE(sz), &cchTmp);
cch += cchTmp;
}
Exit:
SafeRelease(pCRangeTmp);
SafeRelease(pCRange);
return cch;
}
//+---------------------------------------------------------------------------
//
// Restore
//
//----------------------------------------------------------------------------
BOOL CRangeBackupProperty::Restore(TfEditCookie ec)
{
int i;
HRESULT hr;
int nCnt;
CRange *pCRange;
nCnt = _rgPropRanges.Count();
if (!nCnt)
return FALSE;
pCRange = _ppr->_pRange->_Clone();
if (!pCRange)
return FALSE;
for (i = 0; i < nCnt; i++)
{
PERSISTPROPERTYRANGE *pPropRange;
LONG cchStart, cchEnd;
pPropRange = _rgPropRanges.GetPtr(i);
Assert(pPropRange);
Assert(pPropRange->_pPropStore);
hr = pCRange->ShiftStartToRange(ec, (ITfRangeAnchor *)_ppr->_pRange,
TF_ANCHOR_START);
if (FAILED(hr))
goto Next;
hr = pCRange->Collapse(ec, TF_ANCHOR_START);
if (FAILED(hr))
goto Next;
// shift End first.
hr = pCRange->ShiftEnd(ec, pPropRange->achEnd, &cchEnd, NULL);
if (FAILED(hr))
goto Next;
hr = pCRange->ShiftStart(ec, pPropRange->achStart, &cchStart, NULL);
if (FAILED(hr))
goto Next;
_pProp->_SetStoreInternal(ec, pCRange, pPropRange->_pPropStore, TRUE);
Next:
pPropRange->_pPropStore->Release();
pPropRange->_pPropStore = NULL;
}
pCRange->Release();
_rgPropRanges.Clear();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
// CRangeBackup
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CRangeBackup::CRangeBackup(CInputContext *pic)
{
_pic = pic;
Assert(!_pRange);
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CRangeBackup::~CRangeBackup()
{
Clear();
}
//+---------------------------------------------------------------------------
//
// Clear
//
//----------------------------------------------------------------------------
void CRangeBackup::Clear()
{
_pic = NULL;
SafeReleaseClear(_pRange);
delete _psz;
_psz = NULL;
int nCnt = _rgProp.Count();
for (int i = 0; i < nCnt; i++)
{
CRangeBackupProperty *pprp = _rgProp.Get(i);
delete pprp;
}
_rgProp.Clear();
}
//+---------------------------------------------------------------------------
//
// Init
//
//----------------------------------------------------------------------------
HRESULT CRangeBackup::Init(TfEditCookie ec, CRange *pRange)
{
ITfRange *pRangeTmp = NULL;
ULONG cch, cchCur;
BOOL fEmpty;
CProperty *pProp;
HRESULT hr;
WCHAR *pszTmp;
Assert(!_pRange);
Assert(!_psz);
_pRange = pRange->_Clone();
hr = _pRange->Clone(&pRangeTmp);
if (FAILED(hr) || !pRangeTmp)
return E_FAIL;
hr = E_FAIL;
//
// Save text.
//
fEmpty = FALSE;
cchCur = 0;
cch = 31;
while ((pRangeTmp->IsEmpty(ec, &fEmpty) == S_OK) && !fEmpty)
{
if (!_psz)
{
Assert(cchCur == 0);
_psz = (WCHAR *)cicMemAlloc((cch + 1) * sizeof(WCHAR));
}
else
{
Assert(cchCur);
pszTmp = (WCHAR *)cicMemReAlloc(_psz, (cchCur + cch + 1) * sizeof(WCHAR));
if (pszTmp != NULL)
{
_psz = pszTmp;
}
else
{
cicMemFree(_psz);
_psz = NULL;
}
}
if (_psz == NULL)
goto Exit;
pRangeTmp->GetText(ec, TF_TF_MOVESTART, _psz + cchCur, cch, &cch);
cchCur += cch;
cch *= 2;
}
if (!cchCur)
{
hr = S_FALSE;
_cch = 0;
if (_psz)
{
cicMemFree(_psz);
_psz = NULL;
}
goto Exit;
}
_cch = cchCur;
_psz[_cch] = L'\0';
//
// Save property.
//
pProp = _pic->_pPropList;
while (pProp)
{
CRangeBackupProperty *pPropRange;
int nCnt = _rgProp.Count();
pPropRange = new CRangeBackupProperty(this, pProp);
if (!pPropRange)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
if (!pPropRange->Init(ec))
{
delete pPropRange;
goto Next;
}
if (!_rgProp.Insert(nCnt, 1))
{
hr = E_OUTOFMEMORY;
delete pPropRange;
goto Next;
}
_rgProp.Set(nCnt, pPropRange);
Next:
pProp = pProp->_pNext;
}
hr = S_OK;
Exit:
SafeRelease(pRangeTmp);
return hr;
}
//+---------------------------------------------------------------------------
//
// Restore
//
//----------------------------------------------------------------------------
STDAPI CRangeBackup::Restore(TfEditCookie ec, ITfRange *pRange)
{
HRESULT hr = E_FAIL;
int i;
int nCnt;
CRange *range;
if (!_pic->_IsValidEditCookie(ec, TF_ES_READWRITE))
{
Assert(0);
return TF_E_NOLOCK;
}
if (pRange)
{
SafeReleaseClear(_pRange);
range = GetCRange_NA(pRange);
if (range == NULL)
return E_INVALIDARG;
if (!VerifySameContext(_pic, range))
return E_INVALIDARG;
range->_QuickCheckCrossedAnchors();
_pRange = range->_Clone();
}
Assert(_pRange);
Assert(_psz || !_cch);
if (!_pic)
return S_OK;
Assert(_pRange);
_pRange->SetText(ec, 0, _psz, _cch);
nCnt = _rgProp.Count();
for (i = 0; i < nCnt; i++)
{
CRangeBackupProperty *pPropRange = _rgProp.Get(i);
Assert(pPropRange);
pPropRange->Restore(ec);
delete pPropRange;
}
_rgProp.Clear();
hr = S_OK;
return hr;
}