diff -r 000000000000 -r 1fb32624e06b textrendering/texthandling/ttext/T_RTCLIP.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/textrendering/texthandling/ttext/T_RTCLIP.CPP Tue Feb 02 02:02:46 2010 +0200 @@ -0,0 +1,586 @@ +/* +* 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 "TSTCLIPB.H" +#include +#include "TXTMRTSR.H" +#include +#include +#include +#include +#include +#include "../incp/T_PMLPAR.H" + +#define UNUSED_VAR(a) a = a + +const TInt KTestCleanupStack=0x80; + + +LOCAL_D RTest test(_L("Cut & Paste")); +LOCAL_D CTrapCleanup* TheTrapCleanup=NULL; +LOCAL_D CRichText* TheText=NULL; +LOCAL_D CParaFormatLayer* TheGlobalParaLayer=NULL; +LOCAL_D CCharFormatLayer* TheGlobalCharLayer=NULL; +LOCAL_D CClipboard* TheWriteBoard=NULL; +LOCAL_D CClipboard* TheReadBoard=NULL; +LOCAL_D TFileName TheFileName = _L("z:\\test\\app-framework\\etext\\rtclipb.pml"); +LOCAL_D RFs TheSession; + + +class TDemStoreResolver : public MRichTextStoreResolver + { +public: + TDemStoreResolver(CStreamStore& aStore); + // + virtual const CStreamStore& StreamStoreL(TInt aPos)const; +private: + CStreamStore* iStore; + }; + + +TDemStoreResolver::TDemStoreResolver(CStreamStore& aStore) +: iStore(&aStore) + {} + +const CStreamStore& TDemStoreResolver::StreamStoreL(TInt /*aPos*/)const + {return *iStore;} + + +LOCAL_C void OpenWriteClipboardLC() +// Initialize a new write clipboard, after +// deleting any existing read clipboard. +// + { + if (TheReadBoard) + { + CleanupStack::PopAndDestroy(); + TheReadBoard=NULL; + TheSession.Close(); + } + User::LeaveIfError(TheSession.Connect()); + TheWriteBoard=CClipboard::NewForWritingLC(TheSession); + } + + +LOCAL_C void OpenReadClipboardLC() +// Initialize a new read clipboard, after +// deleting any existing write clipboard. +// + { + if (TheWriteBoard) + { + TheWriteBoard->CommitL(); + CleanupStack::PopAndDestroy(); + TheWriteBoard=NULL; + TheSession.Close(); + } + User::LeaveIfError(TheSession.Connect()); + TheReadBoard=CClipboard::NewForReadingLC(TheSession); + } + + +LOCAL_C void ParseRichTextDocumentLC() +// + { + CParser* myParser=CParser::NewL(); + CleanupStack::PushL(myParser); + TheText=myParser->ParseL(TheFileName); + TheGlobalParaLayer=(CParaFormatLayer*)TheText->GlobalParaFormatLayer(); + TheGlobalCharLayer=(CCharFormatLayer*)TheText->GlobalCharFormatLayer(); + CleanupStack::PopAndDestroy(); + // + CleanupStack::PushL(TheText); + } + + +LOCAL_C void testRichTextCutPaste1a() +// +// + { + test.Next(_L("Cut & paste, preserving formatting into non-empty document")); + TheFileName=_L("z:\\test\\app-framework\\etext\\rtclipb2.pml"); + ParseRichTextDocumentLC(); + TheText->DeleteL(0,TheText->DocumentLength()); + TPtrC buf1(_L("ab")); + TheText->InsertL(0,buf1); + TheText->InsertL(1,CEditableText::EParagraphDelimiter); + TheReadBoard=NULL; + TheWriteBoard=NULL; + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,TheText->DocumentLength()); + TheText->DeleteL(1,2); // Just leaves the single character 'a' as content. + // + OpenReadClipboardLC(); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),1); + // + CleanupStack::PopAndDestroy(); // Last clipboard object + CleanupStack::PopAndDestroy(); // TheTextObject + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + } + +_LIT(KOutputFile, "c:\\etext\\t_rtclip.doc"); +LOCAL_C void testRichTextCutPaste1b() +// +// + { + TheReadBoard=NULL; + TheWriteBoard=NULL; + test.Next(_L("Copy to Clipboard with pictures, with missing host applications.")); + TheFileName=_L("z:\\test\\app-framework\\etext\\rtclipb2.pml"); // dummy - just to get global layers + ParseRichTextDocumentLC(); + TheText->Reset(); + // + CXzeDoor* pic1=CXzeDoor::NewL('1',EFalse); // never fail to detach + CXzePicture* pic2=CXzePicture::NewL('2'); + CXzeDoor* pic3=CXzeDoor::NewL('1',EFalse); // never fail to detach + CXzePicture* pic4=CXzePicture::NewL('2'); + // + TPictureHeader hdr1; + TPictureHeader hdr2; + TPictureHeader hdr3; + TPictureHeader hdr4; + // + hdr1.iPictureType=KUidXzeDoorType; + hdr2.iPictureType=KUidXzePictureType; + hdr3.iPictureType=KUidXzeDoorType; + hdr4.iPictureType=KUidXzePictureType; + // + hdr1.iPicture=pic1; + hdr2.iPicture=pic2; + hdr3.iPicture=pic3; + hdr4.iPicture=pic4; + // + TheText->InsertL(0,hdr4); + TheText->InsertL(0,hdr3); + TheText->InsertL(0,hdr2); + TheText->InsertL(0,hdr1); + test(TheText->PictureCount()==4); + // + // Now save and reload this to get the pictures into a deferred picture store. + RFs session; + session.Connect(); + session.Delete(KOutputFile); + session.MkDirAll(KOutputFile); + CFileStore* store=CDirectFileStore::CreateLC(session,KOutputFile,EFileRead|EFileWrite); + store->SetTypeL(KDirectFileStoreLayoutUid); + TStreamId id=KNullStreamId; + TRAPD(r, + id=TheText->StoreL(*store)); + test(r==KErrNone); + // + TheText->Reset(); + TheText->RestoreL(*store,id); + MDemPictureFactory* factory=new(ELeave) MDemPictureFactory; + TDemStoreResolver resolver(*store); + TheText->SetPictureFactory(factory,&resolver); + // + // Now the tests. + OpenWriteClipboardLC(); + TInt documentLength=TheText->DocumentLength(); + TRAP(r, + TheText->DetachFromStoreL(CPicture::EDetachFull,0,documentLength)); + if (r==KErrNotSupported) + test.Printf(_L(" SIMULATION: Some picture data has been removed\n")); + else if (r!=KErrNone) + User::Leave(r); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,documentLength); + // + TheText->Reset(); + TheText->SetPictureFactory(factory,&resolver); + documentLength=TheText->DocumentLength(); + test(documentLength==0); + OpenReadClipboardLC(); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),documentLength); + test(TheText->DocumentLength()==4); + test(TheText->ParagraphCount()==1); + test(TheText->PictureCount()==4); + ///////////////////////////////////////////////////////////////////////////// + CleanupStack::PopAndDestroy(); // Last clipboard object + CleanupStack::PopAndDestroy(); // store + CleanupStack::PopAndDestroy(); // TheTextObject + delete factory; + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + session.Close(); + } + + + LOCAL_C void testRichTextCutPaste1() +// +// + { + test.Next(_L("Cut&Paste - preserving formatting")); + TheFileName=_L("z:\\test\\app-framework\\etext\\rtclipb2.pml"); + ParseRichTextDocumentLC(); + // + CRichText* copiedText=CRichText::NewL(TheGlobalParaLayer,TheGlobalCharLayer); + //////////////////////////////////////////////////////////////////////////// + TheReadBoard=NULL; + TheWriteBoard=NULL; + // + // Scenario 1 + test.Start(_L("multiple partial phrases")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),36,73); + OpenReadClipboardLC(); + copiedText->Reset(); + TInt pasted=0; + TRAPD(ret, + pasted=copiedText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0)); + test(ret==KErrNone); + test(pasted==73); + test(copiedText->DocumentLength()==73); + test(copiedText->ParagraphCount()==3); + // + // Scenario 2 + test.Next(_L("multiple whole phrases")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),51,60); + copiedText->Reset(); + OpenReadClipboardLC(); + pasted=copiedText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0); + test(pasted==60); + test(copiedText->DocumentLength()==60); + test(copiedText->ParagraphCount()==3); + // + // Scenario 3 + test.Next(_L("single middle portion of a phrase")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),53,2); + copiedText->Reset(); + OpenReadClipboardLC(); + pasted=copiedText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0); + test(pasted==2); + test(copiedText->DocumentLength()==2); + test(copiedText->ParagraphCount()==1); + // + // Scenario 4 + test.Next(_L("multiple phrases, starting/ending on shared paragraphs")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,140); + copiedText->Reset(); + OpenReadClipboardLC(); + pasted=copiedText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0); + test(pasted==140); + test(copiedText->DocumentLength()==140); + test(copiedText->ParagraphCount()==5); + + // + // Scenario 5 + test.Next(_L("zero phrases")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),70,10); + copiedText->Reset(); + OpenReadClipboardLC(); + pasted=copiedText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0); + test(pasted==10); + test(copiedText->DocumentLength()==10); + test(copiedText->ParagraphCount()==1); + + // + CleanupStack::PopAndDestroy(); // Last clipboard object + CleanupStack::PopAndDestroy(); // TheTextObject + delete copiedText; + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + test.End(); + } + + +/** +@SYMTestCaseID SYSLIB-ETEXT-CT-4001 +@SYMTestCaseDesc Pasted final paragraph formatting should match copied final paragraph + formatting. +@SYMTestPriority High +@SYMTestActions Enter three paragraphs into an empty document with the last paragraph + *not* terminated by a paragraph delimiter. Apply some custom + formatting to the last paragraph then copy and paste all of the text + into a new empty document. +@SYMTestExpectedResults The formatting in the pasted final paragraph should match the copied. +@SYMDEF INC115783 +*/ +LOCAL_C void testRichTextCutPaste2() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-ETEXT-CT-4001 Pasted final paragraph format should match copied final paragraph format ")); + TheReadBoard=NULL; + TheWriteBoard=NULL; + TheFileName=_L("z:\\test\\app-framework\\etext\\rtclipb2.pml"); // dummy - just to get global layers + ParseRichTextDocumentLC(); + TheText->Reset(); + TheText->InsertL(0,_L("\x2029\x2029SomeData")); //3 paras, last has no ending para delimiter); + + //create paragraph formatting (yellow bkg, indent & bullets) + CParaFormat* paraFormatIn = CParaFormat::NewLC(); + paraFormatIn->iBullet=new(ELeave)TBullet; + paraFormatIn->iBullet->iHeightInTwips=240; + paraFormatIn->iFillColor = 0xffffff00; + paraFormatIn->iIndentInTwips = 600; + TParaFormatMask paraFormatMask; + paraFormatMask.SetAttrib(EAttBullet); + paraFormatMask.SetAttrib(EAttFillColor); + paraFormatMask.SetAttrib(EAttIndent); + + TheText->ApplyParaFormatL(paraFormatIn,paraFormatMask,3,0); //Apply format to last para only + + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,TheText->DocumentLength()); + + TheText->Reset(); + test(TheText->DocumentLength()==0); + OpenReadClipboardLC(); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),TheText->DocumentLength()); + test(TheText->DocumentLength()==_L("\x2029\x2029SomeData").Length()); + test(TheText->ParagraphCount()==3); + + CParaFormat* paraFormatOut = CParaFormat::NewLC(); + TheText->GetParagraphFormatL(paraFormatOut,3); + + test(paraFormatOut->IsEqual(*paraFormatIn,paraFormatMask));// in and out should match + + CleanupStack::PopAndDestroy(4); + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + } + + +LOCAL_C void testRichTextCutPaste3() +// +// + { + test.Next(_L("Cutting paragraph of constant character formatting")); + TheFileName=_L("z:\\test\\app-framework\\etext\\rtclipb3.pml"); + ParseRichTextDocumentLC(); + // + TheReadBoard=NULL; + TheWriteBoard=NULL; + // + test.Start(_L("Copying to clipboard")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),4,3); + // + CleanupStack::PopAndDestroy(); // Last clipboard object + CleanupStack::PopAndDestroy(); // TheTextObject + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + test.End(); + } + + + +LOCAL_C void testRichTextCutPaste() +// +// + { + test.Start(_L("Cut&Paste - with Rich Text")); + ParseRichTextDocumentLC(); + OpenWriteClipboardLC(); + test.Next(_L("Copy zero-length text to the clipboard")); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,0); + + OpenReadClipboardLC(); + test.Next(_L("Paste from empty clipboard")); + TInt err=0; + TRAPD(ret, + err=TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),TheText->DocumentLength())); + UNUSED_VAR(ret); + if (err==KErrNotFound) + test.Printf(_L(" No recognised data to paste or clipboard empty\n\r")); + TInt fieldCount=TheText->FieldCount(); + test(fieldCount==0); + //////////////////////////////////////////////////////////////////////////// + test.Next(_L("Paste into empty RichText")); + TheText->Reset(); + TheText->InsertL(TheText->DocumentLength(),_L("SomeData")); + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,TheText->DocumentLength()); + TheText->Reset(); + test(TheText->DocumentLength()==0); + OpenReadClipboardLC(); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),TheText->DocumentLength()); + test(TheText->DocumentLength()==_L("SomeData").Length()); + test(TheText->ParagraphCount()==1); + fieldCount=TheText->FieldCount(); + test(fieldCount==0); + ///////////////////////////////////////////////////////////////////////////// + test.Next(_L("Pasting text only - no paragraph delimiter")); + TheText->Reset(); + TheText->InsertL(0,_L("the end")); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),4); + test(TheText->DocumentLength()==16); + ////////////////////////////////////////////////////////////////////////// + test.Next(_L("Paste @ start (pos=0)")); + TheText->Reset(); + TheText->InsertL(TheText->DocumentLength(),_L("SomeData")); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),0); + test(TheText->DocumentLength()==_L("SomeDataSomeData").Length()); + test(TheText->ParagraphCount()==1); + fieldCount=TheText->FieldCount(); + test(fieldCount==0); + //////////////////////////////////////////////////////////////////////////// + test.Next(_L("Paste @ end (DocumentLength())")); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),TheText->DocumentLength()); + test(TheText->DocumentLength()==_L("SomeDataSomeDataSomeData").Length()); + test(TheText->ParagraphCount()==1); + fieldCount=TheText->FieldCount(); + test(fieldCount==0); + //////////////////////////////////////////////////////////////////////////// + test.Next(_L("Paste @ middle")); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),4); + fieldCount=TheText->FieldCount(); + test(fieldCount==0); + TBuf<33> buf(_L("SomeSomeDataDataSomeDataSomeData")); + test(TheText->DocumentLength()==buf.Length()); + buf.Append(CEditableText::EParagraphDelimiter); + test(TheText->Read(0)==buf); + test(TheText->ParagraphCount()==1); + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + test.Next(_L("Pasting rich text inbetween 2 pictures")); + TheText->Reset(); + // + CXzePicture* pic1=CXzePicture::NewL('1'); + CXzePicture* pic2=CXzePicture::NewL('2'); + // + TPictureHeader hdr1; + TPictureHeader hdr2; + // + hdr1.iPictureType=KUidXzePictureType; + hdr2.iPictureType=KUidXzePictureType; + // + hdr1.iPicture=pic1; + hdr2.iPicture=pic2; + // + TheText->InsertL(0,hdr2); + TheText->InsertL(0,hdr1); + // + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,TheText->DocumentLength()); + // + OpenReadClipboardLC(); + + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),1); + test(TheText->DocumentLength()==4); + test(TheText->ParagraphCount()==1); + ///////////////////////////////////////////////////////////////////////////// + test.Next(_L("Pasting rich text with para delimiters")); + TheText->InsertL(1,CEditableText::EParagraphDelimiter); + // + OpenWriteClipboardLC(); + TheText->CopyToStoreL(TheWriteBoard->Store(),TheWriteBoard->StreamDictionary(),0,TheText->DocumentLength()); + // + OpenReadClipboardLC(); + TheText->PasteFromStoreL(TheReadBoard->Store(),TheReadBoard->StreamDictionary(),1); + test(TheText->DocumentLength()==10); + test(TheText->ParagraphCount()==3); + + ///////////////////////////////////////////////////////////////////////////// + CleanupStack::PopAndDestroy(); // Last clipboard object + CleanupStack::PopAndDestroy(); // TheTextObject + delete TheGlobalParaLayer; + delete TheGlobalCharLayer; + } + + +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, testRichTextCutPaste()); + test(r == KErrNone); + + TRAP(r, testRichTextCutPaste1()); + test(r == KErrNone); + + TRAP(r, testRichTextCutPaste1a()); + test(r == KErrNone); + + TRAP(r, testRichTextCutPaste1b()); + test(r == KErrNone); + + TRAP(r, testRichTextCutPaste2()); + test(r == KErrNone); + + TRAP(r, testRichTextCutPaste3()); + test(r == KErrNone); + + delete TheTrapCleanup; + + __UHEAP_MARKEND; + + ::DeleteDataFile(KOutputFile); //deletion of data files must be before call to End() - DEF047652 + + test.End(); + test.Close(); + + return 0; + }