home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / EDITWIN / EDITWIN.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-23  |  23KB  |  802 lines

  1. {$X+}
  2. {**************************************************************}
  3. {                                                              }
  4. {           Saved as: EDITWIN.PAS                              }
  5. {           Language: Turbo Pascal 6                           }
  6. {             Author: Pat Anderson                             }
  7. {            Purpose: Drop in Editor object                    }
  8. {      Last modified: Mon 10-22-92                             }
  9. {                                                              }
  10. {**************************************************************}
  11.  
  12. unit EditWin;
  13.  
  14. interface
  15.  
  16. uses
  17.   Crt,
  18.   Minikit,        { Non-OOP mini-toolkit }
  19.   O_Tbuf,         { OOP text buffer unit }
  20.   EdLine;         { non-OOP line editor }
  21.  
  22. type
  23.   TStatusProc = procedure;
  24.   TMode = (EditOK, ReadOnly);
  25.   PEditWindow = ^TEditWindow;
  26.   TEditWindow = object
  27.     Header : string;
  28.     LeftX, TopY, RightX, BottomY,
  29.     EditWindowHeight, EditWindowWidth :  byte;
  30.     TopLine, CurrentLine : integer;
  31.     Cursor, Col, Row : byte;
  32.     InsertFlag,
  33.     WindowOpen : boolean;
  34.     SavedScreen : TSavedScreenInfo;
  35.     WindowCoords : TWindowCoords;
  36.     StatusProc : TStatusProc;
  37.     theTextBuffer : PTextBuffer;
  38.     ExitKey : char;
  39.     EditAllowed : boolean;
  40.     FileName : string;
  41.     SaveLine : string;
  42.     constructor Init (Left, Top, Right, Bottom : byte;
  43.                       HeaderMsg : string;
  44.                       TextBuffer : PTextBuffer; Mode : TMode);
  45.     procedure ShowWindow;
  46.     procedure HideWindow;
  47.     procedure SetFileName (Name : string);
  48.     procedure Process;
  49.     function GetFileName : string;
  50.     function GetExitKey : char;
  51.     destructor Done;
  52.   end;
  53.  
  54. implementation
  55.   var
  56.     SaveAttr : byte;
  57.     StatusX,
  58.     StatusY : byte;
  59.     Line : integer;
  60.     FName : string;
  61.  
  62.   {$F+}
  63.   procedure UpdateStatus;
  64.     var
  65.       ColStr,
  66.       LineStr,
  67.       StatusText : string;
  68.     begin
  69.       Str (CursorPosition - StartColumn + 1:2, ColStr);
  70.       Str (Line:3, LineStr);
  71.       StatusText := ' Col ' + ColStr + ' Line ' + LineStr + ' ';
  72.       if FName <> '' then
  73.         StatusText := StatusText + '  ' + FName + ' ';
  74.       FastWrite (StatusText, StatusY, StatusX, Edit_Attr);
  75.     end;
  76.   {$F-}
  77.  
  78.   constructor TEditWindow.Init (Left, Top, Right, Bottom : byte;
  79.                                 HeaderMsg : string;
  80.                                 TextBuffer : PTextBuffer; Mode : TMode);
  81.     begin
  82.       if HeaderMsg <> '' then
  83.         Header := HeaderMsg
  84.       else Header := '';
  85.       LeftX := Left; TopY := Top;
  86.       RightX := Right; BottomY := Bottom;
  87.       theTextBuffer := TextBuffer;
  88.       if Mode = EditOK then
  89.         EditAllowed := true
  90.       else
  91.         EditAllowed := false;
  92.       FileName := '';
  93.       EditWindowHeight := BottomY - TopY - 1;
  94.       EditWindowWidth := RightX - LeftX - 2;
  95.       TextAttr := Text_Attr;
  96.       TopLine := 1;
  97.       CurrentLine := 1;
  98.       Col := 1;
  99.       Cursor := Col;
  100.       Row := 1;
  101.       InsertFlag := false;
  102.       WindowOpen := false;
  103.     end;
  104.  
  105. procedure TEditWindow.ShowWindow;
  106.   begin
  107.     SaveScreen (SavedScreen);
  108.     DrawBox (LeftX, TopY, RightX, BottomY, Text_Attr);
  109.     Window (LeftX + 1, TopY + 1, RightX - 1, BottomY - 1);
  110.     ClrScr;
  111.     WindowOpen := true;
  112.   end;
  113.  
  114. procedure TEditWindow.HideWindow;
  115.   begin
  116.     RestoreScreen (SavedScreen);
  117.     WindowOpen := false;
  118.   end;
  119.  
  120. procedure TEditWindow.SetFileName (Name : string);
  121.   begin
  122.     FileName := ToUpper (Name);
  123.   end;
  124.  
  125. procedure TEditWindow.Process;
  126.   var
  127.     UserQuits : boolean;
  128.     Key : char;
  129.     CurrentLineStr : string;
  130.     TitleStr : string;
  131.  
  132.   procedure RedrawScreen;
  133.     var
  134.       Row : byte;
  135.     begin
  136.       CursorOff;
  137.       Row := 1;
  138.       while Row <= EditWindowHeight do begin
  139.         GotoXY (1, Row); ClrEOL;
  140.         Write (Copy (theTextBuffer^.StringFromArray (TopLine + Row - 1),
  141.                1, EditWindowWidth));
  142.         Inc (Row);
  143.       end;
  144.     end;
  145.  
  146.   procedure ScrollScreenUp;
  147.     var
  148.       Difference : byte;
  149.     begin
  150.       Difference := CurrentLine - TopLine;
  151.       TopLine := TopLine + EditWindowHeight;
  152.       if TopLine > theTextBuffer^.TotalLines - EditWindowHeight then
  153.         TopLine := theTextBuffer^.TotalLines - EditWindowHeight;
  154.       CurrentLine := TopLine + Difference;
  155.  
  156.       RedrawScreen;
  157.     end;
  158.  
  159.   procedure ScrollScreenDown;
  160.     var
  161.       Difference : byte;
  162.     begin
  163.       Difference := CurrentLine - TopLine;
  164.       TopLine := TopLine - EditWindowHeight;
  165.       if TopLine < 1 then
  166.         TopLine := 1;
  167.       CurrentLine := TopLine + Difference;
  168.       RedrawScreen;
  169.     end;
  170.  
  171.   procedure DeleteLine;
  172.     begin
  173.       SaveLine := theTextBuffer^.StringFromArray (CurrentLine);
  174.       theTextBuffer^.DeleteLineFromArray (CurrentLine);
  175.       RedrawScreen;
  176.     end;
  177.  
  178.   procedure UndeleteLine;
  179.     var
  180.       OK : boolean;
  181.     begin
  182.       OK := theTextBuffer^.InsertLine (SaveLine, CurrentLine);
  183.       RedrawScreen;
  184.     end;
  185.  
  186.   procedure TopOfFile;
  187.     begin
  188.       CurrentLine := 1;
  189.       TopLine := 1;
  190.       Row := 1;
  191.       RedrawScreen;
  192.     end;
  193.  
  194.   PROCEDURE CursorUpOneLine;
  195.     BEGIN
  196.       if CurrentLine > 1 then
  197.         Dec (CurrentLine)
  198.       else
  199.         Exit;
  200.  
  201.       { Up one line on same screen }
  202.       if Row > 1 then begin
  203.         Dec (Row);
  204.         Exit;
  205.       end;
  206.  
  207.       { if not room on screen then scroll }
  208.       if Row = 1 then begin
  209.         Dec (TopLine);
  210.         if TopLine < 1 then TopLine := 1;
  211.         RedrawScreen;
  212.       end;
  213.     END;  {of procedure CursorUpOneLine}
  214.  
  215.   PROCEDURE CursorDownOneLine;
  216.     BEGIN
  217.       if ExitKey = DownArrow then
  218.         if CurrentLine >= theTextBuffer^.TotalLines + 1 then
  219.           Exit;
  220.  
  221.       Inc (CurrentLine);
  222.       Inc (Row);
  223.  
  224.       if Row > EditWindowHeight then begin
  225.         Inc (TopLine);
  226.         Row := EditWindowHeight;
  227.         RedrawScreen;
  228.       end;
  229.  
  230.       IF (ExitKey = Enter) or (ExitKey = RightArrow) THEN
  231.         Cursor := 1;
  232.  
  233.     END;  {of procedure CursorDownOneline}
  234.  
  235.   procedure SplitLine;
  236.     var
  237.       CurrentLineStr,
  238.       RightPart : string;
  239.       Count : byte;
  240.     begin
  241.       CurrentLineStr := theTextBuffer^.StringFromArray (CurrentLine);
  242.       Count := Length (CurrentLineStr) - Cursor + 1;
  243.       RightPart := RightStr (CurrentLineStr, Count);
  244.       Delete (CurrentLineStr, Cursor, Count);
  245.       theTextBuffer^.StringToArray (CurrentLineStr, CurrentLine);
  246.       theTextBuffer^.InsertLine (RightPart, CurrentLine + 1);
  247.     end;
  248.  
  249.   procedure DoEnter;
  250.     begin
  251.       if InsertFlag then
  252.         SplitLine;
  253.       CursorDownOneLine;
  254.       if InsertFlag then
  255.         RedrawScreen;
  256.     end;
  257.  
  258.   procedure DoBackSpace;
  259.     var
  260.       TempStr : string;
  261.       OK : boolean;
  262.     begin
  263.       if CurrentLine = 1 then begin
  264.         Cursor := Col;
  265.         Exit;
  266.       end;
  267.       if CurrentLine > 1 then begin
  268.         TempStr := theTextBuffer^.StringFromArray (CurrentLine - 1);
  269.         TempStr := Copy (TempStr, 1, Length (TempStr) - 1);
  270.         OK := theTextBuffer^.StringToArray (TempStr, CurrentLine - 1);
  271.         CursorUpOneLine;
  272.         if Cursor < 1 then
  273.           Cursor := EditWindowWidth;
  274.       end;
  275.     end;
  276.  
  277.   function ReformText (StartLine : integer) : integer;
  278.     var
  279.       Index : integer;
  280.       CurrentStr,
  281.       NextStr : string;
  282.       SpaceAvailable,
  283.       LengthOfFirstWord : byte;
  284.       OK,
  285.       CurrentLineDone,
  286.       Done : boolean;
  287.  
  288.     { Returns the length of the first word of NextStr }
  289.     function GetLengthOfFirstWord : byte;
  290.       var
  291.         Position : byte;
  292.       begin
  293.         if Length (NextStr) = 0 then begin
  294.           GetLengthOfFirstWord := 0;
  295.           Exit;
  296.         end;
  297.         Position := 1;
  298.         while (NextStr[Position] <> Space) and (Position <= Length (NextStr)) do
  299.           Inc (Position);
  300.         if Position < Length (NextStr) then
  301.           Dec (Position);
  302.         GetLengthOfFirstWord := Position;
  303.       end;
  304.  
  305.     { Returns the space available in CurrentStr }
  306.     function GetSpaceAvailable : byte;
  307.       var
  308.         SpaceAvailable : byte;
  309.       begin
  310.         SpaceAvailable := EditWindowWidth - Length (CurrentStr) - 1;
  311.         if SpaceAvailable < 0 then
  312.           SpaceAvailable := 0;
  313.         GetSpaceAvailable := SpaceAvailable;
  314.       end;
  315.  
  316.     { Moves first word of NextStr to last position of CurrentStr }
  317.     procedure MoveWordUp;
  318.       var
  319.         FirstWord : string;
  320.       begin
  321.         if Length (NextStr) = 0 then begin
  322.           CurrentLineDone := true;
  323.           Exit;
  324.         end;
  325.  
  326.         LengthOfFirstWord := GetLengthOfFirstWord;
  327.         FirstWord := Copy (NextStr, 1, LengthOfFirstWord);
  328.  
  329.         if (Length (CurrentStr) + LengthOfFirstWord + 1) > EditWindowWidth
  330.         then begin
  331.           CurrentLineDone := true;
  332.           Exit;
  333.         end;
  334.  
  335.         CurrentStr := CurrentStr + ' ' + FirstWord;
  336.  
  337.         Delete (NextStr, 1, LengthOfFirstWord);
  338.         while NextStr[1] = Space do
  339.           Delete (NextStr, 1, 1);
  340.       end;
  341.  
  342.     { Fill out the current line with as many words as fit in EditWindowWidth }
  343.     procedure FillCurrentLine;
  344.       begin
  345.         CurrentLineDone := false;
  346.         while not CurrentLineDone do begin
  347.           if Length (NextStr) = 0 then begin
  348.             theTextBuffer^.DeleteLineFromArray (Index + 1);
  349.             if theTextBuffer^.TextArray^[Index + 1] <> nil then
  350.               NextStr := theTextBuffer^.StringFromArray (Index + 1)
  351.             else
  352.               CurrentLineDone := true;
  353.             if (NextStr = '') or (NextStr[1] = ' ') then begin
  354.               CurrentLineDone := true;
  355.               Done := true;
  356.             end;
  357.           end;
  358.           if not CurrentLineDone then
  359.             MoveWordUp;
  360.         end;
  361.         OK := theTextBuffer^.StringToArray (CurrentStr, Index);
  362.         if Length (NextStr) > 0 then
  363.           OK := theTextBuffer^.StringToArray (NextStr, Index + 1);
  364.       end;
  365.  
  366.   { Main of ReformText }
  367.   begin
  368.     Index := StartLine;
  369.     Done := false;
  370.     repeat
  371.       CurrentStr := theTextBuffer^.StringFromArray (Index);
  372.       (*
  373.       if theTextBuffer^.TextArray^[Index + 1] <> nil then
  374.         NextStr := theTextBuffer^.StringFromArray (Index + 1)
  375.       else
  376.         Done := true;
  377.       *)
  378.       if Index = theTextBuffer^.TotalLines then
  379.         Done := true
  380.       else
  381.         NextStr := theTextBuffer^.StringFromArray (Index + 1);
  382.  
  383.       if (NextStr = '') or (NextStr[1] = ' ') then
  384.         Done := true;
  385.  
  386.       if not Done then
  387.         FillCurrentLine;
  388.  
  389.       Inc (Index);
  390.     until Done;
  391.     ReformText := Index - StartLine;
  392.     RedrawScreen;
  393.   end;
  394.  
  395.   procedure GlobalReform;
  396.     var
  397.       Index : integer;
  398.     begin
  399.       Index := 1;
  400.       while theTextBuffer^.TextArray^[Index] <> nil do
  401.         Index := Index + ReformText (Index);
  402.       RedrawScreen;
  403.     end;
  404.  
  405.   function InputFileName : string;
  406.     var
  407.       FileName : string;
  408.       Cursor : byte;
  409.       ExitKey : char;
  410.       InsertFlag : boolean;
  411.       SaveRow,
  412.       SaveCursor : byte;
  413.     begin
  414.       InsertFlag := False;
  415.       SaveCursor := WhereX;
  416.       SaveRow := WhereY;
  417.       Cursor := 11;
  418.       FileName := '';
  419.       Window (LeftX + 1, TopY + 1, RightX - 1, BottomY);
  420.       TextAttr := Status_Attr;
  421.       GotoXY (1, EditWindowHeight + 1); ClrEOL;
  422.       Write ('Filename: ');
  423.       ExitKey := EditLn (FileName,
  424.                          Status_Attr,
  425.                          InsertFlag,
  426.                          Cursor, 11, EditWindowHeight + 1,
  427.                          EditWindowWidth - 11,
  428.                          true,
  429.                          DoNothing);
  430.     if ExitKey = Enter then
  431.       InputFileName := ToUpper (FileName)
  432.     else
  433.       InputFileName := '';
  434.     Window (LeftX + 1, TopY + 1, RightX - 1, BottomY - 1);
  435.     TextAttr := Text_Attr;
  436.     GotoXY (SaveCursor, SaveRow);
  437.     DrawBox (LeftX, TopY, RightX, BottomY, Edit_Attr);
  438.     FastWrite (Header, TopY, Leftx + 2, Edit_Attr);
  439.   end;
  440.  
  441.   procedure ChopLongLine (var Line : string; Index : integer);
  442.     var
  443.       LeftPart : string;
  444.       Position : byte;
  445.       OK : boolean;
  446.     begin
  447.       Position := EditWindowWidth;
  448.       while (line[Position] <> Space) and (Position >= 0) do
  449.         Dec (Position);
  450.       if Position = 0 then
  451.         Position := EditWindowWidth;
  452.       LeftPart := Copy (line, 1, Position);
  453.       LeftPart := Strip (LeftPart);
  454.       OK := theTextBuffer^.StringToArray (LeftPart, Index);
  455.       Delete (line, 1, Position);
  456.       while line[1] = Space do
  457.         Delete (line, 1, 1);
  458.     end;
  459.  
  460.   procedure LoadFile;
  461.     var
  462.       Index : integer;
  463.       F : text;
  464.       line : string;
  465.       OK : boolean;
  466.       ErrorStr : string;
  467.  
  468.     begin
  469.  
  470.       Assign (F, Filename);
  471.       {$I-} Reset (F); {$I+}
  472.       OK := IOResult = 0;
  473.       if not OK then begin
  474.         ErrorStr := MakeString (EditWindowWidth, ' ');
  475.         ErrorStr := Merge ('File not found - press a key',
  476.                             ErrorStr, 1);
  477.         FastWrite (ErrorStr, BottomY, LeftX + 1, Status_Attr);
  478.         Pause;
  479.         FName := '';
  480.         Exit;
  481.       end;
  482.  
  483.       { Clear out current text, reset variables }
  484.       theTextBuffer^.ClearTextArray;
  485.       CurrentLine := 1;
  486.       TopLine := 1;
  487.       Row := 1;
  488.       Col := 1;
  489.       Cursor := Col;
  490.  
  491.       Index := 0;
  492.       while not EOF (F) do begin
  493.         Inc (Index);
  494.         ReadLn (F, line);
  495.         {if Length (line) > EditWindowWidth then begin}
  496.         while Length (line) > EditWindowWidth do begin
  497.           ChopLongLine (Line, Index);
  498.           Inc (Index);
  499.         end;
  500.         {end;}
  501.         OK := theTextBuffer^.StringToArray (line, Index);
  502.       end;
  503.       Close (F);
  504.       RedrawScreen;
  505.     end;
  506.  
  507.   procedure NewFile;
  508.     var
  509.       SaveFileName : string;
  510.     begin
  511.       SaveFileName := FileName;
  512.       { Get name of file to load, error message if not found }
  513.       FileName := InputFileName;
  514.       if FileName = '' then begin
  515.         FileName := SaveFileName;
  516.         Exit;
  517.       end else
  518.         LoadFile;
  519.     end;
  520.  
  521.   procedure SaveFile;
  522.     var
  523.       F : text;
  524.       line : string;
  525.       OK : boolean;
  526.       Index : integer;
  527.     begin
  528.       if FileName = '' then begin
  529.         FileName := InputFileName;
  530.         FName := FileName;
  531.       end;
  532.       Assign (F, FileName);
  533.       {$I-} Rewrite (F); {$I-}
  534.       OK := IOResult = 0;
  535.       Index := 0;
  536.       while Index <= theTextBuffer^.TotalLines do begin
  537.         Inc (Index);
  538.         if theTextBuffer^.TextArray^[Index] <> nil then
  539.           WriteLn (F, theTextBuffer^.StringFromArray (Index));
  540.       end;
  541.       Close (F);
  542.     end;
  543.  
  544.   function WrapWord (var Current, Next : string) : byte;
  545.     var
  546.       Position : byte;
  547.       WordToWrap : string;
  548.     begin
  549.       WordToWrap := '';
  550.       { Find the start of last word on the current line }
  551.       Position := Length (Current);
  552.       while Current[Position] <> ' ' do
  553.         Dec (Position);
  554.       WordToWrap := Copy (Current, Position + 1, 255);
  555.       if (InsertFlag) and (Next[1] <> ' ') and (Cursor < Length (Current)) then
  556.         WordToWrap := WordToWrap + ' ';
  557.       Delete (Current, Position, 255);
  558.       if not InsertFlag then
  559.         Delete (Next, 1, Length (WordToWrap));
  560.       Insert (WordToWrap, Next, 1);
  561.       WrapWord := Length (WordToWrap);
  562.     end;
  563.  
  564.   procedure WrapText;
  565.     var
  566.       Index : integer;
  567.       Current,
  568.       Next : string;
  569.       OK,
  570.       Done : boolean;
  571.       WrapLength,
  572.       FirstWrapLength,
  573.       DummyLength,
  574.       Position,
  575.       LineLength,
  576.       Difference : byte;
  577.       Iterations : integer;
  578.  
  579.     begin
  580.       Index := CurrentLine;
  581.       Done := false;
  582.       Iterations := 0;
  583.       LineLength := Length (theTextBuffer^.StringFromArray (CurrentLine));
  584.  
  585.       repeat
  586.         Current := theTextBuffer^.StringFromArray (Index);
  587.         (*
  588.         if Index < theTextBuffer^.TotalLines then begin
  589.           Next := theTextBuffer^.StringFromArray (Index + 1);
  590.           if (Next = '') then begin
  591.             OK := theTextBuffer^.InsertLine ('', Index + 1);
  592.             Done := true;
  593.           end
  594.         end else
  595.           Next := '';
  596.         *)
  597.  
  598.         if theTextBuffer^.TextArray^[Index + 1] = nil then
  599.           OK := theTextBuffer^.InsertLine ('', Index + 1);
  600.         Next := theTextBuffer^.StringFromArray (Index + 1);
  601.  
  602.         WrapLength := WrapWord (Current, Next);
  603.  
  604.  
  605.         if Iterations = 0 then
  606.           FirstWrapLength := WrapLength;
  607.         (*
  608.         while Length (Current) > EditWindowWidth do
  609.           DummyLength := WrapWord (Current, Next);
  610.         *)
  611.  
  612.         { Save the lines as wrapped }
  613.         OK := theTextBuffer^.StringToArray (Current, Index);
  614.         OK := theTextBuffer^.StringToArray (Next, Index + 1);
  615.  
  616.         if not InsertFlag then
  617.           Done := true;
  618.         if Length (Next) <= EditWindowWidth then
  619.           Done := true;
  620.  
  621.         { Insert mode }
  622.         if InsertFlag then begin
  623.           Inc (Index);
  624.           Inc (Iterations);
  625.         end;
  626.     until Done;
  627.  
  628.     { Update screen }
  629.     (*
  630.     if not InsertFlag then begin
  631.       GotoXY (Col, Row); ClrEOL;
  632.       Write (Current);
  633.       OK := theTextBuffer^.StringToArray (Next, Index + 1);
  634.       GotoXY (Col, Row + 1); ClrEOL;
  635.       Write (Next);
  636.     end else
  637.     *)
  638.     RedrawScreen;
  639.  
  640.     { Position the cursor }
  641.     if InsertFlag then begin
  642.       { Cursor is past end of line }
  643.       if Cursor > LineLength then begin
  644.         CursorDownOneLine;
  645.         Cursor := FirstWrapLength + 1;
  646.       end;
  647.  
  648.       { Cursor is in the word that will be wrapped, i.e.
  649.         pushing text right  }
  650.       Difference := LineLength  - Cursor;
  651.       if Difference < FirstWrapLength then begin
  652.         CursorDownOneLine;
  653.         Cursor := FirstWrapLength - Difference - 1;
  654.       end;
  655.     end;
  656.  
  657.     if not InsertFlag then begin
  658.       Cursor := WrapLength + 1;
  659.       CursorDownOneLine;
  660.     end;
  661.   end;
  662.  
  663.  
  664.   {====================== START OF PROCESS =========================}
  665.   begin
  666.     if not WindowOpen then begin
  667.       WriteLn ('Can''t Process in an EditWindow until you OpenWindow!!');
  668.       Halt;
  669.     end;
  670.     StatusProc := UpdateStatus;
  671.     UserQuits := false;
  672.     FName := FileName;
  673.     if FileName <> '' then
  674.       LoadFile;
  675.     StatusX := LeftX + 2;
  676.     StatusY := BottomY;
  677.     DrawBox (LeftX, TopY, RightX, BottomY, Edit_Attr);
  678.     FastWrite (Header, TopY, Leftx + 2, Edit_Attr);
  679.     SaveLine := '';
  680.     Window (LeftX + 1, TopY + 1, RightX - 1, BottomY - 1);
  681.     RedrawScreen;
  682.  
  683.     {==================== Main Loop =====================}
  684.     repeat
  685.       if EditAllowed then begin
  686.  
  687.         {Get current line from array}
  688.         CurrentLineStr := theTextBuffer^.StringFromArray (CurrentLine);
  689.  
  690.         { Needed for the UpdateStatus procedure }
  691.         Line := CurrentLine;
  692.  
  693.         { Call line editor to edit the string }
  694.         ExitKey := EditLn (CurrentLineStr,
  695.                            Edit_Attr,
  696.                            InsertFlag,
  697.                            Cursor,
  698.                            Col, Row,
  699.                            EditWindowWidth,
  700.                            false,
  701.                            StatusProc);
  702.  
  703.         if not theTextBuffer^.StringToArray (CurrentLineStr, CurrentLine) then
  704.             begin end;
  705.  
  706.         GotoXY (1, Row); Write (CurrentLineStr);
  707.  
  708.         { Act on the key press that terminated editing current line }
  709.         case ExitKey of
  710.           #33..#127       : WrapText;
  711.           RightArrow,
  712.           DownArrow       : CursorDownOneLine;
  713.           Enter           : DoEnter;
  714.           LeftArrow       : begin
  715.                               if CurrentLine > 1 then
  716.                                 Cursor := EditWindowWidth
  717.                               else
  718.                                 Cursor := 1;
  719.                               CursorUpOneLine;
  720.                             end;
  721.           UpArrow         : CursorUpOneLine;
  722.           BackSpace       : DoBackSpace;
  723.           AltR            : RedrawScreen;
  724.           AltC            : begin
  725.                               theTextBuffer^.ClearTextArray;
  726.                               TopLine := 1;
  727.                               CurrentLine := 1;
  728.                               Row := 1;
  729.                               Cursor := 1;
  730.                               ClrScr;
  731.                             end;
  732.           PgDn            : ScrollScreenUp;
  733.           PgUp            : ScrollScreenDown;
  734.           ^Y              : DeleteLine;
  735.           ^U              : UndeleteLine;
  736.           AltB,
  737.           AltJ            : ReformText (CurrentLine);
  738.           AltG            : GlobalReform;
  739.           CtlHome         : TopOfFile;
  740.           F9              : NewFile;
  741.           F10             : SaveFile;
  742.         else
  743.           UserQuits := true;
  744.         end; {of case}
  745.       end else begin
  746.         RedrawScreen;
  747.         Key := GetKey (DoNothing);
  748.         case Key of
  749.           Esc,
  750.           Tab,
  751.           AltX            : begin
  752.                               UserQuits := true;
  753.                               ExitKey := Key;
  754.                             end;
  755.           AltG            : GlobalReform;
  756.           Home,
  757.           CtlHome         : TopLine := 1;
  758.           UpArrow         : if TopLine > 1 then
  759.                               Dec (TopLine);
  760.           DownArrow       : if TopLine < theTextBuffer^.TotalLines then
  761.                               Inc (TopLine);
  762.           PgUp            : begin
  763.                               TopLine := TopLine - EditWindowHeight;
  764.                               if TopLine < 1 then
  765.                                 TopLine := 1;
  766.                             end;
  767.           PgDn            : begin
  768.                               TopLine := TopLine + EditWindowHeight;
  769.                               if TopLine > theTextBuffer^.TotalLines then
  770.                                 TopLine := theTextbuffer^.TotalLines;
  771.                             end;
  772.           F9              : LoadFile;
  773.         else
  774.           UserQuits := true;
  775.         end; { case }
  776.       end;  { else }
  777.     until UserQuits;
  778.     DrawBox (LeftX, TopY, RightX, BottomY, Text_Attr);
  779.   end;
  780.  
  781.   function TEditWindow.GetFileName : string;
  782.     begin
  783.       GetFileName := FileName;
  784.     end;
  785.  
  786.   function TEditWindow.GetExitKey : char;
  787.     begin
  788.       GetExitKey := ExitKey;
  789.     end;
  790.  
  791.   destructor TEditWindow.Done;
  792.     begin
  793.       Window (1, 1, 80, 25);
  794.       TextAttr := SaveAttr;
  795.       ClrScr;
  796.     end;
  797.  
  798. begin
  799.   FName := '';
  800.   SaveAttr := TextAttr;
  801. end.
  802.