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