1 /************************************************************************/
2 /*									*/
3 /*  Ted: Copy/Paste implementation.					*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"tedConfig.h"
8 
9 #   include	<stddef.h>
10 #   include	<stdlib.h>
11 #   include	<stdio.h>
12 #   include	<ctype.h>
13 
14 #   include	"tedApp.h"
15 #   include	"tedSelect.h"
16 #   include	"tedCopyPasteImpl.h"
17 #   include	"tedEdit.h"
18 #   include	"tedDocument.h"
19 #   include	<docRtfReadWrite.h>
20 #   include	<docPlainReadWrite.h>
21 #   include	<docRtfFlags.h>
22 #   include	<docTreeNode.h>
23 #   include	<docEditCommand.h>
24 
25 #   include	<sioFileio.h>
26 #   include	<sioMemory.h>
27 
28 #   include	<appDebugon.h>
29 
30 /************************************************************************/
31 /*									*/
32 /*  Write copy/paste to file for debugging purposes.			*/
33 /*									*/
34 /************************************************************************/
35 
tedSaveSelectionToFile(BufferDocument * bd,const DocumentSelection * ds,int rtfFlags,const char * filename)36 void tedSaveSelectionToFile(	BufferDocument *		bd,
37 				const DocumentSelection *	ds,
38 				int				rtfFlags,
39 				const char *			filename )
40     {
41     SimpleOutputStream *	sos;
42 
43     SDEB(filename);
44     sos= sioOutFileioOpenS( filename );
45     if  ( ! sos )
46 	{ SPDEB( filename, sos );	}
47     else{
48 	if  ( docRtfSaveDocument( sos, bd, ds, rtfFlags ) )
49 	    { LDEB(1); 	}
50 	if  ( sioOutClose( sos ) )
51 	    { LDEB(1);	}
52 	}
53 
54     return;
55     }
56 
tedSaveSelectionTxtToFile(BufferDocument * bd,const char * filename)57 void tedSaveSelectionTxtToFile(	BufferDocument *		bd,
58 				const char *			filename )
59     {
60     SimpleOutputStream *	sos;
61 
62     SDEB(filename);
63     sos= sioOutFileioOpenS( filename );
64     if  ( ! sos )
65 	{ SPDEB( filename, sos );	}
66     else{
67 	if  ( docPlainSaveDocument( sos, bd, (DocumentSelection *)0, 0 ) )
68 	    { LDEB(1); 	}
69 	if  ( sioOutClose( sos ) )
70 	    { LDEB(1);	}
71 	}
72 
73     return;
74     }
75 
76 /************************************************************************/
77 /*									*/
78 /*  Save the current selection in rtf format.				*/
79 /*									*/
80 /************************************************************************/
81 
tedDocSaveSelectionRtf(MemoryBuffer * mb,DocumentSelection * ds,SelectionDescription * sd,EditDocument * ed)82 int tedDocSaveSelectionRtf(	MemoryBuffer *		mb,
83 				DocumentSelection *	ds,
84 				SelectionDescription *	sd,
85 				EditDocument *		ed )
86     {
87     TedDocument *		td= (TedDocument *)ed->edPrivateData;
88     SimpleOutputStream *	sos;
89 
90     SelectionGeometry		sg;
91 
92     const int			rtfFlags= RTFflagNO_BOOKMARKS;
93 
94     if  ( ! tedHasSelection( ed ) || tedHasIBarSelection( ed ) )
95 	{ return -1; }
96 
97     if  ( tedGetSelection( ds, &sg, sd,
98 			    (DocumentTree **)0, (struct BufferItem **)0, ed ) )
99 	{ return -1;	}
100 
101     sos= sioOutMemoryOpen( mb );
102     if  ( ! sos )
103 	{ XDEB(sos); return -1;    }
104 
105     if  ( docRtfSaveDocument( sos, td->tdDocument, ds, rtfFlags ) )
106 	{ LDEB(1); sioOutClose( sos ); return -1;	}
107 
108     if  ( sioOutClose( sos ) )
109 	{ LDEB(1); return -1;	}
110 
111     if  ( getenv( "TED_SAVE_COPIES" ) )
112 	{
113 	tedSaveSelectionToFile( td->tdDocument, ds, rtfFlags,
114 							"/tmp/saved.rtf" );
115 	}
116 
117     return 0;
118     }
119 
120 /************************************************************************/
121 /*									*/
122 /*  Save the selection in order to make it available if someone asks	*/
123 /*  for a paste.							*/
124 /*									*/
125 /************************************************************************/
126 
tedDocCopySelection(EditDocument * ed)127 int tedDocCopySelection(	EditDocument *	ed )
128     {
129     TedDocument *		td= (TedDocument *)ed->edPrivateData;
130 
131     DocumentPosition		dpObject;
132     int				partObject;
133     InsertedObject *		io;
134 
135     DocumentSelection		ds;
136     SelectionDescription	sd;
137 
138     if  ( tedDocSaveSelectionRtf( &(td->tdCopiedSelection), &ds, &sd, ed ) )
139 	{ LDEB(1); return -1;	}
140 
141     bmCleanRasterImage( &(td->tdCopiedImage) );
142     bmInitRasterImage( &(td->tdCopiedImage) );
143 
144     docInitDocumentPosition( &dpObject );
145 
146     if  ( sd.sdIsObjectSelection					&&
147 	  ! docGetObjectSelection( &ds, td->tdDocument,
148 				      &partObject, &dpObject, &io )	)
149 	{
150 	if  ( tedSaveObjectPicture( &(td->tdCopiedImage), io )	)
151 	    { LDEB(1);	}
152 	}
153 
154     return 0;
155     }
156 
157 /************************************************************************/
158 
tedGetRulerFromPaste(ParagraphProperties * ppSet,PropertyMask * ppSetMask,EditOperation * eo,const MemoryBuffer * filename,BufferDocument * bdFrom)159 static int tedGetRulerFromPaste(	ParagraphProperties *	ppSet,
160 					PropertyMask *		ppSetMask,
161 					EditOperation *		eo,
162 					const MemoryBuffer *	filename,
163 					BufferDocument *	bdFrom )
164     {
165     int				rval= 0;
166 
167     const int			forceAttributeTo= -1;
168     DocumentPosition		dp;
169 
170     DocumentCopyJob		dcj;
171 
172     docInitDocumentCopyJob( &dcj );
173 
174     if  ( docSet2DocumentCopyJob( &dcj, eo, bdFrom, &(bdFrom->bdBody),
175 					filename, forceAttributeTo ) )
176 	{ LDEB(1); rval= -1; goto ready;	}
177 
178     if  ( docDocumentHead( &dp, bdFrom ) )
179 	{ LDEB(1); rval= -1; goto ready;	}
180 
181     utilPropMaskClear( ppSetMask );
182     PROPmaskADD( ppSetMask, PPpropLEFT_INDENT );
183     PROPmaskADD( ppSetMask, PPpropFIRST_INDENT );
184     PROPmaskADD( ppSetMask, PPpropRIGHT_INDENT );
185     PROPmaskADD( ppSetMask, PPpropALIGNMENT );
186     PROPmaskADD( ppSetMask, PPpropTAB_STOPS );
187 
188     PROPmaskADD( ppSetMask, PPpropLISTOVERRIDE );
189     PROPmaskADD( ppSetMask, PPpropOUTLINELEVEL );
190     PROPmaskADD( ppSetMask, PPpropLISTLEVEL );
191 
192     if  ( docUpdParaProperties( (PropertyMask *)0, ppSet, ppSetMask,
193 						&(dp.dpNode->biParaProperties),
194 						&(dcj.dcjAttributeMap) ) )
195 	{ LDEB(1); rval= -1; goto ready; }
196 
197   ready:
198 
199     docCleanDocumentCopyJob( &dcj );
200 
201     return rval;
202     }
203 
204 /************************************************************************/
205 /*									*/
206 /*  Apply the Ruler of the first paragraph in the pasted document to	*/
207 /*  the current selection.						*/
208 /*									*/
209 /************************************************************************/
210 
tedApplyPastedRuler(EditDocument * ed,BufferDocument * bdFrom,int traced)211 int tedApplyPastedRuler(		EditDocument *		ed,
212 					BufferDocument *	bdFrom,
213 					int			traced )
214     {
215     int				rval= 0;
216 
217     ParagraphProperties		ppSet;
218     PropertyMask		ppSetMask;
219 
220     TedEditOperation		teo;
221     EditOperation *		eo= &(teo.teoEo);
222     SelectionGeometry		sg;
223     SelectionDescription	sd;
224 
225     DocumentSelection		ds;
226 
227     const int			fullWidth= 1;
228 
229     docInitParagraphProperties( &ppSet );
230 
231     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
232 
233     docEditOperationGetSelection( &ds, eo );
234 
235     if  ( tedGetRulerFromPaste( &ppSet, &ppSetMask,
236 					    eo, &(ed->edFilename), bdFrom ) )
237 	{ LDEB(1); rval= -1; goto ready;	}
238 
239     if  ( tedEditChangeSelectionProperties( &teo, &ds,
240 		    DOClevPARA, EDITcmdUPD_PARA_PROPS,
241 		    (const PropertyMask *)0, (const TextAttribute *)0,
242 		    &ppSetMask, &ppSet,
243 		    (const PropertyMask *)0, (const CellProperties *)0,
244 		    (const PropertyMask *)0, (const RowProperties *)0,
245 		    (const PropertyMask *)0, (const SectionProperties *)0,
246 		    (const PropertyMask *)0, (const DocumentProperties *)0 ) )
247 	{ LDEB(1); rval= -1; goto ready; }
248 
249     /* tedEditChangeSelectionProperties() finishes the TedEditOperation */
250 
251   ready:
252 
253     tedCleanEditOperation( &teo );
254     docCleanParagraphProperties( &ppSet );
255 
256     return rval;
257     }
258 
259 /************************************************************************/
260 
tedGetAttributesFromPaste(TextAttribute * taSetTo,PropertyMask * taSetMask,EditOperation * eo,const MemoryBuffer * filename,BufferDocument * bdFrom)261 static int tedGetAttributesFromPaste(	TextAttribute *		taSetTo,
262 					PropertyMask *		taSetMask,
263 					EditOperation *		eo,
264 					const MemoryBuffer *	filename,
265 					BufferDocument *	bdFrom )
266     {
267     int				rval= 0;
268 
269     const int			forceAttributeTo= -1;
270     PropertyMask		taOnlyMask;
271 
272     DocumentSelection		dsAll;
273 
274     TextAttribute		taSetFrom;
275 
276     DocumentCopyJob		dcj;
277 
278     docInitDocumentCopyJob( &dcj );
279 
280     if  ( docSet2DocumentCopyJob( &dcj, eo, bdFrom, &(bdFrom->bdBody),
281 					filename, forceAttributeTo ) )
282 	{ LDEB(1); rval= -1; goto ready;	}
283 
284     docInitDocumentSelection( &dsAll );
285     if  ( docSelectWholeBody( &dsAll, bdFrom ) )
286 	{ LDEB(1); rval= -1; goto ready;	}
287 
288     utilPropMaskClear( taSetMask );
289 
290     utilInitTextAttribute( &taSetFrom );
291     utilInitTextAttribute( taSetTo );
292 
293     docGetSelectionAttributes( bdFrom, &dsAll, taSetMask, &taSetFrom );
294     docMapTextAttribute( taSetTo, &taSetFrom, &dcj );
295 
296     utilPropMaskClear( &taOnlyMask );
297 
298     PROPmaskADD( &taOnlyMask, TApropFONT_NUMBER );
299     PROPmaskADD( &taOnlyMask, TApropFONTSIZE );
300     PROPmaskADD( &taOnlyMask, TApropFONTBOLD );
301     PROPmaskADD( &taOnlyMask, TApropFONTSLANTED );
302     PROPmaskADD( &taOnlyMask, TApropTEXTUNDERLINED );
303     PROPmaskADD( &taOnlyMask, TApropSTRIKETHROUGH );
304 
305     /* PROPmaskADD( &taOnlyMask, TApropSUPERSUB ); */
306     /* PROPmaskADD( &taOnlyMask, TApropSMALLCAPS ); */
307     /* PROPmaskADD( &taOnlyMask, TApropCAPITALS ); */
308 
309     PROPmaskADD( &taOnlyMask, TApropTEXT_COLOR );
310     PROPmaskADD( &taOnlyMask, TApropTEXT_STYLE );
311     PROPmaskADD( &taOnlyMask, TApropBORDER );
312     PROPmaskADD( &taOnlyMask, TApropSHADING );
313 
314     utilPropMaskAnd( taSetMask, taSetMask, &taOnlyMask );
315 
316   ready:
317 
318     docCleanDocumentCopyJob( &dcj );
319 
320     return rval;
321     }
322 
323 /************************************************************************/
324 /*									*/
325 /*  Apply the text attributes of the first position in the pasted	*/
326 /*  document to the current selection.					*/
327 /*									*/
328 /************************************************************************/
329 
tedApplyPastedFont(EditDocument * ed,BufferDocument * bdFrom,int traced)330 int tedApplyPastedFont(		EditDocument *		ed,
331 				BufferDocument *	bdFrom,
332 				int			traced )
333     {
334     int				rval= 0;
335 
336     DocumentSelection		dsAll;
337 
338     TextAttribute		taSet;
339     PropertyMask		taSetMask;
340 
341     TedEditOperation		teo;
342     EditOperation *		eo= &(teo.teoEo);
343     SelectionGeometry		sg;
344     SelectionDescription	sd;
345 
346     DocumentSelection		ds;
347 
348     const int			fullWidth= 1;
349 
350     docInitDocumentSelection( &dsAll );
351 
352     tedStartEditOperation( &teo, &sg, &sd, ed, fullWidth, traced );
353 
354     docEditOperationGetSelection( &ds, eo );
355 
356     if  ( tedGetAttributesFromPaste( &taSet, &taSetMask,
357 					    eo, &(ed->edFilename), bdFrom ) )
358 	{ LDEB(1); rval= -1; goto ready; }
359 
360     if  ( tedEditChangeSelectionProperties( &teo, &ds,
361 		    DOClevSPAN, EDITcmdUPD_SPAN_PROPS,
362 		    &taSetMask, &taSet,
363 		    (const PropertyMask *)0, (const ParagraphProperties *)0,
364 		    (const PropertyMask *)0, (const CellProperties *)0,
365 		    (const PropertyMask *)0, (const RowProperties *)0,
366 		    (const PropertyMask *)0, (const SectionProperties *)0,
367 		    (const PropertyMask *)0, (const DocumentProperties *)0 ) )
368 	{ LDEB(1); rval= -1; goto ready; }
369 
370     /* tedEditChangeSelectionProperties() finishes the TedEditOperation */
371 
372   ready:
373 
374     tedCleanEditOperation( &teo );
375 
376     return rval;
377     }
378 
379