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