textrendering/texthandling/ttext/T_TRAN.CPP
changeset 0 1fb32624e06b
child 51 a7c938434754
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/texthandling/ttext/T_TRAN.CPP	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,631 @@
+/*
+* 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 <e32base.h>
+
+#include <gdi.h>
+#include <conpics.h>
+#include <s32file.h>
+#include <e32test.h>
+
+#include <txtrich.h>
+#include <txtfmlyr.h>
+#include "TXTMRTSR.H"
+
+#include "../incp/T_PMLPAR.H"
+#include "../spml/T_PMLPAR.CPP"
+
+/* this fixes a MSVC link warning */
+#ifdef __VC32__
+#pragma comment (linker, "/opt:noref") 
+#endif
+
+#define UNUSED_VAR(a) a = a
+
+const TInt KTestCleanupStack=0x40;
+
+_LIT(KExportFileName1, "c:\\etext\\t_para.txg");
+_LIT(KExportFileName2, "c:\\etext\\t_para2.txg");
+
+void EnsureFileExists(const TDesC& aName)
+	{
+	RFs fs;
+	fs.Connect();
+	fs.MkDirAll(aName);
+	RFile file;
+	file.Create(fs, aName, EFileRead|EFileWrite);
+	file.Close();
+	fs.Close();
+	}
+
+class CContainer : public CBase, public MRichTextStoreResolver
+	{
+public:
+	static CContainer* NewL(TFileName aFileName);
+	~CContainer();
+	//
+	// Mixin
+	//
+	virtual const CStreamStore& StreamStoreL(TInt aPos)const;
+	// Methods
+	TStreamId StoreL(CStreamStore& aStore)const;
+	void RestoreL(const CStreamStore& aStore,TStreamId aId,MPictureFactory* aFctry);
+protected:
+	CContainer();
+	void ConstructL(TFileName aFileName);
+public:
+	CRichText* iText;
+	const CParaFormatLayer* iGlobalParaFormatLayer;
+	const CCharFormatLayer* iGlobalCharFormatLayer;
+	};
+
+
+LOCAL_D RTest test(_L("Testing Picture Restorer mechanism"));
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D RFs TheFs;  // the file server
+LOCAL_D RFile TheFile;  // the data file
+LOCAL_D CParser* TheParser;
+LOCAL_D CContainer* TheContainer;
+LOCAL_D CStreamStore* TheDeferredPictureStore;
+
+CContainer* CContainer::NewL(TFileName aFileName)
+// Create new container & set its components.
+//
+	{
+	CContainer* self=new(ELeave) CContainer;
+	CleanupStack::PushL(self);
+	self->ConstructL(aFileName);
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+CContainer::CContainer()
+	{
+	}
+
+
+void CContainer::ConstructL(TFileName aFileName)
+	{
+	TheParser=CParser::NewL();
+	CleanupStack::PushL(TheParser);
+	iText=TheParser->ParseL(aFileName);
+	CleanupStack::PopAndDestroy();
+	iGlobalParaFormatLayer=iText->GlobalParaFormatLayer();
+	iGlobalCharFormatLayer=iText->GlobalCharFormatLayer();
+	}
+
+
+CContainer::~CContainer()
+	{
+	delete iText;
+	delete (CParaFormatLayer*)iGlobalParaFormatLayer;
+	delete (CCharFormatLayer*)iGlobalCharFormatLayer;
+	}
+
+
+const CStreamStore& CContainer::StreamStoreL(TInt /*aPos*/)const
+// Return the deferred picture store.
+// In this instance, the deferred picture store does not vary with document position.
+//
+	{return *TheDeferredPictureStore;}
+
+
+TStreamId CContainer::StoreL(CStreamStore& aStore)const
+// Store this component
+//
+	{
+	CStoreMap* map=CStoreMap::NewLC(aStore);
+	iText->StoreComponentsL(aStore,*map);
+	//
+	RStoreWriteStream stream(*map);
+	TStreamId id=stream.CreateLC(aStore);
+	iGlobalParaFormatLayer->ExternalizeL(stream);
+	iGlobalCharFormatLayer->ExternalizeL(stream);
+	stream<< *iText;
+	stream.CommitL();
+	//
+	map->Reset();
+	CleanupStack::PopAndDestroy(2);
+	return id;
+	}
+
+
+void CContainer::RestoreL(const CStreamStore& aStore,TStreamId aId,MPictureFactory* aFactory)
+// Restore this component
+//
+	{
+	RStoreReadStream stream;
+	stream.OpenLC(aStore,aId);
+	iGlobalParaFormatLayer=CParaFormatLayer::NewL(stream);
+	iGlobalCharFormatLayer=CCharFormatLayer::NewL(stream);
+	iText=CRichText::NewL(iGlobalParaFormatLayer,iGlobalCharFormatLayer);
+	iText->SetPictureFactory(aFactory,this);
+	stream>> *iText;
+	//
+	CleanupStack::PopAndDestroy();
+	//
+	iText->RestoreComponentsL(aStore);
+	}
+
+
+/*LOCAL_C void testPictureRestorer(TBool aDeferPictureLoad=ETrue)
+// Test Picture persistance.
+//
+    {
+	//
+	TheFs.Connect();
+	//
+	TheStore=CDirectFileStore::ReplaceL(TheFs,_L("c:\\etext\\t_word.doc"),EFileRead|EFileWrite);
+	TheDeferredPictureStore=TheStore;
+	CleanupStack::PushL(TheStore);
+	TheStore->SetTypeL(KDirectFileStoreLayout);
+	//
+	// Create concrete picture factory.
+	MDemPictureFactory* factory=new(ELeave) MDemPictureFactory;
+
+	TheContainer->iText->Reset();
+	TheContainer->iText->InsertL(0,_L("Hello Duncan how"));
+
+	TheContainer->iText->SetPictureFactory(factory,TheContainer);
+	// Create some pictures.
+	CXzePicture* pic1=CXzePicture::NewL('x');
+		CleanupStack::PushL(pic1);
+	CXzePicture* pic2=CXzePicture::NewL('z');
+		CleanupStack::PushL(pic2);
+	CXzePicture* pic3=CXzePicture::NewL('e');
+		CleanupStack::PushL(pic3);
+	//
+	// Create the picture headers
+	TPictureHeader hdr1;
+	TPictureHeader hdr2;
+	TPictureHeader hdr3;
+	//
+	TSize size;
+	pic1->GetSizeInTwips(size);
+	hdr1.iPictureType=KUidXzePictureType;
+	hdr1.iPicture=pic1;
+	hdr2.iPictureType=KUidXzePictureType;
+	hdr2.iPicture=pic2;
+	hdr3.iPictureType=KUidXzePictureType;
+	hdr3.iPicture=pic3;
+	//
+	// Insert the pictures into the rich text
+	TBool hasMarkupData=TheContainer->iText->HasMarkupData();
+	test(!hasMarkupData);
+	TheContainer->iText->CancelInsertCharFormat();
+	TheContainer->iText->InsertL(0,hdr1);
+	TheContainer->iText->InsertL(5,hdr2);
+	TheContainer->iText->InsertL(7,hdr3);
+	TheContainer->iText->InsertL(0,CEditableText::EParagraphDelimiter);
+	TheContainer->iText->CancelInsertCharFormat();
+	TheContainer->iText->InsertL(2,CEditableText::EParagraphDelimiter);
+	CleanupStack::Pop(3);
+	hasMarkupData=TheContainer->iText->HasMarkupData();
+	test(hasMarkupData);
+	//
+	// High level Store context
+	TStreamId id=TheContainer->StoreL(*TheStore);
+//
+	delete TheContainer->iText;
+	delete (CParaFormatLayer*)TheContainer->iGlobalParaFormatLayer;
+	delete (CCharFormatLayer*)TheContainer->iGlobalCharFormatLayer;
+//
+//
+//	Now restore the container with rich text
+	TheContainer->RestoreL(*TheStore,id,factory);
+	if (!aDeferPictureLoad)
+		TheContainer->iText->LoadAllPicturesNowL();
+	//
+	hasMarkupData=TheContainer->iText->HasMarkupData();
+	test(hasMarkupData);
+	test(TheContainer->iText->ParagraphCount()==3);
+	test(TheContainer->iText->DocumentLength()==21);
+	TPtrC view;
+	TCharFormat format;
+	CPicture* picture;
+	//
+	// TEST THE PICTURE HEADERS, DEPENDING ON WHETHER DEFERRED LOADING IS SET OR NOT
+	TPictureHeader hdrA=TheContainer->iText->PictureHeader(1);
+	test(hdrA.iPictureType==KUidXzePictureType);
+	if (aDeferPictureLoad)
+		{
+		test(hdrA.iPicture.IsId());
+		}
+	else
+		{
+		test(hdrA.iPicture!=NULL);
+		test(hdrA.iPicture.IsPtr());
+		test(((CXzePicture*)hdrA.iPicture.AsPtr())->iLabel=='x');
+		}
+	TPictureHeader hdrB=TheContainer->iText->PictureHeader(7);
+	test(hdrB.iPictureType==KUidXzePictureType);
+	if (aDeferPictureLoad)
+		{
+		test(hdrB.iPicture.IsId());
+		}
+	else
+		{
+		test(hdrB.iPicture!=NULL);
+		test(hdrB.iPicture.IsPtr());
+		test(((CXzePicture*)hdrB.iPicture.AsPtr())->iLabel=='z');
+		}
+	TPictureHeader hdrC=TheContainer->iText->PictureHeader(9);
+	test(hdrC.iPictureType==KUidXzePictureType);
+	if (aDeferPictureLoad)
+		{
+		test(hdrC.iPicture.IsId());
+		}
+	else
+		{
+		test(hdrC.iPicture!=NULL);
+		test(hdrC.iPicture.IsPtr());
+		test(((CXzePicture*)hdrC.iPicture.AsPtr())->iLabel=='e');
+		}
+	TPictureHeader hdrD=TheContainer->iText->PictureHeader(0);  // This is not a picture character
+	test(hdrD.iPictureType==KNullUid);
+	test(hdrD.iPicture==NULL);
+	TSize dummySize;
+	test(hdrD.iSize==dummySize);
+	//
+	TheContainer->iText->GetChars(view,format,1);
+	test(view[0]==CEditableText::EPictureCharacter);
+	picture=TheContainer->iText->PictureHandleL(1);
+	test(((CXzePicture*)picture)->iLabel=='x');
+	
+	TheContainer->iText->GetChars(view,format,7);
+	test(view[0]==CEditableText::EPictureCharacter);
+	picture=TheContainer->iText->PictureHandleL(7);
+	test(((CXzePicture*)picture)->iLabel=='z');
+	
+	TheContainer->iText->GetChars(view,format,9);
+	test(view[0]==CEditableText::EPictureCharacter);
+	picture=TheContainer->iText->PictureHandleL(9);
+	test(((CXzePicture*)picture)->iLabel=='e');
+
+	delete factory;
+	CleanupStack::PopAndDestroy();  // TheStore
+	TheFs.Close();
+    }
+
+
+LOCAL_C void testPictureRestorer2(TBool aAlwaysFailToLoad=EFalse)
+// Test Picture persistance.
+//
+    {
+	//
+	TheFs.Connect();
+	//
+	TheStore=CDirectFileStore::ReplaceL(TheFs,_L("c:\\etext\\t_word1.doc"),EFileRead|EFileWrite);
+	TheDeferredPictureStore=TheStore;
+	CleanupStack::PushL(TheStore);
+	TheStore->SetTypeL(KDirectFileStoreLayout);
+	//
+	// Create concrete picture factory.
+	MDemPictureFactory* factory=new(ELeave) MDemPictureFactory;
+
+	TheContainer->iText->Reset();
+	TheContainer->iText->InsertL(0,_L("Hello Duncan how"));
+
+	TheContainer->iText->SetPictureFactory(factory,TheContainer);
+	// Create some pictures.
+	CXzeDoor* pic1=CXzeDoor::NewL('x',aAlwaysFailToLoad);
+		CleanupStack::PushL(pic1);
+	CXzeDoor* pic2=CXzeDoor::NewL('z',aAlwaysFailToLoad);
+		CleanupStack::PushL(pic2);
+	CXzePicture* pic3=CXzePicture::NewL('e');  // Control: will always load.
+		CleanupStack::PushL(pic3);
+	//
+	// Create the picture headers
+	TPictureHeader hdr1;
+	TPictureHeader hdr2;
+	TPictureHeader hdr3;
+	//
+	TSize size;
+	pic1->GetSizeInTwips(size);
+	hdr1.iPictureType=KUidXzeDoorType;
+	hdr1.iPicture=pic1;
+	hdr2.iPictureType=KUidXzeDoorType;
+	hdr2.iPicture=pic2;
+	hdr3.iPictureType=KUidXzePictureType;
+	hdr3.iPicture=pic3;
+	//
+	// Insert the pictures into the rich text
+	TBool hasMarkupData=TheContainer->iText->HasMarkupData();
+	test(!hasMarkupData);
+	TheContainer->iText->CancelInsertCharFormat();
+	TheContainer->iText->InsertL(0,hdr1);
+	TheContainer->iText->InsertL(5,hdr2);
+	TheContainer->iText->InsertL(7,hdr3);
+	TheContainer->iText->InsertL(0,CEditableText::EParagraphDelimiter);
+	TheContainer->iText->CancelInsertCharFormat();
+	TheContainer->iText->InsertL(2,CEditableText::EParagraphDelimiter);
+	CleanupStack::Pop(3);  // pic1,2,3 - ownership transferred to rich text
+	hasMarkupData=TheContainer->iText->HasMarkupData();
+	test(hasMarkupData);
+	//
+	// High level Store context - all pictures currently in memory
+	TStreamId id=TheContainer->StoreL(*TheStore);
+//
+	delete TheContainer->iText;
+	delete (CParaFormatLayer*)TheContainer->iGlobalParaFormatLayer;
+	delete (CCharFormatLayer*)TheContainer->iGlobalCharFormatLayer;
+//
+//
+//	Now restore the container with rich text
+	TheContainer->RestoreL(*TheStore,id,factory);
+//
+//
+//  Now store the stuff again
+	TInt error=TheContainer->iText->LoadAllPicturesNowL();
+	if (error==KErrNotFound)
+		test.Printf(_L("   SIMULATION: Some picture data has been removed as no app could be found."));
+//	if (aAlwaysFailToLoad)
+//		test(error==KErrNotFound);
+//	else
+//		test(error==KErrNone);
+	id=KNullStreamId;
+	TRAP(error,
+	id=TheContainer->StoreL(*TheStore));
+	test(error==KErrNone);
+//
+// ...and restore it to check what we have got.
+	delete TheContainer->iText;
+	delete (CParaFormatLayer*)TheContainer->iGlobalParaFormatLayer;
+	delete (CCharFormatLayer*)TheContainer->iGlobalCharFormatLayer;
+    TheContainer->RestoreL(*TheStore,id,factory);
+	TInt pictureCount=TheContainer->iText->PictureCount();
+	if (aAlwaysFailToLoad)
+		test(pictureCount==1);
+	else
+		test(pictureCount==3);
+//
+	delete factory;
+	CleanupStack::PopAndDestroy();  // TheStore
+	TheFs.Close();
+    }*/
+
+
+LOCAL_C void CompareRichTextL(CRichText *aDoc1,CRichText *aDoc2)
+//
+	{
+	test.Start(_L("Comparing Documents"));
+	TInt length;
+	TInt num1,num2;
+ 	TInt ii=0,len1,len2,pos1,pos2,oldPos;
+
+	test.Next(_L("Document Length"));
+	length=aDoc1->LdDocumentLength();
+	num2=aDoc2->LdDocumentLength();
+	test(length==num2);
+
+	test.Next(_L("Paragraph Count"));
+	num1=aDoc1->ParagraphCount();
+	num2=aDoc2->ParagraphCount();
+	test(num1==num2);
+
+	test.Next(_L("Paragraph Lengths"));
+	pos1=-1;
+	oldPos=-2;
+	while (pos1>oldPos)
+		{
+		oldPos=pos1;
+		pos1=aDoc1->CharPosOfParagraph(len1,ii);
+		pos2=aDoc2->CharPosOfParagraph(len2,ii);
+		test(len1==len2);
+		test(pos1==pos2);
+		ii++;
+		}
+ 
+	test.Next(_L("Word Count"));
+	num1=aDoc1->WordCount();
+	num2=aDoc2->WordCount();
+	test(num1==num2);
+
+	test.Next(_L("Characters"));
+	TCharFormat format1,format2;
+	TPtrC chars1,chars2;
+	len1=1;
+	ii=0;
+	while (ii<=length)
+		{
+		aDoc1->GetChars(chars1,format1,ii);
+		aDoc2->GetChars(chars2,format2,ii);
+		len1=Min(chars1.Length(),chars2.Length());
+		test(chars1.Left(len1)==chars2.Left(len1));
+		test(format1.IsEqual(format2));
+		test(format2.IsEqual(format1));
+		ii+=len1;
+		}
+	
+	test.End();
+	}
+
+
+LOCAL_C  void GoL()
+// Run the tests
+//
+	{
+	CParaFormatLayer* pLayer=CParaFormatLayer::NewL();
+	CCharFormatLayer* cLayer=CCharFormatLayer::NewL();
+	CRichText *document=CRichText::NewL(pLayer,cLayer);
+	TInt err;
+	
+	test.Start(_L("Document with single Paragraph"));
+	test.Next(_L(" @SYMTestCaseID:SYSLIB-TTEXT-LEGACY-T_TRAN-0001 "));
+	{	
+	TheContainer=CContainer::NewL(_L("z:\\test\\app-framework\\etext\\t_para.pml"));
+	test.Start(_L("Exporting a file by Para"));
+	TFileName exportFile=KExportFileName1();
+	EnsureFileExists(exportFile);
+	TRAP(err,TheContainer->iText->ExportAsTextL(exportFile,CPlainText::EOrganiseByParagraph,0));
+	test(err==KErrNone);
+	test.Next(_L("Importing a file by Para"));
+	document->Reset();
+	TInt charsImported=document->ImportTextFileL(0,exportFile,CPlainText::EOrganiseByParagraph);
+	test(charsImported>0);
+	test.Next(_L("Comparing Result"));
+	TRAP(err,CompareRichTextL(TheContainer->iText,document));
+ 	test(err==KErrNone);
+	delete TheContainer;
+	}
+	
+	{
+	TheContainer=CContainer::NewL(_L("z:\\test\\app-framework\\etext\\t_para.pml"));
+	test.Next(_L("Exporting and Importing a file by Line"));
+	test.Start(_L("Line Lengths 25,30,...,95"));
+	TFileName exportFile=KExportFileName1();
+	TInt ii;
+	for(ii=25;ii<100;ii+=5)
+		{
+		test.Next(_L("With next line length"));
+		EnsureFileExists(exportFile);
+		TRAP(err,TheContainer->iText->ExportAsTextL(exportFile,CPlainText::EOrganiseByLine,ii));
+		test(err==KErrNone);
+		document->Reset();
+		TInt charsImported=document->ImportTextFileL(0,exportFile,CPlainText::EOrganiseByLine);
+		test(charsImported>0);
+		TRAP(err,CompareRichTextL(TheContainer->iText,document));
+ 		test(err==KErrNone);
+		}
+	delete TheContainer;
+	test.End();
+	}
+
+	test.End();
+	test.Next(_L("Document with two Paragraphs"));
+	
+	{	
+	TheContainer=CContainer::NewL(_L("z:\\test\\app-framework\\etext\\t_para2.pml"));
+	test.Start(_L("Exporting a file by Para"));
+	TFileName exportFile=KExportFileName2();
+	EnsureFileExists(exportFile);
+	TRAP(err,TheContainer->iText->ExportAsTextL(exportFile,CPlainText::EOrganiseByParagraph,0));
+	test(err==KErrNone);
+	test.Next(_L("Importing a file by Para"));
+	document->Reset();
+	TInt charsImported=document->ImportTextFileL(0,exportFile,CPlainText::EOrganiseByParagraph);
+	test(charsImported>0);
+	test.Next(_L("Comparing Result"));
+	TRAP(err,CompareRichTextL(TheContainer->iText,document));
+ 	test(err==KErrNone);
+	delete TheContainer;
+	}
+	
+	{
+	TheContainer=CContainer::NewL(_L("z:\\test\\app-framework\\etext\\t_para.pml"));
+	test.Next(_L("Exporting and Importing a file by Line"));
+	test.Start(_L("Line Lengths 30,40,...,100"));
+	TFileName exportFile=KExportFileName1();
+	TInt ii;
+	for(ii=30;ii<105;ii+=10)
+		{
+		test.Next(_L("With next line length"));
+		EnsureFileExists(exportFile);
+		TRAP(err,TheContainer->iText->ExportAsTextL(exportFile,CPlainText::EOrganiseByLine,ii));
+		test(err==KErrNone);
+		document->Reset();
+		TInt charsImported=document->ImportTextFileL(0,exportFile,CPlainText::EOrganiseByLine);
+		test(charsImported>0);
+		TRAP(err,CompareRichTextL(TheContainer->iText,document));
+ 		test(err==KErrNone);
+		}
+	delete TheContainer;
+	test.End();
+	}
+
+	delete document;
+	delete cLayer;
+	delete pLayer;
+
+	test.End();
+	}
+
+
+LOCAL_C void setupCleanup()
+//
+// Initialise the cleanup stack.
+//
+    {
+
+	TheTrapCleanup=CTrapCleanup::New();
+	TRAPD(r,\
+		{\
+		for (TInt i=KTestCleanupStack;i>0;i--)\
+			CleanupStack::PushL((TAny*)1);\
+		test(r==KErrNone);\
+		CleanupStack::Pop(KTestCleanupStack);\
+		});
+	}
+
+
+LOCAL_C void DeleteDataFile(const TDesC& aFullName)
+	{
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if(err == KErrNone)
+		{
+		TEntry entry;
+		if(fsSession.Entry(aFullName, entry) == KErrNone)
+			{
+			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
+			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+			if(err != KErrNone) 
+				{
+				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+				}
+			err = fsSession.Delete(aFullName);
+			if(err != KErrNone) 
+				{
+				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+				}
+			}
+		fsSession.Close();
+		}
+	else
+		{
+		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+		}
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Test the streaming framework.
+//
+    {
+
+	test.Title();
+	
+	__UHEAP_MARK;
+	setupCleanup();
+	TRAPD(r,GoL());
+    test(r == KErrNone);
+
+	delete TheTrapCleanup;
+	
+	__UHEAP_MARKEND;
+	
+	::DeleteDataFile(KExportFileName1);		//deletion of data files must be before call to End() - DEF047652
+	::DeleteDataFile(KExportFileName2);	
+	
+	test.End();
+	test.Close();
+
+	return 0;
+    }