home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tvision / newed / newedit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-10-31  |  156.3 KB  |  6,156 lines

  1. { FILE:  newedit.pas }
  2.  
  3.  
  4.  
  5. unit NewEdit;
  6.  
  7.  
  8.  
  9. { ******************************************************************** }
  10. {                                                                      }
  11. { NOTICE:  The following code was written by Borland International.    }
  12. {          The code is for use by TP6.0 users.  Keep the copyright     }
  13. {          notice intact!                                              }
  14. {                                                                      }
  15. {          Turbo Pascal 6.0                                            }
  16. {          Turbo Vision Demo                                           }
  17. {          Copyright (c) 1990 by Borland International                 }
  18. {                                                                      }
  19. {          I have taken the liberty of prettying up the source.        }
  20. {          I have also taken the liberty of adding additional features.}
  21. {          Search for the following keywords and compare your original }
  22. {          editors code to any code between the Start/Stop comments    }
  23. {          for changes.                                                }
  24. {                                                                      }
  25. { Label    Description:                                                }
  26. { ------   ------------                                                }
  27. {                                                                      }
  28. { CENTER - Added a feature to center text on a line.                   }
  29. {          Centering only works to Right_Margin.                       }
  30. {                                                                      }
  31. { CTRLBK - Added new key to map to ^QH.  Does the same thing.          }
  32. {                                                                      }
  33. { HOMEND - Added feature to move cursor to top and bottom of page      }
  34. {          using the [Ctrl]-[Home] and [Ctrl]-[End] keys.              }
  35. {                                                                      }
  36. { LOAD   - Fixed bug that prevented load operations and added new      }
  37. {          stream reads to handle new TEditor objects.                 }
  38. {                                                                      }
  39. { MARK   - A place mark type feature.  Exactly the same as WordStar's  }
  40. {          ^K# and ^Q#, except that the mark is for the exact poistion }
  41. {          the cursor is at in a line, not just the start of a line.   }
  42. {                                                                      }
  43. { INDENT - Change AutoIndent from a ^O to a ^QI call.                  }
  44. {                                                                      }
  45. { INSLIN - Insert new line at cursor and maintain cursor position.     }
  46. {                                                                      }
  47. { JLINE  - A jump to line number feature.  Pressing ^JL will bring     }
  48. {          up a dialog box asking the line number to jump to.          }
  49. {                                                                      }
  50. { PRETAB - Preset tab feature.  Tabs are preset in increments of 7.    }
  51. {          The user can call up a dialog and set the tabs in any way   }
  52. {          they want.  Uses WordStar ^OI feature.  Note that a "real"  }
  53. {          tab (^I) is no longer supported.  Tabs are converted to     }
  54. {          spaces if you are inserting text, and only move the cursor  }
  55. {          to the next tab stop if you are overwriting text.           }
  56. {                                                                      }
  57. { REFDOC - Reformats a document from either the beginning or the       }
  58. {          current line the cursor is on.                              }
  59. {                                                                      }
  60. { REFORM - Reformats a paragraph to the Right_Margin setting.          }
  61. {          This feature works regardless if wordwrap is active,        }
  62. {          as a standalone ^B call.                                    }
  63. {                                                                      }
  64. { RMSET  - User can set the Right_Margin by pressing ^OR.  A dialog    }
  65. {          box comes up asking you for the Right_Margin you want.      }
  66. {          The dialog box has the current Right_Margin displayed in    }
  67. {          it.  There is only one dialog button "cmOK."  Selecting     }
  68. {          this button, or aborting, will maintain the current margin. }
  69. {          Default Right_Margin is 76.  Valid entries are >10 or < 256.}
  70. {                                                                      }
  71. { SAVE   - Add new save options.  Keep F2 as the default cmSave to     }
  72. {          save file and continue editing, but tie ^KS to it also.     }
  73. {          Add ^KT to cmSaveAs to save current file to another file.   }
  74. {          Add ^KD and ^KX as cmSaveDone to do an immediate save and   }
  75. {          automatically remove the editor from the desktop.           }
  76. {                                                                      }
  77. { SCRLBG - Added a bug fix so editor doesn't consume ScrollbarChanged  }
  78. {          events.                                                     }
  79. {                                                                      }
  80. { SCRLDN - Added feature to scroll the screen up a line-at-a-time      }
  81. {          by pressing ^Z.                                             }
  82. {                                                                      }
  83. { SCRLUP - Added feature to scroll the screen down a line-at-a-time    }
  84. {          by pressing ^W.                                             }
  85. {                                                                      }
  86. { SELWRD - Added feature to select a word only by pressing ^KT.        }
  87. {                                                                      }
  88. { STATS  - Changed the appearance of the PIndicator line.              }
  89. {          It now shows "M" for modified, "I" for AutoIndent,          }
  90. {          and "W" for wordwrap.                                       }
  91. {                                                                      }
  92. { STORE  - Fixed bug that prevented store operations and added new     }
  93. {          stream writes to handle new TEditor objects.  Send thanks   }
  94. {          to Johnathan Stein CIS: 76576,470 in the form of a lollipop }
  95. {          for finding this bug.                                       }
  96. {                                                                      }
  97. { UNDO   - Added IDE ^QL undo feature.  ^U is still functional.        }
  98. {                                                                      }
  99. { WRAP   - A word wrap modification.  Allows user to toggle wordwrap   }
  100. {          on or off.  If on, wordwrap will occur when the cursor      }
  101. {          reaches +1 of the current Right_Margin setting.  Wrap works }
  102. {          as a "push the line out until cursor gets to Right_Margin"  }
  103. {          principle.  Wordwrap also supports the AutoIndent feature.  }
  104. {                                                                      }
  105. { Al Andersen - 10/31/93.                                              }
  106. {                                                                      }
  107. { ******************************************************************** }
  108.  
  109.  
  110. {$F+,I-,O+,Q-,S-,V-,X+,D-}
  111.  
  112.  
  113.  
  114. interface
  115.  
  116. uses Drivers,
  117.      Objects,
  118.      Views;
  119.  
  120.  
  121.  
  122. CONST { Command constants for saving files and finding text. }
  123.  
  124.   cmSave        = 80;
  125.   cmSaveAs      = 81;
  126.   cmFind        = 82;
  127.   cmReplace     = 83;
  128.   cmSearchAgain = 84;
  129.  
  130.   { SAVE - Start. }
  131.  
  132.   cmSaveDone    = 85;
  133.  
  134.   { SAVE - Stop.  }
  135.  
  136.  
  137.  
  138. CONST { New editor commands that user may want to put into a menu. }
  139.  
  140.   { CENTER - Start. }
  141.   { HOMEND - Start. }
  142.   { INSLIN - Start. }
  143.   { JLINE  - Start. }
  144.   { MARK   - Start. }
  145.   { PRETAB - Start. }
  146.   { REFDOC - Start. }
  147.   { REFORM - Start. }
  148.   { RMSET  - Start. }
  149.   { SCRLDN - Start. }
  150.   { SCRLDN - Start. }
  151.   { SELWRD - Start. }
  152.   { WRAP   - Start. }
  153.  
  154.   cmCenterText  = 200;
  155.   cmEndPage     = 201;
  156.   cmHomePage    = 202;
  157.   cmIndentMode  = 203;
  158.   cmInsertLine  = 204;
  159.   cmJumpLine    = 205;
  160.   cmJumpMark0   = 206;
  161.   cmJumpMark1   = 207;
  162.   cmJumpMark2   = 208;
  163.   cmJumpMark3   = 209;
  164.   cmJumpMark4   = 210;
  165.   cmJumpMark5   = 211;
  166.   cmJumpMark6   = 212;
  167.   cmJumpMark7   = 213;
  168.   cmJumpMark8   = 214;
  169.   cmJumpMark9   = 215;
  170.   cmReformDoc   = 216;
  171.   cmReformPara  = 217;
  172.   cmRightMargin = 218;
  173.   cmScrollDown  = 219;
  174.   cmScrollUp    = 220;
  175.   cmSelectWord  = 221;
  176.   cmSetMark0    = 222;
  177.   cmSetMark1    = 223;
  178.   cmSetMark2    = 224;
  179.   cmSetMark3    = 225;
  180.   cmSetMark4    = 226;
  181.   cmSetMark5    = 227;
  182.   cmSetMark6    = 228;
  183.   cmSetMark7    = 229;
  184.   cmSetMark8    = 230;
  185.   cmSetMark9    = 231;
  186.   cmSetTabs     = 232;
  187.   cmTabKey      = 233;
  188.   cmWordWrap    = 234;
  189.  
  190.  
  191.   { WRAP   - Stop. }
  192.   { SELWRD - Stop. }
  193.   { SCRLUP - Stop. }
  194.   { SCRLDN - Stop. }
  195.   { RMSET  - Stop. }
  196.   { REFORM - Stop. }
  197.   { REFDOC - Stop. }
  198.   { PRETAB - Stop. }
  199.   { MARK   - Stop. }
  200.   { JLINE  - Stop. }
  201.   { INSLIN - Stop. }
  202.   { HOMEND - Stop. }
  203.   { CENTER - Stop. }
  204.  
  205.  
  206.  
  207. CONST { Command constants for cursor movement and modifying text. }
  208.  
  209.   cmCharLeft      = 500;
  210.   cmCharRight     = 501;
  211.   cmWordLeft      = 502;
  212.   cmWordRight     = 503;
  213.   cmLineStart     = 504;
  214.   cmLineEnd       = 505;
  215.   cmLineUp        = 506;
  216.   cmLineDown      = 507;
  217.   cmPageUp        = 508;
  218.   cmPageDown      = 509;
  219.   cmTextStart     = 510;
  220.   cmTextEnd       = 511;
  221.   cmNewLine       = 512;
  222.   cmBackSpace     = 513;
  223.   cmDelChar       = 514;
  224.   cmDelWord       = 515;
  225.   cmDelStart      = 516;
  226.   cmDelEnd        = 517;
  227.   cmDelLine       = 518;
  228.   cmInsMode       = 519;
  229.   cmStartSelect   = 520;
  230.   cmHideSelect    = 521;
  231.   cmUpdateTitle   = 523;
  232.  
  233.   { STATS - Start. }
  234.  
  235.   cmBludgeonStats = 524;
  236.  
  237.   { STATS - Stop. } { Needed this for TEditWindow.HandleEvent }
  238.  
  239.  
  240.  
  241. CONST { Editor constants for dialog boxes. }
  242.  
  243.   edOutOfMemory   = 0;
  244.   edReadError     = 1;
  245.   edWriteError    = 2;
  246.   edCreateError   = 3;
  247.   edSaveModify    = 4;
  248.   edSaveUntitled  = 5;
  249.   edSaveAs        = 6;
  250.   edFind          = 7;
  251.   edSearchFailed  = 8;
  252.   edReplace       = 9;
  253.   edReplacePrompt = 10;
  254.  
  255.   { JLINE  - Start. }
  256.   { PRETAB - Start. }
  257.   { REFDOC - Start. }
  258.   { RMSET  - Start. }
  259.   { WRAP   - Start. }
  260.  
  261.   edJumpToLine         = 11;
  262.   edPasteNotPossible   = 12;
  263.   edReformatDocument   = 13;
  264.   edReformatNotAllowed = 14;
  265.   edReformNotPossible  = 15;
  266.   edReplaceNotPossible = 16;
  267.   edRightMargin        = 17;
  268.   edSetTabStops        = 18;
  269.   edWrapNotPossible    = 19;
  270.  
  271.   { WRAP   - Stop. }
  272.   { RMSET  - Stop. }
  273.   { REFDOC - Stop. }
  274.   { PRETAB - Stop. }
  275.   { JLINE  - Stop. }
  276.  
  277.  
  278.  
  279. CONST { Editor flag constants for dialog options. }
  280.  
  281.   efCaseSensitive   = $0001;
  282.   efWholeWordsOnly  = $0002;
  283.   efPromptOnReplace = $0004;
  284.   efReplaceAll      = $0008;
  285.   efDoReplace       = $0010;
  286.   efBackupFiles     = $0100;
  287.  
  288.  
  289.  
  290. CONST { Constants for object palettes. }
  291.  
  292.   CIndicator = #2#3;
  293.   CEditor    = #6#7;
  294.   CMemo      = #26#27;
  295.  
  296.  
  297.  
  298. CONST { Length constants. }
  299.  
  300.   MaxLineLength = 256;
  301.  
  302.   { PRETAB - Start. }
  303.  
  304.   Tab_Stop_Length = 74;
  305.  
  306.   { PRETAB - Stop. }
  307.  
  308.  
  309.  
  310. TYPE
  311.  
  312.   TEditorDialog = function (Dialog : Integer; Info : Pointer) : Word;
  313.  
  314.  
  315.  
  316. TYPE
  317.  
  318.   PIndicator = ^TIndicator;
  319.   TIndicator = object (TView)
  320.  
  321.     Location   : Objects.TPoint;
  322.     Modified   : Boolean;
  323.  
  324.     { STATS - Start. }
  325.  
  326.     AutoIndent   : Boolean;          { Added boolean for AutoIndent mode. }
  327.     WordWrap     : Boolean;          { Added boolean for WordWrap mode.   }
  328.  
  329.     { STATS - Stop. }
  330.  
  331.     constructor Init (var Bounds : TRect);
  332.     procedure   Draw; virtual;
  333.     function    GetPalette : Views.PPalette; virtual;
  334.     procedure   SetState (AState : Word; Enable : Boolean); virtual;
  335.  
  336.     { STATS - Start. }
  337.  
  338.     procedure   SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  339.                                                       IsModified   : Boolean;
  340.                                                       IsWordWrap   : Boolean);
  341.  
  342.     { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  343.  
  344.   end;
  345.  
  346.  
  347.  
  348. TYPE
  349.  
  350.   PEditBuffer = ^TEditBuffer;
  351.   TEditBuffer = array[0..65519] of Char;
  352.  
  353.  
  354.  
  355. TYPE
  356.  
  357.   PEditor = ^TEditor;
  358.   TEditor = object (TView)
  359.  
  360.     HScrollBar         : PScrollBar;
  361.     VScrollBar         : PScrollBar;
  362.     Indicator          : PIndicator;
  363.     Buffer             : PEditBuffer;
  364.     BufSize            : Word;
  365.     BufLen             : Word;
  366.     GapLen             : Word;
  367.     SelStart           : Word;
  368.     SelEnd             : Word;
  369.     CurPtr             : Word;
  370.     CurPos             : Objects.TPoint;
  371.     Delta              : Objects.TPoint;
  372.     Limit              : Objects.TPoint;
  373.     DrawLine           : Integer;
  374.     DrawPtr            : Word;
  375.     DelCount           : Word;
  376.     InsCount           : Word;
  377.     IsValid            : Boolean;
  378.     CanUndo            : Boolean;
  379.     Modified           : Boolean;
  380.     Selecting          : Boolean;
  381.     Overwrite          : Boolean;
  382.     AutoIndent         : Boolean;
  383.  
  384.     { WRAP - Start. }
  385.  
  386.     BlankLine          : Word;    { First blank line after a paragraph.      }
  387.     Word_Wrap          : Boolean; { Added boolean to toggle wordwrap on/off. }
  388.  
  389.     { WRAP - Stop. }
  390.  
  391.     { JLINE - Start. }
  392.  
  393.     Line_Number        : string [4]; { Holds line number to jump to. }
  394.  
  395.     { JLINE - Stop. }
  396.  
  397.     { RMSET - Start. }
  398.  
  399.     Right_Margin       : Integer; { Added integer to set right margin.       }
  400.  
  401.     { RMSET - Stop. }
  402.  
  403.     { PRETAB - Start. }
  404.  
  405.     Tab_Settings : String[Tab_Stop_Length]; { Added string to hold tab stops. }
  406.  
  407.     { PRETAB - Stop. }
  408.  
  409.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  410.                           AIndicator : PIndicator; ABufSize : Word);
  411.     constructor Load (var S : Objects.TStream);
  412.     destructor Done; virtual;
  413.     function   BufChar (P : Word) : Char;
  414.     function   BufPtr (P : Word) : Word;
  415.     procedure  ChangeBounds (var Bounds : TRect); virtual;
  416.     procedure  ConvertEvent (var Event : Drivers.TEvent); virtual;
  417.     function   CursorVisible : Boolean;
  418.     procedure  DeleteSelect;
  419.     procedure  DoneBuffer; virtual;
  420.     procedure  Draw; virtual;
  421.     function   GetPalette : Views.PPalette; virtual;
  422.     procedure  HandleEvent (var Event : Drivers.TEvent); virtual;
  423.     procedure  InitBuffer; virtual;
  424.     function   InsertBuffer (var P : PEditBuffer; Offset, Length : Word;
  425.                                      AllowUndo, SelectText : Boolean) : Boolean;
  426.     function   InsertFrom (Editor : PEditor) : Boolean; virtual;
  427.     function   InsertText (Text : Pointer; Length : Word; SelectText : Boolean) : Boolean;
  428.     procedure  ScrollTo (X, Y : Integer);
  429.     function   Search (CONST FindStr : String; Opts : Word) : Boolean;
  430.     function   SetBufSize (NewSize : Word) : Boolean; virtual;
  431.     procedure  SetCmdState (Command : Word; Enable : Boolean);
  432.     procedure  SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  433.     procedure  SetState (AState : Word; Enable : Boolean); virtual;
  434.     procedure  Store (var S : Objects.TStream);
  435.     procedure  TrackCursor (Center : Boolean);
  436.     procedure  Undo;
  437.     procedure  UpdateCommands; virtual;
  438.     function   Valid (Command : Word) : Boolean; virtual;
  439.  
  440.   private
  441.  
  442.     KeyState       : Integer;
  443.     LockCount      : Byte;
  444.     UpdateFlags    : Byte;
  445.  
  446.     { MARK - Start. }
  447.  
  448.     Place_Marker   : Array [1..10] of Word; { Inserted array to hold place markers. }
  449.     Search_Replace : Boolean; { Added boolean to test for Search and Replace insertions. }
  450.  
  451.     { MARK - Stop. }
  452.  
  453.     { CENTER - Start. }
  454.  
  455.     procedure  Center_Text (Select_Mode : Byte);
  456.  
  457.     { CENTER - Stop. } { Added procedure to center a line of text. }
  458.  
  459.     function   CharPos (P, Target : Word) : Integer;
  460.     function   CharPtr (P : Word; Target : Integer) : Word;
  461.  
  462.     { WRAP -   Start. }
  463.  
  464.     procedure  Check_For_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean);
  465.  
  466.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  467.  
  468.     function   ClipCopy : Boolean;
  469.     procedure  ClipCut;
  470.     procedure  ClipPaste;
  471.     procedure  DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  472.     procedure  DoSearchReplace;
  473.     procedure  DoUpdate;
  474.  
  475.     { WRAP -   Start. }
  476.  
  477.     function   Do_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean) : Boolean;
  478.  
  479.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  480.  
  481.     procedure  DrawLines (Y, Count : Integer; LinePtr : Word);
  482.     procedure  FormatLine (var DrawBuf; LinePtr : Word; Width : Integer; Colors : Word);
  483.     procedure  Find;
  484.     function   GetMousePtr (Mouse : Objects.TPoint) : Word;
  485.     function   HasSelection : Boolean;
  486.     procedure  HideSelect;
  487.  
  488.     { INSLIN - Start. }
  489.  
  490.     procedure  Insert_Line (Select_Mode : Byte);
  491.  
  492.     { INSLIN - Stop. } { Added procedure to insert line at cursor. }
  493.  
  494.     function   IsClipboard : Boolean;
  495.  
  496.     { MARK -   Start. }
  497.  
  498.     procedure  Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  499.  
  500.     { MARK -   Stop. } { Added procedure to jump to a place marker if ^Q# is pressed. }
  501.  
  502.     { JLINE -  Start }
  503.  
  504.     procedure  Jump_To_Line  (Select_Mode : Byte);
  505.  
  506.     { JLINE -  Stop. }
  507.  
  508.     function   LineEnd (P : Word) : Word;
  509.     function   LineMove (P : Word; Count : Integer) : Word;
  510.     function   LineStart (P : Word) : Word;
  511.     procedure  Lock;
  512.  
  513.     { WRAP -   Start. }
  514.  
  515.     function NewLine (Select_Mode : Byte) : Boolean;
  516.  
  517.     { WRAP -   Stop. } { Included a new parameter. }
  518.  
  519.     function   NextChar (P : Word) : Word;
  520.     function   NextLine (P : Word) : Word;
  521.     function   NextWord (P : Word) : Word;
  522.     function   PrevChar (P : Word) : Word;
  523.     function   PrevLine (P : Word) : Word;
  524.     function   PrevWord (P : Word) : Word;
  525.  
  526.     { REFDOC - Start. }
  527.  
  528.     procedure  Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  529.  
  530.     { REFDOC - Stop. } { Added procedure to allow document reformatting. }
  531.  
  532.     { REFORM - Start. }
  533.  
  534.     function   Reformat_Paragraph (Select_Mode   : Byte;
  535.                                    Center_Cursor : Boolean) : Boolean;
  536.  
  537.     { REFORM - Stop. } { Added procedure to reformat paragraphs. }
  538.  
  539.     { WRAP -   Start. }
  540.  
  541.     procedure  Remove_EOL_Spaces (Select_Mode : Byte);
  542.  
  543.     { WRAP -   Stop. }  { Added procedure to remove spaces at end of a line. }
  544.  
  545.     procedure  Replace;
  546.  
  547.     { SCRLDN - Start. }
  548.  
  549.     procedure  Scroll_Down;
  550.  
  551.     { SCRLDN - Stop. }
  552.  
  553.     { SCRLUP - Start. }
  554.  
  555.     procedure  Scroll_Up;
  556.  
  557.     { SCRLUP - Stop. }
  558.  
  559.     { SELWRD - Start. }
  560.  
  561.     procedure  Select_Word;
  562.  
  563.     { SELWRD - Stop. } { Added procedure to allow selecting a word only. }
  564.  
  565.     procedure  SetBufLen (Length : Word);
  566.     procedure  SetCurPtr (P : Word; SelectMode : Byte);
  567.  
  568.     { MARK -   Start. }
  569.  
  570.     procedure  Set_Place_Marker (Element : Byte);
  571.  
  572.     { MARK -   Stop. } { Added procedure to set a Place_Marker if ^K# is pressed. }
  573.  
  574.     { RMSET -  Start. }
  575.  
  576.     procedure  Set_Right_Margin;
  577.  
  578.     { RMSET -  Stop. } { Added procedure to set Right_Margin via a dialog box. }
  579.  
  580.     { PRETAB - Start. }
  581.  
  582.     procedure  Set_Tabs;
  583.  
  584.     { PRETAB - Stop. } { Added procedure to allow preset tabs. }
  585.  
  586.     procedure  StartSelect;
  587.  
  588.     { PRETAB - Start. }
  589.  
  590.     procedure  Tab_Key (Select_Mode : Byte);
  591.  
  592.     { PRETAB - Stop. } { Added procedure to process Tab key as spaces or movment. }
  593.  
  594.     procedure  ToggleInsMode;
  595.     procedure  Unlock;
  596.     procedure  Update (AFlags : Byte);
  597.  
  598.     { MARK -   Start. }
  599.  
  600.     procedure  Update_Place_Markers (AddCount : Word; KillCount : Word;
  601.                                      StartPtr : Word;    EndPtr : Word);
  602.  
  603.     { MARK -   Stop. } { Added procedure to update Place_Marker as we change text. }
  604.  
  605.   end;
  606.  
  607.  
  608.  
  609. TYPE
  610.  
  611.   TMemoData = record
  612.  
  613.     Length : Word;
  614.     Buffer : TEditBuffer;
  615.  
  616.   end;
  617.  
  618.  
  619.  
  620. TYPE
  621.  
  622.   PMemo = ^TMemo;
  623.   TMemo = object (TEditor)
  624.  
  625.     constructor Load (var S : Objects.TStream);
  626.     function    DataSize : Word; virtual;
  627.     procedure   GetData (var Rec); virtual;
  628.     function    GetPalette : Views.PPalette; virtual;
  629.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  630.     procedure   SetData (var Rec); virtual;
  631.     procedure   Store (var S : Objects.TStream);
  632.  
  633.   end;
  634.  
  635.  
  636.  
  637. TYPE
  638.  
  639.   PFileEditor = ^TFileEditor;
  640.   TFileEditor = object (TEditor)
  641.  
  642.     FileName : FNameStr;
  643.  
  644.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  645.                           AIndicator : PIndicator; AFileName : FNameStr);
  646.     constructor Load (var S : Objects.TStream);
  647.     procedure   DoneBuffer; virtual;
  648.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  649.     procedure   InitBuffer; virtual;
  650.     function    LoadFile : Boolean;
  651.     function    Save : Boolean;
  652.     function    SaveAs : Boolean;
  653.     function    SaveFile : Boolean;
  654.     function    SetBufSize (NewSize : Word) : Boolean; virtual;
  655.     procedure   Store (var S : Objects.TStream);
  656.     procedure   UpdateCommands; virtual;
  657.     function    Valid (Command : Word) : Boolean; virtual;
  658.  
  659.   end;
  660.  
  661.  
  662.  
  663. TYPE
  664.  
  665.   PEditWindow = ^TEditWindow;
  666.   TEditWindow = object (TWindow)
  667.  
  668.     Editor : PFileEditor;
  669.  
  670.     constructor Init (var Bounds : TRect; FileName : FNameStr; ANumber : Integer);
  671.     constructor Load (var S : Objects.TStream);
  672.     procedure   Close; virtual;
  673.     function    GetTitle (MaxSize : Integer) : Views.TTitleStr; virtual;
  674.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  675.     Procedure   SizeLimits (var Min, Max : TPoint); virtual;
  676.     procedure   Store (var S : Objects.TStream);
  677.  
  678.   end;
  679.  
  680.  
  681.  
  682. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  683.  
  684.  
  685.  
  686. CONST
  687.  
  688.   { PRETAB - Start. }
  689.   { WRAP   - Start. }
  690.  
  691.   WordChars    : set of Char = ['!'..#255];
  692.  
  693.   { WRAP   - Stop. }
  694.   { PRETAB - Stop. } { Changed set parameters to allow punctuation. }
  695.  
  696.  
  697.  
  698.   { ------------------------------------------------- }
  699.   {                                                   }
  700.   { The Allow_Reformat boolean is a programmer hook.  }
  701.   { I've placed this here to allow programmers to     }
  702.   { determine whether or not paragraph and document   }
  703.   { reformatting are allowed if Word_Wrap is not      }
  704.   { active.  Some people say don't allow, and others  }
  705.   { say allow it.  I've left it up to the programmer. }
  706.   { Set to FALSE if not allowed, or TRUE if allowed.  }
  707.   {                                                   }
  708.   { ------------------------------------------------- }
  709.  
  710.   Allow_Reformat : Boolean = True;
  711.  
  712.   EditorDialog   : TEditorDialog = DefEditorDialog;
  713.   EditorFlags    : Word = efBackupFiles + efPromptOnReplace;
  714.   FindStr        : String[80] = '';
  715.   ReplaceStr     : String[80] = '';
  716.   Clipboard      : PEditor = nil;
  717.  
  718.  
  719.  
  720. TYPE
  721.  
  722.   TFindDialogRec = record
  723.  
  724.     Find    : String[80];
  725.     Options : Word;
  726.  
  727.   end;
  728.  
  729.  
  730.  
  731.   TReplaceDialogRec = record
  732.  
  733.        Find : String[80];
  734.     Replace : String[80];
  735.     Options : Word;
  736.  
  737.   end;
  738.  
  739.  
  740.  
  741.   { RMSET - Start. }
  742.  
  743.   TRightMarginRec = record
  744.  
  745.     Margin_Position : String[3];
  746.  
  747.   end;
  748.  
  749.   { RMSET - Stop. } { Record required by Right_Margin_Dialog. }
  750.  
  751.  
  752.  
  753.   { PRETAB - Start. }
  754.  
  755.   TTabStopRec = record
  756.  
  757.     Tab_String : String [Tab_Stop_Length];
  758.  
  759.   end;
  760.  
  761.   { PRETAB - Stop. } { Record required by Tab_Stop_Dialog. }
  762.  
  763.  
  764.  
  765. CONST { VMT constants. }
  766.  
  767.   REditor   : TStreamRec = (ObjType : 70;
  768.                             VmtLink : Ofs (TypeOf (TEditor)^);
  769.                                Load : @TEditor.Load;
  770.                               Store : @TEditor.Store);
  771.  
  772.  
  773.   RMemo     : TStreamRec = (ObjType : 71;
  774.                             VmtLink : Ofs (TypeOf (TMemo)^);
  775.                                Load : @TMemo.Load;
  776.                               Store : @TMemo.Store);
  777.  
  778.  
  779.   RFileEditor : TStreamRec = (ObjType : 72;
  780.                               VmtLink : Ofs (TypeOf (TFileEditor)^);
  781.                                  Load : @TFileEditor.Load;
  782.                                 Store : @TFileEditor.Store);
  783.  
  784.  
  785.   RIndicator : TStreamRec = (ObjType : 73;
  786.                              VmtLink : Ofs (TypeOf (TIndicator)^);
  787.                                 Load : @TIndicator.Load;
  788.                                Store : @TIndicator.Store);
  789.  
  790.  
  791.   REditWindow : TStreamRec = (ObjType : 74;
  792.                               VmtLink : Ofs (TypeOf (TEditWindow)^);
  793.                                  Load : @TEditWindow.Load;
  794.                                 Store : @TEditWindow.Store);
  795.  
  796.  
  797.  
  798. procedure RegisterEditors;
  799.  
  800.  
  801.  
  802.  
  803. implementation
  804.  
  805.  
  806.  
  807. uses
  808.  
  809.   Memory,
  810.   Dos;
  811.  
  812.  
  813.  
  814. CONST { Update flag constants. }
  815.  
  816.   ufUpdate = $01;
  817.   ufLine   = $02;
  818.   ufView   = $04;
  819.  
  820.   { STATS - Start. }
  821.  
  822.   ufStats  = $05;
  823.  
  824.   { STATS - Stop. }
  825.  
  826.  
  827.  
  828. CONST { SelectMode constants. }
  829.  
  830.   smExtend = $01;
  831.   smDouble = $02;
  832.  
  833.  
  834.  
  835. CONST
  836.  
  837.   sfSearchFailed = $FFFF;
  838.  
  839.  
  840.  
  841. CONST { Arrays that hold all the command keys and options. }
  842.  
  843.   { CTRLBK - Start. }
  844.   { HOMEND - Start. }
  845.   { INDENT - Start. }
  846.   { INSLIN - Start. }
  847.   { JLINE  - Start. }
  848.   { PRETAB - Start. }
  849.   { REFORM - Start. }
  850.   { SCRLDN - Start. }
  851.   { SCRLDN - Start. }
  852.  
  853.   FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A),    cmWordLeft,
  854.                                               Ord (^B),    cmReformPara,
  855.                                               Ord (^C),    cmPageDown,
  856.                                               Ord (^D),    cmCharRight,
  857.                                               Ord (^E),    cmLineUp,
  858.                                               Ord (^F),    cmWordRight,
  859.                                               Ord (^G),    cmDelChar,
  860.                                               Ord (^H),    cmBackSpace,
  861.                                               Ord (^I),    cmTabKey,
  862.                                               Ord (^J),    $FF04,
  863.                                               Ord (^K),    $FF02,
  864.                                               Ord (^L),    cmSearchAgain,
  865.                                               Ord (^M),    cmNewLine,
  866.                                               Ord (^N),    cmInsertLine,
  867.                                               Ord (^O),    $FF03,
  868.                                               Ord (^Q),    $FF01,
  869.                                               Ord (^R),    cmPageUp,
  870.                                               Ord (^S),    cmCharLeft,
  871.                                               Ord (^T),    cmDelWord,
  872.                                               Ord (^U),    cmUndo,
  873.                                               Ord (^V),    cmInsMode,
  874.                                               Ord (^W),    cmScrollUp,
  875.                                               Ord (^X),    cmLineDown,
  876.                                               Ord (^Y),    cmDelLine,
  877.                                               Ord (^Z),    cmScrollDown,
  878.                                               kbLeft,      cmCharLeft,
  879.                                               kbRight,     cmCharRight,
  880.                                               kbCtrlLeft,  cmWordLeft,
  881.                                               kbCtrlRight, cmWordRight,
  882.                                               kbHome,      cmLineStart,
  883.                                               kbEnd,       cmLineEnd,
  884.                                               kbCtrlHome,  cmHomePage,
  885.                                               kbCtrlEnd,   cmEndPage,
  886.                                               kbUp,        cmLineUp,
  887.                                               kbDown,      cmLineDown,
  888.                                               kbPgUp,      cmPageUp,
  889.                                               kbPgDn,      cmPageDown,
  890.                                               kbCtrlPgUp,  cmTextStart,
  891.                                               kbCtrlPgDn,  cmTextEnd,
  892.                                               kbIns,       cmInsMode,
  893.                                               kbDel,       cmDelChar,
  894.                                               kbCtrlBack,  cmDelStart,
  895.                                               kbShiftIns,  cmPaste,
  896.                                               kbShiftDel,  cmCut,
  897.                                               kbCtrlIns,   cmCopy,
  898.                                               kbCtrlDel,   cmClear);
  899.  
  900.   { SCRLUP - Stop. } { Added ^W to scroll screen up.         }
  901.   { SCRLDN - Stop. } { Added ^Z to scroll screen down.       }
  902.   { REFORM - Stop. } { Added ^B for paragraph reformatting.  }
  903.   { PRETAB - Stop. } { Added ^I for preset tabbing.          }
  904.   { JLINE  - Stop. } { Added ^J to jump to a line number.    }
  905.   { INSLIN - Stop. } { Added ^N to insert line at cursor.    }
  906.   { INDENT - Stop. } { Removed ^O and put it into ^QI.       }
  907.   { HOMEND - Stop. } { Added kbCtrlHome and kbCtrlEnd pages. }
  908.   { CTRLBK - Stop. } { Added kbCtrlBack same as ^QH.         }
  909.  
  910.   { INDENT - Start. }
  911.   { MARK   - Start. }
  912.   { REFDOC - Start. }
  913.   { UNDO   - Start. }
  914.  
  915.   QuickKeys : array[0..21 * 2] of Word = (21, Ord ('0'), cmJumpMark0,
  916.                                               Ord ('1'), cmJumpMark1,
  917.                                               Ord ('2'), cmJumpMark2,
  918.                                               Ord ('3'), cmJumpMark3,
  919.                                               Ord ('4'), cmJumpMark4,
  920.                                               Ord ('5'), cmJumpMark5,
  921.                                               Ord ('6'), cmJumpMark6,
  922.                                               Ord ('7'), cmJumpMark7,
  923.                                               Ord ('8'), cmJumpMark8,
  924.                                               Ord ('9'), cmJumpMark9,
  925.                                               Ord ('A'), cmReplace,
  926.                                               Ord ('C'), cmTextEnd,
  927.                                               Ord ('D'), cmLineEnd,
  928.                                               Ord ('F'), cmFind,
  929.                                               Ord ('H'), cmDelStart,
  930.                                               Ord ('I'), cmIndentMode,
  931.                                               Ord ('L'), cmUndo,
  932.                                               Ord ('R'), cmTextStart,
  933.                                               Ord ('S'), cmLineStart,
  934.                                               Ord ('U'), cmReformDoc,
  935.                                               Ord ('Y'), cmDelEnd);
  936.  
  937.   { UNDO   - Stop. } { Added IDE undo feature of ^QL.                  }
  938.   { REFDOC - Stop. } { Added document reformat feature if ^QU pressed. }
  939.   { MARK   - Stop. } { Added cmJumpMark# to allow place marking.       }
  940.   { INDENT - Stop. } { Moved IndentMode here from Firstkeys.           }
  941.  
  942.   { MARK   - Start. }
  943.   { SAVE   - Start. }
  944.   { SELWRD - Start. }
  945.  
  946.   BlockKeys : array[0..20 * 2] of Word = (20, Ord ('0'), cmSetMark0,
  947.                                               Ord ('1'), cmSetMark1,
  948.                                               Ord ('2'), cmSetMark2,
  949.                                               Ord ('3'), cmSetMark3,
  950.                                               Ord ('4'), cmSetMark4,
  951.                                               Ord ('5'), cmSetMark5,
  952.                                               Ord ('6'), cmSetMark6,
  953.                                               Ord ('7'), cmSetMark7,
  954.                                               Ord ('8'), cmSetMark8,
  955.                                               Ord ('9'), cmSetMark9,
  956.                                               Ord ('B'), cmStartSelect,
  957.                                               Ord ('C'), cmPaste,
  958.                                               Ord ('D'), cmSaveDone,
  959.                                               Ord ('F'), cmSaveAs,
  960.                                               Ord ('H'), cmHideSelect,
  961.                                               Ord ('K'), cmCopy,
  962.                                               Ord ('S'), cmSave,
  963.                                               Ord ('T'), cmSelectWord,
  964.                                               Ord ('Y'), cmCut,
  965.                                               Ord ('X'), cmSaveDone);
  966.  
  967.   { SELWRD - Stop. } { Added ^KT to select word only. }
  968.   { SAVE   - Stop. } { Added ^KD, ^KF, ^KS, ^KX key commands.   }
  969.   { MARK   - Stop. } { Added cmSetMark# to allow place marking. }
  970.  
  971.   { CENTER - Start. }
  972.   { PRETAB - Start. }
  973.   { RMSET  - Start. }
  974.   { WRAP   - Start. }
  975.  
  976.   FormatKeys : array[0..4 * 2] of Word = (4,  Ord ('C'), cmCenterText,
  977.                                               Ord ('I'), cmSetTabs,
  978.                                               Ord ('R'), cmRightMargin,
  979.                                               Ord ('W'), cmWordWrap);
  980.  
  981.   { WRAP   - Stop. } { Added Wordwrap feature if ^OW pressed.          }
  982.   { RMSET  - Stop. } { Added set right margin feature if ^OR pressed.  }
  983.   { PRETAB - Stop. } { Added preset tab feature if ^OI pressed.        }
  984.   { CENTER - Stop. } { Added center text option ^OC for a line.        }
  985.  
  986.  
  987.  
  988.   { JLINE - Start. }
  989.  
  990.   JumpKeys : array[0..1 * 2] of Word = (1, Ord ('L'), cmJumpLine);
  991.  
  992.   { JLINE - Stop. } { Added jump to line number feature if ^JL pressed. }
  993.  
  994.  
  995.  
  996.   { CENTER - Start. }
  997.   { JLINE  - Start. }
  998.   { PRETAB - Start. }
  999.   { WRAP   - Start. }
  1000.  
  1001.   KeyMap : array[0..4] of Pointer = (@FirstKeys,
  1002.                                      @QuickKeys,
  1003.                                      @BlockKeys,
  1004.                                      @FormatKeys,
  1005.                                      @JumpKeys);
  1006.  
  1007.   { WRAP   - Stop. } { Added @FormatKeys for new ^O? keys. }
  1008.   { PRETAB - Stop. } { Added @FormatKeys for new ^O? keys. }
  1009.   { JLINE  - Stop. } { Added @JumpKeys for new ^J? keys.   }
  1010.   { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
  1011.  
  1012.  
  1013.  
  1014. { -------------------------------------------------------------------------- }
  1015.  
  1016.  
  1017.  
  1018. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  1019.  
  1020. begin
  1021.  
  1022.   DefEditorDialog := Views.cmCancel;
  1023.  
  1024.  
  1025. end; { DefEditorDialog }
  1026.  
  1027.  
  1028.  
  1029. { -------------------------------------------------------------------------- }
  1030.  
  1031.  
  1032.  
  1033. function Min (X, Y : Integer) : Integer; assembler;
  1034.  
  1035. asm
  1036.         MOV     AX,X
  1037.         CMP     AX,Y
  1038.         JLE     @@1
  1039.         MOV     AX,Y
  1040. @@1:
  1041.  
  1042.  
  1043. end; { Min }
  1044.  
  1045.  
  1046.  
  1047. { -------------------------------------------------------------------------- }
  1048.  
  1049.  
  1050.  
  1051. function Max (X, Y : Integer) : Integer; assembler;
  1052.  
  1053. asm
  1054.         MOV     AX,X
  1055.         CMP     AX,Y
  1056.         JGE     @@1
  1057.         MOV     AX,Y
  1058. @@1:
  1059.  
  1060.  
  1061. end; { Max }
  1062.  
  1063.  
  1064.  
  1065. { -------------------------------------------------------------------------- }
  1066.  
  1067.  
  1068.  
  1069. function MinWord (X, Y : Word) : Word; assembler;
  1070.  
  1071. asm
  1072.         MOV     AX,X
  1073.         CMP     AX,Y
  1074.         JBE     @@1
  1075.         MOV     AX,Y
  1076. @@1:
  1077.  
  1078.  
  1079. end; { MinWord }
  1080.  
  1081.  
  1082.  
  1083. { -------------------------------------------------------------------------- }
  1084.  
  1085.  
  1086.  
  1087. function MaxWord (X, Y : Word) : Word; assembler;
  1088.  
  1089. asm
  1090.         MOV     AX,X
  1091.         CMP     AX,Y
  1092.         JAE     @@1
  1093.         MOV     AX,Y
  1094. @@1:
  1095.  
  1096.  
  1097. end; { MaxWord }
  1098.  
  1099.  
  1100.  
  1101. { -------------------------------------------------------------------------- }
  1102.  
  1103.  
  1104.  
  1105. function CountLines (var Buf; Count : Word) : Integer; assembler;
  1106.  
  1107. asm
  1108.         LES     DI,Buf
  1109.         MOV     CX,Count
  1110.         XOR     DX,DX
  1111.         MOV     AL,0DH
  1112.         CLD
  1113. @@1:    JCXZ    @@2
  1114.         REPNE   SCASB
  1115.         JNE     @@2
  1116.         INC     DX
  1117.         JMP     @@1
  1118. @@2:    MOV     AX,DX
  1119.  
  1120.  
  1121. end; { CountLines }
  1122.  
  1123.  
  1124.  
  1125. { -------------------------------------------------------------------------- }
  1126.  
  1127.  
  1128.  
  1129. function ScanKeyMap (KeyMap : Pointer; KeyCode : Word) : Word; assembler;
  1130.  
  1131. asm
  1132.         PUSH    DS
  1133.         LDS     SI,KeyMap
  1134.         MOV     DX,KeyCode
  1135.         CLD
  1136.         LODSW
  1137.         MOV     CX,AX
  1138. @@1:    LODSW
  1139.         MOV     BX,AX
  1140.         LODSW
  1141.         CMP     BL,DL
  1142.         JNE     @@3
  1143.         OR      BH,BH
  1144.         JE      @@4
  1145.         CMP     BH,DH
  1146.         JE      @@4
  1147. @@3:    LOOP    @@1
  1148.         XOR     AX,AX
  1149. @@4:    POP     DS
  1150.  
  1151.  
  1152. end; { ScanKeyMap }
  1153.  
  1154.  
  1155.  
  1156. { -------------------------------------------------------------------------- }
  1157.  
  1158.  
  1159.  
  1160. function Scan (var Block; Size : Word; Str : String) : Word; assembler;
  1161.  
  1162. asm
  1163.         PUSH    DS
  1164.         LES     DI,Block
  1165.         LDS     SI,Str
  1166.         MOV     CX,Size
  1167.         JCXZ    @@3
  1168.         CLD
  1169.         LODSB
  1170.         CMP     AL,1
  1171.         JB      @@5
  1172.         JA      @@1
  1173.         LODSB
  1174.         REPNE   SCASB
  1175.         JNE     @@3
  1176.         JMP     @@5
  1177. @@1:    XOR     AH,AH
  1178.         MOV     BX,AX
  1179.         DEC     BX
  1180.         MOV     DX,CX
  1181.         SUB     DX,AX
  1182.         JB      @@3
  1183.         LODSB
  1184.         INC     DX
  1185.         INC     DX
  1186. @@2:    DEC     DX
  1187.         MOV     CX,DX
  1188.         REPNE   SCASB
  1189.         JNE     @@3
  1190.         MOV     DX,CX
  1191.         MOV     CX,BX
  1192.         REP     CMPSB
  1193.         JE      @@4
  1194.         SUB     CX,BX
  1195.         ADD     SI,CX
  1196.         ADD     DI,CX
  1197.         INC     DI
  1198.         OR      DX,DX
  1199.         JNE     @@2
  1200. @@3:    XOR     AX,AX
  1201.         JMP     @@6
  1202. @@4:    SUB     DI,BX
  1203. @@5:    MOV     AX,DI
  1204.         SUB     AX,WORD PTR Block
  1205. @@6:    DEC     AX
  1206.         POP     DS
  1207.  
  1208.  
  1209. end; { Scan }
  1210.  
  1211.  
  1212.  
  1213. { -------------------------------------------------------------------------- }
  1214.  
  1215.  
  1216.  
  1217. function IScan (var Block; Size : Word; Str : String) : Word; assembler;
  1218.  
  1219. VAR
  1220.  
  1221.   S : String;
  1222.  
  1223. asm
  1224.         PUSH    DS
  1225.         MOV     AX,SS
  1226.         MOV     ES,AX
  1227.         LEA     DI,S
  1228.         LDS     SI,Str
  1229.         XOR     AH,AH
  1230.         LODSB
  1231.         STOSB
  1232.         MOV     CX,AX
  1233.         MOV     BX,AX
  1234.         JCXZ    @@9
  1235. @@1:    LODSB
  1236.         CMP     AL,'a'
  1237.         JB      @@2
  1238.         CMP     AL,'z'
  1239.         JA      @@2
  1240.         SUB     AL,20H
  1241. @@2:    STOSB
  1242.         LOOP    @@1
  1243.         SUB     DI,BX
  1244.         LDS     SI,Block
  1245.         MOV     CX,Size
  1246.         JCXZ    @@8
  1247.         CLD
  1248.         SUB     CX,BX
  1249.         JB      @@8
  1250.         INC     CX
  1251. @@4:    MOV     AH,ES:[DI]
  1252.         AND     AH,$DF
  1253. @@5:    LODSB
  1254.         AND     AL,$DF
  1255.         CMP     AL,AH
  1256.         LOOPNE  @@5
  1257.         JNE     @@8
  1258.         DEC     SI
  1259.         MOV     DX,CX
  1260.         MOV     CX,BX
  1261. @@6:    REPE    CMPSB
  1262.         JE      @@10
  1263.         MOV     AL,DS:[SI-1]
  1264.         CMP     AL,'a'
  1265.         JB      @@7
  1266.         CMP     AL,'z'
  1267.         JA      @@7
  1268.         SUB     AL,20H
  1269. @@7:    CMP     AL,ES:[DI-1]
  1270.         JE      @@6
  1271.         SUB     CX,BX
  1272.         ADD     SI,CX
  1273.         ADD     DI,CX
  1274.         INC     SI
  1275.         MOV     CX,DX
  1276.         TEST    CX,CX
  1277.         JNE     @@4
  1278. @@8:    XOR     AX,AX
  1279.         JMP     @@11
  1280. @@9:    MOV     AX, 1
  1281.         JMP     @@11
  1282. @@10:   SUB     SI,BX
  1283.         MOV     AX,SI
  1284.         SUB     AX,WORD PTR Block
  1285.         INC     AX
  1286. @@11:   DEC     AX
  1287.         POP     DS
  1288.  
  1289.  
  1290. end; { Iscan }
  1291.  
  1292.  
  1293.  
  1294. { -------------------------------------------------------------------------- }
  1295.  
  1296.  
  1297.  
  1298.          { ---------------------------------------------------- }
  1299.          {                                                      }
  1300.          { The following methods are for the TINDICATOR object. }
  1301.          {                                                      }
  1302.          { ---------------------------------------------------- }
  1303.  
  1304.  
  1305.  
  1306. constructor TIndicator.Init (var Bounds : TRect);
  1307.  
  1308. VAR
  1309.  
  1310.   R : TRect;
  1311.  
  1312. begin
  1313.  
  1314.   TView.Init (Bounds);
  1315.   GrowMode := gfGrowLoY + gfGrowHiY;
  1316.  
  1317.  
  1318.  
  1319. end; { TIndicator.Init }
  1320.  
  1321.  
  1322.  
  1323. { -------------------------------------------------------------------------- }
  1324.  
  1325.  
  1326.  
  1327. procedure TIndicator.Draw;
  1328.  
  1329. VAR
  1330.  
  1331.   Color : Byte;
  1332.   Frame : Char;
  1333.   L     : array[0..1] of Longint;
  1334.   S     : String[15];
  1335.   B     : Views.TDrawBuffer;
  1336.  
  1337. begin
  1338.  
  1339.   if State and sfDragging = 0 then
  1340.     begin
  1341.       Color := GetColor (1);
  1342.       Frame := #205;
  1343.     end
  1344.   else
  1345.     begin
  1346.       Color := GetColor (2);
  1347.       Frame := #196;
  1348.     end;
  1349.  
  1350.   MoveChar (B, Frame, Color, Size.X);
  1351.  
  1352.  
  1353.  
  1354.   { STATS - Start. }
  1355.  
  1356.   { -------------------------------------------------------------------- }
  1357.   {                                                                      }
  1358.   { If the text has been modified, put an 'M' in the TIndicator display. }
  1359.   {                                                                      }
  1360.   { -------------------------------------------------------------------- }
  1361.  
  1362.  
  1363.   if Modified then
  1364.     WordRec (B[1]).Lo := 77;
  1365.  
  1366.  
  1367.  
  1368.   { ---------------------------------------------------------- }
  1369.   {                                                            }
  1370.   { If WordWrap is active put a 'W' in the TIndicator display. }
  1371.   { Otherwise, just use the current frame character.           }
  1372.   {                                                            }
  1373.   { ---------------------------------------------------------- }
  1374.  
  1375.  
  1376.   if WordWrap then
  1377.     WordRec (B[2]).Lo := 87
  1378.   else
  1379.     WordRec (B[2]).Lo := Byte (Frame);
  1380.  
  1381.  
  1382.  
  1383.   { --------------------------------------------------------- }
  1384.   {                                                           }
  1385.   { If AutoIndent is active put an 'I' in TIndicator display. }
  1386.   { Otherwise, just use the current frame character.          }
  1387.   {                                                           }
  1388.   { --------------------------------------------------------- }
  1389.  
  1390.  
  1391.   if AutoIndent then
  1392.     WordRec (B[0]).Lo := 73
  1393.   else
  1394.     WordRec (B[0]).Lo := Byte (Frame);
  1395.  
  1396.   L[0] := Location.Y + 1;
  1397.   L[1] := Location.X + 1;
  1398.  
  1399.   FormatStr (S, ' %d:%d ', L);
  1400.   MoveStr (B[9 - Pos (':', S)], S, Color);       { Changed original 8 to 9. }
  1401.   WriteBuf (0, 0, Size.X, 1, B);
  1402.  
  1403.   { STATS - Stop. } { Changed who goes where in B array and added new code. }
  1404.  
  1405.  
  1406. end; { TIndicator.Draw }
  1407.  
  1408.  
  1409.  
  1410. { -------------------------------------------------------------------------- }
  1411.  
  1412.  
  1413.  
  1414. function TIndicator.GetPalette : Views.PPalette;
  1415.  
  1416. CONST
  1417.  
  1418.   P : string[Length (CIndicator)] = CIndicator;
  1419.  
  1420. begin
  1421.  
  1422.   GetPalette := @P;
  1423.  
  1424.  
  1425. end; { TIndicator.GetPalette }
  1426.  
  1427.  
  1428.  
  1429. { -------------------------------------------------------------------------- }
  1430.  
  1431.  
  1432.  
  1433. procedure TIndicator.SetState (AState : Word; Enable : Boolean);
  1434.  
  1435. begin
  1436.  
  1437.   TView.SetState (AState, Enable);
  1438.   if AState = sfDragging
  1439.     then DrawView;
  1440.  
  1441.  
  1442. end; { TIndicator.SetState }
  1443.  
  1444.  
  1445.  
  1446. { -------------------------------------------------------------------------- }
  1447.  
  1448.  
  1449.  
  1450. { STATS - Start. }
  1451.  
  1452. procedure TIndicator.SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  1453.                                                            IsModified   : Boolean;
  1454.                                                            IsWordWrap   : Boolean);
  1455.  
  1456. begin
  1457.  
  1458.   if   (Longint (Location) <> Longint (ALocation))
  1459.     or (AutoIndent <> IsAutoIndent)
  1460.     or (Modified <> IsModified)
  1461.     or (WordWrap <> IsWordWrap) then
  1462.   begin
  1463.     Location   := ALocation;
  1464.     AutoIndent := IsAutoIndent;    { Added provisions to show AutoIndent. }
  1465.     Modified   := IsModified;
  1466.     WordWrap   := IsWordWrap;      { Added provisions to show WordWrap.   }
  1467.  
  1468.     DrawView;
  1469.   end;
  1470.  
  1471.  
  1472. end; { TIndicator.SetValue }
  1473.  
  1474. { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  1475.  
  1476.  
  1477.  
  1478. { -------------------------------------------------------------------------- }
  1479.  
  1480.  
  1481.  
  1482.          { ------------------------------------------------- }
  1483.          {                                                   }
  1484.          { The following methods are for the TEDITOR object. }
  1485.          {                                                   }
  1486.          { ------------------------------------------------- }
  1487.  
  1488.  
  1489.  
  1490. constructor TEditor.Init (var Bounds : TRect;
  1491.                               AHScrollBar, AVScrollBar : PScrollBar;
  1492.                               AIndicator : PIndicator; ABufSize : Word);
  1493.  
  1494. { MARK - Start. }
  1495.  
  1496. VAR
  1497.  
  1498.   Element : Byte;      { Place_Marker array element to initialize array with. }
  1499.  
  1500. { MARK - Stop. } { Added Element variable. }
  1501.  
  1502. begin
  1503.  
  1504.   TView.Init (Bounds);
  1505.   GrowMode := gfGrowHiX + gfGrowHiY;
  1506.   Options := Options or ofSelectable;
  1507.   EventMask := evMouseDown + evKeyDown + evCommand + evBroadcast;
  1508.   ShowCursor;
  1509.  
  1510.   HScrollBar := AHScrollBar;
  1511.   VScrollBar := AVScrollBar;
  1512.  
  1513.   Indicator := AIndicator;
  1514.   BufSize := ABufSize;
  1515.   CanUndo := True;
  1516.   InitBuffer;
  1517.  
  1518.   if Buffer <> nil then
  1519.     IsValid := True
  1520.   else
  1521.     begin
  1522.       EditorDialog (edOutOfMemory, nil);
  1523.       BufSize := 0;
  1524.     end;
  1525.  
  1526.   SetBufLen (0);
  1527.  
  1528.   { MARK - Start. }
  1529.  
  1530.   for Element := 1 to 10 do
  1531.     Place_Marker[Element] := 0;
  1532.  
  1533.   { MARK - Stop. } { Added code to initialize Place_Marker array to zero's. }
  1534.  
  1535.   { PRETAB - Start. }
  1536.  
  1537.   Element := 1;
  1538.  
  1539.   while Element <= 70 do
  1540.     begin
  1541.       if Element mod 5 = 0 then
  1542.         Insert ('x', Tab_Settings, Element)
  1543.       else
  1544.         Insert (#32, Tab_Settings, Element);
  1545.       Inc (Element);
  1546.     end;
  1547.  
  1548.   { PRETAB - Stop. }
  1549.  
  1550.   { WRAP - Start. }
  1551.  
  1552.   Right_Margin := 76; { Default Right_Margin value.  Change it if you want another. }
  1553.  
  1554.   { WRAP - Stop. }
  1555.  
  1556.  
  1557. end; { TEditor.Init }
  1558.  
  1559.  
  1560.  
  1561. { -------------------------------------------------------------------------- }
  1562.  
  1563.  
  1564.  
  1565. constructor TEditor.Load (var S : Objects.TStream);
  1566.  
  1567. begin
  1568.  
  1569.   TView.Load (S);
  1570.  
  1571.   GetPeerViewPtr (S, HScrollBar);
  1572.   GetPeerViewPtr (S, VScrollBar);
  1573.   GetPeerViewPtr (S, Indicator);
  1574.   S.Read (BufSize, SizeOf (Word));
  1575.  
  1576.  
  1577.   { LOAD - Start. }
  1578.  
  1579.   { S.Read (CanUndo, SizeOf (Boolean)); }
  1580.  
  1581.   { LOAD - Stop. } { This item caused load/store bug. }
  1582.  
  1583.  
  1584.   { STATS  - Start. }
  1585.   { JLINE  - Start. }
  1586.   { MARK   - Start. }
  1587.   { RMSET  - Start. }
  1588.   { PRETAB - Start. }
  1589.   { WRAP   - Start. }
  1590.  
  1591.   S.Read (AutoIndent,   SizeOf (AutoIndent));
  1592.   S.Read (Line_Number,  SizeOf (Line_Number));
  1593.   S.Read (Place_Marker, SizeOf (Place_Marker));
  1594.   S.Read (Right_Margin, SizeOf (Right_Margin));
  1595.   S.Read (Tab_Settings, SizeOf (Tab_Settings));
  1596.   S.Read (Word_Wrap,    SizeOf (Word_Wrap));
  1597.  
  1598.   CanUndo := True;
  1599.  
  1600.   { WRAP   - Stop. }
  1601.   { PRETAB - Stop. }
  1602.   { RMSET  - Stop. }
  1603.   { MARK   - Stop. }
  1604.   { JLINE  - Stop. }
  1605.   { STATS  - Stop. } { Added these to allow load/store operations. }
  1606.  
  1607.   InitBuffer;
  1608.  
  1609.   if Buffer <> nil then
  1610.     IsValid := True
  1611.   else
  1612.     begin
  1613.       EditorDialog (edOutOfMemory, nil);
  1614.       BufSize := 0;
  1615.     end;
  1616.  
  1617.   Lock;
  1618.  
  1619.   SetBufLen (0);
  1620.  
  1621.  
  1622. end; { TEditor.Load }
  1623.  
  1624.  
  1625.  
  1626. { -------------------------------------------------------------------------- }
  1627.  
  1628.  
  1629.  
  1630. destructor TEditor.Done;
  1631.  
  1632. begin
  1633.  
  1634.   DoneBuffer;
  1635.   TView.Done;
  1636.  
  1637.  
  1638. end; { TEditor.Done }
  1639.  
  1640.  
  1641.  
  1642. { -------------------------------------------------------------------------- }
  1643.  
  1644.  
  1645.  
  1646. function TEditor.BufChar (P : Word) : Char; assembler;
  1647.  
  1648. asm
  1649.         LES     DI,Self
  1650.         MOV     BX,P
  1651.         CMP     BX,ES:[DI].TEditor.CurPtr
  1652.         JB      @@1
  1653.         ADD     BX,ES:[DI].TEditor.GapLen
  1654. @@1:    LES     DI,ES:[DI].TEditor.Buffer
  1655.         MOV     AL,ES:[DI+BX]
  1656.  
  1657.  
  1658. end; { TEditor.BufChar }
  1659.  
  1660.  
  1661.  
  1662. { -------------------------------------------------------------------------- }
  1663.  
  1664.  
  1665.  
  1666. function TEditor.BufPtr (P : Word) : Word; assembler;
  1667.  
  1668. asm
  1669.         LES     DI,Self
  1670.         MOV     AX,P
  1671.         CMP     AX,ES:[DI].TEditor.CurPtr
  1672.         JB      @@1
  1673.         ADD     AX,ES:[DI].TEditor.GapLen
  1674. @@1:
  1675.  
  1676.  
  1677. end; { TEditor.BufPtr }
  1678.  
  1679.  
  1680.  
  1681. { -------------------------------------------------------------------------- }
  1682.  
  1683.  
  1684.  
  1685. { CENTER - Start. }
  1686.  
  1687. procedure TEditor.Center_Text (Select_Mode : Byte);
  1688.  
  1689.  
  1690.   { ---------------------------------------------------- }
  1691.   {                                                      }
  1692.   { This procedure will center the current line of text. }
  1693.   { Centering is based on the current Right_Margin.      }
  1694.   { If the Line_Length exceeds the Right_Margin, or the  }
  1695.   { line is just a blank line, we exit and do nothing.   }
  1696.   {                                                      }
  1697.   { ---------------------------------------------------- }
  1698.  
  1699.  
  1700. VAR
  1701.  
  1702.   Spaces      : array [1..80] of Char;  { Array to hold spaces we'll insert. }
  1703.   Index       : Byte;                   { Index into Spaces array.           }
  1704.   Line_Length : Integer;                { Holds the length of the line.      }
  1705.  
  1706.   E : Word;                             { End of the current line.           }
  1707.   S : Word;                             { Start of the current line.         }
  1708.  
  1709. begin
  1710.  
  1711.   E := LineEnd (CurPtr);
  1712.   S := LineStart (CurPtr);
  1713.  
  1714.  
  1715.  
  1716.   { --------------------------------------------------------- }
  1717.   {                                                           }
  1718.   { If the line is blank (only a CR/LF on it) then do noting. }
  1719.   {                                                           }
  1720.   { --------------------------------------------------------- }
  1721.  
  1722.  
  1723.   if E = S then
  1724.     Exit;
  1725.  
  1726.  
  1727.  
  1728.   { ----------------------------------------------------------------- }
  1729.   {                                                                   }
  1730.   { Set CurPtr to start of line.  Check if line begins with a space.  }
  1731.   { We must strip out any spaces from the beginning, or end of lines. }
  1732.   { If line does not start with space, make sure line length does not }
  1733.   { exceed the Right_Margin.  If it does, then do nothing.            }
  1734.   {                                                                   }
  1735.   { ----------------------------------------------------------------- }
  1736.  
  1737.  
  1738.   SetCurPtr (S, Select_Mode);
  1739.   Remove_EOL_Spaces (Select_Mode);
  1740.  
  1741.   if Buffer^[CurPtr] = #32 then
  1742.     begin
  1743.  
  1744.  
  1745.  
  1746.       { ----------------------------------------------------------------- }
  1747.       {                                                                   }
  1748.       { If the next word is greater than the end of line then do nothing. }
  1749.       { If the line length is greater than Right_Margin then do nothing.  }
  1750.       { Otherwise, delete all spaces at the start of line.                }
  1751.       { Then reset end of line and put CurPtr at start of modified line.  }
  1752.       {                                                                   }
  1753.       { ----------------------------------------------------------------- }
  1754.  
  1755.       E := LineEnd (CurPtr);
  1756.  
  1757.       if NextWord (CurPtr) > E then
  1758.         Exit;
  1759.       if E - NextWord (CurPtr) > Right_Margin then
  1760.         Exit;
  1761.  
  1762.       DeleteRange (CurPtr, NextWord (CurPtr), True);
  1763.  
  1764.       E := LineEnd (CurPtr);
  1765.       SetCurPtr (LineStart (CurPtr), Select_Mode);
  1766.  
  1767.     end
  1768.   else
  1769.     if E - CurPtr > Right_Margin then
  1770.       Exit;
  1771.  
  1772.  
  1773.  
  1774.   { --------------------------------------------------- }
  1775.   {                                                     }
  1776.   { Now we determine the real length of the line.       }
  1777.   { Then we subtract the Line_Length from Right_Margin. }
  1778.   { Dividing the result by two tells us how many spaces }
  1779.   { must be inserted at start of line to center it.     }
  1780.   { When we're all done, set the CurPtr to end of line. }
  1781.   {                                                     }
  1782.   { --------------------------------------------------- }
  1783.  
  1784.  
  1785.   Line_Length := E - CurPtr;
  1786.  
  1787.   for Index := 1 to ((Right_Margin - Line_Length) DIV 2) do
  1788.     Spaces[Index] := #32;
  1789.  
  1790.   InsertText (@Spaces, Index, False);
  1791.   SetCurPtr (LineEnd (CurPtr), Select_Mode);
  1792.  
  1793.  
  1794. end; { TEditor.Center_Text }
  1795.  
  1796. { CENTER - Stop. }
  1797.  
  1798.  
  1799.  
  1800. { -------------------------------------------------------------------------- }
  1801.  
  1802.  
  1803.  
  1804. procedure TEditor.ChangeBounds (var Bounds : TRect);
  1805.  
  1806. begin
  1807.  
  1808.   SetBounds (Bounds);
  1809.   Delta.X := Max (0, Min (Delta.X, Limit.X - Size.X));
  1810.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  1811.   Update (ufView);
  1812.  
  1813.  
  1814. end; { TEditor.ChangeBounds }
  1815.  
  1816.  
  1817.  
  1818. { -------------------------------------------------------------------------- }
  1819.  
  1820.  
  1821.  
  1822. function TEditor.CharPos (P, Target : Word) : Integer;
  1823.  
  1824. VAR
  1825.  
  1826.   Pos : Integer;
  1827.  
  1828. begin
  1829.  
  1830.   Pos := 0;
  1831.  
  1832.   while P < Target do
  1833.   begin
  1834.     if BufChar (P) = #9 then
  1835.       Pos := Pos or 7;
  1836.     Inc (Pos);
  1837.     Inc (P);
  1838.   end;
  1839.  
  1840.   CharPos := Pos;
  1841.  
  1842.  
  1843. end; { TEditor.CharPos }
  1844.  
  1845.  
  1846.  
  1847. { -------------------------------------------------------------------------- }
  1848.  
  1849.  
  1850.  
  1851. function TEditor.CharPtr (P : Word; Target : Integer) : Word;
  1852.  
  1853. VAR
  1854.  
  1855.   Pos : Integer;
  1856.  
  1857. begin
  1858.  
  1859.   Pos := 0;
  1860.  
  1861.   while (Pos < Target) and (P < BufLen) and (BufChar (P) <> #13) do
  1862.   begin
  1863.     if BufChar (P) = #9 then
  1864.       Pos := Pos or 7;
  1865.     Inc (Pos);
  1866.     Inc (P);
  1867.   end;
  1868.  
  1869.   if Pos > Target then
  1870.     Dec (P);
  1871.  
  1872.   CharPtr := P;
  1873.  
  1874.  
  1875. end; { TEditor.CharPtr }
  1876.  
  1877.  
  1878.  
  1879. { -------------------------------------------------------------------------- }
  1880.  
  1881.  
  1882.  
  1883. { WRAP - Start. }
  1884.  
  1885. procedure TEditor.Check_For_Word_Wrap (Select_Mode   : Byte;
  1886.                                        Center_Cursor : Boolean);
  1887.  
  1888.  
  1889.  
  1890.   { ------------------------------------------------- }
  1891.   {                                                   }
  1892.   { This procedure checks if CurPos.X > Right_Margin. }
  1893.   { If it is, then we Do_Word_Wrap.  Simple, eh?      }
  1894.   {                                                   }
  1895.   { ------------------------------------------------- }
  1896.  
  1897. begin
  1898.  
  1899.   if CurPos.X > Right_Margin then
  1900.     Do_Word_Wrap (Select_Mode, Center_Cursor);
  1901.  
  1902.  
  1903. end; {Check_For_Word_Wrap}
  1904.  
  1905. { WRAP - Stop. }
  1906.  
  1907.  
  1908.  
  1909. { -------------------------------------------------------------------------- }
  1910.  
  1911.  
  1912.  
  1913. function TEditor.ClipCopy : Boolean;
  1914.  
  1915. begin
  1916.  
  1917.   ClipCopy := False;
  1918.  
  1919.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1920.   begin
  1921.     ClipCopy := Clipboard^.InsertFrom (@Self);
  1922.     Selecting := False;
  1923.     Update (ufUpdate);
  1924.   end;
  1925.  
  1926.  
  1927. end; { TEditor.ClipCopy }
  1928.  
  1929.  
  1930.  
  1931. { -------------------------------------------------------------------------- }
  1932.  
  1933.  
  1934.  
  1935. procedure TEditor.ClipCut;
  1936.  
  1937. begin
  1938.  
  1939.   if ClipCopy then
  1940.   begin
  1941.  
  1942.     { MARK - Start. }
  1943.  
  1944.     Update_Place_Markers (0,
  1945.                           Self.SelEnd - Self.SelStart,
  1946.                           Self.SelStart,
  1947.                           Self.SelEnd);
  1948.     { MARK - Stop. }
  1949.  
  1950.     DeleteSelect;
  1951.  
  1952.   end;
  1953.  
  1954.  
  1955. end; { TEditor.ClipCut }
  1956.  
  1957.  
  1958.  
  1959. { -------------------------------------------------------------------------- }
  1960.  
  1961.  
  1962.  
  1963. procedure TEditor.ClipPaste;
  1964.  
  1965. begin
  1966.  
  1967.  
  1968.  
  1969.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1970.     begin
  1971.  
  1972.  
  1973.  
  1974.       { WRAP - Start. }
  1975.  
  1976.       { ---------------------------------------------- }
  1977.       {                                                }
  1978.       { Do not allow paste operations that will exceed }
  1979.       { the Right_Margin when Word_Wrap is active and  }
  1980.       { cursor is at EOL.                              }
  1981.       {                                                }
  1982.       { ---------------------------------------------- }
  1983.  
  1984.  
  1985.       if Word_Wrap and (CurPos.X > Right_Margin) then
  1986.  
  1987.         begin
  1988.           EditorDialog (edPasteNotPossible, nil);
  1989.           Exit;
  1990.         end;
  1991.  
  1992.       { WRAP - Stop. }
  1993.  
  1994.  
  1995.  
  1996.       { MARK - Start. }
  1997.  
  1998.       { ---------------------------------------------------- }
  1999.       {                                                      }
  2000.       { The editor will not copy selected text if the CurPtr }
  2001.       { is not the same value as the SelStart.  However, it  }
  2002.       { does return an InsCount.  This may, or may not, be a }
  2003.       { bug.  We don't want to update the Place_Marker if    }
  2004.       { there's no text copied.                              }
  2005.       {                                                      }
  2006.       { ---------------------------------------------------- }
  2007.  
  2008.       if CurPtr = SelStart then
  2009.  
  2010.         Update_Place_Markers (Clipboard^.SelEnd - Clipboard^.SelStart,
  2011.                               0,
  2012.                               Clipboard^.SelStart,
  2013.                               Clipboard^.SelEnd);
  2014.  
  2015.       { MARK - Stop. }
  2016.  
  2017.       InsertFrom (Clipboard);
  2018.  
  2019.  
  2020.     end;
  2021.  
  2022.  
  2023. end; { TEditor.ClipPaste }
  2024.  
  2025.  
  2026.  
  2027. { -------------------------------------------------------------------------- }
  2028.  
  2029.  
  2030.  
  2031. procedure TEditor.ConvertEvent (var Event : Drivers.TEvent);
  2032.  
  2033. VAR
  2034.  
  2035.   ShiftState : Byte absolute $40:$17;
  2036.   Key        : Word;
  2037.  
  2038.  
  2039. begin
  2040.  
  2041.   if Event.What = evKeyDown then
  2042.   begin
  2043.  
  2044.     if (ShiftState and $03 <> 0)
  2045.                    and (Event.ScanCode >= $47)
  2046.                    and (Event.ScanCode <= $51) then
  2047.       Event.CharCode := #0;
  2048.  
  2049.     Key := Event.KeyCode;
  2050.  
  2051.     if KeyState <> 0 then
  2052.     begin
  2053.       if (Lo (Key) >= $01) and (Lo (Key) <= $1A) then
  2054.         Inc (Key, $40);
  2055.       if (Lo (Key) >= $61) and (Lo (Key) <= $7A) then
  2056.         Dec (Key, $20);
  2057.     end;
  2058.  
  2059.     Key := ScanKeyMap (KeyMap[KeyState], Key);
  2060.     KeyState := 0;
  2061.  
  2062.     if Key <> 0 then
  2063.       if Hi (Key) = $FF then
  2064.         begin
  2065.           KeyState := Lo (Key);
  2066.           ClearEvent (Event);
  2067.         end
  2068.       else
  2069.         begin
  2070.           Event.What := evCommand;
  2071.           Event.Command := Key;
  2072.         end;
  2073.   end;
  2074.  
  2075.  
  2076. end; { TEditor.ConvertEvent }
  2077.  
  2078.  
  2079.  
  2080. { -------------------------------------------------------------------------- }
  2081.  
  2082.  
  2083.  
  2084. function TEditor.CursorVisible : Boolean;
  2085.  
  2086. begin
  2087.  
  2088.   CursorVisible := (CurPos.Y >= Delta.Y) and (CurPos.Y < Delta.Y + Size.Y);
  2089.  
  2090. end; { TEditor.CursorVisible }
  2091.  
  2092.  
  2093.  
  2094. { -------------------------------------------------------------------------- }
  2095.  
  2096.  
  2097.  
  2098. procedure TEditor.DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  2099.  
  2100.  
  2101. begin
  2102.  
  2103.   { MARK - Start. }
  2104.  
  2105.   Update_Place_Markers (0, EndPtr - StartPtr, StartPtr, EndPtr);
  2106.  
  2107.   { MARK - Stop. } { This will update Place_Marker for all deletions. }
  2108.                    { EXCEPT the Remove_EOL_Spaces deletion.           }
  2109.  
  2110.   if HasSelection and DelSelect then
  2111.     DeleteSelect
  2112.   else
  2113.     begin
  2114.       SetSelect (CurPtr, EndPtr, True);
  2115.       DeleteSelect;
  2116.       SetSelect (StartPtr, CurPtr, False);
  2117.       DeleteSelect;
  2118.     end;
  2119.  
  2120.  
  2121. end; { TEditor.DeleteRange }
  2122.  
  2123.  
  2124.  
  2125. { -------------------------------------------------------------------------- }
  2126.  
  2127.  
  2128.  
  2129. procedure TEditor.DeleteSelect;
  2130.  
  2131. begin
  2132.  
  2133.   InsertText (nil, 0, False);
  2134.  
  2135. end; { TEditor.DeleteSelect }
  2136.  
  2137.  
  2138.  
  2139. { -------------------------------------------------------------------------- }
  2140.  
  2141.  
  2142. procedure TEditor.DoneBuffer;
  2143.  
  2144. begin
  2145.  
  2146.   if Buffer <> nil then
  2147.     begin
  2148.       FreeMem (Buffer, BufSize);
  2149.       Buffer := NIL;
  2150.     end;
  2151.  
  2152.  
  2153. end; { TEditor.DoneBuffer }
  2154.  
  2155.  
  2156.  
  2157. { -------------------------------------------------------------------------- }
  2158.  
  2159.  
  2160.  
  2161. procedure TEditor.DoSearchReplace;
  2162.  
  2163. VAR
  2164.  
  2165.   I : Word;
  2166.   C : Objects.TPoint;
  2167.  
  2168. begin
  2169.  
  2170.   repeat
  2171.  
  2172.     I := Views.cmCancel;
  2173.  
  2174.     if not Search (FindStr, EditorFlags) then
  2175.       begin
  2176.         if EditorFlags and (efReplaceAll + efDoReplace) <>
  2177.             (efReplaceAll + efDoReplace) then
  2178.           EditorDialog (edSearchFailed, nil)
  2179.       end
  2180.     else
  2181.  
  2182.       if EditorFlags and efDoReplace <> 0 then
  2183.       begin
  2184.  
  2185.         I := cmYes;
  2186.         if EditorFlags and efPromptOnReplace <> 0 then
  2187.         begin
  2188.           MakeGlobal (Cursor, C);
  2189.           I := EditorDialog (edReplacePrompt, Pointer (C));
  2190.         end;
  2191.  
  2192.         if I = cmYes then
  2193.           begin
  2194.  
  2195.             { WRAP - Start. }
  2196.  
  2197.             { ---------------------------------------- }
  2198.             {                                          }
  2199.             { If Word_Wrap is active and we are at EOL }
  2200.             { disallow replace by bringing up a dialog }
  2201.             { stating that replace is not possible.    }
  2202.             {                                          }
  2203.             { ---------------------------------------- }
  2204.  
  2205.             if Word_Wrap and
  2206.                ((CurPos.X + (Length (ReplaceStr) - Length (FindStr))) > Right_Margin) then
  2207.               EditorDialog (edReplaceNotPossible, nil)
  2208.             else
  2209.  
  2210.             { WRAP - Stop. }
  2211.  
  2212.               begin
  2213.  
  2214.                 Lock;
  2215.  
  2216.                 { MARK - Start. }
  2217.  
  2218.                 Search_Replace := True;
  2219.  
  2220.                 if length (ReplaceStr) < length (FindStr) then
  2221.                   Update_Place_Markers (0,
  2222.                                         Length (FindStr) - Length (ReplaceStr),
  2223.                                         CurPtr - Length (FindStr) + Length (ReplaceStr),
  2224.                                         CurPtr)
  2225.                 else
  2226.                   if length (ReplaceStr) > length (FindStr) then
  2227.                     Update_Place_Markers (Length (ReplaceStr) - Length (FindStr),
  2228.                                           0,
  2229.                                           CurPtr,
  2230.                                           CurPtr + (Length (ReplaceStr) - Length (FindStr)));
  2231.  
  2232.                 { MARK - Stop. }
  2233.  
  2234.                 InsertText (@ReplaceStr[1], Length (ReplaceStr), False);
  2235.  
  2236.                 { MARK - Start. }
  2237.  
  2238.                 Search_Replace := False;
  2239.  
  2240.                 { MARK - Stop. }
  2241.  
  2242.                 TrackCursor (False);
  2243.                 Unlock;
  2244.  
  2245.              end;
  2246.           end;
  2247.       end;
  2248.  
  2249.   until (I = Views.cmCancel) or (EditorFlags and efReplaceAll = 0);
  2250.  
  2251.  
  2252. end; { TEditor.DoSearchReplace }
  2253.  
  2254.  
  2255.  
  2256. { -------------------------------------------------------------------------- }
  2257.  
  2258.  
  2259.  
  2260. procedure TEditor.DoUpdate;
  2261.  
  2262. begin
  2263.  
  2264.   if UpdateFlags <> 0 then
  2265.   begin
  2266.  
  2267.     SetCursor (CurPos.X - Delta.X, CurPos.Y - Delta.Y);
  2268.  
  2269.     if UpdateFlags and ufView <> 0 then
  2270.       DrawView
  2271.     else
  2272.       if UpdateFlags and ufLine <> 0 then
  2273.         DrawLines (CurPos.Y - Delta.Y, 1, LineStart (CurPtr));
  2274.  
  2275.     if HScrollBar <> nil then
  2276.       HScrollBar^.SetParams (Delta.X, 0, Limit.X - Size.X, Size.X div 2, 1);
  2277.  
  2278.     if VScrollBar <> nil then
  2279.       VScrollBar^.SetParams (Delta.Y, 0, Limit.Y - Size.Y, Size.Y - 1, 1);
  2280.  
  2281.     { STATS - Start. }
  2282.  
  2283.     if Indicator <> nil then
  2284.       Indicator^.SetValue (CurPos, AutoIndent, Modified, Word_Wrap);
  2285.  
  2286.     { STATS - Stop. } { Added AutoIndent and Word_Wrap parameters. }
  2287.  
  2288.     if State and sfActive <> 0 then
  2289.       UpdateCommands;
  2290.  
  2291.     UpdateFlags := 0;
  2292.  
  2293.   end;
  2294.  
  2295.  
  2296. end; { TEditor.DoUpdate }
  2297.  
  2298.  
  2299.  
  2300. { -------------------------------------------------------------------------- }
  2301.  
  2302.  
  2303.  
  2304. { WRAP - Start. }
  2305.  
  2306. function TEditor.Do_Word_Wrap (Select_Mode   : Byte;
  2307.                                Center_Cursor : Boolean) : Boolean;
  2308.  
  2309.  
  2310.  
  2311.   { ---------------------------------------------------------------------- }
  2312.   {                                                                        }
  2313.   { This procedure does the actual wordwrap.  It always assumes the CurPtr }
  2314.   { is at Right_Margin + 1.  It makes several tests for special conditions }
  2315.   { and processes those first.  If they all fail, it does a normal wrap.   }
  2316.   {                                                                        }
  2317.   { ---------------------------------------------------------------------- }
  2318.  
  2319.  
  2320. VAR
  2321.  
  2322.   A : Word;          { Distance between line start and first word on line. }
  2323.   C : Word;          { Current pointer when we come into procedure.        }
  2324.   L : Word;          { BufLen when we come into procedure.                 }
  2325.   P : Word;          { Position of pointer at any given moment.            }
  2326.   S : Word;          { Start of a line.                                    }
  2327.  
  2328. begin
  2329.  
  2330.   Do_Word_Wrap := False;
  2331.   Select_Mode := 0;
  2332.  
  2333.   if BufLen >= (BufSize - 1) then
  2334.     exit;
  2335.  
  2336.   C := CurPtr;
  2337.   L := BufLen;
  2338.   S := LineStart (CurPtr);
  2339.  
  2340.  
  2341.  
  2342.   { -------------------------------------------------------------------- }
  2343.   {                                                                      }
  2344.   { If first character in the line is a space and autoindent mode is on  }
  2345.   { then we check to see if NextWord(S) exceeds the CurPtr.  If it does, }
  2346.   { we set CurPtr as the AutoIndent marker.  If it doesn't, we will set  }
  2347.   { NextWord(S) as the AutoIndent marker.  If neither, we set it to S.   }
  2348.   {                                                                      }
  2349.   { -------------------------------------------------------------------- }
  2350.  
  2351.  
  2352.   if AutoIndent and (Buffer^[S] = ' ') then
  2353.     begin
  2354.       if NextWord (S) > CurPtr then
  2355.         A := CurPtr
  2356.       else
  2357.         A := NextWord (S);
  2358.     end
  2359.   else
  2360.     A := NextWord (S);
  2361.  
  2362.  
  2363.  
  2364.   { --------------------------------------------------------- }
  2365.   {                                                           }
  2366.   { Though NewLine will remove EOL spaces, we do it here too. }
  2367.   { This catches the instance where a user may try to space   }
  2368.   { completely across the line, in which case CurPtr.X = 0.   }
  2369.   {                                                           }
  2370.   { --------------------------------------------------------- }
  2371.  
  2372.  
  2373.   Remove_EOL_Spaces (Select_Mode);
  2374.  
  2375.   if CurPos.X = 0 then
  2376.     begin
  2377.       NewLine (Select_Mode);
  2378.       Do_Word_Wrap := True;
  2379.       Exit;
  2380.     end;
  2381.  
  2382.  
  2383.  
  2384.   { --------------------------------------------------------------------------- }
  2385.   {                                                                             }
  2386.   { At this point we have one of five situations:                               }
  2387.   {                                                                             }
  2388.   { 1)  AutoIndent is on and this line is all spaces before CurPtr.             }
  2389.   { 2)  AutoIndent is off and this line is all spaces before CurPtr.            }
  2390.   { 3)  AutoIndent is on and this line is continuous characters before CurPtr.  }
  2391.   { 4)  AutoIndent is off and this line is continuous characters before CurPtr. }
  2392.   { 5)  This is just a normal line of text.                                     }
  2393.   {                                                                             }
  2394.   { Conditions 1 through 4 have to be taken into account before condition 5.    }
  2395.   {                                                                             }
  2396.   { --------------------------------------------------------------------------- }
  2397.  
  2398.  
  2399.  
  2400.   { ------------------------------------------------------------ }
  2401.   {                                                              }
  2402.   { First, we see if there are all spaces and/or all characters. }
  2403.   { Then we determine which one it really is.  Finally, we take  }
  2404.   { a course of action based on the state of AutoIndent.         }
  2405.   {                                                              }
  2406.   { ------------------------------------------------------------ }
  2407.  
  2408.  
  2409.  
  2410.   if PrevWord (CurPtr) <= S then
  2411.     begin
  2412.  
  2413.       P := CurPtr - 1;
  2414.  
  2415.       while ((Buffer^[P] <> ' ') and (P > S)) do
  2416.         Dec (P);
  2417.  
  2418.  
  2419.  
  2420.       { -------------------------------------------------------------- }
  2421.       {                                                                }
  2422.       { We found NO SPACES.  Conditions 4 and 5 are treated the same.  }
  2423.       { We can NOT do word wrap and put up a dialog box stating such.  }
  2424.       { Delete character just entered so we don't exceed Right_Margin. }
  2425.       {                                                                }
  2426.       { -------------------------------------------------------------- }
  2427.  
  2428.  
  2429.       if P = S then
  2430.         begin
  2431.           EditorDialog (edWrapNotPossible, nil);
  2432.           DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2433.           Exit;
  2434.         end
  2435.       else
  2436.         begin
  2437.  
  2438.  
  2439.  
  2440.           { ------------------------------------------------------- }
  2441.           {                                                         }
  2442.           { There are spaces.  Now find out if they are all spaces. }
  2443.           { If so, see if AutoIndent is on.  If it is, turn it off, }
  2444.           { do a NewLine, and turn it back on.  Otherwise, just do  }
  2445.           { the NewLine.  We go through all of these gyrations for  }
  2446.           { AutoIndent.  Being way out here with a preceding line   }
  2447.           { of spaces and wrapping with AutoIndent on is real dumb! }
  2448.           { However, the user expects something.  The wrap will NOT }
  2449.           { autoindent, but they had no business being here anyway! }
  2450.           {                                                         }
  2451.           { ------------------------------------------------------- }
  2452.  
  2453.  
  2454.           P := CurPtr - 1;
  2455.  
  2456.           while ((Buffer^[P] = ' ') and (P > S)) do
  2457.             Dec (P);
  2458.  
  2459.           if P = S then
  2460.             begin
  2461.  
  2462.               if Autoindent then
  2463.                 begin
  2464.                   AutoIndent := False;
  2465.                   NewLine (Select_Mode);
  2466.                   AutoIndent := True;
  2467.                 end
  2468.               else
  2469.                 NewLine (Select_Mode);
  2470.               end; { AutoIndent }
  2471.  
  2472.             end; { P = S for spaces }
  2473.  
  2474.         end { P = S for no spaces }
  2475.  
  2476.     else { PrevWord (CurPtr) <= S }
  2477.  
  2478.       begin
  2479.  
  2480.  
  2481.         { ---------------------------------------------------------------- }
  2482.         {                                                                  }
  2483.         { Hooray!  We actually had a plain old line of text to wrap!       }
  2484.         { Regardless if we are pushing out a line beyond the Right_Margin, }
  2485.         { or at the end of a line itself, the following will determine     }
  2486.         { exactly where to do the wrap and re-set the cursor accordingly.  }
  2487.         { However, if P = A then we can't wrap.  Show dialog and exit.     }
  2488.         {                                                                  }
  2489.         { ---------------------------------------------------------------- }
  2490.  
  2491.  
  2492.         P := CurPtr;
  2493.  
  2494.         while P - S > Right_Margin do
  2495.           P := PrevWord (P);
  2496.  
  2497.         if (P = A) then
  2498.           begin
  2499.             EditorDialog (edReformNotPossible, nil);
  2500.             SetCurPtr (P, Select_Mode);
  2501.             Exit;
  2502.           end;
  2503.  
  2504.         SetCurPtr (P, Select_Mode);
  2505.         NewLine (Select_Mode);
  2506.  
  2507.     end; { PrevWord (CurPtr <= S }
  2508.  
  2509.  
  2510.  
  2511.   { ---------------------------------------------------------- }
  2512.   {                                                            }
  2513.   { Track the cursor here (it is at CurPos.X = 0) so the view  }
  2514.   { will redraw itself at column 0.  This eliminates having it }
  2515.   { redraw starting at the current cursor and not being able   }
  2516.   { to see text before the cursor.  Of course, we also end up  }
  2517.   { redrawing the view twice, here and back in HandleEvent.    }
  2518.   {                                                            }
  2519.   { Reposition cursor so user can pick up where they left off. }
  2520.   {                                                            }
  2521.   { ---------------------------------------------------------- }
  2522.  
  2523.  
  2524.   TrackCursor (Center_Cursor);
  2525.   SetCurPtr (C - (L - BufLen), Select_Mode);
  2526.  
  2527.   Do_Word_Wrap := True;
  2528.  
  2529.  
  2530. end; { TEditor.Do_Word_Wrap }
  2531.  
  2532. { WRAP - Stop. }
  2533.  
  2534.  
  2535.  
  2536. { -------------------------------------------------------------------------- }
  2537.  
  2538.  
  2539.  
  2540. procedure TEditor.Draw;
  2541.  
  2542. begin
  2543.  
  2544.   if DrawLine <> Delta.Y then
  2545.   begin
  2546.     DrawPtr := LineMove (DrawPtr, Delta.Y - DrawLine);
  2547.     DrawLine := Delta.Y;
  2548.   end;
  2549.  
  2550.   DrawLines (0, Size.Y, DrawPtr);
  2551.  
  2552.  
  2553. end; { TEditor.Draw }
  2554.  
  2555.  
  2556.  
  2557. { -------------------------------------------------------------------------- }
  2558.  
  2559.  
  2560.  
  2561. procedure TEditor.DrawLines (Y, Count : Integer; LinePtr : Word);
  2562.  
  2563. VAR
  2564.  
  2565.   Color : Word;
  2566.   B     : array[0..MaxLineLength - 1] of Word;
  2567.  
  2568. begin
  2569.  
  2570.   Color := GetColor ($0201);
  2571.  
  2572.   while Count > 0 do
  2573.   begin
  2574.     FormatLine (B, LinePtr, Delta.X + Size.X, Color);
  2575.     WriteBuf (0, Y, Size.X, 1, B[Delta.X]);
  2576.     LinePtr := NextLine (LinePtr);
  2577.     Inc (Y);
  2578.     Dec (Count);
  2579.   end;
  2580.  
  2581.  
  2582. end; { TEditor.DrawLines }
  2583.  
  2584.  
  2585.  
  2586. { -------------------------------------------------------------------------- }
  2587.  
  2588.  
  2589.  
  2590. procedure TEditor.Find;
  2591.  
  2592. VAR
  2593.  
  2594.   FindRec : TFindDialogRec;
  2595.  
  2596. begin
  2597.  
  2598.   with FindRec do
  2599.   begin
  2600.  
  2601.     Find := FindStr;
  2602.     Options := EditorFlags;
  2603.  
  2604.     if EditorDialog (edFind, @FindRec) <> Views.cmCancel then
  2605.     begin
  2606.       FindStr := Find;
  2607.       EditorFlags := Options and not efDoReplace;
  2608.       DoSearchReplace;
  2609.     end;
  2610.  
  2611.   end;
  2612.  
  2613.  
  2614. end; { TEditor.Find }
  2615.  
  2616.  
  2617.  
  2618. { -------------------------------------------------------------------------- }
  2619.  
  2620.  
  2621.  
  2622. procedure TEditor.FormatLine (var DrawBuf; LinePtr : Word;
  2623.                                   Width  : Integer;
  2624.                                   Colors : Word); assembler;
  2625.  
  2626. asm
  2627.         PUSH    DS
  2628.         LDS     BX,Self
  2629.         LES     DI,DrawBuf
  2630.         MOV     SI,LinePtr
  2631.         XOR     DX,DX
  2632.         CLD
  2633.         MOV     AH,Colors.Byte[0]
  2634.         MOV     CX,DS:[BX].TEditor.SelStart
  2635.         CALL    @@10
  2636.         MOV     AH,Colors.Byte[1]
  2637.         MOV     CX,DS:[BX].TEditor.CurPtr
  2638.         CALL    @@10
  2639.         ADD     SI,DS:[BX].TEditor.GapLen
  2640.         MOV     CX,DS:[BX].TEditor.SelEnd
  2641.         ADD     CX,DS:[BX].TEditor.GapLen
  2642.         CALL    @@10
  2643.         MOV     AH,Colors.Byte[0]
  2644.         MOV     CX,DS:[BX].TEditor.BufSize
  2645.         CALL    @@10
  2646.         JMP     @@31
  2647. @@10:   SUB     CX,SI
  2648.         JA      @@11
  2649.         RETN
  2650. @@11:   LDS     BX,DS:[BX].TEditor.Buffer
  2651.         ADD     SI,BX
  2652.         MOV     BX,Width
  2653. @@12:   LODSB
  2654.         CMP     AL,' '
  2655.         JB      @@20
  2656. @@13:   STOSW
  2657.         INC     DX
  2658. @@14:   CMP     DX,BX
  2659.         JAE     @@30
  2660.         LOOP    @@12
  2661.         LDS     BX,Self
  2662.         SUB     SI,DS:[BX].TEditor.Buffer.Word[0]
  2663.         RETN
  2664. @@20:   CMP     AL,0DH
  2665.         JE      @@30
  2666.         CMP     AL,09H
  2667.         JNE     @@13
  2668.         MOV     AL,' '
  2669. @@21:   STOSW
  2670.         INC     DX
  2671.         TEST    DL,7
  2672.         JNE     @@21
  2673.         JMP     @@14
  2674. @@30:   POP     CX
  2675. @@31:   MOV     AL,' '
  2676.         MOV     CX,Width
  2677.         SUB     CX,DX
  2678.         JBE     @@32
  2679.         REP     STOSW
  2680. @@32:   POP     DS
  2681.  
  2682.  
  2683. end; {TEditor.FormatLine}
  2684.  
  2685.  
  2686.  
  2687. { -------------------------------------------------------------------------- }
  2688.  
  2689.  
  2690.  
  2691. function TEditor.GetMousePtr (Mouse : Objects.TPoint) : Word;
  2692.  
  2693. begin
  2694.  
  2695.   MakeLocal (Mouse, Mouse);
  2696.   Mouse.X := Max (0, Min (Mouse.X, Size.X - 1));
  2697.   Mouse.Y := Max (0, Min (Mouse.Y, Size.Y - 1));
  2698.  
  2699.   GetMousePtr := CharPtr (LineMove (DrawPtr, Mouse.Y + Delta.Y - DrawLine),
  2700.                           Mouse.X + Delta.X);
  2701.  
  2702.  
  2703. end; { TEditor.GetMousePtr }
  2704.  
  2705.  
  2706.  
  2707. { -------------------------------------------------------------------------- }
  2708.  
  2709.  
  2710.  
  2711. function TEditor.GetPalette : Views.PPalette;
  2712.  
  2713. CONST
  2714.  
  2715.   P : String[Length (CEditor)] = CEditor;
  2716.  
  2717. begin
  2718.  
  2719.   GetPalette := @P;
  2720.  
  2721.  
  2722. end; { TEditor.GetPalette }
  2723.  
  2724.  
  2725.  
  2726. { -------------------------------------------------------------------------- }
  2727.  
  2728.  
  2729.  
  2730. procedure TEditor.HandleEvent (var Event : Drivers.TEvent);
  2731.  
  2732. VAR
  2733.  
  2734.   ShiftState   : Byte absolute $40:$17;
  2735.   CenterCursor : Boolean;
  2736.   SelectMode   : Byte;
  2737.   I            : Integer;
  2738.   D            : Objects.TPoint;
  2739.   Mouse        : Objects.TPoint;
  2740.  
  2741.  
  2742.  
  2743.   { ------------------------------------------------------------------------ }
  2744.  
  2745.  
  2746.  
  2747.   { SCRLBG - Start }
  2748.  
  2749.   { procedure CheckScrollBar (P : PScrollBar; var D : Integer); }
  2750.   function CheckScrollBar (P : PScrollBar; var D : Integer) : Boolean;
  2751.  
  2752.   { SCRLBG - Stop. } { Changed froma procedure to a function. }
  2753.  
  2754.   begin
  2755.  
  2756.     { SCRLBG - Start. }
  2757.  
  2758.     CheckScrollBar := FALSE;
  2759.  
  2760.     { SCRLBG - Stop. } { Set function return to default to FALSE. }
  2761.  
  2762.     if (Event.InfoPtr = P) and (P^.Value <> D) then
  2763.     begin
  2764.       D := P^.Value;
  2765.       Update (ufView);
  2766.  
  2767.       { SCRLBG - Start. }
  2768.  
  2769.       CheckScrollBar := TRUE;
  2770.  
  2771.       { SCRLBG - Stop. } { Set function return to TRUE. }
  2772.  
  2773.     end;
  2774.  
  2775.  
  2776.   end; {CheckScrollBar}
  2777.  
  2778.  
  2779.  
  2780.   { ------------------------------------------------------------------------ }
  2781.  
  2782.  
  2783.  
  2784. begin
  2785.  
  2786.   TView.HandleEvent (Event);
  2787.   ConvertEvent (Event);
  2788.   CenterCursor := not CursorVisible;
  2789.   SelectMode := 0;
  2790.  
  2791.   if Selecting or (ShiftState and $03 <> 0) then
  2792.     SelectMode := smExtend;
  2793.  
  2794.   case Event.What of
  2795.  
  2796.     Drivers.evMouseDown:
  2797.  
  2798.       begin
  2799.         if Event.Double then
  2800.           SelectMode := SelectMode or smDouble;
  2801.  
  2802.         repeat
  2803.           Lock;
  2804.  
  2805.           if Event.What = evMouseAuto then
  2806.           begin
  2807.             MakeLocal (Event.Where, Mouse);
  2808.             D := Delta;
  2809.             if Mouse.X < 0 then
  2810.               Dec (D.X);
  2811.             if Mouse.X >= Size.X then
  2812.               Inc (D.X);
  2813.             if Mouse.Y < 0 then
  2814.               Dec (D.Y);
  2815.             if Mouse.Y >= Size.Y then
  2816.               Inc (D.Y);
  2817.             ScrollTo (D.X, D.Y);
  2818.           end;
  2819.  
  2820.           SetCurPtr (GetMousePtr (Event.Where), SelectMode);
  2821.           SelectMode := SelectMode or smExtend;
  2822.           Unlock;
  2823.  
  2824.         until not MouseEvent (Event, evMouseMove + evMouseAuto);
  2825.  
  2826.       end; { Drivers.evMouseDown }
  2827.  
  2828.     Drivers.evKeyDown:
  2829.  
  2830.       case Event.CharCode of
  2831.  
  2832.         #32..#255:
  2833.  
  2834.           begin
  2835.             Lock;
  2836.  
  2837.             if Overwrite and not HasSelection then
  2838.               if CurPtr <> LineEnd (CurPtr) then
  2839.                 SelEnd := NextChar (CurPtr);
  2840.  
  2841.             InsertText (@Event.CharCode, 1, False);
  2842.  
  2843.             { WRAP - Start. }
  2844.  
  2845.             if Word_Wrap then
  2846.               Check_For_Word_Wrap (SelectMode, CenterCursor);
  2847.  
  2848.             { WRAP - Stop. } { Added code to check for wordwrap. }
  2849.  
  2850.             TrackCursor (CenterCursor);
  2851.             Unlock;
  2852.  
  2853.           end;
  2854.  
  2855.       else
  2856.  
  2857.         Exit;
  2858.  
  2859.       end; { Drivers.evKeyDown }
  2860.  
  2861.     Drivers.evCommand:
  2862.  
  2863.       case Event.Command of
  2864.  
  2865.         cmFind        : Find;
  2866.         cmReplace     : Replace;
  2867.         cmSearchAgain : DoSearchReplace;
  2868.  
  2869.       else
  2870.  
  2871.         begin
  2872.  
  2873.           Lock;
  2874.  
  2875.           case Event.Command of
  2876.  
  2877.             cmCut         : ClipCut;
  2878.             cmCopy        : ClipCopy;
  2879.             cmPaste       : ClipPaste;
  2880.             cmUndo        : Undo;
  2881.             cmClear       : DeleteSelect;
  2882.             cmCharLeft    : SetCurPtr (PrevChar  (CurPtr), SelectMode);
  2883.             cmCharRight   : SetCurPtr (NextChar  (CurPtr), SelectMode);
  2884.             cmWordLeft    : SetCurPtr (PrevWord  (CurPtr), SelectMode);
  2885.             cmWordRight   : SetCurPtr (NextWord  (CurPtr), SelectMode);
  2886.             cmLineStart   : SetCurPtr (LineStart (CurPtr), SelectMode);
  2887.             cmLineEnd     : SetCurPtr (LineEnd   (CurPtr), SelectMode);
  2888.             cmLineUp      : SetCurPtr (LineMove  (CurPtr, -1), SelectMode);
  2889.             cmLineDown    : SetCurPtr (LineMove  (CurPtr, 1),  SelectMode);
  2890.             cmPageUp      : SetCurPtr (LineMove  (CurPtr, - (Size.Y - 1)), SelectMode);
  2891.             cmPageDown    : SetCurPtr (LineMove  (CurPtr, Size.Y - 1), SelectMode);
  2892.             cmTextStart   : SetCurPtr (0, SelectMode);
  2893.             cmTextEnd     : SetCurPtr (BufLen, SelectMode);
  2894.  
  2895.             { WRAP - Start. }
  2896.  
  2897.             cmNewLine     : NewLine (SelectMode);
  2898.  
  2899.             { WRAP - Stop. } { Add new parameter to call. }
  2900.  
  2901.             cmBackSpace   : DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2902.             cmDelChar     : DeleteRange (CurPtr, NextChar (CurPtr), True);
  2903.             cmDelWord     : DeleteRange (CurPtr, NextWord (CurPtr), False);
  2904.             cmDelStart    : DeleteRange (LineStart (CurPtr), CurPtr, False);
  2905.             cmDelEnd      : DeleteRange (CurPtr, LineEnd (CurPtr), False);
  2906.             cmDelLine     : DeleteRange (LineStart (CurPtr), NextLine (CurPtr), False);
  2907.             cmInsMode     : ToggleInsMode;
  2908.             cmStartSelect : StartSelect;
  2909.             cmHideSelect  : HideSelect;
  2910.  
  2911.             { STATS - Start. }
  2912.  
  2913.             cmIndentMode  : begin
  2914.                               AutoIndent := not AutoIndent;
  2915.                               Update (ufStats);
  2916.                             end; { Added provision to update TIndicator if ^QI pressed. }
  2917.  
  2918.             { STATS - Stop. }
  2919.  
  2920.             { CENTER - Start. }
  2921.             { HOMEND - Start. }
  2922.             { INSLIN - Start. }
  2923.             { JLINE  - Start. }
  2924.             { MARK   - Start. }
  2925.             { PRETAB - Start. }
  2926.             { REFDOC - Start. }
  2927.             { REFORM - Start. }
  2928.             { RMSET  - Start. }
  2929.             { SCRLDN - Start. }
  2930.             { SCRLUP - Start. }
  2931.             { SELWRD - Start. }
  2932.             { WRAP   - Start. }
  2933.  
  2934.             cmCenterText  : Center_Text (SelectMode);
  2935.             cmEndPage     : SetCurPtr (LineMove  (CurPtr, Delta.Y - CurPos.Y + Size.Y - 1), SelectMode);
  2936.             cmHomePage    : SetCurPtr (LineMove  (CurPtr, -(CurPos.Y - Delta.Y)), SelectMode);
  2937.             cmInsertLine  : Insert_Line (SelectMode);
  2938.             cmJumpLine    : Jump_To_Line (SelectMode);
  2939.             cmReformDoc   : Reformat_Document (SelectMode, CenterCursor);
  2940.             cmReformPara  : Reformat_Paragraph (SelectMode, CenterCursor);
  2941.             cmRightMargin : Set_Right_Margin;
  2942.             cmScrollDown  : Scroll_Down;
  2943.             cmScrollUp    : Scroll_Up;
  2944.             cmSelectWord  : Select_Word;
  2945.             cmSetTabs     : Set_Tabs;
  2946.             cmTabKey      : Tab_Key (SelectMode);
  2947.  
  2948.             { STATS  - Start. }
  2949.  
  2950.             cmWordWrap    : begin
  2951.                               Word_Wrap := not Word_Wrap;
  2952.                               Update (ufStats);
  2953.                             end; { Added provision to update TIndicator if ^OW pressed. }
  2954.  
  2955.             { STATS  - Stop. }
  2956.  
  2957.             cmSetMark0    : Set_Place_Marker (10);
  2958.             cmSetMark1    : Set_Place_Marker  (1);
  2959.             cmSetMark2    : Set_Place_Marker  (2);
  2960.             cmSetMark3    : Set_Place_Marker  (3);
  2961.             cmSetMark4    : Set_Place_Marker  (4);
  2962.             cmSetMark5    : Set_Place_Marker  (5);
  2963.             cmSetMark6    : Set_Place_Marker  (6);
  2964.             cmSetMark7    : Set_Place_Marker  (7);
  2965.             cmSetMark8    : Set_Place_Marker  (8);
  2966.             cmSetMark9    : Set_Place_Marker  (9);
  2967.  
  2968.             cmJumpMark0   : Jump_Place_Marker (10, SelectMode);
  2969.             cmJumpMark1   : Jump_Place_Marker  (1, SelectMode);
  2970.             cmJumpMark2   : Jump_Place_Marker  (2, SelectMode);
  2971.             cmJumpMark3   : Jump_Place_Marker  (3, SelectMode);
  2972.             cmJumpMark4   : Jump_Place_Marker  (4, SelectMode);
  2973.             cmJumpMark5   : Jump_Place_Marker  (5, SelectMode);
  2974.             cmJumpMark6   : Jump_Place_Marker  (6, SelectMode);
  2975.             cmJumpMark7   : Jump_Place_Marker  (7, SelectMode);
  2976.             cmJumpMark8   : Jump_Place_Marker  (8, SelectMode);
  2977.             cmJumpMark9   : Jump_Place_Marker  (9, SelectMode);
  2978.  
  2979.             { WRAP   - Stop. } { Added cmWordWrap event.                  }
  2980.             { SELWRD - Stop. } { Added cmSelectWord event.                }
  2981.             { SCRLUP - Stop. } { Added cmScrollUp event.                  }
  2982.             { SCRLDN - Stop. } { Added cmScrollDown event.                }
  2983.             { RMSET  - Stop. } { Added cmRightMargin event.               }
  2984.             { REFORM - Stop. } { Added cmReformPara event.                }
  2985.             { REFDOC - Stop. } { Added cmReformDoc event.                 }
  2986.             { PRETAB - Stop. } { Added cmTabKey event.                    }
  2987.             { MARK   - Stop. } { Added cmSetMark# and cmJumpMark# events. }
  2988.             { JLINE  - Stop. } { Added cmJumpLine event.                  }
  2989.             { INSLIN - Stop. } { Added cmInsertLine event.                }
  2990.             { HOMEND - Stop. } { Added cmHomePage and cmEndPage events.   }
  2991.             { CENTER - Stop. { { Added cmCenterText event.                }
  2992.  
  2993.           else
  2994.  
  2995.             Unlock;
  2996.             Exit;
  2997.  
  2998.           end; { Event.Command (Inner) }
  2999.  
  3000.           TrackCursor (CenterCursor);
  3001.  
  3002.           { WRAP - Start. }
  3003.  
  3004.           { ------------------------------------------------------------ }
  3005.           {                                                              }
  3006.           { If the user presses any key except cmNewline or cmBackspace  }
  3007.           { we need to check if the file has been modified yet.  There   }
  3008.           { can be no spaces at the end of a line, or wordwrap doesn't   }
  3009.           { work properly.  We don't want to do this if the file hasn't  }
  3010.           { been modified because the user could be bringing in an ASCII }
  3011.           { file from an editor that allows spaces at the EOL.  If we    }
  3012.           { took them out in that scenario the "M" would appear on the   }
  3013.           { TIndicator line and the user would get upset or confused.    }
  3014.           {                                                              }
  3015.           { ------------------------------------------------------------ }
  3016.  
  3017.  
  3018.           if (Event.Command <> cmNewLine)   and
  3019.              (Event.Command <> cmBackSpace) and
  3020.              (Event.Command <> cmTabKey)    and
  3021.               Modified then
  3022.             Remove_EOL_Spaces (SelectMode);
  3023.  
  3024.           { WRAP - Stop. } { Added code to check for wordwrap, and to  }
  3025.                            { ignore removing EOL spaces for cmNewLine. }
  3026.  
  3027.           Unlock;
  3028.  
  3029.         end; { Event.Command (Outer) }
  3030.  
  3031.       end; { Drivers.evCommand }
  3032.  
  3033.     Drivers.evBroadcast:
  3034.  
  3035.       case Event.Command of
  3036.         cmScrollBarChanged:
  3037.           begin
  3038.  
  3039.             { SCRLBG - Start. }
  3040.  
  3041.             { ------------------------------------------------------------ }
  3042.             {                                                              }
  3043.             { The problem with this bug was that it would clear the event. }
  3044.             { Don't allow the event to be cleared if the sending scrollbar }
  3045.             { is not the scrollbar in question.                            }
  3046.             {                                                              }
  3047.             { ------------------------------------------------------------ }
  3048.  
  3049.             { CheckScrollBar (HScrollBar, Delta.X); }
  3050.             { CheckScrollBar (VScrollBar, Delta.Y); }
  3051.  
  3052.             if NOT (CheckScrollBar (HScrollBar, Delta.X)
  3053.                 OR  CheckScrollBar (VScrollBar, Delta.Y)) then
  3054.               Exit;
  3055.  
  3056.           end;
  3057.       else
  3058.  
  3059.         Exit;
  3060.  
  3061.       end; { Drivers.evBroadcast }
  3062.  
  3063.   end;
  3064.  
  3065.   ClearEvent (Event);
  3066.  
  3067.  
  3068. end; { TEditor.HandleEvent }
  3069.  
  3070.  
  3071.  
  3072. { -------------------------------------------------------------------------- }
  3073.  
  3074.  
  3075.  
  3076. function TEditor.HasSelection : Boolean;
  3077.  
  3078. begin
  3079.  
  3080.   HasSelection := SelStart <> SelEnd;
  3081.  
  3082.  
  3083. end; { TEditor.HasSelection }
  3084.  
  3085.  
  3086.  
  3087. { -------------------------------------------------------------------------- }
  3088.  
  3089.  
  3090.  
  3091. procedure TEditor.HideSelect;
  3092.  
  3093. begin
  3094.  
  3095.   Selecting := False;
  3096.   SetSelect (CurPtr, CurPtr, False);
  3097.  
  3098.  
  3099. end; { TEditor.HideSelect }
  3100.  
  3101.  
  3102.  
  3103. { -------------------------------------------------------------------------- }
  3104.  
  3105.  
  3106.  
  3107. procedure TEditor.InitBuffer;
  3108.  
  3109. begin
  3110.  
  3111.   Buffer := MemAlloc (BufSize);
  3112.  
  3113.  
  3114. end; { TEditor.InitBuffer }
  3115.  
  3116.  
  3117.  
  3118. { -------------------------------------------------------------------------- }
  3119.  
  3120.  
  3121.  
  3122. function TEditor.InsertBuffer (var P : PEditBuffer;
  3123.                                Offset,    Length     : Word;
  3124.                                AllowUndo, SelectText : Boolean) : Boolean;
  3125.  
  3126. VAR
  3127.  
  3128.   SelLen   : Word;
  3129.   DelLen   : Word;
  3130.   SelLines : Word;
  3131.   Lines    : Word;
  3132.   NewSize  : Longint;
  3133.  
  3134. begin
  3135.  
  3136.   InsertBuffer := True;
  3137.   Selecting := False;
  3138.  
  3139.   SelLen := SelEnd - SelStart;
  3140.  
  3141.   if (SelLen = 0) and (Length = 0) then
  3142.     Exit;
  3143.  
  3144.   DelLen := 0;
  3145.  
  3146.   if AllowUndo then
  3147.     if CurPtr = SelStart then
  3148.       DelLen := SelLen
  3149.     else
  3150.       if SelLen > InsCount then
  3151.         DelLen := SelLen - InsCount;
  3152.  
  3153.   NewSize := Longint (BufLen + DelCount - SelLen + DelLen) + Length;
  3154.  
  3155.   if NewSize > BufLen + DelCount then
  3156.     if (NewSize > $FFF0) or not SetBufSize (NewSize) then
  3157.       begin
  3158.         EditorDialog (edOutOfMemory, nil);
  3159.         InsertBuffer := False;
  3160.         SelEnd := SelStart;
  3161.         Exit;
  3162.       end;
  3163.  
  3164.   SelLines := CountLines (Buffer^[BufPtr (SelStart)], SelLen);
  3165.  
  3166.   if CurPtr = SelEnd then
  3167.   begin
  3168.  
  3169.     if AllowUndo then
  3170.     begin
  3171.       if DelLen > 0 then
  3172.         Move (Buffer^[SelStart], Buffer^[CurPtr + GapLen - DelCount - DelLen], DelLen);
  3173.       Dec (InsCount, SelLen - DelLen);
  3174.     end;
  3175.  
  3176.     CurPtr := SelStart;
  3177.     Dec (CurPos.Y, SelLines);
  3178.  
  3179.   end;
  3180.  
  3181.   if Delta.Y > CurPos.Y then
  3182.     begin
  3183.       Dec (Delta.Y, SelLines);
  3184.       if Delta.Y < CurPos.Y then
  3185.         Delta.Y := CurPos.Y;
  3186.     end;
  3187.  
  3188.   if Length > 0 then
  3189.     Move (P^[Offset], Buffer^[CurPtr], Length);
  3190.  
  3191.   Lines := CountLines (Buffer^[CurPtr], Length);
  3192.  
  3193.   Inc (CurPtr, Length);
  3194.   Inc (CurPos.Y, Lines);
  3195.  
  3196.   DrawLine := CurPos.Y;
  3197.   DrawPtr := LineStart (CurPtr);
  3198.  
  3199.   CurPos.X := CharPos (DrawPtr, CurPtr);
  3200.  
  3201.   if not SelectText then
  3202.     SelStart := CurPtr;
  3203.  
  3204.   SelEnd := CurPtr;
  3205.  
  3206.   Inc (BufLen, Length - SelLen);
  3207.   Dec (GapLen, Length - SelLen);
  3208.  
  3209.   if AllowUndo then
  3210.     begin
  3211.       Inc (DelCount, DelLen);
  3212.       Inc (InsCount, Length);
  3213.     end;
  3214.  
  3215.   Inc (Limit.Y, Lines - SelLines);
  3216.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  3217.  
  3218.   if not IsClipboard then
  3219.     Modified := True;
  3220.  
  3221.   SetBufSize (BufLen + DelCount);
  3222.  
  3223.   if (SelLines = 0) and (Lines = 0) then
  3224.     Update (ufLine)
  3225.   else
  3226.     Update (ufView);
  3227.  
  3228.  
  3229. end; { TEditor.InsertBuffer }
  3230.  
  3231.  
  3232.  
  3233. { -------------------------------------------------------------------------- }
  3234.  
  3235.  
  3236.  
  3237. function TEditor.InsertFrom (Editor : PEditor) : Boolean;
  3238.  
  3239. begin
  3240.  
  3241.   InsertFrom := InsertBuffer (Editor^.Buffer,
  3242.     Editor^.BufPtr (Editor^.SelStart),
  3243.     Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
  3244.  
  3245.  
  3246. end; { TEditor.InsertFrom }
  3247.  
  3248.  
  3249.  
  3250. { -------------------------------------------------------------------------- }
  3251.  
  3252.  
  3253.  
  3254. { INSLIN - Start. }
  3255.  
  3256. procedure TEditor.Insert_Line (Select_Mode : Byte);
  3257.  
  3258.  
  3259.   { --------------------------------------------------------------- }
  3260.   {                                                                 }
  3261.   { This procedure inserts a newline at the current cursor position }
  3262.   { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
  3263.   { to its original position.  If the cursor was at the end of a    }
  3264.   { line, and its spaces were removed, the cursor returns to the    }
  3265.   { end of the line instead.                                        }
  3266.   {                                                                 }
  3267.   { --------------------------------------------------------------- }
  3268.  
  3269.  
  3270.  
  3271. begin
  3272.  
  3273.   NewLine (Select_Mode);
  3274.   SetCurPtr (LineEnd (LineMove (CurPtr, -1)), Select_Mode);
  3275.  
  3276.  
  3277. end; { TEditor.Insert_Line }
  3278.  
  3279. { INSLIN - Stop. }
  3280.  
  3281.  
  3282.  
  3283. { -------------------------------------------------------------------------- }
  3284.  
  3285.  
  3286.  
  3287. function TEditor.InsertText (Text       : Pointer;
  3288.                              Length     : Word;
  3289.                              SelectText : Boolean) : Boolean;
  3290.  
  3291. begin
  3292.  
  3293.   { MARK - Start. }
  3294.  
  3295.   if (Text <> NIL) and not Search_Replace then
  3296.     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
  3297.  
  3298.   { MARK - Stop } { This will update Place_Marker ONLY if we are inserting text.}
  3299.                   { ClipPaste and deletions of any sort are handled elsewhere.  }
  3300.  
  3301.   InsertText := InsertBuffer (PEditBuffer (Text),
  3302.                 0, Length, CanUndo, SelectText);
  3303.  
  3304.  
  3305. end; { TEditor.InsertText }
  3306.  
  3307.  
  3308.  
  3309. { -------------------------------------------------------------------------- }
  3310.  
  3311.  
  3312.  
  3313. function TEditor.IsClipboard : Boolean;
  3314.  
  3315. begin
  3316.  
  3317.   IsClipboard := Clipboard = @Self;
  3318.  
  3319.  
  3320. end; { TEditor.IsClipboard }
  3321.  
  3322.  
  3323.  
  3324. { -------------------------------------------------------------------------- }
  3325.  
  3326.  
  3327.  
  3328. { MARK - Start. }
  3329.  
  3330. procedure TEditor.Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  3331.  
  3332.  
  3333.   { ---------------------------------------------------------- }
  3334.   {                                                            }
  3335.   { This procedure jumps to a place marker if ^Q# is pressed.  }
  3336.   { We don't go anywhere if Place_Marker[Element] is not zero. }
  3337.   {                                                            }
  3338.   { ---------------------------------------------------------- }
  3339.  
  3340.  
  3341. begin
  3342.  
  3343.   if (not IsClipboard) and (Place_Marker[Element] <> 0) then
  3344.     SetCurPtr (Place_Marker[Element], Select_Mode);
  3345.  
  3346.  
  3347. end; { TEditor.Jump_Place_Marker }
  3348.  
  3349. { MARK - Stop. }
  3350.  
  3351.  
  3352.  
  3353. { -------------------------------------------------------------------------- }
  3354.  
  3355.  
  3356.  
  3357. { JLINE - Start. }
  3358.  
  3359. procedure TEditor.Jump_To_Line (Select_Mode : Byte);
  3360.  
  3361.  
  3362.   { ------------------------------------------------ }
  3363.   {                                                  }
  3364.   { This function brings up a dialog box that allows }
  3365.   { the user to select a line number to jump to.     }
  3366.   {                                                  }
  3367.   { ------------------------------------------------ }
  3368.  
  3369.  
  3370. VAR
  3371.  
  3372.   Code       : Integer;         { Used for Val conversion.      }
  3373.   Temp_Value : Integer;         { Holds converted dialog value. }
  3374.  
  3375. begin
  3376.  
  3377.  
  3378.   if EditorDialog (edJumpToLine, @Line_Number) <> Views.cmCancel then
  3379.     begin
  3380.  
  3381.  
  3382.  
  3383.       { ---------------------------------------------- }
  3384.       {                                                }
  3385.       { Convert the Line_Number string to an interger. }
  3386.       { Put it into Temp_Value.  If the number is not  }
  3387.       { in the range 1..9999 abort.  If the number is  }
  3388.       { our current Y position, abort.  Otherwise,     }
  3389.       { go to top of document, and jump to the line.   }
  3390.       { There are faster methods.  This one's easy.    }
  3391.       { Note that CurPos.Y is always 1 less than what  }
  3392.       { the TIndicator line says.                      }
  3393.       {                                                }
  3394.       { ---------------------------------------------- }
  3395.  
  3396.  
  3397.       val (Line_Number, Temp_Value, Code);
  3398.  
  3399.       if (Temp_Value < 1) or (Temp_Value > 9999) then
  3400.         Exit;
  3401.  
  3402.       if Temp_Value = CurPos.Y + 1 then
  3403.         Exit;
  3404.  
  3405.       SetCurPtr (0, Select_Mode);
  3406.       SetCurPtr (LineMove (CurPtr, Temp_Value - 1), Select_Mode);
  3407.  
  3408.     end;
  3409.  
  3410.  
  3411. end; {TEditor.Jump_To_Line}
  3412.  
  3413. { JLINE - Stop. }
  3414.  
  3415.  
  3416.  
  3417. { -------------------------------------------------------------------------- }
  3418.  
  3419.  
  3420.  
  3421. function TEditor.LineEnd (P : Word) : Word; assembler;
  3422.  
  3423. asm
  3424.         PUSH    DS
  3425.         LDS     SI,Self
  3426.         LES     BX,DS:[SI].TEditor.Buffer
  3427.         MOV     DI,P
  3428.         MOV     AL,0DH
  3429.         CLD
  3430.         MOV     CX,DS:[SI].TEditor.CurPtr
  3431.         SUB     CX,DI
  3432.         JBE     @@1
  3433.         ADD     DI,BX
  3434.         REPNE   SCASB
  3435.         JE      @@2
  3436.         MOV     DI,DS:[SI].TEditor.CurPtr
  3437. @@1:    MOV     CX,DS:[SI].TEditor.BufLen
  3438.         SUB     CX,DI
  3439.         JCXZ    @@4
  3440.         ADD     BX,DS:[SI].TEditor.GapLen
  3441.         ADD     DI,BX
  3442.         REPNE   SCASB
  3443.         JNE     @@3
  3444. @@2:    DEC     DI
  3445. @@3:    SUB     DI,BX
  3446. @@4:    MOV     AX,DI
  3447.         POP     DS
  3448.  
  3449.  
  3450. end; { TEditor.LineEnd }
  3451.  
  3452.  
  3453.  
  3454. { -------------------------------------------------------------------------- }
  3455.  
  3456.  
  3457.  
  3458. function TEditor.LineMove (P : Word; Count : Integer) : Word;
  3459.  
  3460. VAR
  3461.  
  3462.   Pos : Integer;
  3463.   I   : Word;
  3464.  
  3465. begin
  3466.  
  3467.   I := P;
  3468.   P := LineStart (P);
  3469.   Pos := CharPos (P, I);
  3470.  
  3471.   while Count <> 0 do
  3472.   begin
  3473.     I := P;
  3474.     if Count < 0 then
  3475.       begin
  3476.         P := PrevLine (P);
  3477.         Inc (Count);
  3478.       end
  3479.     else
  3480.       begin
  3481.         P := NextLine (P);
  3482.         Dec (Count);
  3483.       end;
  3484.   end;
  3485.  
  3486.   if P <> I then
  3487.     P := CharPtr (P, Pos);
  3488.  
  3489.   LineMove := P;
  3490.  
  3491.  
  3492. end; { TEditor.LineMove }
  3493.  
  3494.  
  3495.  
  3496. { -------------------------------------------------------------------------- }
  3497.  
  3498.  
  3499.  
  3500. function TEditor.LineStart (P : Word) : Word; assembler;
  3501.  
  3502. asm
  3503.         PUSH    DS
  3504.         LDS     SI,Self
  3505.         LES     BX,DS:[SI].TEditor.Buffer
  3506.         MOV     DI,P
  3507.         MOV     AL,0DH
  3508.         STD
  3509.         MOV     CX,DI
  3510.         SUB     CX,DS:[SI].TEditor.CurPtr
  3511.         JBE     @@1
  3512.         ADD     BX,DS:[SI].TEditor.GapLen
  3513.         ADD     DI,BX
  3514.         DEC     DI
  3515.         REPNE   SCASB
  3516.         JE      @@2
  3517.         SUB     BX,DS:[SI].TEditor.GapLen
  3518.         MOV     DI,DS:[SI].TEditor.CurPtr
  3519. @@1:    MOV     CX,DI
  3520.         JCXZ    @@4
  3521.         ADD     DI,BX
  3522.         DEC     DI
  3523.         REPNE   SCASB
  3524.         JNE     @@3
  3525. @@2:    INC     DI
  3526.         INC     DI
  3527.         SUB     DI,BX
  3528.         CMP     DI,DS:[SI].TEditor.CurPtr
  3529.         JE      @@4
  3530.         CMP     DI,DS:[SI].TEditor.BufLen
  3531.         JE      @@4
  3532.         CMP     ES:[BX+DI].Byte,0AH
  3533.         JNE     @@4
  3534.         INC     DI
  3535.         JMP     @@4
  3536. @@3:    XOR     DI,DI
  3537. @@4:    MOV     AX,DI
  3538.         POP     DS
  3539.  
  3540.  
  3541. end; { TEditor.LineStart }
  3542.  
  3543.  
  3544.  
  3545. { -------------------------------------------------------------------------- }
  3546.  
  3547.  
  3548.  
  3549. procedure TEditor.Lock;
  3550.  
  3551. begin
  3552.  
  3553.   Inc (LockCount);
  3554.  
  3555.  
  3556. end; { TEditor.Lock }
  3557.  
  3558.  
  3559.  
  3560. { -------------------------------------------------------------------------- }
  3561.  
  3562.  
  3563.  
  3564. { WRAP - Start. }
  3565.  
  3566. function TEditor.NewLine (Select_Mode : Byte) : Boolean;
  3567.  
  3568.  
  3569.  
  3570. CONST
  3571.  
  3572.   CrLf : array[1..2] of Char = #13#10;
  3573.  
  3574. VAR
  3575.  
  3576.   I : Word;          { Used to track spaces for AutoIndent.                 }
  3577.   P : Word;          { Position of Cursor when we arrive and after Newline. }
  3578.  
  3579. begin
  3580.  
  3581.   P := LineStart (CurPtr);
  3582.   I := P;
  3583.  
  3584.  
  3585.  
  3586.   { -------------------------------------------------------- }
  3587.   {                                                          }
  3588.   { The first thing we do is remove any End Of Line spaces.  }
  3589.   { Then we check to see how many spaces are on beginning    }
  3590.   { of a line.   We need this check to add them after CR/LF  }
  3591.   { if AutoIndenting.  Last of all we insert spaces required }
  3592.   { for the AutoIndenting, if it was on.                     }
  3593.   {                                                          }
  3594.   { -------------------------------------------------------- }
  3595.  
  3596.  
  3597.   Remove_EOL_Spaces (Select_Mode);
  3598.  
  3599.   while (I < CurPtr) and ((Buffer^[I] = ' ') or (Buffer^[I] = #9)) do
  3600.      Inc (I);
  3601.  
  3602.   if InsertText (@CrLf, 2, False) = FALSE then
  3603.     exit;
  3604.  
  3605.   if AutoIndent then
  3606.     InsertText (@Buffer^[P], I - P, False);
  3607.  
  3608.  
  3609.  
  3610.   { ------------------------------------------------ }
  3611.   {                                                  }
  3612.   { Remember where the CurPtr is at this moment.     }
  3613.   { Remember the length of the buffer at the moment. }
  3614.   { Go to the previous line and remove EOL spaces.   }
  3615.   { Once removed, re-set the cursor to where we were }
  3616.   { minus any spaces that might have been removed.   }
  3617.   {                                                  }
  3618.   { ------------------------------------------------ }
  3619.  
  3620.  
  3621.   I := BufLen;
  3622.   P := CurPtr;
  3623.  
  3624.   SetCurPtr (LineMove (CurPtr, - 1), Select_Mode);
  3625.   Remove_EOL_Spaces (Select_Mode);
  3626.  
  3627.   if I - BufLen <> 0 then
  3628.     SetCurPtr (P - (I - BufLen), Select_Mode)
  3629.   else
  3630.     SetCurPtr (P, Select_Mode);
  3631.  
  3632.  
  3633. end; { TEditor.NewLine }
  3634.  
  3635. { WRAP - Stop. } { Added new parameter and new code to support wordwrap. }
  3636.  
  3637.  
  3638.  
  3639. { -------------------------------------------------------------------------- }
  3640.  
  3641.  
  3642.  
  3643. function TEditor.NextChar (P : Word) : Word; assembler;
  3644.  
  3645. asm
  3646.         PUSH    DS
  3647.         LDS     SI,Self
  3648.         MOV     DI,P
  3649.         CMP     DI,DS:[SI].TEditor.BufLen
  3650.         JE      @@2
  3651.         INC     DI
  3652.         CMP     DI,DS:[SI].TEditor.BufLen
  3653.         JE      @@2
  3654.         LES     BX,DS:[SI].TEditor.Buffer
  3655.         CMP     DI,DS:[SI].TEditor.CurPtr
  3656.         JB      @@1
  3657.         ADD     BX,DS:[SI].TEditor.GapLen
  3658. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3659.         JNE     @@2
  3660.         INC     DI
  3661. @@2:    MOV     AX,DI
  3662.         POP     DS
  3663.  
  3664.  
  3665. end; { TEditor.NextChar }
  3666.  
  3667.  
  3668.  
  3669. { -------------------------------------------------------------------------- }
  3670.  
  3671.  
  3672.  
  3673. function TEditor.NextLine (P : Word) : Word;
  3674.  
  3675. begin
  3676.  
  3677.   NextLine := NextChar (LineEnd (P));
  3678.  
  3679.  
  3680. end; { TEditor.NextLine }
  3681.  
  3682.  
  3683.  
  3684. { -------------------------------------------------------------------------- }
  3685.  
  3686.  
  3687.  
  3688. function TEditor.NextWord (P : Word) : Word;
  3689.  
  3690.  
  3691. begin
  3692.  
  3693.   while (P < BufLen) and (BufChar (P) in WordChars) do
  3694.     P := NextChar (P);
  3695.  
  3696.   while (P < BufLen) and not (BufChar (P) in WordChars) do
  3697.     P := NextChar (P);
  3698.  
  3699.   NextWord := P;
  3700.  
  3701.  
  3702. end; { TEditor.NextWord }
  3703.  
  3704.  
  3705.  
  3706. { -------------------------------------------------------------------------- }
  3707.  
  3708.  
  3709.  
  3710. function TEditor.PrevChar (P : Word) : Word; assembler;
  3711.  
  3712. asm
  3713.         PUSH    DS
  3714.         LDS     SI,Self
  3715.         MOV     DI,P
  3716.         OR      DI,DI
  3717.         JE      @@2
  3718.         DEC     DI
  3719.         JE      @@2
  3720.         LES     BX,DS:[SI].TEditor.Buffer
  3721.         CMP     DI,DS:[SI].TEditor.CurPtr
  3722.         JB      @@1
  3723.         ADD     BX,DS:[SI].TEditor.GapLen
  3724. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3725.         JNE     @@2
  3726.         DEC     DI
  3727. @@2:    MOV     AX,DI
  3728.         POP     DS
  3729.  
  3730.  
  3731. end; { TEditor.PrevChar }
  3732.  
  3733.  
  3734.  
  3735. { -------------------------------------------------------------------------- }
  3736.  
  3737.  
  3738.  
  3739. function TEditor.PrevLine (P : Word) : Word;
  3740.  
  3741. begin
  3742.  
  3743.   PrevLine := LineStart (PrevChar (P));
  3744.  
  3745.  
  3746. end; { TEditor.PrevLine }
  3747.  
  3748.  
  3749.  
  3750. { -------------------------------------------------------------------------- }
  3751.  
  3752.  
  3753.  
  3754. function TEditor.PrevWord (P : Word) : Word;
  3755.  
  3756. begin
  3757.  
  3758.   while (P > 0) and not (BufChar (PrevChar (P)) in WordChars) do
  3759.     P := PrevChar (P);
  3760.  
  3761.   while (P > 0) and (BufChar (PrevChar (P)) in WordChars) do
  3762.     P := PrevChar (P);
  3763.  
  3764.   PrevWord := P;
  3765.  
  3766.  
  3767. end; { TEditor.PrevWord }
  3768.  
  3769.  
  3770.  
  3771. { -------------------------------------------------------------------------- }
  3772.  
  3773.  
  3774.  
  3775. { REFDOC - Start. }
  3776.  
  3777. procedure TEditor.Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  3778.  
  3779.  
  3780.   { -------------------------------------------------------------------- }
  3781.   {                                                                      }
  3782.   { This procedure will do a reformat of the entire document, or just    }
  3783.   { from the current line to the end of the document, if ^QU is pressed. }
  3784.   { It simply brings up the correct dialog box, and then calls the       }
  3785.   { TEditor.Reformat_Paragraph procedure to do the actual reformatting.  }
  3786.   {                                                                      }
  3787.   { -------------------------------------------------------------------- }
  3788.  
  3789.  
  3790. CONST
  3791.  
  3792.   efCurrentLine   = $0000;  { Radio button #1 selection for dialog box.  }
  3793.   efWholeDocument = $0001;  { Radio button #2 selection for dialog box.  }
  3794.  
  3795. VAR
  3796.  
  3797.   Reformat_Options : Word;  { Holds the dialog options for reformatting. }
  3798.  
  3799.  
  3800. begin
  3801.  
  3802.  
  3803.  
  3804.   { ----------------------------------------------------------------- }
  3805.   {                                                                   }
  3806.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3807.   { allows reformatting of document and if not show user dialog that  }
  3808.   { says reformatting is not permissable.                             }
  3809.   {                                                                   }
  3810.   { ----------------------------------------------------------------- }
  3811.  
  3812.  
  3813.   if not Word_Wrap then
  3814.     begin
  3815.       if not Allow_Reformat then
  3816.         begin
  3817.           EditorDialog (edReformatNotAllowed, nil);
  3818.           Exit;
  3819.         end;
  3820.       Word_Wrap := True;
  3821.       Update (ufStats);
  3822.     end;
  3823.  
  3824.  
  3825.  
  3826.   { ------------------------------------------------------------- }
  3827.   {                                                               }
  3828.   { Default radio button option to 1st one.  Bring up dialog box. }
  3829.   {                                                               }
  3830.   { ------------------------------------------------------------- }
  3831.  
  3832.  
  3833.   Reformat_Options := efCurrentLine;
  3834.  
  3835.   if EditorDialog (edReformatDocument, @Reformat_Options) <> Views.cmCancel then
  3836.     begin
  3837.  
  3838.  
  3839.  
  3840.       { ----------------------------------------------------------- }
  3841.       {                                                             }
  3842.       { If the option to reformat the whole document was selected   }
  3843.       { we need to go back to start of document.  Otherwise we stay }
  3844.       { on the current line.  Call Reformat_Paragraph until we get  }
  3845.       { to the end of the document to do the reformatting.          }
  3846.       {                                                             }
  3847.       { ----------------------------------------------------------- }
  3848.  
  3849.  
  3850.       if Reformat_Options and efWholeDocument <> 0 then
  3851.         SetCurPtr (0, Select_Mode);
  3852.  
  3853.       Unlock;
  3854.  
  3855.       repeat
  3856.         Lock;
  3857.  
  3858.         if NOT Reformat_Paragraph (Select_Mode, Center_Cursor) then
  3859.           Exit;
  3860.  
  3861.         TrackCursor (False);
  3862.         Unlock;
  3863.       until CurPtr = BufLen;
  3864.  
  3865.     end;
  3866.  
  3867.  
  3868. end; { TEditor.Reformat_Document }
  3869.  
  3870. { REFDOC - Stop. }
  3871.  
  3872.  
  3873.  
  3874. { -------------------------------------------------------------------------- }
  3875.  
  3876.  
  3877.  
  3878. { REFORM - Start. }
  3879.  
  3880. function TEditor.Reformat_Paragraph (Select_Mode   : Byte;
  3881.                                      Center_Cursor : Boolean) : Boolean;
  3882.  
  3883.  
  3884.   { ------------------------------------------------------------------------- }
  3885.   {                                                                           }
  3886.   { This procedure will do a reformat of the current paragraph if ^B pressed. }
  3887.   { The feature works regardless if wordrap is on or off.  It also supports   }
  3888.   { the AutoIndent feature.  Reformat is not possible if the CurPos exceeds   }
  3889.   { the Right_Margin.  Right_Margin is where the EOL is considered to be.     }
  3890.   {                                                                           }
  3891.   { ------------------------------------------------------------------------- }
  3892.  
  3893.  
  3894. CONST
  3895.  
  3896.   Space : array [1..2] of Char = #32#32;
  3897.  
  3898. VAR
  3899.  
  3900.   C : Word;  { Position of CurPtr when we come into procedure. }
  3901.   E : Word;  { End of a line.                                  }
  3902.   S : Word;  { Start of a line.                                }
  3903.  
  3904. begin
  3905.  
  3906.   Reformat_Paragraph := False;
  3907.  
  3908.  
  3909.  
  3910.   { ----------------------------------------------------------------- }
  3911.   {                                                                   }
  3912.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3913.   { allows reformatting of paragraph and if not show user dialog that }
  3914.   { says reformatting is not permissable.                             }
  3915.   {                                                                   }
  3916.   { ----------------------------------------------------------------- }
  3917.  
  3918.  
  3919.   if not Word_Wrap then
  3920.     begin
  3921.       if not Allow_Reformat then
  3922.         begin
  3923.           EditorDialog (edReformatNotAllowed, nil);
  3924.           Exit;
  3925.         end;
  3926.       Word_Wrap := True;
  3927.       Update (ufStats);
  3928.     end;
  3929.  
  3930.  
  3931.  
  3932.   C := CurPtr;
  3933.   E := LineEnd (CurPtr);
  3934.   S := LineStart (CurPtr);
  3935.  
  3936.  
  3937.  
  3938.   { ---------------------------------------------------- }
  3939.   {                                                      }
  3940.   { Reformat possible only if current line is NOT blank! }
  3941.   {                                                      }
  3942.   { ---------------------------------------------------- }
  3943.  
  3944.  
  3945.   if E <> S then
  3946.     begin
  3947.  
  3948.  
  3949.  
  3950.       { ------------------------------------------ }
  3951.       {                                            }
  3952.       { Reformat is NOT possible if the first word }
  3953.       { on the line is beyond the Right_Margin.    }
  3954.       {                                            }
  3955.       { ------------------------------------------ }
  3956.  
  3957.  
  3958.       if NextWord (S) - S >= Right_Margin - 1 then
  3959.         begin
  3960.           EditorDialog (edReformNotPossible, nil);
  3961.           Exit;
  3962.         end;
  3963.  
  3964.  
  3965.  
  3966.       { ----------------------------------------------- }
  3967.       {                                                 }
  3968.       { First objective is to find the first blank line }
  3969.       { after this paragraph so we know when to stop.   }
  3970.       { That could be the end of the document.          }
  3971.       {                                                 }
  3972.       { ----------------------------------------------- }
  3973.  
  3974.  
  3975.       Repeat
  3976.         SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  3977.         E := LineEnd (CurPtr);
  3978.         S := LineStart (CurPtr);
  3979.         BlankLine := E;
  3980.       until ((CurPtr = BufLen) or (E = S));
  3981.  
  3982.       SetCurPtr (C, Select_Mode);
  3983.  
  3984.       repeat
  3985.  
  3986.  
  3987.  
  3988.         { ------------------------------------------------ }
  3989.         {                                                  }
  3990.         { Set CurPtr to LineEnd and remove the EOL spaces. }
  3991.         { Pull up the next line and remove its EOL space.  }
  3992.         { First make sure the next line is not BlankLine!  }
  3993.         { Insert spaces as required between the two lines. }
  3994.         {                                                  }
  3995.         { ------------------------------------------------ }
  3996.  
  3997.  
  3998.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  3999.         Remove_EOL_Spaces (Select_Mode);
  4000.         if CurPtr <> Blankline - 2 then
  4001.           DeleteRange (CurPtr, Nextword (CurPtr), True);
  4002.         Remove_EOL_Spaces (Select_Mode);
  4003.  
  4004.         case Buffer^[CurPtr-1] of
  4005.           '!' : InsertText (@Space, 2, False);
  4006.           '.' : InsertText (@Space, 2, False);
  4007.           ':' : InsertText (@Space, 2, False);
  4008.           '?' : InsertText (@Space, 2, False);
  4009.         else
  4010.           InsertText (@Space, 1, False);
  4011.         end;
  4012.  
  4013.  
  4014.  
  4015.         { --------------------------------------------------------- }
  4016.         {                                                           }
  4017.         { Reset CurPtr to EOL.  While line length is > Right_Margin }
  4018.         { go Do_Word_Wrap.  If wordrap failed, exit routine.        }
  4019.         {                                                           }
  4020.         { --------------------------------------------------------- }
  4021.  
  4022.  
  4023.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4024.  
  4025.         while LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin do
  4026.           begin
  4027.             if not Do_Word_Wrap (Select_Mode, Center_Cursor) then
  4028.               Exit;
  4029.           end;
  4030.  
  4031.  
  4032.  
  4033.         { -------------------------------------------------------- }
  4034.         {                                                          }
  4035.         { If LineEnd - LineStart > Right_Margin then set CurPtr    }
  4036.         { to Right_Margin on current line.  Otherwise we set the   }
  4037.         { CurPtr to LineEnd.  This gyration sets up the conditions }
  4038.         { to test for time of loop exit.                           }
  4039.         {                                                          }
  4040.         { -------------------------------------------------------- }
  4041.  
  4042.  
  4043.         if LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin then
  4044.           SetCurPtr (LineStart (CurPtr) + Right_Margin, Select_Mode)
  4045.         else
  4046.           SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4047.  
  4048.       until ((CurPtr >= BufLen) or (CurPtr >= BlankLine - 2));
  4049.  
  4050.     end;
  4051.  
  4052.  
  4053.  
  4054.   { --------------------------------------------------------------------- }
  4055.   {                                                                       }
  4056.   { If not at the end of the document reset CurPtr to start of next line. }
  4057.   { This should be a blank line between paragraphs.                       }
  4058.   {                                                                       }
  4059.   { --------------------------------------------------------------------- }
  4060.  
  4061.  
  4062.   if CurPtr < BufLen then
  4063.     SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  4064.  
  4065.  
  4066.   Reformat_Paragraph := True;
  4067.  
  4068.  
  4069. end; { TEditor.Reformat_Paragraph }
  4070.  
  4071. { REFORM - Stop. }
  4072.  
  4073.  
  4074.  
  4075. { -------------------------------------------------------------------------- }
  4076.  
  4077.  
  4078.  
  4079. { WRAP - Start. }
  4080.  
  4081. procedure TEditor.Remove_EOL_Spaces (Select_Mode : Byte);
  4082.  
  4083.  
  4084.   { ----------------------------------------------------------- }
  4085.   {                                                             }
  4086.   { This procedure tests to see if there are consecutive spaces }
  4087.   { at the end of a line (EOL).  If so, we delete all spaces    }
  4088.   { after the last non-space character to the end of line.      }
  4089.   { We then reset the CurPtr to where we ended up at.           }
  4090.   {                                                             }
  4091.   { ----------------------------------------------------------- }
  4092.  
  4093.  
  4094. VAR
  4095.  
  4096.   C : Word;           { Current pointer when we come into procedure. }
  4097.   E : Word;           { End of line.                                 }
  4098.   P : Word;           { Position of pointer at any given moment.     }
  4099.   S : Word;           { Start of a line.                             }
  4100.  
  4101. begin
  4102.  
  4103.   C := CurPtr;
  4104.   E := LineEnd (CurPtr);
  4105.   P := E;
  4106.   S := LineStart (CurPtr);
  4107.  
  4108.  
  4109.  
  4110.   { ------------------------------------------------------ }
  4111.   {                                                        }
  4112.   { Start at the end of a line and move towards the start. }
  4113.   { Find first non-space character in that direction.      }
  4114.   {                                                        }
  4115.   { ------------------------------------------------------ }
  4116.  
  4117.  
  4118.   while (P > S) and (BufChar (PrevChar (P)) = #32) do
  4119.     P := PrevChar (P);
  4120.  
  4121.  
  4122.  
  4123.   { ---------------------------------------- }
  4124.   {                                          }
  4125.   { If we found any spaces then delete them. }
  4126.   {                                          }
  4127.   { ---------------------------------------- }
  4128.  
  4129.  
  4130.   if P < E then
  4131.     begin
  4132.  
  4133.       SetSelect (P, E, True);
  4134.       DeleteSelect;
  4135.  
  4136.       { MARK - Start. }
  4137.  
  4138.       Update_Place_Markers (0, E - P, P, E);
  4139.  
  4140.       { MARK - Stop. } { This will update Place_Marker for EOL deletions. }
  4141.                        { All other deletions are handled by DeleteRange.  }
  4142.  
  4143.     end;
  4144.  
  4145.  
  4146.  
  4147.   { --------------------------------------------------- }
  4148.   {                                                     }
  4149.   { If C, our pointer when we came into this procedure, }
  4150.   { is less than the CurPtr then reset CurPtr to C so   }
  4151.   { cursor is where we started.  Otherwise, set it to   }
  4152.   { the new CurPtr, for we have deleted characters.     }
  4153.   {                                                     }
  4154.   { --------------------------------------------------- }
  4155.  
  4156.  
  4157.   if C < CurPtr then
  4158.     SetCurPtr (C, Select_Mode)
  4159.   else
  4160.     SetCurPtr (CurPtr, Select_Mode);
  4161.  
  4162.  
  4163. end; { TEditor.Remove_EOL_Spaces }
  4164.  
  4165. { WRAP - Stop. }
  4166.  
  4167.  
  4168.  
  4169. { -------------------------------------------------------------------------- }
  4170.  
  4171.  
  4172.  
  4173. procedure TEditor.Replace;
  4174.  
  4175. VAR
  4176.  
  4177.   ReplaceRec : TReplaceDialogRec;
  4178.  
  4179. begin
  4180.  
  4181.   with ReplaceRec do
  4182.   begin
  4183.  
  4184.     Find := FindStr;
  4185.     Replace := ReplaceStr;
  4186.     Options := EditorFlags;
  4187.  
  4188.     if EditorDialog (edReplace, @ReplaceRec) <> Views.cmCancel then
  4189.     begin
  4190.       FindStr := Find;
  4191.       ReplaceStr := Replace;
  4192.       EditorFlags := Options or efDoReplace;
  4193.       DoSearchReplace;
  4194.     end;
  4195.   end;
  4196.  
  4197.  
  4198. end; { TEditor.Replace }
  4199.  
  4200.  
  4201.  
  4202. { -------------------------------------------------------------------------- }
  4203.  
  4204.  
  4205.  
  4206. { SCRLDN - Start. }
  4207.  
  4208. procedure TEditor.Scroll_Down;
  4209.  
  4210.  
  4211.   { -------------------------------------------------------------- }
  4212.   {                                                                }
  4213.   { This procedure will scroll the screen up, and always keep      }
  4214.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4215.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4216.   { will stay in the upper left corner of the screen.  This will   }
  4217.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4218.   { only messes up if we are on long lines and we then encounter   }
  4219.   { a shorter or blank line beneath the current one as we scroll.  }
  4220.   { In that case, it goes to the end of the new line.              }
  4221.   {                                                                }
  4222.   { -------------------------------------------------------------- }
  4223.  
  4224.  
  4225. VAR
  4226.  
  4227.   C : Word;           { Position of CurPtr when we enter procedure. }
  4228.   P : Word;           { Position of CurPtr at any given time.       }
  4229.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4230.  
  4231. begin
  4232.  
  4233.  
  4234.  
  4235.   { ---------------------------------------------------------------------- }
  4236.   {                                                                        }
  4237.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4238.   { Now issue the equivalent of a [Ctrl]-[End] command so the cursor will  }
  4239.   { go to the bottom of the current screen.  Reset the cursor to this new  }
  4240.   { position and then send FALSE to TrackCursor so we fool it into         }
  4241.   { incrementing Delta.Y by only +1.  If we didn't do this it would try    }
  4242.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4243.   {                                                                        }
  4244.   { ---------------------------------------------------------------------- }
  4245.  
  4246.  
  4247.   C := CurPtr;
  4248.   W.X := CurPos.Y;
  4249.  
  4250.   P := LineMove (CurPtr, Delta.Y - CurPos.Y + Size.Y);
  4251.  
  4252.   SetCurPtr (P, 0);
  4253.  
  4254.   TrackCursor (False);
  4255.  
  4256.  
  4257.  
  4258.   { -------------------------------------------------------------------- }
  4259.   {                                                                      }
  4260.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4261.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4262.   { If they are, we need to move cursor position itself down by one.     }
  4263.   { Otherwise, send the cursor back to our original CurPtr.              }
  4264.   {                                                                      }
  4265.   { -------------------------------------------------------------------- }
  4266.  
  4267.  
  4268.   W.Y := CurPos.Y;
  4269.  
  4270.   if W.Y - W.X > Size.Y - 1 then
  4271.     SetCurPtr (LineMove (C, 1), 0)
  4272.   else
  4273.     SetCurPtr (C, 0);
  4274.  
  4275.  
  4276. end; { TEditor.Scroll_Down }
  4277.  
  4278. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4279.  
  4280.  
  4281.  
  4282. { -------------------------------------------------------------------------- }
  4283.  
  4284.  
  4285.  
  4286. { SCRLUP - Start. }
  4287.  
  4288. procedure TEditor.Scroll_Up;
  4289.  
  4290.  
  4291.   { -------------------------------------------------------------- }
  4292.   {                                                                }
  4293.   { This procedure will scroll the screen down, and always keep    }
  4294.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4295.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4296.   { will stay in the bottom left corner of the screen.  This will  }
  4297.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4298.   { only messes up if we are on long lines and we then encounter   }
  4299.   { a shorter or blank line beneath the current one as we scroll.  }
  4300.   { In that case, it goes to the end of the new line.              }
  4301.   {                                                                }
  4302.   { -------------------------------------------------------------- }
  4303.  
  4304.  
  4305. VAR
  4306.  
  4307.   C : Word;           { Position of CurPtr when we enter procedure. }
  4308.   P : Word;           { Position of CurPtr at any given time.       }
  4309.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4310.  
  4311. begin
  4312.  
  4313.  
  4314.  
  4315.   { ---------------------------------------------------------------------- }
  4316.   {                                                                        }
  4317.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4318.   { Now issue the equivalent of a [Ctrl]-[Home] command so the cursor will }
  4319.   { go to the top of the current screen.  Reset the cursor to this new     }
  4320.   { position and then send FALSE to TrackCursor so we fool it into         }
  4321.   { decrementing Delta.Y by only -1.  If we didn't do this it would try    }
  4322.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4323.   {                                                                        }
  4324.   { ---------------------------------------------------------------------- }
  4325.  
  4326.  
  4327.   C := CurPtr;
  4328.   W.Y := CurPos.Y;
  4329.  
  4330.   P := LineMove (CurPtr, -(CurPos.Y - Delta.Y + 1));
  4331.  
  4332.   SetCurPtr (P, 0);
  4333.  
  4334.   TrackCursor (False);
  4335.  
  4336.  
  4337.  
  4338.   { -------------------------------------------------------------------- }
  4339.   {                                                                      }
  4340.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4341.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4342.   { If they are, we need to move the cursor position itself up by one.   }
  4343.   { Otherwise, send the cursor back to our original CurPtr.              }
  4344.   {                                                                      }
  4345.   { -------------------------------------------------------------------- }
  4346.  
  4347.  
  4348.   W.X := CurPos.Y;
  4349.  
  4350.   if W.Y - W.X > Size.Y - 1 then
  4351.     SetCurPtr (LineMove (C, -1), 0)
  4352.   else
  4353.     SetCurPtr (C, 0);
  4354.  
  4355.  
  4356. end; { TEditor.Scroll_Up }
  4357.  
  4358. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4359.  
  4360.  
  4361.  
  4362. { -------------------------------------------------------------------------- }
  4363.  
  4364.  
  4365.  
  4366. procedure TEditor.ScrollTo (X, Y : Integer);
  4367.  
  4368. begin
  4369.  
  4370.   X := Max (0, Min (X, Limit.X - Size.X));
  4371.   Y := Max (0, Min (Y, Limit.Y - Size.Y));
  4372.  
  4373.   if (X <> Delta.X) or (Y <> Delta.Y) then
  4374.   begin
  4375.     Delta.X := X;
  4376.     Delta.Y := Y;
  4377.     Update (ufView);
  4378.   end;
  4379.  
  4380.  
  4381. end; { TEditor.ScrollTo }
  4382.  
  4383.  
  4384.  
  4385. { -------------------------------------------------------------------------- }
  4386.  
  4387.  
  4388.  
  4389. function TEditor.Search (CONST FindStr : String; Opts : Word) : Boolean;
  4390.  
  4391. VAR
  4392.  
  4393.   I   : Word;
  4394.   Pos : Word;
  4395.  
  4396. begin
  4397.  
  4398.   Search := False;
  4399.   Pos := CurPtr;
  4400.  
  4401.   repeat
  4402.  
  4403.     if Opts and efCaseSensitive <> 0 then
  4404.       I := Scan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr)
  4405.     else
  4406.       I := IScan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr);
  4407.  
  4408.     if (I <> sfSearchFailed) then
  4409.     begin
  4410.  
  4411.       Inc (I, Pos);
  4412.  
  4413.       if (Opts and efWholeWordsOnly = 0) or
  4414.          not (((I <> 0) and (BufChar (I - 1) in WordChars)) or
  4415.               ((I + Length (FindStr) <> BufLen) and
  4416.                (BufChar (I + Length (FindStr)) in WordChars))) then
  4417.         begin
  4418.           Lock;
  4419.           SetSelect (I, I + Length (FindStr), False);
  4420.           TrackCursor (not CursorVisible);
  4421.           Unlock;
  4422.           Search := True;
  4423.           Exit;
  4424.         end
  4425.       else
  4426.         Pos := I + 1;
  4427.  
  4428.     end;
  4429.  
  4430.   until I = sfSearchFailed;
  4431.  
  4432.  
  4433. end; { TEditor.Search }
  4434.  
  4435.  
  4436.  
  4437. { -------------------------------------------------------------------------- }
  4438.  
  4439.  
  4440.  
  4441. { SELWRD - Start. }
  4442.  
  4443. procedure TEditor.Select_Word;
  4444.  
  4445.  
  4446.   { ------------------------------------------------------------------ }
  4447.   {                                                                    }
  4448.   { This procedure will select the a word to put into the clipboard.   }
  4449.   { I've added it just to maintain compatibility with the IDE editor.  }
  4450.   { Note that selection starts at the current cursor position and ends }
  4451.   { when a space or the end of line is encountered.                    }
  4452.   {                                                                    }
  4453.   { ------------------------------------------------------------------ }
  4454.  
  4455.  
  4456. VAR
  4457.  
  4458.   E : Word;           { End of the current line.                           }
  4459.   Select_Mode : Byte; { Allows us to turn select mode on inside procedure. }
  4460.  
  4461. begin
  4462.  
  4463.   E := LineEnd (CurPtr);
  4464.  
  4465.  
  4466.  
  4467.   { ----------------------------------------------------------- }
  4468.   {                                                             }
  4469.   { If the cursor is on a space or at the end of a line, abort. }
  4470.   { Stupid action on users part for you can't select blanks!    }
  4471.   {                                                             }
  4472.   { ----------------------------------------------------------- }
  4473.  
  4474.  
  4475.   if (BufChar (CurPtr) = #32) or (CurPtr = E) then
  4476.     Exit;
  4477.  
  4478.  
  4479.  
  4480.   { ------------------------------------------------------------ }
  4481.   {                                                              }
  4482.   { Turn on select mode and tell editor to start selecting text. }
  4483.   { As long as we have a character > a space (this is done to    }
  4484.   { exclude CR/LF pairs at end of a line) and we are NOT at the  }
  4485.   { end of a line, set the CurPtr to the next character.         }
  4486.   { Once we find a space or CR/LF, selection is done and we      }
  4487.   { automatically put the selected word into the Clipboard.      }
  4488.   {                                                              }
  4489.   { ------------------------------------------------------------ }
  4490.  
  4491.  
  4492.   Select_Mode := smExtend;
  4493.   StartSelect;
  4494.  
  4495.   while (BufChar (NextChar (CurPtr)) > #32) and (CurPtr < E) do
  4496.     SetCurPtr (NextChar (CurPtr), Select_Mode);
  4497.  
  4498.   SetCurPtr (NextChar (CurPtr), Select_Mode);
  4499.   ClipCopy;
  4500.  
  4501.  
  4502. end; {TEditor.Select_Word }
  4503.  
  4504. {SELWRD - Stop. }
  4505.  
  4506.  
  4507.  
  4508. { -------------------------------------------------------------------------- }
  4509.  
  4510.  
  4511.  
  4512. procedure TEditor.SetBufLen (Length : Word);
  4513.  
  4514.  
  4515. begin
  4516.  
  4517.   BufLen := Length;
  4518.   GapLen := BufSize - Length;
  4519.  
  4520.   SelStart := 0;
  4521.   SelEnd := 0;
  4522.  
  4523.   CurPtr := 0;
  4524.  
  4525.   Longint (CurPos) := 0;
  4526.   Longint (Delta) := 0;
  4527.  
  4528.   Limit.X := MaxLineLength;
  4529.   Limit.Y := CountLines (Buffer^[GapLen], BufLen) + 1;
  4530.  
  4531.   DrawLine := 0;
  4532.   DrawPtr := 0;
  4533.  
  4534.   DelCount := 0;
  4535.   InsCount := 0;
  4536.  
  4537.   Modified := False;
  4538.   Update (ufView);
  4539.  
  4540.  
  4541. end; { TEditor.SetBufLen }
  4542.  
  4543.  
  4544.  
  4545. { -------------------------------------------------------------------------- }
  4546.  
  4547.  
  4548.  
  4549. function TEditor.SetBufSize (NewSize : Word) : Boolean;
  4550.  
  4551. begin
  4552.  
  4553.   SetBufSize := NewSize <= BufSize;
  4554.  
  4555.  
  4556. end; { TEditor.SetBufSize }
  4557.  
  4558.  
  4559.  
  4560. { -------------------------------------------------------------------------- }
  4561.  
  4562.  
  4563.  
  4564. procedure TEditor.SetCmdState (Command : Word; Enable : Boolean);
  4565.  
  4566. VAR
  4567.  
  4568.   S : Views.TCommandSet;
  4569.  
  4570. begin
  4571.  
  4572.   S := [Command];
  4573.  
  4574.   if Enable and (State and sfActive <> 0) then
  4575.     EnableCommands (S)
  4576.   else
  4577.     DisableCommands (S);
  4578.  
  4579.  
  4580. end; { TEditor.SetCmdState }
  4581.  
  4582.  
  4583.  
  4584. { -------------------------------------------------------------------------- }
  4585.  
  4586.  
  4587.  
  4588. procedure TEditor.SetCurPtr (P : Word; SelectMode : Byte);
  4589.  
  4590. VAR
  4591.  
  4592.   Anchor : Word;
  4593.  
  4594. begin
  4595.  
  4596.   if SelectMode and smExtend = 0 then
  4597.     Anchor := P
  4598.   else
  4599.     if CurPtr = SelStart then
  4600.       Anchor := SelEnd
  4601.     else
  4602.       Anchor := SelStart;
  4603.  
  4604.   if P < Anchor then
  4605.     begin
  4606.  
  4607.       if SelectMode and smDouble <> 0 then
  4608.       begin
  4609.         P := PrevLine (NextLine (P));
  4610.         Anchor := NextLine (PrevLine (Anchor));
  4611.       end;
  4612.  
  4613.       SetSelect (P, Anchor, True);
  4614.  
  4615.     end
  4616.   else
  4617.     begin
  4618.  
  4619.       if SelectMode and smDouble <> 0 then
  4620.       begin
  4621.         P := NextLine (P);
  4622.         Anchor := PrevLine (NextLine (Anchor));
  4623.       end;
  4624.  
  4625.       SetSelect (Anchor, P, False);
  4626.  
  4627.     end;
  4628.  
  4629.  
  4630. end; { TEditor.SetCurPtr }
  4631.  
  4632.  
  4633.  
  4634. { -------------------------------------------------------------------------- }
  4635.  
  4636.  
  4637.  
  4638. { MARK - Start. }
  4639.  
  4640. procedure TEditor.Set_Place_Marker (Element : Byte);
  4641.  
  4642.  
  4643.   { -------------------------------------------------------------------- }
  4644.   {                                                                      }
  4645.   { This procedure sets a place marker for the CurPtr if ^K# is pressed. }
  4646.   {                                                                      }
  4647.   { -------------------------------------------------------------------- }
  4648.  
  4649.  
  4650. begin
  4651.  
  4652.   if not IsClipboard then
  4653.     Place_Marker[Element] := CurPtr;
  4654.  
  4655.  
  4656. end; { TEditor.Set_Place_Marker }
  4657.  
  4658. { MARK - Stop. }
  4659.  
  4660.  
  4661.  
  4662. { -------------------------------------------------------------------------- }
  4663.  
  4664.  
  4665.  
  4666. { RMSET - Start. }
  4667.  
  4668. procedure TEditor.Set_Right_Margin;
  4669.  
  4670.  
  4671.   { ----------------------------------------- }
  4672.   {                                           }
  4673.   { This procedure will bring up a dialog box }
  4674.   { that allows the user to set Right_Margin. }
  4675.   { Values must be < MaxLineLength and > 9.   }
  4676.   {                                           }
  4677.   { ----------------------------------------- }
  4678.  
  4679.  
  4680. VAR
  4681.  
  4682.   Code        : Integer;          { Used for Val conversion.      }
  4683.   Margin_Data : TRightMarginRec;  { Holds dialog results.         }
  4684.   Temp_Value  : Integer;          { Holds converted dialog value. }
  4685.  
  4686. begin
  4687.  
  4688.   with Margin_Data do
  4689.     begin
  4690.  
  4691.       Str (Right_Margin, Margin_Position);
  4692.  
  4693.       if EditorDialog (edRightMargin, @Margin_Position) <> Views.cmCancel then
  4694.         begin
  4695.           val (Margin_Position, Temp_Value, Code);
  4696.           if (Temp_Value <= MaxLineLength) and (Temp_Value > 9) then
  4697.             Right_Margin := Temp_Value;
  4698.         end;
  4699.  
  4700.     end;
  4701.  
  4702.  
  4703. end; { TEditor.Set_Right_Margin }
  4704.  
  4705.  
  4706. { RMSET - Stop. }
  4707.  
  4708.  
  4709.  
  4710. { -------------------------------------------------------------------------- }
  4711.  
  4712.  
  4713.  
  4714. procedure TEditor.SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  4715.  
  4716. VAR
  4717.  
  4718.   Flags : Byte;
  4719.   P     : Word;
  4720.   L     : Word;
  4721.  
  4722. begin
  4723.  
  4724.   if CurStart then
  4725.     P := NewStart
  4726.   else
  4727.     P := NewEnd;
  4728.  
  4729.   Flags := ufUpdate;
  4730.  
  4731.   if (NewStart <> SelStart) or (NewEnd <> SelEnd) then
  4732.     if (NewStart <> NewEnd) or (SelStart <> SelEnd) then
  4733.       Flags := ufView;
  4734.  
  4735.   if P <> CurPtr then
  4736.   begin
  4737.  
  4738.     if P > CurPtr then
  4739.       begin
  4740.         L := P - CurPtr;
  4741.         Move (Buffer^[CurPtr + GapLen], Buffer^[CurPtr], L);
  4742.         Inc (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4743.         CurPtr := P;
  4744.       end
  4745.     else
  4746.       begin
  4747.         L := CurPtr - P;
  4748.         CurPtr := P;
  4749.         Dec (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4750.         Move (Buffer^[CurPtr], Buffer^[CurPtr + GapLen], L);
  4751.       end;
  4752.  
  4753.     DrawLine := CurPos.Y;
  4754.     DrawPtr := LineStart (P);
  4755.  
  4756.     CurPos.X := CharPos (DrawPtr, P);
  4757.  
  4758.     DelCount := 0;
  4759.     InsCount := 0;
  4760.  
  4761.     SetBufSize (BufLen);
  4762.  
  4763.   end;
  4764.  
  4765.   SelStart := NewStart;
  4766.   SelEnd := NewEnd;
  4767.  
  4768.   Update (Flags);
  4769.  
  4770.  
  4771. end; { TEditor.Select }
  4772.  
  4773.  
  4774.  
  4775. { -------------------------------------------------------------------------- }
  4776.  
  4777.  
  4778.  
  4779. procedure TEditor.SetState (AState : Word; Enable : Boolean);
  4780.  
  4781. begin
  4782.  
  4783.   TView.SetState (AState, Enable);
  4784.  
  4785.   case AState of
  4786.  
  4787.     Views.sfActive: begin
  4788.                       if HScrollBar <> nil then
  4789.                         HScrollBar^.SetState (Views.sfVisible, Enable);
  4790.                       if VScrollBar <> nil then
  4791.                         VScrollBar^.SetState (Views.sfVisible, Enable);
  4792.                       if Indicator <> nil then
  4793.                         Indicator^.SetState (Views.sfVisible, Enable);
  4794.                       UpdateCommands;
  4795.                     end;
  4796.  
  4797.     Views.sfExposed: if Enable then Unlock;
  4798.  
  4799.   end;
  4800.  
  4801.  
  4802. end; { TEditor.SetState }
  4803.  
  4804.  
  4805.  
  4806. { -------------------------------------------------------------------------- }
  4807.  
  4808.  
  4809.  
  4810. { PRETAB - Start. }
  4811.  
  4812. procedure TEditor.Set_Tabs;
  4813.  
  4814.  
  4815.  
  4816.   { ----------------------------------------- }
  4817.   {                                           }
  4818.   { This procedure will bring up a dialog box }
  4819.   { that allows the user to set tab stops.    }
  4820.   {                                           }
  4821.   { ----------------------------------------- }
  4822.  
  4823.  
  4824. VAR
  4825.  
  4826.   Index    : Integer;      { Index into string array. }
  4827.   Tab_Data : TTabStopRec;  { Holds dialog results.    }
  4828.  
  4829. begin
  4830.  
  4831.   with Tab_Data do
  4832.     begin
  4833.  
  4834.  
  4835.  
  4836.       { --------------------------------------------- }
  4837.       {                                               }
  4838.       { Assign current Tab_Settings to Tab_String.    }
  4839.       { Bring up the tab dialog so user can set tabs. }
  4840.       {                                               }
  4841.       { --------------------------------------------- }
  4842.  
  4843.  
  4844.       Tab_String := Copy (Tab_Settings, 1, Tab_Stop_Length);
  4845.  
  4846.       if EditorDialog (edSetTabStops, @Tab_String) <> Views.cmCancel then
  4847.         begin
  4848.  
  4849.  
  4850.  
  4851.           { --------------------------------------------------------------- }
  4852.           {                                                                 }
  4853.           { If Tab_String comes back as empty then set Tab_Settings to nil. }
  4854.           { Otherwise, find the last character in Tab_String that is not    }
  4855.           { a space and copy Tab_String into Tab_Settings up to that spot.  }
  4856.           {                                                                 }
  4857.           { --------------------------------------------------------------- }
  4858.  
  4859.  
  4860.           if Length (Tab_String) = 0 then
  4861.             begin
  4862.               FillChar (Tab_Settings, SizeOf (Tab_Settings), #0);
  4863.               Tab_Settings[0] := #0;
  4864.               Exit;
  4865.             end
  4866.           else
  4867.             begin
  4868.               Index := Length (Tab_String);
  4869.               while Tab_String[Index] <= #32 do
  4870.                 Dec (Index);
  4871.               Tab_Settings := Copy (Tab_String, 1, Index);
  4872.             end;
  4873.  
  4874.         end;
  4875.  
  4876.   end;
  4877.  
  4878.  
  4879. end; { TEditor.Set_Tabs }
  4880.  
  4881. { PRETAB - Stop. }
  4882.  
  4883.  
  4884.  
  4885. { -------------------------------------------------------------------------- }
  4886.  
  4887.  
  4888.  
  4889. procedure TEditor.StartSelect;
  4890.  
  4891. begin
  4892.  
  4893.   HideSelect;
  4894.   Selecting := True;
  4895.  
  4896.  
  4897. end; { TEditor.StartSelect }
  4898.  
  4899.  
  4900.  
  4901. { -------------------------------------------------------------------------- }
  4902.  
  4903.  
  4904.  
  4905. procedure TEditor.Store (var S : Objects.TStream);
  4906.  
  4907. begin
  4908.  
  4909.   TView.Store (S);
  4910.  
  4911.   PutPeerViewPtr (S, HScrollBar);
  4912.   PutPeerViewPtr (S, VScrollBar);
  4913.   PutPeerViewPtr (S, Indicator);
  4914.   S.Write (BufSize, SizeOf (Word));
  4915.  
  4916.  
  4917.   { STORE - Start. }
  4918.  
  4919.   { S.Write (Canundo, SizeOf (Boolean)); }
  4920.  
  4921.   { STORE - Stop. } {This item caused load/store bug. }
  4922.  
  4923.  
  4924.   { STATS  - Start. }
  4925.   { JLINE  - Start. }
  4926.   { MARK   - Start. }
  4927.   { RMSET  - Start. }
  4928.   { PRETAB - Start. }
  4929.   { WRAP   - Start. }
  4930.  
  4931.   S.Write (AutoIndent,   SizeOf (AutoIndent));
  4932.   S.Write (Line_Number,  SizeOf (Line_Number));
  4933.   S.Write (Place_Marker, SizeOf (Place_Marker));
  4934.   S.Write (Right_Margin, SizeOf (Right_Margin));
  4935.   S.Write (Tab_Settings, SizeOf (Tab_Settings));
  4936.   S.Write (Word_Wrap,    SizeOf (Word_Wrap));
  4937.  
  4938.   { WRAP   - Stop. }
  4939.   { PRETAB - Stop. }
  4940.   { RMSET  - Stop. }
  4941.   { MARK   - Stop. }
  4942.   { JLINE  - Stop. }
  4943.   { STATS  - Stop. } { Added these to allow load/store operations. }
  4944.  
  4945.  
  4946. end; { Editor.Store }
  4947.  
  4948.  
  4949.  
  4950. { -------------------------------------------------------------------------- }
  4951.  
  4952.  
  4953.  
  4954. { PRETAB - Start. }
  4955.  
  4956.  
  4957. procedure TEditor.Tab_Key (Select_Mode : Byte);
  4958.  
  4959.  
  4960.   { ------------------------------------------------------------------ }
  4961.   {                                                                    }
  4962.   { This function determines if we are in overstrike or insert mode,   }
  4963.   { and then moves the cursor if overstrike, or adds spaces if insert. }
  4964.   {                                                                    }
  4965.   { ------------------------------------------------------------------ }
  4966.  
  4967.  
  4968. VAR
  4969.  
  4970.   E        : Word;                   { End of current line.                }
  4971.   Index    : Integer;                { Loop counter.                       }
  4972.   Position : Integer;                { CurPos.X position.                  }
  4973.   S        : Word;                   { Start of current line.              }
  4974.   Spaces   : array [1..80] of Char;  { Array to hold spaces for insertion. }
  4975.  
  4976.  
  4977. begin
  4978.  
  4979.   E := LineEnd (CurPtr);
  4980.   S := LineStart (CurPtr);
  4981.  
  4982.  
  4983.  
  4984.   { -------------------------------------------- }
  4985.   {                                              }
  4986.   { Find the current horizontal cursor position. }
  4987.   { Now loop through the Tab_Settings string and }
  4988.   { find the next available tab stop.            }
  4989.   {                                              }
  4990.   { -------------------------------------------- }
  4991.  
  4992.  
  4993.   Position := CurPos.X + 1;
  4994.  
  4995.   repeat
  4996.     Inc (Position);
  4997.   until (Tab_Settings[Position] <> #32) or (Position >= Ord (Tab_Settings[0]));
  4998.  
  4999.   E := CurPos.X;
  5000.   Index := 1;
  5001.  
  5002.  
  5003.  
  5004.   { ---------------------------------------------------- }
  5005.   {                                                      }
  5006.   { Now we enter a loop to go to the next tab position.  }
  5007.   { If we are in overwrite mode, we just move the cursor }
  5008.   { through the text to the next tab stop.  If we are in }
  5009.   { insert mode, we add spaces to the Spaces array for   }
  5010.   { the number of times we loop.                         }
  5011.   {                                                      }
  5012.   { ---------------------------------------------------- }
  5013.  
  5014.  
  5015.   while Index < Position - E do
  5016.     begin
  5017.  
  5018.       if Overwrite then
  5019.         begin
  5020.           if (Position > LineEnd (CurPtr) - LineStart (CurPtr))
  5021.               or (Position > Ord (Tab_Settings[0])) then
  5022.             begin
  5023.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5024.               Exit;
  5025.             end
  5026.           else
  5027.             if CurPtr < BufLen then
  5028.               SetCurPtr (NextChar (CurPtr), Select_Mode);
  5029.         end
  5030.       else
  5031.         begin
  5032.           if (Position > Right_Margin) or (Position > Ord (Tab_Settings[0])) then
  5033.             begin
  5034.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5035.               Exit;
  5036.             end
  5037.           else
  5038.             Spaces[Index] := #32;
  5039.         end;
  5040.  
  5041.       Inc (Index);
  5042.  
  5043.   end;
  5044.  
  5045.  
  5046.  
  5047.   { -------------------------------------------------------------------- }
  5048.   {                                                                      }
  5049.   { If we are insert mode, we insert spaces to the next tab stop.        }
  5050.   { When we're all done, the cursor will be sitting on the new tab stop. }
  5051.   {                                                                      }
  5052.   { -------------------------------------------------------------------- }
  5053.  
  5054.  
  5055.   if not OverWrite then
  5056.     InsertText (@Spaces, Index - 1, False);
  5057.  
  5058.  
  5059. end; { TEditor.Tab_Key }
  5060.  
  5061. { PRETAB - Stop. }
  5062.  
  5063.  
  5064.  
  5065. { -------------------------------------------------------------------------- }
  5066.  
  5067.  
  5068.  
  5069. procedure TEditor.ToggleInsMode;
  5070.  
  5071. begin
  5072.  
  5073.   Overwrite := not Overwrite;
  5074.   SetState (sfCursorIns, not GetState (sfCursorIns));
  5075.  
  5076.  
  5077. end; { TEditor.ToggleInsMode }
  5078.  
  5079.  
  5080.  
  5081. { -------------------------------------------------------------------------- }
  5082.  
  5083.  
  5084.  
  5085. procedure TEditor.TrackCursor (Center : Boolean);
  5086.  
  5087. begin
  5088.  
  5089.   if Center then
  5090.     ScrollTo (CurPos.X - Size.X + 1, CurPos.Y - Size.Y div 2)
  5091.   else
  5092.     ScrollTo (Max (CurPos.X - Size.X + 1, Min (Delta.X, CurPos.X)),
  5093.               Max (CurPos.Y - Size.Y + 1, Min (Delta.Y, CurPos.Y)));
  5094.  
  5095.  
  5096. end; { TEditor.TrackCursor }
  5097.  
  5098.  
  5099.  
  5100. { -------------------------------------------------------------------------- }
  5101.  
  5102.  
  5103.  
  5104. procedure TEditor.Undo;
  5105.  
  5106. VAR
  5107.  
  5108.   Length : Word;
  5109.  
  5110. begin
  5111.  
  5112.   if (DelCount <> 0) or (InsCount <> 0) then
  5113.   begin
  5114.  
  5115.     { MARK - Start. }
  5116.  
  5117.     Update_Place_Markers (DelCount, 0, CurPtr, CurPtr + DelCount);
  5118.  
  5119.     { MARK - Stop. } { Update Place_Marker array if we undelete text. }
  5120.  
  5121.     SelStart := CurPtr - InsCount;
  5122.     SelEnd := CurPtr;
  5123.     Length := DelCount;
  5124.     DelCount := 0;
  5125.     InsCount := 0;
  5126.     InsertBuffer (Buffer, CurPtr + GapLen - Length, Length, False, True);
  5127.  
  5128.   end;
  5129.  
  5130.  
  5131. end; { TEditor.Undo }
  5132.  
  5133.  
  5134.  
  5135. { -------------------------------------------------------------------------- }
  5136.  
  5137.  
  5138.  
  5139. procedure TEditor.Unlock;
  5140.  
  5141. begin
  5142.  
  5143.   if LockCount > 0 then
  5144.   begin
  5145.     Dec (LockCount);
  5146.     if LockCount = 0 then
  5147.       DoUpdate;
  5148.   end;
  5149.  
  5150.  
  5151. end; { TEditor.Unlock }
  5152.  
  5153.  
  5154.  
  5155. { -------------------------------------------------------------------------- }
  5156.  
  5157.  
  5158.  
  5159. procedure TEditor.Update (AFlags : Byte);
  5160.  
  5161. begin
  5162.  
  5163.   UpdateFlags := UpdateFlags or AFlags;
  5164.  
  5165.   if LockCount = 0 then
  5166.     DoUpdate;
  5167.  
  5168.  
  5169. end; { TEditor.Update }
  5170.  
  5171.  
  5172.  
  5173. { -------------------------------------------------------------------------- }
  5174.  
  5175.  
  5176.  
  5177. procedure TEditor.UpdateCommands;
  5178.  
  5179. begin
  5180.  
  5181.   SetCmdState (cmUndo, (DelCount <> 0) or (InsCount <> 0));
  5182.  
  5183.   if not IsClipboard then
  5184.     begin
  5185.       SetCmdState (cmCut, HasSelection);
  5186.       SetCmdState (cmCopy, HasSelection);
  5187.       SetCmdState (cmPaste, (Clipboard <> nil) and (Clipboard^.HasSelection));
  5188.     end;
  5189.  
  5190.   SetCmdState (cmClear, HasSelection);
  5191.   SetCmdState (cmFind, True);
  5192.   SetCmdState (cmReplace, True);
  5193.   SetCmdState (cmSearchAgain, True);
  5194.  
  5195.  
  5196. end; { TEditor.UpdateCommands }
  5197.  
  5198.  
  5199.  
  5200. { -------------------------------------------------------------------------- }
  5201.  
  5202.  
  5203.  
  5204. { MARK - Start. }
  5205.  
  5206. procedure TEditor.Update_Place_Markers (AddCount : Word; KillCount : Word;
  5207.                                         StartPtr : Word;    EndPtr : Word);
  5208.  
  5209.  
  5210.   { -------------------------------------------------------- }
  5211.   {                                                          }
  5212.   { This procedure updates the position of the place markers }
  5213.   { as the user inserts and deletes text in the document.    }
  5214.   {                                                          }
  5215.   { -------------------------------------------------------- }
  5216.  
  5217.  
  5218. VAR
  5219.  
  5220.   Element : Byte;     { Place_Marker array element to traverse array with. }
  5221.  
  5222.  
  5223. begin
  5224.  
  5225.   for Element := 1 to 10 do
  5226.     begin
  5227.       if AddCount > 0 then
  5228.         begin
  5229.           if (Place_Marker[Element] >= Curptr)
  5230.               and (Place_Marker[Element] <> 0) then
  5231.             Place_Marker[Element] := Place_Marker[Element] + AddCount;
  5232.         end
  5233.       else
  5234.         begin
  5235.           if Place_Marker[Element] >= StartPtr then
  5236.             begin
  5237.               if (Place_Marker[Element] >= StartPtr) and
  5238.                  (Place_Marker[Element] < EndPtr) then
  5239.                 Place_marker[Element] := 0
  5240.               else
  5241.                 begin
  5242.                   if integer (Place_Marker[Element]) - integer (KillCount) > 0 then
  5243.                     Place_Marker[Element] := Place_Marker[Element] - KillCount
  5244.                   else
  5245.                     Place_Marker[Element] := 0;
  5246.                 end;
  5247.             end;
  5248.         end;
  5249.     end;
  5250.  
  5251.   { WRAP - Start. }
  5252.  
  5253.   if AddCount > 0 then
  5254.     BlankLine := BlankLine + AddCount
  5255.   else
  5256.     begin
  5257.       if integer (BlankLine) - Integer (KillCount) > 0 then
  5258.         BlankLine := BlankLine - KillCount
  5259.       else
  5260.         BlankLine := 0;
  5261.     end;
  5262.  
  5263.   { WRAP - Stop. }
  5264.  
  5265.  
  5266. end; { TEditor.Update_Place_Markers }
  5267.  
  5268. {MARK - Stop. }
  5269.  
  5270.  
  5271.  
  5272. { -------------------------------------------------------------------------- }
  5273.  
  5274.  
  5275.  
  5276. function TEditor.Valid (Command : Word) : Boolean;
  5277.  
  5278. begin
  5279.  
  5280.   Valid := IsValid;
  5281.  
  5282.  
  5283. end; { TEditor.Valid }
  5284.  
  5285.  
  5286.  
  5287. { -------------------------------------------------------------------------- }
  5288.  
  5289.  
  5290.  
  5291.          { ----------------------------------------------- }
  5292.          {                                                 }
  5293.          { The following methods are for the TMEMO object. }
  5294.          {                                                 }
  5295.          { ----------------------------------------------- }
  5296.  
  5297.  
  5298.  
  5299. constructor TMemo.Load (var S : Objects.TStream);
  5300.  
  5301. VAR
  5302.  
  5303.   Length : Word;
  5304.  
  5305. begin
  5306.  
  5307.   TEditor.Load (S);
  5308.   S.Read (Length, SizeOf (Word));
  5309.  
  5310.   if IsValid then
  5311.     begin
  5312.       S.Read (Buffer^[BufSize - Length], Length);
  5313.       SetBufLen (Length);
  5314.     end
  5315.   else
  5316.     S.Seek (S.GetPos + Length);
  5317.  
  5318.  
  5319. end; { TMemo.Load }
  5320.  
  5321.  
  5322.  
  5323. { -------------------------------------------------------------------------- }
  5324.  
  5325.  
  5326.  
  5327. function TMemo.DataSize : Word;
  5328.  
  5329. begin
  5330.  
  5331.   DataSize := BufSize + SizeOf (Word);
  5332.  
  5333.  
  5334. end; { TMemo.DataSize }
  5335.  
  5336.  
  5337.  
  5338. { -------------------------------------------------------------------------- }
  5339.  
  5340.  
  5341.  
  5342. procedure TMemo.GetData (var Rec);
  5343.  
  5344. VAR
  5345.  
  5346.   Data : TMemoData absolute Rec;
  5347.  
  5348. begin
  5349.  
  5350.   Data.Length := BufLen;
  5351.   Move (Buffer^, Data.Buffer, CurPtr);
  5352.   Move (Buffer^[CurPtr + GapLen], Data.Buffer[CurPtr], BufLen - CurPtr);
  5353.   FillChar (Data.Buffer[BufLen], BufSize - BufLen, 0);
  5354.  
  5355.  
  5356. end; { TMemo.GetData }
  5357.  
  5358.  
  5359.  
  5360. { -------------------------------------------------------------------------- }
  5361.  
  5362.  
  5363.  
  5364. function TMemo.GetPalette : Views.PPalette;
  5365.  
  5366. CONST
  5367.  
  5368.   P : String[Length (CMemo)] = CMemo;
  5369.  
  5370. begin
  5371.  
  5372.   GetPalette := @P;
  5373.  
  5374.  
  5375. end; { TMemo.GetPalette }
  5376.  
  5377.  
  5378.  
  5379. { -------------------------------------------------------------------------- }
  5380.  
  5381.  
  5382.  
  5383. procedure TMemo.HandleEvent (var Event : Drivers.TEvent);
  5384.  
  5385. begin
  5386.  
  5387.   if (Event.What <> Drivers.evKeyDown) or (Event.KeyCode <> Drivers.kbTab) then
  5388.     TEditor.HandleEvent (Event);
  5389.  
  5390.  
  5391. end; { TMemo.HandleEvent }
  5392.  
  5393.  
  5394.  
  5395. { -------------------------------------------------------------------------- }
  5396.  
  5397.  
  5398.  
  5399. procedure TMemo.SetData (var Rec);
  5400.  
  5401. VAR
  5402.  
  5403.   Data : TMemoData absolute Rec;
  5404.  
  5405. begin
  5406.  
  5407.   Move (Data.Buffer, Buffer^[BufSize - Data.Length], Data.Length);
  5408.   SetBufLen (Data.Length);
  5409.  
  5410.  
  5411. end; { TMemo.SetData }
  5412.  
  5413.  
  5414.  
  5415. { -------------------------------------------------------------------------- }
  5416.  
  5417.  
  5418.  
  5419. procedure TMemo.Store (var S : Objects.TStream);
  5420.  
  5421. begin
  5422.  
  5423.   TEditor.Store (S);
  5424.   S.Write (BufLen, SizeOf (Word));
  5425.   S.Write (Buffer^, CurPtr);
  5426.   S.Write (Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5427.  
  5428.  
  5429. end; { TMemo.Store }
  5430.  
  5431.  
  5432.  
  5433. { -------------------------------------------------------------------------- }
  5434.  
  5435.  
  5436.  
  5437.          { ----------------------------------------------------- }
  5438.          {                                                       }
  5439.          { The following methods are for the TFILEEDITOR object. }
  5440.          {                                                       }
  5441.          { ----------------------------------------------------- }
  5442.  
  5443.  
  5444.  
  5445. constructor TFileEditor.Init (var Bounds : TRect;
  5446.                               AHScrollBar, AVScrollBar : PScrollBar;
  5447.                               AIndicator : PIndicator;
  5448.                               AFileName  : FNameStr);
  5449.  
  5450. begin
  5451.  
  5452.   TEditor.Init (Bounds, AHScrollBar, AVScrollBar, AIndicator, 0);
  5453.  
  5454.   if AFileName <> '' then
  5455.   begin
  5456.  
  5457.     FileName := FExpand (AFileName);
  5458.     if IsValid then
  5459.       IsValid := LoadFile;
  5460.  
  5461.   end;
  5462.  
  5463.  
  5464. end; { TFileEditor.Init }
  5465.  
  5466.  
  5467.  
  5468. { -------------------------------------------------------------------------- }
  5469.  
  5470.  
  5471.  
  5472. constructor TFileEditor.Load (var S : Objects.TStream);
  5473.  
  5474. VAR
  5475.  
  5476.   SStart : Word;
  5477.   SEnd   : Word;
  5478.   Curs   : Word;
  5479.  
  5480. begin
  5481.  
  5482.   TEditor.Load (S);
  5483.  
  5484.   BufSize := 0;
  5485.  
  5486.   S.Read (FileName[0], SizeOf (Char));
  5487.   S.Read (Filename[1], Length (FileName));
  5488.  
  5489.   if IsValid then
  5490.     IsValid := LoadFile;
  5491.  
  5492.   S.Read (SStart, SizeOf (Word));
  5493.   S.Read (SEnd, SizeOf (Word));
  5494.   S.Read (Curs, SizeOf (Word));
  5495.  
  5496.   if IsValid and (SEnd <= BufLen) then
  5497.   begin
  5498.     SetSelect (SStart, SEnd, Curs = SStart);
  5499.     TrackCursor (True);
  5500.   end;
  5501.  
  5502.  
  5503. end; { TFileEditor.Load }
  5504.  
  5505.  
  5506.  
  5507. { -------------------------------------------------------------------------- }
  5508.  
  5509.  
  5510.  
  5511. procedure TFileEditor.DoneBuffer;
  5512.  
  5513. begin
  5514.  
  5515.   if Buffer <> nil then
  5516.     DisposeBuffer (Buffer);
  5517.  
  5518.  
  5519. end; { TFileEditor.DoneBuffer }
  5520.  
  5521.  
  5522.  
  5523. { -------------------------------------------------------------------------- }
  5524.  
  5525.  
  5526.  
  5527. procedure TFileEditor.HandleEvent (var Event : Drivers.TEvent);
  5528.  
  5529. begin
  5530.  
  5531.   TEditor.HandleEvent (Event);
  5532.  
  5533.   case Event.What of
  5534.     Drivers.evCommand:
  5535.       case Event.Command of
  5536.  
  5537.         cmSave   : Save;
  5538.         cmSaveAs : SaveAs;
  5539.  
  5540.         { SAVE - Start. }
  5541.  
  5542.         cmSaveDone : if Save then
  5543.                        Message (Owner, Drivers.evCommand, Views.cmClose, nil);
  5544.  
  5545.         { SAVE - Stop. } { Added code to remove editor if ^KD or ^KX pressed. }
  5546.  
  5547.       else
  5548.         Exit;
  5549.       end;
  5550.   else
  5551.     Exit;
  5552.   end;
  5553.  
  5554.   ClearEvent (Event);
  5555.  
  5556.  
  5557. end; { TFileEditor.HandleEvent }
  5558.  
  5559.  
  5560.  
  5561. { -------------------------------------------------------------------------- }
  5562.  
  5563.  
  5564.  
  5565. procedure TFileEditor.InitBuffer;
  5566.  
  5567. begin
  5568.  
  5569.   NewBuffer (Pointer (Buffer), $1000);
  5570.  
  5571.   { LOAD  - Start. }
  5572.   { STORE - Start. }
  5573.  
  5574.   BufSize := 0;
  5575.  
  5576.   { STORE - Stop. }
  5577.   { LOAD  - Stop. }
  5578.  
  5579.  
  5580. end; { TFileEditor.InitBuffer }
  5581.  
  5582.  
  5583.  
  5584. { -------------------------------------------------------------------------- }
  5585.  
  5586.  
  5587.  
  5588. function TFileEditor.LoadFile : Boolean;
  5589.  
  5590. VAR
  5591.  
  5592.   Length : Word;
  5593.   FSize  : Longint;
  5594.   F      : File;
  5595.  
  5596. begin
  5597.  
  5598.   LoadFile := False;
  5599.   Length := 0;
  5600.   Assign (F, FileName);
  5601.   Reset (F, 1);
  5602.  
  5603.   if IOResult <> 0 then
  5604.     EditorDialog (edReadError, @FileName)
  5605.   else
  5606.     begin
  5607.  
  5608.       FSize := FileSize (F);
  5609.  
  5610.       if (FSize > $FFF0) or not SetBufSize (Word (FSize)) then
  5611.         EditorDialog (edOutOfMemory, nil)
  5612.       else
  5613.         begin
  5614.  
  5615.           BlockRead (F, Buffer^[BufSize - Word (FSize)], FSize);
  5616.  
  5617.           if IOResult <> 0 then
  5618.             EditorDialog (edReadError, @FileName)
  5619.           else
  5620.             begin
  5621.               LoadFile := True;
  5622.               Length := FSize;
  5623.             end;
  5624.  
  5625.         end;
  5626.  
  5627.         Close (F);
  5628.  
  5629.     end;
  5630.  
  5631.   SetBufLen (Length);
  5632.  
  5633.  
  5634. end; { TFileEditor.LoadFile }
  5635.  
  5636.  
  5637.  
  5638. { -------------------------------------------------------------------------- }
  5639.  
  5640.  
  5641.  
  5642. function TFileEditor.Save : Boolean;
  5643.  
  5644. begin
  5645.  
  5646.   if FileName = '' then
  5647.     Save := SaveAs
  5648.   else
  5649.     Save := SaveFile;
  5650.  
  5651.  
  5652. end; { TFileEditor.Save }
  5653.  
  5654.  
  5655.  
  5656. { -------------------------------------------------------------------------- }
  5657.  
  5658.  
  5659.  
  5660. function TFileEditor.SaveAs : Boolean;
  5661.  
  5662. begin
  5663.  
  5664.   SaveAs := False;
  5665.  
  5666.   if EditorDialog (edSaveAs, @FileName) <> Views.cmCancel then
  5667.   begin
  5668.  
  5669.     FileName := FExpand (FileName);
  5670.     Message (Owner, Drivers.evBroadcast, cmUpdateTitle, nil);
  5671.     SaveAs := SaveFile;
  5672.  
  5673.     if IsClipboard then
  5674.       FileName := '';
  5675.   end;
  5676.  
  5677.  
  5678. end; { TFileEditor.SaveAs }
  5679.  
  5680.  
  5681.  
  5682. { -------------------------------------------------------------------------- }
  5683.  
  5684.  
  5685.  
  5686. function TFileEditor.SaveFile : Boolean;
  5687.  
  5688. VAR
  5689.  
  5690.   F          : File;
  5691.   BackupName : Objects.FNameStr;
  5692.   D          : DOS.DirStr;
  5693.   N          : DOS.NameStr;
  5694.   E          : DOS.ExtStr;
  5695.  
  5696. begin
  5697.  
  5698.   SaveFile := False;
  5699.  
  5700.   if EditorFlags and efBackupFiles <> 0 then
  5701.   begin
  5702.     FSplit (FileName, D, N, E);
  5703.     BackupName := D + N + '.BAK';
  5704.     Assign (F, BackupName);
  5705.     Erase (F);
  5706.     Assign (F, FileName);
  5707.     Rename (F, BackupName);
  5708.     InOutRes := 0;
  5709.   end;
  5710.  
  5711.   Assign (F, FileName);
  5712.   Rewrite (F, 1);
  5713.  
  5714.   if IOResult <> 0 then
  5715.     EditorDialog (edCreateError, @FileName)
  5716.   else
  5717.     begin
  5718.  
  5719.       BlockWrite (F, Buffer^, CurPtr);
  5720.       BlockWrite (F, Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5721.  
  5722.       if IOResult <> 0 then
  5723.         EditorDialog (edWriteError, @FileName)
  5724.       else
  5725.         begin
  5726.           Modified := False;
  5727.           Update (ufUpdate);
  5728.           SaveFile := True;
  5729.         end;
  5730.         Close (F);
  5731.       end;
  5732.  
  5733.  
  5734. end; { TFileEditor.SaveFile }
  5735.  
  5736.  
  5737.  
  5738. { -------------------------------------------------------------------------- }
  5739.  
  5740.  
  5741.  
  5742. function TFileEditor.SetBufSize (NewSize : Word) : Boolean;
  5743.  
  5744. VAR
  5745.  
  5746.   N : Word;
  5747.  
  5748. begin
  5749.  
  5750.   SetBufSize := False;
  5751.  
  5752.   if NewSize = 0 then
  5753.     NewSize := $1000
  5754.   else
  5755.     if NewSize > $F000 then
  5756.       NewSize := $FFF0
  5757.     else
  5758.       NewSize := (NewSize + $0FFF) and $F000;
  5759.  
  5760.   if NewSize <> BufSize then
  5761.   begin
  5762.  
  5763.     if NewSize > BufSize then
  5764.       if not SetBufferSize (Buffer, NewSize) then
  5765.         Exit;
  5766.  
  5767.     N := BufLen - CurPtr + DelCount;
  5768.     Move (Buffer^[BufSize - N], Buffer^[NewSize - N], N);
  5769.  
  5770.     if NewSize < BufSize then
  5771.       SetBufferSize (Buffer, NewSize);
  5772.  
  5773.     BufSize := NewSize;
  5774.     GapLen := BufSize - BufLen;
  5775.  
  5776.   end;
  5777.  
  5778.   SetBufSize := True;
  5779.  
  5780.  
  5781. end; { TFileEditor.SetBufSize }
  5782.  
  5783.  
  5784.  
  5785. { -------------------------------------------------------------------------- }
  5786.  
  5787.  
  5788.  
  5789. procedure TFileEditor.Store (var S : Objects.TStream);
  5790.  
  5791. begin
  5792.  
  5793.   TEditor.Store (S);
  5794.   S.Write (FileName, Length (FileName) + 1);
  5795.   S.Write (SelStart, SizeOf (Word) * 3);
  5796.  
  5797.  
  5798. end; { TFileEditor.Store }
  5799.  
  5800.  
  5801.  
  5802. { -------------------------------------------------------------------------- }
  5803.  
  5804.  
  5805.  
  5806. procedure TFileEditor.UpdateCommands;
  5807.  
  5808. begin
  5809.  
  5810.   TEditor.UpdateCommands;
  5811.  
  5812.   SetCmdState (cmSave, True);
  5813.   SetCmdState (cmSaveAs, True);
  5814.  
  5815.   { SAVE - Start. }
  5816.  
  5817.   SetCmdState (cmSaveDone, True);
  5818.  
  5819.   { SAVE - Stop. } { Added cmSaveDone toggle. }
  5820.  
  5821.  
  5822.  
  5823.   { -------------------------------------------------------------------- }
  5824.   {                                                                      }
  5825.   { The following SetCmdState calls are included to allow you to disable }
  5826.   { any custom menu options you design for the editor features.  I have  }
  5827.   { commented them out.  You pay a price in speed performance for EACH   }
  5828.   { option you uncomment.  Read the MENU section of NEWEDIT.DOC!         }
  5829.   {                                                                      }
  5830.   { -------------------------------------------------------------------- }
  5831.  
  5832.  
  5833.   { CENTER - Start. }
  5834.   { HOMEND - Start. }
  5835.   { INSLIN - Start. }
  5836.   { JLINE  - Start. }
  5837.   { MARK   - Start. }
  5838.   { PRETAB - Start. }
  5839.   { REFDOC - Start. }
  5840.   { REFORM - Start. }
  5841.   { RMSET  - Start. }
  5842.   { SCRLDN - Start. }
  5843.   { SCRLDN - Start. }
  5844.   { SELWRD - Start. }
  5845.   { WRAP   - Start. }
  5846.  
  5847.   { SetCmdState (cmCenterText, True);  }
  5848.   { SetCmdState (cmEndPage, True);     }
  5849.   { SetCmdState (cmHomePage, True);    }
  5850.   { SetCmdState (cmIndentMode, True);  }
  5851.   { SetCmdState (cmInsertLine, True);  }
  5852.   { SetCmdState (cmJumpLine, True);    }
  5853.   { SetCmdState (cmJumpMark0, True);   }
  5854.   { SetCmdState (cmJumpMark1, True);   }
  5855.   { SetCmdState (cmJumpMark2, True);   }
  5856.   { SetCmdState (cmJumpMark3, True);   }
  5857.   { SetCmdState (cmJumpMark4, True);   }
  5858.   { SetCmdState (cmJumpMark5, True);   }
  5859.   { SetCmdState (cmJumpMark6, True);   }
  5860.   { SetCmdState (cmJumpMark7, True);   }
  5861.   { SetCmdState (cmJumpMark8, True);   }
  5862.   { SetCmdState (cmJumpMark9, True);   }
  5863.   { SetCmdState (cmReformDoc, True);   }
  5864.   { SetCmdState (cmReformPara, True);  }
  5865.   { SetCmdState (cmRightMargin, True); }
  5866.   { SetCmdState (cmScrollDown, True);  }
  5867.   { SetCmdState (cmScrollUp, True);    }
  5868.   { SetCmdState (cmSelectWord, True);  }
  5869.   { SetCmdState (cmSetMark0, True);    }
  5870.   { SetCmdState (cmSetMark1, True);    }
  5871.   { SetCmdState (cmSetMark2, True);    }
  5872.   { SetCmdState (cmSetMark3, True);    }
  5873.   { SetCmdState (cmSetMark4, True);    }
  5874.   { SetCmdState (cmSetMark5, True);    }
  5875.   { SetCmdState (cmSetMark6, True);    }
  5876.   { SetCmdState (cmSetMark7, True);    }
  5877.   { SetCmdState (cmSetMark8, True);    }
  5878.   { SetCmdState (cmSetMark9, True);    }
  5879.   { SetCmdState (cmSetTabs, True);     }
  5880.   { SetCmdState (cmTabKey, True);      }
  5881.   { SetCmdState (cmWordWrap, True);    }
  5882.  
  5883.  
  5884.   { WRAP   - Stop. }
  5885.   { SELWRD - Stop. }
  5886.   { SCRLUP - Stop. }
  5887.   { SCRLDN - Stop. }
  5888.   { RMSET  - Stop. }
  5889.   { REFORM - Stop. }
  5890.   { REFDOC - Stop. }
  5891.   { PRETAB - Stop. }
  5892.   { MARK   - Stop. }
  5893.   { JLINE  - Stop. }
  5894.   { INSLIN - Stop. }
  5895.   { HOMEND - Stop. }
  5896.   { CENTER - Stop. } { This was required so these command constants may }
  5897.                      { be used in enabling and disabling menu options.  }
  5898.  
  5899.  
  5900. end; { TFileEditor.UpdateCommands }
  5901.  
  5902.  
  5903.  
  5904. { -------------------------------------------------------------------------- }
  5905.  
  5906.  
  5907.  
  5908. function TFileEditor.Valid (Command : Word) : Boolean;
  5909.  
  5910. VAR
  5911.  
  5912.   D : Integer;
  5913.  
  5914. begin
  5915.  
  5916.   if Command = Views.cmValid then
  5917.     Valid := IsValid
  5918.   else
  5919.     begin
  5920.  
  5921.       Valid := True;
  5922.  
  5923.       if Modified then
  5924.       begin
  5925.  
  5926.         if FileName = '' then
  5927.           D := edSaveUntitled
  5928.         else
  5929.           D := edSaveModify;
  5930.  
  5931.         case EditorDialog (D, @FileName) of
  5932.           Views.cmYes    : Valid := Save;
  5933.           Views.cmNo     : Modified := False;
  5934.           Views.cmCancel : Valid := False;
  5935.  
  5936.         end;
  5937.  
  5938.       end;
  5939.  
  5940.     end;
  5941.  
  5942.  
  5943. end; { TFileEditor.Valid }
  5944.  
  5945.  
  5946.  
  5947. { -------------------------------------------------------------------------- }
  5948.  
  5949.  
  5950.  
  5951.          { ----------------------------------------------------- }
  5952.          {                                                       }
  5953.          { The following methods are for the TEDITWINDOW object. }
  5954.          {                                                       }
  5955.          { ----------------------------------------------------- }
  5956.  
  5957.  
  5958.  
  5959. constructor TEditWindow.Init (var Bounds   : TRect;
  5960.                                   FileName : Objects.FNameStr;
  5961.                                   ANumber  : Integer);
  5962.  
  5963. VAR
  5964.  
  5965.   HScrollBar : Views.PScrollBar;
  5966.   VScrollBar : Views.PScrollBar;
  5967.   Indicator  : PIndicator;
  5968.   R          : TRect;
  5969.  
  5970. begin
  5971.  
  5972.   TWindow.Init (Bounds, '', ANumber);
  5973.   Options := Options or Views.ofTileable;
  5974.  
  5975.   R.Assign (18, Size.Y - 1, Size.X - 2, Size.Y);
  5976.   HScrollBar := New (Views.PScrollBar, Init (R));
  5977.   HScrollBar^.Hide;
  5978.   Insert (HScrollBar);
  5979.  
  5980.   R.Assign (Size.X - 1, 1, Size.X, Size.Y - 1);
  5981.   VScrollBar := New (Views.PScrollBar, Init (R));
  5982.   VScrollBar^.Hide;
  5983.   Insert (VScrollBar);
  5984.  
  5985.   R.Assign (2, Size.Y - 1, 16, Size.Y);
  5986.   Indicator := New (PIndicator, Init (R));
  5987.   Indicator^.Hide;
  5988.   Insert (Indicator);
  5989.  
  5990.   GetExtent (R);
  5991.   R.Grow (-1, -1);
  5992.   Editor := New (PFileEditor, Init (R, HScrollBar, VScrollBar, Indicator, FileName));
  5993.  
  5994.   Insert (Editor);
  5995.  
  5996.  
  5997. end; { TEditWindow.Init }
  5998.  
  5999.  
  6000.  
  6001. { -------------------------------------------------------------------------- }
  6002.  
  6003.  
  6004.  
  6005. constructor TEditWindow.Load (var S : Objects.TStream);
  6006.  
  6007. begin
  6008.  
  6009.   TWindow.Load (S);
  6010.   GetSubViewPtr (S, Editor);
  6011.  
  6012.  
  6013. end; { TEditWindow.Load }
  6014.  
  6015.  
  6016.  
  6017. { -------------------------------------------------------------------------- }
  6018.  
  6019.  
  6020.  
  6021. procedure TEditWindow.Close;
  6022.  
  6023. begin
  6024.  
  6025.   if Editor^.IsClipboard then
  6026.     Hide
  6027.   else
  6028.     TWindow.Close;
  6029.  
  6030.  
  6031. end; { TEditWindow.Close }
  6032.  
  6033.  
  6034.  
  6035. { -------------------------------------------------------------------------- }
  6036.  
  6037.  
  6038.  
  6039. function TEditWindow.GetTitle (MaxSize : Integer) : Views.TTitleStr;
  6040.  
  6041. begin
  6042.  
  6043.   if Editor^.IsClipboard then
  6044.     GetTitle := 'Clipboard'
  6045.   else
  6046.     if Editor^.FileName = '' then
  6047.       GetTitle := 'Untitled'
  6048.     else
  6049.       GetTitle := Editor^.FileName;
  6050.  
  6051.  
  6052. end; { TEditWindow.GetTile }
  6053.  
  6054.  
  6055.  
  6056. { -------------------------------------------------------------------------- }
  6057.  
  6058.  
  6059.  
  6060. procedure TEditWindow.HandleEvent (var Event : Drivers.TEvent);
  6061.  
  6062. begin
  6063.  
  6064.   TWindow.HandleEvent (Event);
  6065.  
  6066.   if (Event.What = Drivers.evBroadcast) then
  6067.     { and (Event.Command = cmUpdateTitle) then }
  6068.  
  6069.  
  6070.  
  6071.     { STATS - Start. }
  6072.  
  6073.     { -------------------------------------------------------------------- }
  6074.     {                                                                      }
  6075.     { Changed if statement above so I could test for cmBlugeonStats.       }
  6076.     { Stats would not show up when loading a file until a key was pressed. }
  6077.     {                                                                      }
  6078.     { -------------------------------------------------------------------- }
  6079.  
  6080.  
  6081.     case Event.Command of
  6082.       cmUpdateTitle   : begin
  6083.                           Frame^.DrawView;
  6084.                           ClearEvent (Event);
  6085.                         end;
  6086.  
  6087.       cmBludgeonStats : begin
  6088.                           Editor^.Update (ufStats);
  6089.                           ClearEvent (Event);
  6090.                         end;
  6091.     end;
  6092.  
  6093.     { STATS - Stop. }
  6094.  
  6095.  
  6096. end; { TEditWindow.HandleEvent }
  6097.  
  6098.  
  6099.  
  6100. { -------------------------------------------------------------------------- }
  6101.  
  6102.  
  6103.  
  6104. procedure TEditWindow.SizeLimits (var Min, Max : TPoint);
  6105.  
  6106. begin
  6107.  
  6108.   TWindow.SizeLimits (Min, Max);
  6109.   Min .X := 23;
  6110.  
  6111.  
  6112. end; { TEditWindow.SizeLimits }
  6113.  
  6114.  
  6115.  
  6116. { -------------------------------------------------------------------------- }
  6117.  
  6118.  
  6119.  
  6120. procedure TEditWindow.Store (var S : Objects.TStream);
  6121.  
  6122. begin
  6123.  
  6124.   TWindow.Store (S);
  6125.   PutSubViewPtr (S, Editor);
  6126.  
  6127.  
  6128. end; { TEditWindow.Store }
  6129.  
  6130.  
  6131.  
  6132. { -------------------------------------------------------------------------- }
  6133.  
  6134.  
  6135.  
  6136. procedure RegisterEditors;
  6137.  
  6138. begin
  6139.  
  6140.   RegisterType (REditor);
  6141.   RegisterType (RMemo);
  6142.   RegisterType (RFileEditor);
  6143.   RegisterType (RIndicator);
  6144.   RegisterType (REditWindow);
  6145.  
  6146.  
  6147. end; { RegisterEditors }
  6148.  
  6149.  
  6150.  
  6151. { -------------------------------------------------------------------------- }
  6152.  
  6153.  
  6154.  
  6155. end. { Unit NewEdit }
  6156.