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