home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / editor / epmtools / epmmac / clipbrd.e < prev    next >
Text File  |  1993-07-09  |  33KB  |  739 lines

  1. /*
  2. ╔════════════════════════════════════════════════════════════════════════════╗
  3. ║ What's it called: clipbrd.e                                                ║
  4. ║                                                                            ║
  5. ║ What does it do:  contains procedures and commands that all:               ║
  6. ║                  -Allow one to pass lines of text between edit windows     ║
  7. ║                  -Allow text to be placed in the PM clipboard              ║
  8. ║                                                                            ║
  9. ║                Text Manipulation between Edit Windows                      ║
  10. ║                ======================================                      ║
  11. ║                Copy2SharBuff  -  Copy Marked area to EPM shared buffer     ║
  12. ║                GetSharBuff    -  Get text from EPM shared buffer           ║
  13. ║                ClearSharBuf   -  Flush out Stuff in shared buffer          ║
  14. ║                Copy2DMBuff    -  Copy Marked area to "Delete Mark" buffer  ║
  15. ║                GetDMBuff    -  Get text from "Delete Mark" buffer          ║
  16. ║                                                                            ║
  17. ║                Text Manipulation between an Edit Window and PM clipboard   ║
  18. ║                ========================================================    ║
  19. ║                                                                            ║
  20. ║                copy2clip - copy marked text to the PM clipboard.           ║
  21. ║                                                                            ║
  22. ║                cut - like copy2clip, but deletes the marked text.          ║
  23. ║                                                                            ║
  24. ║                paste - retrieve text from PM clipboard to edit window.     ║
  25. ║                                                                            ║
  26. ║                                                                            ║
  27. ║ Who and When: Ralph Yozzo, Gennaro (Jerry) Cuomo, & Larry Margolis 3-88    ║
  28. ║                                                                    6/89    ║
  29. ╚════════════════════════════════════════════════════════════════════════════╝
  30. */
  31. /*
  32. ┌────────────────────────────────────────────────────────────────────────────┐
  33. │ Copy2SharBuff -                                                            │
  34. │                 Copy Marked area to EPM shared buffer                      │
  35. │                                                                            │
  36. │                                                                            │
  37. └────────────────────────────────────────────────────────────────────────────┘
  38. */
  39. defc Copy2SharBuff                     /* former name = CLIPBRD_pt          */
  40.    if not marktype() then              /* check if mark exists              */
  41.       return                           /* if mark doesn't exist, return     */
  42.    endif
  43.                                        /* save the dimensions of the mark   */
  44. compile if EVERSION >= 5.50
  45.    getmarkg fstline,                   /* returned:  first line of mark     */
  46. compile else
  47.    getmark fstline,                    /* returned:  first line of mark     */
  48. compile endif
  49.            lstline,                    /* returned:  last  line of mark     */
  50.            fstcol,                     /* returned:  first column of mark   */
  51.            lstcol,                     /* returned:  last  column of mark   */
  52.            mkfileid                    /* returned:  file id of marked file */
  53.  
  54.    getfileid fileid                    /* save file id of visible file      */
  55.    activatefile mkfileid               /* switch to file with mark          */
  56.    /* Try to open the buffer.  If it doesn't exist, create it.              */
  57.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  58.    if bufhndl then
  59.       opened = 1
  60.    else
  61.       -- Make a 64K buffer... memory's plentiful.  Easily changed.
  62.       bufsize = MAXBUFSIZE
  63.       bufhndl = buffer(CREATEBUF, EPMSHAREDBUFFER, bufsize)
  64.       opened = 0
  65.    endif
  66.    if not bufhndl then
  67.       sayerror CAN_NOT_OPEN__MSG EPMSHAREDBUFFER '-' ERROR_NUMBER__MSG RC
  68.       stop
  69.    endif
  70.  
  71.    /* Copy the current marked lines (up to 64k worth of data ) into EPM's */
  72.    /* shared memory buffer.                                               */
  73. compile if EVERSION >= 5.51
  74.    call buffer(PUTMARKBUF, bufhndl, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES)  -- Was +FINALNULL
  75. compile else  -- Older versions needed the null for the copy to clipboard routine
  76.    call buffer(PUTMARKBUF, bufhndl, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES+FINALNULL)
  77. compile endif
  78.  
  79. compile if EVERSION >= 5.50
  80.    poke bufhndl, 28, atol(lstline-fstline+1-(lstline>.last))  -- Remember how many lines are *supposed* to be there.
  81. compile else
  82.    poke bufhndl, 28, atol(lstline-fstline+1)  -- Remember how many lines are *supposed* to be there.
  83. compile endif
  84.  
  85.    activatefile fileid
  86.    if opened then
  87.       call buffer(FREEBUF, bufhndl)
  88.    endif
  89.  
  90. /*
  91. ┌────────────────────────────────────────────────────────────────────────────┐
  92. │ GetSharBuff -                                                              │
  93. │                 Get text from EPM shared buffer.                           │
  94. │                 'O' means Overlay instead of copy.                         │
  95. │                                                                            │
  96. └────────────────────────────────────────────────────────────────────────────┘
  97. */
  98. defc GetSharBuff            /* former name = CLIPBRD_gt                 */
  99.    /* EPMSHAREDBUFFER= buffer name known between edit windows           */
  100.    -- Try to open the buffer.  If it doesn't exist, nothing to get.
  101.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  102.    if not bufhndl then
  103.       sayerror CAN_NOT_OPEN__MSG EPMSHAREDBUFFER '-' ERROR_NUMBER__MSG RC
  104.       stop
  105.    endif
  106.    call psave_pos(save_pos)
  107.    call GetBuffCommon(bufhndl, NO_MARK_NO_BUFF__MSG, arg(1))
  108.    call buffer(FREEBUF, bufhndl)
  109.    call prestore_pos(save_pos)
  110.  
  111. /*
  112. ┌────────────────────────────────────────────────────────────────────────────┐
  113. │ ClearSharBuff -                                                            │
  114. │                 Flush out stuff in  EPM shared buffer                      │
  115. │                                                                            │
  116. └────────────────────────────────────────────────────────────────────────────┘
  117. */
  118. defc ClearSharBuff
  119.    bufhndl=buffer(OPENBUF, EPMSHAREDBUFFER)
  120.    if bufhndl then
  121.       call buffer(CLEARBUF, bufhndl)
  122.       call buffer(FREEBUF, bufhndl)
  123.    endif
  124.  
  125. /*
  126. ┌────────────────────────────────────────────────────────────────────────────┐
  127. │ copy2clip                                                                  │
  128. │       copy marked text into the PM clipboard.                              │
  129. │                                                                            │
  130. │                                                                            │
  131. └────────────────────────────────────────────────────────────────────────────┘
  132. */
  133. defc copy2clip
  134.    call checkmark()                          /* Make sure there's a mark. */
  135.  
  136.    'Copy2SharBuff'   -- Recopy the marked area to the shared buffer,
  137.                      -- in case the user has modified the mark contents.
  138.  
  139.    /* Try to open the buffer.  If it doesn't exist, then we can't copy   */
  140.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  141.    if not bufhndl then
  142.       return 1                              /* buffer does not exist     */
  143.    endif
  144.    if peek(bufhndl,6,2) /== peek(bufhndl,28,2) then
  145.       sayerror TOO_MUCH_FOR_CLIPBD__MSG
  146.       return 1
  147.    endif
  148.  
  149. compile if EVERSION < '5.50'
  150.    hab=gethwnd(0)                           /* get EPM's anchorblock     */
  151.    call dynalink('PMWIN',                   /* Open PM's clipboard       */
  152.                  'WINOPENCLIPBRD',
  153.                  hab)
  154.  
  155.    call dynalink('PMWIN',                   -- Empty the clipboard completely
  156.                  'WINEMPTYCLIPBRD',         -- before filling it.
  157.                  hab)
  158.    result = dynalink(EUTIL_DLL,             /* create a buffer and copy  */
  159.             'CLIPBOARDCOPY',                /* the contents of the EPM   */
  160.             atoi(bufhndl)||                 /* shared buffer             */
  161.             atoi(0)      ||
  162.             atoi(1),                        /* buffer to pm clipboard    */
  163.             2)                              /* return long               */
  164.  
  165.    /* Clipboardcopy allocates a buffer of memory                         */
  166.    /* we don't have to worry about freeing the buffer that clipboardcopy */
  167.    /* allocates... PM will free it                                       */
  168.  
  169.    call dynalink('PMWIN',                   /* call PM function to       */
  170.                  'WINSETCLIPBRDDATA',       /* move data into the PM e cb*/
  171.                   hab ||                    /* anchor block              */
  172.                   atol(result) ||           /* pointer to text.          */
  173.                   atoi(1) ||                /* format (TEXT)             */
  174.                   atoi(256))                /* selector                  */
  175.  
  176.    call dynalink('PMWIN',
  177.                  'WINCLOSECLIPBRD',
  178.                  hab)
  179.    call buffer(FREEBUF, bufhndl)
  180.  
  181. compile else
  182. --  Copying to the Clipboard using the EToolkit message:
  183. --  EPM_EDIT_CLIPBOARDCOPY -  mp1 = pointer to memory buffer containing
  184. --                                  contents to copy to the clipboard.
  185. --                            mp2 = flag that describes what type of buffer
  186. --                                  was passed in mp1.
  187. --                                  0=CF_TEXT type buffer, terminated by nul
  188. --                                  1=EPM shared memory buffer (32byte head)
  189. --  When the contents of mp1 is copied to the clipboard a EPM defc event is
  190. --  called by the name of PROCESSCLIPBOARDCOPY.  Arg(1) of this function is
  191. --  the original buffer passed in as mp1.  The caller may choose to free
  192. --  the buffer during this command.    if zero is passed as arg(1), an error
  193. --  was encountered.  An error message should be displayed at this point.
  194.  
  195.    call windowmessage(0,  getpminfo(EPMINFO_EDITCLIENT),
  196.                       5441,               -- EPM_EDIT_CLIPBOARDCOPY
  197.                       mpfrom2short( bufhndl, 0),
  198.                       1)
  199.  
  200. defc processclipboardcopy
  201.    result=arg(1)
  202.    if not result then      -- If non-zero, free the buffer.
  203.       call buffer(FREEBUF, itoa(substr(atol(result),3,2),10))  -- pass just the selector
  204.    endif
  205.  
  206. compile endif -- EVERSION < '5.50'
  207.  
  208. /*
  209. ┌────────────────────────────────────────────────────────────────────────────┐
  210. │ cut                                                                        │
  211. │       copy marked text into the PM clipboard, then delete the mark.        │
  212. │                                                                            │
  213. │                                                                            │
  214. └────────────────────────────────────────────────────────────────────────────┘
  215. */
  216. defc cut
  217.    'copy2clip'
  218.    if not RC then
  219.       getmark firstline,lastline,firstcol,lastcol,markfileid
  220.       markfileid.line = firstline
  221.       if leftstr(marktype(), 1)<>'L' then
  222.          markfileid.col = firstcol
  223.       endif
  224.       call pdelete_mark()
  225.    endif
  226.  
  227. /*
  228. ┌─────────────────────────────────────────────────────────────────────────┐
  229. │ paste                                                                   │
  230. │                                                                         │
  231. │    retrieve text from PM clipboard to edit window                       │
  232. │                                                                         │
  233. └─────────────────────────────────────────────────────────────────────────┘
  234. */
  235. defc paste
  236. compile if WANT_CUA_MARKING = 'SWITCH'
  237.    universal CUA_marking_switch
  238. compile endif
  239.    if browse() then
  240.       sayerror BROWSE_IS__MSG ON__MSG
  241.       return
  242.    endif
  243. compile if EVERSION < '5.50'
  244.    if not clipcheck(format) then
  245.       sayerror CLIPBOARD_ERROR__MSG
  246.       return
  247.    endif
  248.    if format<>256 then                 -- no text in clipboard
  249.       sayerror CLIPBOARD_EMPTY__MSG
  250.       return
  251.    endif
  252.  
  253. compile if EPM32
  254.    hab=gethwndc(0)                          -- get EPM's anchorblock
  255.    call dynalink32('PMWIN',                   /* Open PM's clipboard       */
  256.                    '#793',  -- WINOPENCLIPBRD
  257.                     hab)
  258.  
  259.    result = dynalink32('PMWIN',               /* call PM function to       */
  260.                        '#806',  -- WINQUERYCLIPBRDDATA  /* look at the data in the cb*/
  261.                        hab ||                 /* anchor block              */
  262.                        atol(1),               /* data format ( TEXT )      */
  263.                        4)                     /* return a 4 byte result    */
  264.  
  265.    result = dynalink32(EUTIL_DLL,             /* create a buffer and copy  */
  266.                        'ClipboardCopy',       /*                           */
  267.                        atol(result) ||        /*                           */
  268.                        atol(0),               /* pm clipboard to shared buf*/
  269.                        4)                     /*                           */
  270.    call dynalink32('PMWIN',
  271.                    '#707',  -- WINCLOSECLIPBRD
  272.                    hab)
  273. compile else
  274.    hab=gethwnd(0)                          -- get EPM's anchorblock
  275.    call dynalink('PMWIN',                   /* Open PM's clipboard       */
  276.                  'WINOPENCLIPBRD',
  277.                  hab)
  278.  
  279.    result = dynalink('PMWIN',               /* call PM function to       */
  280.                      'WINQUERYCLIPBRDDATA', /* look at the data in the cb*/
  281.                      hab ||                 /* anchor block              */
  282.                      atoi(1),               /* data format ( TEXT )      */
  283.                      2)                     /* return a 4 byte result    */
  284.  
  285.    result = dynalink(EUTIL_DLL,             /* create a buffer and copy  */
  286.                      'CLIPBOARDCOPY',       /*                           */
  287.                      atol(result) ||        /*                           */
  288.                      atoi(0),               /* pm clipboard to shared buf*/
  289.                      2)                     /*                           */
  290.    call dynalink('PMWIN',
  291.                  'WINCLOSECLIPBRD',
  292.                  hab)
  293. compile endif  -- EPM32
  294.  
  295.    result=itoa(substr(atol(result),3,2),10) /* convert from bin to str   */
  296.    if arg(1)='C' | arg(1)='B' then
  297.       poke result, 8, chr(68-asc(arg(1)))              -- 'C'->1; 'B'->2; mark as a character or block buffer
  298.  compile if WANT_CUA_MARKING
  299.       if arg(1)='C' &
  300.   compile if WANT_CUA_MARKING = 'SWITCH'
  301.          CUA_marking_switch &
  302.   compile endif
  303.          marktype()
  304.       then
  305.          call pbegin_mark()
  306.          call pdelete_mark()
  307.          'ClearSharBuff'       /* Remove Content in EPM shared text buffer */
  308.       endif
  309.  compile endif
  310.       call psave_mark(savemark)                        -- Save the user's mark
  311.       call GetBuffCommon(result, NOTHING_TO_PASTE__MSG, arg(1))
  312.       -- clause continued below for common stuff.
  313. compile else  -- if EVERSION < 5.50
  314. --  Pasting from the PM Clipboard using the EToolkit message:
  315. --  EPM_EDIT_CLIPBOARDPASTE-  mp1 = flag that describes the type of paste
  316. --                                  that is desired.  A paste could be of
  317. --                            the following types; 'C' for Character, 'B' for
  318. --                            block and 'L' for line.
  319. --  During the processing of this message the text in the PM clipboard is
  320. --  queried.  Once this is done an EPM defc event is
  321. --  called by the name of PROCESSCLIPBOARDPASTE.  Arg(1) of this function
  322. --  contains a pointer to a buffer containing a copy of the text found in
  323. --  the PM clipboard.   Arg(2) of this function is
  324. --  the original flag passed in as mp1.  The caller may choose to free
  325. --  the buffer during this command.    if zero is passed as arg(1), an error
  326. --  was encountered.  An error message should be displayed at this point.
  327.    mark=arg(1)
  328.    if mark<>'C' and  mark<>'B' then
  329.       mark='L'
  330.    endif
  331.    call windowmessage(0,  getpminfo(EPMINFO_EDITCLIENT),
  332.                       5442,               -- EPM_EDIT_CLIPBOARDPASTE
  333.                       asc(mark), 0)
  334.  
  335. defc processclipboardpaste
  336.  compile if WANT_CUA_MARKING = 'SWITCH'
  337.    universal CUA_marking_switch
  338.  compile endif
  339.  
  340.    parse arg result mark .
  341.    if not result then
  342.       sayerror CLIPBOARD_ERROR__MSG
  343.       return
  344.    endif
  345.  
  346.    if mark=67 | mark=66 then  -- asc('C') | asc('B')
  347.       poke result, 8, chr(68-mark)              -- 'C'->1; 'B'->2; mark as a character or block buffer
  348.  compile if WANT_CUA_MARKING
  349.       if mark=67 &
  350.   compile if WANT_CUA_MARKING = 'SWITCH'
  351.          CUA_marking_switch &
  352.   compile endif
  353.          marktype()
  354.       then
  355.          getmark x, x, x, x, mark_fid
  356.          getfileid cur_fid
  357.          if mark_fid=cur_fid then
  358.             call pbegin_mark()
  359.             call pdelete_mark()
  360.          else
  361.             unmark
  362.             sayerror MARKED_OTHER__MSG
  363.          endif
  364.          'ClearSharBuff'       /* Remove content in EPM shared text buffer */
  365.       endif
  366.  compile endif
  367.       call psave_mark(savemark)                        -- Save the user's mark
  368.       call GetBuffCommon(result, NOTHING_TO_PASTE__MSG, chr(mark))
  369. compile endif -- EVERSION < '5.50'
  370.       -- Two cases join here, in the middle of this IF statement.
  371.       call prestore_mark(savemark)                     -- Restore the user's mark
  372.    else
  373.       oldsize = .last
  374. compile if EVERSION >= 5.50
  375.       call buffer(GETBUF2, result)          /* put buffer into text      */
  376.  compile if EVERSION >= 5.60
  377.       if textline(.line+.last-oldsize)=='' then
  378.          deleteline .line+.last-oldsize
  379.       endif
  380.  compile endif
  381. compile else
  382.       call buffer(GETBUF, result)           /* put buffer into text      */
  383. compile endif -- EVERSION >= 5.50
  384.       '+'(.last-oldsize)
  385.    endif
  386.  
  387. compile if EPM32
  388.    call dynalink32('DOSCALLS',        /* dynamic link library name         */
  389.                    '#304',             /* DosFreeSeg                        */
  390.                    ltoa(atoi(0) || atoi(result), 10))
  391. compile else
  392.    call dynalink('DOSCALLS',        /* dynamic link library name         */
  393.                  '#39',             /* DosFreeSeg                        */
  394.                  atoi(result))
  395. compile endif
  396.  
  397. compile if WANT_DM_BUFFER
  398. definit
  399.    universal DMbuf_handle
  400.    DMbuf_handle = 0
  401.  
  402. defexit
  403.    universal DMbuf_handle
  404.    if DMbuf_handle then
  405.       call buffer(FREEBUF, DMbuf_handle)              -- Free the OPEN
  406.    endif
  407.  
  408. /*
  409. ┌────────────────────────────────────────────────────────────────────────────┐
  410. │ Copy2DMBuff -                                                              │
  411. │                 Copy Marked area to "Delete Mark" buffer                   │
  412. │                                                                            │
  413. │                                                                            │
  414. └────────────────────────────────────────────────────────────────────────────┘
  415. */
  416. defc Copy2DMBuff
  417.    universal DMbuf_handle
  418.    themarktype = marktype()
  419.    if not themarktype then             /* check if mark exists              */
  420.       return                           /* if mark doesn't exist, return     */
  421.    endif
  422.                                        /* save the dimensions of the mark   */
  423.    getmark fstline,                    /* returned:  first line of mark     */
  424.            lstline,                    /* returned:  last  line of mark     */
  425.            fstcol,                     /* returned:  first column of mark   */
  426.            lstcol,                     /* returned:  last  column of mark   */
  427.            mkfileid                    /* returned:  file id of marked file */
  428.  
  429.    if themarktype='BLOCK' then  -- Size of block, + 2 per line for CR, LF
  430.       size=(lstcol-fstcol+3) * (lstline-fstline+1) + 3
  431.    else                       -- Probably much larger than we need, but must assume:
  432.       size=(MAXCOL+2) * (lstline-fstline+1) +3  -- 255 chars/line + CR, LF
  433.    endif
  434.    /* Try to open the buffer.  If it doesn't exist or is too small, create it. */
  435.    if not DMbuf_handle then
  436.       DMbuf_handle = buffer(OPENBUF, EPMDMBUFFER)
  437.       if DMbuf_handle then
  438.          call buffer(FREEBUF, DMbuf_handle)              -- Free the OPEN
  439.       endif
  440.    endif
  441.    if DMbuf_handle then
  442.       maxsize  = buffer(MAXSIZEBUF,DMbuf_handle)
  443.       if size > maxsize & maxsize < MAXBUFSIZE then
  444.          success=buffer(FREEBUF, DMbuf_handle)        -- Free the original CREATE
  445.          if not success then
  446.             sayerror ERROR__MSG rc TRYING_TO_FREE__MSG EPMDMBUFFER BUFFER__MSG
  447.          endif
  448.          DMbuf_handle = ''
  449.       endif
  450.    endif
  451.    if not DMbuf_handle then
  452.       DMbuf_handle = buffer(CREATEBUF, EPMDMBUFFER, min(size,MAXBUFSIZE), 1)
  453.    endif
  454.    if not DMbuf_handle then
  455.       messageNwait(CAN_NOT_OPEN__MSG EPMDMBUFFER '-' ERROR_NUMBER__MSG RC)
  456.       return
  457.    endif
  458.  
  459.    getfileid fileid                    /* save file id of visible file      */
  460.    activatefile mkfileid               /* switch to file with mark          */
  461.    /* Copy the current marked lines (up to 64k worth of data ) into EPM's */
  462.    /* shared memory buffer.                                               */
  463.    call buffer(PUTMARKBUF, DMbuf_handle, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES)
  464.  
  465.    poke DMbuf_handle, 28, atol(lstline-fstline+1)  -- Remember how many lines are *supposed* to be there.
  466.  
  467.    activatefile fileid
  468.  
  469.  
  470. /*
  471. ┌────────────────────────────────────────────────────────────────────────────┐
  472. │ GetDMBuff -                                                                │
  473. │                 Get text from "Delete Mark" buffer.                        │
  474. │                                                                            │
  475. │                                                                            │
  476. └────────────────────────────────────────────────────────────────────────────┘
  477. */
  478. defc GetDMBuff
  479.    universal DMbuf_handle
  480.    -- Try to open the buffer.  If it doesn't exist, nothing to get.
  481. ;; DMbuf_handle = buffer(OPENBUF, EPMDMBUFFER)
  482. ;; -- (If it doesn't exist in this window, the lines were deleted from some other window.)
  483.    if not DMbuf_handle then
  484. ;;    sayerror 'Unable to open a buffer named' EPMDMBUFFER'.  Error number 'RC
  485.       sayerror NO_MARK_DELETED__MSG
  486.       return
  487.    endif
  488.    call psave_mark(savemark)                              -- Save the user's mark
  489.    call GetBuffCommon(DMbuf_handle, NO_TEXT_RECOVERED__MSG)  -- (This marks what's recovered)
  490.    call prestore_mark(savemark)                           -- Restore the user's mark
  491. compile endif  -- WANT_DM_BUFFER
  492.  
  493.  
  494. /*
  495. ┌────────────────────────────────────────────────────────────────────────────┐
  496. │ GetBuffCommon                                                              │
  497. │                 Common code called by GetSharBuff, Paste and GetDMBuff     │
  498. │                                                                            │
  499. └────────────────────────────────────────────────────────────────────────────┘
  500. */
  501. defproc GetBuffCommon(bufhndl, errormsg)
  502.    markt = buffer(MARKTYPEBUF, bufhndl)
  503.    getfileid activefid                  -- get current files file id
  504.    if not markt & arg(3)<>'O' then      -- MARKT=0 ==> line mark (simple case)
  505.       noflines = buffer(GETBUF, bufhndl)   -- Retrieve data from shared EPM buf
  506.       if noflines then
  507.          call pset_mark(.line+1,.line+noflines,1,MAXCOL,'LINE',activefid)
  508.          '+'noflines
  509.          call verify_buffer_size(bufhndl, noflines)
  510.       else
  511.          sayerror errormsg
  512.       endif
  513.       return                            -- ... and that's all.
  514.    endif
  515.  
  516.    cur_line_len = length(textline(.line))
  517.    'xcom e /q /c epmbuff.cpy'           -- edit a temp hidden file
  518.    .visible=0                           -- (hide file)
  519.    getfileid tmpfileid                  -- get hidden file's id
  520.  
  521. compile if EVERSION >= 5.50
  522.    noflines = buffer(GETBUF2, bufhndl)  -- retrieve data from shared EPM buf
  523. compile else
  524.    noflines = buffer(GETBUF, bufhndl)   -- retrieve data from shared EPM buf
  525. compile endif -- EVERSION >= 5.50
  526. compile if 0 -- EVERSION >= 5.50
  527.    if arg(3)='C' then
  528.       noflines = buffer(GETBUF2, bufhndl)  -- retrieve data from shared EPM buf
  529.    else
  530. ;compile endif
  531. ;      noflines = buffer(GETBUF, bufhndl)   -- retrieve data from shared EPM buf
  532. ;compile if EVERSION >= 5.50
  533.    endif
  534. compile endif
  535.    if not noflines then
  536.       'xcom quit'
  537.       sayerror errormsg
  538.       return
  539.    endif
  540. compile if EVERSION < 5.50
  541.    insert_attribute 13, 0, 2, 0, activefid.col, activefid.line, activefid  -- Place a bookmark on the character
  542. compile endif
  543.  
  544. compile if EVERSION >= 5.50
  545.    orig_lines = ltoa(peek(bufhndl,28,4),10)
  546.  compile if EVERSION = 5.50
  547.    if orig_lines & orig_lines = noflines-1 & markt = 2 & textline(.last)==\0 then  -- Block mark?  Get rid of extra blank line
  548.  compile else
  549.    if orig_lines & orig_lines = noflines-1 & markt = 2 & textline(.last)=='' then  -- Block mark?  Get rid of extra blank line
  550.  compile endif
  551.       noflines = noflines-1
  552.       deleteline .last
  553.    endif
  554. compile endif
  555.    length_last = length(textline(.last))
  556.    split_start = 0; split_end = 0
  557.    '+1'                              -- advance to next line in hidden
  558.    if markt=2 | markt=4 then            -- Mark type is BLOCK(G)
  559.       markblock                         -- block mark first character
  560.       noflines+1                        -- advance down to last line
  561.       if arg(3)='B' then                -- Block-marking from clipboard;
  562.          .col=longestline()             -- move cursor to end of longest line
  563.       else                              -- Was originally a block; width is OK.
  564.          .col=length_last               -- move to last character
  565.       endif
  566.       markblock                         -- complete block mark
  567.    elseif markt=1 | markt=3 then        -- Mark type is Character(G)
  568.       split_start = activefid.col + length(textline(2)) > MAXCOL
  569.       split_end = cur_line_len - activefid.col + length_last > MAXCOL
  570. compile if EVERSION >= 5.50
  571.       setmark 2, .last, 1, length_last+1, 3, tmpfileid  -- 3 = CHARG mark
  572. compile else
  573.       mark_char                         -- character mark first char
  574.       noflines+1                        -- advance down to last
  575.       .col=length_last                  -- move to last character
  576.       mark_char                         -- complete character mark
  577. compile endif
  578.    else
  579.       mark_line                         -- line mark first line
  580.       noflines+1                        -- advance down to last
  581.       mark_line                         -- complete line mark
  582.    endif
  583.  
  584.    activatefile activefid               -- activate destination file
  585.    rc=0                                 -- clear return code before copy
  586.    if arg(3)='O' then
  587. compile if WANT_CHAR_OPS
  588.       call pcommon_adjust_overlay('O')  -- copy mark
  589. compile else
  590.       overlay_block
  591. compile endif
  592.    else
  593.       if split_end then split; endif
  594.       if split_start then split; '+1'; begin_line; endif
  595.       call pcopy_mark()                 -- copy mark
  596.    endif
  597.    if rc then                           -- Test for memory too full for copy_mark.
  598.       display -4
  599.       sayerror ERROR_COPYING__MSG
  600.       display 4
  601.    endif
  602.  
  603.    activatefile tmpfileid               -- activate temp file
  604.    'xcom q'                             -- quit it
  605.    activatefile activefid               -- activate destination file
  606. compile if EVERSION < 5.50
  607.    class = 13  -- BOOKMARK_CLASS
  608.    col=.col+1; line=.line; offst=0
  609.    attribute_action 1, class, offst, col, line  -- 1=FIND NEXT ATTR
  610.    if class=13 then
  611.       query_attribute class, val, IsPush, offst, col, line
  612.       line; .col=col
  613.       attribute_action 16, class, offst, col, line -- 16=Delete attribute
  614.    endif
  615. compile else  -- 5.50 does char marks internally, so moving to the end of the mark will always work.
  616.    call pend_mark()
  617. ;  sayerror 'length_last='length_last'; .col='.col'; cl1, cl2 =' cl1 cl2
  618.    if length_last then executekey right; endif
  619. compile endif
  620.    call verify_buffer_size(bufhndl, noflines)
  621.  
  622. defproc verify_buffer_size(bufhndl, noflines)
  623.    orig_lines = ltoa(peek(bufhndl,28,4),10)
  624.    if orig_lines <> noflines & orig_lines then  -- If 0, assume never set.
  625.       display -4
  626.       sayerror ONLY__MSG noflines LINES_OF__MSG orig_lines RECOVERED__MSG
  627.       display 4
  628.    endif
  629.  
  630. defc clipview =
  631.    if not clipcheck(format) then
  632.       sayerror CLIPBOARD_ERROR__MSG
  633.       return
  634.    endif
  635.    if format<>256 then                 -- no text in clipboard
  636.       sayerror CLIPBOARD_EMPTY__MSG
  637.       return
  638.    endif
  639.    "open 'paste C' 'postme clipview2'"
  640.  
  641. defc clipview2 =
  642.    if .filename=UNNAMED_FILE_NAME then
  643.       .filename=CLIPBOARD_VIEW_NAME
  644.       .autosave = 0
  645.       .modify = 0
  646.       call browse(1)
  647.    endif
  648.  
  649. defproc clipcheck(var format)  -- Returns error code; if OK, sets FORMAT
  650. compile if EPM32
  651.    hab=gethwndc(0)                         -- get EPM's anchorblock
  652.    format = \0\0\0\0                       -- (reserve four bytes)
  653.    rc=dynalink32('PMWIN',                   -- call PM function to
  654.                  '#807',   -- look at the data in the cb
  655.                  hab              ||         -- anchor block
  656.                  atol(1)          ||         -- data format ( TEXT )
  657.                  address(format), 4)
  658. --   format = ltoa(format,10)                -- Convert format to ASCII
  659.    format = 1024
  660. compile else
  661.    hab=gethwnd(0)                          -- get EPM's anchorblock
  662.    format = \0\0                           -- (reserve two bytes)
  663.    rc=dynalink('PMWIN',                    -- call PM function to
  664.                'WINQUERYCLIPBRDFMTINFO',   -- look at the data in the cb
  665.                hab              ||         -- anchor block
  666.                atoi(1)          ||         -- data format ( TEXT )
  667.                address(format))
  668. --   format = itoa(format,10)                -- Convert format to ASCII
  669.    format = 256
  670. compile endif
  671.    return rc
  672.  
  673. compile if EVERSION >= 5.50
  674. defc insert_text_file
  675.    universal default_edit_options
  676.    get_file = strip(arg(1))
  677.    if get_file='' then sayerror NO_FILENAME__MSG 'GET'; return; endif
  678.    if pos(argsep,get_file) then
  679.       sayerror INVALID_OPTION__MSG
  680.       return
  681.    endif
  682.    getfileid fileid
  683.    s_last=.last
  684.    display -1
  685.    'e /q /d' get_file
  686.    editrc=rc
  687.    getfileid gfileid
  688.    if editrc=sayerror('New file') | not .last then
  689.       'q'
  690.       display 1
  691.       if editrc= -2 | not .last then  -- -2 = sayerror('New file') then
  692.          sayerror FILE_NOT_FOUND__MSG':  'get_file
  693.       else
  694.          sayerror FILE_NOT_FOUND__MSG':  'get_file
  695.       endif
  696.       return
  697.    endif
  698.    if editrc & editrc<>-278 then  -- -278  sayerror('Lines truncated') then
  699.       display 1
  700.       sayerror editrc
  701.       stop
  702.    endif
  703.    call psave_mark(save_mark)
  704. compile if WANT_BOOKMARKS
  705.    if not .levelofattributesupport then
  706.       'loadattributes'
  707.    endif
  708. compile endif
  709.    get_file_attrib = .levelofattributesupport
  710.    setmark 1, .last, 1, length(textline(.last))+1, 3, gfileid  -- 3 = CHARG mark
  711.    activatefile fileid
  712.    rc=0
  713.    copy_mark
  714.    copy_rc=rc           -- Test for memory too full for copy_mark.
  715.    activatefile gfileid
  716.    'q'
  717.    parse value save_mark with s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt
  718.    if fileid=s_mkfileid then           -- May have to move the mark.
  719.       diff=fileid.last-s_last          -- (Adjustment for difference in size)
  720.       if fileid.line<s_firstline then s_firstline=s_firstline+diff; endif
  721.       if fileid.line<s_lastline then s_lastline=s_lastline+diff; endif
  722.    endif
  723.    call prestore_mark(s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt)
  724.    activatefile fileid
  725.    if get_file_attrib // 2 then
  726.       call attribute_on(1)  -- Colors flag
  727.    endif
  728.    if get_file_attrib % 4 - 2 * (get_file_attrib % 8) then
  729.       call attribute_on(4)  -- Mixed fonts flag
  730.    endif
  731.    if get_file_attrib % 8 - 2 * (get_file_attrib % 16) then
  732.       call attribute_on(8)  -- "Save attributes" flag
  733.    endif
  734.    display 1
  735.    if copy_rc & copy_rc<>-281 then
  736.       sayerror NOT_2_COPIES__MSG get_file
  737.    endif
  738. compile endif
  739.