home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / clarion / brokcode.zip / MEMOEDIT.EXE / MEMOEDIT.CLA < prev    next >
Text File  |  1991-12-05  |  32KB  |  772 lines

  1.  
  2. !═════════════════════════════════════════════════════════════════════════
  3. !
  4. !  'MEMOEDIT.CLA' - Clarion Memo Field Editor
  5. !
  6. !  Revision Number: '1'
  7. !  Revision Date  : '21-Sep-91'
  8. !
  9. !  Copyright : Bobcat Systems (c) 1991
  10. !  Author    : Robert J. Pupazzoni
  11. !           CIS:[70441,204]
  12. !
  13. !  Compiler  : Clarion Professional Developer v.2.1, Batch 2105
  14. !
  15. !
  16. !  BACKGROUND
  17. !
  18. !    I wrote this because of my frustration with Eckenroed's MEMO3 product.
  19. !    While MEMO3 does what it claims to do, it is quite inflexible and a real
  20. !    memory hog (>30K BIN file).  This was not acceptable for the app I was
  21. !    writing at the time, so MEMOEDIT is my attempt to rectify the situation.
  22. !
  23. !  DESCRIPTION
  24. !
  25. !    This module replaces the standard Clarion memo field editing.  It adds the
  26. !    following features:
  27. !
  28. !       Dynamic word wrapping and paragraph reformatting
  29. !
  30. !       Block operations: Copy, Move, Delete
  31. !
  32. !       NOT a LEM - Written entirely in Clarion, so it can be put in an
  33. !     overlay.
  34. !
  35. !       Since it's all in Clarion, you can add as many Hot Keys, features
  36. !     etc. as you want.
  37. !
  38. !
  39. !═════════════════════════════════════════════════════════════════════════
  40.  
  41.          MEMBER()
  42.  
  43. !═════════════════════════════════════════════════════════════════════════
  44. !               Edit a memo field
  45. !═════════════════════════════════════════════════════════════════════════
  46. MemoEdit     FUNCTION( xMemo, xLine, ibRow, ibMaxRows )
  47.  
  48.          ! Parameters:
  49. xMemo         EXTERNAL,DIM(1)             ! Memo field
  50. xLine         EXTERNAL                 ! Screen string for edit
  51. ibRow         EXTERNAL                 ! Repeat index for screen
  52. ibMaxRows    BYTE                 ! # of rows on screen
  53.  
  54.          ! Return:
  55. bbModified   BYTE                 ! Modified flag
  56.  
  57.          ! Equates:
  58. eMarkedFG    EQUATE(14)                 ! Foreground for marked text
  59. eMarkedBG    EQUATE(4)                 ! Background for marked text
  60. eHelpID         EQUATE('MEMOEDIT')             ! Help screen ID
  61.  
  62.          ! Locals:
  63. tTable         TABLE,PRE(TAB)             ! Edit table
  64.            STRING(255)             !
  65.          .                     !
  66.  
  67. tHold         TABLE,PRE(HLD)             ! Hold area for block ops.
  68.            STRING(255)             !
  69.          .                     !
  70.  
  71. sCursorSize  STRING('<07><06><07><04>')         ! Cursor sizes
  72. aCursorSize  SHORT,DIM(2),OVER(sCursorSize)     !
  73.  
  74. gRegisters   GROUP                 ! CPU Registers
  75. isAX           SHORT                 !
  76. isBX           SHORT                 !
  77. isCX           SHORT                 !
  78. isDX           SHORT                 !
  79. isSI           SHORT                 !
  80. isDI           SHORT                 !
  81. isDS           SHORT                 !
  82. isES           SHORT                 !
  83. ibInt           BYTE                 !
  84. isFlags           SHORT                 !
  85.          .                     !
  86.  
  87. ilMemoRows   LONG                 ! Total rows in memo field
  88.  
  89. ibRowOfs     BYTE                 ! Screen field row offset
  90. ibColOfs     BYTE                 ! Screen field column offset
  91. ilRowTop     LONG                 ! Index of top displayed line
  92. ibCol         BYTE                 ! Cursor column
  93.  
  94. ibMaxCols    BYTE                 ! Max. displayable columns
  95. ibWrapCol    BYTE                 ! Column to word-wrap on
  96.  
  97. isKeystroke  SHORT                 ! Last keystroke
  98. bbInsertMode BYTE                 ! Insert mode flag
  99.  
  100. sTemp         STRING(255)             ! Temporary line buffer
  101.  
  102. ilMarkBegRow LONG                 ! Start row of marked block
  103. ibMarkBegCol BYTE                 ! Start column of marked block
  104. ilMarkEndRow LONG                 ! End row of marked block
  105. ibMarkEndCol BYTE                 ! End column of marked block
  106. bbMarking    BYTE                 ! Marking mode flag
  107.  
  108. ilAbsTarget  LONG                 ! Temporaries used in block
  109. ilAbsMrkBeg  LONG                 ! operations
  110. ilAbsMrkEnd  LONG                 !
  111. ibHiCol1     BYTE                 ! Hilight column start
  112. ibHiCol2     BYTE                 ! Hilight column end
  113.  
  114. ilTblNdx     LONG                 ! Edit table index
  115. ilHoldNdx    LONG                 ! Hold table index
  116. ilMemoNdx    LONG                 ! Memo array index
  117. ibColNdx     BYTE                 ! Column index
  118. ibLineNdx    BYTE                 ! Line index
  119.  
  120.   CODE
  121.   bbModified   = 0                 ! Clear modified flag
  122.   bbInsertMode = 1                 ! Set Insert mode ON
  123.   ibRow           = 1                 ! Start on first row
  124.   ibCol           = 1                 ! Start in first column
  125.  
  126.   ilMemoRows = MAXIMUM(xMemo[],1)         ! Set row/column values
  127.   ibRowOfs   = ROW(xLine) - 1             !
  128.   ibColOfs   = COL(xLine) - 1             !
  129.   ibMaxCols  = COLS(xLine)             !
  130.   ibWrapCol  = ibMaxCols - 1             !
  131.  
  132.   ilMarkBegRow = 0                 ! Reset marked block values
  133.   ibMarkBegCol = 0                 !
  134.   ilMarkEndRow = 0                 !
  135.   ibMarkEndCol = 0                 !
  136.   bbMarking    = 0                 !
  137.  
  138.   HELP(,eHelpID)                 ! Set the help window
  139.  
  140.   DO LoadMemo                     ! Load memo into table
  141.   DO First_Page                     ! Display first page
  142.   DO EditLoop                     ! Edit the memo
  143.   DO SaveMemo                     ! Save table to memo field
  144.  
  145.   HELP(,'')                     ! Deactivate help window
  146.   SETCURSOR                     ! Turn offf cursor
  147.   FREE(tTable)                     ! Clean up
  148.   FREE(tHold)                     !
  149.   RETURN(bbModified)                 ! Return modified flag
  150.  
  151. !──────────────────────────────────────────────────────────────────────────
  152. EditLoop     ROUTINE      ! Main edit loop
  153. !──────────────────────────────────────────────────────────────────────────
  154.   LOOP                         ! Loop
  155.     SETCURSOR(ibRowOfs+ibRow,ibColOfs+ibCol)     !   Set cursor position
  156.     DO CursorSize                 !   Set cursor size
  157.     ASK                         !   Wait for keystroke
  158.     isKeystroke = KEYCODE()             !   Save it
  159.     CASE isKeystroke                 !   Process action
  160.       OF Esc_Key;    BREAK             !
  161.       OF F1_Key;     HELP             !
  162.  
  163.       OF Left_Key;   DO Move_Left         !   Horizontal movement
  164.       OF Ctrl_Left;  DO MoveW_Left         !
  165.       OF Home_Key;   DO Move_BOL         !
  166.       OF Right_Key;  DO Move_Right         !
  167.       OF Ctrl_Right; DO MoveW_Right         !
  168.       OF End_Key;    DO Move_EOL         !
  169.       OF Tab_Key;    DO Tab_Right         !
  170.  
  171.       OF Up_Key;     DO Move_Up             !   Vertical movement
  172.       OF Down_Key;   DO Move_Down         !
  173.       OF PgUp_Key;   DO Page_Up             !
  174.       OF PgDn_Key;   DO Page_Down         !
  175.       OF Ctrl_PgUp;  DO First_Page         !
  176.       OF Ctrl_PgDn;  DO Last_Page         !
  177.  
  178.       OF Enter_Key;  DO Newline             !   Insertion/deletion
  179.       OF Ins_Key;    DO Toggle_Ins         !
  180.       OF Del_Key;    DO Delete_Char         !
  181.       OF BS_Key;     DO Backspace         !
  182.       OF Ctrl_End;   DO Delete_EOL         !
  183.  
  184.       OF Alt_K;         DO Block_Mark         !   Block operations
  185.       OF Alt_D;         DO Block_Delete         !
  186.       OF Alt_Y;         DO Block_Copy         !
  187.       OF Alt_M;         DO Block_Move         !
  188.  
  189.       OF Alt_O;         sTemp = '°'         !   Special keys
  190.              Do Insert_Str         !
  191.                          !
  192.       OF F4_Key;     sTemp = FORMAT(TODAY(),@D1) !
  193.              Do Insert_Str         !
  194.  
  195.     ELSE
  196.       IF ALERTED(isKeystroke) THEN BREAK.     !   Return on alerted key
  197.       IF INRANGE(isKeystroke,32,255)         !   Printable character
  198.     DO Insert_Char                 !
  199.       ELSE                     !
  200.     BEEP                     !   Garbage
  201.     . .
  202.     IF bbMarking                 !   If marking a block
  203.       ilMarkEndRow = ilRowTop + ibRow         !     Update block end row
  204.       ibMarkEndCol = ibCol             !     Update block end column
  205.       DO Show_Page                 !     Update marking on screen
  206.   . .                         ! End loop
  207.  
  208.  
  209. !
  210. !              Horizontal Movement Routines
  211. !
  212.  
  213. !──────────────────────────────────────────────────────────────────────────
  214. Move_Left    ROUTINE      ! Move cursor left
  215. !──────────────────────────────────────────────────────────────────────────
  216.   IF ibCol > 1                     ! If not at first column
  217.     ibCol -= 1                     !   Move cursor left
  218.   .                         ! Endif
  219.  
  220. !──────────────────────────────────────────────────────────────────────────
  221. MoveW_Left   ROUTINE      ! Move left one word
  222. !──────────────────────────────────────────────────────────────────────────
  223.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  224.   ibColNdx = ibCol - 1                 ! Set column index
  225.   DO Word_Left                     ! Search left
  226.   ibCol = ibColNdx                 ! Set new cursor postion
  227.  
  228. !──────────────────────────────────────────────────────────────────────────
  229. Move_BOL     ROUTINE      ! Move to beginning of line
  230. !──────────────────────────────────────────────────────────────────────────
  231.   ibCol = 1                     ! Set to first column
  232.  
  233. !──────────────────────────────────────────────────────────────────────────
  234. Move_Right   ROUTINE      ! Move cursor right
  235. !──────────────────────────────────────────────────────────────────────────
  236.   IF ibCol < ibMaxCols                 ! If not on last column
  237.     ibCol += 1                     !   Move cursor right
  238.   .                         ! Endif
  239.  
  240. !──────────────────────────────────────────────────────────────────────────
  241. MoveW_Right  ROUTINE      ! Move right one word
  242. !──────────────────────────────────────────────────────────────────────────
  243.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  244.   ibColNdx = ibCol                 ! Set column index
  245.   DO Word_Right                     ! Search right
  246.   ibCol = ibColNdx                 ! Set new cursor postion
  247.  
  248. !──────────────────────────────────────────────────────────────────────────
  249. Move_EOL     ROUTINE
  250. !──────────────────────────────────────────────────────────────────────────
  251.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  252.   ibCol = LEN(CLIP(tTable)) + 1             ! Set cursor to last character
  253.   IF ibCol > ibMaxCols
  254.     ibCol = ibMaxCols
  255.   .
  256.  
  257. !──────────────────────────────────────────────────────────────────────────
  258. Tab_Right    ROUTINE
  259. !──────────────────────────────────────────────────────────────────────────
  260.   ibCol = 8 * (ibCol/8 + 1)             ! Calculate new tab column
  261.   IF ibCol > ibMaxCols                 ! If past end of screen
  262.     ibCol = ibMaxCols                 !   Fix cursor positionn
  263.   .                         ! Endif
  264.  
  265.  
  266. !
  267. !            Vertical Movement Routines
  268. !
  269.  
  270. !──────────────────────────────────────────────────────────────────────────
  271. Move_Up         ROUTINE      ! Move one line up
  272. !──────────────────────────────────────────────────────────────────────────
  273.   IF ilRowTop + ibRow = 1 THEN EXIT.         ! Exit if at first record
  274.   IF ibRow > 1                     ! If not at first screen row
  275.     ibRow -= 1                     !   Move cursor up
  276.   ELSE                         ! Else
  277.     ilRowTop -= 1                 !   Scroll up
  278.     SCROLL(ibRowOfs+1,ibColOfs+1,ibMaxRows,ibMaxCols,-1)
  279.     GET(tTable,ilRowTop+1)             !   Fill top line
  280.     DO Show_Line                 !
  281.   .                         ! Endif
  282.  
  283. !──────────────────────────────────────────────────────────────────────────
  284. Move_Down    ROUTINE      ! Move one line down
  285. !──────────────────────────────────────────────────────────────────────────
  286.   IF ilRowTop+ibRow = RECORDS(tTable) THEN EXIT. ! Exit if at last record
  287.   IF ibRow < ibMaxRows                 ! If not at last screen row
  288.     ibRow += 1                     !   Move cursor down
  289.   ELSE                         ! Else
  290.     ilRowTop += 1                 !   Scroll down
  291.     SCROLL(ibRowOfs+1,ibColOfs+1,ibMaxRows,ibMaxCols,1)
  292.     GET(tTable,ilRowTop+ibRow)             !   Fill bottom line
  293.     DO Show_Line                 !
  294.   .                         ! Endif
  295.  
  296. !──────────────────────────────────────────────────────────────────────────
  297. First_Page   ROUTINE      ! Display first page
  298. !──────────────────────────────────────────────────────────────────────────
  299.   ilRowTop = 0                     ! Reset top row
  300.   ibRow       = 1                     ! Move cursor to top line
  301.   DO Show_Page                     ! Display the page
  302.  
  303. !──────────────────────────────────────────────────────────────────────────
  304. Last_Page    ROUTINE      ! Display last page
  305. !──────────────────────────────────────────────────────────────────────────
  306.   IF RECORDS(tTable) > ibMaxRows         ! If more records than rows
  307.     ilRowTop = RECORDS(tTable) - ibMaxRows     !   Set top row
  308.     ibRow    = ibMaxRows             !   Set cursor row
  309.   ELSE                         ! Else
  310.     ilRowTop = 0                 !   Set top row
  311.     ibRow    = RECORDS(tTable)             !   Set cursor row
  312.   .                         ! Endif
  313.   DO Show_Page                     ! Display page
  314.  
  315. !──────────────────────────────────────────────────────────────────────────
  316. Page_Up         ROUTINE      ! Scroll one page up
  317. !──────────────────────────────────────────────────────────────────────────
  318.   IF ilRowTop > ibMaxRows             ! If previous page exists
  319.     ilRowTop -= ibMaxRows             !   Display previous page
  320.     DO Show_Page                 !
  321.   ELSE                         ! Else
  322.     DO First_Page                 !  Display first page
  323.   .                         ! Endif
  324.  
  325. !──────────────────────────────────────────────────────────────────────────
  326. Page_Down    ROUTINE      ! Scroll one page down
  327. !──────────────────────────────────────────────────────────────────────────
  328.   IF ilRowTop + ibMaxRows >= RECORDS(tTable)     ! Exit if no next page
  329.     EXIT                     !
  330.   .                         !
  331.   ilRowTop += ibMaxRows                 ! Set to next page
  332.   IF ilRowTop + ibRow > RECORDS(tTable)         ! If past last record
  333.     ibRow = RECORDS(tTable) - ilRowTop         !   Fix cursor position
  334.   .                         ! Endif
  335.   DO Show_Page                     ! Display page
  336.  
  337.  
  338. !
  339. !            Insertion and Deletion Routines
  340. !
  341.  
  342. !──────────────────────────────────────────────────────────────────────────
  343. Toggle_Ins   ROUTINE      ! Toggle insert/overwrite mode
  344. !──────────────────────────────────────────────────────────────────────────
  345.   bbInsertMode = BXOR(bbInsertMode,1)         ! Toggle insert flag
  346.  
  347. !──────────────────────────────────────────────────────────────────────────
  348. Newline         ROUTINE      ! Insert a new line, or go to BOL of next line
  349. !──────────────────────────────────────────────────────────────────────────
  350.   bbModified = 1                 ! Set modified flag
  351.   IF bbInsertMode                 ! If insert mode
  352.     DO Split                     !   Split current line
  353.   ELSE                         ! Else
  354.     DO Move_BOL                     !   Move to start-of-line
  355.     DO Move_Down                 !   Move to next line
  356.   .                         ! Endif
  357.  
  358. !──────────────────────────────────────────────────────────────────────────
  359. Insert_Char  ROUTINE      ! Insert a character
  360. !──────────────────────────────────────────────────────────────────────────
  361.   sTemp = CHR(isKeystroke)             ! Set to last char typed
  362.   DO Insert_Str                     ! Insert into text
  363.  
  364. !──────────────────────────────────────────────────────────────────────────
  365. Insert_Str   ROUTINE      ! Insert a string
  366. !──────────────────────────────────────────────────────────────────────────
  367.   bbModified = 1                 ! Set modified flag
  368.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  369.   ibColNdx = ibCol + BXOR(bbInsertMode,1)     ! Set insert/overwrite column
  370.   IF CLIP(sTemp)                 ! If string not empty
  371.     tTable = SUB(tTable,1,ibCol-1) & |         !   Insert string
  372.          CLIP(sTemp)       & |         !
  373.          SUB(tTable,ibColNdx,255)         !
  374.     ibCol += LEN(CLIP(sTemp))             !   Move cursor
  375.   ELSE                         ! Else
  376.     tTable = SUB(tTable,1,ibCol-1) & |         !   Insert space
  377.          ' '           & |         !
  378.          SUB(tTable,ibColNdx,255)         !
  379.     ibCol += 1                     !   Move cursor
  380.   .                         ! Endif
  381.   PUT(tTable)                     ! Update line table
  382.   DO Show_Line                     ! Refresh display
  383.  
  384.   IF ibCol > ibWrapCol+1             ! If past wrap column
  385.     DO WordWrap                     !   Perform word wrap
  386.   ELSIF LEN(CLIP(tTable)) > ibWrapCol         ! Else if line is too long
  387.     DO Reformat                     !   Reformat paragraph
  388.   .                         ! Endif
  389.  
  390. !──────────────────────────────────────────────────────────────────────────
  391. Delete_Char  ROUTINE      ! Delete character under cursor
  392. !──────────────────────────────────────────────────────────────────────────
  393.   bbModified = 1                 ! Set modified flag
  394.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  395.   IF ibCol > LEN(CLIP(tTable))             ! If EOL
  396.     DO Join                     !   Join next line
  397.   ELSE                         ! Else
  398.     tTable = SUB(tTable,1,ibCol-1) & |         !   Delete cursor char.
  399.          SUB(tTable,ibCol+1,255)         !
  400.     PUT(tTable)                     !   Update line
  401.     DO Show_Line                 !   Refresh display
  402.     DO Backfill                     !   Backfill empty space
  403.   .                         ! Endif
  404.  
  405. !──────────────────────────────────────────────────────────────────────────
  406. Backspace    ROUTINE      ! Delete character before cursor
  407. !──────────────────────────────────────────────────────────────────────────
  408.   IF ibCol > 1                     ! If not at BOL
  409.     ibCol -= 1                     !   Move cursor left
  410.     DO Delete_Char                 !   Delete char under cursor
  411.   .                         ! Endif
  412.  
  413. !──────────────────────────────────────────────────────────────────────────
  414. Delete_EOL   ROUTINE      ! Delete to end-of-line
  415. !──────────────────────────────────────────────────────────────────────────
  416.   bbModified = 1                 ! Set modified flag
  417.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  418.   tTable = SUB(tTable,1,ibCol-1)         ! Delete after cursor
  419.   PUT(tTable)                     ! Update line table
  420.   DO Show_Line                     ! Refresh display
  421.   DO Backfill                     ! Fill in empty space
  422.  
  423. !──────────────────────────────────────────────────────────────────────────
  424. Split         ROUTINE      ! Split line at cursor position
  425. !──────────────────────────────────────────────────────────────────────────
  426.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  427.   sTemp     = SUB(tTable,ibCol,255)         ! Save text after cursor
  428.   tTable = SUB(tTable,1,ibCol-1)         ! Delete part after cursor
  429.   PUT(tTable)                     ! Update line table
  430.   DO Show_Line                     ! Refresh display
  431.   tTable = sTemp                 ! Create a new line
  432.   ADD(tTable,ilRowTop+ibRow+1)             ! with saved text
  433.   DO Move_BOL                     ! Move to BOL
  434.   DO Move_Down                     ! Move down
  435.   DO Show_Partial                 ! Refresh display
  436.  
  437. !──────────────────────────────────────────────────────────────────────────
  438. Join         ROUTINE      ! Join next line with current line
  439. !──────────────────────────────────────────────────────────────────────────
  440.   GET(tTable,ilRowTop+ibRow+1)             ! Get next line
  441.   IF ERRORCODE() THEN EXIT.             ! Exit if not found
  442.   sTemp = tTable                 ! Save text
  443.   DELETE(tTable)                 ! Delete line
  444.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  445.   tTable = CLIP(tTable) & ' ' & sTemp         ! Join lines
  446.   PUT(tTable)                     ! Update line table
  447.   DO Show_Partial                 ! Refresh display
  448.   GET(tTable,ilRowTop+ibRow)             ! Get current line
  449.   DO Reformat                     ! Reformat paragraph
  450.  
  451.  
  452. !
  453. !               Word Wrap and Reformatting
  454. !
  455.  
  456. !──────────────────────────────────────────────────────────────────────────
  457. WordWrap     ROUTINE      ! Perform word wrap
  458. !──────────────────────────────────────────────────────────────────────────
  459.   IF isKeystroke = VAL(' ')             ! If last char was space
  460.     ibCol = 1                     !   Move cursor to 1st column
  461.   ELSE                         ! Else
  462.     ibColNdx = ibCol                 !   Find breakpoint
  463.     DO Word_Left                 !
  464.     sTemp = SUB(tTable,ibColNdx,255)         !
  465.     ibCol = LEN(CLIP(sTemp)) + 1         !   Move cursor to new pos.
  466.     DO Reformat                     !   Reformat the paragraph
  467.   .                         ! Endif
  468.   IF ilRowTop+ibRow = RECORDS(tTable)         ! If last line
  469.     CLEAR(tTable); ADD(tTable)             !   Add a new one
  470.   .                         ! Endif
  471.   DO Move_Down                     ! Move cursor down one line
  472.  
  473. !──────────────────────────────────────────────────────────────────────────
  474. Reformat     ROUTINE      ! Reformat paragraph
  475. !──────────────────────────────────────────────────────────────────────────
  476.                          ! Loop for each line
  477.   LOOP ilTblNdx = ilRowTop+ibRow TO RECORDS(tTable)
  478.     IF LEN(CLIP(tTable)) <= ibWrapCol THEN BREAK.!   Break if no wrap needed
  479.     ibColNdx = ibWrapCol+1             !
  480.     DO Word_Left                 !   Find breakpoint
  481.     sTemp  = SUB(tTable,ibColNdx,255)         !   Save excess portion
  482.     tTable = SUB(tTable,1,ibColNdx-1)         !
  483.     PUT(tTable)                     !   Update current line
  484.     GET(tTable,ilTblNdx+1)             !   Get next line
  485.     IF ERRORCODE() OR NOT tTable         !   If not found or empty
  486.       tTable = sTemp                 !     Create a new one
  487.       ADD(tTable,ilTblNdx+1)             !
  488.     ELSE                     !   Else
  489.       tTable = CLIP(sTemp) & ' ' & tTable     !     Add saved section
  490.       PUT(tTable)                 !     Update line
  491.   . .                         ! End loop
  492.   DO Show_Partial                 ! Refresh display
  493.  
  494. !──────────────────────────────────────────────────────────────────────────
  495. Backfill     ROUTINE      ! Backfill line
  496. !──────────────────────────────────────────────────────────────────────────
  497.     GET(tTable,ilRowTop+ibRow+1)         ! Get next line
  498.     IF ERRORCODE() OR NOT tTable THEN EXIT.     ! Exit if empty or not found
  499.     sTemp = tTable                 ! Save contents
  500.     DELETE(tTable)                 ! Delete line
  501.     GET(tTable,ilRowTop+ibRow)             ! Get current line
  502.     tTable = CLIP(tTable) & ' ' & sTemp         ! Append saved section
  503.     PUT(tTable)                     ! Update line
  504.     DO Reformat                     ! Reformat paragraph
  505.  
  506. !──────────────────────────────────────────────────────────────────────────
  507. Word_Left    ROUTINE      ! Search for next word to left
  508. !──────────────────────────────────────────────────────────────────────────
  509.   LOOP WHILE (ibColNdx > 0)             ! Loop
  510.     IF SUB(tTable,ibColNdx,1) <> '  ' THEN BREAK.!   Break on non-space
  511.     ibColNdx -= 1                 !   Decrement column index
  512.   .                         ! End loop
  513.   LOOP WHILE (ibColNdx > 0)             ! Loop
  514.     IF SUB(tTable,ibColNdx,1) = '  ' THEN BREAK. !   Break on space
  515.     ibColNdx -= 1                 !   Decrement column index
  516.   .                         ! End loop
  517.   ibColNdx += 1                     ! Adjust column index
  518.  
  519. !──────────────────────────────────────────────────────────────────────────
  520. Word_Right   ROUTINE      ! Search for next word to right
  521. !──────────────────────────────────────────────────────────────────────────
  522.   LOOP WHILE (ibColNdx <= LEN(CLIP(tTable)))     ! Loop
  523.     IF SUB(tTable,ibColNdx,1) = '  ' THEN BREAK. !   Break on space
  524.     ibColNdx += 1                 !   Increment column index
  525.   .                         ! End loop
  526.   LOOP WHILE (ibColNdx <= LEN(CLIP(tTable)))     ! Loop
  527.     IF SUB(tTable,ibColNdx,1) <> '  ' THEN BREAK.!   Break on non-space
  528.     ibColNdx += 1                 !   Increment column index
  529.   .                         ! End loop
  530.  
  531.  
  532. !
  533. !               Block Operation Routines
  534. !
  535.  
  536. !──────────────────────────────────────────────────────────────────────────
  537. Block_Mark   ROUTINE      ! Toggle block marking on/off
  538. !──────────────────────────────────────────────────────────────────────────
  539.   IF NOT bbMarking                 ! If not in marking mode
  540.     ilMarkBegRow = ilRowTop + ibRow         !   Set block start
  541.     ibMarkBegCol = ibCol             !
  542.     ilMarkEndRow = ilMarkBegRow             !   Set block end
  543.     ibMarkEndCol = ibMarkBegCol             !
  544.     bbMarking = 1                 !   Turn marking mode on
  545.   ELSE                         ! Else
  546.     bbMarking = 0                 !   Turn marking mode off
  547.   .                         ! Endif
  548.  
  549. !──────────────────────────────────────────────────────────────────────────
  550. Block_Unmark ROUTINE      ! Unmark any marked blocks
  551. !──────────────────────────────────────────────────────────────────────────
  552.   bbMarking    = 0                 ! Turn marking off
  553.   ilMarkBegRow = 0                 ! Clear mark locations
  554.   ibMarkBegCol = 0                 !
  555.   ilMarkEndRow = 0                 !
  556.   ibMarkEndCol = 0                 !
  557.   DO Show_Page                     ! Refresh screen
  558.  
  559. !──────────────────────────────────────────────────────────────────────────
  560. Block_Delete ROUTINE      ! Delete marked block
  561. !──────────────────────────────────────────────────────────────────────────
  562.   IF NOT ilMarkBegRow THEN EXIT.         ! Exit if nothing marked
  563.  
  564.   bbModified = 1                 ! Set modified flag
  565.   DO CutBlock                     ! Delete block
  566.   IF INRANGE(ilMarkBegRow,ilRowTop+1,ilRowTop+ibMaxRows)
  567.     ibRow = ilMarkBegRow - ilRowTop         ! Update cursor position
  568.     ibCol = ibMarkBegCol             !
  569.   .                         !
  570.   DO Block_Unmark                 ! Unmark the block
  571.   DO BackFill                     ! Backfill empty space
  572.  
  573. !──────────────────────────────────────────────────────────────────────────
  574. Block_Copy   ROUTINE      ! Copy marked block to cursor location
  575. !──────────────────────────────────────────────────────────────────────────
  576.   IF NOT ilMarkBegRow THEN EXIT.         ! Exit if nothing marked
  577.  
  578.   ilAbsTarget = 255 * (ilRowTop+ibRow) + ibCol     ! Calculate absolute locations
  579.   ilAbsMrkBeg = 255 * ilMarkBegRow + ibMarkBegCol!
  580.   ilAbsMrkEnd = 255 * ilMarkEndRow + ibMarkEndCol!
  581.  
  582.   IF INRANGE(ilAbsTarget,ilAbsMrkBeg,ilAbsMrkEnd)! If target in middle of block
  583.     ! Not implemented                 !   Can't do that!
  584.     EXIT                     !   Exit
  585.   .                         ! Endif
  586.  
  587.   bbModified = 1                 ! Set modified flag
  588.   DO CopyToHold                     ! Copy marked block to hold
  589.   DO CopyFromHold                 ! Copy hold to cursor pos.
  590.   DO Block_Unmark                 ! Unmark the block
  591.   DO Reformat                     ! Reformat paragraph
  592.  
  593. !──────────────────────────────────────────────────────────────────────────
  594. Block_Move   ROUTINE      ! Move marked block to cursor location
  595. !──────────────────────────────────────────────────────────────────────────
  596.   IF NOT ilMarkBegRow THEN EXIT.         ! Exit if nothing marked
  597.  
  598.   ilAbsTarget = 255 * (ilRowTop+ibRow) + ibCol     ! Calculate absolute locations
  599.   ilAbsMrkBeg = 255 * ilMarkBegRow + ibMarkBegCol!
  600.   ilAbsMrkEnd = 255 * ilMarkEndRow + ibMarkEndCol!
  601.  
  602.   IF ilAbsTarget < ilAbsMrkBeg             ! If target before block
  603.     DO CopyToHold                 !   Copy marked block to hold
  604.     DO CutBlock                     !   Delete the block
  605.     DO CopyFromHold                 !   Copy hold to cursor pos.
  606.     DO Block_Unmark                 !   Unmark the block
  607.     bbModified = 1                 !   Set modified flag
  608.   ELSIF ilAbsTarget > ilAbsMrkEnd         ! Else if target after block
  609.     DO CopyToHold                 !   Copy marked block to hold
  610.     DO CopyFromHold                 !   Copy hold to cursor pos.
  611.     DO CutBlock                     !   Delete the block
  612.     DO Block_Unmark                 !   Unmark the block
  613.     bbModified = 1                 !   Set modified flag
  614.   ELSE                         ! Else target is inside block
  615.     ! Not implemented                 !   Can't do that!
  616.   .                         ! Endif
  617.  
  618. !──────────────────────────────────────────────────────────────────────────
  619. CopyToHold   ROUTINE      ! Copy the marked block to the hold area
  620. !──────────────────────────────────────────────────────────────────────────
  621.   IF NOT ilMarkBegRow THEN EXIT.         ! Exit if nothing marked
  622.  
  623.   FREE(tHold)                     ! Clear hold area
  624.  
  625.   GET(tTable,ilMarkBegRow)             ! Get first marked line
  626.   IF ilMarkBegRow = ilMarkEndRow         ! If only one line marked
  627.     tHold = SUB(tTable,ibMarkBegCol,ibMarkEndCol-ibMarkBegCol+1)
  628.   ELSE                         ! Else
  629.     tHold = SUB(tTable,ibMarkBegCol,255)     !   Get mark to EOL
  630.   .                         ! Endif
  631.   ADD(tHold)                     ! Copy to hold area
  632.  
  633.   LOOP ilTblNdx = ilMarkBegRow+1 TO ilMarkEndRow-1! Loop thru fully marked lines
  634.     GET(tTable,ilTblNdx)             !   Get line
  635.     tHold = tTable                 !   Copy to hold area
  636.     ADD(tHold)                     !
  637.   .                         ! End loop
  638.  
  639.   IF ilMarkBegRow <> ilMarkEndRow         ! If more than one line marked
  640.     GET(tTable,ilMarkEndRow)             !   Get last marked line
  641.     tHold = SUB(tTable,1,ibMarkEndCol)         !   Isolate marked section
  642.     ADD(tHold)                     !   Copy to hold area
  643.   .                         !
  644.  
  645. !──────────────────────────────────────────────────────────────────────────
  646. CopyFromHold ROUTINE      ! Copy hold area to current cursor position
  647. !──────────────────────────────────────────────────────────────────────────
  648.   IF RECORDS(tHold) = 0 THEN EXIT.         ! Exit if hold is empty
  649.  
  650.   ilTblNdx = ilRowTop + ibRow             ! Get current line index
  651.  
  652.   GET(tHold,1)                     ! Get first hold line
  653.   GET(tTable,ilTblNdx)                 ! Get current line
  654.   sTemp     = SUB(tTable,ibCol,255)         ! Save portion past cursor
  655.   tTable = SUB(tTable,1,ibCol-1) & tHold     ! Insert hold at cursor
  656.   PUT(tTable)                     ! Update line
  657.  
  658.   LOOP ilHoldNdx = 2 TO RECORDS(tHold)-1     ! Loop for each hold line
  659.     GET(tHold,ilHoldNdx)             !   Get hold line
  660.     tTable = tHold                 !   Add to line table
  661.     ilTblNdx += 1                 !   Increment table index
  662.     ADD(tTable,ilTblNdx)             !
  663.   .                         ! End loop
  664.  
  665.   IF RECORDS(tHold) = 1                 ! If only one line in hold
  666.     GET(tTable,ilTblNdx)             !   Get displayed line
  667.     tTable = CLIP(tTable) & sTemp         !   Join line and saved sect.
  668.     PUT(tTable)                     !   Update line table
  669.   ELSE                         ! Else
  670.     GET(tHold,RECORDS(tHold))             !   Get last hold line
  671.     tTable = CLIP(tHold) & sTemp         !   Join hold and saved sect.
  672.     ilTblNdx += 1                 !   Increment table index
  673.     ADD(tTable,ilTblNdx)             !   Add to line table
  674.  .                         ! End if
  675.  
  676. !──────────────────────────────────────────────────────────────────────────
  677. CutBlock     ROUTINE      ! Cut marked block
  678. !──────────────────────────────────────────────────────────────────────────
  679.   GET(tTable,ilMarkEndRow)             ! Get last marked line
  680.   sTemp = SUB(tTable,ibMarkEndCol+1,255)     ! Isolate unmarked section
  681.  
  682.   GET(tTable,ilMarkBegRow)             ! Get first marked line
  683.   tTable = SUB(tTable,1,ibMarkBegCol-1) & sTemp     ! Join unmarked sections
  684.   PUT(tTable)                     ! Update line
  685.  
  686.   LOOP ilTblNdx = ilMarkBegRow+1 TO ilMarkEndRow ! Loop for each marked row
  687.     GET(tTable,ilMarkBegRow+1)             !   Get line
  688.     IF ERRORCODE() THEN CYCLE.             !   Ignore if not found
  689.     DELETE(tTable)                 !   Delete line
  690.   .                         ! End loop
  691.  
  692.  
  693. !
  694. !               Display Routines
  695. !
  696.  
  697. !──────────────────────────────────────────────────────────────────────────
  698. Show_Page    ROUTINE      ! Redisplay entire page
  699. !──────────────────────────────────────────────────────────────────────────
  700.   ibLineNdx = ibRow                 ! Save current row
  701.   LOOP ibRow = 1 TO ibMaxRows             ! Loop thru each row
  702.     GET(tTable,ilRowTop+ibRow)             !   Get line from table
  703.     IF ERRORCODE() THEN CLEAR(tTable).         !   Clear if not found
  704.     DO Show_Line                 !   Display line
  705.   .                         ! End loop
  706.   ibRow = ibLineNdx                 ! Restore current row
  707.  
  708. !──────────────────────────────────────────────────────────────────────────
  709. Show_Partial ROUTINE      ! Redisplay page from current cursor position
  710. !──────────────────────────────────────────────────────────────────────────
  711.   ibLineNdx = ibRow                 ! Save current row
  712.   LOOP ibRow = ibLineNdx TO ibMaxRows         ! Loop thru each row
  713.     GET(tTable,ilRowTop+ibRow)             !   Get line from table
  714.     IF ERRORCODE() THEN CLEAR(tTable).         !   Clear if not found
  715.     DO Show_Line                 !   Display line
  716.   .                         ! End loop
  717.   ibRow = ibLineNdx                 ! Restore current row
  718.  
  719. !──────────────────────────────────────────────────────────────────────────
  720. Show_Line    ROUTINE      ! Display line, including block marks
  721. !──────────────────────────────────────────────────────────────────────────
  722.   xLine = tTable
  723.   IF INRANGE(ilRowTop+ibRow,ilMarkBegRow,ilMarkEndRow)
  724.     ibHiCol1 = ibColOfs + 1
  725.     ibHiCol2 = ibColOfs + ibMaxCols
  726.     IF ilRowTop+ibRow = ilMarkBegRow
  727.       ibHiCol1 = ibColOfs + ibMarkBegCol
  728.     .
  729.     IF ilRowTop+ibRow = ilMarkEndRow
  730.       ibHiCol2 = ibColOfs + ibMarkEndCol
  731.     .
  732.     SETHUE(eMarkedFG,eMarkedBG)
  733.     COLOR(ibRowOfs+ibRow,ibHiCol1,1,ibHiCol2-ibHiCol1+1)
  734.     SETHUE
  735.   .
  736.  
  737. !──────────────────────────────────────────────────────────────────────────
  738. CursorSize   ROUTINE      ! Set cursor size
  739. !──────────────────────────────────────────────────────────────────────────
  740.   CLEAR(gRegisters)                 ! Clear group
  741.   isAX    = 0100H                     ! Set Cursor Size request
  742.   isCX    = aCursorSize[1+bbInsertMode]         ! Select cursor size
  743.   ibInt = 10H                     ! ROM-BIOS Video Services
  744.   Interrupt(gRegisters)                 ! Call interrupt handler
  745.  
  746.  
  747. !
  748. !            Memo Read/Write Routines
  749. !
  750.  
  751. !──────────────────────────────────────────────────────────────────────────
  752. LoadMemo     ROUTINE      ! Load memo field into edit table
  753. !──────────────────────────────────────────────────────────────────────────
  754.   FREE(tTable)                     ! Clear edit table
  755.   LOOP ilMemoNdx = ilMemoRows TO 2 BY -1     ! Loop back thru each line
  756.     IF xMemo[ilMemoNdx] THEN BREAK.         !   Find last non-blank line
  757.   .                         ! End loop
  758.   LOOP ilTblNdx = 1 TO ilMemoNdx         ! Loop for each line
  759.     tTable = xMemo[ilTblNdx]             !   Add to edit table
  760.     ADD(tTable)                     !
  761.   .                         ! End loop
  762.  
  763. !──────────────────────────────────────────────────────────────────────────
  764. SaveMemo     ROUTINE      ! Save edit table back to memo field
  765. !──────────────────────────────────────────────────────────────────────────
  766.   CLEAR(xMemo[])                 ! Clear memo field
  767.   LOOP ilTblNdx = 1 TO RECORDS(tTable)         ! Loop for each record
  768.     GET(tTable,ilTblNdx)             !   Get table line
  769.     xMemo[ilTblNdx] = tTable             !   Add to edit table
  770.   .                         ! End loop
  771.  
  772.