textrendering/texthandling/stext/TXTRTFLD.CPP
changeset 0 1fb32624e06b
child 40 91ef7621b7fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/texthandling/stext/TXTRTFLD.CPP	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,97 @@
+/*
+* 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;
+	}