1 /************************************************************************/
2 /*									*/
3 /*  Trace modifications to a document.					*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docEditConfig.h"
8 
9 #   include	<stdio.h>
10 #   include	<ctype.h>
11 
12 #   include	<appDebugon.h>
13 
14 #   include	<sioFd.h>
15 
16 #   include	"docRtfTrace.h"
17 #   include	"docEditCommand.h"
18 
19 #   include	<docRtfTraceImpl.h>
20 #   include	<docRtfReaderImpl.h>
21 #   include	<docTreeType.h>
22 #   include	<docRtfTags.h>
23 #   include	<docRtfFlags.h>
24 
25 /************************************************************************/
26 
docRtfReadVersion(const RtfControlWord * rcw,int arg,RtfReader * rrc)27 static int docRtfReadVersion(	const RtfControlWord *	rcw,
28 				int			arg,
29 				RtfReader *		rrc )
30     {
31     int		res;
32 
33     if  ( rcw->rcwID == rrc->rrcTraceReadWhat )
34 	{
35 	if  ( rrc->rrcTraceCommand != EDITcmdUPD_NOTE )
36 	    { rrc->rrcSelectionScope.ssTreeType= DOCinBODY;	}
37 
38 	utilPropMaskClear( &(rrc->rrcPicturePropMask) );
39 	docInitPictureProperties( &(rrc->rrcPictureProperties) );
40 
41 	res= docRtfReadGroup( rcw, 0, 0, rrc,
42 				docRtfDocumentGroups,
43 				docRtfTextParticule,
44 				(RtfCommitGroup)0 );
45 	if  ( res )
46 	    { SLDEB(rcw->rcwWord,res);	}
47 	}
48     else{
49 	res= docRtfSkipGroup( rcw, arg, rrc );
50 	if  ( res )
51 	    { SLDEB(rcw->rcwWord,res);	}
52 	}
53 
54     return res;
55     }
56 
docRtfCommitNewProps(const RtfControlWord * rcw,RtfReader * rrc)57 static int docRtfCommitNewProps(	const RtfControlWord *	rcw,
58 					RtfReader *		rrc )
59     {
60     if  ( docRtfStoreStyleProperties( rrc ) )
61 	{ LDEB(1);	}
62 
63     return 0;
64     }
65 
docRtfReadNewProps(const RtfControlWord * rcw,int arg,RtfReader * rrc)66 static int docRtfReadNewProps(	const RtfControlWord *	rcw,
67 				int			arg,
68 				RtfReader *		rrc )
69     {
70     RtfReadingState *	rrs= rrc->rrcState;
71     int			res;
72 
73     docCleanDocumentStyle( &(rrc->rrcStyle) );
74     docInitDocumentStyle( &(rrc->rrcStyle) );
75 
76     docRtfResetParagraphProperties( rrs );
77     docRtfResetTextAttribute( rrs, rrc->rrDocument );
78 
79     rrc->rrcTraceInProps++;
80 
81     res= docRtfReadGroup( rcw, 0, 0, rrc,
82 			    docRtfDocumentGroups,
83 			    docRtfRefuseText,
84 			    docRtfCommitNewProps );
85     if  ( res )
86 	{ SLDEB(rcw->rcwWord,res);	}
87 
88     rrc->rrcTraceInProps--;
89 
90     docRtfResetParagraphProperties( rrs );
91     docRtfResetTextAttribute( rrs, rrc->rrDocument );
92 
93     return res;
94     }
95 
96 static RtfControlWord	docRtfTraceDetailGroups[]=
97     {
98 	RTF_DEST_XX( RTFtag_NTX,	 1, docRtfReadVersion ),
99 	RTF_DEST_XX( RTFtag_NPR,	 1, docRtfReadNewProps ),
100 	RTF_DEST_XX( RTFtag_OTX,	-1, docRtfReadVersion ),
101 
102 	{ (char *)0, 0, 0 }
103     };
104 
105 /************************************************************************/
106 /*									*/
107 /*  Read a trace step.							*/
108 /*									*/
109 /************************************************************************/
110 
docRtfReadTraceStep(const RtfControlWord * rcw,int arg,RtfReader * rrc)111 static int docRtfReadTraceStep(	const RtfControlWord *	rcw,
112 				int			arg,
113 				RtfReader *		rrc )
114     {
115     int		res;
116 
117     rrc->rrcTraceCommand= rcw->rcwID;
118 
119     if  ( rrc->rrcTraceCommand == EDITcmdUPD_NOTE )
120 	{ rrc->rrcSelectionScope.ssTreeType= DOCinFOOTNOTE;	}
121 
122     res= docRtfReadGroup( rcw, 0, 0, rrc,
123 				docRtfTraceDetailGroups,
124 				(RtfAddTextParticule)0,
125 				(RtfCommitGroup)0 );
126     if  ( res )
127 	{ SLDEB(rcw->rcwWord,res);	}
128 
129     return res;
130     }
131 
132 /************************************************************************/
133 /*									*/
134 /*  Read a trace item.							*/
135 /*									*/
136 /************************************************************************/
137 
138 # define RTF_TRACE_CMD( word, id ) \
139 		    RTF_DEST_XX( (word), (id), docRtfReadTraceStep )
140 
141 static RtfControlWord	docRtfTraceGroups[]=
142 {
143     RTF_TRACE_CMD( RTFtag_SLI,		EDITcmdSET_HYPERLINK ),
144     RTF_TRACE_CMD( RTFtag_SBK,		EDITcmdSET_BOOKMARK ),
145     RTF_TRACE_CMD( RTFtag_DFL,		EDITcmdDEL_FIELD ),
146     RTF_TRACE_CMD( RTFtag_UFL,		EDITcmdUPD_FIELD ),
147     RTF_TRACE_CMD( RTFtag_ULI,		EDITcmdUPD_LIST ),
148     RTF_TRACE_CMD( RTFtag_NLI,		EDITcmdSET_NEW_LIST ),
149     RTF_TRACE_CMD( RTFtag_NNO,		EDITcmdINS_NOTE ),
150     RTF_TRACE_CMD( RTFtag_UNO,		EDITcmdUPD_NOTE ),
151     RTF_TRACE_CMD( RTFtag_UTA,		EDITcmdUPD_SPAN_PROPS ),
152     RTF_TRACE_CMD( RTFtag_UPP,		EDITcmdUPD_PARA_PROPS ),
153     RTF_TRACE_CMD( RTFtag_UTP,		EDITcmdUPD_TABLE_PROPS ),
154     RTF_TRACE_CMD( RTFtag_USP,		EDITcmdUPD_SECT_PROPS ),
155     RTF_TRACE_CMD( RTFtag_USDP,		EDITcmdUPD_SECTDOC_PROPS ),
156     RTF_TRACE_CMD( RTFtag_UDP,		EDITcmdUPD_DOC_PROPS ),
157     RTF_TRACE_CMD( RTFtag_REP,		EDITcmdREPLACE ),
158     RTF_TRACE_CMD( RTFtag_REPF,		EDITcmdREPLACE_FTNSEP ),
159     RTF_TRACE_CMD( RTFtag_REPB,		EDITcmdREPLACE_BODY_LEVEL ),
160     RTF_TRACE_CMD( RTFtag_DELS,		EDITcmdDELETE_SELECTION ),
161     RTF_TRACE_CMD( RTFtag_DELF,		EDITcmdDELETE_SELECTION_DEL ),
162     RTF_TRACE_CMD( RTFtag_DELB,		EDITcmdDELETE_SELECTION_BS ),
163     RTF_TRACE_CMD( RTFtag_REX,		EDITcmdEXTEND_REPLACE ),
164     RTF_TRACE_CMD( RTFtag_MPA,		EDITcmdMERGE_PARAS ),
165 
166     RTF_TRACE_CMD( RTFtag_DPA,		EDITcmdDELETE_PARA ),
167     RTF_TRACE_CMD( RTFtag_DSE,		EDITcmdDELETE_SECT ),
168     RTF_TRACE_CMD( RTFtag_DTB,		EDITcmdDELETE_TABLE ),
169     RTF_TRACE_CMD( RTFtag_DRW,		EDITcmdDELETE_ROW ),
170     RTF_TRACE_CMD( RTFtag_DCO,		EDITcmdDELETE_COLUMN ),
171 
172     RTF_TRACE_CMD( RTFtag_IPA,		EDITcmdINSERT_PARA ),
173     RTF_TRACE_CMD( RTFtag_APA,		EDITcmdAPPEND_PARA ),
174     RTF_TRACE_CMD( RTFtag_ITB,		EDITcmdINSERT_TABLE ),
175     RTF_TRACE_CMD( RTFtag_ISE,		EDITcmdINSERT_SECT ),
176     RTF_TRACE_CMD( RTFtag_ASE,		EDITcmdAPPEND_SECT ),
177     RTF_TRACE_CMD( RTFtag_SSE,		EDITcmdSPLIT_SECT ),
178 
179     RTF_TRACE_CMD( RTFtag_IRW,		EDITcmdINSERT_ROW ),
180     RTF_TRACE_CMD( RTFtag_ARW,		EDITcmdAPPEND_ROW ),
181     RTF_TRACE_CMD( RTFtag_ICO,		EDITcmdINSERT_COLUMN ),
182     RTF_TRACE_CMD( RTFtag_ACO,		EDITcmdAPPEND_COLUMN ),
183 
184     RTF_TRACE_CMD( RTFtag_IHD,		EDITcmdINSERT_HEADER ),
185     RTF_TRACE_CMD( RTFtag_IFT,		EDITcmdINSERT_FOOTER ),
186     RTF_TRACE_CMD( RTFtag_DHD,		EDITcmdDELETE_HEADER ),
187     RTF_TRACE_CMD( RTFtag_DFT,		EDITcmdDELETE_FOOTER ),
188 
189     RTF_TRACE_CMD( RTFtag_UOB,		EDITcmdUPD_OBJECT ),
190 
191     RTF_TRACE_CMD( RTFtag_SRWD,		EDITcmdSHIFT_ROWS_DOWN ),
192     RTF_TRACE_CMD( RTFtag_SRWU,		EDITcmdSHIFT_ROWS_UP ),
193     RTF_TRACE_CMD( RTFtag_SPR,		EDITcmdSHIFT_RIGHT ),
194     RTF_TRACE_CMD( RTFtag_SPL,		EDITcmdSHIFT_LEFT ),
195 
196     RTF_TRACE_CMD( "",			EDITcmd_EDIT_COUNT ),
197 
198     RTF_TRACE_CMD( RTFtag_Open,		EDITcmd_OPEN ),
199     RTF_TRACE_CMD( RTFtag_Save,		EDITcmd_SAVE ),
200     RTF_TRACE_CMD( RTFtag_New,		EDITcmd_NEW ),
201 
202     { (char *)0, 0, 0 }
203 };
204 
205 const int docRtfTraceGroupCount=
206 		    sizeof(docRtfTraceGroups)/sizeof(RtfControlWord)- 1;
207 
docRtfGetTraceTag(int command)208 const char *	docRtfGetTraceTag(	int	command )
209     {
210     const RtfControlWord *	rcw;
211 
212     if  ( docRtfTraceGroupCount != EDITcmd_COUNT		||
213 	  command < 0						||
214 	  command >= docRtfTraceGroupCount			)
215 	{
216 	LLLDEB(command,docRtfTraceGroupCount,EDITcmd_COUNT);
217 	return (const char *)0;
218 	}
219 
220     rcw= docRtfTraceGroups+ command;
221     if  ( rcw->rcwID != command )
222 	{ LLSDEB(command,rcw->rcwID,rcw->rcwWord); return (const char *)0; }
223 
224     return rcw->rcwWord;
225     }
226 
docRtfReadEditStep(EditStep * es,SimpleInputStream * sis,int readOld,int readNew,const BufferDocument * bdRef)227 static int docRtfReadEditStep(	EditStep *			es,
228 				SimpleInputStream *		sis,
229 				int				readOld,
230 				int				readNew,
231 				const BufferDocument *		bdRef )
232     {
233     int				rval= 0;
234     int				res;
235     BufferDocument *		bd= (BufferDocument *)0;
236     RtfReader *			rr= (RtfReader *)0;
237     const RtfControlWord *	rcw;
238 
239     char			controlWord[TEDszRTFCONTROL+1];
240     int				gotArg;
241     int				arg= -1;
242     int				readWhat= 0;
243     int				c;
244 
245     const int			recursively= 1;
246 
247     const DocumentAttributeMap * const dam0= (const DocumentAttributeMap *)0;
248 
249     if  ( readOld && readNew )
250 	{ LLDEB(readOld,readNew); rval= -1; goto ready;	}
251     else{
252 	if  ( readOld )
253 	    { readWhat= -1;	}
254 	if  ( readNew )
255 	    { readWhat=  1;	}
256 	}
257 
258     bd= docEditStepMakeSourceDocument( es, bdRef );
259     if  ( ! bd )
260 	{ XDEB(bd); rval= -1; goto ready;	}
261 
262     rr= docRtfOpenReader( sis, bd, RTFflagUNENCODED );
263 
264     rr->rrcTree= &(rr->rrDocument->bdBody);
265     rr->rrcNode= rr->rrcTree->dtRoot;
266     rr->rrcLevel= DOClevBODY;
267     rr->rrcTraceReadWhat= readWhat;
268     rr->rrcTraceSelectionPosition= SELposTAIL;
269     rr->rrcTraceFieldKind= -1;
270 
271     /* Make shallow copies of the document properties */
272     if  ( bdRef )
273 	{
274 	bd->bdProperties.dpDefaultFont= bdRef->bdProperties.dpDefaultFont;
275 	}
276 
277     res= docRtfFindControl( rr, &c, controlWord, &gotArg, &arg );
278     if  ( res != RTFfiCTRLGROUP )
279 	{ LDEB(res); rval= -1; goto ready; }
280 
281     rcw= docRtfFindWord( controlWord, docRtfTraceGroups );
282     if  ( ! rcw )
283 	{ SXDEB(controlWord,rcw); rval= -1; goto ready; }
284     if  ( rcw->rcwType != RTCtypeDEST )
285 	{ SLDEB(rcw->rcwWord,rcw->rcwType); rval= -1; goto ready;	}
286 
287     res= docRtfApplyControlWord( rcw, gotArg, arg, rr );
288     if  ( res )
289 	{ LDEB(1); rval= -1; goto ready; }
290 
291     docDelimitTables( rr->rrDocument->bdBody.dtRoot, recursively );
292 
293     es->esCommand= rr->rrcTraceCommand;
294     es->esSelectionPosition= rr->rrcTraceSelectionPosition;
295     es->esFieldKind= rr->rrcTraceFieldKind;
296 
297     es->esOldSelectionScope= rr->rrcTraceOldSelectionScope;
298     es->esOldEditRange= rr->rrcTraceOldRange;
299     es->esOldCol0= rr->rrcTraceOldCol0;
300     es->esOldCol1= rr->rrcTraceOldCol1;
301     es->esOldPage= rr->rrcTraceOldPage;
302     es->esOldColumn= rr->rrcTraceOldColumn;
303 
304     es->esNewSelectionScope= rr->rrcTraceNewSelectionScope;
305     es->esNewEditRange= rr->rrcTraceNewRange;
306     es->esNewCol0= rr->rrcTraceNewCol0;
307     es->esNewCol1= rr->rrcTraceNewCol1;
308     es->esNewPage= rr->rrcTraceNewPage;
309     es->esNewColumn= rr->rrcTraceNewColumn;
310 
311     es->esPropLevel= rr->rrcTracePropLevel;
312 
313     if  ( es->esCommand == EDITcmdUPD_SPAN_PROPS	||
314 	  es->esCommand == EDITcmdUPD_PARA_PROPS	||
315 	  es->esCommand == EDITcmdUPD_TABLE_PROPS	||
316 	  es->esCommand == EDITcmdUPD_SECT_PROPS	||
317 	  es->esCommand == EDITcmdUPD_SECTDOC_PROPS	||
318 	  es->esCommand == EDITcmdUPD_DOC_PROPS		||
319 	  es->esCommand == EDITcmdSET_HYPERLINK		||
320 	  es->esCommand == EDITcmdSET_BOOKMARK		||
321 	  es->esCommand == EDITcmdDEL_FIELD		||
322 	  es->esCommand == EDITcmdSET_NEW_LIST		)
323 	{
324 	if  ( docUpdRowProperties( &(rr->rrcStyle.dsRowMask),
325 		    &(rr->rrcStyle.dsRowProps),
326 		    &(rr->rrcRowPropertyMask), &(rr->rrcRowProperties),
327 		    (const DocumentAttributeMap *)0 ) )
328 	    { LDEB(es->esCommand); rval= -1; goto ready;	}
329 
330 	if  ( docCopyStyle( &(es->esNewStyle), &(rr->rrcStyle), dam0 )	)
331 	    { LDEB(es->esCommand); rval= -1; goto ready;	}
332 
333 	if  ( PROPmaskISSET( &(es->esNewStyle.dsRowMask),RPpropCELL_LAYOUT ) ||
334 	      PROPmaskISSET( &(es->esNewStyle.dsRowMask),RPpropCELL_PROPS ) )
335 	    { PROPmaskUNSET( &(es->esNewStyle.dsCellMask), CLpropCELLX ); }
336 	}
337 
338     if  ( docUpdDocumentProperties(
339 	    (PropertyMask *)0, &(es->esNewDocProps),
340 	    &(rr->rrcDocPropertyMask), &(rr->rrcDocumentProperties), dam0 ) )
341 	{ LDEB(es->esCommand); rval= -1; goto ready;	}
342     es->esNewDocPropMask= rr->rrcDocPropertyMask;
343 
344     es->esPicturePropMask= rr->rrcPicturePropMask;
345 
346     es->esNotePropMask= rr->rrcNotePropertyMask;
347     docInitNoteProperties( &(rr->rrcNoteProperties) );
348 
349     es->esDocumentList= rr->rrcDocumentList;
350     docInitDocumentList( &(rr->rrcDocumentList) );
351 
352   ready:
353 
354     if  ( rr )
355 	{ docRtfCloseReader( rr ); 	}
356 
357     return rval;
358     }
359 
360 /************************************************************************/
361 
docRtfSelectionScopeProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)362 int docRtfSelectionScopeProperty(	const RtfControlWord *	rcw,
363 					int			arg,
364 					RtfReader *		rrc )
365     {
366     SelectionScope *	ssOld= &(rrc->rrcTraceOldSelectionScope);
367     SelectionScope *	ssNew= &(rrc->rrcTraceNewSelectionScope);
368 
369     switch( rcw->rcwID )
370 	{
371 	case SSpropTREE_TYPE:
372 	    ssOld->ssTreeType= ssNew->ssTreeType= arg;
373 	    return 0;
374 	case SSpropSECT_NR:
375 	    ssOld->ssSectNr= ssNew->ssSectNr= arg;
376 	    return 0;
377 	case SSpropOWNER_SECT_NR:
378 	    ssOld->ssOwnerSectNr= ssNew->ssOwnerSectNr= arg;
379 	    return 0;
380 	case SSpropOWNER_NR:
381 	    ssOld->ssOwnerNumber= ssNew->ssOwnerNumber= arg;
382 	    return 0;
383 
384 	case SSpropPAGE:
385 	    rrc->rrcTraceOldPage= rrc->rrcTraceNewPage= arg;
386 	    return 0;
387 	case SSpropCOLUMN:
388 	    rrc->rrcTraceOldColumn= rrc->rrcTraceNewColumn= arg;
389 	    return 0;
390 
391 	case SSprop_COUNT+ SSpropTREE_TYPE:
392 	    ssNew->ssTreeType= arg;
393 	    return 0;
394 	case SSprop_COUNT+ SSpropSECT_NR:
395 	    ssNew->ssSectNr= arg;
396 	    return 0;
397 	case SSprop_COUNT+ SSpropOWNER_SECT_NR:
398 	    ssNew->ssOwnerSectNr= arg;
399 	    return 0;
400 	case SSprop_COUNT+ SSpropOWNER_NR:
401 	    ssNew->ssOwnerNumber= arg;
402 	    return 0;
403 
404 	case SSprop_COUNT+ SSpropPAGE:
405 	    rrc->rrcTraceNewPage= arg;
406 	    return 0;
407 	case SSprop_COUNT+ SSpropCOLUMN:
408 	    rrc->rrcTraceNewColumn= arg;
409 	    return 0;
410 
411 	default:
412 	    SDEB(rcw->rcwWord); return -1;
413 	}
414     }
415 
docRtfEditRangeProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)416 int docRtfEditRangeProperty(		const RtfControlWord *	rcw,
417 					int			arg,
418 					RtfReader *		rrc )
419     {
420     switch( rcw->rcwID )
421 	{
422 	case TRACEposOLD_HEAD_COL:
423 	    rrc->rrcTraceOldCol0= arg;
424 	    return 0;
425 	case TRACEposOLD_HEAD_PARA:
426 	    rrc->rrcTraceOldRange.erHead.epParaNr= arg;
427 	    return 0;
428 	case TRACEposOLD_HEAD_STROFF:
429 	    rrc->rrcTraceOldRange.erHead.epStroff= arg;
430 	    return 0;
431 
432 	case TRACEposOLD_TAIL_COL:
433 	    rrc->rrcTraceOldCol1= arg;
434 	    return 0;
435 	case TRACEposOLD_TAIL_PARA:
436 	    rrc->rrcTraceOldRange.erTail.epParaNr= arg;
437 	    return 0;
438 	case TRACEposOLD_TAIL_STROFF:
439 	    rrc->rrcTraceOldRange.erTail.epStroff= arg;
440 	    return 0;
441 
442 	case TRACEposNEW_HEAD_COL:
443 	    rrc->rrcTraceNewCol0= arg;
444 	    return 0;
445 	case TRACEposNEW_HEAD_PARA:
446 	    rrc->rrcTraceNewRange.erHead.epParaNr= arg;
447 	    return 0;
448 	case TRACEposNEW_HEAD_STROFF:
449 	    rrc->rrcTraceNewRange.erHead.epStroff= arg;
450 	    return 0;
451 
452 	case TRACEposNEW_TAIL_COL:
453 	    rrc->rrcTraceNewCol1= arg;
454 	    return 0;
455 	case TRACEposNEW_TAIL_PARA:
456 	    rrc->rrcTraceNewRange.erTail.epParaNr= arg;
457 	    return 0;
458 	case TRACEposNEW_TAIL_STROFF:
459 	    rrc->rrcTraceNewRange.erTail.epStroff= arg;
460 	    return 0;
461 
462 	case TRACEposSELECTED:
463 	    rrc->rrcTraceSelectionPosition= rcw->rcwEnumValue;
464 	    return 0;
465 
466 	case TRACEposPROP_LEVEL:
467 	    rrc->rrcTracePropLevel= arg;
468 	    return 0;
469 	case TRACEposFIELD_KIND:
470 	    rrc->rrcTraceFieldKind= arg;
471 	    return 0;
472 
473 	default:
474 	    SDEB(rcw->rcwWord); return -1;
475 	}
476     }
477 
478 /************************************************************************/
479 
docRtfReadTraceStepN(EditStep * es,int readOld,int readNew,const EditTrace * et,int n,const BufferDocument * bdRef)480 static int docRtfReadTraceStepN( EditStep *			es,
481 				int				readOld,
482 				int				readNew,
483 				const EditTrace *		et,
484 				int				n,
485 				const BufferDocument *		bdRef )
486     {
487     int				rval= 0;
488     SimpleInputStream *		sis= (SimpleInputStream *)0;
489     const TraceStep *		ts;
490 
491     ts= (const TraceStep *)utilPagedListGetItemByNumber(
492 						    &(et->etTraceSteps), n );
493     if  ( ! ts )
494 	{ LXDEB(n,ts); rval= -1; goto ready;	}
495 
496     sis= sioInFdOpenAt( et->etTraceFileHandle, ts->tsTraceOffset );
497     if  ( ! sis )
498 	{ LPDEB(et->etTraceFileHandle,sis); rval= -1; goto ready;	}
499 
500     if  ( docRtfReadEditStep( es, sis, readOld, readNew, bdRef ) )
501 	{ LDEB(1); rval= -1; goto ready;	}
502 
503   ready:
504 
505     if  ( sis )
506 	{ sioInClose( sis );	}
507 
508     return rval;
509     }
510 
docRtfReadExtendedReplace(EditStep * es,int readOld,int readNew,const EditTrace * et,int n,const BufferDocument * bdRef)511 static int docRtfReadExtendedReplace(
512 				EditStep *			es,
513 				int				readOld,
514 				int				readNew,
515 				const EditTrace *		et,
516 				int				n,
517 				const BufferDocument *		bdRef )
518     {
519     int			rval= 0;
520     EditStep		esExt;
521 
522     docInitEditStep( &esExt );
523 
524     if  ( docRtfReadTraceStepN( es, readOld, readNew, et, n, bdRef ) )
525 	{ LDEB(1); rval= -1; goto ready;	}
526     if  ( es->esCommand != EDITcmdREPLACE )
527 	{ LDEB(es->esCommand); rval= -1; goto ready;	}
528 
529     if  ( docRtfReadTraceStepN( &esExt, readOld, readNew, et, n+ 1, bdRef ) )
530 	{ LDEB(1); rval= -1; goto ready;	}
531     if  ( esExt.esCommand != EDITcmdEXTEND_REPLACE )
532 	{ LDEB(es->esCommand); rval= -1; goto ready;	}
533 
534     es->esNewEditRange= esExt.esNewEditRange;
535 
536     /* Not used
537     es->esNewSelectionScope= esExt.esNewSelectionScope;
538     es->esNewCol0= esExt.esNewCol0;
539     es->esNewCol1= esExt.esNewCol1;
540     es->esNewPage= esExt.esNewPage;
541     es->esNewColumn= esExt.esNewColumn;
542     */
543 
544     if  ( readNew )
545 	{
546 	BufferDocument *	swap;
547 	int			inte;
548 
549 	swap= es->esSourceDocument;
550 	      es->esSourceDocument= esExt.esSourceDocument;
551 			            esExt.esSourceDocument= swap;
552 
553 	inte= es->esSourceIsIntermediary;
554 	      es->esSourceIsIntermediary= esExt.esSourceIsIntermediary;
555 					  esExt.esSourceIsIntermediary= inte;
556 	}
557 
558   ready:
559 
560     docCleanEditStep( &esExt );
561 
562     return rval;
563     }
564 
docEditReadTraceStep(EditStep * es,int * pIsRepeat,int direction,const EditTrace * et,const BufferDocument * bdRef)565 int docEditReadTraceStep(	EditStep *			es,
566 				int *				pIsRepeat,
567 				int				direction,
568 				const EditTrace *		et,
569 				const BufferDocument *		bdRef )
570     {
571     int			rval= 0;
572     int			n;
573     const TraceStep *	ts= (const TraceStep *)0;
574 
575     const int		readNew= direction > 0;
576     const int		readOld= direction < 0;
577     int			isRepeat= 0;
578 
579     n= docEditGetTraceStep( &ts, &isRepeat, direction, et, et->etIndex );
580     if  ( n < 0 )
581 	{ LDEB(n); rval= -1; goto ready;	}
582 
583     switch( ts->tsCommand )
584 	{
585 	case EDITcmdEXTEND_REPLACE:
586 	    if  ( docRtfReadExtendedReplace( es, readOld, readNew,
587 							    et, n- 1, bdRef ) )
588 		{ LDEB(1); rval= -1; goto ready;	}
589 	    es->esTraceIndex= n- 1;
590 	    es->esStepCount= 2;
591 	    break;
592 
593 	case EDITcmdREPLACE:
594 	    ts= (const TraceStep *)0;
595 	    if  ( n < et->etCount- 1 )
596 		{
597 		ts= (const TraceStep *)utilPagedListGetItemByNumber(
598 						&(et->etTraceSteps), n+ 1 );
599 		if  ( ! ts )
600 		    { LXDEB(n,ts); rval= -1; goto ready;	}
601 		}
602 
603 	    if  ( ts && ts->tsCommand == EDITcmdEXTEND_REPLACE )
604 		{
605 		if  ( docRtfReadExtendedReplace( es, readOld, readNew,
606 								et, n, bdRef ) )
607 		    { LDEB(1); rval= -1; goto ready;	}
608 		es->esTraceIndex= n;
609 		es->esStepCount= 2;
610 		}
611 	    else{
612 		if  ( docRtfReadTraceStepN( es, readOld, readNew,
613 								et, n, bdRef ) )
614 		    { LDEB(1); rval= -1; goto ready;	}
615 		es->esTraceIndex= n;
616 		es->esStepCount= 1;
617 		}
618 	    break;
619 
620 	default:
621 	    if  ( docRtfReadTraceStepN( es, readOld, readNew, et, n, bdRef ) )
622 		{ LDEB(1); rval= -1; goto ready;	}
623 	    es->esTraceIndex= n;
624 	    es->esStepCount= 1;
625 	    break;
626 	}
627 
628     if  ( pIsRepeat )
629 	{ *pIsRepeat= isRepeat;	}
630 
631   ready:
632 
633     return rval;
634     }
635 
docRtfScanEditTrace(const EditTrace * et,SimpleInputStream * sis,HandleEditStep handleStep,void * through,int readOld,int readNew,const BufferDocument * bdRef)636 int docRtfScanEditTrace(	const EditTrace *		et,
637 				SimpleInputStream *		sis,
638 				HandleEditStep			handleStep,
639 				void *				through,
640 				int				readOld,
641 				int				readNew,
642 				const BufferDocument *		bdRef )
643     {
644     int			rval= 0;
645 
646     TraceStep		ts;
647     EditStep		es;
648     int			step= 0;
649     int			exhausted= 0;
650 
651     docInitTraceStep( &ts );
652     docInitEditStep( &es );
653 
654     step= 0;
655     ts.tsTraceOffset= 0;
656 
657     while( ! exhausted )
658 	{
659 	int	res;
660 	long	endOffset;
661 
662 	ts.tsTraceOffset= sioInGetBytesRead( sis );
663 
664 	if  ( docRtfReadEditStep( &es, sis, readOld, readNew, bdRef ) )
665 	    { LDEB(1); rval= -1; goto ready;	}
666 
667 	{
668 	int	c= sioInGetByte( sis );
669 
670 	while ( c == '\r' || c == '\n' )
671 	    { c= sioInGetByte( sis );	}
672 
673 	if  ( c == EOF )
674 	    { exhausted= 1;			}
675 	else{ sioInUngetLastRead( sis );	}
676 	}
677 
678 	endOffset= sioInGetBytesRead( sis );
679 
680 	ts.tsCommand= es.esCommand;
681 	ts.tsFieldKind= es.esFieldKind;
682 	/* ts.tsTraceOffset= .. set above */
683 	ts.tsByteCount= endOffset- ts.tsTraceOffset;
684 
685 	res= (*handleStep)( &ts, &es, step, through );
686 	if  ( res < 0 )
687 	    { LDEB(res); rval= -1; goto ready;	}
688 	if  ( res > 0 )
689 	    { goto ready;	}
690 
691 	step++;
692 	docCleanEditStep( &es ); docInitEditStep( &es );
693 	}
694 
695   ready:
696 
697     docCleanEditStep( &es );
698 
699     return rval;
700     }
701