home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / BBS_UTIL / BM0406_A.ZIP / ANSIED.BAS < prev    next >
BASIC Source File  |  1994-04-06  |  50KB  |  1,394 lines

  1. '*
  2. '*  ANSIED v2.44a
  3. '*---------------------------------------------------------------------------
  4. '*  Full Screen Text Editor for RBBS-PC
  5. '*  QuickBASIC v4.5 Version
  6. '*  02-16-91
  7. '*
  8. '*  v2.1xx ... made it work with RBBS v17
  9. '*  v2.2 ..... fixed some inconsistincies in the code as to # of lines in msg.
  10. '*             Some of the code thought 99 was length, some thought 100.
  11. '*  v2.3 ..... let it work with quoted reply.  No more REDIM of ZOutTxt$
  12. '*  v2.4 ..... removed tabs, margins code to be smaller
  13. '*  v2.41..... fixed bug with loss of bold attribute occasionally
  14. '*  v2.42..... made it work as a v17.3 subroutine.  Added block delete.
  15. '*  v2.43..... Added to: and from:.  Made cursor keys work locally.
  16. '*  v2.43a.... Stupid little bugs fixed
  17. '*  v2.44..... Fixed bugs, added ^T, Import, Subject, ASM functions
  18. '*  v2.44a.... Wordwrap/reflow bug fixed.  Arrows work in del.  Lines renum.
  19. '*
  20. '*  Returns:
  21. '*  ZSubParm  =  1 - Save Message
  22. '*            =  2 - Abort Message
  23. '*            = -1 - Dropped Carrier
  24. '*            = -2 - Sleep Disconnect
  25. '*
  26. '* Compile with:
  27. '*   BC C:\RBBSARCS\ANSIED.BAS /O/T/C:512;
  28. '*
  29. '* Modifications to 2.44a by: Steve Stevens
  30. '* If you Like 'em let me know!
  31. '*       FIDONET 1:376/102                     RBBSNet 8:927/2
  32.  
  33. DECLARE SUB Ansied (T$, S$, L%)
  34. DECLARE SUB BackspChar ()
  35. DECLARE SUB CarrRetKey ()
  36. DECLARE SUB ChangeSubject ()
  37. DECLARE SUB ClearScreen ()
  38. DECLARE SUB DeleteCurrentLine (Index%)
  39. DECLARE SUB DisplayKeys ()
  40. DECLARE SUB DisplayMainMenu ()
  41. DECLARE SUB DoneWithMsg (YY$)
  42. DECLARE SUB EraseToEOL (LineNumber%, ColNumber%)
  43. DECLARE SUB MenuCommand (YY$)
  44. DECLARE SUB FindEndOfMsg (EndOfMsg%)
  45. DECLARE SUB FindWord (YY$, I%, NewCol%)
  46. DECLARE SUB FindWrap (YY$, WhereToWrap%)
  47. DECLARE SUB GetChar (YY$)
  48. DECLARE SUB GetString (Prompt$, YY$)
  49. DECLARE SUB HelpMe ()
  50. DECLARE SUB ImportFile ()
  51. DECLARE SUB LastParaLine (I%, LastLine%, Result%)
  52. DECLARE SUB MoveCurStr (CurrentRow%, CurrentCol%, NewRow%, NewCol%, YY$, YLen%)
  53. DECLARE SUB MoveCursor (NewRow%, NewCol%)
  54. DECLARE SUB NormalChar (YY$)
  55. DECLARE SUB PutScreen (YY$, Colour%, Bold%)
  56. DECLARE SUB ReformText (Justify%)
  57. DECLARE SUB SaveCursor (Row%, Col%)
  58. DECLARE SUB UnString (YY$, BadString$)
  59. DECLARE SUB UnGetChar (X%)
  60. DECLARE SUB UpdateScreen ()
  61. DECLARE SUB UpdateStatusLine (How%)
  62.  
  63. DECLARE SUB BufFile (FileName$, Z%)
  64. DECLARE SUB Carrier ()
  65. DECLARE SUB CheckTime (LogoffTime!, Remain!, Z%)
  66. DECLARE SUB ColorPrompt (YY$)
  67. DECLARE SUB EofComm (Char%)
  68. DECLARE SUB FindFKey ()
  69. DECLARE SUB GetCom (YY$)
  70. DECLARE SUB Line25 ()
  71. DECLARE SUB NameCaps (YY$)
  72. DECLARE SUB QuickTput (YY$, NumReturns%)
  73. DECLARE SUB Tput ()
  74. DECLARE SUB TrimTrail (YY$, XX$)
  75. DECLARE SUB UpdtCalr (YY$, Z%)
  76.  
  77. ' $INCLUDE: 'RBBS-VAR.MOD'
  78.  
  79. 100   CONST RedFore = 31
  80.       CONST GreenFore = 32
  81.       CONST YellowFore = 33
  82.       CONST BlueFore = 34
  83.       CONST MagentaFore = 35
  84.       CONST CyanFore = 36
  85.       CONST WhiteFore = 37
  86.       CONST BlueBack = 44
  87.       CONST DefaultColor = 99
  88.       CONST DefaultBold = 99
  89.  
  90. 110   CONST ESCKey = 27
  91.       CONST BackspKey = 8
  92.       CONST OtherBackspKey = 127
  93.       CONST CarrRet = 13
  94.       CONST WordLeftKey = 1          ' Ctrl-A
  95.       CONST ReformTextKey = 2        ' Ctrl-B
  96.       CONST PageDownKey = 3          ' Ctrl-C
  97.       CONST ColRightKey = 4          ' Ctrl-D
  98.       CONST LineUpKey = 5            ' Ctrl-E
  99.       CONST WordRightKey = 6         ' Ctrl-F
  100.       CONST CharDeleteKey = 7        ' Ctrl-G
  101.       CONST TabKey = 9               ' Ctrl-I <- Tab Key Support
  102.       CONST EndSessionKey = 11       ' Ctrl-K
  103.       CONST HelpKey = 14             ' Ctrl-N
  104.       CONST ReflowTextKey = 15       ' Ctrl-O
  105.       CONST RepaintKey = 16          ' Ctrl-P
  106.       CONST PageUpKey = 18           ' Ctrl-R
  107.       CONST ColLeftKey = 19          ' Ctrl-S
  108.       CONST DeleteWordRightKey = 20  ' Ctrl-T
  109.       CONST ToggleINSKey = 22        ' Ctrl-V
  110.       CONST HomeKey = 23             ' Ctrl-W
  111.       CONST LineDownKey = 24         ' Ctrl-X
  112.       CONST LineDeleteKey = 25       ' Ctrl-Y
  113.       CONST EndKey = 26              ' Ctrl-Z
  114.  
  115.       CONST BlankLine$ = ""
  116. 119   CONST Version$ = "v2.44a"      ' v2.44a
  117.  
  118.       DEFINT A-Z
  119.  
  120. 120   COMMON SHARED /Ansied/ CurrentRow, CurrentCol, TopLine
  121.       COMMON SHARED /Ansied/ OldColour, IsBold, InsertMode
  122.       COMMON SHARED /Ansied/ SoftSpace$
  123.       COMMON SHARED /Ansied/ BlockDelActive, MsgLockLines
  124.       COMMON SHARED /Ansied/ BlockLine1, BlockLine2
  125.       COMMON SHARED /Ansied/ MsgTo$, MsgSubj$
  126.  
  127. '*  AnsiEd
  128. '*----------------------------------------------------------------------------
  129. '*  Main full-screen editor routine
  130. '*
  131. '*
  132.       SUB Ansied (T$, S$, L%)
  133.  
  134.       '*
  135.       '* ZworkAra$() holds what's currently on the user's screen.
  136.       '* 24 Lines: ZWorkAra$(1) = Menu, Bottom Line = "Line 25"
  137.       '*
  138. 500   Temp = 24                                                      ' RM08299301
  139.       REDIM ZWorkAra$(Temp)                                          ' RM08299301
  140.       '*
  141.       '* TopLine is the index into the ZOutTxt$() array that
  142.       '* corresponds to the top of the displayed image, i.e.
  143.       '* what's on line 3 of the user's screen.
  144.       '*
  145.       '*   1,12,23,34,45,56,67,78,89,100,111,122,133,144,155,166,177,188,
  146.       '*   199,210,221,232,243,254,265,276,287,298,309,320,331,342,353,
  147.       '*   364,375,386,397,408,419,430
  148.       '*
  149.       TopLine = 1
  150.       SoftSpace$ = CHR$(250)
  151.       InsertMode = ZTrue
  152.       ZLineFeed$ = CHR$(10)
  153.       BlockDelActive = ZFalse
  154.       HiLiteSave = ZHiLiteOff
  155.       ZHiLiteOff = ZFalse
  156.       UseTputSave = ZUseTput
  157.       ZUseTput = ZFalse
  158.  
  159.       MsgLockLines = L%
  160.  
  161.       MsgTo$ = T$
  162.       CALL NameCaps(MsgTo$)
  163.  
  164.       MsgSubj$ = S$
  165.       YY$ = ""
  166.       IF LEFT$(MsgSubj$, 3) = "(R)" THEN
  167.          YY$ = "(R)"
  168.          MsgSubj$ = MID$(MsgSubj$, 4)
  169.       END IF
  170.       CALL NameCaps(MsgSubj$)
  171.       MsgSubj$ = YY$ + MsgSubj$
  172.  
  173.       '*
  174.       '* Initialize the screen
  175.       '*
  176. 510   CALL ClearScreen
  177.       CALL UpdateStatusLine(1)
  178.       CALL DisplayKeys                                               ' SS
  179.       CALL MoveCursor(3, 1)
  180.       '*
  181.       '* Remove ANSI sequences from the quoted lines
  182.       '*
  183.       IF ZLinesInMsg > (ZMsgDim - 11) THEN                           ' RM020901  88
  184.          ZLinesInMsg = (ZMsgDim - 11)                                ' RM020901  88
  185.       END IF
  186.       IF ZMaxMsgLines > (ZMsgDim - 1) THEN                           ' RM020901  98
  187.          ZMaxMsgLines = (ZMsgDim - 1)                                ' RM020901  98
  188.       END IF
  189.       IF ZLinesInMsg > ZMaxMsgLines THEN
  190.          ZLinesInMsg = ZMaxMsgLines
  191.       END IF
  192.       FOR I = ZLinesInMsg + 1 TO ZMaxMsgLines                        ' RM020901  99
  193.          ZOutTxt$(I) = BlankLine$
  194.       NEXT
  195.       IF ZLinesInMsg <> 0 THEN
  196.          FOR I = 1 TO ZLinesInMsg
  197.             CALL UnString(ZOutTxt$(I), "")
  198.          NEXT
  199.          J = ZLinesInMsg \ 11
  200.          IF ZLinesInMsg MOD 11 = 0 THEN
  201.            J = J - 1
  202.          END IF
  203.          TopLine = J * 11 + 1
  204.          J = ZLinesInMsg - TopLine
  205.          CALL MoveCursor(J + 5, 1)
  206.       END IF
  207.       CALL UpdateScreen
  208.       '*
  209.       '* Run the Editor
  210.       '*
  211. 520   WHILE 1
  212.  
  213.          CALL GetChar(B$): GOSUB 740
  214.          KeyPressed = ASC(B$)
  215.          CALL SaveCursor(RowSave, ColSave)
  216.  
  217.          '*
  218.          '* Look for an ANSI escape sequence after an ESC
  219.          '*
  220. 525      IF KeyPressed = ESCKey THEN            ' v2.44a
  221.             CALL GetChar(B$): GOSUB 740
  222.             IF B$ = "[" THEN                    ' ANSI sequence
  223.                CALL GetChar(B$): GOSUB 740
  224.                IF B$ = "C" THEN
  225.                   KeyPressed = ColRightKey
  226.                ELSEIF B$ = "D" THEN
  227.                   KeyPressed = ColLeftKey
  228.                ELSEIF B$ = "A" THEN
  229.                   KeyPressed = LineUpKey
  230.                ELSEIF B$ = "B" THEN
  231.                   KeyPressed = LineDownKey
  232.                END IF
  233.             END IF
  234.          END IF
  235.  
  236.          Index = CurrentRow + TopLine - 3
  237.  
  238.          IF BlockDelActive OR Index <= MsgLockLines OR Index > ZMaxMsgLines THEN
  239. 530         SELECT CASE KeyPressed
  240.                CASE CarrRet
  241.                   IF BlockDelActive THEN
  242.                      BlockDelActive = ZFalse
  243.                      BlockLine2 = Index
  244.                      IF BlockLine2 < BlockLine1 THEN
  245.                         SWAP BlockLine1, BlockLine2
  246.                      END IF
  247.                      IF BlockLine1 <= MsgLockLines THEN
  248.                         BlockLine1 = MsgLockLines + 1
  249.                      END IF
  250.                      IF BlockLine2 > ZMaxMsgLines THEN
  251.                         BlockLine2 = ZMaxMsgLines
  252.                      END IF
  253.                      K = 0
  254.                      FOR I = BlockLine2 + 1 TO ZMaxMsgLines          ' RM020901/RM030601
  255.                         ZOutTxt$(BlockLine1 + K) = ZOutTxt$(I)
  256.                         K = K + 1
  257.                      NEXT I
  258.                      WHILE BlockLine1 + K <= ZMaxMsgLines            ' RM020901/RM030601
  259.                         ZOutTxt$(BlockLine1 + K) = BlankLine$
  260.                         K = K + 1
  261.                      WEND
  262.                      CALL UpdateScreen
  263.                      CALL UpdateStatusLine(2)
  264.                      CALL MoveCursor(BlockRow, BlockCol)
  265.                   END IF
  266.                   KeyPressed = 255
  267.  
  268. 540            CASE ESCKey
  269.                   IF BlockDelActive THEN
  270.                      BlockDelActive = ZFalse
  271.                      CALL UpdateStatusLine(2)
  272.                      CALL MoveCursor(BlockRow, BlockCol)
  273.                      KeyPressed = 255
  274.                   END IF
  275.  
  276.                CASE LineUpKey, LineDownKey, PageDownKey, PageUpKey
  277.                   '*
  278.                   '* Up and Down get passed on
  279.                   '*
  280.                CASE ELSE
  281.                   '*
  282.                   '* Ignore the key
  283.                   '*
  284.                   KeyPressed = 255
  285.  
  286.             END SELECT
  287.          END IF
  288.  
  289. 560      SELECT CASE KeyPressed
  290.             CASE ESCKey, EndSessionKey
  291.                '*
  292.                '* User wants to see main menu
  293.                '*
  294.                CALL DisplayMainMenu
  295.                CALL MoveCursor(RowSave, ColSave)
  296.                CALL GetChar(B$): GOSUB 740
  297.                B$ = UCASE$(B$)
  298.                IF B$ = "D" THEN
  299.                   BlockDelActive = ZTrue
  300.                   BlockLine1 = RowSave + TopLine - 3
  301.                   BlockCol = ColSave
  302.                   BlockRow = RowSave
  303.                   CALL EraseToEOL(1, 1)
  304.                   ' v2.44a
  305.                   CALL PutScreen("Delete Block: Press ENTER on Last Line to Delete, or ESC Twice to Quit", DefaultColor, DefaultBold)
  306.                   BlockLine2 = 0
  307.                ELSE
  308.                   CALL MenuCommand(B$): GOSUB 740
  309.                END IF
  310.                CALL MoveCursor(RowSave, ColSave)
  311.  
  312. 570         CASE LineUpKey
  313.                '*
  314.                '* Move the current cursor position up one line
  315.                '*
  316.                IF CurrentRow > 3 THEN
  317.                   CALL MoveCursor(CurrentRow - 1, CurrentCol)
  318.                ELSE
  319.                   IF TopLine <> 1 THEN
  320.                      TopLine = TopLine - 11
  321.                      IF TopLine < 1 THEN                             ' RM020901
  322.                         TopLine = 1                                  ' RM020901
  323.                      ENDIF                                           ' RM020901
  324.                      CALL MoveCursor(CurrentRow + 10, CurrentCol)
  325.                      CALL UpdateScreen
  326.                   END IF
  327.                END IF
  328.  
  329. 580         CASE LineDownKey
  330.                '*
  331.                '* Move the current cursor position down one line
  332.                '*
  333.                IF CurrentRow < 19 THEN                               ' SS
  334.                   IF (CurrentRow + (TopLine - 3)) < ZMaxMsgLines THEN      ' RM020901
  335.                   CALL MoveCursor(CurrentRow + 1, CurrentCol)
  336.                   ENDIF                                              ' RM020901
  337.                ELSE
  338.                   IF TopLine < ZMaxMsgLines - 18 THEN                ' RM020901/RM030602
  339.                      TopLine = TopLine + 11
  340.                      CALL MoveCursor(CurrentRow - 10, CurrentCol)
  341.                      CALL UpdateScreen
  342.                   END IF
  343.                END IF
  344.  
  345. 590         CASE ColLeftKey
  346.                '*
  347.                '* Move the current cursor left one column
  348.                '*
  349.                IF CurrentCol > 1 THEN
  350.                   CALL MoveCursor(CurrentRow, CurrentCol - 1)
  351.                END IF
  352.  
  353. 595         CASE TabKey    ' <- Tab Key Support here..               ' SS
  354.                '*                                                    ' SS
  355.                '* Tab 8 Spaces                                       ' SS
  356.                '*                                                    ' SS
  357.                IF CurrentCol < 72 THEN                               ' SS
  358.                 CALL MoveCursor(CurrentRow, CurrentCol + 8)          ' SS
  359.                END IF                                                ' SS
  360.  
  361. 600         CASE ColRightKey
  362.                '*
  363.                '* Move the current cursor right one column
  364.                '*
  365.                IF CurrentCol < 79 THEN
  366.                   CALL MoveCursor(CurrentRow, CurrentCol + 1)
  367.                END IF
  368.  
  369. 610         CASE WordRightKey, WordLeftKey
  370.                '*
  371.                '* Move the current cursor one word
  372.                '*
  373.                I = KeyPressed - WordLeftKey
  374.                NewCol = CurrentCol
  375.                CALL FindWord(ZOutTxt$(Index), I, NewCol)
  376.                IF NewCol > 79 THEN
  377.                   NewCol = 79
  378.                END IF
  379.                CALL MoveCursor(CurrentRow, NewCol)
  380.  
  381. 620         CASE DeleteWordRightKey
  382.                '*
  383.                '* Delete the current word
  384.                '*
  385.                I = CurrentCol
  386.                L = LEN(ZOutTxt$(Index))
  387.                CALL FindWord(ZOutTxt$(Index), 1, I)
  388.                IF I > CurrentCol THEN
  389.                   YY$ = MID$(ZOutTxt$(Index), I)
  390.                   MID$(ZOutTxt$(Index), CurrentCol) = YY$
  391.                   ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), L - (I - CurrentCol))
  392.                   CALL PutScreen(YY$, YellowFore, ZTrue)
  393.                   CALL EraseToEOL(RowSave, CurrentCol)
  394.                   CALL MoveCursor(RowSave, ColSave)
  395.                END IF
  396.  
  397. 630         CASE HomeKey
  398.                '*
  399.                '* Move cursor to the start of the line
  400.                '*
  401.                CALL MoveCursor(CurrentRow, 1)
  402.  
  403. 640         CASE EndKey
  404.                '*
  405.                '* Move cursor to the end of the line
  406.                '*
  407.                NewCol = LEN(ZOutTxt$(Index)) + 1
  408.                IF NewCol > 79 THEN
  409.                   NewCol = 79
  410.                END IF
  411.                CALL MoveCursor(CurrentRow, NewCol)
  412.  
  413. 650         CASE PageDownKey
  414.                '*
  415.                '* Move the display one page down
  416.                '*
  417.                TopLine = TopLine + 22
  418.                IF TopLine > ZMaxMsgLines - 15 THEN                   ' RM020901  78
  419.                   TopLine = ZMaxMsgLines - 15                        ' RM020901  78
  420.                END IF
  421.                CALL UpdateScreen
  422.  
  423. 660         CASE PageUpKey
  424.                '*
  425.                '* Move the display one page up
  426.                '*
  427.                TopLine = TopLine - 22
  428.                IF TopLine < 1 THEN
  429.                   TopLine = 1
  430.                END IF
  431.                CALL UpdateScreen
  432.  
  433. 670         CASE LineDeleteKey
  434.                '*
  435.                '* Delete the current line in the file
  436.                '*
  437.                CALL DeleteCurrentLine(Index)
  438.                CALL MoveCursor(RowSave, ColSave)
  439.  
  440. 680         CASE CharDeleteKey
  441.                '*
  442.                '* Delete the current character
  443.                '*
  444.                IF CurrentCol <= LEN(ZOutTxt$(Index)) THEN
  445.                   CALL MoveCursor(CurrentRow, CurrentCol + 1)
  446.                   CALL BackspChar
  447.                END IF
  448.  
  449. 690         CASE BackspKey, OtherBackspKey
  450.                '*
  451.                '* Back up one character and destroy it
  452.                '*
  453.                CALL BackspChar
  454.  
  455. 700         CASE CarrRet
  456.                '*
  457.                '* Move to the next line, left column
  458.                '*
  459.                IF NOT Index >= ZMaxMsgLines THEN
  460.                   CALL CarrRetKey
  461.                END IF
  462.  
  463. 710         CASE HelpKey, ReformTextKey, ReflowTextKey, ToggleINSKey, RepaintKey
  464.                '*
  465.                '* Execute a main menu command
  466.                '*
  467.                '*          1234567890123456789012
  468.                YY$ = MID$(" J           HRP     I", KeyPressed, 1)
  469.                CALL MenuCommand(YY$): GOSUB 740
  470.                CALL MoveCursor(RowSave, ColSave)
  471.  
  472. '            CASE IS > 127, IS < 32
  473.             CASE IS < 32                                             ' DGS010201-DS
  474.                '*
  475.                '* Accept characters above 127 for special msgs       ' DGS010101-DS
  476.                '*
  477.                '* Ignore characters above 127 or below 32
  478.                '*
  479. 720         CASE ELSE
  480.                '*
  481.                '* Input was a normal character
  482.                '*
  483.                CALL NormalChar(B$)
  484.  
  485.          END SELECT
  486.       WEND
  487.  
  488. 730   REDIM ZWorkAra$(ZMaxWorkVar)                                   ' RM112201/RM08279301
  489.       Temp = 1                                                       ' RM08299301
  490.       REDIM Places(Temp)                                             ' RM112201/RM08299301
  491.       ZHiLiteOff = HiLiteSave
  492.       ZUseTput = UseTputSave
  493.       S$ = UCASE$(MsgSubj$)
  494.       EXIT SUB
  495.  
  496.       '*
  497.       '* Test ZSubParm and Exit ANSIED if the carrier dropped
  498.       '*
  499. 740   IF ZSubParm <> 0 THEN
  500.          GOTO 730
  501.       END IF
  502.       RETURN
  503.  
  504.       END SUB         ' Sub AnsiEd
  505.  
  506. '*  BackspChar()
  507. '*----------------------------------------------------------------------------
  508. '*  This routine handles the user entering the backspace key
  509. '*
  510. '*
  511.       SUB BackspChar
  512. 1200  CALL SaveCursor(RowSave, ColSave)
  513.       Index = TopLine + CurrentRow - 3
  514.       IF Index = MsgLockLines + 1 AND CurrentCol = 1 THEN
  515.          EXIT SUB
  516.       END IF
  517.       AtEndOfLine = CurrentCol > LEN(ZOutTxt$(Index))
  518. 1210  IF CurrentCol > 1 THEN
  519.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 2) + MID$(ZOutTxt$(Index), CurrentCol)
  520.          CALL EraseToEOL(CurrentRow, CurrentCol - 1)
  521.          IF NOT AtEndOfLine THEN
  522.             YY$ = MID$(ZOutTxt$(Index), ColSave - 1)
  523.             CALL MoveCursor(RowSave, ColSave - 1)
  524.             CALL PutScreen(YY$, YellowFore, ZTrue)
  525.          END IF
  526.          CALL MoveCursor(RowSave, ColSave - 1)
  527.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  528.       ELSEIF LEN(ZOutTxt$(Index - 1)) >= ZRightMargin THEN
  529.          '*
  530.          '* Do nothing
  531.          '*
  532. 1220  ELSE
  533.          NewCol = LEN(ZOutTxt$(Index - 1)) + 1
  534.          YY$ = ZOutTxt$(Index)
  535.          CALL UnString(YY$, SoftSpace$)
  536.          ZOutTxt$(Index - 1) = ZOutTxt$(Index - 1) + YY$
  537.                                    ' v2.44a
  538.          IF LEN(ZOutTxt$(Index - 1)) <= ZRightMargin THEN
  539.             CALL DeleteCurrentLine(Index)
  540. 1230     ELSE
  541.             CALL FindWrap(LEFT$(ZOutTxt$(Index - 1), ZRightMargin + 1), I)
  542.             IF I <= 1 THEN
  543.                I = ZRightMargin
  544.             END IF
  545.             ZOutTxt$(Index) = MID$(ZOutTxt$(Index - 1), I + 1)
  546.             ZOutTxt$(Index - 1) = LEFT$(ZOutTxt$(Index - 1), I)
  547.          END IF
  548.          IF RowSave > 3 THEN
  549.             CALL MoveCursor(RowSave - 1, NewCol)
  550.             CALL UpdateScreen
  551.          ELSE
  552.             CALL MoveCursor(RowSave, NewCol)
  553.             CALL UnGetChar(LineUpKey)
  554.          END IF
  555.       END IF
  556.       END SUB
  557.  
  558. '*  CarrRetKey()
  559. '*----------------------------------------------------------------------------
  560. '*  This routine handles carriage returns entered in the file
  561. '*
  562. '*
  563.       SUB CarrRetKey
  564. 1300  Index = CurrentRow + TopLine - 3
  565.       IF Index >= ZMaxMsgLines THEN                                  ' RM020901  99
  566.          EXIT SUB
  567.       END IF
  568.       IF InsertMode THEN         ' Insert a new line
  569.          FOR I = (ZMaxMsgLines - 1) TO Index + 1 STEP -1             ' RM020901  98
  570.             ZOutTxt$(I + 1) = ZOutTxt$(I)
  571.          NEXT I
  572.          IF LEN(ZOutTxt$(Index)) >= CurrentCol THEN
  573.             ZOutTxt$(Index + 1) = MID$(ZOutTxt$(Index), CurrentCol)
  574.             ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1)
  575.          ELSE
  576.             ZOutTxt$(Index + 1) = BlankLine$
  577.          END IF
  578.          CALL UpdateScreen
  579.       END IF
  580.       IF CurrentRow < 19 THEN
  581.          CALL MoveCursor(CurrentRow + 1, 1)
  582.       ELSE
  583.          CALL MoveCursor(CurrentRow, 1)
  584.          CALL UnGetChar(LineDownKey)
  585.       END IF
  586.       END SUB
  587.  
  588. '*  ChangeSubject()
  589. '*----------------------------------------------------------------------------
  590. '*  Routine to allow user to change the message subject
  591. '*
  592. '*
  593.       SUB ChangeSubject
  594.       CALL GetString("Change Subject From '" + MsgSubj$ + "' To? ", NewSubj$)
  595.       IF NewSubj$ <> "" THEN
  596.          MsgSubj$ = LEFT$(NewSubj$, 25)
  597.          CALL NameCaps(MsgSubj$)
  598.       END IF
  599.       END SUB
  600.  
  601. '*  ClearScreen()
  602. '*----------------------------------------------------------------------------
  603. '*  This routine clears the screen and moves the cursor to row 2, col 1
  604. '*
  605. '*
  606.       SUB ClearScreen
  607. 1500  FOR I = 1 TO 19
  608.          ZWorkAra$(I) = BlankLine$
  609.       NEXT I
  610.       CALL QuickTput("", 0)
  611.       ZSubParm = 2
  612.       CALL Line25
  613.       ZSubParm = 0
  614.       CALL QuickTput("H" + ZEmphasizeOff$, 0)
  615.       CurrentCol = 1
  616.       CurrentRow = 3                                                 ' 4 IN MAPLE CODE
  617.       IsBold = DefaultBold
  618.       OldColour = DefaultColor
  619.       END SUB
  620.  
  621. '*  DeleteCurrentLine()
  622. '*----------------------------------------------------------------------------
  623. '*  This routine deletes the current line on the screen and in the array
  624. '*  ZOutTxt$, and moves the next lower line up one  It then repaints the
  625. '*  affected portion of the screen (from the deleted line down)
  626. '*
  627. '*
  628.       SUB DeleteCurrentLine (Index%)
  629. 1600  FOR I = Index% TO (ZMaxMsgLines - 1)                           ' RM020901  98
  630.          ZOutTxt$(I) = ZOutTxt$(I + 1)
  631.       NEXT I
  632.       ZOutTxt$(ZMaxMsgLines) = BlankLine$                            ' RM020901  99
  633.       CALL UpdateScreen
  634.       END SUB
  635.  
  636. '*  DisplayMainMenu()
  637. '*----------------------------------------------------------------------------
  638. '*  This routine displays the main menu on the top line
  639. '*
  640. '*
  641.       SUB DisplayMainMenu
  642. 1700  CALL MoveCursor(1, 1)
  643.       YY$ = "A)bort H)elp D)elete I)ns/ovw J)ustify "
  644.       IF ZLocalUser OR ZSysop THEN
  645.          YY$ = YY$ + "O)import R)eflow P)aint S)ave U)subject "
  646.       ELSE
  647.          YY$ = YY$ + "R)eflow P)aint S)ave U)subject          "
  648.       END IF
  649.       CALL ColorPrompt(YY$)
  650.       CALL PutScreen(YY$, DefaultColor, DefaultBold)
  651.       END SUB
  652.  
  653. '*  DoneWithMsg()
  654. '*----------------------------------------------------------------------------
  655. '*  This routine is called to save or abort the message
  656. '*
  657. '*
  658.       SUB DoneWithMsg (YY$)
  659. 1810  SELECT CASE YY$
  660.          CASE "S"        ' Save Message
  661.             '*
  662.             '* Remove trailing blank lines from the message
  663.             '*
  664.             CALL FindEndOfMsg(EndOfMsg)
  665.             FOR I = 1 TO EndOfMsg
  666.                J = INSTR(ZOutTxt$(I), SoftSpace$)
  667.                WHILE J <> 0
  668.                   MID$(ZOutTxt$(I), J, 1) = " "
  669.                   J = INSTR(ZOutTxt$(I), SoftSpace$)
  670.                WEND
  671.                CALL TrimTrail(ZOutTxt$(I), " ")
  672.             NEXT I
  673.             CALL FindEndOfMsg(ZLinesInMsg)
  674.             CALL ClearScreen
  675.             ZSubParm = 1
  676.  
  677. 1820     CASE "A"
  678.             CALL EraseToEOL(1, 1)
  679.             YY$ = "Abort: Are You Sure (Y)es,[N]o)? "
  680.             CALL ColorPrompt(YY$)
  681.             CALL PutScreen(YY$, DefaultColor, DefaultBold)
  682.             CALL GetChar(B$)
  683.             IF ZSubParm <> 0 THEN
  684.                B$ = "Y"
  685.             END IF
  686.             IF UCASE$(B$) = "Y" THEN
  687.                CALL ClearScreen
  688.                ZSubParm = 2
  689.             END IF
  690.       END SELECT
  691.       END SUB
  692.  
  693. '*  EraseToEOL()
  694. '*----------------------------------------------------------------------------
  695. '*  This routine clears from a position to to the end of that line
  696. '*
  697. '*
  698.       SUB EraseToEOL (LineNumber, ColNumber)
  699. 1900  CALL MoveCursor(LineNumber, ColNumber)
  700.       CALL QuickTput("", 0)
  701.       END SUB
  702.  
  703. '*  FindEndOfMsg()
  704. '*----------------------------------------------------------------------------
  705. '*  Finds the last active line in the message
  706. '*
  707. '*
  708.       SUB FindEndOfMsg (EndOfMsg)
  709.       EndOfMsg = 1
  710.       FOR I = ZMaxMsgLines TO 1 STEP -1
  711.          IF ZOutTxt$(I) <> BlankLine$ OR I <= MsgLockLines THEN
  712.             EndOfMsg = I
  713.             EXIT FOR
  714.          END IF
  715.       NEXT I
  716.       END SUB
  717.  
  718. '*  FindWrap()
  719. '*----------------------------------------------------------------------------
  720. '*  This routine finds a place in the string yy$ that could be used as a
  721. '*  place to wrap the line WhereToWrap should be the last position that
  722. '*  remains in the line, ie
  723. '*    set   currentline$ = left$(yy$,wheretowrap)
  724. '*          nextline$    = mid$ (yy$,wheretowrap+1)
  725. '*
  726. '*
  727.       SUB FindWrap (YY$, WhereToWrap)
  728. 2100  WhereToWrap = LEN(YY$) + 1
  729.       CALL FindWord(YY$, 0, WhereToWrap)
  730.       WhereToWrap = WhereToWrap - 1
  731.       END SUB
  732.  
  733. '*  GetChar()
  734. '*----------------------------------------------------------------------------
  735. '*  This routine reads a character from the user into YY$
  736. '*
  737. '*
  738.       SUB GetChar (YY$)
  739. 2200  ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  740.       CALL Carrier
  741.       YY$ = ""
  742.       WHILE ZSubParm <> -1 AND ZSubParm <> -2 AND YY$ = ""
  743.          ZSubParm = 0
  744.          IF LEN(ZCommportStack$) > 0 THEN
  745.             YY$ = LEFT$(ZCommportStack$, 1)
  746.             ZCommportStack$ = MID$(ZCommportStack$, 2)
  747.          ELSE
  748.             IF ZLocalUser THEN
  749.                YY$ = INKEY$
  750.                IF LEN(YY$) = 2 THEN
  751.                   KeyPressed = ASC(RIGHT$(YY$, 1))
  752.                   YY$ = ""
  753.                   SELECT CASE KeyPressed
  754.                      CASE 82                  ' Insert
  755.                         KeyPressed = ToggleINSKey
  756.                      CASE 83                  ' Delete
  757.                         KeyPressed = CharDeleteKey
  758.                      CASE 71                  ' Home
  759.                         KeyPressed = HomeKey
  760.                      CASE 73                  ' PgUp
  761.                         KeyPressed = PageUpKey
  762.                      CASE 72                  ' Up Arrow
  763.                         KeyPressed = LineUpKey
  764.                      CASE 80                  ' Down Arrow
  765.                         KeyPressed = LineDownKey
  766.                      CASE 81                  ' PgDn
  767.                         KeyPressed = PageDownKey
  768.                      CASE 75                  ' Left Arrow
  769.                         KeyPressed = ColLeftKey
  770.                      CASE 77                  ' Right Arrow
  771.                         KeyPressed = ColRightKey
  772.                      CASE 115                 ' Ctrl-Left Arrow
  773.                         KeyPressed = WordLeftKey
  774.                      CASE 116                 ' Ctrl-Right Arrow
  775.                         KeyPressed = WordRightKey
  776.                      CASE 79                  ' End
  777.                         KeyPressed = EndKey
  778.                      CASE 9                                          ' SS
  779.                         KeyPressed = TabKey                          ' SS
  780.                      CASE ELSE
  781.                         KeyPressed = 0
  782.                   END SELECT
  783.                   IF KeyPressed <> 0 THEN
  784.                      YY$ = CHR$(KeyPressed)
  785.                   END IF
  786.                END IF
  787.             ELSE
  788.                CALL FindFKey
  789.                IF ZSubParm >= 0 THEN
  790.                   YY$ = ZKeyPressed$
  791.                   IF YY$ = "" THEN
  792.                      CALL EofComm(Char%)
  793.                      IF Char% = -1 THEN
  794.                         CALL CheckTime(ZAutoLogoff!, Remain!, 1)
  795.                         IF Remain! < 0 THEN
  796. '                          CALL UpdtCalr("Sleep disconnect", 1)      ' RM02029401
  797.                            ZSubParm = -2
  798.                            ZNo = ZTrue
  799.                            ZSleepDisconnect = ZTrue
  800.                         END IF
  801.                      ELSE
  802.                         CALL Carrier
  803.                         IF ZSubParm <> -1 THEN
  804.                            ZSubParm = 0
  805.                            CALL GetCom(YY$)
  806.                         END IF
  807.                      END IF
  808.                   END IF
  809.                END IF
  810.             END IF
  811.          END IF
  812.       CALL GoIdle                                                    ' RM10299301
  813.       WEND
  814.       END SUB
  815.  
  816. '*  GetString()
  817. '*----------------------------------------------------------------------------
  818. '*  Gets a string from the user
  819. '*
  820. '*
  821.       SUB GetString (Prompt$, YY$)
  822.       YY$ = ""
  823.       CALL EraseToEOL(1, 1)
  824.       CALL PutScreen(Prompt$, DefaultColor, DefaultBold)
  825.       NewCol = CurrentCol
  826.       InitCol = NewCol
  827.       DO
  828.          CALL MoveCursor(CurrentRow, NewCol)
  829.          CALL GetChar(B$)
  830.          IF ZSubParm <> 0 THEN
  831.             B$ = CHR$(ESCKey)
  832.          END IF
  833.          KeyPressed = ASC(B$)
  834.          SELECT CASE KeyPressed
  835.             CASE BackspKey, OtherBackspKey
  836.                IF NewCol <> InitCol THEN
  837.                   CALL MoveCursor(CurrentRow, NewCol - 1)
  838.                   CALL PutScreen(" ", DefaultColor, DefaultBold)
  839.                   NewCol = NewCol - 1
  840.                   YY$ = LEFT$(YY$, LEN(YY$) - 1)
  841.                END IF
  842.             CASE CarrRet
  843.                EXIT DO
  844.             CASE ESCKey
  845.                YY$ = ""
  846.                EXIT DO
  847.             CASE ELSE
  848.                YY$ = YY$ + B$
  849.                CALL PutScreen(B$, DefaultColor, DefaultBold)
  850.                NewCol = NewCol + 1
  851.          END SELECT
  852.       LOOP WHILE 1
  853.       END SUB
  854.  
  855. '*  HelpMe()
  856. '*----------------------------------------------------------------------------
  857. '*  This routine provides on-line help for the user
  858. '*
  859. '*
  860.       SUB HelpMe
  861. 2300  CALL SaveCursor(RowSave, ColSave)
  862.       CALL ClearScreen
  863.       CALL BufFile(ZHelpPath$ + "ANSIED" + ZHelpExtension$, X)
  864.       CALL ClearScreen
  865.       CALL UpdateScreen
  866.       CALL MoveCursor(RowSave, ColSave)
  867.       END SUB
  868.  
  869. '*  ImportFile()
  870. '*----------------------------------------------------------------------------
  871. '*  Imports an ASCII text file in the message
  872. '*
  873. '*
  874.       SUB ImportFile
  875.       IF ZLocalUser OR ZSysop THEN
  876.          CALL GetString("Import What File? ", FileName$)
  877.          IF FileName$ <> "" THEN
  878.             CALL FindIt(FileName$)
  879.             IF ZOK THEN
  880.                ZUserIn$(1) = FileName$
  881.                ZAnsIndex = 0
  882.                ZLastIndex = 1
  883.                CALL FindEndOfMsg(EndOfMsg)
  884.                CALL MsgImport(ZMaxMsgLines, ZRightMargin, EndOfMsg, ZOutTxt$())
  885.                CALL UpdateScreen
  886.             END IF
  887.          END IF
  888.       END IF
  889.       END SUB
  890.  
  891. '*  LastParaLine()
  892. '*----------------------------------------------------------------------------
  893. '*  This routine returns ZTrue if ZOutTxt$(I) is the last line
  894. '*  in a paragraph
  895. '*
  896. '*
  897.       SUB LastParaLine (I, LastLine, Result)
  898. 2400  Result = ZFalse
  899.       IF I = LastLine OR I >= ZMaxMsgLines THEN
  900.          Result = ZTrue
  901.       ELSE
  902.          YY$ = ZOutTxt$(I)
  903.          J = INSTR(YY$, ">")
  904.          IF J = 0 THEN
  905.             J = 6
  906.          END IF
  907.          IF J < 5 THEN
  908.             Result = ZTrue
  909.          ELSEIF YY$ = BlankLine$ THEN
  910.             Result = ZTrue
  911.          ELSE
  912.             IF ZOutTxt$(I + 1) = BlankLine$ THEN
  913.                Result = ZTrue
  914.             ELSEIF LEFT$(ZOutTxt$(I + 1), 1) = " " THEN
  915.                Result = ZTrue
  916.             ELSE
  917.                K = INSTR(ZOutTxt$(I + 1), ">")
  918.                IF K <> 0 AND K < 5 THEN
  919.                   Result = ZTrue
  920.                END IF
  921.             END IF
  922.          END IF
  923.       END IF
  924.       END SUB
  925.  
  926. '*  MenuCommand()
  927. '*----------------------------------------------------------------------------
  928. '* This routine executes the passed main menu command
  929. '*
  930. '*
  931.       SUB MenuCommand (YY$)
  932. 2450  ZSubParm = 0              ' v2.44a
  933.       SELECT CASE YY$
  934.          CASE "H"
  935.             CALL HelpMe
  936.             CALL DisPlayKeys                                         ' SS
  937.          CASE "S", "A"
  938.             CALL DoneWithMsg(YY$)
  939.          CASE "P"
  940.             CALL ClearScreen
  941.             CALL DisplayKeys                                         ' SS
  942.             CALL UpdateScreen
  943.          CASE "I"
  944.             InsertMode = NOT InsertMode
  945.          CASE "R"
  946.             CALL ReformText(ZFalse)
  947.          CASE "J"
  948.             CALL ReformText(ZTrue)
  949.          CASE "O"
  950.             CALL ImportFile
  951.          CASE "U"
  952.             CALL ChangeSubject
  953.       END SELECT
  954.       IF ZSubParm = 0 THEN
  955.          CALL EraseToEOL(1, 1)
  956.          CALL UpdateStatusLine(1)
  957.       END IF
  958.       END SUB
  959.  
  960. '*  MoveCursor()
  961. '*----------------------------------------------------------------------------
  962. '*  This routine moves the cursor to the position spec'd by newcol and
  963. '*  newrow and tries to do it with the minimum number of Ansi characters
  964. '*
  965. '*
  966.       SUB MoveCursor (NewRow, NewCol)
  967. 2500  YY$ = "        "
  968.       CALL MoveCurStr(CurrentRow, CurrentCol, NewRow, NewCol, YY$, YLen)
  969.       IF YLen <> 0 THEN
  970.          YY$ = LEFT$(YY$, YLen)
  971.          CALL QuickTput(YY$, 0)
  972.       END IF
  973.       ZSubParm = 0
  974.       END SUB
  975.  
  976. '*  NormalChar()
  977. '*----------------------------------------------------------------------------
  978. '*  This routine handles 'normal' characters entered into the message
  979. '*
  980. '*
  981.       SUB NormalChar (YY$)
  982.  
  983. 2600  CALL SaveCursor(RowSave, ColSave)
  984.       Index = CurrentRow + TopLine - 3
  985.       CurrentLineBlank = (ZOutTxt$(Index) = BlankLine$)
  986.       LML = LEN(ZOutTxt$(Index))
  987.  
  988.       IF CurrentCol > 79 THEN
  989.          EXIT SUB
  990.       END IF
  991.  
  992.       AtEndOfLine = ZFalse
  993.  
  994.       IF CurrentCol > LML THEN
  995.          ZOutTxt$(Index) = ZOutTxt$(Index) + SPACE$(CurrentCol - LML)
  996.          ZWorkAra$(CurrentRow) = ZWorkAra$(CurrentRow) + SPACE$(CurrentCol - LML)
  997.          LML = LEN(ZOutTxt$(Index))
  998.          AtEndOfLine = ZTrue
  999.       END IF
  1000.  
  1001. 2610  IF (CurrentCol <= ZRightMargin AND AtEndOfLine) OR (CurrentCol <= ZRightMargin AND NOT InsertMode) THEN
  1002.          '*
  1003.          '* Single character changed
  1004.          '*
  1005.          MID$(ZOutTxt$(Index), CurrentCol, 1) = YY$
  1006.          MID$(ZWorkAra$(CurrentRow), CurrentCol, 1) = YY$
  1007.          CALL PutScreen(YY$, YellowFore, ZTrue)
  1008.                                                                                     ' v2.44a
  1009. 2620  ELSEIF (NOT AtEndOfLine AND InsertMode AND CurrentCol <= ZRightMargin AND LML < ZRightMargin) THEN
  1010.          '*
  1011.          '* Have to rewrite the screen from the current pos forward
  1012.          '*
  1013.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1) + YY$ + MID$(ZOutTxt$(Index), CurrentCol)
  1014.  
  1015.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  1016.  
  1017.          CALL EraseToEOL(CurrentRow, CurrentCol)
  1018.          ZZ$ = MID$(ZWorkAra$(CurrentRow), CurrentCol)
  1019.          CALL PutScreen(ZZ$, YellowFore, ZTrue)
  1020.          CALL MoveCursor(RowSave, ColSave + 1)
  1021.  
  1022. 2630  ELSE
  1023.          '*
  1024.          '* Wrap the end of the line
  1025.          '*
  1026.          IF NOT AtEndOfLine THEN
  1027.             ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1) + YY$ + MID$(ZOutTxt$(Index), CurrentCol)
  1028.             LML = LML + 1
  1029.          ELSE
  1030.             MID$(ZOutTxt$(Index), CurrentCol, 1) = YY$
  1031.          END IF
  1032.  
  1033.          CALL FindWrap(ZOutTxt$(Index), I)
  1034.          IF I <= 1 THEN
  1035.             I = ZRightMargin
  1036.          END IF
  1037.  
  1038.          ZZ$ = MID$(ZOutTxt$(Index), (I + 1))
  1039.          CALL TrimTrail(ZZ$, SoftSpace$)
  1040.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), I)
  1041.          '*
  1042.          '* Add to the beginning of a new line
  1043.          '*
  1044.          IF Index <= (ZMaxMsgLines - 1) THEN                         ' RM020901  98
  1045.             Index = Index + 1
  1046.          END IF
  1047.  
  1048.          Z = INSTR(ZOutTxt$(Index), ">")                                                  ' v2.44a
  1049.          IF ZOutTxt$(Index) <> BlankLine$ AND (Z <= 0 OR Z > 6) AND LEN(ZOutTxt$(Index)) + LEN(ZZ$) < ZRightMargin THEN
  1050.             ZOutTxt$(Index) = ZZ$ + ZOutTxt$(Index)
  1051.          ELSE
  1052.             FOR J = (ZMaxMsgLines - 1) TO Index STEP -1              ' RM020901  98
  1053.                ZOutTxt$(J + 1) = ZOutTxt$(J)
  1054.             NEXT J
  1055.             ZOutTxt$(Index) = ZZ$
  1056.          END IF
  1057.  
  1058.          CALL EraseToEOL(CurrentRow, I + 1)        ' do the "easy" line
  1059.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  1060.  
  1061.          CALL UpdateScreen
  1062.          IF (ColSave > I) THEN
  1063.             NewCol = ColSave - I + 1
  1064.             IF RowSave <> 19 THEN                                    ' SS
  1065.                CALL MoveCursor(RowSave + 1, NewCol)
  1066.             ELSE
  1067.                CALL MoveCursor(RowSave, NewCol)
  1068.                CALL UnGetChar(LineDownKey)
  1069.             END IF
  1070.          ELSE
  1071.             CALL MoveCursor(RowSave, ColSave + 1)
  1072.          END IF
  1073.       END IF
  1074.       END SUB
  1075.  
  1076. '*  PutScreen()
  1077. '*----------------------------------------------------------------------------
  1078. '* This routine writes YY$ to the user in the color and
  1079. '* intensity specified
  1080. '*
  1081. '*
  1082.       SUB PutScreen (YY$, Colour, Bold)
  1083. 2800  ZZ$ = ""
  1084.       IF Colour <> 99 THEN
  1085.          IF (Colour <> OldColour) OR (Bold <> IsBold) THEN
  1086.             ZZ$ = ""
  1087.             IF Bold <> IsBold THEN
  1088.                IF Bold THEN
  1089.                   ZZ$ = ZZ$ + "1;"
  1090.                ELSE
  1091.                   ZZ$ = ZZ$ + "0;"
  1092.                END IF
  1093.             END IF
  1094.             ZZ$ = ZZ$ + MID$(STR$(Colour), 2) + "m"
  1095.          END IF
  1096.       ELSE
  1097.          ZZ$ = ZEmphasizeOff$
  1098.       END IF
  1099.       ZOutTxt$ = ZZ$ + YY$
  1100.       IF ZLocalUser THEN
  1101.          CALL QuickTput(ZOutTxt$, 0)
  1102.       ELSE
  1103.          ZSubParm = 4
  1104.          CALL Tput
  1105.       END IF
  1106.       ZSubParm = 0
  1107.       IF INSTR(YY$, "") = 0 THEN
  1108.          CurrentCol = CurrentCol + LEN(YY$)
  1109.          IF CurrentCol > 80 THEN
  1110.             CurrentCol = 0
  1111.             CurrentRow = 0
  1112.          END IF
  1113.       ELSE
  1114.          CurrentRow = 0
  1115.          CurrentCol = 0
  1116.       END IF
  1117.       OldColour = Colour
  1118.       IsBold = Bold
  1119.       END SUB
  1120.  
  1121. '*  ReformText()
  1122. '*----------------------------------------------------------------------------
  1123. '*  This routine reflows the text to the current margins.  Optionally,
  1124. '*  it right justifies all lines by adding "soft spaces"
  1125. '*
  1126. '*
  1127.       SUB ReformText (Justify%)
  1128. 2900  Temp = 80                                                      ' RM08299301
  1129.       DIM Places(Temp)                                               ' RM08299301
  1130.  
  1131.       CALL EraseToEOL(1, 1)
  1132.       CALL PutScreen("Reformatting... Please Wait.", WhiteFore, ZTrue)
  1133.  
  1134.       CALL FindEndOfMsg(EndOfMsg)
  1135.  
  1136.       I = MsgLockLines + 1   ' Read index
  1137.       J = MsgLockLines + 1   ' Write index
  1138.  
  1139.       '*
  1140.       '* Reflow the text to the maximum on a line
  1141.       '*
  1142.       DO WHILE I <= EndOfMsg
  1143.          '*
  1144.          '* Loop until we get a long line or an end of paragraph
  1145.          '*
  1146.          ZOutTxt$ = ""
  1147.          DO WHILE 1
  1148.             YY$ = ZOutTxt$(I)
  1149.             CALL UnString(YY$, SoftSpace$)
  1150.             IF ZOutTxt$ <> "" AND RIGHT$(ZOutTxt$, 1) <> " " THEN
  1151.                ZOutTxt$ = ZOutTxt$ + " "
  1152.             END IF
  1153.             ZOutTxt$ = ZOutTxt$ + YY$
  1154.             CALL LastParaLine(I, EndOfMsg, EndOfPara)
  1155.             I = I + 1
  1156.             IF LEN(ZOutTxt$) > ZRightMargin THEN
  1157.                '*
  1158.                '* Wrap the long line
  1159.                '*
  1160.                CALL FindWrap(LEFT$(ZOutTxt$, ZRightMargin + 1), K)
  1161.                IF K <= 1 THEN
  1162.                   K = ZRightMargin
  1163.                END IF
  1164.                ZOutTxt$(J) = LEFT$(ZOutTxt$, K)
  1165.                IF EndOfPara THEN
  1166.                   '*
  1167.                   '* Go to the next paragraph
  1168.                   '*
  1169.                   J = J + 1
  1170.                   ZOutTxt$(J) = MID$(ZOutTxt$, K + 1)
  1171.                ELSE
  1172.                   '*
  1173.                   '* Keep the remaining part of the line and process
  1174.                   '* it on the next pass
  1175.                   '*
  1176.                   IF I - 1 <> J OR MID$(ZOutTxt$, K + 1) = "" THEN   ' DGS010401-DS/DGS010901-DS
  1177.                      I = I - 1                                       ' DGS010401-DS
  1178.                      ZOutTxt$(I) = MID$(ZOutTxt$, K + 1)             ' DGS010401-DS
  1179.                   ELSE                                               ' DGS010401-DS
  1180.                      ZOutTxt$(I) = MID$(ZOutTxt$, K + 1) + " " + ZOutTxt$(I) ' DGS010401-DS
  1181.                   END IF                                             ' DGS010401-DS
  1182. '                  ZOutTxt$(I) = MID$(ZOutTxt$, K + 1)               ' DGS010401-DS
  1183.                END IF
  1184.                J = J + 1
  1185.                EXIT DO
  1186.             ELSEIF EndOfPara THEN
  1187.                ZOutTxt$(J) = ZOutTxt$
  1188.                J = J + 1
  1189.                EXIT DO
  1190.             END IF
  1191.          LOOP
  1192.       LOOP
  1193.  
  1194.       FOR I = J TO ZMaxMsgLines                                      ' RM020901/RM030601
  1195.          ZOutTxt$(I) = BlankLine$
  1196.       NEXT
  1197.  
  1198.       EndOfMsg = J - 1
  1199.  
  1200.       '*
  1201.       '* Space out the text on each line
  1202.       '*
  1203.       IF Justify% THEN
  1204.          FOR I = MsgLockLines + 1 TO EndOfMsg
  1205.             CALL LastParaLine(I, EndOfMsg, EndOfPara)
  1206.             IF NOT EndOfPara THEN
  1207.                '*
  1208.                '* Space out the line
  1209.                '*
  1210.                ZOutTxt$ = ZOutTxt$(I)
  1211.                CALL TrimTrail(ZOutTxt$, " ")
  1212.                TxtLen = LEN(ZOutTxt$)
  1213.                SpacesToAdd = ZRightMargin - TxtLen
  1214.                IF SpacesToAdd > 0 THEN
  1215.                   '*
  1216.                   '* Skip leading spaces on the line
  1217.                   '*
  1218.                   Place = 1
  1219.                   IF LEFT$(ZOutTxt$, 1) = " " THEN
  1220.                      CALL FindWord(ZOutTxt$, 1, Place)
  1221.                   END IF
  1222.                   '*
  1223.                   '* Find all of the possible places to space out the line
  1224.                   '*
  1225.                   NumPlaces = 0
  1226.                   DO WHILE 1
  1227.                      CALL FindWord(ZOutTxt$, 1, Place)
  1228.                      IF Place < TxtLen THEN
  1229.                         NumPlaces = NumPlaces + 1
  1230.                         Places(NumPlaces) = Place
  1231.                      ELSE
  1232.                         EXIT DO
  1233.                      END IF
  1234.                   LOOP
  1235.                   '*
  1236.                   '* Fill in available places with soft spaces
  1237.                   '*
  1238.                   IF NumPlaces <> 0 THEN
  1239.                      ExtraPlaces = (SpacesToAdd MOD NumPlaces)
  1240.                      LeftExtra = ExtraPlaces \ 2
  1241.                      RightExtra = ExtraPlaces - LeftExtra
  1242.                      FOR J = NumPlaces TO 1 STEP -1
  1243.                         SpacesThisPlace = SpacesToAdd \ NumPlaces
  1244.                         IF J <= LeftExtra OR J > NumPlaces - RightExtra THEN
  1245.                            SpacesThisPlace = SpacesThisPlace + 1
  1246.                         END IF
  1247.                         IF SpacesThisPlace <> 0 THEN
  1248.                            ZOutTxt$ = LEFT$(ZOutTxt$, Places(J) - 1) + STRING$(SpacesThisPlace, SoftSpace$) + MID$(ZOutTxt$, Places(J))
  1249.                         END IF
  1250.                      NEXT J
  1251.                   END IF
  1252.                END IF
  1253.                ZOutTxt$(I) = ZOutTxt$
  1254.             END IF
  1255.          NEXT I
  1256.       END IF
  1257.  
  1258.       CALL UpdateScreen
  1259.  
  1260.       END SUB
  1261.  
  1262. '*  SaveCursor()
  1263. '*----------------------------------------------------------------------------
  1264. '*  This routine saves the current cursor position
  1265. '*
  1266. '*
  1267.       SUB SaveCursor (Row%, Col%)
  1268.       Row% = CurrentRow
  1269.       Col% = CurrentCol
  1270.       END SUB
  1271.  
  1272. '*  UnGetChar()
  1273. '*----------------------------------------------------------------------------
  1274. '*   Puts a key in the beginning of the keyboard buffer
  1275. '*
  1276. '*
  1277.       SUB UnGetChar (X)
  1278.       ZCommportStack$ = CHR$(X) + ZCommportStack$
  1279.       END SUB
  1280.  
  1281. '*  UnString()
  1282. '*----------------------------------------------------------------------------
  1283. '*  Removes one string from another
  1284. '*
  1285. '*
  1286.       SUB UnString (YY$, BadString$)
  1287.       I = INSTR(YY$, BadString$)
  1288.       WHILE I <> 0
  1289.          YY$ = LEFT$(YY$, I - 1) + MID$(YY$, I + LEN(BadString$))
  1290.          I = INSTR(YY$, BadString$)
  1291.       WEND
  1292.       END SUB
  1293.  
  1294. '*  UpdateScreen()
  1295. '*----------------------------------------------------------------------------
  1296. '*  This is one of the most important routines  It compares the arrays
  1297. '*  ZOutTxt$ and ZWorkAra$ and only sends the user the DIFFERENCE between the
  1298. '*  two within the viewing area  In this way all processing can be done on
  1299. '*  ZOutTxt$ and then the screen is updated to reflect the changes. After the
  1300. '*  users screen is updated, ZWorkAra$ is changed to reflect what should be
  1301. '*  on the users' screen The cursor is restored to its original position
  1302. '*
  1303. '*
  1304.       SUB UpdateScreen
  1305. 3100  CALL SaveCursor(RowSave, ColSave)
  1306.       FOR I = 3 TO 19 AND Index < ZMaxMsgLines                       ' SS/RM020901/RM030601
  1307.          Index = I + TopLine - 3
  1308.          ScreenLine$ = ZWorkAra$(I)
  1309.          IF Index >= ZMaxMsgLines THEN                               ' RM020901/RM030601
  1310.             MessageLine$ = ZOutTxt$(ZMaxMsgLines)                    ' RM020901/RM030601
  1311.          ELSE                                                        ' RM020901
  1312.             MessageLine$ = ZOutTxt$(Index)
  1313.          ENDIF                                                       ' RM020901
  1314.          LML = LEN(MessageLine$)
  1315.          IF Index = ZMaxMsgLines + 1 THEN
  1316.             CALL EraseToEOL(I, 1)
  1317.             CALL PutScreen("[* End of Message *]", CyanFore, ZFalse)
  1318.             ZWorkAra$(I) = CHR$(EndKey)
  1319.          ELSEIF Index > ZMaxMsgLines + 1 THEN
  1320.             IF ScreenLine$ <> BlankLine$ THEN
  1321.                CALL EraseToEOL(I, 1)
  1322.                ZWorkAra$(I) = BlankLine$
  1323.             END IF
  1324.          ELSEIF MessageLine$ = ScreenLine$ THEN
  1325.             '*
  1326.             '* Screen = What's in message buffer
  1327.             '*
  1328.          ELSEIF MessageLine$ = BlankLine$ OR MessageLine$ = SPACE$(LML) THEN
  1329.             CALL EraseToEOL(I, 1)
  1330.             ZWorkAra$(I) = MessageLine$
  1331.          ELSE
  1332.             CALL MoveCursor(I, 1)
  1333.             YY$ = MessageLine$
  1334.             CALL PutScreen(YY$, YellowFore, ZTrue)
  1335.             CALL EraseToEOL(CurrentRow, CurrentCol)
  1336.             ZWorkAra$(I) = ZOutTxt$(Index)
  1337.          END IF
  1338.       NEXT I
  1339.       CALL MoveCursor(RowSave, ColSave)
  1340.       END SUB
  1341.  
  1342. '*  UpdateStatusLine()
  1343. '*-----------------------------------------------------------------------------
  1344. '*  Rewrites the status line on screen line(s) 1 and 2
  1345. '*
  1346. '*    Input:  How% = 1   - Rewrite both lines
  1347. '*            How% = 2   - Just rewrite top line
  1348. '*
  1349.       SUB UpdateStatusLine (How%)
  1350. 3200  YY$ = "ANSIED " + Version$
  1351.       YY$ = YY$ + SPACE$(79 - LEN(YY$))
  1352.       CALL MoveCursor(1, 1)
  1353.       CALL PutScreen(YY$, RedFore, ZTrue)
  1354.       YY$ = " by Tom Collins"
  1355.       CALL MoveCursor(1,14)
  1356.       CALL PutScreen(YY$, BlueFore, ZTrue)
  1357.       YY$ = "* Press ESC Twice"
  1358.       CALL MoveCursor(1,31)
  1359.       CALL PutScreen(YY$, RedFore, ZTrue)
  1360.       YY$ = " or Cntrl-K"
  1361.       CALL MoveCursor(1,48)
  1362.       CALL PutScreen(YY$, BlueFore, ZTrue)
  1363.       YY$ = " for MENU *"
  1364.       CALL MoveCursor(1,59)
  1365.       CALL PutScreen(YY$, RedFore, ZTrue)
  1366.  
  1367. 3210  IF How% = 1 THEN
  1368.          YY$ = CHR$(205) + " To: " + MsgTo$ + " " + CHR$(205) + " Re: " + MsgSubj$ + " " + CHR$(205)
  1369.          YY$ = YY$ + STRING$(79 - LEN(YY$), CHR$(205))
  1370.          IF InsertMode THEN
  1371.             MID$(YY$, 74) = " Ins "
  1372.          ELSE
  1373.             MID$(YY$, 74) = " Ovw "
  1374.          END IF
  1375.          I = 1
  1376.          CALL MoveCursor(2, I)
  1377.          CALL PutScreen(YY$, WhiteFore, ZFalse)
  1378.       END IF
  1379.       END SUB
  1380. 3220 SUB DisplayKeys
  1381.      CALL MoveCursor(20,1)                                           ' SS
  1382.      YY$ = STRING$(79,CHR$(205))                                     ' SS
  1383.      MID$ (YY$,30) = " ANSIED QuickKeys Menu "                       ' SS
  1384.      CALL PutScreen(YY$,RedFore,DefaultBold)                         ' SS
  1385.      CALL MoveCursor(21,1)                                           ' SS
  1386.      CALL PutScreen ("^A Word Left  ^B Reformat ^C PageDown  ^D ColRight ^E LineUp   ^F Word Right",DefaultColor, DefaultBold) ' SS
  1387.      CALL MoveCursor(22,1)                                           ' SS
  1388.      CALL PutScreen ("^G Del        ^O Reflow   ^P Repaint   ^R PageUp   ^S ColLeft  ^T DelWordRight",DefaultColor, DefaultBold) ' SS
  1389.      CALL MoveCursor(23,1)                                           ' SS
  1390.      CALL PutScreen ("^V Toggle Ins ^W Home     ^X Line Down ^Y Del Line ^Z End",DefaultColor, DefaultBold) ' RM072301
  1391.      CALL MoveCursor(23,64)                                          ' SS/RM092301
  1392.      CALL PutScreen ("^K Lists Menu",GreenFore, DefaultBold)         ' SS
  1393.      END SUB
  1394.