Revert last code drop.
/*
* 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;
}