|
1 /* |
|
2 * Copyright (c) 2003-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 <e32std.h> |
|
20 #include <e32base.h> |
|
21 |
|
22 #include "TXTRICH.H" |
|
23 |
|
24 #include "TXTINDEX.H" |
|
25 #include "TXTSTD.H" |
|
26 #include "TXTRTPFL.H" |
|
27 #include "ParseLst.h" |
|
28 |
|
29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
30 #include "TXTETEXT_INTERNAL.H" |
|
31 #include "TXTRICH_INTERNAL.H" |
|
32 #endif |
|
33 |
|
34 /////////////////////////////////////////////////////////// |
|
35 // |
|
36 // Default persist functions - Deferred loading of pictures |
|
37 // |
|
38 /////////////////////////////////////////////////////////// |
|
39 |
|
40 |
|
41 EXPORT_C void CRichText::RestoreWithStyleListL(const CStreamStore& aStore, TStreamId aStreamId, const CStyleList& aExternalStyleList) |
|
42 /** Restores a rich text object, including all of its components and an |
|
43 externally owned style list, from a stream store. |
|
44 |
|
45 @param aStore Stream store from which the object is restored. |
|
46 @param aStreamId ID of the stream store. |
|
47 @param aExternalStyleList An externally owned style list. */ |
|
48 { |
|
49 RStoreReadStream stream; |
|
50 stream.OpenLC(aStore,aStreamId); |
|
51 // |
|
52 InternalizeL(stream,&aExternalStyleList); |
|
53 CleanupStack::PopAndDestroy(); // stream |
|
54 RestoreComponentsL(aStore); |
|
55 } |
|
56 |
|
57 EXPORT_C void CRichText::StoreComponentsL(CStreamStore& aStore, CStoreMap& aMap) const |
|
58 /** Stores the rich text object's components (field set, style list, formatting |
|
59 and pictures) to the stream store specified. |
|
60 |
|
61 @param aStore Stream store to which the text components are written. |
|
62 @param aMap A store map. This binds the address of text components to the |
|
63 stream ID of aStore. This is needed to support the deferred loading of pictures |
|
64 in rich text. */ |
|
65 { |
|
66 CGlobalText::StoreComponentsL(aStore,aMap); |
|
67 StoreStylesL(aStore,aMap); |
|
68 StoreMarkupL(aStore,aMap); |
|
69 } |
|
70 |
|
71 EXPORT_C void CRichText::RestoreComponentsL(const CStreamStore& aStore) |
|
72 /** Restores the rich text object's components (field set, style list, |
|
73 formatting and pictures) from a stream store. |
|
74 |
|
75 @param aStore The stream store from which the text object's components are |
|
76 restored. */ |
|
77 { |
|
78 CPlainText::RestoreComponentsL(aStore); // field components |
|
79 if (iStyleList.IsId() && iStyleList.AsId()!=KNullStreamId) |
|
80 RestoreStylesL(aStore,iStyleList.AsId(),iGlobalParaFormatLayer,iGlobalCharFormatLayer); |
|
81 if (iIndex.AsId()!=KNullStreamId) |
|
82 iIndex=CRichTextIndex::NewL(aStore,iIndex.AsId(),iGlobalParaFormatLayer,iGlobalCharFormatLayer,*this); |
|
83 } |
|
84 |
|
85 |
|
86 |
|
87 EXPORT_C void CRichText::ExternalizeL(RWriteStream& aStream)const |
|
88 /** Externalises the rich text object and all of its components (field set, |
|
89 style list, rich text formatting, pictures) to a read stream. The presence |
|
90 of this function means that the standard templated operator<<() (defined in |
|
91 s32strm.h) is available to externalise objects of this class. |
|
92 |
|
93 Notes: |
|
94 |
|
95 Any "insert pending" state is cancelled (calls CancelInsertCharFormat()). |
|
96 |
|
97 The global format layers are not owned by the object; they are supplied by |
|
98 the owner of the object and not saved when the object is externalised or loaded |
|
99 when it is internalized. |
|
100 |
|
101 StoreComponentsL() must be called before calling this function. This is necessary to set |
|
102 up the the stream store needed to externalize rich text objects. It is not possible to get |
|
103 a stream store into a stream and a rich text object cannot be externalized to an arbitrary |
|
104 stream thus StoreComponentsL() will set up this stream store before externalizing. |
|
105 |
|
106 The inherited function CEditableText::StoreL() combines both calling of StoreComponentsL() |
|
107 to set up the stream store and externalizing the rich text object to this stream store. |
|
108 |
|
109 @param aStream Stream to which to write the rich text object. */ |
|
110 { |
|
111 __TEST_INVARIANT; |
|
112 |
|
113 CONST_CAST(CRichText*,this)->CancelInsertCharFormat(); |
|
114 CEditableText::ExternalizeL(aStream); |
|
115 DoExternalizeFieldDataL(aStream); |
|
116 DoExternalizeStyleDataL(aStream); |
|
117 DoExternalizeMarkupDataL(aStream); |
|
118 DoExternalizePlainTextL(aStream); |
|
119 } |
|
120 |
|
121 |
|
122 EXPORT_C void CRichText::InternalizeL(RReadStream& aStream) |
|
123 /** Internalises the rich text object and all of its components (field set, |
|
124 style list, rich text formatting and pictures) from a read stream. The |
|
125 presence of this function means that the standard templated operator>>() |
|
126 (defined in s32strm.h) is available to internalise objects of this class. |
|
127 |
|
128 Note: The global format layers are not owned by the object; they are supplied by |
|
129 the owner of the object and not saved when the object is externalised or loaded |
|
130 when it is internalized. |
|
131 |
|
132 @param aStream Stream from which to read the rich text object. */ |
|
133 {InternalizeL(aStream,NULL);} |
|
134 |
|
135 |
|
136 void CRichText::InternalizeL(RReadStream& aStream,const CStyleList* aExternalStyleList) |
|
137 // Restore this rich text object. |
|
138 // The global format layers are not present in this persistent state. |
|
139 // |
|
140 { |
|
141 CEditableText::InternalizeL(aStream); |
|
142 DoInternalizeFieldDataL(aStream); |
|
143 DoInternalizeStyleDataL(aStream,aExternalStyleList); |
|
144 DoInternalizeMarkupDataL(aStream); |
|
145 DoInternalizePlainTextL(aStream); |
|
146 if (iParserData == NULL) |
|
147 iParserData = new(ELeave) CParserData(DocumentLength()); |
|
148 iParserData->KillRange(); |
|
149 iParserData->MergeRange(0,0,DocumentLength()); |
|
150 CallEditObserver(0,DocumentLength()); |
|
151 } |
|
152 |
|
153 |
|
154 void CRichText::StoreStylesL(CStreamStore& aStore,CStoreMap& aMap)const |
|
155 // Write the style list, if present, out of line. |
|
156 // |
|
157 { |
|
158 if (StyleListPresent() && !StyleListExternallyOwned()) |
|
159 { |
|
160 TStreamId id=iStyleList->StoreL(aStore); |
|
161 aMap.BindL(iStyleList,id); |
|
162 } |
|
163 } |
|
164 |
|
165 |
|
166 void CRichText::RestoreStylesL(const CStreamStore& aStore,TStreamId aId,const CParaFormatLayer* aParaFormatLayer,const CCharFormatLayer* aCharFormatLayer) |
|
167 // Restore the style list |
|
168 // |
|
169 { |
|
170 RStoreReadStream stream; |
|
171 stream.OpenLC(aStore,aId); |
|
172 // |
|
173 iStyleList=CStyleList::NewL(stream,aParaFormatLayer,aCharFormatLayer); |
|
174 CleanupStack::PopAndDestroy(); // stream |
|
175 } |
|
176 |
|
177 |
|
178 void CRichText::StoreMarkupL(CStreamStore& aStore,CStoreMap& aMap)const |
|
179 // Write the index/markup data, if present, out of line. |
|
180 // |
|
181 { |
|
182 if (IndexPresent()) |
|
183 { |
|
184 TStreamId id=iIndex->StoreMarkupL(aStore,iStyleList); |
|
185 aMap.BindL(iIndex,id); |
|
186 } |
|
187 } |
|
188 |
|
189 |
|
190 EXPORT_C void CRichText::DoExternalizeStyleDataL(RWriteStream& aStream)const |
|
191 // Write to the stream, the T.V. representing the style definitions. |
|
192 // |
|
193 { |
|
194 aStream<< KRichTextStyleDataUid; |
|
195 if (StyleListPresent() && !StyleListExternallyOwned()) |
|
196 aStream<< iStyleList; |
|
197 else |
|
198 aStream<< KNullStreamId; |
|
199 } |
|
200 |
|
201 |
|
202 EXPORT_C void CRichText::DoInternalizeStyleDataL(RReadStream& aStream) |
|
203 // Load the out-of-line component representing the style list. |
|
204 // |
|
205 {DoInternalizeStyleDataL(aStream,NULL);} |
|
206 |
|
207 |
|
208 void CRichText::DoInternalizeStyleDataL(RReadStream& aStream,const CStyleList* aExternalStyleList) |
|
209 // Load the out-of-line component representing the style list. |
|
210 // |
|
211 { |
|
212 TUid uid=UidFromStreamL(aStream); |
|
213 while (uid!=KRichTextStyleDataUid) |
|
214 { |
|
215 if (uid==KPlainTextCharacterDataUid) |
|
216 User::Leave(KErrCorrupt); // There is no style or markup Data !!!!! |
|
217 CPlainText::ConsumeAdornmentL(aStream); |
|
218 uid=UidFromStreamL(aStream); |
|
219 } |
|
220 aStream>> iStyleList; |
|
221 if (aExternalStyleList) |
|
222 iStyleList=CONST_CAST(CStyleList*,aExternalStyleList); |
|
223 } |
|
224 |
|
225 |
|
226 |
|
227 EXPORT_C void CRichText::DoExternalizeMarkupDataL(RWriteStream& aStream)const |
|
228 // Write to the stream, the T.V. representing the markup. |
|
229 // |
|
230 { |
|
231 aStream<< KRichTextMarkupDataUid; |
|
232 aStream<< iIndex; // the specific markup |
|
233 } |
|
234 |
|
235 |
|
236 EXPORT_C void CRichText::DoInternalizeMarkupDataL(RReadStream& aStream) |
|
237 // Load the out-of-line component representing the markup data. |
|
238 { |
|
239 TUid uid=UidFromStreamL(aStream); |
|
240 while (uid!=KRichTextMarkupDataUid) |
|
241 { |
|
242 if (uid==KPlainTextCharacterDataUid) |
|
243 User::Leave(KErrCorrupt); // There is no style or markup Data !!!!! |
|
244 CPlainText::ConsumeAdornmentL(aStream); |
|
245 uid=UidFromStreamL(aStream); |
|
246 } |
|
247 KillIndex(); // prevent alloc heaven when current index handle is lost to internalized swizzle |
|
248 aStream>> iIndex; |
|
249 } |
|
250 |
|
251 |
|
252 /////////////////////////////////////////////////////////// |
|
253 // |
|
254 // Custom persist functions |
|
255 // |
|
256 /////////////////////////////////////////////////////////// |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 EXPORT_C void CRichText::ExternalizeStyleDataL(RWriteStream& aStream)const |
|
262 /** Externalises the style list owned by the rich text object. |
|
263 |
|
264 @param aStream Stream to which to write the style list. */ |
|
265 { |
|
266 __TEST_INVARIANT; |
|
267 |
|
268 if (StyleListPresent() && !StyleListExternallyOwned()) |
|
269 { |
|
270 aStream.WriteUint8L((TUint8)1); // there follows a style list |
|
271 aStream<< *iStyleList; |
|
272 } |
|
273 else |
|
274 aStream.WriteUint8L((TUint8)0); // there are no paragraph styles |
|
275 } |
|
276 |
|
277 EXPORT_C void CRichText::InternalizeStyleDataL(RReadStream& aStream) |
|
278 /** Internalises the style list owned by the rich text object from a read stream, |
|
279 if one is present in the stream. |
|
280 |
|
281 @param aStream Stream from which to read the style list. */ |
|
282 { |
|
283 TUint8 styleListPresent=aStream.ReadUint8L(); |
|
284 if (styleListPresent) |
|
285 { |
|
286 CStyleList* styleList=CStyleList::NewL(aStream,iGlobalParaFormatLayer,iGlobalCharFormatLayer); |
|
287 //coverity[leave_without_push] |
|
288 delete iStyleList.AsPtr(); |
|
289 iStyleList=styleList; |
|
290 } |
|
291 } |
|
292 |
|
293 EXPORT_C void CRichText::ExternalizeMarkupDataL(RWriteStream& aStream)const |
|
294 /** Externalises the rich text object's markup (specific formatting, styles and |
|
295 pictures). CRichText::HasMarkupData() can be used to test whether the object |
|
296 has any markup information. |
|
297 |
|
298 @param aStream Stream to which to store the rich text markup information. */ |
|
299 { |
|
300 __TEST_INVARIANT; |
|
301 |
|
302 CONST_CAST(CRichText*,this)->CancelInsertCharFormat(); |
|
303 if (!IndexPresent()) |
|
304 CONST_CAST(CRichText*,this)->CreateAndGenerateMarkupComponentL(); |
|
305 aStream<< *iIndex; |
|
306 } |
|
307 |
|
308 EXPORT_C void CRichText::InternalizeMarkupDataL(RReadStream& aStream) |
|
309 /** Internalises the rich text object's markup (specific formatting, styles and |
|
310 pictures). |
|
311 |
|
312 @param aStream Stream from which to internalise the rich text markup. */ |
|
313 { |
|
314 KillIndex(); |
|
315 CreateEmptyMarkupComponentL(); // set iIndex::iStyleList |
|
316 iIndex->InternalizeL(aStream,iGlobalParaFormatLayer,iGlobalCharFormatLayer,iStyleList.AsPtr()); |
|
317 } |
|
318 |
|
319 EXPORT_C void CRichText::StoreMarkupComponentsL(CStreamStore& aStore,CStoreMap& aMap)const |
|
320 /** Stores all pictures in the rich text object to a stream store. |
|
321 |
|
322 @param aStore Stream store to which the pictures are to be stored. |
|
323 @param aMap A store map. This binds the address of pictures to the stream ID |
|
324 of aStore. This is needed to support the deferred loading of pictures. */ |
|
325 { |
|
326 __TEST_INVARIANT; |
|
327 |
|
328 if (!IndexPresent()) |
|
329 CONST_CAST(CRichText*,this)->CreateAndGenerateMarkupComponentL(); |
|
330 iIndex->StorePicturesL(aStore,aMap); |
|
331 } |
|
332 |
|
333 |
|
334 /////////////////////////////////////////////////////////// |
|
335 // |
|
336 // Utility persist functions |
|
337 // |
|
338 /////////////////////////////////////////////////////////// |
|
339 |
|
340 EXPORT_C TBool CRichText::HasMarkupData()const |
|
341 /** Tests whether the rich text object has any markup, or owns a style list. |
|
342 |
|
343 Markup is rich text-specific information, for instance specific formatting, |
|
344 styles and pictures. It may be stored in a separate stream from the text. |
|
345 |
|
346 @return ETrue if the rich text object has markup, or owns a style list. EFalse |
|
347 if not. */ |
|
348 { |
|
349 if (StyleListPresent() && !StyleListExternallyOwned()) |
|
350 return ETrue; |
|
351 if (IndexPresent()) |
|
352 return iIndex->HasMarkupData(iGlobalParaFormatLayer); |
|
353 else |
|
354 return EFalse; |
|
355 } |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 EXPORT_C void CRichText::DetachFromStoreL(CPicture::TDetach aDegree) |
|
361 /** Loads pictures not already present in memory overloaded function. |
|
362 Either loads all pictures in the document, or just the pictures located within |
|
363 a specified range. Note: In order to load pictures, a picture factory and a |
|
364 store resolver must have been set. |
|
365 |
|
366 @param aDegree There are two possible values: EDetachFull and EDetachDraw. |
|
367 If you detach using EDetachFull then you can both draw and edit the picture(s), |
|
368 but if you detach with EDetachDraw then you can only draw them any attempt |
|
369 at editing them causes a panic. |
|
370 @param aPos The start of the range of characters to search. |
|
371 @param aLength The number of characters in the range. */ |
|
372 { |
|
373 __ETEXT_WATCH(DETACH); |
|
374 |
|
375 __TEST_INVARIANT; |
|
376 |
|
377 if (IndexPresent()) |
|
378 iIndex->DetachFromStoreL(aDegree,0,DocumentLength()); |
|
379 |
|
380 __TEST_INVARIANT; |
|
381 |
|
382 __ETEXT_WATCH_END(DETACH); |
|
383 } |
|
384 |
|
385 |
|
386 EXPORT_C void CRichText::DetachFromStoreL(CPicture::TDetach aDegree,TInt aPos,TInt aLength) |
|
387 /** Loads pictures not already present in memory overloaded function. Either |
|
388 loads all pictures in the document, or just the pictures located within a |
|
389 specified range. |
|
390 |
|
391 Note: In order to load pictures, a picture factory and a store resolver must have |
|
392 been set. |
|
393 |
|
394 @param aDegree There are two possible values: EDetachFull and EDetachDraw. |
|
395 If you detach using EDetachFull then you can both draw and edit the picture(s), |
|
396 but if you detach with EDetachDraw then you can only draw them any attempt |
|
397 at editing them causes a panic. |
|
398 @param aPos The start of the range of characters to search. |
|
399 @param aLength The number of characters in the range. */ |
|
400 { |
|
401 __ETEXT_WATCH(DETACH_POS_LENGTH); |
|
402 |
|
403 __TEST_INVARIANT; |
|
404 TInt documentLength = DocumentLength(); |
|
405 __ASSERT_ALWAYS(aPos >= 0 && aPos <= documentLength,Panic(ECharPosBeyondDocument)); |
|
406 __ASSERT_ALWAYS(aLength >= 0,Panic(ECopyToStreamNegativeLength)); |
|
407 __ASSERT_ALWAYS(aPos + aLength <= documentLength,Panic(ECharPosBeyondDocument)); |
|
408 |
|
409 if (aLength > 0 && IndexPresent()) |
|
410 iIndex->DetachFromStoreL(aDegree,aPos,aLength); |
|
411 |
|
412 __TEST_INVARIANT; |
|
413 |
|
414 __ETEXT_WATCH_END(DETACH_POS_LENGTH); |
|
415 } |
|
416 |
|
417 EXPORT_C void CRichText::SetPictureFactory(MPictureFactory* aPictureFactory,MRichTextStoreResolver* aStoreResolver) |
|
418 // Sets up a callback for the index. |
|
419 // Only called if the owner of this rich text component knows they will wanting to restore pictures |
|
420 // into this rich text. |
|
421 // If the index component is not yet present, the callbacks are preserved until required. |
|
422 // |
|
423 /** Sets the picture factory. |
|
424 |
|
425 Pictures in a rich text object may be represented as picture headers, or by |
|
426 the picture data itself. CRichText supports the deferred loading of picture |
|
427 data, so that it is only loaded when it is needed to be displayed, thus |
|
428 economising on memory use. A rich text object which supports the deferred |
|
429 loading of pictures needs to be supplied with a picture factory. It can either |
|
430 be set using this function, or during construction. |
|
431 |
|
432 Note: A panic occurs if the factory is NULL, but the store resolver is not NULL. |
|
433 |
|
434 @param aPictureFactory The picture factory. |
|
435 @param aStoreResolver The store resolver. This determines which file store |
|
436 the picture is stored in. */ |
|
437 { |
|
438 __TEST_INVARIANT; |
|
439 __ASSERT_ALWAYS(!(!aPictureFactory && aStoreResolver),Panic(EInvalidPictureFactorySettings)); |
|
440 |
|
441 iPictureFactory=aPictureFactory; |
|
442 iStoreResolver=aStoreResolver; |
|
443 } |
|
444 |
|
445 EXPORT_C TPictureHeader CRichText::PictureHeader(TInt aPos)const |
|
446 /** Gets the picture header which describes the picture located at a specified |
|
447 document position. If no picture header is located at the position, the function |
|
448 constructs and returns a default one. |
|
449 |
|
450 @param aPos The document position. Must be valid. |
|
451 @return The picture header located at document position aPos, or a default |
|
452 picture header. */ |
|
453 { |
|
454 __TEST_INVARIANT; |
|
455 __ASSERT_ALWAYS(aPos>=0 && aPos<=DocumentLength(),Panic(ECharPosBeyondDocument)); |
|
456 |
|
457 return (IndexPresent()) |
|
458 ? iIndex->PictureHeader(aPos) |
|
459 : TPictureHeader(); |
|
460 } |
|
461 |
|
462 EXPORT_C void CRichText::DropPictureOwnership(TInt aPos) |
|
463 /** Removes ownership from this rich text object of the picture located at a |
|
464 document position. The picture character is deleted from the document and |
|
465 ownership of the picture passes to the caller of this function. |
|
466 Use PictureHandleL() beforehand to get a pointer to the picture. |
|
467 |
|
468 @param aPos The document position of the picture character. Must be valid |
|
469 or a panic occurs. |
|
470 @see CRichText::PictureHandleL() */ |
|
471 { |
|
472 __TEST_INVARIANT; |
|
473 __ASSERT_ALWAYS(aPos>=0 && aPos<=DocumentLength(),Panic(ECharPosBeyondDocument)); |
|
474 |
|
475 TPictureHeader* p = IndexPresent()? iIndex->PictureHeaderPtr(aPos) : 0; |
|
476 if (!p) |
|
477 return; |
|
478 |
|
479 p->iPicture = 0; |
|
480 DeleteFromParagraph(aPos, 1); |
|
481 } |
|
482 |