1 /************************************************************************/
2 /*									*/
3 /*  Ted: Field,Bookmark,Hyperlink related editing functionality.	*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"tedConfig.h"
8 
9 #   include	<stddef.h>
10 #   include	<stdio.h>
11 
12 #   include	"tedEdit.h"
13 #   include	"tedSelect.h"
14 #   include	"tedDocFront.h"
15 #   include	"tedDocument.h"
16 #   include	<docRtfTrace.h>
17 #   include	<docEditImpl.h>
18 #   include	<docField.h>
19 #   include	<docTreeType.h>
20 #   include	<docNodeTree.h>
21 #   include	<docNotes.h>
22 #   include	<docDocumentNote.h>
23 #   include	<docEditCommand.h>
24 
25 #   include	<appDebugon.h>
26 
27 /************************************************************************/
28 /*									*/
29 /*  Insert a footnote in the document.					*/
30 /*									*/
31 /*  1)  Change the selection to a reference to a note.			*/
32 /*  2)	Insert a note immediately after the reference.			*/
33 /*  3)	Preliminary layout of the footnote.				*/
34 /*  4)	Layout of the node that receives the footnote. (Usually redoes	*/
35 /*	the layout of the footnote)					*/
36 /*  5)	Select the end of the freshly inserted footnote.		*/
37 /*  6)	Finish the edit operation with the cursor at the end of the new	*/
38 /*	note. That is after the number and the space after it.		*/
39 /*  7)	Notes only have a single location: Make the formatter happy and	*/
40 /*	tell that it has been selected where it belongs.		*/
41 /*									*/
42 /************************************************************************/
43 
tedDocInsertNote(EditDocument * ed,int noteTreeType,int traced)44 int tedDocInsertNote(	EditDocument *		ed,
45 			int			noteTreeType,
46 			int			traced )
47     {
48     int				rval= 0;
49     TedDocument *		td= (TedDocument *)ed->edPrivateData;
50     BufferDocument *		bd= td->tdDocument;
51 
52     DocumentSelection		dsInside;
53     DocumentSelection		dsAround;
54 
55     const unsigned int		fieldUpdMask= FIELDdoCHFTN;
56 
57     DocumentNote *		dn;
58     DocumentField *		dfNote;
59     struct BufferItem *		bodySectNode;
60 
61     TedEditOperation		teo;
62     EditOperation *		eo= &(teo.teoEo);
63 
64     SelectionGeometry		sg;
65     SelectionDescription	sd;
66 
67     DocumentPosition		dpEnd;
68 
69     TextAttribute		taSet;
70     PropertyMask		taSetMask;
71 
72     int				headPart;
73     int				tailPart;
74 
75     int				fieldKind= DOCfkCHFTN;
76 
77     DocumentSelection		dsTraced;
78 
79     FieldInstructions		fi;
80 
81     const int			fullWidth= 0;
82 
83     docInitFieldInstructions( &fi );
84 
85     if  ( docStartFieldInstructions( &fi, "-CHFTN", 6 ) )
86 	{ LDEB(6); rval= -1; goto ready;	}
87 
88     utilInitTextAttribute( &taSet );
89     utilPropMaskClear( &taSetMask );
90 
91     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
92 
93     if  ( sd.sdInTreeType != DOCinBODY )
94 	{ LDEB(sd.sdInTreeType); rval= -1; goto ready;	}
95 
96     if  ( tedEditStartReplace( &dsTraced, &teo, EDITcmdINS_NOTE, DOClevSPAN, 0 ) )
97 	{ LDEB(1); rval= -1; goto ready;	}
98 
99     bodySectNode= docGetSectNode( eo->eoHeadDp.dpNode );
100     if  ( ! bodySectNode )
101 	{ XDEB(bodySectNode); rval= -1; goto ready;	}
102 
103     /*  1  */
104     if  ( tedDocReplaceSelectionWithField( &teo, &dfNote,
105 					    &headPart, &tailPart,
106 					    &dsInside, &dsAround,
107 					    &fi, fieldKind,
108 					    &taSetMask, &taSet ) )
109 	{ LDEB(1); rval= -1; goto ready;	}
110 
111     /*  2  */
112     if  ( docEditMakeNote( &dn, bd, dfNote,
113 				    bodySectNode, noteTreeType, fieldKind ) )
114 	{ LDEB(1); rval= -1; goto ready;	}
115     utilIndexSetAdd( &(eo->eoNoteFieldsAdded), dfNote->dfFieldNumber );
116 
117     /*  4  */
118     if  ( tedLayoutNodeOfField( &teo, &dsAround, fieldUpdMask ) )
119 	{ LDEB(1); rval= -1; goto ready;	}
120 
121     /*  5  */
122     if  ( docTailPosition( &dpEnd, dn->dnDocumentTree.dtRoot ) )
123 	{ LDEB(1); rval= -1; goto ready;	}
124 
125     if  ( teo.teoEditTrace )
126 	{
127 	if  ( docRtfTraceNewContents( eo, SELposTAIL ) )
128 	    { LDEB(1); rval= -1; goto ready;	}
129 	}
130 
131     /*  6  */
132     eo->eoTree= &(dn->dnDocumentTree);
133     docGetSelectionScope( &(eo->eoSelectionScope), dpEnd.dpNode );
134 
135     docSetIBarRange( &(eo->eoAffectedRange), &dpEnd );
136     docSetIBarRange( &(eo->eoSelectedRange), &dpEnd );
137     tedEditFinishSelectionTail( &teo );
138 
139     tedFinishEditOperation( &teo );
140 
141   ready:
142 
143     docCleanFieldInstructions( &fi );
144     tedCleanEditOperation( &teo );
145 
146     return rval;
147     }
148 
149 /************************************************************************/
150 /*									*/
151 /*  Change the kind of note for the current selection.			*/
152 /*									*/
153 /************************************************************************/
154 
tedChangeNoteImpl(EditOperation * eo,DocumentField * dfNote,DocumentNote * dn,int selInNote,const PropertyMask * npSetMask,const NoteProperties * npSet)155 int tedChangeNoteImpl(		EditOperation *		eo,
156 				DocumentField *		dfNote,
157 				DocumentNote *		dn,
158 				int			selInNote,
159 				const PropertyMask *	npSetMask,
160 				const NoteProperties *	npSet )
161     {
162     PropertyMask		npDoneMask;
163 
164     utilPropMaskClear( &npDoneMask );
165 
166     if  ( docUpdNoteProperties( &npDoneMask, &(dn->dnNoteProperties),
167 							npSetMask, npSet ) )
168 	{ LDEB(1); return -1;	}
169 
170     if  ( PROPmaskISSET( &npDoneMask, NOTEpropTREE_TYPE ) )
171 	{
172 	if  ( docCheckSeparatorItemForNoteType( eo->eoDocument,
173 					    dn->dnNoteProperties.npTreeType ) )
174 	    { LDEB(DOCinFTNSEP); return -1;	}
175 
176 	dn->dnNoteNumber= 0;
177 	docInvalidateTreeLayout( &(dn->dnDocumentTree) );
178 
179 	if  ( ! dn->dnDocumentTree.dtRoot )
180 	    { XDEB(dn->dnDocumentTree.dtRoot); return -1;	}
181 
182 	docSetTreeTypeOfNode( dn->dnDocumentTree.dtRoot,
183 					    dn->dnNoteProperties.npTreeType );
184 
185 	if  ( selInNote )
186 	    {
187 	    eo->eoSelectionScope.ssTreeType= dn->dnNoteProperties.npTreeType;
188 	    }
189 	}
190 
191     eo->eoFieldUpdate |= FIELDdoCHFTN;
192     utilIndexSetAdd( &(eo->eoNoteFieldsAdded), dfNote->dfFieldNumber );
193 
194     return 0;
195     }
196 
197 /************************************************************************/
198 /*									*/
199 /*  Change the kind of note for the current selection.			*/
200 /*									*/
201 /************************************************************************/
202 
tedDocChangeCurrentNote(EditDocument * ed,const PropertyMask * npSetMask,const NoteProperties * npSet,int traced)203 int tedDocChangeCurrentNote(	EditDocument *		ed,
204 				const PropertyMask *	npSetMask,
205 				const NoteProperties *	npSet,
206 				int			traced )
207     {
208     int				rval= 0;
209 
210     TedEditOperation		teo;
211     EditOperation *		eo= &(teo.teoEo);
212     SelectionGeometry		sg;
213     SelectionDescription	sd;
214 
215     DocumentField *		dfNote= (DocumentField *)0;
216     DocumentNote *		dn= (DocumentNote *)0;
217     int				selInNote= 0;
218 
219     const int			fullWidth= 0;
220 
221     PropertyMask		npDoneMask;
222 
223     utilPropMaskClear( &npDoneMask );
224 
225     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
226 
227     dfNote= docEditOperationGetSelectedNote( &dn, &selInNote, eo );
228     if  ( ! dfNote )
229 	{ XDEB(dfNote); rval= -1; goto ready;	}
230 
231     if  ( tedEditStartStep( &teo, EDITcmdUPD_NOTE ) )
232 	{ LDEB(1); rval= -1; goto ready;	}
233 
234     if  ( teo.teoEditTrace )
235 	{
236 	if  ( docRtfTraceOldNoteProperties( eo,
237 				    npSetMask, &(dn->dnNoteProperties) ) )
238 	    { LDEB(1); rval= -1; goto ready;	}
239 	if  ( docRtfTraceNewNoteProperties( eo, npSetMask, npSet ) )
240 	    { LDEB(1); rval= -1; goto ready;	}
241 	}
242 
243     if  ( tedChangeNoteImpl( eo, dfNote, dn, selInNote, npSetMask, npSet ) )
244 	{ LDEB(1); rval= -1; goto ready;	}
245 
246     if  ( tedEditFinishOldSelection( &teo ) )
247 	{ LDEB(1);	}
248 
249     if  ( teo.teoEditTrace )
250 	{
251 	docRtfTraceNewPosition( eo, (const SelectionScope *)0, SELposALL );
252 	}
253 
254     tedFinishEditOperation( &teo );
255 
256   ready:
257 
258     tedCleanEditOperation( &teo );
259 
260     return rval;
261     }
262 
263 /************************************************************************/
264 
tedGetSelectedNote(DocumentNote ** pDn,int * pSelInNote,EditDocument * ed)265 static DocumentField * tedGetSelectedNote(	DocumentNote **	pDn,
266 						int *		pSelInNote,
267 						EditDocument *	ed )
268     {
269     TedDocument *		td= (TedDocument *)ed->edPrivateData;
270     BufferDocument *		bd= td->tdDocument;
271 
272     DocumentSelection		ds;
273     SelectionGeometry		sg;
274     SelectionDescription	sd;
275 
276     if  ( tedGetSelection( &ds, &sg, &sd,
277 			    (DocumentTree **)0, (struct BufferItem **)0, ed ) )
278 	{ LDEB(1); return (DocumentField *)0;	}
279 
280     return docGetSelectedNote( pDn, pSelInNote, bd, &ds );
281     }
282 
283 /************************************************************************/
284 
tedGotoNoteRef(EditDocument * ed,const DocumentField * dfNote)285 static int tedGotoNoteRef(	EditDocument *		ed,
286 				const DocumentField *	dfNote )
287     {
288     TedDocument *		td= (TedDocument *)ed->edPrivateData;
289     BufferDocument *		bd= td->tdDocument;
290 
291     DocumentSelection		dsRef;
292     const int			lastLine= 0;
293 
294     if  ( docSelectionForEditPositionsInTree( &dsRef, &(bd->bdBody),
295 		    &(dfNote->dfHeadPosition), &(dfNote->dfTailPosition) ) )
296 	{ LDEB(1); return -1;	}
297 
298     tedSetSelection( ed, &dsRef, lastLine, (int *)0, (int *)0 );
299 
300     return 0;
301     }
302 
tedGotoNoteDef(EditDocument * ed,const DocumentNote * dn)303 static int tedGotoNoteDef(	EditDocument *		ed,
304 				const DocumentNote *	dn )
305     {
306     TedDocument *		td= (TedDocument *)ed->edPrivateData;
307     BufferDocument *		bd= td->tdDocument;
308 
309     int				scrolledX= 0;
310     int				scrolledY= 0;
311 
312     DocumentPosition		dpNote;
313     const int			lastLine= 0;
314 
315     if  ( ! dn->dnDocumentTree.dtRoot					||
316 	  docHeadPosition( &dpNote, dn->dnDocumentTree.dtRoot )	)
317 	{ XDEB(dn->dnDocumentTree.dtRoot); return -1;	}
318 
319     docAvoidParaHeadField( &dpNote, (int *)0, bd );
320 
321     tedSetSelectedPosition( ed, &dpNote, lastLine, &scrolledX, &scrolledY );
322 
323     return 0;
324     }
325 
326 /************************************************************************/
327 /*									*/
328 /*  Jump to the foot/end note thet is selected in the body of the	*/
329 /*  document.								*/
330 /*									*/
331 /************************************************************************/
332 
tedDocGotoNoteDef(EditDocument * ed)333 void tedDocGotoNoteDef(		EditDocument *	ed )
334     {
335     DocumentNote *		dn= (DocumentNote *)0;
336     DocumentField *		dfNote= (DocumentField *)0;
337     int				selInNote= 0;
338 
339     dfNote= tedGetSelectedNote( &dn, &selInNote, ed );
340     if  ( ! dfNote || selInNote )
341 	{ XDEB(dfNote); return;	}
342 
343     if  ( tedGotoNoteDef( ed, dn ) )
344 	{ LDEB(1);	}
345 
346     return;
347     }
348 
349 /************************************************************************/
350 /*									*/
351 /*  Jump to the foot/end note reference in the body of the document to	*/
352 /*  the note text that is selected.					*/
353 /*									*/
354 /************************************************************************/
355 
tedDocGotoNoteRef(EditDocument * ed)356 void tedDocGotoNoteRef(		EditDocument *	ed )
357     {
358     DocumentField *		dfNote= (DocumentField *)0;
359     DocumentNote *		dn= (DocumentNote *)0;
360     int				selInNote= 0;
361 
362     dfNote= tedGetSelectedNote( &dn, &selInNote, ed );
363     if  ( ! dfNote || ! selInNote )
364 	{ XLDEB(dfNote,selInNote); return;	}
365 
366     if  ( tedGotoNoteRef( ed, dfNote ) )
367 	{ LDEB(1);	}
368 
369     return;
370     }
371 
372 /************************************************************************/
373 /*									*/
374 /*  Navigate over the notes in the document.				*/
375 /*									*/
376 /************************************************************************/
377 
tedStepNote(EditDocument * ed,int direction)378 static void tedStepNote(		EditDocument *	ed,
379 					int		direction )
380     {
381     TedDocument *		td= (TedDocument *)ed->edPrivateData;
382     BufferDocument *		bd= td->tdDocument;
383 
384     DocumentField *		dfNote= (DocumentField *)0;
385     DocumentNote *		dn= (DocumentNote *)0;
386     int				selInNote= 0;
387 
388     dfNote= tedGetSelectedNote( &dn, &selInNote, ed );
389     if  ( ! dfNote )
390 	{ XDEB(dfNote); return;	}
391 
392     if  ( direction > 0 )
393 	{
394 	dfNote= docGetNextNoteInDocument( &dn, bd, dfNote, -1 );
395 	if  ( ! dfNote )
396 	    { XDEB(dfNote); return;	}
397 	}
398     else{
399 	dfNote= docGetPrevNoteInDocument( &dn, bd, dfNote, -1 );
400 	if  ( ! dfNote )
401 	    { XDEB(dfNote); return;	}
402 	}
403 
404     if  ( selInNote )
405 	{
406 	if  ( tedGotoNoteDef( ed, dn ) )
407 	    { LDEB(1);	}
408 	}
409     else{
410 	if  ( tedGotoNoteRef( ed, dfNote ) )
411 	    { LDEB(1);	}
412 	}
413 
414     return;
415     }
416 
tedDocNextNote(EditDocument * ed)417 void tedDocNextNote(		EditDocument *	ed )
418     {
419     const int	direction=  1;
420 
421     tedStepNote( ed, direction );
422     }
423 
tedDocPrevNote(EditDocument * ed)424 void tedDocPrevNote(		EditDocument *	ed )
425     {
426     const int	direction= -1;
427 
428     tedStepNote( ed, direction );
429     }
430