|
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 <e32std.h> |
|
20 #include <e32base.h> |
|
21 |
|
22 #include <s32strm.h> |
|
23 |
|
24 #include <txtfrmat.h> |
|
25 #include <txtfmlyr.h> |
|
26 #include <txtstyle.h> |
|
27 #include <txtrich.h> |
|
28 #include <txtuids.h> |
|
29 |
|
30 #include <prnsetup.h> |
|
31 #include <prnuids.h> |
|
32 |
|
33 #include "WNGMODEL.H" |
|
34 #include "WNGPANIC.H" |
|
35 |
|
36 const TInt KDefaultTextGranularity=256; |
|
37 |
|
38 EXPORT_C CWordModel* CWordModel::NewL(const MFieldFileNameInfo* aFileNameInfo,const MFieldNumPagesInfo* aFieldNumPagesInfo,const TDesC& aDriverPath) |
|
39 /** Allocates and creates a new word processor engine, and performs printer initalisation. |
|
40 |
|
41 @param aFileNameInfo Optional callback interface to get the current document's |
|
42 filename. This provides the file name for insertion into a field in the header |
|
43 or footer. |
|
44 @param aFieldNumPagesInfo Optional callback interface to return the number |
|
45 of pages in the current document. This provides the total number of pages |
|
46 for insertion into a field in the header or footer. |
|
47 @param aDriverPath Directory that contains printer driver files |
|
48 @return New word processor engine */ |
|
49 { |
|
50 CWordModel* self=new(ELeave) CWordModel(); |
|
51 CleanupStack::PushL(self); |
|
52 self->ConstructMinimalL(aFileNameInfo,aFieldNumPagesInfo,aDriverPath); |
|
53 CleanupStack::Pop(); // self |
|
54 return self; |
|
55 } |
|
56 |
|
57 |
|
58 EXPORT_C CWordModel* CWordModel::NewL(const MFieldFileNameInfo* aFileNameInfo,const MFieldNumPagesInfo* aNumPagesInfo) |
|
59 /** Allocates and creates a new word processor engine. |
|
60 |
|
61 @param aFileNameInfo Optional callback interface to get the current document's |
|
62 filename. This provides the file name for insertion into a field in the header |
|
63 or footer. |
|
64 @param aNumPagesInfo Optional callback interface to return the number |
|
65 of pages in the current document. This provides the total number of pages |
|
66 for insertion into a field in the header or footer. |
|
67 @return New word processor engine */ |
|
68 { |
|
69 CWordModel* self=new(ELeave) CWordModel(); |
|
70 CleanupStack::PushL(self); |
|
71 self->ConstructL(aFileNameInfo,aNumPagesInfo); |
|
72 CleanupStack::Pop(); |
|
73 return self; |
|
74 } |
|
75 |
|
76 |
|
77 EXPORT_C CWordModel::CWordModel() |
|
78 /** Default constructor. */ |
|
79 {} |
|
80 |
|
81 |
|
82 void CWordModel::ConstructGlobalLayersL() |
|
83 { |
|
84 // |
|
85 // Create a default usable Normal style (the default layers) |
|
86 CParaFormat paraFormat; |
|
87 TParaFormatMask paraFormatMask; |
|
88 paraFormat.iSpaceAfterInTwips=100; |
|
89 paraFormatMask.SetAttrib(EAttSpaceAfter); |
|
90 paraFormat.iHorizontalAlignment=CParaFormat::ELeftAlign; |
|
91 paraFormatMask.SetAttrib(EAttAlignment); |
|
92 iParaFormatLayer=CParaFormatLayer::NewL(¶Format,paraFormatMask); |
|
93 // |
|
94 TCharFormat charFormat; |
|
95 TCharFormatMask charFormatMask; |
|
96 TInt typefaceAttributes=TTypeface::EProportional|TTypeface::ESerif; |
|
97 charFormat.iFontSpec.iTypeface.SetAttributes(typefaceAttributes); |
|
98 charFormat.iFontSpec.iHeight=200; |
|
99 charFormatMask.SetAttrib(EAttFontTypeface); |
|
100 charFormatMask.SetAttrib(EAttFontHeight); |
|
101 iCharFormatLayer=CCharFormatLayer::NewL(charFormat,charFormatMask); |
|
102 // |
|
103 iText=CRichText::NewL(iParaFormatLayer,iCharFormatLayer, |
|
104 CEditableText::ESegmentedStorage, |
|
105 KDefaultTextGranularity); |
|
106 iPageTable=new(ELeave) CArrayFixFlat<TInt>(5); |
|
107 } |
|
108 |
|
109 |
|
110 EXPORT_C void CWordModel::ConstructMinimalL(const MFieldFileNameInfo* aFileNameInfo,const MFieldNumPagesInfo* aFieldNumPagesInfo,const TDesC& aDriverPath) |
|
111 // Minimal initialisation, to allow all components to function well. |
|
112 // Used by winc developers. |
|
113 // A printer device must be created by the caller. |
|
114 // |
|
115 /** Second-phase constructor, with printer initialisation. |
|
116 |
|
117 @param aFileNameInfo Optional callback interface to get the current document's |
|
118 filename. This provides the file name for insertion into a field in the header |
|
119 or footer. |
|
120 @param aFieldNumPagesInfo Optional callback interface to return the number |
|
121 of pages in the current document. This provides the total number of pages |
|
122 for insertion into a field in the header or footer. |
|
123 @param aDriverPath Directory that contains printer driver files */ |
|
124 { |
|
125 // |
|
126 // Create the uninitialised print setup object |
|
127 InitPrintSetupL(aFileNameInfo,aFieldNumPagesInfo,aDriverPath); |
|
128 // |
|
129 // Create global layers |
|
130 // |
|
131 ConstructGlobalLayersL(); |
|
132 // |
|
133 // Create the default, empty style list. |
|
134 iStyleList=CStyleList::NewL(); |
|
135 iStyleShortCutList=new(ELeave) CStyleShortCutList(3); |
|
136 // |
|
137 // |
|
138 iText->SetStyleListExternallyOwned(*iStyleList); |
|
139 } |
|
140 |
|
141 |
|
142 EXPORT_C void CWordModel::ConstructL(const MFieldFileNameInfo* aFileNameInfo,const MFieldNumPagesInfo* aNumPagesInfo) |
|
143 /** Second-phase constructor. |
|
144 |
|
145 @param aFileNameInfo Callback interface to get the current document's filename. |
|
146 @param aNumPagesInfo Callback interface to return the number of pages in the current |
|
147 document. */ |
|
148 { |
|
149 // |
|
150 // Create the uninitialised print setup object |
|
151 InitPrintSetupL( aFileNameInfo, aNumPagesInfo, KDefaultPrinterDriverPath ); |
|
152 // |
|
153 // Create a default usable Normal style (the default layers) |
|
154 ConstructGlobalLayersL(); |
|
155 /* |
|
156 iStyleList=NULL; |
|
157 iStyleShortCutList=NULL; |
|
158 iStyleList=CStyleList::NewL(); |
|
159 iStyleShortCutList=new(ELeave) CStyleShortCutList(3); |
|
160 for (TInt ii=0;ii<3;ii++) |
|
161 { |
|
162 CParagraphStyle* style=CParagraphStyle::NewL(*iParaFormatLayer,*iCharFormatLayer); |
|
163 RParagraphStyleInfo info(style); |
|
164 iStyleList->AppendL(&info); |
|
165 } |
|
166 iStyleList->At(0).iStyle->SetType(KSystemParagraphStyleUid); |
|
167 iStyleList->At(0).iStyle->iName=_L("Heading 1"); |
|
168 iStyleList->At(1).iStyle->SetType(KSystemParagraphStyleUid); |
|
169 iStyleList->At(1).iStyle->iName=_L("Heading 2"); |
|
170 iStyleList->At(2).iStyle->SetType(KSystemParagraphStyleUid); |
|
171 iStyleList->At(2).iStyle->iName=_L("Heading 3"); |
|
172 |
|
173 iStyleShortCutList->AppendL('1'); |
|
174 iStyleShortCutList->AppendL('2'); |
|
175 iStyleShortCutList->AppendL('3'); |
|
176 iNormalStyleShortCut='N'; |
|
177 */ |
|
178 // iText->SetStyleListExternallyOwned(*iStyleList); |
|
179 } |
|
180 |
|
181 |
|
182 void CWordModel::InitPrintSetupL(const MFieldFileNameInfo* aFileNameInfo,const MFieldNumPagesInfo* aNumPagesInfo,const TDesC& aDriverPath) |
|
183 // Creates a default printer device and does some initialisation |
|
184 // A real printer device is not constructed here. |
|
185 // |
|
186 { |
|
187 iPrintSetup=CPrintSetup::NewL(); |
|
188 iPrintSetup->AddPrinterDriverDirL(aDriverPath); |
|
189 iPrintSetup->Header()->SetFileNameInfo(CONST_CAST(MFieldFileNameInfo&,*aFileNameInfo)); |
|
190 iPrintSetup->Footer()->SetFileNameInfo(CONST_CAST(MFieldFileNameInfo&,*aFileNameInfo)); |
|
191 iPrintSetup->Header()->SetNumPagesInfo(CONST_CAST(MFieldNumPagesInfo&,*aNumPagesInfo)); |
|
192 iPrintSetup->Footer()->SetNumPagesInfo(CONST_CAST(MFieldNumPagesInfo&,*aNumPagesInfo)); |
|
193 iPrintSetup->iNumOfFirstPage=1; |
|
194 } |
|
195 |
|
196 |
|
197 EXPORT_C CWordModel::~CWordModel() |
|
198 /** Destructor. */ |
|
199 { |
|
200 delete iPrintSetup; |
|
201 delete iStyleList; |
|
202 delete iStyleShortCutList; |
|
203 delete iPageTable; |
|
204 delete iText; |
|
205 delete iParaFormatLayer; |
|
206 delete iCharFormatLayer; |
|
207 } |
|
208 |
|
209 EXPORT_C void CWordModel::StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic,const TAny* aSecurity)const |
|
210 /** Stores the engine. |
|
211 |
|
212 This function writes the engine data to a stream store, and records the streams |
|
213 used in a stream dictionary. |
|
214 |
|
215 @param aStore Store to write to |
|
216 @param aStreamDic Stream dictionary to write to |
|
217 @param aSecurity Optional security object. If this is specified, the stored |
|
218 text stream is encrypted */ |
|
219 { |
|
220 TStreamId id=StoreStylesL(aStore); |
|
221 aStreamDic.AssignL(KUidParagraphStyleStream,id); |
|
222 |
|
223 id=iPrintSetup->StoreL(aStore); |
|
224 aStreamDic.AssignL(KUidPrintSetupStream,id); |
|
225 |
|
226 id=StoreTextDataL(aStore,aSecurity); |
|
227 aStreamDic.AssignL(KUidEditableTextStream,id); |
|
228 |
|
229 id=StoreFieldDataL(aStore); |
|
230 aStreamDic.AssignL(KUidTextFieldStream,id); |
|
231 |
|
232 id=StoreMarkupDataL(aStore); |
|
233 aStreamDic.AssignL(KUidTextMarkupStream,id); |
|
234 } |
|
235 |
|
236 EXPORT_C void CWordModel::RestoreL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic, |
|
237 const TAny* aSecurity,const MFieldFileNameInfo* aFileNameInfo, |
|
238 const MFieldNumPagesInfo* aNumPagesInfo, |
|
239 MPictureFactory* aPictureFactory) |
|
240 |
|
241 /** Restores the engine. |
|
242 |
|
243 @param aStore Store to read from |
|
244 @param aStreamDic Stream dictionary to read from |
|
245 @param aSecurity Optional security object. This is required to read text from |
|
246 an encrypted stream. |
|
247 @param aFileNameInfo An optional object implementing the MFieldFileNameInfo |
|
248 interface. This provides the file name for insertion into a field in the header |
|
249 or footer. |
|
250 @param aNumPagesInfo An optional object implementing the MFieldNumPagesInfo |
|
251 interface. This provides the total number of pages for insertion into a field |
|
252 in the header or footer. |
|
253 @param aPictureFactory An optional object implementing the picture factory |
|
254 interface. This is required if the header or footer contains pictures which |
|
255 should be restored. */ |
|
256 { |
|
257 TStreamId id=aStreamDic.At(KUidParagraphStyleStream); |
|
258 __ASSERT_ALWAYS(id!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
259 RestoreStylesL(aStore,id); |
|
260 |
|
261 id=aStreamDic.At(KUidPrintSetupStream); |
|
262 __ASSERT_ALWAYS(id!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
263 iPrintSetup->RestoreL(aStore,id,CONST_CAST(MFieldFileNameInfo*,aFileNameInfo),CONST_CAST(MFieldNumPagesInfo*,aNumPagesInfo),aPictureFactory); |
|
264 |
|
265 id=aStreamDic.At(KUidEditableTextStream); |
|
266 __ASSERT_ALWAYS(id!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
267 RestoreTextDataL(aStore,id,aSecurity); |
|
268 |
|
269 id=aStreamDic.At(KUidTextFieldStream); |
|
270 if (id!=KNullStreamId) |
|
271 RestoreFieldDataL(aStore,id); |
|
272 |
|
273 iText->SetStyleListExternallyOwned(*iStyleList); // forces restore with style references |
|
274 id=aStreamDic.At(KUidTextMarkupStream); |
|
275 if (id!=KNullStreamId) |
|
276 RestoreMarkupDataL(aStore,id); |
|
277 } |
|
278 |
|
279 EXPORT_C void CWordModel::RestoreMinimalL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic, |
|
280 const TAny* aSecurity,const MFieldFileNameInfo* /*aFileNameInfo*/, |
|
281 const MFieldNumPagesInfo* /*aNumPagesInfo*/, |
|
282 MPictureFactory* /*aPictureFactory*/) |
|
283 /** Restores the engine, without restoring the print setup stream. |
|
284 |
|
285 This allows restoring without loading a printer driver. Header and footer information |
|
286 will not be available. |
|
287 |
|
288 @param aStore Store to read from |
|
289 @param aStreamDic Stream dictionary to read from |
|
290 @param aSecurity Optional security object. This is required to read text from |
|
291 an encrypted stream. |
|
292 @param aFileNameInfo Unused |
|
293 @param aNumPagesInfo Unused |
|
294 @param aPictureFactory Unused */ |
|
295 { |
|
296 TStreamId id=aStreamDic.At(KUidParagraphStyleStream); |
|
297 __ASSERT_ALWAYS(id!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
298 RestoreStylesL(aStore,id); |
|
299 |
|
300 id=aStreamDic.At(KUidEditableTextStream); |
|
301 __ASSERT_ALWAYS(id!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
302 RestoreTextDataL(aStore,id,aSecurity); |
|
303 |
|
304 id=aStreamDic.At(KUidTextFieldStream); |
|
305 if (id!=KNullStreamId) |
|
306 RestoreFieldDataL(aStore,id); |
|
307 |
|
308 iText->SetStyleListExternallyOwned(*iStyleList); // forces restore with style references |
|
309 id=aStreamDic.At(KUidTextMarkupStream); |
|
310 if (id!=KNullStreamId) |
|
311 RestoreMarkupDataL(aStore,id); |
|
312 } |
|
313 |
|
314 |
|
315 |
|
316 TStreamId CWordModel::StoreFieldDataL(CStreamStore& aStore)const |
|
317 // |
|
318 { |
|
319 const TInt fieldCount=iText->FieldCount(); |
|
320 if (fieldCount<=0) |
|
321 return KNullStreamId; |
|
322 CStoreMap* map=CStoreMap::NewLC(aStore); |
|
323 iText->StoreFieldComponentsL(aStore,*map); |
|
324 // |
|
325 RStoreWriteStream stream(*map); |
|
326 TStreamId id=stream.CreateLC(aStore); |
|
327 iText->ExternalizeFieldDataL(stream); |
|
328 stream.CommitL(); |
|
329 // |
|
330 map->Reset(); |
|
331 CleanupStack::PopAndDestroy(2); // stream, map |
|
332 return id; |
|
333 } |
|
334 |
|
335 void CWordModel::RestoreFieldDataL(const CStreamStore& aStore,TStreamId aId) |
|
336 // Assumes a valid stream id |
|
337 // |
|
338 { |
|
339 __ASSERT_DEBUG(aId!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
340 |
|
341 RStoreReadStream stream; |
|
342 stream.OpenLC(aStore,aId); |
|
343 // |
|
344 iText->InternalizeFieldDataL(stream); |
|
345 CleanupStack::PopAndDestroy(); // stream |
|
346 // |
|
347 iText->RestoreFieldComponentsL(aStore); |
|
348 } |
|
349 |
|
350 TStreamId CWordModel::StoreTextDataL(CStreamStore& aStore,const TAny* aSecurity)const |
|
351 { |
|
352 CStreamStore* store = &aStore; |
|
353 // |
|
354 RStoreWriteStream stream; |
|
355 TStreamId id=stream.CreateLC(*store); |
|
356 iText->ExternalizePlainTextL(stream); |
|
357 stream.CommitL(); |
|
358 CleanupStack::PopAndDestroy(); // stream |
|
359 // |
|
360 if (aSecurity) |
|
361 CleanupStack::PopAndDestroy(); // secure store |
|
362 return id; |
|
363 } |
|
364 |
|
365 void CWordModel::RestoreTextDataL(const CStreamStore& aStore,TStreamId aId,const TAny* aSecurity) |
|
366 { |
|
367 __ASSERT_DEBUG(aId!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
368 const CStreamStore* store=&aStore; |
|
369 // |
|
370 RStoreReadStream stream; |
|
371 stream.OpenLC(*store,aId); |
|
372 // |
|
373 iText->InternalizePlainTextL(stream); |
|
374 CleanupStack::PopAndDestroy(); // stream |
|
375 // |
|
376 if (aSecurity) |
|
377 CleanupStack::PopAndDestroy(); // secure store |
|
378 } |
|
379 |
|
380 |
|
381 TStreamId CWordModel::StoreMarkupDataL(CStreamStore& aStore)const |
|
382 // The markup data must be stored in a distinct stream, and will never be encrypted. |
|
383 // Only the text content will be encrypted. |
|
384 // ie, If the container doc is passworded, that password will NOT apply to all embedded objects. |
|
385 // |
|
386 { |
|
387 const TBool hasMarkupData=iText->HasMarkupData(); |
|
388 if (!hasMarkupData) |
|
389 return KNullStreamId; |
|
390 CStoreMap* map=CStoreMap::NewLC(aStore); |
|
391 iText->StoreMarkupComponentsL(aStore,*map); |
|
392 // |
|
393 RStoreWriteStream stream(*map); |
|
394 TStreamId id=stream.CreateLC(aStore); |
|
395 iText->ExternalizeMarkupDataL(stream); |
|
396 stream.CommitL(); |
|
397 // |
|
398 map->Reset(); |
|
399 CleanupStack::PopAndDestroy(2); // stream, map |
|
400 return id; |
|
401 } |
|
402 |
|
403 |
|
404 void CWordModel::RestoreMarkupDataL(const CStreamStore& aStore,TStreamId aId) |
|
405 // |
|
406 // |
|
407 { |
|
408 __ASSERT_DEBUG(aId!=KNullStreamId,User::Leave(KErrCorrupt)); |
|
409 |
|
410 RStoreReadStream stream; |
|
411 stream.OpenLC(aStore,aId); |
|
412 // |
|
413 iText->InternalizeMarkupDataL(stream); |
|
414 CleanupStack::PopAndDestroy(); // strean |
|
415 } |
|
416 |
|
417 |
|
418 TStreamId CWordModel::StoreStylesL(CStreamStore& aStore)const |
|
419 // Store the style list, and the table of short cut keys. |
|
420 // (The short-cut table is mapped directly on to the style list) |
|
421 // Also stores the normal (global layers). |
|
422 // |
|
423 { |
|
424 RStoreWriteStream stream; |
|
425 TStreamId id=stream.CreateLC(aStore); |
|
426 // |
|
427 stream<< *iText->GlobalParaFormatLayer(); // The "normal" style |
|
428 stream<< *iText->GlobalCharFormatLayer(); // |
|
429 stream.WriteUint32L(iNormalStyleShortCut); // The "normal" short cut |
|
430 // |
|
431 TInt shortCutCount=(iStyleShortCutList) ? iStyleShortCutList->Count() : 0; |
|
432 stream.WriteUint8L((TUint8)shortCutCount); |
|
433 for (TInt nn=0;nn<shortCutCount;nn++) |
|
434 stream.WriteUint32L((*iStyleShortCutList)[nn]); |
|
435 stream<< *iStyleList; |
|
436 // |
|
437 stream.CommitL(); |
|
438 CleanupStack::PopAndDestroy(); // stream |
|
439 return id; |
|
440 } |
|
441 |
|
442 |
|
443 void CWordModel::RestoreStylesL(const CStreamStore& aStore,TStreamId aId) |
|
444 // Restore the style list and style short cut key list from the specified stream. |
|
445 // |
|
446 { |
|
447 RStoreReadStream stream; |
|
448 stream.OpenLC(aStore,aId); |
|
449 // |
|
450 delete iParaFormatLayer; |
|
451 delete iCharFormatLayer; |
|
452 iParaFormatLayer=NULL; |
|
453 iCharFormatLayer=NULL; |
|
454 iParaFormatLayer=CParaFormatLayer::NewL(stream); |
|
455 iCharFormatLayer=CCharFormatLayer::NewL(stream); |
|
456 iNormalStyleShortCut=stream.ReadUint32L(); |
|
457 // |
|
458 TUint8 shortCutCount=stream.ReadUint8L(); |
|
459 if (iStyleList) |
|
460 iStyleList->Reset(); |
|
461 // |
|
462 if (iStyleShortCutList) |
|
463 iStyleShortCutList->Reset(); // loading new document from within word |
|
464 else |
|
465 iStyleShortCutList=new(ELeave) CStyleShortCutList(Max(1,(TInt)shortCutCount)); // loading document from shell |
|
466 for (TInt mm=0;mm<shortCutCount;mm++) |
|
467 { |
|
468 TChar shortcut=stream.ReadUint32L(); |
|
469 iStyleShortCutList->AppendL(shortcut); |
|
470 } |
|
471 if (iStyleList) |
|
472 iStyleList->InternalizeL(stream,iParaFormatLayer,iCharFormatLayer); |
|
473 else |
|
474 iStyleList=CStyleList::NewL(stream,iParaFormatLayer,iCharFormatLayer); |
|
475 // |
|
476 iText->SetGlobalParaFormat(iParaFormatLayer); |
|
477 iText->SetGlobalCharFormat(iCharFormatLayer); |
|
478 // |
|
479 CleanupStack::PopAndDestroy(); // stream |
|
480 |
|
481 //__ASSERT_DEBUG(iStyleList->Count()==iStyleShortCutList->Count(),Panic(EStyleIntegrityError)); |
|
482 //remove assertion so word engine supports wp apps with no short cuts but 1 (global) style |
|
483 } |