1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/textrendering/texthandling/ttext/TRTCUSTM.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,915 @@
1.4 +/*
1.5 +* Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include <txtrich.h>
1.23 +#include <txtstyle.h>
1.24 +#include "TXTMRTSR.H"
1.25 +#include <gdi.h>
1.26 +#include <conpics.h>
1.27 +#include <s32mem.h>
1.28 +#include <s32file.h>
1.29 +#include <flddef.h>
1.30 +#include <fldbltin.h>
1.31 +#include <fldset.h>
1.32 +#include "TRTCUSTM.h"
1.33 +
1.34 +#define test(cond) \
1.35 + { \
1.36 + TBool __bb = (cond); \
1.37 + TEST(__bb); \
1.38 + if (!__bb) \
1.39 + { \
1.40 + ERR_PRINTF1(_L("ERROR: Test Failed")); \
1.41 + User::Leave(1); \
1.42 + } \
1.43 + }
1.44 +
1.45 +LOCAL_D RFs theFs;
1.46 +LOCAL_D CFileStore* TheStore;
1.47 +LOCAL_D CParaFormatLayer* GlobalParaFormatLayer;
1.48 +LOCAL_D CCharFormatLayer* GlobalCharFormatLayer;
1.49 +LOCAL_D CTrapCleanup* TheTrapCleanup;
1.50 +const TInt KTestCleanupStack=0x500;
1.51 +
1.52 +
1.53 +class TStoreResolver : public MRichTextStoreResolver
1.54 + {
1.55 +public:
1.56 + virtual const CStreamStore& StreamStoreL(TInt /*aPos*/)const {return *iStore;}
1.57 +public:
1.58 + CStreamStore* iStore;
1.59 + };
1.60 +
1.61 +
1.62 +////////////////////////////////////////////////////////////////////////////////////////////
1.63 +class TTestFieldFactoryTRTCUSTM : public MTextFieldFactory
1.64 + {
1.65 +public:
1.66 + // from MTextFieldFactory
1.67 + virtual CTextField* NewFieldL(TUid aFieldType);
1.68 + // Creates a field of the type specified
1.69 + // Returns NULL if it does not recognise/support the field type
1.70 + };
1.71 +
1.72 +CTextField* TTestFieldFactoryTRTCUSTM::NewFieldL(TUid aFieldType)
1.73 +// Creates a field (in aHeader) of the type specified in aHeader
1.74 +//
1.75 + {
1.76 + CTextField* field=NULL;
1.77 + if (aFieldType==KDateTimeFieldUid)
1.78 + field = (CTextField*)new(ELeave) CDateTimeField();
1.79 + return field;
1.80 + }
1.81 +/////////////////////////////////////////////////////////////////////////////////////////////
1.82 +
1.83 +void CT_TRTCUSTM::WriteInlineL(RWriteStream& aStream,CRichText* aRichText)
1.84 + {
1.85 + aRichText->CancelInsertCharFormat();
1.86 + aRichText->ExternalizeFieldDataL(aStream);
1.87 + aRichText->ExternalizeStyleDataL(aStream);
1.88 + TBool hasMarkupData=aRichText->HasMarkupData();
1.89 + aStream.WriteUint8L((TUint8)hasMarkupData!=EFalse);
1.90 + if (hasMarkupData)
1.91 + aRichText->ExternalizeMarkupDataL(aStream);
1.92 + aRichText->ExternalizePlainTextL(aStream);
1.93 + }
1.94 +
1.95 +void CT_TRTCUSTM::ReadInlineL(RReadStream& aStream,CRichText* aRichText)
1.96 + {
1.97 + aRichText->InternalizeFieldDataL(aStream);
1.98 + aRichText->InternalizeStyleDataL(aStream);
1.99 + TBool hasMarkupData=(TBool)aStream.ReadUint8L();
1.100 + if (hasMarkupData)
1.101 + aRichText->InternalizeMarkupDataL(aStream);
1.102 + aRichText->InternalizePlainTextL(aStream);
1.103 + }
1.104 +
1.105 +
1.106 +TStreamId CT_TRTCUSTM::PerformSaveL(CRichText* aRichText)
1.107 +//
1.108 + {
1.109 + RStoreWriteStream out;
1.110 + TStreamId id1=out.CreateLC(*TheStore);
1.111 + WriteInlineL(out,aRichText);
1.112 + delete aRichText;
1.113 + out.CommitL();
1.114 + CleanupStack::PopAndDestroy(); // out
1.115 + TheStore->CommitL();
1.116 + return id1;
1.117 + }
1.118 +
1.119 +
1.120 +CRichText* CT_TRTCUSTM::PerformLoadL(TStreamId aId)
1.121 +//
1.122 + {
1.123 + CRichText* text=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.124 + RStoreReadStream in;
1.125 + in.OpenLC(*TheStore,aId);
1.126 + TRAPD(ret,
1.127 + ReadInlineL(in,text));
1.128 + test(ret==KErrNone);
1.129 + CleanupStack::PopAndDestroy(); // in
1.130 + return text;
1.131 + }
1.132 +
1.133 +
1.134 +CStyleList* CT_TRTCUSTM::CreatePopulatedStyleList()
1.135 +//
1.136 + {
1.137 + //
1.138 + // Create style aswell.
1.139 + CStyleList* list=CStyleList::NewL();
1.140 + CParagraphStyle* style1=CParagraphStyle::NewL(*GlobalParaFormatLayer,*GlobalCharFormatLayer);
1.141 + CParagraphStyle* style2=CParagraphStyle::NewL(*GlobalParaFormatLayer,*GlobalCharFormatLayer);
1.142 + CParagraphStyle* style3=CParagraphStyle::NewL(*GlobalParaFormatLayer,*GlobalCharFormatLayer);
1.143 + RParagraphStyleInfo info1(style1);
1.144 + RParagraphStyleInfo info2(style2);
1.145 + RParagraphStyleInfo info3(style3);
1.146 + list->AppendL(&info1);
1.147 + list->AppendL(&info2);
1.148 + list->AppendL(&info3);
1.149 + return list;
1.150 + }
1.151 +
1.152 +_LIT(KTRtCustOutputFile,"c:\\etext\\TRTCUSTM.DAT");
1.153 +
1.154 +void CT_TRTCUSTM::CustomLoadSave()
1.155 + {
1.156 +// Set up the framework
1.157 + theFs.Delete(KTRtCustOutputFile);
1.158 + theFs.MkDirAll(KTRtCustOutputFile);
1.159 + TheStore=CPermanentFileStore::CreateLC(theFs,KTRtCustOutputFile,EFileRead|EFileWrite);
1.160 + TheStore->SetTypeL(TheStore->Layout());
1.161 +
1.162 +//
1.163 +// Case (1) Rich text with owned style list. - no markup data
1.164 +//
1.165 + INFO_PRINTF1(_L("RT + no markup + style list owned"));
1.166 + //
1.167 + // Setup the rich text
1.168 + CStyleList* list=CreatePopulatedStyleList();
1.169 + CRichText* richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer,*list);
1.170 + TBool hasMarkupData=richText1->HasMarkupData();
1.171 + test(hasMarkupData);
1.172 + richText1->InsertL(0,_L("hello"));
1.173 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.174 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.175 + //
1.176 + // Save the rich text
1.177 + TStreamId id1=PerformSaveL(richText1);
1.178 + //
1.179 + // Load the rich text
1.180 + CRichText* empty=NULL;
1.181 + TRAPD(ret,
1.182 + empty=PerformLoadL(id1));
1.183 + test(ret==KErrNone);
1.184 + hasMarkupData=empty->HasMarkupData();
1.185 + test(hasMarkupData);
1.186 + delete empty;
1.187 + empty=NULL;
1.188 +//
1.189 +// Case (2) Rich text with referenced style list. - no markup data
1.190 +//
1.191 + INFO_PRINTF1(_L("RT + no markup + style list externally owned"));
1.192 + //
1.193 + // Setup the rich text
1.194 + list=CreatePopulatedStyleList();
1.195 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer,*list,CEditableText::ESegmentedStorage,2);
1.196 + richText1->SetStyleListExternallyOwned(ETrue);
1.197 + hasMarkupData=richText1->HasMarkupData();
1.198 + test(!hasMarkupData);
1.199 + richText1->InsertL(0,_L("hello"));
1.200 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.201 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.202 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.203 + hasMarkupData=richText1->HasMarkupData();
1.204 + test(!hasMarkupData);
1.205 + //
1.206 + // Save the rich text
1.207 + id1=PerformSaveL(richText1);
1.208 + //
1.209 + // Load the rich text
1.210 + empty=PerformLoadL(id1);
1.211 + hasMarkupData=empty->HasMarkupData();
1.212 + test(!hasMarkupData);
1.213 + TInt paragraphCount=empty->ParagraphCount();
1.214 + test(paragraphCount==3);
1.215 + test(list->Count()==3); // the style list is now externally owned.
1.216 + delete empty;
1.217 + test(list->Count()==3); // the style list should not have been destroyed by the rich text
1.218 + delete list;
1.219 + empty=NULL;
1.220 +//
1.221 +// Case (3) Rich text with referenced style list. - with markup
1.222 +//
1.223 + INFO_PRINTF1(_L("RT + markup + style list externally owned"));
1.224 + // Setup the rich text
1.225 + list=CreatePopulatedStyleList();
1.226 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer,*list);
1.227 + richText1->SetStyleListExternallyOwned(ETrue);
1.228 + hasMarkupData=richText1->HasMarkupData();
1.229 + test(!hasMarkupData);
1.230 + richText1->InsertL(0,_L("hello"));
1.231 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.232 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.233 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.234 + CParaFormat* paraFormat=CParaFormat::NewLC();
1.235 + TParaFormatMask paraMask;
1.236 + paraFormat->iHorizontalAlignment=CParaFormat::ERightAlign;
1.237 + paraMask.SetAttrib(EAttAlignment);
1.238 + richText1->ApplyParaFormatL(paraFormat,paraMask,8,0);
1.239 + CleanupStack::PopAndDestroy(); // paraFormat
1.240 + hasMarkupData=richText1->HasMarkupData();
1.241 + test(hasMarkupData);
1.242 + //
1.243 + // Save the rich text
1.244 + id1=PerformSaveL(richText1);
1.245 + //
1.246 + // Load the rich text
1.247 + empty=PerformLoadL(id1);
1.248 + hasMarkupData=empty->HasMarkupData();
1.249 + test(hasMarkupData);
1.250 + paragraphCount=empty->ParagraphCount();
1.251 + test(paragraphCount==3);
1.252 + test(list->Count()==3); // the style list is now externally owned.
1.253 + delete empty;
1.254 + test(list->Count()==3); // the style list should not have been destroyed by the rich text
1.255 + delete list;
1.256 + empty=NULL;
1.257 +//
1.258 +// Case (4) Rich text with no style list. - no effective markup
1.259 +//
1.260 + INFO_PRINTF1(_L("RT + delete picture + no style list"));
1.261 + // Setup the rich text
1.262 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.263 + hasMarkupData=richText1->HasMarkupData();
1.264 + test(!hasMarkupData);
1.265 + richText1->InsertL(0,_L("hello"));
1.266 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.267 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.268 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.269 + //
1.270 + // Create & insert a picture
1.271 + CXzePicture* pic1=CXzePicture::NewL('o');
1.272 + TPictureHeader header1;
1.273 + TSize size;
1.274 + pic1->GetSizeInTwips(size);
1.275 + header1.iPictureType=KUidXzePictureType;
1.276 + header1.iPicture=pic1;
1.277 + header1.iSize=size;
1.278 + richText1->InsertL(3,header1);
1.279 + hasMarkupData=richText1->HasMarkupData();
1.280 + test(hasMarkupData);
1.281 + richText1->DeleteL(3,1);
1.282 + hasMarkupData=richText1->HasMarkupData();
1.283 + test(!hasMarkupData);
1.284 + //
1.285 + // Save the rich text
1.286 + id1=PerformSaveL(richText1);
1.287 + //
1.288 + // Load the rich text
1.289 + empty=PerformLoadL(id1);
1.290 + hasMarkupData=empty->HasMarkupData();
1.291 + test(!hasMarkupData);
1.292 + paragraphCount=empty->ParagraphCount();
1.293 + test(paragraphCount==3);
1.294 + delete empty;
1.295 + empty=NULL;
1.296 +//
1.297 +// Case (5) Rich text with SetInsertCharFormat()
1.298 +//
1.299 + INFO_PRINTF1(_L("RT + SetInsertCharFormatL()"));
1.300 + // Setup the rich text
1.301 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.302 + hasMarkupData=richText1->HasMarkupData();
1.303 + test(!hasMarkupData);
1.304 + richText1->InsertL(0,_L("hello"));
1.305 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.306 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.307 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.308 + TCharFormat charFormat;
1.309 + TCharFormatMask charMask;
1.310 + charFormat.iFontPresentation.iStrikethrough=EStrikethroughOn;
1.311 + charMask.SetAttrib(EAttFontStrikethrough);
1.312 + richText1->SetInsertCharFormatL(charFormat,charMask,3);
1.313 + hasMarkupData=richText1->HasMarkupData();
1.314 + test(hasMarkupData);
1.315 + //
1.316 + // Save the rich text
1.317 + id1=PerformSaveL(richText1);
1.318 + //
1.319 + // Load the rich text
1.320 + empty=PerformLoadL(id1);
1.321 + hasMarkupData=empty->HasMarkupData();
1.322 + test(!hasMarkupData);
1.323 + paragraphCount=empty->ParagraphCount();
1.324 + test(paragraphCount==3);
1.325 + delete empty;
1.326 + empty=NULL;
1.327 +//
1.328 +// Case (6) Rich text with components - default re/store used.
1.329 +//
1.330 +
1.331 + INFO_PRINTF1(_L("RT + components"));
1.332 + // Setup the rich text
1.333 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.334 + hasMarkupData=richText1->HasMarkupData();
1.335 + test(!hasMarkupData);
1.336 + richText1->InsertL(0,_L("hello"));
1.337 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.338 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.339 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.340 + //
1.341 + // Create & insert some fields
1.342 + TTestFieldFactoryTRTCUSTM factory;
1.343 + richText1->SetFieldFactory(&factory);
1.344 + CTextField* field=NULL;
1.345 + CTextField* field2=NULL;
1.346 + TRAP(ret,
1.347 + field=factory.NewFieldL(KDateTimeFieldUid)); test(ret==KErrNone);
1.348 + TRAP(ret,
1.349 + field2=factory.NewFieldL(KDateTimeFieldUid)); test(ret==KErrNone);
1.350 + TRAP(ret,
1.351 + richText1->InsertFieldL(0,field,KDateTimeFieldUid)); test(ret==KErrNone);
1.352 + TRAP(ret,
1.353 + richText1->UpdateFieldL(0));
1.354 + test(ret==KErrNone);
1.355 + TRAP(ret,
1.356 + richText1->InsertFieldL(0,field2,KDateTimeFieldUid));
1.357 + test(ret==KErrNone);
1.358 + TRAP(ret,
1.359 + richText1->UpdateFieldL(0));
1.360 + test(ret==KErrNone);
1.361 + //
1.362 + // Create & insert a picture
1.363 + pic1=CXzePicture::NewL('o');
1.364 + pic1->GetSizeInTwips(size);
1.365 + header1.iPictureType=KUidXzePictureType;
1.366 + header1.iPicture=pic1;
1.367 + header1.iSize=size;
1.368 + richText1->InsertL(0,header1);
1.369 + hasMarkupData=richText1->HasMarkupData();
1.370 + test(hasMarkupData);
1.371 + //
1.372 + // Save the rich text
1.373 + TStreamId head=richText1->StoreL(*TheStore);
1.374 + delete richText1;
1.375 + //
1.376 + // Load the rich text
1.377 + empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.378 + empty->SetFieldFactory(&factory);
1.379 + empty->RestoreL(*TheStore,head);
1.380 + //
1.381 + // Create the correct factories
1.382 + TStoreResolver storeResolver;
1.383 + storeResolver.iStore=TheStore;
1.384 + MDemPictureFactory* pictureFactory=new(ELeave) MDemPictureFactory;
1.385 +
1.386 + empty->SetPictureFactory(pictureFactory,&storeResolver);
1.387 + CXzePicture* rPic=(CXzePicture*)empty->PictureHandleL(0);
1.388 + test(rPic->iLabel=='o');
1.389 + //
1.390 + hasMarkupData=empty->HasMarkupData();
1.391 + test(hasMarkupData);
1.392 + paragraphCount=empty->ParagraphCount();
1.393 + test(paragraphCount==3);
1.394 + delete empty;
1.395 + empty=NULL;
1.396 + delete pictureFactory;
1.397 +//
1.398 +// Case (7) Rich text with fields with referenced style list with markup
1.399 +//
1.400 + INFO_PRINTF1(_L("RT + fields + markup + style list"));
1.401 + // Setup the rich text
1.402 + list=CreatePopulatedStyleList();
1.403 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer,*list);
1.404 + hasMarkupData=richText1->HasMarkupData();
1.405 + test(hasMarkupData);
1.406 + richText1->InsertL(0,_L("hello"));
1.407 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.408 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.409 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.410 + paraFormat=CParaFormat::NewLC();
1.411 + paraMask.ClearAll();
1.412 + paraFormat->iHorizontalAlignment=CParaFormat::ERightAlign;
1.413 + paraMask.SetAttrib(EAttAlignment);
1.414 + richText1->ApplyParaFormatL(paraFormat,paraMask,8,0);
1.415 + CleanupStack::PopAndDestroy(); // paraFormat
1.416 + hasMarkupData=richText1->HasMarkupData();
1.417 + test(hasMarkupData);
1.418 + //
1.419 + // Now add a text field to this.
1.420 + richText1->SetFieldFactory(&factory);
1.421 + field=NULL;
1.422 + TRAP(ret,
1.423 + field=factory.NewFieldL(KDateTimeFieldUid));
1.424 + test(ret==KErrNone);
1.425 + TRAP(ret,
1.426 + richText1->InsertFieldL(0,field,KDateTimeFieldUid));
1.427 + test(ret==KErrNone);
1.428 + TRAP(ret,
1.429 + richText1->UpdateFieldL(0));
1.430 + test(ret==KErrNone);
1.431 + //
1.432 + // Save the rich text
1.433 + //
1.434 + // 1st the components.
1.435 + CStoreMap* map=CStoreMap::NewLC(*TheStore);
1.436 + richText1->StoreFieldComponentsL(*TheStore,*map);
1.437 + //
1.438 + RStoreWriteStream out(*map);
1.439 + id1=out.CreateLC(*TheStore);
1.440 + //
1.441 + richText1->CancelInsertCharFormat();
1.442 + richText1->ExternalizeFieldDataL(out);
1.443 + richText1->ExternalizeStyleDataL(out);
1.444 + hasMarkupData=richText1->HasMarkupData();
1.445 + out.WriteUint8L((TUint8)hasMarkupData!=EFalse);
1.446 + if (hasMarkupData)
1.447 + richText1->ExternalizeMarkupDataL(out);
1.448 + richText1->ExternalizePlainTextL(out);
1.449 + //
1.450 + delete richText1;
1.451 + out.CommitL();
1.452 + //
1.453 + map->Reset();
1.454 + CleanupStack::PopAndDestroy(2); // map,out
1.455 + TheStore->CommitL();
1.456 + //
1.457 + // Load the rich text
1.458 + empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.459 + empty->SetFieldFactory(&factory);
1.460 + RStoreReadStream in;
1.461 + in.OpenLC(*TheStore,id1);
1.462 + empty->InternalizeFieldDataL(in);
1.463 + empty->InternalizeStyleDataL(in);
1.464 + hasMarkupData=(TBool)in.ReadUint8L();
1.465 + if (hasMarkupData)
1.466 + empty->InternalizeMarkupDataL(in);
1.467 + empty->InternalizePlainTextL(in);
1.468 + CleanupStack::PopAndDestroy(); // in
1.469 + //
1.470 + empty->RestoreFieldComponentsL(*TheStore);
1.471 + hasMarkupData=empty->HasMarkupData();
1.472 + test(hasMarkupData);
1.473 + paragraphCount=empty->ParagraphCount();
1.474 + test(paragraphCount==3);
1.475 + test(empty->StyleList()->Count()==3); // the style list is now externally owned.
1.476 + delete empty;
1.477 + empty=NULL;
1.478 +//
1.479 +// Case (8) Rich text with fields with referenced style list with markup - default store
1.480 +//
1.481 + INFO_PRINTF1(_L("RT + fields + markup + style list - default store"));
1.482 + // Setup the rich text
1.483 + list=CreatePopulatedStyleList();
1.484 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer,*list);
1.485 + hasMarkupData=richText1->HasMarkupData();
1.486 + test(hasMarkupData);
1.487 + richText1->InsertL(0,_L("hello"));
1.488 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.489 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.490 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.491 + paraFormat=CParaFormat::NewLC();
1.492 + paraMask.ClearAll();
1.493 + paraFormat->iHorizontalAlignment=CParaFormat::ERightAlign;
1.494 + paraMask.SetAttrib(EAttAlignment);
1.495 + richText1->ApplyParaFormatL(paraFormat,paraMask,8,0);
1.496 + CleanupStack::PopAndDestroy(); // paraFormat
1.497 + hasMarkupData=richText1->HasMarkupData();
1.498 + test(hasMarkupData);
1.499 + //
1.500 + // Now add a text field to this.
1.501 + richText1->SetFieldFactory(&factory);
1.502 + field=NULL;
1.503 + TRAP(ret,
1.504 + field=factory.NewFieldL(KDateTimeFieldUid));
1.505 + test(ret==KErrNone);
1.506 + TRAP(ret,
1.507 + richText1->InsertFieldL(0,field,KDateTimeFieldUid));
1.508 + test(ret==KErrNone);
1.509 + TRAP(ret,
1.510 + richText1->UpdateFieldL(0));
1.511 + test(ret==KErrNone);
1.512 + //
1.513 + // Save the rich text
1.514 + id1=richText1->StoreL(*TheStore);
1.515 + delete richText1;
1.516 + //
1.517 + // Load the rich text
1.518 + empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.519 + empty->SetFieldFactory(&factory);
1.520 + empty->RestoreL(*TheStore,id1);
1.521 + //
1.522 + hasMarkupData=empty->HasMarkupData();
1.523 + test(hasMarkupData);
1.524 + paragraphCount=empty->ParagraphCount();
1.525 + test(paragraphCount==3);
1.526 + TEtextComponentInfo ci=empty->ComponentInfo();
1.527 + test(ci.iFieldCount==1);
1.528 + test(ci.iStyleCount==3);
1.529 + delete empty;
1.530 + empty=NULL; //
1.531 +//
1.532 +// Case (9) Rich text with no components whatsoever - default store
1.533 +//
1.534 + INFO_PRINTF1(_L("RT + no markup whatsoever - default store"));
1.535 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.536 + hasMarkupData=richText1->HasMarkupData();
1.537 + test(!hasMarkupData);
1.538 + richText1->InsertL(0,_L("hello"));
1.539 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.540 + richText1->InsertL(richText1->DocumentLength(),_L("there"));
1.541 + richText1->InsertL(richText1->DocumentLength(),CEditableText::EParagraphDelimiter);
1.542 + //
1.543 + // Save the rich text
1.544 + id1=richText1->StoreL(*TheStore);
1.545 + delete richText1;
1.546 + //
1.547 + // Load the rich text
1.548 + empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.549 + empty->RestoreL(*TheStore,id1);
1.550 + //
1.551 + hasMarkupData=empty->HasMarkupData();
1.552 + test(!hasMarkupData);
1.553 + paragraphCount=empty->ParagraphCount();
1.554 + test(paragraphCount==3);
1.555 + ci=empty->ComponentInfo();
1.556 + test(ci.iFieldCount==0);
1.557 + test(ci.iStyleCount==0);
1.558 + test(ci.iPictureCount==0);
1.559 + delete empty;
1.560 + empty=NULL;
1.561 + //
1.562 + //
1.563 + CleanupStack::PopAndDestroy(); // TheStore
1.564 + }
1.565 +
1.566 +/**
1.567 +@SYMTestCaseID SYSLIB-ETEXT-CT-3380
1.568 +@SYMTestCaseDesc Inserting and deleting rich text and verify behaviours of DeleteParagraph(), Delete() and NotifyDelete();
1.569 + ie. when encounter paragraph delimiter and hidden character
1.570 +@SYMTestPriority High
1.571 +@SYMTestActions 1. Insert and delete a whole paragraph of rich text
1.572 + 2. Insert a paragraph and delete some text
1.573 + 3. Insert 2nd paragraph and DeleteParagraph() both
1.574 + 4. Insert field to rich text object and delete field
1.575 + 5. Insert field to rich text object after some plain text and delete it
1.576 + 6. Insert field to rich text object in between two plain texts then delete the field to merge the texts
1.577 + 7. Insert plain text in between two fields to rich text object then delete plain text to merge two fields
1.578 +@SYMTestExpectedResults CTextFieldSet, CPlainText, CRichText's APIs for performing various types of deletion function properly when
1.579 + dealing with paragraph delimiter and hidden characters in a paragraph
1.580 +@SYMDEF PDEF101757
1.581 +*/
1.582 +void CT_TRTCUSTM::TestDEF101757()
1.583 + {
1.584 + TFindFieldInfo info;
1.585 + TTestFieldFactoryTRTCUSTM factory;
1.586 + CTextField* field=NULL;
1.587 + CTextField* field1=NULL;
1.588 + CTextField* field2=NULL;
1.589 + CTextField* field3=NULL;
1.590 + CTextField* field4=NULL;
1.591 +
1.592 + _LIT(KSample1, "Hello"); // length:5
1.593 + _LIT(KSample2, "How are you"); // length:11
1.594 +
1.595 + INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-ETEXT-CT-3380 Insertion and deletion to rich text object "));
1.596 +
1.597 + CRichText* richText=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.598 + CleanupStack::PushL(richText);
1.599 +
1.600 + // Case1
1.601 + // Insert and delete a whole paragraph of rich text
1.602 + richText->InsertL(0, KSample1);
1.603 + richText->InsertL(richText->DocumentLength(),CEditableText::EParagraphDelimiter);
1.604 + test(richText->DocumentLength()==6);
1.605 +
1.606 + richText->DeleteParagraph(0, 5); //do not delete para delimiter
1.607 +
1.608 + richText->InsertL(0, KSample1);
1.609 + richText->InsertL(richText->DocumentLength(),CEditableText::EParagraphDelimiter);
1.610 + test(richText->DocumentLength()==7);
1.611 +
1.612 + richText->DeleteParagraph(0, 7); //delete para delimiter
1.613 +
1.614 + test(richText->DocumentLength()==0);
1.615 + test(richText->ParagraphCount()==1);
1.616 +
1.617 + // Case2
1.618 + // Insert a paragraph and delete some text
1.619 + richText->InsertL(0, KSample2);
1.620 + richText->InsertL(richText->DocumentLength(),CEditableText::EParagraphDelimiter);
1.621 + test(richText->DocumentLength()==12);
1.622 +
1.623 + richText->DeleteParagraph(10, 1); //delete last char 'u' and not para delimter
1.624 + test(richText->DocumentLength()==11);
1.625 +
1.626 + richText->DeleteParagraph(9, 2); //delete last char 'o' and also para delimter
1.627 + test(richText->DocumentLength()==9);
1.628 + //should not panic due to fix for PDEF101757
1.629 +
1.630 + test(richText->ParagraphCount()==1);
1.631 +
1.632 + // Case3
1.633 + // Insert 2nd paragraph and DeleteParagraph() both
1.634 + richText->InsertL(richText->DocumentLength(),CEditableText::EParagraphDelimiter);
1.635 + test(richText->ParagraphCount()==2);
1.636 + richText->InsertL(richText->DocumentLength(),KSample1);
1.637 + richText->InsertL(richText->DocumentLength(),CEditableText::EParagraphDelimiter);
1.638 + test(richText->DocumentLength()==16);
1.639 + test(richText->ParagraphCount()==3); //2 paragraph delimiters including EOD delimiter (always there)
1.640 +
1.641 + richText->DeleteParagraph(0, 16);
1.642 + test(richText->DocumentLength()==0);
1.643 + test(richText->ParagraphCount()==1); //2 paragrsphs deleted
1.644 +
1.645 + // Case4
1.646 + // Insert field to rich text object and delete field
1.647 + richText->SetFieldFactory(&factory);
1.648 + field=factory.NewFieldL(KDateTimeFieldUid); // TUid KDateTimeFieldUid: length:10
1.649 + CleanupStack::PushL(field);
1.650 + richText->InsertFieldL(0,field,KDateTimeFieldUid);
1.651 + CleanupStack::Pop(field);//richtext has taken ownership successfully
1.652 +
1.653 + richText->UpdateFieldL(0);
1.654 + test(richText->FieldCount()==1);
1.655 + richText->DeleteParagraph(0, 10);
1.656 + richText->UpdateFieldL(0);
1.657 + test(richText->FieldCount()==0);
1.658 +
1.659 + // Case5
1.660 + // Insert field to rich text object after some plain text and delete it
1.661 + richText->InsertL(0, KSample1);
1.662 + field1=factory.NewFieldL(KDateTimeFieldUid);
1.663 + CleanupStack::PushL(field1);
1.664 + richText->InsertFieldL(5, field1, KDateTimeFieldUid);
1.665 + CleanupStack::Pop(field1);
1.666 + richText->UpdateFieldL(5);
1.667 + test(richText->FieldCount()==1);
1.668 + richText->DeleteParagraph(5, 10);
1.669 + test(richText->FieldCount()==0);
1.670 +
1.671 + // Case6
1.672 + // Insert field to rich text object in between two plain texts then delete the field to merge the texts
1.673 + field2=factory.NewFieldL(KDateTimeFieldUid);
1.674 + CleanupStack::PushL(field2);
1.675 + richText->InsertFieldL(5, field2, KDateTimeFieldUid);
1.676 + CleanupStack::Pop(field2);
1.677 + richText->UpdateFieldL(5);
1.678 + richText->InsertL(14, KSample1);
1.679 + richText->DeleteParagraph(5, 10);
1.680 + test(richText->DocumentLength()==10); //two plain texts merged
1.681 + richText->DeleteParagraph(0, 10);
1.682 + test(richText->FieldCount()==0);
1.683 + test(richText->DocumentLength()==0);
1.684 +
1.685 + // Case7
1.686 + // Insert plain text in between two fields to rich text object then delete plain text to merge two fields
1.687 + field3=factory.NewFieldL(KDateTimeFieldUid);
1.688 + field4=factory.NewFieldL(KDateTimeFieldUid);
1.689 +
1.690 + CleanupStack::PushL(field3);
1.691 + richText->InsertFieldL(0, field3, KDateTimeFieldUid);
1.692 + CleanupStack::Pop(field3);
1.693 + richText->UpdateFieldL(0);
1.694 +
1.695 + richText->InsertL(10, KSample1);
1.696 +
1.697 + CleanupStack::PushL(field4);
1.698 + richText->InsertFieldL(15, field4, KDateTimeFieldUid);
1.699 + CleanupStack::Pop(field4);
1.700 + richText->UpdateFieldL(15);
1.701 + richText->DeleteParagraph(10, 5);
1.702 +
1.703 + richText->FindFields(info,5);
1.704 + test(info.iFirstFieldLen==10);
1.705 + test(info.iFirstFieldPos==0);
1.706 + richText->FindFields(info,15);
1.707 + test(info.iFirstFieldLen==10);
1.708 + test(info.iFirstFieldPos==10);
1.709 + test(richText->FieldCount()==2);
1.710 +
1.711 + CleanupStack::PopAndDestroy(richText);
1.712 + }
1.713 +
1.714 +
1.715 +//Testcode for INC054540
1.716 +void CT_TRTCUSTM::TestINC054540()
1.717 + {
1.718 + theFs.Delete(KTRtCustOutputFile);
1.719 + theFs.MkDirAll(KTRtCustOutputFile);
1.720 + TheStore=CPermanentFileStore::CreateLC(theFs,KTRtCustOutputFile,EFileRead|EFileWrite);
1.721 + TheStore->SetTypeL(TheStore->Layout());
1.722 +//
1.723 +//test 1: Test INC054540 fix for 255 fields
1.724 +//
1.725 + INFO_PRINTF1(_L("test"));
1.726 +
1.727 + CRichText* richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.728 + //
1.729 + // Now add a text field to this.
1.730 + TTestFieldFactoryTRTCUSTM factory;
1.731 + richText1->SetFieldFactory(&factory);
1.732 + CTextField* field=NULL;
1.733 + TInt x=0;
1.734 + //add 255 fields
1.735 + while(x<255)
1.736 + {
1.737 + TRAPD(ret,field=factory.NewFieldL(KDateTimeFieldUid));
1.738 + test(ret==KErrNone);
1.739 + TRAP(ret,richText1->InsertFieldL(0,field,KDateTimeFieldUid));
1.740 + test(ret==KErrNone);
1.741 + TRAP(ret,richText1->UpdateFieldL(0));
1.742 + test(ret==KErrNone);
1.743 + x++;
1.744 + }
1.745 + // Save the rich text
1.746 + //
1.747 + CStoreMap* map=CStoreMap::NewLC(*TheStore);
1.748 + richText1->StoreFieldComponentsL(*TheStore,*map);
1.749 + //
1.750 + RStoreWriteStream out1(*map);
1.751 + TStreamId id1=out1.CreateLC(*TheStore);
1.752 + //
1.753 + richText1->ExternalizeFieldDataL(out1);
1.754 + //
1.755 + delete richText1;
1.756 + out1.CommitL();
1.757 + //
1.758 + map->Reset();
1.759 + CleanupStack::PopAndDestroy(2); // map,out1
1.760 + TheStore->CommitL();
1.761 + //
1.762 + // Load the rich text
1.763 + CRichText* empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.764 + empty->SetFieldFactory(&factory);
1.765 + RStoreReadStream in;
1.766 + in.OpenLC(*TheStore,id1);
1.767 + empty->InternalizeFieldDataL(in);
1.768 + CleanupStack::PopAndDestroy(); // in
1.769 + //
1.770 + empty->RestoreFieldComponentsL(*TheStore);
1.771 + test(empty->FieldCount()==255);
1.772 + delete empty;
1.773 + empty=NULL;
1.774 +
1.775 +//
1.776 +//test 2: Test INC054540 fix for more than 255 fields
1.777 +//
1.778 + INFO_PRINTF1(_L("test for more than 255 fields"));
1.779 + richText1=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.780 + // Add the text fields
1.781 + richText1->SetFieldFactory(&factory);
1.782 + field=NULL;
1.783 + x=0;
1.784 + //add 256 fields
1.785 + while(x<256)
1.786 + {
1.787 + TRAPD(ret,field=factory.NewFieldL(KDateTimeFieldUid));
1.788 + test(ret==KErrNone);
1.789 + TRAP(ret,richText1->InsertFieldL(0,field,KDateTimeFieldUid));
1.790 + test(ret==KErrNone);
1.791 + TRAP(ret,richText1->UpdateFieldL(0));
1.792 + test(ret==KErrNone);
1.793 + x++;
1.794 + }
1.795 + // Save the rich text
1.796 + //
1.797 + map=CStoreMap::NewLC(*TheStore);
1.798 + richText1->StoreFieldComponentsL(*TheStore,*map);
1.799 + //
1.800 + RStoreWriteStream out2(*map);
1.801 + id1=out2.CreateLC(*TheStore);
1.802 + //
1.803 + richText1->ExternalizeFieldDataL(out2);
1.804 + //
1.805 + delete richText1;
1.806 + out2.CommitL();
1.807 + //
1.808 + map->Reset();
1.809 + CleanupStack::PopAndDestroy(2); // map,out2
1.810 + TheStore->CommitL();
1.811 + //
1.812 + // Load the rich text
1.813 + empty=CRichText::NewL(GlobalParaFormatLayer,GlobalCharFormatLayer);
1.814 + empty->SetFieldFactory(&factory);
1.815 + in.OpenLC(*TheStore,id1);
1.816 + empty->InternalizeFieldDataL(in);
1.817 + CleanupStack::PopAndDestroy(); // in
1.818 + //
1.819 + empty->RestoreFieldComponentsL(*TheStore);
1.820 + test(empty->FieldCount()==256);
1.821 + delete empty;
1.822 + empty=NULL;
1.823 + //
1.824 + //
1.825 + CleanupStack::PopAndDestroy(); // TheStore
1.826 + }
1.827 +
1.828 +
1.829 +void CT_TRTCUSTM::doMainL()
1.830 + {
1.831 + GlobalParaFormatLayer=CParaFormatLayer::NewL();
1.832 + GlobalCharFormatLayer=CCharFormatLayer::NewL();
1.833 + theFs.Connect();
1.834 + //
1.835 + CustomLoadSave();
1.836 + TestDEF101757();
1.837 + TestINC054540();
1.838 + //
1.839 + delete GlobalParaFormatLayer;
1.840 + delete GlobalCharFormatLayer;
1.841 + theFs.Close();
1.842 + }
1.843 +
1.844 +
1.845 +void CT_TRTCUSTM::setupCleanup()
1.846 +//
1.847 +// Initialise the cleanup stack.
1.848 +//
1.849 + {
1.850 + TheTrapCleanup=CTrapCleanup::New();
1.851 + test(TheTrapCleanup!=NULL);
1.852 + TRAPD(r,\
1.853 + {\
1.854 + for (TInt i=KTestCleanupStack;i>0;i--)\
1.855 + CleanupStack::PushL((TAny*)0);\
1.856 + CleanupStack::Pop(KTestCleanupStack);\
1.857 + });
1.858 + test(r==KErrNone);
1.859 + }
1.860 +
1.861 +
1.862 +void CT_TRTCUSTM::DeleteDataFile(const TDesC& aFullName)
1.863 + {
1.864 + RFs fsSession;
1.865 + TInt err = fsSession.Connect();
1.866 + if(err == KErrNone)
1.867 + {
1.868 + TEntry entry;
1.869 + if(fsSession.Entry(aFullName, entry) == KErrNone)
1.870 + {
1.871 + RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
1.872 + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
1.873 + if(err != KErrNone)
1.874 + {
1.875 + RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
1.876 + }
1.877 + err = fsSession.Delete(aFullName);
1.878 + if(err != KErrNone)
1.879 + {
1.880 + RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
1.881 + }
1.882 + }
1.883 + fsSession.Close();
1.884 + }
1.885 + else
1.886 + {
1.887 + RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
1.888 + }
1.889 + }
1.890 +
1.891 +
1.892 +CT_TRTCUSTM::CT_TRTCUSTM()
1.893 + {
1.894 + SetTestStepName(KTestStep_T_TRTCUSTM);
1.895 + }
1.896 +
1.897 +TVerdict CT_TRTCUSTM::doTestStepL()
1.898 + {
1.899 + SetTestStepResult(EFail);
1.900 +
1.901 + setupCleanup();
1.902 + __UHEAP_MARK;
1.903 +
1.904 + INFO_PRINTF1(_L("TRTCUSTM"));
1.905 + INFO_PRINTF1(_L("Testing custom save/load optimization"));
1.906 + TRAPD(error1, doMainL());
1.907 + DeleteDataFile(KTRtCustOutputFile); //deletion of data files must be before call to End() - DEF047652
1.908 +
1.909 + __UHEAP_MARKEND;
1.910 + delete TheTrapCleanup;
1.911 +
1.912 + if(error1 == KErrNone)
1.913 + {
1.914 + SetTestStepResult(EPass);
1.915 + }
1.916 +
1.917 + return TestStepResult();
1.918 + }