|
1 /* |
|
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <txtetext.h> |
|
20 #include <txtglobl.h> |
|
21 #include <txtfmlyr.h> |
|
22 #include <s32mem.h> |
|
23 #include <s32file.h> |
|
24 #include <e32test.h> |
|
25 #include <fldbase.h> |
|
26 #include <fldbltin.h> |
|
27 #include <flddef.h> |
|
28 |
|
29 const TInt KTestCleanupStack=0x20; |
|
30 const TInt KTestExpandSize=0x20; |
|
31 |
|
32 LOCAL_D CTrapCleanup* TheTrapCleanup; |
|
33 LOCAL_D RTest test(_L("T_CONVS - EditableText Persistence")); |
|
34 LOCAL_D TPtrC bigBuf(_L("This is a very big buffer indeed, containing text and special characters,\ |
|
35 big enough to fill a segment of an editable text component that employs segmented storage")); |
|
36 |
|
37 //////////////////////////////////////////////////////////////////////////////////////////// |
|
38 class TTestFieldFactory : public MTextFieldFactory |
|
39 { |
|
40 public: |
|
41 // from MTextFieldFactory |
|
42 virtual CTextField* NewFieldL(TUid aFieldType); |
|
43 // Creates a field of the type specified |
|
44 // Returns NULL if it does not recognise/support the field type |
|
45 }; |
|
46 |
|
47 CTextField* TTestFieldFactory::NewFieldL(TUid aFieldType) |
|
48 // Creates a field (in aHeader) of the type specified in aHeader |
|
49 // |
|
50 { |
|
51 CTextField* field=NULL; |
|
52 if (aFieldType==KDateTimeFieldUid) |
|
53 field = (CTextField*)new(ELeave) CDateTimeField(); |
|
54 return field; |
|
55 } |
|
56 ///////////////////////////////////////////////////////////////////////////////////////////// |
|
57 |
|
58 template <class T> |
|
59 void testCopy(T &aCopy,const T &anOriginal) |
|
60 // |
|
61 // Copy anOriginal to aCopy using memory-based streams. |
|
62 // |
|
63 { |
|
64 CBufSeg *buf=CBufSeg::NewL(KTestExpandSize); |
|
65 if (buf==NULL) |
|
66 test.Panic(_L("Allocating buffer")); |
|
67 |
|
68 // Write anOriginal out to the buffer. |
|
69 RBufWriteStream out(*buf); |
|
70 TRAPD(r,out<<anOriginal); |
|
71 test(r==KErrNone); |
|
72 TRAP(r,out.CommitL()); |
|
73 if (r!=KErrNone) |
|
74 test.Panic(_L("Committing write stream")); |
|
75 |
|
76 // Read anOriginal in from the buffer. |
|
77 RBufReadStream in(*buf); |
|
78 TRAP(r,in>>aCopy); |
|
79 test(r==KErrNone); |
|
80 |
|
81 // See if it's consumed the lot. |
|
82 TRAP(r,in.ReadUint8L()); |
|
83 test(r==KErrEof); |
|
84 // |
|
85 delete buf; |
|
86 } |
|
87 |
|
88 _LIT(KOutputFile, "c:\\etext\\t_convs.tst"); |
|
89 template <class T> |
|
90 void testStoreRestoreL(T& aCopy,const T& aOriginal) |
|
91 // Test document persistance. |
|
92 // |
|
93 { |
|
94 // set up the store |
|
95 RFs theFs; |
|
96 theFs.Connect(); |
|
97 // |
|
98 theFs.Delete(KOutputFile); |
|
99 theFs.MkDirAll(KOutputFile); |
|
100 CFileStore* theStore=CDirectFileStore::CreateL(theFs,KOutputFile,EFileRead|EFileWrite); |
|
101 CleanupStack::PushL(theStore); |
|
102 theStore->SetTypeL(KDirectFileStoreLayoutUid); |
|
103 // |
|
104 // store the original |
|
105 TStreamId id(0); |
|
106 TRAPD(ret,id=aOriginal.StoreL(*theStore)); |
|
107 test(ret==KErrNone); |
|
108 // |
|
109 // restore into the copy |
|
110 TRAP(ret,aCopy.RestoreL(*theStore,id)); |
|
111 test(ret==KErrNone); |
|
112 // |
|
113 // tidy up |
|
114 CleanupStack::PopAndDestroy(); // theStore |
|
115 theFs.Close(); |
|
116 } |
|
117 |
|
118 |
|
119 template <class T> |
|
120 void testCopyChain(T &aCopy,const T &anOriginal,TInt aExcludeCount,const CFormatLayer* aBase) |
|
121 // |
|
122 // Copy anOriginal to aCopy using memory-based streams. |
|
123 // |
|
124 { |
|
125 CBufSeg *buf=CBufSeg::NewL(KTestExpandSize); |
|
126 if (buf==NULL) |
|
127 test.Panic(_L("Allocating buffer")); |
|
128 |
|
129 // Write anOriginal out to the buffer. |
|
130 RBufWriteStream out(*buf); |
|
131 TRAPD(r,anOriginal.ExternalizeChainL(out,aExcludeCount)); |
|
132 test(r==KErrNone); |
|
133 TRAP(r,out.CommitL()); |
|
134 if (r!=KErrNone) |
|
135 test.Panic(_L("Committing write stream")); |
|
136 |
|
137 // Read anOriginal in from the buffer. |
|
138 RBufReadStream in(*buf); |
|
139 TRAP(r,aCopy.InternalizeChainL(in,aBase)); |
|
140 test(r==KErrNone); |
|
141 |
|
142 // See if it's consumed the lot. |
|
143 TRAP(r,in.ReadUint8L()); |
|
144 test(r!=KErrNone); |
|
145 // |
|
146 delete buf; |
|
147 } |
|
148 |
|
149 |
|
150 LOCAL_C TInt IsEqual(const CPlainText* aCopy,const CPlainText* aOriginal) |
|
151 // |
|
152 // Returns true if aCopy contents matches aOriginal contents. |
|
153 // Takes account of multiple segments of a segmented text component. |
|
154 // |
|
155 { |
|
156 TInt lengthOfOriginal=aOriginal->DocumentLength(); |
|
157 TInt lengthOfCopy=aCopy->DocumentLength(); |
|
158 test(lengthOfOriginal==lengthOfCopy); |
|
159 // |
|
160 TPtrC copy,orig; |
|
161 // |
|
162 TInt lengthRead=0; |
|
163 while(lengthRead<=lengthOfOriginal) |
|
164 { |
|
165 copy.Set((aCopy->Read(lengthRead))); |
|
166 orig.Set((aOriginal->Read(lengthRead))); |
|
167 for (TInt offset=0; offset<orig.Length(); offset++) |
|
168 test(copy[offset]==orig[offset]); |
|
169 lengthRead+=orig.Length(); |
|
170 } |
|
171 test(lengthRead==lengthOfOriginal+1); |
|
172 test(aCopy->FieldCount()==aOriginal->FieldCount()); |
|
173 return 1; |
|
174 } |
|
175 |
|
176 |
|
177 void testPlainTextL(CEditableText::TDocumentStorage aStorage) |
|
178 // |
|
179 // Test streaming CPlainText. |
|
180 // |
|
181 {// Create the plain text components. |
|
182 test.Start(_L("Streaming CPlainText")); |
|
183 CPlainText* copy=CPlainText::NewL(aStorage); |
|
184 CPlainText* testDoc=CPlainText::NewL(aStorage); |
|
185 // |
|
186 // Set the original - empty |
|
187 test.Start(_L("empty.")); |
|
188 testStoreRestoreL(*copy,*testDoc); |
|
189 test(IsEqual(copy,testDoc)); |
|
190 // |
|
191 test.Next(_L("paragraph delimiter")); |
|
192 TRAPD(r,testDoc->InsertL(0,CEditableText::EParagraphDelimiter)); |
|
193 test(r==KErrNone); |
|
194 testStoreRestoreL(*copy,*testDoc); |
|
195 test(IsEqual(copy,testDoc)); |
|
196 // |
|
197 // Next test with tons of text guaranteed to force segment break when using segmented storage. |
|
198 test.Next(_L("big text component")); |
|
199 testDoc->InsertL(0,bigBuf); |
|
200 testStoreRestoreL(*copy,*testDoc); |
|
201 test(IsEqual(copy,testDoc)); |
|
202 // |
|
203 // Now test with field components. |
|
204 test.Next(_L("big text doc with field components.")); |
|
205 TTestFieldFactory factory; |
|
206 testDoc->SetFieldFactory(&factory); |
|
207 copy->SetFieldFactory(&factory); |
|
208 CTextField* field=NULL; |
|
209 TRAPD(ret, |
|
210 field=factory.NewFieldL(KDateTimeFieldUid)); |
|
211 test(ret==KErrNone); |
|
212 TRAP(ret, |
|
213 testDoc->InsertFieldL(0,field,KDateTimeFieldUid)); |
|
214 test(ret==KErrNone); |
|
215 testStoreRestoreL(*copy,*testDoc); |
|
216 test(IsEqual(copy,testDoc)); |
|
217 // |
|
218 // |
|
219 test.End(); |
|
220 delete copy; |
|
221 delete testDoc; |
|
222 } |
|
223 |
|
224 |
|
225 void testGlobalTextL(CEditableText::TDocumentStorage aStorage) |
|
226 // |
|
227 // Test streaming CGlobalText. |
|
228 // |
|
229 {// Create the plain text components. |
|
230 test.Next(_L("Streaming CGlobalText")); |
|
231 CParaFormatLayer* paraLayer=CParaFormatLayer::NewL(); |
|
232 CCharFormatLayer* charLayer=CCharFormatLayer::NewL(); |
|
233 // Set something interesting in the layers: |
|
234 CParaFormat* paraFormat1=CParaFormat::NewL(); TParaFormatMask paraMask1; |
|
235 TCharFormat charFormat1; TCharFormatMask charMask1; |
|
236 paraFormat1->iHorizontalAlignment=CParaFormat::ECenterAlign; paraMask1.SetAttrib(EAttAlignment); |
|
237 paraFormat1->iLeftMarginInTwips=4000; paraMask1.SetAttrib(EAttLeftMargin); |
|
238 paraLayer->SetL(paraFormat1,paraMask1); |
|
239 charFormat1.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask1.SetAttrib(EAttFontPosture); |
|
240 charFormat1.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask1.SetAttrib(EAttFontStrokeWeight); |
|
241 charLayer->SetL(charFormat1,charMask1); |
|
242 // |
|
243 CGlobalText* copy=CGlobalText::NewL(paraLayer,charLayer,aStorage); |
|
244 CGlobalText* testDoc=CGlobalText::NewL(paraLayer,charLayer,aStorage); |
|
245 |
|
246 // Set the original - empty |
|
247 test.Start(_L("empty.")); |
|
248 testStoreRestoreL(*copy,*testDoc); |
|
249 test(IsEqual(copy,testDoc)); |
|
250 // |
|
251 test.Next(_L("paragraph delimiter")); |
|
252 TRAPD(r,testDoc->InsertL(0,CEditableText::EParagraphDelimiter)); |
|
253 test(r==KErrNone); |
|
254 testStoreRestoreL(*copy,*testDoc); |
|
255 test(IsEqual(copy,testDoc)); |
|
256 |
|
257 // Next test with tons of text guaranteed to force segment break when using segmented storage. |
|
258 test.Next(_L("big text component")); |
|
259 testDoc->InsertL(0,bigBuf); |
|
260 testStoreRestoreL(*copy,*testDoc); |
|
261 test(IsEqual(copy,testDoc)); |
|
262 |
|
263 test.End(); |
|
264 test.End(); |
|
265 delete copy; |
|
266 delete testDoc; |
|
267 delete paraLayer; |
|
268 delete charLayer; |
|
269 delete paraFormat1; |
|
270 } |
|
271 |
|
272 |
|
273 LOCAL_C TInt LayerIsEqual(const CParaFormatLayer* aRestored,const CParaFormatLayer* aOriginal) |
|
274 // |
|
275 // Returns true if aRestored contents matches aOriginal contents. |
|
276 // |
|
277 { |
|
278 CParaFormat* restored=NULL; TParaFormatMask rm; |
|
279 CParaFormat* original=NULL; TParaFormatMask om; |
|
280 TRAPD(r,restored=CParaFormat::NewL()); test(r==KErrNone); |
|
281 TRAP(r,original=CParaFormat::NewL()); test(r==KErrNone); |
|
282 |
|
283 aOriginal->SenseL(original,om); |
|
284 aRestored->SenseL(restored,rm); |
|
285 |
|
286 test(original->IsEqual(*restored)); |
|
287 |
|
288 delete restored; |
|
289 delete original; |
|
290 return 1; |
|
291 } |
|
292 |
|
293 |
|
294 LOCAL_C TInt LayerIsEqual(const CCharFormatLayer* aRestored,const CCharFormatLayer* aOriginal) |
|
295 // |
|
296 // Returns true if aRestored contents matches aOriginal contents. |
|
297 // |
|
298 { |
|
299 TCharFormat restored; TCharFormatMask rm; |
|
300 TCharFormat original; TCharFormatMask om; |
|
301 |
|
302 aOriginal->Sense(original,om); |
|
303 aRestored->Sense(restored,rm); |
|
304 |
|
305 test(original.IsEqual(restored)); |
|
306 |
|
307 return 1; |
|
308 } |
|
309 |
|
310 |
|
311 void testFmtLayerStoreL() |
|
312 // |
|
313 // Test the format layer StoreL(). |
|
314 // |
|
315 { |
|
316 test.Start(_L("CParaFormatLayer")); |
|
317 // Create test layers. |
|
318 CParaFormatLayer* pfl1=NULL; |
|
319 CParaFormatLayer* restored=NULL; |
|
320 CParaFormat* pf1=NULL; |
|
321 TRAPD(r,restored=CParaFormatLayer::NewL()); test(r==KErrNone); |
|
322 // Force *restored* to allocate storage for iteself by storing a null layer. |
|
323 TParaFormatMask rm; rm.ClearAll(); CParaFormat* rpf=NULL; |
|
324 restored->SetL(rpf,rm); |
|
325 TRAP(r,pfl1=CParaFormatLayer::NewL()); test(r==KErrNone); |
|
326 TRAP(r,pf1=CParaFormat::NewL()); test(r==KErrNone); |
|
327 TParaFormatMask pm1; |
|
328 pm1.SetAll(); // Sets all but the compound attributes. |
|
329 // TEST ONE DEFAULT CASES |
|
330 test.Start(_L("Default paragraph format values.")); |
|
331 TRAP(r,pfl1->SetL(pf1,pm1)); test(r==KErrNone); |
|
332 testCopy(*restored,*pfl1); |
|
333 test(LayerIsEqual(restored,pfl1)); |
|
334 test(restored->SenseBase()==pfl1->SenseBase()); // Both should default to based on NULL |
|
335 // TEST TWO |
|
336 test.Next(_L("Setting all attributes")); |
|
337 pf1->iLeftMarginInTwips=5000; pm1.ClearAll(); pm1.SetAttrib(EAttLeftMargin); |
|
338 pf1->iRightMarginInTwips=5001; pm1.SetAttrib(EAttRightMargin); |
|
339 pf1->iIndentInTwips=5002;pm1.SetAttrib(EAttIndent); |
|
340 pf1->iHorizontalAlignment=CParaFormat::ERightAlign; pm1.SetAttrib(EAttAlignment); |
|
341 pf1->iVerticalAlignment=CParaFormat::ECenterAlign; pm1.SetAttrib(EAttVerticalAlignment); |
|
342 pf1->iLineSpacingInTwips=5003; pm1.SetAttrib(EAttLineSpacing); |
|
343 pf1->iLineSpacingControl=CParaFormat::ELineSpacingAtLeastInTwips; pm1.SetAttrib(EAttLineSpacingControl); |
|
344 pf1->iSpaceBeforeInTwips=5004; pm1.SetAttrib(EAttSpaceBefore); |
|
345 pf1->iSpaceAfterInTwips=5005; pm1.SetAttrib(EAttSpaceAfter); |
|
346 pf1->iKeepTogether=ETrue; pm1.SetAttrib(EAttKeepTogether); |
|
347 pf1->iKeepWithNext=ETrue; pm1.SetAttrib(EAttKeepWithNext); |
|
348 pf1->iStartNewPage=ETrue; pm1.SetAttrib(EAttStartNewPage); |
|
349 pf1->iWidowOrphan=ETrue; pm1.SetAttrib(EAttWidowOrphan); |
|
350 pf1->iWrap=EFalse; pm1.SetAttrib(EAttWrap); |
|
351 pf1->iBorderMarginInTwips=5006; pm1.SetAttrib(EAttBorderMargin); |
|
352 pf1->iDefaultTabWidthInTwips=5007; pm1.SetAttrib(EAttDefaultTabWidth); |
|
353 // TopBorder |
|
354 TParaBorder top; |
|
355 top.iLineStyle=TParaBorder::ESolid; |
|
356 top.iThickness=4; |
|
357 top.iAutoColor=ETrue; |
|
358 pf1->SetParaBorderL(CParaFormat::EParaBorderTop,top); |
|
359 pm1.SetAttrib(EAttTopBorder); |
|
360 // BottomBorder |
|
361 TParaBorder bottom; |
|
362 bottom.iLineStyle=TParaBorder::ESolid; |
|
363 bottom.iThickness=4; |
|
364 bottom.iAutoColor=ETrue; |
|
365 pf1->SetParaBorderL(CParaFormat::EParaBorderBottom,bottom); |
|
366 pm1.SetAttrib(EAttBottomBorder); |
|
367 // LeftBorder |
|
368 TParaBorder left; |
|
369 left.iLineStyle=TParaBorder::ESolid; |
|
370 left.iThickness=4; |
|
371 left.iAutoColor=ETrue; |
|
372 pf1->SetParaBorderL(CParaFormat::EParaBorderLeft,left); |
|
373 pm1.SetAttrib(EAttLeftBorder); |
|
374 // RightBorder |
|
375 TParaBorder right; |
|
376 right.iLineStyle=TParaBorder::ESolid; |
|
377 right.iThickness=4; |
|
378 top.iAutoColor=ETrue; |
|
379 pf1->SetParaBorderL(CParaFormat::EParaBorderRight,right); |
|
380 pm1.SetAttrib(EAttRightBorder); |
|
381 // Bullet |
|
382 pf1->iBullet=new(ELeave)TBullet; |
|
383 TUint charCode=5008; |
|
384 pf1->iBullet->iCharacterCode=(TUint8)charCode; |
|
385 pf1->iBullet->iHeightInTwips=5009; |
|
386 pf1->iBullet->iTypeface.iName=_L("Duncan"); |
|
387 pf1->iBullet->iTypeface.SetIsProportional(EFalse); |
|
388 pf1->iBullet->iTypeface.SetIsSerif(EFalse); |
|
389 pm1.SetAttrib(EAttBullet); |
|
390 // 2 Tab Stops. |
|
391 TTabStop tab1,tab2; |
|
392 tab1.iTwipsPosition=5010; tab1.iType=TTabStop::ERightTab; |
|
393 tab2.iTwipsPosition=5011; tab2.iType=TTabStop::ECenteredTab; |
|
394 pf1->StoreTabL(tab1); |
|
395 pf1->StoreTabL(tab2); |
|
396 pm1.SetAttrib(EAttTabStop); |
|
397 // |
|
398 TRAP(r,pfl1->SetL(pf1,pm1)); |
|
399 testCopy(*restored,*pfl1); |
|
400 test(LayerIsEqual(restored,pfl1)); |
|
401 test(restored->SenseBase()==pfl1->SenseBase()); // Both should default to based on NULL |
|
402 test.End(); |
|
403 // |
|
404 delete pf1; |
|
405 delete pfl1; |
|
406 delete restored; |
|
407 // |
|
408 // Now the CCharFormatLayer Store/Restore |
|
409 // |
|
410 test.Next(_L("CCharFormatLayer")); |
|
411 // |
|
412 test.Start(_L("Setting all attributes")); |
|
413 // Create test layers. |
|
414 CCharFormatLayer* cfl1=NULL; |
|
415 CCharFormatLayer* cRestored=NULL; |
|
416 TCharFormat cf1; TCharFormatMask cm1; |
|
417 // |
|
418 TRAP(r,cRestored=CCharFormatLayer::NewL()); test(r==KErrNone); |
|
419 // Force *restored* to allocate storage for iteself by storing a null layer. |
|
420 TCharFormatMask rcm; rcm.ClearAll(); TCharFormat rcf; |
|
421 cRestored->SetL(rcf,rcm); |
|
422 // |
|
423 TRAP(r,cfl1=CCharFormatLayer::NewL()); test(r==KErrNone); |
|
424 // |
|
425 TRgb color(20,20,20); |
|
426 cf1.iFontPresentation.iTextColor=color; cm1.SetAttrib(EAttColor); |
|
427 cf1.iFontSpec.iTypeface.iName=_L("DUNCANXZE"); |
|
428 cf1.iFontSpec.iTypeface.SetIsProportional(ETrue); cm1.SetAttrib(EAttFontTypeface); |
|
429 cf1.iFontSpec.iTypeface.SetIsSerif(EFalse); |
|
430 cf1.iFontSpec.iFontStyle.SetBitmapType(EMonochromeGlyphBitmap); |
|
431 |
|
432 cf1.iFontSpec.iHeight=6000; cm1.SetAttrib(EAttFontHeight); |
|
433 cf1.iFontSpec.iFontStyle.SetPosture(EPostureItalic); cm1.SetAttrib(EAttFontPosture); |
|
434 cf1.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); cm1.SetAttrib(EAttFontStrokeWeight); |
|
435 cf1.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript); cm1.SetAttrib(EAttFontPrintPos); |
|
436 cf1.iFontPresentation.iUnderline=EUnderlineOn; cm1.SetAttrib(EAttFontUnderline); |
|
437 cf1.iFontPresentation.iStrikethrough=EStrikethroughOn; cm1.SetAttrib(EAttFontStrikethrough); |
|
438 cf1.iFontPresentation.iHighlightColor=color; cm1.SetAttrib(EAttFontHighlightColor); |
|
439 cf1.iFontPresentation.iHighlightStyle=TFontPresentation::EFontHighlightNormal; cm1.SetAttrib(EAttFontHighlightStyle); |
|
440 // |
|
441 TRAP(r,cfl1->SetL(cf1,cm1)); |
|
442 test(r==KErrNone); |
|
443 testCopy(*cRestored,*cfl1); |
|
444 test(LayerIsEqual(cRestored,cfl1)); |
|
445 |
|
446 TCharFormat rfmt; |
|
447 TCharFormatMask rmask; |
|
448 cRestored->Sense(rfmt, rmask); |
|
449 test(rfmt.iFontSpec.iFontStyle.BitmapType() == EMonochromeGlyphBitmap); |
|
450 |
|
451 // |
|
452 delete cfl1; |
|
453 delete cRestored; |
|
454 test.End(); |
|
455 } |
|
456 |
|
457 |
|
458 LOCAL_C TInt ChainIsEqual(const CParaFormatLayer* aCopy,const CParaFormatLayer* aOriginal) |
|
459 // |
|
460 // Tests that the restored chain is identical to the original chain. |
|
461 // |
|
462 { |
|
463 TInt origChainCount=aOriginal->ChainCount(); |
|
464 /*TInt copyChainCount=*/aCopy->ChainCount(); |
|
465 // Check the chain heads are equal. |
|
466 test(LayerIsEqual(aCopy,aOriginal)); |
|
467 TInt descendantCount=origChainCount-1; |
|
468 |
|
469 const CFormatLayer* nextCopyLayer=aCopy->SenseBase(); |
|
470 const CFormatLayer* nextOrigLayer=aOriginal->SenseBase(); |
|
471 for (TInt loop=0;loop<descendantCount;loop++) |
|
472 { |
|
473 test(LayerIsEqual((CParaFormatLayer*)nextCopyLayer,(CParaFormatLayer*)nextOrigLayer)); |
|
474 |
|
475 nextCopyLayer=nextCopyLayer->SenseBase(); |
|
476 nextOrigLayer=nextOrigLayer->SenseBase(); |
|
477 } |
|
478 return 1; |
|
479 } |
|
480 |
|
481 |
|
482 LOCAL_C TInt ChainIsEqual(const CCharFormatLayer* aCopy,const CCharFormatLayer* aOriginal) |
|
483 // |
|
484 // Tests that the restored chain is identical to the original chain. |
|
485 // |
|
486 { |
|
487 TInt origChainCount=aOriginal->ChainCount(); |
|
488 /*TInt copyChainCount=*/aCopy->ChainCount(); |
|
489 // Check the chain heads are equal. |
|
490 test(LayerIsEqual(aCopy,aOriginal)); |
|
491 TInt descendantCount=origChainCount-1; |
|
492 |
|
493 const CFormatLayer* nextCopyLayer=aCopy->SenseBase(); |
|
494 const CFormatLayer* nextOrigLayer=aOriginal->SenseBase(); |
|
495 for (TInt loop=0;loop<descendantCount;loop++) |
|
496 { |
|
497 test(LayerIsEqual((CCharFormatLayer*)nextCopyLayer,(CCharFormatLayer*)nextOrigLayer)); |
|
498 |
|
499 nextCopyLayer=nextCopyLayer->SenseBase(); |
|
500 nextOrigLayer=nextOrigLayer->SenseBase(); |
|
501 } |
|
502 return 1; |
|
503 } |
|
504 |
|
505 |
|
506 void DoParaChainL() |
|
507 // |
|
508 // Tests the streaming of a chain of format layers |
|
509 // |
|
510 { |
|
511 test.Next(_L("Re/StoreChainL()")); |
|
512 test.Start(_L("CParaFormatLayer")); |
|
513 // Create the chain of para format layers. |
|
514 CParaFormatLayer* l1=CParaFormatLayer::NewL(); |
|
515 CParaFormatLayer* l2=CParaFormatLayer::NewL(); |
|
516 CParaFormatLayer* l3=CParaFormatLayer::NewL(); |
|
517 CParaFormatLayer* l4=CParaFormatLayer::NewL(); |
|
518 // Chain together. |
|
519 l1->SetBase(l2); |
|
520 l2->SetBase(l3); |
|
521 l3->SetBase(l4); |
|
522 // Create head of restored format stream, and force it to get storage. |
|
523 CParaFormatLayer* restoredChainHead=CParaFormatLayer::NewL(); |
|
524 CParaFormat* restoredParaFormat=CParaFormat::NewL(); |
|
525 TParaFormatMask restoredParaMask; |
|
526 restoredParaMask.ClearAll(); |
|
527 restoredChainHead->SetL(restoredParaFormat,restoredParaMask); |
|
528 // General paraformat and its mask. |
|
529 CParaFormat* paraFormat=CParaFormat::NewL(); |
|
530 TParaFormatMask paraMask; |
|
531 paraMask.ClearAll(); |
|
532 // Set layer one stuff |
|
533 TTabStop tab1,tab2; |
|
534 tab1.iTwipsPosition=5000; tab2.iTwipsPosition=5001; |
|
535 tab1.iType=TTabStop::ERightTab; tab2.iType=TTabStop::ECenteredTab; |
|
536 paraFormat->StoreTabL(tab1); |
|
537 paraFormat->StoreTabL(tab2); |
|
538 paraMask.SetAttrib(EAttTabStop); |
|
539 l1->SetL(paraFormat,paraMask); |
|
540 paraMask.ClearAll(); |
|
541 // Set layer two stuff |
|
542 TParaBorder top1; |
|
543 top1.iLineStyle=TParaBorder::ESolid; |
|
544 top1.iThickness=3; |
|
545 top1.iAutoColor=ETrue; |
|
546 paraFormat->SetParaBorderL(CParaFormat::EParaBorderTop,top1); |
|
547 paraMask.SetAttrib(EAttTopBorder); |
|
548 l2->SetL(paraFormat,paraMask); |
|
549 paraMask.ClearAll(); |
|
550 // Set the layer 3 stuff. |
|
551 paraFormat->iBullet=new(ELeave)TBullet; |
|
552 paraFormat->iBullet->iTypeface.iName=_L("SKELTON"); |
|
553 paraFormat->iBullet->iTypeface.SetIsProportional(EFalse); |
|
554 paraFormat->iBullet->iTypeface.SetIsSerif(EFalse); |
|
555 paraFormat->iBullet->iHeightInTwips=3003; |
|
556 paraFormat->iBullet->iCharacterCode=32; |
|
557 paraMask.SetAttrib(EAttBullet); |
|
558 l3->SetL(paraFormat,paraMask); |
|
559 paraMask.ClearAll(); |
|
560 // Set the layer 4 stuff. |
|
561 paraFormat->iHorizontalAlignment=CParaFormat::EJustifiedAlign; paraMask.SetAttrib(EAttAlignment); |
|
562 paraFormat->iSpaceAfterInTwips=6000; paraMask.SetAttrib(EAttSpaceAfter); |
|
563 paraFormat->iKeepTogether=ETrue; paraMask.SetAttrib(EAttKeepTogether); |
|
564 l4->SetL(paraFormat,paraMask); |
|
565 // NOW DO IT |
|
566 testCopyChain(*restoredChainHead,*l1,0,(const CFormatLayer*)NULL); |
|
567 TInt restoredChainCount=restoredChainHead->ChainCount(); |
|
568 test(ChainIsEqual(restoredChainHead,l1)); |
|
569 // DESTROY STUFF |
|
570 CParaFormatLayer* current=restoredChainHead; |
|
571 CParaFormatLayer* next=(CParaFormatLayer*)restoredChainHead->SenseBase(); |
|
572 delete current; |
|
573 for (TInt loop=0;loop<restoredChainCount-1;loop++) |
|
574 { |
|
575 current=next; |
|
576 next=(CParaFormatLayer*)current->SenseBase(); |
|
577 delete current; |
|
578 } |
|
579 delete l1; |
|
580 delete l2; |
|
581 delete l3; |
|
582 delete l4; |
|
583 delete paraFormat; |
|
584 delete restoredParaFormat; |
|
585 } |
|
586 |
|
587 |
|
588 void DoCharChainL() |
|
589 // |
|
590 // |
|
591 // |
|
592 { |
|
593 test.Next(_L("CCharFormatLayer")); |
|
594 // Create the chain of character format layers. |
|
595 CCharFormatLayer* cl1=CCharFormatLayer::NewL(); |
|
596 CCharFormatLayer* cl2=CCharFormatLayer::NewL(); |
|
597 CCharFormatLayer* cl3=CCharFormatLayer::NewL(); |
|
598 CCharFormatLayer* cl4=CCharFormatLayer::NewL(); |
|
599 // Chain together. |
|
600 cl1->SetBase(cl2); |
|
601 cl2->SetBase(cl3); |
|
602 cl3->SetBase(cl4); |
|
603 // Create head of restored format stream, and force it to get storage. |
|
604 CCharFormatLayer* rChar=CCharFormatLayer::NewL(); |
|
605 TCharFormat restoredCharFormat; |
|
606 TCharFormatMask restoredCharMask; |
|
607 restoredCharMask.ClearAll(); |
|
608 rChar->SetL(restoredCharFormat,restoredCharMask); |
|
609 // General charformat and its mask. |
|
610 TCharFormat charFormat; TCharFormatMask charMask; |
|
611 charMask.ClearAll(); |
|
612 // Set layer one stuff |
|
613 charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask.SetAttrib(EAttFontStrokeWeight); |
|
614 charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask.SetAttrib(EAttFontPosture); |
|
615 charFormat.iFontPresentation.iUnderline=EUnderlineOn; charMask.SetAttrib(EAttFontUnderline); |
|
616 cl1->SetL(charFormat,charMask); |
|
617 charMask.ClearAll(); |
|
618 // Set layer two stuff |
|
619 charFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript); charMask.SetAttrib(EAttFontPrintPos); |
|
620 cl2->SetL(charFormat,charMask); |
|
621 charMask.ClearAll(); |
|
622 // Set the layer 3 stuff. |
|
623 charFormat.iFontPresentation.iStrikethrough=EStrikethroughOn; charMask.SetAttrib(EAttFontStrikethrough); |
|
624 cl3->SetL(charFormat,charMask); |
|
625 charMask.ClearAll(); |
|
626 // Set the layer 4 stuff. |
|
627 charFormat.iFontSpec.iTypeface.iName=_L("Arial"); |
|
628 charFormat.iFontSpec.iHeight=200; |
|
629 charMask.SetAttrib(EAttFontHeight); |
|
630 charMask.SetAttrib(EAttFontTypeface); |
|
631 cl4->SetL(charFormat,charMask); |
|
632 // NOW DO IT |
|
633 test.Start(_L("Chain 4 layers deep, terminating on a based on NULL")); |
|
634 testCopyChain(*rChar,*cl1,0,(const CFormatLayer*)NULL); |
|
635 TInt restoredChainCount=rChar->ChainCount(); |
|
636 test(ChainIsEqual(rChar,cl1)); |
|
637 // DESTROY STUFF |
|
638 CCharFormatLayer* chCurrent=rChar; |
|
639 CCharFormatLayer* chNext=(CCharFormatLayer*)rChar->SenseBase(); |
|
640 delete chCurrent; |
|
641 for (TInt loop=0;loop<restoredChainCount-1;loop++) |
|
642 { |
|
643 chCurrent=chNext; |
|
644 chNext=(CCharFormatLayer*)chCurrent->SenseBase(); |
|
645 delete chCurrent; |
|
646 } |
|
647 delete cl1; |
|
648 delete cl2; |
|
649 delete cl3; |
|
650 delete cl4; |
|
651 } |
|
652 |
|
653 |
|
654 void DoCharChainVariant1() |
|
655 // |
|
656 // Case 2: Where the chain does not terminate at a NULL link. |
|
657 // |
|
658 { |
|
659 // Create the chain of character format layers. |
|
660 CCharFormatLayer* cl1=CCharFormatLayer::NewL(); |
|
661 CCharFormatLayer* cl2=CCharFormatLayer::NewL(); |
|
662 CCharFormatLayer* cl3=CCharFormatLayer::NewL(); |
|
663 CCharFormatLayer* cl4=CCharFormatLayer::NewL(); |
|
664 // Chain together. |
|
665 cl1->SetBase(cl2); |
|
666 cl2->SetBase(cl3); |
|
667 cl3->SetBase(cl4); |
|
668 // Create head of restored format stream, and force it to get storage. |
|
669 CCharFormatLayer* rChar=CCharFormatLayer::NewL(); |
|
670 TCharFormat restoredCharFormat; |
|
671 TCharFormatMask restoredCharMask; |
|
672 restoredCharMask.ClearAll(); |
|
673 rChar->SetL(restoredCharFormat,restoredCharMask); |
|
674 // General charformat and its mask. |
|
675 TCharFormat charFormat; TCharFormatMask charMask; |
|
676 charMask.ClearAll(); |
|
677 // Set layer one stuff |
|
678 charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask.SetAttrib(EAttFontStrokeWeight); |
|
679 charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask.SetAttrib(EAttFontPosture); |
|
680 charFormat.iFontPresentation.iUnderline=EUnderlineOn; charMask.SetAttrib(EAttFontUnderline); |
|
681 cl1->SetL(charFormat,charMask); |
|
682 charMask.ClearAll(); |
|
683 // Set layer two stuff |
|
684 charFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript); charMask.SetAttrib(EAttFontPrintPos); |
|
685 cl2->SetL(charFormat,charMask); |
|
686 charMask.ClearAll(); |
|
687 // Set the layer 3 stuff. |
|
688 charFormat.iFontPresentation.iStrikethrough=EStrikethroughOn; charMask.SetAttrib(EAttFontStrikethrough); |
|
689 cl3->SetL(charFormat,charMask); |
|
690 charMask.ClearAll(); |
|
691 // Set the layer 4 stuff. |
|
692 charFormat.iFontSpec.iTypeface.iName=_L("Arial"); |
|
693 charFormat.iFontSpec.iHeight=200; |
|
694 charMask.SetAttrib(EAttFontHeight); |
|
695 charMask.SetAttrib(EAttFontTypeface); |
|
696 cl4->SetL(charFormat,charMask); |
|
697 // NOW DO IT |
|
698 test.Next(_L("Chain 3 layers deep, terminating on a non-NULL based-on")); |
|
699 testCopyChain(*rChar,*cl1,1,(const CFormatLayer*)cl4); |
|
700 TInt restoredChainCount=rChar->ChainCount(); |
|
701 test(ChainIsEqual(rChar,cl1)); |
|
702 // DESTROY STUFF |
|
703 CCharFormatLayer* chCurrent=rChar; |
|
704 CCharFormatLayer* chNext=(CCharFormatLayer*)rChar->SenseBase(); |
|
705 delete chCurrent; |
|
706 for (TInt loop=0;loop<restoredChainCount-2;loop++) |
|
707 { |
|
708 chCurrent=chNext; |
|
709 chNext=(CCharFormatLayer*)chCurrent->SenseBase(); |
|
710 delete chCurrent; |
|
711 } |
|
712 delete cl1; |
|
713 delete cl2; |
|
714 delete cl3; |
|
715 delete cl4; |
|
716 |
|
717 test.End(); |
|
718 test.End(); |
|
719 test.End(); |
|
720 } |
|
721 |
|
722 |
|
723 void testFmtLayerStoreChainL() |
|
724 // |
|
725 // Controls the testing of the chainig stuff. |
|
726 // |
|
727 { |
|
728 DoParaChainL(); |
|
729 DoCharChainL(); |
|
730 DoCharChainVariant1(); |
|
731 // DoCharChainVariant2(); TO BE IMPLEMENTED |
|
732 // doCharChainVariant3(); TO BE IMPLEMENTED |
|
733 } |
|
734 |
|
735 |
|
736 void testFmtLayerL() |
|
737 // |
|
738 // Tests the streaming of format layers. |
|
739 // |
|
740 { |
|
741 testFmtLayerStoreL(); |
|
742 testFmtLayerStoreChainL(); |
|
743 } |
|
744 |
|
745 |
|
746 LOCAL_C void setupCleanup() |
|
747 // |
|
748 // Initialise the cleanup stack. |
|
749 // |
|
750 { |
|
751 |
|
752 TheTrapCleanup=CTrapCleanup::New(); |
|
753 TRAPD(r,\ |
|
754 {\ |
|
755 for (TInt i=KTestCleanupStack;i>0;i--)\ |
|
756 CleanupStack::PushL((TAny*)1);\ |
|
757 test(r==KErrNone);\ |
|
758 CleanupStack::Pop(KTestCleanupStack);\ |
|
759 }); |
|
760 } |
|
761 |
|
762 |
|
763 LOCAL_C void DeleteDataFile(const TDesC& aFullName) |
|
764 { |
|
765 RFs fsSession; |
|
766 TInt err = fsSession.Connect(); |
|
767 if(err == KErrNone) |
|
768 { |
|
769 TEntry entry; |
|
770 if(fsSession.Entry(aFullName, entry) == KErrNone) |
|
771 { |
|
772 RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); |
|
773 err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); |
|
774 if(err != KErrNone) |
|
775 { |
|
776 RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); |
|
777 } |
|
778 err = fsSession.Delete(aFullName); |
|
779 if(err != KErrNone) |
|
780 { |
|
781 RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); |
|
782 } |
|
783 } |
|
784 fsSession.Close(); |
|
785 } |
|
786 else |
|
787 { |
|
788 RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); |
|
789 } |
|
790 } |
|
791 |
|
792 GLDEF_C TInt E32Main() |
|
793 // |
|
794 // Test streaming conversions. |
|
795 // |
|
796 { |
|
797 setupCleanup(); |
|
798 test.Title(); |
|
799 __UHEAP_MARK; |
|
800 |
|
801 test.Start(_L(" @SYMTestCaseID:SYSLIB-ETEXT-LEGACY-T_CONVS-0001 EText components using Flat Storage ")); |
|
802 TRAPD(r,testPlainTextL(CEditableText::EFlatStorage)); |
|
803 test(r==KErrNone); |
|
804 TRAP(r,testGlobalTextL(CEditableText::EFlatStorage)); |
|
805 test(r==KErrNone); |
|
806 |
|
807 // |
|
808 test.Next(_L("EText components using Segmented storage")); |
|
809 TRAP(r,testPlainTextL(CEditableText::ESegmentedStorage)); |
|
810 test(r==KErrNone); |
|
811 TRAP(r,testGlobalTextL(CEditableText::ESegmentedStorage)); |
|
812 test(r==KErrNone); |
|
813 |
|
814 test.Next(_L("Format Layer components")); |
|
815 TRAP(r,testFmtLayerL()); |
|
816 test(r==KErrNone); |
|
817 |
|
818 // test.End(); |
|
819 __UHEAP_MARKEND; |
|
820 |
|
821 ::DeleteDataFile(KOutputFile); //deletion of data files must be before call to End() - DEF047652 |
|
822 test.End(); |
|
823 test.Close(); |
|
824 delete TheTrapCleanup; |
|
825 |
|
826 return 0; |
|
827 } |
|
828 |