1 /************************************************************************/
2 /* */
3 /* Read footnotes, headers, footers, textboxes. */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <string.h>
10 # include <stdio.h>
11 # include <ctype.h>
12
13 # include <appDebugon.h>
14
15 # include "docRtfReaderImpl.h"
16 # include <docParaParticules.h>
17 # include <docRecalculateFields.h>
18 # include <docTreeType.h>
19 # include <docNodeTree.h>
20 # include <docNotes.h>
21 # include <docDocumentNote.h>
22
23 /************************************************************************/
24 /* */
25 /* Consume Headers, Footers, Notes &c: Separate item trees that are. */
26 /* embedded in the document. */
27 /* */
28 /* 1) Save the current position. */
29 /* 2) Make the header/note &c. */
30 /* 3) Consume its contents. */
31 /* 4) Make sure that no bookmarks protrude beyond the end of the */
32 /* external item. */
33 /* 5) If the external item happens to be empty, insert an empty */
34 /* paragraph to avoid problems later on. */
35 /* 6) Restore the current position. */
36 /* */
37 /************************************************************************/
38
docRtfReadDocumentTree(const RtfControlWord * rcw,DocumentTree * dt,int * pExtItKind,RtfReader * rrc,int ignoreEmpty,const SelectionScope * ss)39 int docRtfReadDocumentTree( const RtfControlWord * rcw,
40 DocumentTree * dt,
41 int * pExtItKind,
42 RtfReader * rrc,
43 int ignoreEmpty,
44 const SelectionScope * ss )
45 {
46 int rval= 0;
47 RtfReadingState internRrs;
48
49 DocumentTree * savedEi;
50 BufferItem * savedBi;
51 int savedLevel;
52 SelectionScope savedSelectionScope;
53 struct RtfFieldStackLevel * savedFieldStackLevel;
54 int savedLastFieldNumber;
55 RowProperties savedRowProperties;
56
57 int changed= 0;
58
59 /* 1 */
60 savedEi= rrc->rrcTree;
61 savedBi= rrc->rrcNode;
62 savedLevel= rrc->rrcLevel;
63 savedSelectionScope= rrc->rrcSelectionScope;
64 savedFieldStackLevel= rrc->rrcFieldStack;
65 savedLastFieldNumber= rrc->rrcLastFieldNumber;
66 savedRowProperties= rrc->rrcRowProperties;
67
68 docInitRowProperties( &(rrc->rrcRowProperties) );
69
70 docRtfPushReadingState( rrc, &internRrs );
71
72 docRtfResetParagraphProperties( &internRrs );
73 docRtfResetTextAttribute( &internRrs, rrc->rrDocument );
74
75 if ( ! savedBi )
76 { XDEB(savedBi); rval= -1; goto ready; }
77
78 /* 2 */
79 if ( ! dt->dtRoot &&
80 docMakeDocumentTree( rrc->rrDocument, dt,
81 ss, &(rrc->rrcSectionProperties) ) )
82 { LDEB(1); rval= -1; goto ready; }
83
84 /* 3 */
85 rrc->rrcTree= dt;
86 rrc->rrcNode= dt->dtRoot;
87 rrc->rrcLevel= DOClevSECT;
88 rrc->rrcSelectionScope= *ss;
89 rrc->rrcFieldStack= (struct RtfFieldStackLevel *)0;
90 rrc->rrcLastFieldNumber= -1;
91
92 if ( docRtfReadGroup( rcw, 0, 0, rrc,
93 docRtfDocumentGroups,
94 docRtfTextParticule, docRtfFinishCurrentNode ) )
95 { LDEB(1); rval= -1; }
96
97 /* 5 */
98 {
99 DocumentPosition dp;
100
101 if ( docTailPosition( &dp, dt->dtRoot ) )
102 {
103 if ( ignoreEmpty )
104 { docEraseDocumentTree( rrc->rrDocument, dt ); }
105 else{
106 const int textAttributeNumber= 0;
107
108 if ( ! docInsertEmptyParagraph( rrc->rrDocument, dt->dtRoot,
109 textAttributeNumber ) )
110 { LDEB(textAttributeNumber); }
111 }
112 }
113 else{
114 /********************************************************/
115 /* Delete empty paragraph caused by final \par */
116 /********************************************************/
117 if ( docParaStrlen( dp.dpNode ) == 0 &&
118 dp.dpNode->biParaTableNesting == 0 &&
119 docNumberOfParagraph( dp.dpNode ) > 1 &&
120 dp.dpNode->biParaParticuleCount == 1 )
121 {
122 BufferItem * bi= dp.dpNode;
123
124 while( bi->biParent && bi->biParent->biChildCount == 1 )
125 { bi= bi->biParent; }
126
127 docDeleteNode( rrc->rrDocument, dt, bi );
128 }
129 }
130 }
131
132 /* 4 */
133 if ( docRtfPopScopeFromFieldStack( rrc ) )
134 { LDEB(1); rval= -1; goto ready; }
135
136 docRenumberSeqFields( &changed, rrc->rrcTree, rrc->rrDocument );
137
138 *pExtItKind= rrc->rrcSelectionScope.ssTreeType;
139
140 ready:
141 /* 6 */
142
143 docCleanRowProperties( &(rrc->rrcRowProperties) );
144 rrc->rrcRowProperties= savedRowProperties;
145
146 rrc->rrcLastFieldNumber= savedLastFieldNumber;
147 rrc->rrcFieldStack= savedFieldStackLevel;
148 rrc->rrcSelectionScope= savedSelectionScope;
149 rrc->rrcLevel= savedLevel;
150 rrc->rrcNode= savedBi;
151 rrc->rrcTree= savedEi;
152
153 docRtfPopReadingState( rrc );
154
155 return rval;
156 }
157
docRtfReadExtTree(const RtfControlWord * rcw,int arg,RtfReader * rrc)158 int docRtfReadExtTree( const RtfControlWord * rcw,
159 int arg,
160 RtfReader * rrc )
161 {
162 BufferItem * sectNode;
163 BufferDocument * bd= rrc->rrDocument;
164 DocumentTree * dt;
165
166 SelectionScope ss;
167 int treeType;
168 int ignoreEmpty= 0;
169
170 docInitSelectionScope( &ss );
171 ss.ssSectNr= 0;
172
173 switch( rcw->rcwID )
174 {
175 case DOCinFIRST_HEADER:
176 case DOCinLEFT_HEADER:
177 case DOCinRIGHT_HEADER:
178
179 case DOCinFIRST_FOOTER:
180 case DOCinLEFT_FOOTER:
181 case DOCinRIGHT_FOOTER:
182
183 sectNode= docRtfGetSectNode( rrc );
184 if ( ! sectNode )
185 { XDEB(sectNode); return -1; }
186
187 dt= docSectionHeaderFooter( sectNode, (unsigned char *)0,
188 &(rrc->rrDocument->bdProperties), rcw->rcwID );
189 if ( ! dt )
190 { LXDEB(rcw->rcwID,dt); return -1; }
191
192 ss.ssOwnerSectNr= sectNode->biNumberInParent;
193 ignoreEmpty= 1;
194 break;
195
196 case DOCinFTNSEP:
197 case DOCinFTNSEPC:
198 case DOCinFTNCN:
199 case DOCinAFTNSEP:
200 case DOCinAFTNSEPC:
201 case DOCinAFTNCN:
202
203 if ( ! bd )
204 { XDEB(bd); return -1; }
205
206 dt= docDocumentNoteSeparator( bd, rcw->rcwID );
207 if ( ! dt )
208 { LXDEB(rcw->rcwID,dt); return -1; }
209
210 ignoreEmpty= 1;
211 break;
212
213 default:
214 SDEB(rcw->rcwWord); return -1;
215 }
216
217 if ( dt->dtRoot )
218 { docEraseDocumentTree( bd, dt ); }
219
220 ss.ssTreeType= rcw->rcwID;
221 ss.ssOwnerNumber= -1;
222
223 if ( docRtfReadDocumentTree( rcw, dt, &treeType, rrc, ignoreEmpty, &ss ) )
224 { SDEB(rcw->rcwWord); return -1; }
225
226 return 0;
227 }
228
229 /************************************************************************/
230
docExtractFixedTextNote(DocumentNote * dn,BufferDocument * bd,BufferItem * ownerNode,int fixedStroff,int fixedStrlen,const char * fieldinst,int fieldsize)231 static int docExtractFixedTextNote( DocumentNote * dn,
232 BufferDocument * bd,
233 BufferItem * ownerNode,
234 int fixedStroff,
235 int fixedStrlen,
236 const char * fieldinst,
237 int fieldsize )
238
239 {
240 DocumentSelection dsField;
241 BufferItem * noteBi;
242 const int part0= 0;
243
244 if ( utilMemoryBufferSetBytes( &(dn->dnNoteProperties.npFixedText),
245 docParaString( ownerNode, fixedStroff ), fixedStrlen ) )
246 { LDEB(fixedStrlen); }
247
248 if ( docHeadPosition( &(dsField.dsHead),
249 dn->dnDocumentTree.dtRoot ) )
250 { LDEB(1); return -1; }
251 noteBi= dsField.dsHead.dpNode;
252 docSetDocumentPosition( &(dsField.dsTail), noteBi, fixedStrlen );
253
254 if ( docParaStrlen( noteBi ) >= fixedStrlen &&
255 ! memcmp( docParaString( noteBi, 0 ),
256 docParaString( ownerNode, fixedStroff ), fixedStrlen ) )
257 {
258 int part1;
259 TextParticule * tp1;
260 DocumentField * df;
261
262 if ( docFindParticuleOfPosition( &part1, (int *)0,
263 &(dsField.dsTail), PARAfindFIRST ) )
264 { LDEB(fixedStroff); return -1; }
265 tp1= noteBi->biParaParticules+ part1;
266
267 if ( tp1->tpStroff+ tp1->tpStrlen > fixedStrlen )
268 {
269 if ( docSplitTextParticule( &tp1, (TextParticule **)0,
270 noteBi, part1, fixedStrlen ) )
271 { LDEB(part1); return -1; }
272 }
273
274 part1++;
275
276 df= docMakeField( bd, &(dn->dnDocumentTree), &dsField,
277 part0, part1, tp1->tpTextAttrNr, tp1->tpTextAttrNr );
278 if ( ! df )
279 { XDEB(df); return -1; }
280
281 df->dfKind= DOCfkCHFTN;
282 if ( docSetFieldInst( df, fieldinst, fieldsize ) )
283 { LDEB(1); }
284 }
285
286 return 0;
287 }
288
289 /************************************************************************/
290 /* */
291 /* Consume a footnote. */
292 /* */
293 /************************************************************************/
294
docRtfReadFootnote(const RtfControlWord * rcw,int arg,RtfReader * rrc)295 int docRtfReadFootnote( const RtfControlWord * rcw,
296 int arg,
297 RtfReader * rrc )
298 {
299 int rval= 0;
300 BufferDocument * bd= rrc->rrDocument;
301
302 DocumentField * dfNote;
303 DocumentNote * dn;
304 int noteIndex;
305
306 BufferItem * ownerNode;
307 BufferItem * sectNode;
308 SelectionScope ss;
309
310 int treeType;
311 int autoNumber= 0;
312 const int ignoreEmpty= 0;
313
314 int fixedStroff= 0;
315 int fixedStrlen= 0;
316
317 const char * fieldinst= " -CHFTN ";
318 int fieldsize= 8;
319
320 docInitSelectionScope( &ss );
321
322 ownerNode= docRtfGetParaNode( rrc );
323 if ( ! ownerNode )
324 { XDEB(ownerNode); rval= -1; goto ready; }
325 sectNode= docGetSectNode( ownerNode );
326 if ( ! sectNode )
327 { XDEB(sectNode); rval= -1; goto ready; }
328
329 if ( rrc->rrcAfterNoteref )
330 { autoNumber= 1; }
331 else{
332 const char * fieldRslt= (const char *)0;
333
334 DocumentPosition dp;
335 int part0;
336
337 dfNote= docRtfSpecialField( DOCfkCHFTN,
338 fieldinst, fieldsize, fieldRslt, rrc );
339 if ( ! dfNote )
340 { SDEB(rcw->rcwWord); rval= -1; goto ready; }
341
342 docSetDocumentPosition( &dp, ownerNode,
343 dfNote->dfHeadPosition.epStroff );
344 if ( docFindParticuleOfPosition( &part0, (int *)0,
345 &dp, PARAfindFIRST ) )
346 { LDEB(dfNote->dfHeadPosition.epStroff); rval= -1; goto ready; }
347
348 /* Move the fixed text into the note field */
349 if ( ownerNode->biParaParticules[part0 ].tpKind == DOCkindSPAN &&
350 ownerNode->biParaParticules[part0+ 1].tpKind == DOCkindFIELDHEAD )
351 {
352 fixedStroff= ownerNode->biParaParticules[part0 ].tpStroff;
353 fixedStrlen= ownerNode->biParaParticules[part0 ].tpStrlen;
354
355 dfNote->dfHeadPosition.epStroff= fixedStroff;
356
357 ownerNode->biParaParticules[part0+ 1].tpKind= DOCkindSPAN;
358 ownerNode->biParaParticules[part0+ 1].tpObjectNumber= -1;
359 ownerNode->biParaParticules[part0+ 1].tpStroff= fixedStroff;
360 ownerNode->biParaParticules[part0+ 1].tpStrlen= fixedStrlen;
361
362 ownerNode->biParaParticules[part0 ].tpKind= DOCkindFIELDHEAD;
363 ownerNode->biParaParticules[part0 ].tpObjectNumber=
364 dfNote->dfFieldNumber;
365 ownerNode->biParaParticules[part0 ].tpStrlen= 0;
366 }
367
368 autoNumber= 0;
369 if ( fixedStrlen > 0 )
370 {
371 PROPmaskADD( &(rrc->rrcNotePropertyMask), NOTEpropFIXED_TEXT );
372 }
373 }
374
375 dfNote= docGetFieldByNumber( &(bd->bdFieldList), rrc->rrcLastFieldNumber );
376 if ( ! dfNote )
377 { LPDEB(rrc->rrcLastFieldNumber,dfNote); return -1; }
378
379 noteIndex= docInsertNote( &dn, bd, dfNote, autoNumber );
380 if ( noteIndex < 0 )
381 { LDEB(noteIndex); rval= -1; goto ready; }
382
383 rrc->rrcAfterNoteref= 0;
384 rrc->rrAfterParaHeadField= 0;
385
386 ss.ssTreeType= DOCinFOOTNOTE;
387 ss.ssSectNr= 0;
388 ss.ssOwnerSectNr= sectNode->biNumberInParent;
389 ss.ssOwnerNumber= dfNote->dfFieldNumber;
390
391 if ( docRtfReadDocumentTree( rcw, &(dn->dnDocumentTree), &treeType,
392 rrc, ignoreEmpty, &ss ) )
393 { SDEB(rcw->rcwWord); rval= -1; goto ready; }
394
395 dn->dnNoteProperties.npAutoNumber= autoNumber;
396 dn->dnNoteProperties.npTreeType= treeType;
397 docSetTreeTypeOfNode( dn->dnDocumentTree.dtRoot, treeType );
398
399 if ( ! autoNumber &&
400 fixedStrlen > 0 &&
401 docExtractFixedTextNote( dn, bd, ownerNode,
402 fixedStroff, fixedStrlen,
403 fieldinst, fieldsize ) )
404 { LDEB(1); rval= -1; goto ready; }
405
406 ready:
407
408 return rval;
409 }
410
411