/*
* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include <e32std.h>
#include "FLDINFO.H"
#include "FLDSET.H"
#include "TXTRICH.H"
#include "TXTSTD.H"
#include "TXTINDEX.H"
#include "ParseLst.h"
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include "TXTETEXT_INTERNAL.H"
#endif
EXPORT_C void CRichText::UpdateFieldL(TInt aPos)
// Updates the field at aPos, adjusting the rich text index by the required amount.
//
/** Re-evaluates the field which covers the document position specified. Re-evaluating
a field means calculating the field's new value, then inserting that value
into the text object, replacing the previous value.
Notes:
fields have a maximum length of 20 characters
the first time a field is updated, the position specified should be the position
at which the field was inserted
@param aPos A document position in the field to be updated. Must be a valid
position, or a panic occurs. */
{
__TEST_INVARIANT;
__ASSERT_ALWAYS(aPos >= 0 && aPos <= DocumentLength(), Panic(ECharPosBeyondDocument));
TFindFieldInfo fieldInfo;
if (iFieldSet->FindFields(fieldInfo, aPos))
{// a field exists at aPos, so update it.
HBufC* valueBuf = HBufC::NewL(KMaxFieldBufferSize); // will hold the new value
/*
Calculate new field value and insert it.
Don't put valueBuf on the cleanup stack before calling NewFieldValueL because NewFieldValueL
sometimes changes valueBuf, in which case it itself puts it on the cleanup stack.
*/
iFieldSet->NewFieldValueL(valueBuf, fieldInfo.iFirstFieldPos); // get the new value
CleanupStack::PushL(valueBuf);
DoPtInsertL(fieldInfo.iFirstFieldPos, *valueBuf); // insert the new text into the document
TBool indexPresent = IndexPresent();
if (indexPresent)
{
TRAPD(ret, iIndex->InsertL(aPos, valueBuf->Des(), *iGlobalParaFormatLayer));
if (ret != KErrNone)
{
DoPtDelete(fieldInfo.iFirstFieldPos, valueBuf->Length());
User::Leave(ret);
}
}
//
// Now delete the old field value from the text.
TIndexDeleteInfo indexInfo;
if (indexPresent)
{
TRAPD(ret, iIndex->SetForDeleteL(indexInfo, fieldInfo.iFirstFieldPos + valueBuf->Length(), fieldInfo.iFirstFieldLen));
if (ret != KErrNone)
{// Maintain rich text invariant. Both old&new values now make up the current field value.
iFieldSet->NotifyFieldUpdate(aPos, valueBuf->Length() + fieldInfo.iFirstFieldLen);
User::Leave(ret);
}// Not the greatest but at least the text stream is consistent with the rich text index.
iIndex->DeleteNow(indexInfo);
}
DoPtDelete(fieldInfo.iFirstFieldPos + valueBuf->Length(), fieldInfo.iFirstFieldLen); // delete the old text of the field
iFieldSet->NotifyFieldUpdate(aPos, valueBuf->Length()); // inform the field set
//
iParserData->MergeRange(aPos,fieldInfo.iFirstFieldLen,valueBuf->Length());
CallEditObserver(aPos, valueBuf->Length() - fieldInfo.iFirstFieldLen);
CleanupStack::PopAndDestroy(); // valueBuf
}
__TEST_INVARIANT;
}