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	"tedEdit.h"
14 #   include	"tedSelect.h"
15 #   include	"tedDocFront.h"
16 #   include	<docRtfTrace.h>
17 #   include	<docEditImpl.h>
18 #   include	<docTreeNode.h>
19 #   include	<docEditCommand.h>
20 
21 #   include	<appDebugon.h>
22 
23 /************************************************************************/
24 /*									*/
25 /*  Delete the current row.						*/
26 /*									*/
27 /************************************************************************/
28 
tedEditDeleteSelectedRows(DocumentPosition * dpNew,int * pSide,const DocumentSelection * dsRows,BufferItem * rowNode0,BufferItem * rowNode1,TedEditOperation * teo)29 static int tedEditDeleteSelectedRows(
30 				DocumentPosition *		dpNew,
31 				int *				pSide,
32 				const DocumentSelection *	dsRows,
33 				BufferItem *			rowNode0,
34 				BufferItem *			rowNode1,
35 				TedEditOperation *		teo )
36     {
37     int				rval= 0;
38     EditOperation *		eo= &(teo->teoEo);
39 
40     BufferItem *		parentNode;
41     int				child0;
42     int				child1;
43 
44     int				side;
45 
46     if  ( docEditDeleteFieldsForBlockDelete( eo, dsRows ) )
47 	{ LDEB(1); rval= -1; goto ready;	}
48 
49     if  ( docEditFindPositionOutsideBlockDelete( &side, dpNew, dsRows ) )
50 	{ LDEB(1); rval= -1; goto ready;	}
51 
52     parentNode= rowNode0->biParent;
53     child0= rowNode0->biNumberInParent;
54     child1= rowNode1->biNumberInParent;
55 
56     if  ( child0 <= child1 )
57 	{
58 	int		firstParaDeleted= -1;
59 	int		sectionsDeleted= 0;
60 	int		paragraphsDeleted= 0;
61 
62 	tedEditIncludeNodeInRedraw( teo, rowNode0 );
63 
64 	docEditDeleteNodes( eo, &sectionsDeleted,
65 				    &firstParaDeleted, &paragraphsDeleted,
66 				    parentNode, child0, child1- child0+ 1 );
67 
68 	docEditIncludeNodeInReformatRange( eo, parentNode );
69 	eo->eoHeadDp= *dpNew;
70 	eo->eoTailDp= *dpNew;
71 	}
72 
73     *pSide= side;
74 
75   ready:
76 
77     return rval;
78     }
79 
80 /************************************************************************/
81 /*									*/
82 /*  Delete rows from a table.						*/
83 /*									*/
84 /************************************************************************/
85 
tedDeleteRowsFromTableOperation(TedEditOperation * teo,int command,int row0,int row1)86 static int tedDeleteRowsFromTableOperation(
87 					TedEditOperation *	teo,
88 					int			command,
89 					int			row0,
90 					int			row1 )
91     {
92     EditOperation *		eo= &(teo->teoEo);
93 
94     int				rval= 0;
95 
96     BufferItem *		parentNode;
97 
98     int				col;
99     int				row;
100     int				tabRow0;
101     int				tabRow1;
102 
103     DocumentPosition		dpNew;
104 
105     int				allChildren= 0;
106 
107     BufferItem *		rowNode0;
108     BufferItem *		rowNode1;
109 
110     DocumentSelection		dsTraced;
111 
112     docInitDocumentPosition( &dpNew );
113 
114     if  ( docDelimitTable( eo->eoHeadDp.dpNode, &parentNode,
115 					    &col, &tabRow0, &row, &tabRow1 ) )
116 	{ LDEB(1); rval= -1; goto ready;	}
117 
118     if  ( row0 > row1 )
119 	{ LLDEB(row0,row1); rval= -1; goto ready;	}
120     if  ( row0 < tabRow0 || row0 > tabRow1 )
121 	{ LLLDEB(tabRow0,row0,tabRow1); rval= -1; goto ready;	}
122     if  ( row1 < tabRow0 || row1 > tabRow1 )
123 	{ LLLDEB(tabRow0,row1,tabRow1); rval= -1; goto ready;	}
124 
125     rowNode0= parentNode->biChildren[row0];
126     rowNode1= parentNode->biChildren[row1];
127 
128     if  ( rowNode0->biNumberInParent == 0 )
129 	{
130 	BufferItem *	parentNode= rowNode0->biParent;
131 
132 	if  ( rowNode1->biNumberInParent == parentNode->biChildCount -1 )
133 	    { allChildren= 1;	}
134 	}
135 
136     if  ( allChildren )
137 	{
138 	if  ( tedEditStartReplace( &dsTraced, teo, command, DOClevSECT, 0 ) )
139 	    { LDEB(1); goto ready;	}
140 
141 	/*  Fraudulous HACK */
142 	if  ( docHeadPosition( &(eo->eoHeadDp), rowNode0 ) )
143 	    { LDEB(1); goto ready;	}
144 	eo->eoHeadDp.dpStroff= 0;
145 	if  ( docTailPosition( &(eo->eoTailDp), rowNode1 ) )
146 	    { LDEB(1); goto ready;	}
147 	eo->eoLastDp= eo->eoTailDp;
148 
149 	if  ( tedDeleteSelectionImpl( teo ) )
150 	    { LDEB(allChildren); goto ready;	}
151 
152 	docFlattenRow( eo->eoTailDp.dpNode );
153 	}
154     else{
155 	int			side;
156 	const int		direction= 1;
157 	const int		recursively= 0;
158 
159 	DocumentSelection	dsRows;
160 	DocumentPosition	dpHead;
161 	DocumentPosition	dpTail;
162 
163 	docInitDocumentSelection( &dsRows );
164 	if  ( docHeadPosition( &dpHead, rowNode0 ) )
165 	    { LDEB(0); return -1;	}
166 	dpHead.dpStroff= 0;
167 
168 	if  ( docTailPosition( &dpTail, rowNode1 ) )
169 	    { LDEB(1); return -1;	}
170 	docSetRangeSelection( &dsRows, &dpHead, &dpTail, direction );
171 
172 	if  ( tedEditStartStep( teo, command ) )
173 	    { LDEB(1); return -1;	}
174 
175 	if  ( teo->teoEditTrace )
176 	    {
177 	    if  ( docRtfTraceOldContentsLow( eo, &dsRows, 0 ) )
178 		{ LDEB(1); goto ready;	}
179 	    }
180 
181 	if  ( tedEditDeleteSelectedRows( &dpNew, &side, &dsRows,
182 						rowNode0, rowNode1, teo ) )
183 	    { LDEB(1); rval= -1; goto ready;	}
184 
185 	docDelimitTables( parentNode, recursively );
186 
187 	docSetIBarRange( &(eo->eoAffectedRange), &dpNew );
188 	docSetIBarRange( &(eo->eoSelectedRange), &dpNew );
189 	tedEditFinishSelectionTail( teo );
190 
191 	if  ( teo->teoEditTrace )
192 	    {
193 	    const SelectionScope * const s0= (const SelectionScope *)0;
194 
195 	    if  ( side > 0 )
196 		{ docRtfTraceNewPosition( eo, s0, SELposAFTER );	}
197 	    else{ docRtfTraceNewPosition( eo, s0, SELposBEFORE );	}
198 	    }
199 
200 	tedFinishEditOperation( teo );
201 	}
202 
203   ready:
204 
205     return rval;
206     }
207 
208 /************************************************************************/
209 /*									*/
210 /*  Delete rows from a table.						*/
211 /*									*/
212 /************************************************************************/
213 
tedDeleteRowsFromTable(EditDocument * ed,int command,int row0,int row1,int traced)214 static int tedDeleteRowsFromTable(	EditDocument *		ed,
215 					int			command,
216 					int			row0,
217 					int			row1,
218 					int			traced )
219     {
220     int				rval= 0;
221     TedEditOperation		teo;
222     SelectionGeometry		sg;
223     SelectionDescription	sd;
224 
225     const int			fullWidth= 1;
226 
227     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
228 
229     if  ( tedDeleteRowsFromTableOperation( &teo, command, row0, row1 ) )
230 	{ LDEB(1); rval= -1; goto ready;	}
231 
232   ready:
233 
234     tedCleanEditOperation( &teo );
235 
236     return rval;
237     }
238 
239 /************************************************************************/
240 /*									*/
241 /*  Delete a table.							*/
242 /*									*/
243 /************************************************************************/
244 
tedDocDeleteTable(EditDocument * ed,int traced)245 int tedDocDeleteTable(	EditDocument *		ed,
246 			int			traced )
247     {
248     DocumentSelection		ds;
249     SelectionGeometry		sg;
250     SelectionDescription	sd;
251 
252     TableRectangle		tr;
253 
254     if  ( tedGetSelection( &ds, &sg, &sd,
255 				(DocumentTree **)0, (BufferItem **)0, ed  ) )
256 	{ LDEB(1); return -1;	}
257 
258     if  ( docGetTableRectangle( &tr, &ds ) )
259 	{ LDEB(1); return -1;	}
260 
261     if  ( tedDeleteRowsFromTable( ed, EDITcmdDELETE_TABLE,
262 					    tr.trRow00, tr.trRow11, traced ) )
263 	{ LLDEB(tr.trRow00,tr.trRow11); return -1;	}
264 
265     return 0;
266     }
267 
268 /************************************************************************/
269 /*									*/
270 /*  Delete a row.							*/
271 /*									*/
272 /************************************************************************/
273 
tedDocDeleteRow(EditDocument * ed,int traced)274 int tedDocDeleteRow(	EditDocument *		ed,
275 			int			traced )
276     {
277     DocumentSelection		ds;
278     SelectionGeometry		sg;
279     SelectionDescription	sd;
280 
281     TableRectangle		tr;
282 
283     if  ( tedGetSelection( &ds, &sg, &sd,
284 				(DocumentTree **)0, (BufferItem **)0, ed  ) )
285 	{ LDEB(1); return -1;	}
286 
287     if  ( docGetTableRectangle( &tr, &ds ) )
288 	{ LDEB(1); return -1;	}
289 
290     if  ( tedDeleteRowsFromTable( ed, EDITcmdDELETE_ROW,
291 					    tr.trRow0, tr.trRow1, traced ) )
292 	{ LLDEB(tr.trRow00,tr.trRow11); return -1;	}
293 
294     return 0;
295     }
296 
297 /************************************************************************/
298 /*									*/
299 /*  Delete columns: Implementation.					*/
300 /*									*/
301 /************************************************************************/
302 
tedDeleteColumnsFromRowsOperation(TedEditOperation * teo,int delRow0,int delRow1,int delCol0,int delCol1)303 static int tedDeleteColumnsFromRowsOperation(
304 					TedEditOperation *	teo,
305 					int			delRow0,
306 					int			delRow1,
307 					int			delCol0,
308 					int			delCol1 )
309     {
310     EditOperation *		eo= &(teo->teoEo);
311 
312     BufferItem *		parentNode;
313     BufferItem *		rowBi;
314 
315     int				col;
316     int				row;
317     int				row0;
318     int				row1;
319 
320     int				side= 1;
321 
322     DocumentPosition		dpNew;
323     DocumentSelection		dsTraced;
324 
325     if  ( docDelimitTable( eo->eoHeadDp.dpNode, &parentNode,
326 						&col, &row0, &row, &row1 ) )
327 	{ LDEB(1); return -1;	}
328 
329     if  ( tedEditStartReplace( &dsTraced, teo,
330 				    EDITcmdDELETE_COLUMN, DOClevCOLUMN, 0 ) )
331 	{ LDEB(1); goto ready;	}
332 
333     tedEditIncludeRowsInRedraw( teo, parentNode, delRow0, delRow1 );
334 
335     docInitDocumentPosition( &dpNew );
336     rowBi= parentNode->biChildren[delRow1];
337     if  ( delCol1 >= rowBi->biChildCount- 1			||
338 	  docTailPosition( &dpNew, rowBi->biChildren[delCol1] )	||
339 	  docNextPosition( &dpNew )				)
340 	{
341 	docInitDocumentPosition( &dpNew );
342 	side= -1;
343 	rowBi= parentNode->biChildren[delRow0];
344 	if  ( delCol0 <= 0						||
345 	      docHeadPosition( &dpNew, rowBi->biChildren[delCol0] )	||
346 	      docPrevPosition( &dpNew )					)
347 	    { docInitDocumentPosition( &dpNew ); }
348 	}
349 
350     if  ( docDeleteColumnsFromRows( eo, parentNode,
351 				    delRow0, delRow1, delCol0, delCol1 ) )
352 	{ LDEB(1); return -1;	}
353 
354     eo->eoHeadDp= dpNew;
355     eo->eoTailDp= dpNew;
356 
357     docSetIBarRange( &(eo->eoAffectedRange), &dpNew );
358     tedEditFinishSelectionTail( teo );
359 
360     if  ( teo->teoEditTrace )
361 	{
362 	const SelectionScope * const s0= (const SelectionScope *)0;
363 
364 	if  ( side > 0 )
365 	    { docRtfTraceNewPosition( eo, s0, SELposAFTER );	}
366 	else{ docRtfTraceNewPosition( eo, s0, SELposBEFORE );	}
367 	}
368 
369     tedFinishEditOperation( teo );
370 
371   ready:
372 
373     return 0;
374     }
375 
376 
377 /************************************************************************/
378 /*									*/
379 /*  Delete a column.							*/
380 /*									*/
381 /************************************************************************/
382 
tedDocDeleteColumn(EditDocument * ed,int traced)383 int tedDocDeleteColumn(	EditDocument *		ed,
384 			int			traced )
385     {
386     int				rval= 0;
387 
388     TedEditOperation		teo;
389     DocumentSelection		ds;
390     SelectionGeometry		sg;
391     SelectionDescription	sd;
392 
393     TableRectangle		tr;
394 
395     const int			fullWidth= 1;
396 
397     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
398 
399     if  ( tedGetSelection( &ds, &sg, &sd,
400 			    (DocumentTree **)0, (BufferItem **)0, ed  ) )
401 	{ LDEB(1); rval= -1; goto ready;	}
402 
403     if  ( docGetTableRectangle( &tr, &ds ) )
404 	{ LDEB(1); rval= -1; goto ready;	}
405 
406     if  ( tedDeleteColumnsFromRowsOperation( &teo,
407 			    tr.trRow00, tr.trRow11, tr.trCol0, tr.trCol1 ) )
408 	{ LLDEB(tr.trRow00,tr.trRow11); rval= -1; goto ready;	}
409 
410   ready:
411 
412     tedCleanEditOperation( &teo );
413 
414     return rval;
415     }
416 
417 /************************************************************************/
418 /*									*/
419 /*  Delete a slice from a table. Either horizontal or vertical or both:	*/
420 /*  the table as a whole.						*/
421 /*									*/
422 /*  1)  See whether the current selection is a table slice.		*/
423 /*  2)  If it is a row slice (Whole rows) delete the rows. This covers	*/
424 /*	deleteing the whole table as well. [ Handling it in the column	*/
425 /*	branch would leave empty rows.]					*/
426 /*  3)  If it is a column slice (Whole columns) delete the columns.	*/
427 /*  4)  Impossible!							*/
428 /*									*/
429 /************************************************************************/
430 
tedDeleteTableSliceSelection(EditDocument * ed,int traced)431 int tedDeleteTableSliceSelection(	EditDocument *		ed,
432 					int			traced )
433     {
434     int				rval= 0;
435 
436     TedEditOperation		teo;
437     SelectionGeometry		sg;
438     SelectionDescription	sd;
439 
440     int				ret;
441 
442     const int			fullWidth= 1;
443 
444     if  ( ed->edIsReadonly )
445 	{ return 1;	}
446 
447     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
448 
449     /*  1  */
450     if  ( ! sd.sdInOneTable || ! sd.sdTableRectangle.trIsTableSlice )
451 	{ rval= 1; goto ready;	}
452 
453     /*  2  */
454     if  ( sd.sdTableRectangle.trIsRowSlice )
455 	{
456 	ret= tedDeleteRowsFromTableOperation( &teo, EDITcmdDELETE_ROW,
457 						sd.sdTableRectangle.trRow0,
458 						sd.sdTableRectangle.trRow1 );
459 	if  ( ret )
460 	    { LDEB(ret); rval= -1; goto ready;	}
461 
462 	goto ready;
463 	}
464 
465     /*  3  */
466     if  ( sd.sdTableRectangle.trIsColSlice )
467 	{
468 	ret= tedDeleteColumnsFromRowsOperation( &teo,
469 						sd.sdTableRectangle.trRow0,
470 						sd.sdTableRectangle.trRow1,
471 						sd.sdTableRectangle.trCol0,
472 						sd.sdTableRectangle.trCol1 );
473 	if  ( ret )
474 	    { LDEB(ret); rval= -1; goto ready;	}
475 
476 	goto ready;
477 	}
478 
479     /*  4  */
480     LLDEB(sd.sdTableRectangle.trIsRowSlice,sd.sdTableRectangle.trIsColSlice);
481     rval= -1;
482 
483   ready:
484 
485     tedCleanEditOperation( &teo );
486 
487     return rval;
488     }
489 
490