1 /************************************************************************/
2 /* */
3 /* Ted: Copy/Paste related functionality. */
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 "tedAppResources.h"
17 # include "tedCopyPasteImpl.h"
18 # include "tedEdit.h"
19 # include "tedDocument.h"
20 # include "tedDocFront.h"
21 # include <docRtfReadWrite.h>
22 # include <docPlainReadWrite.h>
23 # include <appImage.h>
24 # include <docRtfFlags.h>
25 # include <docEditCommand.h>
26
27 # include <sioMemory.h>
28 # include <sioXprop.h>
29 # include <sioFileio.h>
30 # include <bmio.h>
31
32 # include <appDebugon.h>
33
tedDocCut(EditDocument * ed)34 void tedDocCut( EditDocument * ed )
35 {
36 TedDocument * td= (TedDocument *)ed->edPrivateData;
37
38 DocumentSelection ds;
39 SelectionGeometry sg;
40 SelectionDescription sd;
41
42 if ( tedGetSelection( &ds, &sg, &sd,
43 (DocumentTree **)0, (struct BufferItem **)0, ed ) )
44 { return; }
45
46 if ( ! sd.sdIsTableSlice && ! sd.sdCanReplace )
47 { LLDEB(sd.sdIsTableSlice,sd.sdCanReplace); return; }
48
49 if ( tedDocCopySelection( ed ) )
50 { LDEB(1); return; }
51
52 if ( sd.sdIsTableSlice )
53 { tedDeleteTableSliceSelection( ed, td->tdTraced ); }
54 else{
55 tedDocDeleteSelection( ed, EDITcmdDELETE_SELECTION, td->tdTraced );
56 }
57
58 if ( appDocOwnSelection( ed, "CLIPBOARD",
59 TedClipboardTextTargets, TedClipboardTextTargetCount ) )
60 { LDEB(1); }
61
62 return;
63 }
64
tedDocCopy(EditDocument * ed)65 void tedDocCopy( EditDocument * ed )
66 {
67 TedDocument * td= (TedDocument *)ed->edPrivateData;
68
69 DocumentSelection ds;
70 SelectionGeometry sg;
71 SelectionDescription sd;
72
73 const int scrolledX= 0;
74 const int scrolledY= 0;
75
76 if ( tedGetSelection( &ds, &sg, &sd,
77 (DocumentTree **)0, (struct BufferItem **)0, ed ) )
78 { return; }
79
80 if ( tedDocCopySelection( ed ) )
81 { return; }
82
83 td->tdVisibleSelectionCopied= 1;
84
85 appDocExposeRectangle( ed, &(sg.sgRectangle), scrolledX, scrolledY );
86
87 if ( appDocOwnSelection( ed, "CLIPBOARD",
88 TedClipboardTextTargets, TedClipboardTextTargetCount ) )
89 { LDEB(1); }
90
91 return;
92 }
93
94 /************************************************************************/
95 /* */
96 /* Ted, Copy/Paste functionality. */
97 /* */
98 /************************************************************************/
99
tedClipboardLost(APP_WIDGET w,void * voided,APP_EVENT * event)100 void tedClipboardLost( APP_WIDGET w,
101 void * voided,
102 APP_EVENT * event )
103 {
104 EditDocument * ed= (EditDocument *)voided;
105 TedDocument * td= (TedDocument *)ed->edPrivateData;
106
107 DocumentSelection ds;
108 SelectionGeometry sg;
109 SelectionDescription sd;
110
111 if ( tedGetSelection( &ds, &sg, &sd,
112 (DocumentTree **)0, (struct BufferItem **)0, ed ) )
113 { return; }
114
115 td->tdVisibleSelectionCopied= 0;
116
117 if ( tedHasSelection( ed ) && ! sd.sdIsIBarSelection )
118 {
119 const int scrolledX= 0;
120 const int scrolledY= 0;
121
122 appDocExposeRectangle( ed, &(sg.sgRectangle), scrolledX, scrolledY );
123 }
124 }
125
tedPrimaryLost(APP_WIDGET w,void * voided,APP_EVENT * event)126 void tedPrimaryLost( APP_WIDGET w,
127 void * voided,
128 APP_EVENT * event )
129 {
130 EditDocument * ed= (EditDocument *)voided;
131 TedDocument * td= (TedDocument *)ed->edPrivateData;
132
133 td->tdOwnsPrimarySelection= 0;
134
135 return;
136 }
137
138 /************************************************************************/
139 /* */
140 /* Return the selection to a requestor. */
141 /* */
142 /************************************************************************/
143
APP_GIVE_COPY(tedCopyClipboardRtf,w,event,voided)144 APP_GIVE_COPY( tedCopyClipboardRtf, w, event, voided )
145 {
146 EditDocument * ed= (EditDocument *)voided;
147 TedDocument * td= (TedDocument *)ed->edPrivateData;
148
149 SimpleOutputStream * sos;
150
151 if ( utilMemoryBufferIsEmpty( &(td->tdCopiedSelection) ) )
152 { LDEB(td->tdCopiedSelection.mbSize); return; }
153
154 sos= sioOutOpenCopy( w, event );
155 if ( ! sos )
156 { XDEB(sos); return; }
157
158 if ( sioOutWriteBytes( sos, td->tdCopiedSelection.mbBytes,
159 td->tdCopiedSelection.mbSize ) <= 0 )
160 { LDEB(td->tdCopiedSelection.mbSize); sioOutClose( sos ); return; }
161
162 sioOutClose( sos );
163
164 if ( getenv( "TED_SAVE_COPIES" ) )
165 {
166 sos= sioOutFileioOpenS( "/tmp/returned.rtf" );
167 if ( sos )
168 {
169 if ( sioOutWriteBytes( sos, td->tdCopiedSelection.mbBytes,
170 td->tdCopiedSelection.mbSize ) <= 0 )
171 { LDEB(td->tdCopiedSelection.mbSize); }
172
173 sioOutClose( sos );
174 }
175 }
176
177 return;
178 }
179
tedCopyString(const MemoryBuffer * mb,APP_WIDGET w,APP_SELECTION_EVENT * event,EditDocument * ed)180 static void tedCopyString( const MemoryBuffer * mb,
181 APP_WIDGET w,
182 APP_SELECTION_EVENT * event,
183 EditDocument * ed )
184 {
185 SimpleOutputStream * sos;
186
187 BufferDocument * bd;
188 SimpleInputStream * sis;
189
190 const unsigned int rtfFlags= 0;
191
192 if ( utilMemoryBufferIsEmpty( mb ) )
193 { LDEB(mb->mbSize); return; }
194
195 sos= sioOutOpenCopy( w, event );
196 if ( ! sos )
197 { XDEB(sos); return; }
198
199 sis= sioInMemoryOpen( mb );
200 if ( ! sis )
201 { XDEB(sis); sioOutClose( sos ); return; }
202
203 bd= docRtfReadFile( sis, rtfFlags );
204 sioInClose( sis );
205
206 if ( ! bd )
207 { XDEB(bd); sioOutClose( sos ); return; }
208
209 if ( getenv( "TED_SAVE_COPIES" ) )
210 { tedSaveSelectionTxtToFile( bd, "/tmp/returned.txt" ); }
211
212 if ( docPlainSaveDocument( sos, bd, (DocumentSelection *)0, 0 ) )
213 { LDEB(1); }
214
215 docFreeDocument( bd );
216 sioOutClose( sos );
217
218 return;
219 }
220
APP_GIVE_COPY(tedCopyPrimaryString,w,event,voided)221 APP_GIVE_COPY( tedCopyPrimaryString, w, event, voided )
222 {
223 EditDocument * ed= (EditDocument *)voided;
224
225 DocumentSelection ds;
226 SelectionDescription sd;
227
228 MemoryBuffer mb;
229
230 utilInitMemoryBuffer( &mb );
231
232 if ( ! tedDocSaveSelectionRtf( &mb, &ds, &sd, ed ) )
233 { tedCopyString( &mb, w, event, ed ); }
234
235 utilCleanMemoryBuffer( &mb );
236
237 return;
238 }
239
APP_GIVE_COPY(tedCopyClipboardString,w,event,voided)240 APP_GIVE_COPY( tedCopyClipboardString, w, event, voided )
241 {
242 EditDocument * ed= (EditDocument *)voided;
243 TedDocument * td= (TedDocument *)ed->edPrivateData;
244
245 tedCopyString( &(td->tdCopiedSelection), w, event, ed );
246 return;
247 }
248
tedCopyImageFile(APP_WIDGET w,APP_SELECTION_EVENT * event,void * voided,bmWriteBitmap writeBitmap)249 static int tedCopyImageFile( APP_WIDGET w,
250 APP_SELECTION_EVENT * event,
251 void * voided,
252 bmWriteBitmap writeBitmap )
253 {
254 int rval= 0;
255 EditDocument * ed= (EditDocument *)voided;
256 TedDocument * td= (TedDocument *)ed->edPrivateData;
257
258 SimpleOutputStream * sos= (SimpleOutputStream *)0;
259
260 if ( ! td->tdCopiedImage.riBytes )
261 { XDEB(td->tdCopiedImage.riBytes); rval= -1; goto ready; }
262
263 sos= sioOutOpenCopy( w, event );
264 if ( ! sos )
265 { XDEB(sos); rval= -1; goto ready; }
266
267 if ( (*writeBitmap)( &(td->tdCopiedImage.riDescription),
268 td->tdCopiedImage.riBytes, sos ) )
269 { LDEB(1); rval= -1; goto ready; }
270
271 ready:
272 if ( sos )
273 { sioOutClose( sos ); }
274
275 return rval;
276 }
277
APP_GIVE_COPY(tedCopyClipboardPng,w,event,voided)278 APP_GIVE_COPY( tedCopyClipboardPng, w, event, voided )
279 {
280 if ( tedCopyImageFile( w, event, voided, bmPngWritePng ) )
281 { LDEB(1); }
282
283 return;
284 }
285
APP_GIVE_COPY(tedCopyClipboardJfif,w,event,voided)286 APP_GIVE_COPY( tedCopyClipboardJfif, w, event, voided )
287 {
288 if ( tedCopyImageFile( w, event, voided, bmJpegWriteJfif ) )
289 { LDEB(1); }
290
291 return;
292 }
293
APP_GIVE_COPY(tedCopyFontTed,w,event,voided)294 APP_GIVE_COPY( tedCopyFontTed, w, event, voided )
295 {
296 EditDocument * ed= (EditDocument *)voided;
297 TedDocument * td= (TedDocument *)ed->edPrivateData;
298
299 SimpleOutputStream * sos;
300
301 if ( utilMemoryBufferIsEmpty( &(td->tdCopiedFont) ) )
302 { LDEB(td->tdCopiedFont.mbSize); return; }
303
304 sos= sioOutOpenCopy( w, event );
305 if ( ! sos )
306 { XDEB(sos); return; }
307
308 if ( sioOutWriteBytes( sos, td->tdCopiedFont.mbBytes,
309 td->tdCopiedFont.mbSize ) <= 0 )
310 { LDEB(1); sioOutClose( sos ); return; }
311
312 sioOutClose( sos );
313
314 return;
315 }
316
317 /************************************************************************/
318 /* */
319 /* Copy the ruler as it was saved on the document struct when the */
320 /* menu option was clicked. */
321 /* */
322 /************************************************************************/
323
APP_GIVE_COPY(tedCopyRulerTed,w,event,voided)324 APP_GIVE_COPY( tedCopyRulerTed, w, event, voided )
325 {
326 EditDocument * ed= (EditDocument *)voided;
327 TedDocument * td= (TedDocument *)ed->edPrivateData;
328
329 SimpleOutputStream * sos;
330
331 if ( utilMemoryBufferIsEmpty( &(td->tdCopiedRuler) ) )
332 { LDEB(td->tdCopiedRuler.mbSize); return; }
333
334 sos= sioOutOpenCopy( w, event );
335 if ( ! sos )
336 { XDEB(sos); return; }
337
338 if ( sioOutWriteBytes( sos, td->tdCopiedRuler.mbBytes,
339 td->tdCopiedRuler.mbSize ) <= 0 )
340 { LDEB(1); sioOutClose( sos ); return; }
341
342 sioOutClose( sos );
343
344 return;
345 }
346
347 /************************************************************************/
348 /* */
349 /* Finish a paste action. */
350 /* */
351 /************************************************************************/
352
353 typedef BufferDocument * (*TED_READ) (
354 SimpleInputStream * sis,
355 EditApplication * ea,
356 const DocumentGeometry * dg );
357
358 typedef int (*TED_INCLUDE) ( EditDocument * ed,
359 BufferDocument * bd,
360 int traced );
361
tedPasteRtfReadFile(SimpleInputStream * sis,EditApplication * ea,const DocumentGeometry * dg)362 static BufferDocument * tedPasteRtfReadFile(
363 SimpleInputStream * sis,
364 EditApplication * ea,
365 const DocumentGeometry * dg )
366 {
367 const unsigned int rtfFlags= 0;
368
369 return docRtfReadFile( sis, rtfFlags );
370 }
371
tedPastePlainReadFile(SimpleInputStream * sis,EditApplication * ea,const DocumentGeometry * dg)372 static BufferDocument * tedPastePlainReadFile(
373 SimpleInputStream * sis,
374 EditApplication * ea,
375 const DocumentGeometry * dg )
376 {
377 int longestPara;
378
379 return docPlainReadFile( sis, &longestPara, dg );
380 }
381
tedPasteClipboardGeneric(APP_WIDGET w,EditDocument * ed,APP_SELECTION_EVENT * event,TED_READ readDoc,TED_INCLUDE includeDoc)382 static int tedPasteClipboardGeneric( APP_WIDGET w,
383 EditDocument * ed,
384 APP_SELECTION_EVENT * event,
385 TED_READ readDoc,
386 TED_INCLUDE includeDoc )
387 {
388 int rval= 0;
389 EditApplication * ea= ed->edApplication;
390 TedDocument * td= (TedDocument *)ed->edPrivateData;
391
392 SimpleInputStream * sis= (SimpleInputStream *)0;
393 BufferDocument * bd= (BufferDocument *)0;
394
395 TedAppResources * tar= (TedAppResources *)ea->eaResourceData;
396
397 tedDetermineDefaultSettings( tar );
398
399 sis= sioInOpenPaste( w, event );
400 if ( ! sis )
401 { XDEB(sis); rval= -1; goto ready; }
402
403 bd= (*readDoc)( sis, ea, &(ea->eaDefaultDocumentGeometry) );
404
405 if ( ! bd )
406 { XDEB( bd ); rval= -1; goto ready; }
407
408 if ( getenv( "TED_SAVE_COPIES" ) )
409 {
410 const int rtfFlags= 0;
411 const DocumentSelection * const ds= (const DocumentSelection *)0;
412
413 tedSaveSelectionToFile( bd, ds, rtfFlags, "/tmp/included.rtf" );
414 }
415
416 if ( (*includeDoc)( ed, bd, td->tdTraced ) )
417 { LDEB(1); rval= -1; goto ready; }
418
419 ready:
420
421 if ( bd )
422 { docFreeDocument( bd ); }
423 if ( sis )
424 { sioInClose( sis ); }
425
426 return rval;
427 }
428
APP_PASTE_REPLY(tedPasteClipboardRtf,w,event,voided)429 APP_PASTE_REPLY( tedPasteClipboardRtf, w, event, voided )
430 {
431 EditDocument * ed= (EditDocument *)voided;
432
433 tedPasteClipboardGeneric( w, ed, event,
434 tedPasteRtfReadFile, tedIncludeRtfDocument );
435
436 }
437
APP_PASTE_REPLY(tedPasteClipboardString,w,event,voided)438 APP_PASTE_REPLY( tedPasteClipboardString, w, event, voided )
439 {
440 EditDocument * ed= (EditDocument *)voided;
441
442 tedPasteClipboardGeneric( w, ed, event,
443 tedPastePlainReadFile, tedIncludePlainDocument );
444 }
445
APP_PASTE_REPLY(tedPastePrimaryString,w,event,voided)446 APP_PASTE_REPLY( tedPastePrimaryString, w, event, voided )
447 {
448 EditDocument * ed= (EditDocument *)voided;
449
450 tedPasteClipboardGeneric( w, ed, event,
451 tedPastePlainReadFile, tedIncludePlainDocument );
452 }
453
tedPasteImageFile(APP_WIDGET w,APP_SELECTION_EVENT * event,EditDocument * ed,bmReadBitmap readBitmap,const char * nameHint)454 static int tedPasteImageFile( APP_WIDGET w,
455 APP_SELECTION_EVENT * event,
456 EditDocument * ed,
457 bmReadBitmap readBitmap,
458 const char * nameHint )
459 {
460 int rval= 0;
461 TedDocument * td= (TedDocument *)ed->edPrivateData;
462
463 SimpleInputStream * sis= (SimpleInputStream *)0;
464 RasterImage * ri= (RasterImage *)0;
465
466 MemoryBuffer filename;
467
468 utilInitMemoryBuffer( &filename );
469
470 if ( ! td->tdSelectionDescription.sdCanReplace )
471 { LDEB(td->tdSelectionDescription.sdCanReplace); rval= -1; goto ready; }
472
473 if ( utilMemoryBufferSetString( &filename, nameHint ) )
474 { SDEB(nameHint); rval= -1; goto ready; }
475
476 ri= (RasterImage *)malloc( sizeof(RasterImage) );
477 if ( ! ri )
478 { XDEB(ri); rval= -1; goto ready; }
479 bmInitRasterImage( ri );
480
481 sis= sioInOpenPaste( w, event );
482 if ( ! sis )
483 { XDEB(sis); rval= -1; goto ready; }
484
485 if ( (*readBitmap)( &(ri->riDescription), &(ri->riBytes), sis ) )
486 { LDEB(1); rval= -1; goto ready; }
487 ri->riFormat= bmSuggestFormat( &(filename),
488 ri->riFormat, &(ri->riDescription) );
489
490 if ( tedReplaceSelectionWithRasterImage( ed, ri, td->tdTraced ) )
491 { LDEB(1); rval= -1; goto ready; }
492
493 ri= (RasterImage *)0; /* stolen */
494
495 ready:
496
497 utilCleanMemoryBuffer( &filename );
498
499 if ( ri )
500 { bmFreeRasterImage( ri ); }
501 if ( sis )
502 { sioInClose( sis ); }
503
504 return rval;
505 }
506
APP_PASTE_REPLY(tedPasteClipboardPng,w,event,voided)507 APP_PASTE_REPLY( tedPasteClipboardPng, w, event, voided )
508 {
509 if ( tedPasteImageFile( w, event, (EditDocument *)voided,
510 bmPngReadPng, "some.png" ) )
511 { LDEB(1); }
512
513 return;
514 }
515
APP_PASTE_REPLY(tedPasteClipboardJfif,w,event,voided)516 APP_PASTE_REPLY( tedPasteClipboardJfif, w, event, voided )
517 {
518 if ( tedPasteImageFile( w, event, (EditDocument *)voided,
519 bmJpegReadJfif, "some.jpeg" ) )
520 { LDEB(1); }
521
522 return;
523 }
524
525 /************************************************************************/
526
APP_PASTE_REPLY(tedPasteRulerTed,w,event,voided)527 APP_PASTE_REPLY( tedPasteRulerTed, w, event, voided )
528 {
529 EditDocument * ed= (EditDocument *)voided;
530
531 tedPasteClipboardGeneric( w, ed, event,
532 tedPasteRtfReadFile, tedApplyPastedRuler );
533 return;
534 }
535
536 /************************************************************************/
537
APP_PASTE_REPLY(tedPasteFontTed,w,event,voided)538 APP_PASTE_REPLY( tedPasteFontTed, w, event, voided )
539 {
540 EditDocument * ed= (EditDocument *)voided;
541
542 tedPasteClipboardGeneric( w, ed, event,
543 tedPasteRtfReadFile, tedApplyPastedFont );
544 return;
545 }
546
547 /************************************************************************/
548 /* */
549 /* 'Copy Font' menu option. */
550 /* */
551 /************************************************************************/
552
tedCopyFont(EditDocument * ed)553 void tedCopyFont( EditDocument * ed )
554 {
555 TedDocument * td= (TedDocument *)ed->edPrivateData;
556 SimpleOutputStream * sos;
557
558 DocumentSelection ds;
559 SelectionGeometry sg;
560 SelectionDescription sd;
561
562 const int rtfFlags= RTFflagNO_BOOKMARKS|RTFflagSAVE_SOMETHING;
563
564 if ( tedGetSelection( &ds, &sg, &sd,
565 (DocumentTree **)0, (struct BufferItem **)0, ed ) )
566 { LDEB(1); return; }
567
568 /* 2 */
569 sos= sioOutMemoryOpen( &(td->tdCopiedFont) );
570 if ( ! sos )
571 { XDEB(sos); return; }
572
573 if ( docRtfSaveDocument( sos, td->tdDocument, &ds, rtfFlags ) )
574 { LDEB(1); sioOutClose( sos ); return; }
575
576 if ( sioOutClose( sos ) )
577 { LDEB(1); return; }
578
579 if ( getenv( "TED_SAVE_COPIES" ) )
580 {
581 tedSaveSelectionToFile( td->tdDocument, &ds,
582 rtfFlags, "/tmp/savedfont.rtf" );
583 }
584
585 appDocOwnSelection( ed, "RTFFONT", TedFontTargets, TedFontTargetCount );
586 }
587
588 /************************************************************************/
589 /* */
590 /* Callbacks for the Copy/Paste ruler menu options. */
591 /* */
592 /* 1) The ruler paste is a selection paste with the selection */
593 /* constrained to the last position of the first paragraph in the */
594 /* selection. */
595 /* 2) Remember the bytes expecting that someone will ask for them. */
596 /* 3) Tell that we have a ruler paste available. */
597 /* */
598 /************************************************************************/
599
tedCopyRuler(EditDocument * ed)600 void tedCopyRuler( EditDocument * ed )
601 {
602 TedDocument * td= (TedDocument *)ed->edPrivateData;
603 SimpleOutputStream * sos;
604
605 DocumentSelection ds;
606 SelectionGeometry sg;
607 SelectionDescription sd;
608
609 DocumentSelection dsPara;
610
611 const int rtfFlags= RTFflagNO_BOOKMARKS;
612
613 if ( tedGetSelection( &ds, &sg, &sd,
614 (DocumentTree **)0, (struct BufferItem **)0, ed ) )
615 { LDEB(1); return; }
616
617 /* 1 */
618 dsPara= ds;
619 docTailPosition( &(dsPara.dsHead), dsPara.dsHead.dpNode );
620 docSetIBarSelection( &dsPara, &(dsPara.dsHead) );
621
622 /* 2 */
623 sos= sioOutMemoryOpen( &(td->tdCopiedRuler) );
624 if ( ! sos )
625 { XDEB(sos); return; }
626
627 if ( docRtfSaveDocument( sos, td->tdDocument, &dsPara, rtfFlags ) )
628 { LDEB(1); sioOutClose( sos ); return; }
629
630 if ( sioOutClose( sos ) )
631 { LDEB(1); return; }
632
633 if ( getenv( "TED_SAVE_COPIES" ) )
634 {
635 tedSaveSelectionToFile( td->tdDocument, &dsPara,
636 rtfFlags, "/tmp/savedruler.rtf" );
637 }
638
639 /* 2 */
640 appDocOwnSelection( ed, "RTFRULER", TedRulerTargets, TedRulerTargetCount );
641 }
642
643 /************************************************************************/
644
tedManagePrimarySelection(EditDocument * ed)645 void tedManagePrimarySelection( EditDocument * ed )
646 {
647 TedDocument * td= (TedDocument *)ed->edPrivateData;
648
649 if ( ! tedHasIBarSelection( ed ) )
650 {
651 if ( appDocOwnSelection( ed, "PRIMARY",
652 TedPrimaryTargets,
653 TedPrimaryTargetCount ) )
654 { LDEB(1); }
655 else{ td->tdOwnsPrimarySelection= 1; }
656 }
657 else{
658 if ( td->tdOwnsPrimarySelection )
659 {
660 appDocReleaseSelection( ed, "PRIMARY" );
661 td->tdOwnsPrimarySelection= 0;
662 }
663 }
664
665 return;
666 }
667
668