1 /************************************************************************/
2 /*									*/
3 /*  Editor functionality.						*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"tedConfig.h"
8 
9 #   include	<stddef.h>
10 #   include	<stdio.h>
11 #   include	<ctype.h>
12 
13 #   include	<uniUtf8.h>
14 #   include	<ucdGeneralCategory.h>
15 
16 #   include	"tedEdit.h"
17 #   include	"tedDocument.h"
18 #   include	"tedApp.h"
19 #   include	"tedSelect.h"
20 #   include	"tedToolFront.h"
21 #   include	<docRtfTrace.h>
22 #   include	<docTreeType.h>
23 #   include	<docField.h>
24 #   include	<docTextParticule.h>
25 #   include	<docTreeNode.h>
26 #   include	<docEditCommand.h>
27 
28 #   include	<appDebugon.h>
29 
30 /************************************************************************/
31 /*									*/
32 /*  Replace the selection in the document with new text.		*/
33 /*									*/
34 /*  b)  Replace the tail of the beginning paragraph with the new text.	*/
35 /*  c)  Merge the two paragraphs.					*/
36 /*  d)  Erase all paragraphs after the beginning of the selection	*/
37 /*	to, including the end.						*/
38 /*  e)  Update the paragraph buffer and the particule administration.	*/
39 /*									*/
40 /*  B)  The first particule of the line was split, also reformat the	*/
41 /*	previous line.							*/
42 /*	If paragraphs were merged, redraw the whole neighbourhood.	*/
43 /*  C)  - Recalculate the geometry from the start of the selection to	*/
44 /*	  the end of the paragraph.					*/
45 /*	- Redraw the affected part of the paragraph.			*/
46 /*  6)  Update the notion of current particule and current line.	*/
47 /*  7)  Redraw the I-Bar.						*/
48 /*									*/
49 /************************************************************************/
50 
tedEditReplaceSelection(TedEditOperation * teo,const char * addedText,int addedLength,int textAttributeNr)51 int tedEditReplaceSelection(	TedEditOperation *	teo,
52 				const char *		addedText,
53 				int			addedLength,
54 				int			textAttributeNr )
55     {
56     EditOperation *		eo= &(teo->teoEo);
57 
58     /*  b,c,d,e  */
59     if  ( docReplaceSelection( eo, addedText, addedLength, textAttributeNr ) )
60 	{ LDEB(addedLength); return -1;	}
61 
62     return 0;
63     }
64 
tedEditDeleteSelection(TedEditOperation * teo)65 int tedEditDeleteSelection(	TedEditOperation *	teo )
66     {
67     EditOperation *		eo= &(teo->teoEo);
68 
69     /*  b,c,d,e  */
70     if  ( docDeleteSelection( eo ) )
71 	{ LDEB(1); return -1;	}
72 
73     return 0;
74     }
75 
76 /************************************************************************/
77 /*									*/
78 /*  Merge the selection into one paragraph.				*/
79 /*									*/
80 /************************************************************************/
81 
tedMergeParagraphsInSelection(EditDocument * ed,int traced)82 int tedMergeParagraphsInSelection(	EditDocument *		ed,
83 					int			traced )
84     {
85     int				rval= 0;
86     int				beforeEnd;
87 
88     TedEditOperation		teo;
89     EditOperation *		eo= &(teo.teoEo);
90     SelectionGeometry		sg;
91     SelectionDescription	sd;
92 
93     DocumentSelection		dsTraced;
94 
95     const int			fullWidth= 1;
96 
97     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
98 
99     if  ( tedEditStartReplace( &dsTraced, &teo,
100 					EDITcmdMERGE_PARAS, DOClevSPAN, 0 ) )
101 	{ LDEB(1); rval= -1; goto ready;	}
102 
103     beforeEnd= docParaStrlen( eo->eoTailDp.dpNode )-
104 					eo->eoSelectedRange.erTail.epStroff;
105 
106     if  ( docMergeParagraphsInSelection( eo ) )
107 	{ LDEB(1); rval= -1; goto ready;	}
108 
109     eo->eoSelectedRange.erTail.epParaNr= eo->eoSelectedRange.erHead.epParaNr;
110     eo->eoSelectedRange.erTail.epStroff=
111 				docParaStrlen( eo->eoHeadDp.dpNode )- beforeEnd;
112     eo->eoAffectedRange= eo->eoSelectedRange;
113 
114     if  ( tedEditFinishOldSelection( &teo ) )
115 	{ LDEB(1);	}
116 
117     if  ( teo.teoEditTrace )
118 	{
119 	if  ( docRtfTraceNewContents( eo, SELposALL ) )
120 	    { LDEB(1); rval= -1; goto ready;	}
121 	}
122 
123     tedFinishEditOperation( &teo );
124 
125   ready:
126 
127     tedCleanEditOperation( &teo );
128 
129     return rval;
130     }
131 
132 /************************************************************************/
133 /*									*/
134 /*  Implementation of replace functionality.				*/
135 /*									*/
136 /************************************************************************/
137 
tedReplaceSelectionImpl(TedEditOperation * teo,const char * word,int len,int typing,int textAttrNr)138 static int tedReplaceSelectionImpl(	TedEditOperation *	teo,
139 					const char *		word,
140 					int			len,
141 					int			typing,
142 					int			textAttrNr )
143     {
144     EditOperation *		eo= &(teo->teoEo);
145 
146     if  ( tedEditReplaceSelection( teo, word, len, textAttrNr ) )
147 	{ LDEB(1); return -1;	}
148 
149     if  ( typing == TYPING_BLANK || typing == TYPING_NONBLANK )
150 	{
151 	EditDocument *		ed= teo->teoEditDocument;
152 	TedDocument *		td= (TedDocument *)ed->edPrivateData;
153 	EditTrace *		et= &(td->tdEditTrace);
154 
155 	eo->eoAffectedRange.erHead= et->etTypingOldRange.erHead;
156 	}
157 
158     /*  6,7  */
159     tedEditFinishSelectionTail( teo );
160 
161     if  ( teo->teoEditTrace )
162 	{
163 	if  ( docRtfTraceNewContents( eo, SELposTAIL ) )
164 	    { LDEB(1); return -1;	}
165 	}
166 
167     tedFinishEditOperation( teo );
168 
169     return 0;
170     }
171 
tedDeleteSelectionImpl(TedEditOperation * teo)172 int tedDeleteSelectionImpl(	TedEditOperation *	teo )
173     {
174     EditDocument *		ed= teo->teoEditDocument;
175     TedDocument *		td= (TedDocument *)ed->edPrivateData;
176 
177     return tedReplaceSelectionImpl( teo, (const char *)0, 0, TYPING_NO,
178 			td->tdSelectionDescription.sdTextAttributeNumber );
179     }
180 
181 /************************************************************************/
182 
tedDetermineTypingClass(int * pHeadClass,const EditTrace * et,const char * str,int length)183 static int tedDetermineTypingClass(	int *			pHeadClass,
184 					const EditTrace *	et,
185 					const char *		str,
186 					int			length )
187     {
188     int			headClass= TYPING_NO;
189     int			tailClass= TYPING_NO;
190 
191     int		done= 0;
192 
193     while( done < length )
194 	{
195 	unsigned short	uni;
196 	int		step;
197 
198 	step= uniGetUtf8( &uni, str+ done );
199 	if  ( step < 1 )
200 	    { LDEB(step); return -1;	}
201 
202 	if  ( ucdIsZ( uni ) )
203 	    { tailClass= TYPING_BLANK;		}
204 	else{ tailClass= TYPING_NONBLANK;	}
205 
206 	if  ( done == 0 )
207 	    { headClass= tailClass;		}
208 
209 	done += step;
210 	}
211 
212     if  ( et->etTyping == TYPING_NO					||
213 	  ( et->etTyping == TYPING_BLANK && headClass == TYPING_NONBLANK ) )
214 	{ *pHeadClass= TYPING_START;	}
215     else{ *pHeadClass= et->etTyping;	}
216 
217     return tailClass;
218     }
219 
220 /************************************************************************/
221 /*									*/
222 /*  Refuse to scribble in the 'bullet' of a note.			*/
223 /*									*/
224 /************************************************************************/
225 
tedEditHoldsNoteHead(const SelectionDescription * sd,const EditOperation * eo)226 static int tedEditHoldsNoteHead(	const SelectionDescription *	sd,
227 					const EditOperation *		eo )
228     {
229     if  ( sd->sdInTreeType == DOCinFOOTNOTE		||
230 	  sd->sdInTreeType == DOCinENDNOTE		)
231 	{
232 	DocumentPosition	dp= eo->eoHeadDp;
233 
234 	if  ( docPrevPosition( &dp ) )
235 	    { return 1;	}
236 	}
237 
238     return 0;
239     }
240 
241 /************************************************************************/
242 /*									*/
243 /*  Replace the selection with something new.				*/
244 /*									*/
245 /*  1)  No selection... Just refuse.					*/
246 /*  2)  Replace nothing with nothing: Do nothing.			*/
247 /*	(Saves a lot of work, and avoids some combinations of special	*/
248 /*	cases)								*/
249 /*  3)  Refuse to scribble in the 'bullet' of a note.			*/
250 /*									*/
251 /************************************************************************/
252 
tedDocReplaceSelection(EditDocument * ed,int command,const char * str,int length,int traced)253 int tedDocReplaceSelection(	EditDocument *		ed,
254 				int			command,
255 				const char *		str,
256 				int			length,
257 				int			traced )
258     {
259     int				rval =0;
260     TedDocument *		td= (TedDocument *)ed->edPrivateData;
261     EditTrace *			et= &(td->tdEditTrace);
262 
263     TedEditOperation		teo;
264     SelectionGeometry		sg;
265     SelectionDescription	sd;
266 
267     const int			fullWidth= 0;
268 
269     /*  1  */
270     if  ( ! tedHasSelection( ed ) )
271 	{ LDEB(1); rval= -1; goto ready; }
272 
273     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
274 
275     /*  2  */
276     if  ( teo.teoEo.eoIBarSelectionOld && length == 0 )
277 	{ goto ready;	}
278 
279     /*  3  */
280     if  ( tedEditHoldsNoteHead( &sd, &(teo.teoEo) ) )
281 	{ goto ready;	}
282 
283     if  ( traced )
284 	{
285 	DocumentSelection		dsTraced;
286 
287 	if  ( tedEditStartReplace( &dsTraced, &teo, command, DOClevSPAN, 0 ) )
288 	    { LDEB(1); rval= -1; goto ready;	}
289 	}
290 
291     if  ( tedReplaceSelectionImpl( &teo, str, length, TYPING_NO,
292 			td->tdSelectionDescription.sdTextAttributeNumber ) )
293 	{ LDEB(length); rval= -1; goto ready;	}
294 
295     et->etTyping= TYPING_NO;
296 
297   ready:
298 
299     tedCleanEditOperation( &teo );
300 
301     return rval;
302     }
303 
tedDocDeleteSelection(EditDocument * ed,int command,int traced)304 int tedDocDeleteSelection(	EditDocument *		ed,
305 				int			command,
306 				int			traced )
307     {
308     return tedDocReplaceSelection( ed, command, (const char *)0, 0, traced );
309     }
310 
tedDocReplaceSelectionTyping(EditDocument * ed,const char * str,int length)311 int tedDocReplaceSelectionTyping(	EditDocument *		ed,
312 					const char *		str,
313 					int			length )
314     {
315     int				rval =0;
316     TedDocument *		td= (TedDocument *)ed->edPrivateData;
317     EditTrace *			et= &(td->tdEditTrace);
318 
319     TedEditOperation		teo;
320     SelectionGeometry		sg;
321     SelectionDescription	sd;
322 
323     const int			fullWidth= 0;
324 
325     int				headClass= et->etTyping;
326     int				tailClass= TYPING_NO;
327 
328     /*  1  */
329     if  ( ! tedHasSelection( ed ) )
330 	{ LDEB(1); rval= -1; goto ready; }
331 
332     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, td->tdTraced );
333 
334     /*  3  */
335     if  ( tedEditHoldsNoteHead( &sd, &(teo.teoEo) ) )
336 	{ goto ready;	}
337 
338     if  ( td->tdTraced )
339 	{
340 	tailClass= tedDetermineTypingClass( &headClass, et, str, length );
341 
342 	if  ( tailClass < 0 )
343 	    { LDEB(tailClass); rval= -1; goto ready;	}
344 	}
345     else{
346 	if  ( et->etTyping != TYPING_NO )
347 	    { CDEB(et->etTyping);	}
348 	}
349 
350     if  ( td->tdTraced )
351 	{
352 	if  ( headClass == TYPING_BLANK		||
353 	      headClass == TYPING_NONBLANK	)
354 	    {
355 	    if  ( teo.teoEditTrace					&&
356 		  docTraceExtendReplace( &(teo.teoEo), teo.teoEditTrace,
357 				    EDITcmdEXTEND_REPLACE, DOClevSPAN, 0 ) )
358 		{ LDEB(1); rval= -1; goto ready;	}
359 	    }
360 	else{
361 	    DocumentSelection		dsTraced;
362 
363 	    if  ( tedEditStartReplace( &dsTraced, &teo,
364 					    EDITcmdREPLACE, DOClevSPAN, 0 ) )
365 		{ LDEB(1); rval= -1; goto ready;	}
366 
367 	    if  ( headClass == TYPING_START )
368 		{ docSetEditRange( &(et->etTypingOldRange), &dsTraced ); }
369 	    }
370 	}
371 
372     if  ( tedReplaceSelectionImpl( &teo, str, length, headClass,
373 			td->tdSelectionDescription.sdTextAttributeNumber ) )
374 	{ LDEB(length); rval= -1; goto ready;	}
375 
376     et->etTyping= tailClass;
377 
378   ready:
379 
380     tedCleanEditOperation( &teo );
381 
382     return rval;
383     }
384 
385 /************************************************************************/
386 /*									*/
387 /*  Insert a string with known attributes (font)			*/
388 /*									*/
389 /************************************************************************/
390 
tedDocInsertStringWithAttribute(EditDocument * ed,const char * word,int len,const TextAttribute * taSet,const PropertyMask * taSetMask,int traced)391 void tedDocInsertStringWithAttribute(	EditDocument *		ed,
392 					const char *		word,
393 					int			len,
394 					const TextAttribute *	taSet,
395 					const PropertyMask *	taSetMask,
396 					int			traced )
397     {
398     TedDocument *		td= (TedDocument *)ed->edPrivateData;
399     BufferDocument *		bd= td->tdDocument;
400 
401     TedEditOperation		teo;
402     SelectionGeometry		sg;
403     SelectionDescription	sd;
404 
405     PropertyMask		taDoneMask;
406 
407     TextAttribute		ta= td->tdSelectionDescription.sdTextAttribute;
408     int				textAttrNr= td->tdSelectionDescription.sdTextAttributeNumber;
409 
410     DocumentSelection		dsTraced;
411 
412     const int			fullWidth= 0;
413 
414     /*  1  */
415     if  ( ! tedHasSelection( ed ) )
416 	{ LDEB(1); goto ready; }
417 
418     utilUpdateTextAttribute( &taDoneMask, &ta, taSetMask, taSet );
419     textAttrNr= docTextAttributeNumber( bd, &ta );
420 
421     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
422 
423     if  ( tedEditStartReplace( &dsTraced, &teo,
424 					    EDITcmdREPLACE, DOClevSPAN, 0 ) )
425 	{ LDEB(1); goto ready;	}
426 
427     if  ( tedReplaceSelectionImpl( &teo, word, len, TYPING_NO, textAttrNr ) )
428 	{ LDEB(len); goto ready;	}
429 
430   ready:
431 
432     tedCleanEditOperation( &teo );
433 
434     return;
435     }
436 
437 /************************************************************************/
438 /*									*/
439 /*  Insert a (line/page) break particule in the document.		*/
440 /*									*/
441 /*  Against flashing, a more subtle approach is used for TABs.		*/
442 /*  (redoLayout=0).							*/
443 /*									*/
444 /************************************************************************/
445 
tedEditInsertSpecialParticule(EditDocument * ed,int kind,int command,int redoLayout,int traced)446 void tedEditInsertSpecialParticule(	EditDocument *	ed,
447 					int		kind,
448 					int		command,
449 					int		redoLayout,
450 					int		traced )
451     {
452     TextParticule *		tp;
453 
454     TedEditOperation		teo;
455     EditOperation *		eo= &(teo.teoEo);
456     SelectionGeometry		sg;
457     SelectionDescription	sd;
458 
459     DocumentSelection		dsTraced;
460 
461     const int			fullWidth= 0;
462 
463     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
464 
465     if  ( tedEditStartReplace( &dsTraced, &teo, command, DOClevSPAN, 0 ) )
466 	{ LDEB(1); goto ready;	}
467 
468     if  ( tedEditDeleteSelection( &teo ) )
469 	{ goto ready;	}
470 
471     tp= docEditParaSpecialParticule( eo, kind );
472     if  ( ! tp )
473 	{ XDEB(tp); goto ready;	}
474 
475     if  ( docCheckNoBreakAsLast( eo, eo->eoTailDp.dpNode ) )
476 	{ LDEB(1);	}
477 
478     /*  3,4,5  */
479     if  ( redoLayout )
480 	{ docEditIncludeNodeInReformatRange( eo, eo->eoTailDp.dpNode );	}
481 
482     /*  6,7  */
483     tedEditFinishSelectionTail( &teo );
484 
485     if  ( teo.teoEditTrace )
486 	{
487 	if  ( docRtfTraceNewContents( eo, SELposTAIL ) )
488 	    { LDEB(1); goto ready;	}
489 	}
490 
491     tedFinishEditOperation( &teo );
492 
493   ready:
494     tedCleanEditOperation( &teo );
495 
496     return;
497     }
498 
tedDocUpdField(TedEditOperation * teo,DocumentField * dfTo,const FieldInstructions * fi)499 int tedDocUpdField(	TedEditOperation *		teo,
500 			DocumentField *			dfTo,
501 			const FieldInstructions *	fi )
502     {
503     int			rval= 0;
504     EditDocument *	ed= teo->teoEditDocument;
505     EditOperation *	eo= &(teo->teoEo);
506 
507     DocumentSelection	dsAround;
508 
509     if  ( tedEditStartTypedStep( teo, EDITcmdUPD_FIELD, dfTo->dfKind ) )
510 	{ LDEB(1); rval= -1; goto ready;	}
511 
512     if  ( teo->teoEditTrace )
513 	{
514 	if  ( docRtfTraceOldField( eo, dfTo ) )
515 	    { LDEB(1); rval= -1; goto ready;	}
516 	}
517 
518     if  ( docCopyFieldInstructions( &(dfTo->dfInstructions), fi ) )
519 	{ LDEB(1); rval= -1; goto ready;	}
520 
521     tedFormatFieldListChanged( ed->edApplication );
522 
523     if  ( dfTo->dfKind == DOCfkTOC			&&
524 	  tedRefreshTocField( &dsAround, teo, dfTo )	)
525 	{ LDEB(1); rval= -1; goto ready;	}
526 
527     tedEditFinishOldSelection( teo );
528 
529     if  ( teo->teoEditTrace )
530 	{
531 	if  ( docRtfTraceNewField( eo, dfTo ) )
532 	    { LDEB(1); rval= -1; goto ready;	}
533 
534 	docRtfTraceNewPosition( eo, (const SelectionScope *)0, SELposALL );
535 	}
536 
537     tedFinishEditOperation( teo );
538 
539   ready:
540 
541     return rval;
542     }
543 
544 /************************************************************************/
545 /*									*/
546 /*  Surround the current selection with a field.			*/
547 /*									*/
548 /*  This is a special case for Hyperlinks and Bookmarks that hold	*/
549 /*  editable text that is part of the document rather than content that	*/
550 /*  is calculated by the field itself.					*/
551 /*									*/
552 /************************************************************************/
553 
tedDocSetField(TedEditOperation * teo,const DocumentSelection * ds,int command,int fieldKind,const FieldInstructions * fi,const PropertyMask * taSetMask,const TextAttribute * taSet)554 int tedDocSetField(	TedEditOperation *		teo,
555 			const DocumentSelection *	ds,
556 			int				command,
557 			int				fieldKind,
558 			const FieldInstructions *	fi,
559 			const PropertyMask *		taSetMask,
560 			const TextAttribute *		taSet )
561     {
562     int			rval= 0;
563 
564     EditDocument *	ed= teo->teoEditDocument;
565     EditOperation *	eo= &(teo->teoEo);
566 
567     DocumentField *	df;
568     DocumentSelection	dsField;
569 
570     DocumentSelection	dsInside;
571     DocumentSelection	dsAround;
572     int			headPart;
573     int			tailPart;
574 
575     if  ( taSetMask && utilPropMaskIsEmpty( taSetMask ) )
576 	{ taSetMask= (const PropertyMask *)0;	}
577 
578     dsField= *ds;
579 
580     if  ( DOC_FieldKinds[fieldKind].fkiSingleParagraph )
581 	{
582 	int	beginMoved;
583 	int	endMoved;
584 
585 	docConstrainSelectionToOneParagraph( &beginMoved, &endMoved,
586 							    &dsField );
587 	eo->eoHeadDp= dsField.dsHead;
588 	eo->eoTailDp= dsField.dsTail;
589 	eo->eoLastDp= eo->eoTailDp;
590 	}
591 
592     if  ( tedEditStartStep( teo, command ) )
593 	{ LDEB(1); rval= -1; goto ready;	}
594 
595     if  ( teo->teoEditTrace && taSetMask )
596 	{
597 	DocumentSelection	dsTraced;
598 
599 	if  ( docRtfTraceNewProperties( eo,
600 		    taSetMask, taSet,
601 		    (const PropertyMask *)0, (const ParagraphProperties *)0,
602 		    (const PropertyMask *)0, (const CellProperties *)0,
603 		    (const PropertyMask *)0, (const RowProperties *)0,
604 		    (const PropertyMask *)0, (const SectionProperties *)0,
605 		    (const PropertyMask *)0, (const DocumentProperties *)0 ) )
606 	    { LDEB(1); rval= -1; goto ready;	}
607 
608 	if  ( docRtfTraceOldContents( &dsTraced, eo, DOClevSPAN, 0 ) )
609 	    { LDEB(1); goto ready;	}
610 	}
611 
612     /*  4  */
613     if  ( docEditSurroundTextSelectionByField( eo, &df,
614 			&dsInside, &dsAround, &headPart, &tailPart,
615 			taSetMask, taSet, fieldKind, fi ) )
616 	{ LDEB(1); rval= -1; goto ready;	}
617 
618     /*  5  */
619     if  ( tedLayoutNodeOfField( teo, &dsAround, FIELDdoNOTHING ) )
620 	{ LDEB(1); rval= -1; goto ready;	}
621 
622     tedFormatFieldListChanged( ed->edApplication );
623 
624     tedEditFinishSelection( teo, &dsInside );
625 
626     if  ( teo->teoEditTrace )
627 	{
628 	if  ( docRtfTraceNewField( eo, df ) )
629 	    { LDEB(1); rval= -1; goto ready;	}
630 
631 	docRtfTraceNewPosition( eo, (const SelectionScope *)0, SELposALL );
632 	}
633 
634     tedFinishEditOperation( teo );
635 
636   ready:
637 
638     return rval;
639     }
640 
641 /************************************************************************/
642 /*									*/
643 /*  Roll the rows in a table.						*/
644 /*									*/
645 /************************************************************************/
646 
tedEditShiftRowsInTable(EditDocument * ed,int direction,int traced)647 int tedEditShiftRowsInTable(	EditDocument *		ed,
648 				int			direction,
649 				int			traced )
650     {
651     int				rval= 0;
652     TedEditOperation		teo;
653     EditOperation *		eo= &(teo.teoEo);
654     SelectionGeometry		sg;
655     SelectionDescription	sd;
656 
657     const int			move= 1;
658     int				rowsdown= 0;
659     int				command= -1;
660 
661     const int			fullWidth= 1;
662 
663     if  ( direction > 0 )
664 	{
665 	rowsdown=  1;
666 	command= EDITcmdSHIFT_ROWS_DOWN;
667 	}
668 
669     if  ( direction < 0 )
670 	{
671 	rowsdown= -1;
672 	command= EDITcmdSHIFT_ROWS_UP;
673 	}
674 
675     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
676 
677     if  ( tedEditStartStep( &teo, command ) )
678 	{ LDEB(1); rval= -1; goto ready;	}
679 
680     if  ( tedDocRollRowsInTableImpl( &teo, &(sd.sdTableRectangle),
681 							    move, rowsdown ) )
682 	{ LDEB(1); rval= -1; goto ready;	}
683 
684     tedEditFinishOldSelection( &teo );
685 
686     if  ( teo.teoEditTrace )
687 	{
688 	docRtfTraceNewPosition( eo, (const SelectionScope *)0, SELposALL );
689 	}
690 
691     tedFinishEditOperation( &teo );
692 
693   ready:
694 
695     tedCleanEditOperation( &teo );
696 
697     return rval;
698     }
699 
700