home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 09_10 / praxis / modedit.mod < prev    next >
Encoding:
Text File  |  1991-07-19  |  22.7 KB  |  729 lines

  1. (* ------------------------------------------------------ *)
  2. (*                      MODEDIT.MOD                       *)
  3. (*                 FST-Editor, die erste...               *)
  4. (*               (c) 1991 W.Rinke & TOOLBOX               *)
  5. (* ------------------------------------------------------ *)
  6. MODULE ModEdit;
  7.  
  8. (* $L+ *)
  9.  
  10. IMPORT InOut;
  11. IMPORT ASCII;
  12. IMPORT Keyboard;
  13.  
  14. FROM SYSTEM           IMPORT ADR;
  15. FROM System           IMPORT GetArg, Move;
  16. FROM Strings          IMPORT Length, Concat, Delete, Append, 
  17.                              Insert, Copy;
  18. FROM Windows          IMPORT Window, OpenWindow, 
  19.                              SelectWindow, CloseWindow;
  20. FROM Display          IMPORT DisplayString, ReadCharAttr, 
  21.                              displayAttr,
  22.                              line0, col0, lineN, colN,
  23.                              ScrollUp, DisplayLine, 
  24.                              DisplayBuffer,
  25.                              ReadScreen, WriteScreen, 
  26.                              displayPtr, Goto;
  27. FROM Keyboard         IMPORT KeyPressed, GetKey, GetKeyCh;
  28. FROM NumberConversion IMPORT CardToString;
  29. FROM FileSystem       IMPORT Response, File, Lookup, Close,
  30.                              Reset, Rewrite, Rename,
  31.                              ReadChar, WriteChar,
  32.                              WriteNBytes;
  33. FROM Storage          IMPORT ALLOCATE, DEALLOCATE;
  34.  
  35. (* ------------------------------------------------------ *)
  36.  
  37. CONST
  38.   MAXLINES = 15600;
  39.   
  40. TYPE
  41.   STRING   = ARRAY [0..80] OF CHAR;
  42.   StrPtr   = POINTER TO STRING;
  43.   
  44. VAR
  45.   Lines         : ARRAY [1..MAXLINES] OF StrPtr;
  46.   FirstOnScreen : CARDINAL; 
  47.   TextLine      : CARDINAL;
  48.   TextCol       : CARDINAL;
  49.   MaxLine       : CARDINAL;
  50.   TextMaxY      : CARDINAL;
  51.  
  52.   InfoBuffer    : ARRAY [0..79] OF CARDINAL;   
  53.   ErrorMessage  : ARRAY [1..6] OF STRING;
  54.   InfoMessage   : STRING;
  55.   InfoColor     : CARDINAL;
  56.   ErrorColor    : CARDINAL; 
  57.   TextColor     : CARDINAL;
  58.   EntryColor    : CARDINAL;
  59.   LastMode      : CARDINAL;
  60.   
  61.   Done          : BOOLEAN;
  62.   InsertMode    : BOOLEAN;
  63.   Modified      : BOOLEAN; 
  64.   FileName      : STRING;
  65.   NextFile      : STRING;
  66.   TextFile      : File;
  67.   
  68. (* ------------------------------------------------------ *)
  69.  
  70.   PROCEDURE ClrScr;                                 (* ok *)
  71.   BEGIN
  72.     ScrollUp(0, line0, col0, lineN, colN, displayAttr);
  73.       (* löscht das Fenster mit den aktuellen Koordinaten *)
  74.       (* analog zu Turbo Pascal.                          *)
  75.   END ClrScr;
  76.  
  77. (* ------------------------------------------------------ *)
  78.  
  79.   PROCEDURE Wait;                                   (* ok *)
  80.   VAR
  81.     c : CHAR;
  82.   BEGIN
  83.     REPEAT UNTIL KeyPressed();  GetKey(c);
  84.   END Wait; 
  85.  
  86. (* ------------------------------------------------------ *)
  87.   
  88.   PROCEDURE UpString(VAR s : STRING);               (* ok *)
  89.   VAR
  90.     i : CARDINAL;
  91.   BEGIN
  92.     FOR i := 0 TO Length(s) DO 
  93.       s[i] := CAP(s[i]);
  94.     END;
  95.   END UpString;
  96.  
  97. (* ------------------------------------------------------ *)
  98.   
  99.   PROCEDURE GetParams(VAR s : STRING);              (* ok *)
  100.   VAR
  101.     l : CARDINAL;
  102.   BEGIN
  103.     GetArg(s, l);
  104.     UpString(s);
  105.   END GetParams;
  106.  
  107. (* ------------------------------------------------------ *)
  108.  
  109.   PROCEDURE Init;
  110.   VAR
  111.     c : CHAR;
  112.   BEGIN
  113.     ReadCharAttr(c, LastMode);
  114.  
  115.     InfoColor  := 3FH;      (* Cyan/White      *)
  116.     TextColor  := 1EH;      (* Blue/Yellow     *)
  117.     ErrorColor := 4FH;      (* Red/White       *)
  118.     EntryColor := 70H;      (* LightGray/Black *)
  119.  
  120.     ErrorMessage[1] := 'Datei nicht gefunden';
  121.     ErrorMessage[2] := 'Lesefehler';
  122.     ErrorMessage[3] := 'Fehler beim Speichern';
  123.     ErrorMessage[4] := 'Laufwerk nicht bereit';
  124.     ErrorMessage[5] := 'Text paßt nicht in den Speicher';
  125.     ErrorMessage[6] := 'Programm normal beendet';
  126.     
  127.     InsertMode  := TRUE;
  128.     TextLine    := 1;  TextCol := 1;  TextMaxY := 24;
  129.  
  130.     InfoMessage := ' Datei: ';
  131.     GetParams(FileName);
  132.     UpString(FileName);
  133.     Append(InfoMessage, FileName);  
  134.     Modified := FALSE;
  135.     IF Length(FileName) > 0 THEN 
  136.       IF NOT LoadFile(FileName) THEN 
  137.         InitEmptyText;
  138.       END;
  139.     END;
  140.     Goto(0, 0);  ClrScr;
  141.   END Init;
  142.  
  143. (* ------------------------------------------------------ *)
  144.  
  145.   PROCEDURE QuitProgram;                            (* ok *)
  146.   BEGIN
  147.     displayAttr := LastMode;
  148.     ClrScr;
  149.     Done := TRUE;        
  150.                (* Löst das Problem mit der HALTED-message *)
  151.   END QuitProgram;
  152.  
  153. (* ------------------------------------------------------ *)
  154.      
  155.   PROCEDURE HelpScreen;                             (* ok *)
  156.   VAR
  157.     w : Window;
  158.     a : CARDINAL;
  159.     c : CHAR;
  160.   BEGIN
  161.     a           := InfoColor;  
  162.     displayAttr := InfoColor;
  163.     OpenWindow(w, 6, 20, 20, 61, TRUE, ' Hilfe ');
  164.     SelectWindow(w, TRUE);
  165.     DisplayString('Spezielle Befehle des toolbox-Editors: ',  
  166.                                                    0, 1, a);
  167.     DisplayString('-------------------------------------- ',  
  168.                                                    1, 1, a);
  169.     DisplayString('                                       ',  
  170.                                                    2, 1, a);
  171.     DisplayString('          <F2>  Sichern                ',  
  172.                                                    3, 1, a);
  173.     DisplayString('          <F3>  Laden                  ',  
  174.                                                    4, 1, a);
  175.     DisplayString('    <Alt>-<F2>  Sichern als            ',  
  176.                                                    5, 1, a);
  177.     DisplayString(' <Ctrl>-<Home>  Textanfang             ',  
  178.                                                    6, 1, a);
  179.     DisplayString('  <Crtl>-<End>  Textende               ',  
  180.                                                    7, 1, a);
  181.     DisplayString('         <Ins>  Einfügen/Überschreiben ',  
  182.                                                    8, 1, a);
  183.     DisplayString('    <Ctrl>-<N>  Zeile einfügen         ',  
  184.                                                    9, 1, a);
  185.     DisplayString('    <Ctrl>-<Y>  Zeile löschen          ', 
  186.                                                   10, 1, a);
  187.     DisplayString('                                       ', 
  188.                                                   11, 1, a);
  189.     DisplayString('    weiter mit beliebiger Taste ...    ', 
  190.                                                   12, 1, a);
  191.     Wait;
  192.     CloseWindow(w);  
  193.     displayAttr := TextColor;
  194.   END HelpScreen;
  195.  
  196. (* ------------------------------------------------------ *)
  197.   
  198.   PROCEDURE UpdateInfoLine;                         (* ok *)
  199.   VAR
  200.     Info, sLine, sCol : STRING;
  201.   BEGIN
  202.     Info := '[';
  203.     IF Modified THEN
  204.       Append(Info, 17C);
  205.     ELSE
  206.       Append(Info, ' ');
  207.     END;
  208.     Append(Info, ']  F1=Hilfe  Pos: '); 
  209.     CardToString(TextLine, sLine, 5);
  210.     CardToString(TextCol, sCol, 2);
  211.     Append(Info, sLine);
  212.     Append(Info, ':');
  213.     Append(Info, sCol);
  214.     Append(Info, '  Modus: ');
  215.     IF InsertMode THEN
  216.       Append(Info, 'INS ');
  217.     ELSE
  218.       Append(Info, 'OVR ');
  219.     END;
  220.     Append(Info, '  Datei: ');
  221.     Append(Info, InfoMessage);
  222.     DisplayLine(Info, 24, InfoColor);
  223.   END UpdateInfoLine;  
  224.  
  225. (* ------------------------------------------------------ *)
  226.  
  227.   PROCEDURE SaveInfoLine;                           (* ok *)
  228.   BEGIN
  229.     ReadScreen(ADR(displayPtr^[24]), ADR(InfoBuffer), 80);
  230.   END SaveInfoLine;          
  231.  
  232. (* ------------------------------------------------------ *)
  233.  
  234.   PROCEDURE RestoreInfoLine;                        (* ok *)
  235.   BEGIN
  236.     WriteScreen(ADR(InfoBuffer), ADR(displayPtr^[24]), 80);
  237.   END RestoreInfoLine;
  238.  
  239. (* ------------------------------------------------------ *)
  240.  
  241.   PROCEDURE ShowError(Nr : CARDINAL; Fatal : BOOLEAN); 
  242.   VAR                                               (* ok *)
  243.     ErrLine : STRING;
  244.     c       : CHAR;
  245.   BEGIN
  246.     SaveInfoLine;
  247.     Concat(ErrorMessage[Nr], ' - Taste...', ErrLine);  
  248.     DisplayLine(ErrLine, 24, ErrorColor);
  249.     Wait;
  250.     RestoreInfoLine;
  251.     IF Fatal THEN QuitProgram; END;
  252.   END ShowError; 
  253.  
  254. (* ------------------------------------------------------ *)
  255.   
  256.   PROCEDURE ToggleInsert;                           (* ok *)
  257.   BEGIN
  258.     InsertMode := NOT InsertMode;
  259.     UpdateInfoLine;
  260.   END ToggleInsert;
  261.  
  262. (* ------------------------------------------------------ *)
  263.  
  264.   PROCEDURE GetFileName(VAR FName : STRING; Msg : STRING);  
  265.   VAR                                               (* ok *)
  266.     Entry     : STRING;
  267.     LeftStop  : CARDINAL;
  268.     c         : CHAR;
  269.   BEGIN
  270.     SaveInfoLine;
  271.     Entry := ''; FName := ''; 
  272.     Concat(' Eingabe -> ', Msg, Entry);
  273.     LeftStop := Length(Entry);
  274.     LOOP
  275.       DisplayLine(Entry, 24, EntryColor);  
  276.       GetKey(c);
  277.       IF c = ASCII.bs THEN 
  278.         IF Length(Entry) - LeftStop > 0 THEN 
  279.           Delete(Entry, Length(Entry)-1, 1);   
  280.           Delete(FName, Length(FName)-1, 1);  
  281.         END;
  282.       ELSIF c = ASCII.cr THEN
  283.         EXIT;         
  284.       ELSE
  285.         c := CAP(c);
  286.         Append(Entry, c);  Append(FName, c);
  287.         DisplayLine(Entry, 24, EntryColor);  
  288.       END;
  289.     END;
  290.     RestoreInfoLine;
  291.   END GetFileName;
  292.   
  293. (* ------------------------------------------------------ *)
  294.  
  295.   PROCEDURE GetNewLine;                             (* ok *)
  296.   BEGIN
  297.     INC(MaxLine);
  298.     NewStr(Lines[MaxLine]);
  299.   END GetNewLine;
  300.  
  301. (* ------------------------------------------------------ *)
  302.  
  303.   PROCEDURE NewStr(VAR p : StrPtr);
  304.   BEGIN
  305.     ALLOCATE(p, SIZE(p^)); 
  306.     IF p = NIL THEN ShowError(5, TRUE); END;
  307.   END NewStr;
  308.  
  309.   PROCEDURE DisposeStr(p : StrPtr);
  310.   BEGIN
  311.     IF p <> NIL THEN DEALLOCATE(p, SIZE(p^)); END;
  312.   END DisposeStr;
  313.  
  314. (* ------------------------------------------------------ *)
  315.  
  316.   PROCEDURE InitEmptyText;                          (* ok *)
  317.   VAR
  318.     i : CARDINAL;
  319.   BEGIN
  320.     MaxLine       := 0;
  321.     displayAttr   := TextColor;  ClrScr;
  322.     FOR i := 1 TO TextMaxY DO
  323.       GetNewLine;
  324.       Lines[i]^   := '';
  325.     END;                   (* sonst bringt Scroll wirre   *) 
  326.                            (* Zeichen auf den Bildschirm. *)
  327.     FirstOnScreen := 1;
  328.     TextLine      := 1;
  329.     TextCol       := 1;
  330.   END InitEmptyText;      
  331.  
  332. (* ------------------------------------------------------ *)
  333.   
  334.   PROCEDURE Scroll(Val : INTEGER);                  (* ok *)
  335.   VAR
  336.     n : CARDINAL;
  337.   BEGIN
  338.     IF MaxLine = 0 THEN RETURN; END;
  339.     IF (INTEGER(FirstOnScreen) + Val) < 1 THEN
  340.       FirstOnScreen := 1;  TextLine := 1;
  341.     ELSE
  342.       FirstOnScreen := 
  343.                      CARDINAL(INTEGER(FirstOnScreen) + Val);
  344.       TextLine      := 
  345.                      CARDINAL(INTEGER(TextLine)      + Val);
  346.       IF FirstOnScreen > (MaxLine - TextMaxY + 1) THEN
  347.         FirstOnScreen := (MaxLine - TextMaxY + 1);       
  348.                                           (* na, Gerald ? *)
  349.       END;
  350.       IF TextLine > MaxLine THEN
  351.         TextLine := MaxLine;    
  352.       END;
  353.     END;  
  354.     UpdateInfoLine;  
  355.     IF Val = 1 THEN
  356.         (* das Zeilenpaket, das in der zweiten Zeile      *)
  357.         (* beginnt und in der vorletzten Zeile endet,     *)
  358.         (* komplett um eine Zeile nach oben verschieben.  *)
  359.       Move(ADR(displayPtr^[1]), ADR(displayPtr^[0]), 
  360.            (TextMaxY - 1) * 160);     (* 23 * 80 * 2 Byte *)
  361.  
  362.         (* neue letzte Zeile aus dem DateiPuffer holen *)   
  363.       DisplayLine(Lines[FirstOnScreen + TextMaxY - 1]^,   
  364.                   TextMaxY - 1, TextColor);         (* ok *)
  365.     ELSIF Val = -1 THEN
  366.       Move(ADR(displayPtr^[0]), ADR(displayPtr^[1]), 
  367.            (TextMaxY - 1) * 160);
  368.  
  369.         (* neue erste Zeile aus dem Dateipuffer holen *)    
  370.       DisplayLine(Lines[FirstOnScreen]^, 0, TextColor);
  371.     ELSE
  372.       FOR n := FirstOnScreen TO 
  373.           FirstOnScreen + TextMaxY - 1 DO
  374.         DisplayLine(Lines[n]^, n-FirstOnScreen, TextColor);
  375.       END; 
  376.     END;
  377.   END Scroll;  
  378.  
  379. (* ------------------------------------------------------ *)
  380.  
  381.   PROCEDURE LoadFile(Name : STRING) : BOOLEAN;      (* ok *)
  382.   VAR
  383.     n : CARDINAL;
  384.     s : STRING;
  385.     c : CHAR; 
  386.   BEGIN
  387.     Lookup(TextFile, Name, TRUE);           (* neue Datei *)     
  388.     InitEmptyText;                          (* ok         *)
  389.     IF TextFile.eof THEN
  390.       RETURN FALSE;                         (* ok         *) 
  391.     ELSE
  392.       n       := 0;
  393.       MaxLine := 0; 
  394.       SaveInfoLine;
  395.       Concat(' Lade Datei ', Name, s);
  396.       DisplayLine(s, 24, InfoColor);
  397.       WHILE NOT TextFile.eof DO
  398.         s := '';
  399.         REPEAT
  400.           ReadChar(TextFile, c);    
  401.           IF c >= ' ' THEN Append(s, c); END;
  402.                            (* Steuercodes nicht aufnehmen *)
  403.         UNTIL (c = ASCII.EOL) OR TextFile.eof;    
  404.         GetNewLine; 
  405.         Lines[MaxLine]^ := s;
  406.       END;
  407.       Close(TextFile); 
  408.       RestoreInfoLine;
  409.       FirstOnScreen := 0;
  410.       TextLine      := 1;
  411.       TextCol       := 1; 
  412.       Scroll(0);  Goto(0, 0);
  413.       RETURN TRUE;
  414.     END;
  415.   END LoadFile;
  416.  
  417. (* ------------------------------------------------------- *)
  418.  
  419.   PROCEDURE F3Key;                                   (* ok *)
  420.   BEGIN
  421.     UpdateInfoLine;
  422.     GetFileName(NextFile, 'Datei laden: ');  
  423.     IF Length(NextFile) > 0 THEN
  424.       IF LoadFile(NextFile) THEN
  425.         FileName    := NextFile;
  426.         InfoMessage := FileName;
  427.         Modified    := FALSE;          
  428.         UpdateInfoLine;
  429.       ELSE
  430.         ShowError(1, FALSE);
  431.       END;
  432.     END;  
  433.   END F3Key;
  434.  
  435. (* ------------------------------------------------------ *)
  436.  
  437.   PROCEDURE SaveFile(Name : STRING) : BOOLEAN;      (* ok *)
  438.   VAR
  439.     Info   : STRING;
  440.     i, j   : CARDINAL;
  441.     Buffer : STRING; 
  442.   BEGIN
  443.     SaveInfoLine;
  444.     Info := ' Speichere Datei ';
  445.     Append(Info, Name);
  446.     Append(Info, '...');
  447.     DisplayLine(Info, 24, InfoColor);
  448.     Lookup(TextFile, Name, TRUE);     
  449.     Rewrite(TextFile); 
  450.     FOR i := 1 TO MaxLine DO
  451.       Buffer := Lines[i]^;
  452.       WriteNBytes(TextFile, ADR(Buffer), Length(Buffer), j);
  453.       IF j <> Length(Buffer) THEN
  454.         Close(TextFile);
  455.         RETURN FALSE;
  456.       END;  
  457.          (* Bis hier sind die Zeilenumbrüche verloren ... *)
  458.       WriteChar(TextFile, ASCII.CR);
  459.       WriteChar(TextFile, ASCII.LF);                (* ok *)
  460.     END;      
  461.     Close(TextFile);
  462.     RestoreInfoLine;  
  463.     Modified := FALSE;
  464.     RETURN TRUE;
  465.   END SaveFile;  
  466.  
  467. (* ------------------------------------------------------ *)
  468.  
  469.   PROCEDURE AltF2Key;                               (* ok *)
  470.   BEGIN
  471.     GetFileName(NextFile, ' Datei speichern als: ');
  472.     IF Length(NextFile) <> 0 THEN
  473.       FileName := NextFile;
  474.       IF NOT SaveFile(FileName) THEN 
  475.         ShowError(3, FALSE);
  476.       END;
  477.       InfoMessage := FileName;
  478.       UpdateInfoLine;
  479.     END;
  480.   END AltF2Key;   
  481.  
  482. (* ------------------------------------------------------ *)
  483. (*  geht unter FST Modula in die Hose ...                 *)
  484.  
  485.   PROCEDURE ReleaseLine;
  486.   BEGIN
  487.     DisposeStr(Lines[MaxLine]);
  488.     DEC(MaxLine);
  489.   END ReleaseLine;
  490.  
  491. (* ------------------------------------------------------ *)
  492.  
  493.   PROCEDURE DeleteLine(Line : CARDINAL);
  494.   VAR
  495.     i : CARDINAL;
  496.   BEGIN
  497.     IF MaxLine > 0 THEN 
  498.       FOR i := Line TO MaxLine - 1 DO
  499.         Lines[i] := Lines[i+1];
  500.       END;
  501.       (* ReleaseLine;  *)
  502.       (* Erstmal sehen, ob der Heap das verträgt ... *)
  503.     END;
  504.   END DeleteLine;
  505.  
  506. (* ------------------------------------------------------ *)
  507.  
  508.   PROCEDURE InsertLine(Line : CARDINAL);            (* ok *)
  509.   VAR
  510.     i    : CARDINAL;
  511.     Last : StrPtr;
  512.   BEGIN
  513.     GetNewLine;
  514.     Last := Lines[MaxLine];                   
  515.     FOR i := MaxLine-1 TO Line BY -1 DO
  516.       Lines[i+1] := Lines[i]; 
  517.     END;
  518.     Lines[Line]  := Last;
  519.     Lines[Line]^ := '';
  520.   END InsertLine;    
  521.  
  522. (* ------------------------------------------------------ *)
  523.  
  524.   PROCEDURE EnterKey;                               (* ok *)
  525.   VAR
  526.     s1, s2 : STRING;
  527.   BEGIN
  528.     IF InsertMode THEN
  529.       Copy(Lines[TextLine]^, 0, TextCol-1, s1);
  530.       Copy(Lines[TextLine]^, TextCol-1, 
  531.            Length(Lines[TextLine]^), s2);
  532.       InsertLine(TextLine);
  533.       Lines[TextLine]^   := s1;
  534.       Lines[TextLine+1]^ := s2;     
  535.       TextCol := 1;
  536.       IF TextLine - FirstOnScreen <= TextMaxY - 2 THEN
  537.         INC(TextLine);
  538.       END;
  539.       Scroll(0);
  540.     ELSE
  541.       IF TextLine < MaxLine THEN
  542.         TextCol := 1;
  543.         IF TextLine - FirstOnScreen > TextMaxY - 2 THEN
  544.           Scroll(1);
  545.         ELSE
  546.           INC(TextLine);
  547.         END;    
  548.       ELSE
  549.         GetNewLine;
  550.         Lines[MaxLine]^ := '';  
  551.       END;
  552.     END;
  553.   END EnterKey;  
  554.  
  555. (* ------------------------------------------------------ *)
  556.  
  557.   PROCEDURE EditLine(y : CARDINAL; x : CARDINAL; ch : CHAR);
  558.   BEGIN                                             (* ok *)
  559.     IF (ch > 31C) AND (ch < 377C) THEN        
  560.       IF InsertMode THEN
  561.         IF Length(Lines[y]^) < 80 THEN
  562.           Insert(ch, Lines[y]^, x-1);
  563.           INC(TextCol);
  564.         END;  
  565.       ELSE
  566.         Lines[y]^[x-1] := ch;
  567.         INC(TextCol);
  568.         IF TextCol > 80 THEN 
  569.           TextCol := 1;
  570.           INC(TextLine);
  571.         END;  
  572.       END;
  573.       Scroll(0);
  574.     END;
  575.   END EditLine;
  576.  
  577. (* ------------------------------------------------------ *)
  578.  
  579.   PROCEDURE DeleteKey;                              (* ok *)
  580.   VAR
  581.     L1, L2 : CARDINAL;
  582.     s      : STRING;
  583.   BEGIN
  584.     L1 := Length(Lines[TextLine]^);
  585.     IF TextLine + 1 <= MaxLine THEN
  586.       L2 := Length(Lines[TextLine + 1]^);
  587.     END;
  588.     IF TextCol < L1 THEN
  589.       Delete(Lines[TextLine]^, TextCol-1, 1);
  590.       Scroll(0);
  591.     ELSE
  592.       IF TextLine + 1 > MaxLine THEN RETURN; END;
  593.       IF L2 <= 80 - L1 THEN
  594.         Concat(Lines[TextLine]^, Lines[TextLine+1]^,
  595.                Lines[TextLine]^);
  596.         DeleteLine(TextLine+1);
  597.         Scroll(0);             
  598.       ELSE
  599.         Copy(Lines[TextLine+1]^, 0, 80-L1, s);
  600.         Concat(Lines[TextLine]^, s, Lines[TextLine]^);
  601.         Delete(Lines[TextLine+1]^, 1, 80-L1);
  602.         Scroll(0);  
  603.       END;
  604.     END;
  605.   END DeleteKey;
  606.   
  607. (* ------------------------------------------------------ *)
  608.  
  609.   PROCEDURE BSKey;                                  (* ok *)
  610.   VAR
  611.     L1, L0 : CARDINAL;
  612.     s      : STRING;
  613.   BEGIN
  614.     L1 := Length(Lines[TextLine]^);
  615.     IF TextLine > 1 THEN
  616.       L0 := Length(Lines[TextLine - 1]^);
  617.     END;
  618.     IF TextCol > 1 THEN
  619.       Delete(Lines[TextLine]^, TextCol-2, 1);       (* ok *)
  620.       DEC(TextCol);
  621.       Scroll(0);
  622.     ELSE
  623.       IF TextLine = 1 THEN RETURN; END;
  624.       IF L0 <= 80 - L1 THEN
  625.         TextCol := L0 + 1;
  626.         Concat(Lines[TextLine-1]^, Lines[TextLine]^, 
  627.                Lines[TextLine]^);
  628.         DEC(TextLine);
  629.         DeleteLine(TextLine);       (* hier ist jetzt noch ein kleiner bug *)
  630.         Scroll(0);       
  631.       ELSE
  632.         Copy(Lines[TextLine]^, 1, 80-L0, s);
  633.         Concat(Lines[TextLine-1]^, s, Lines[TextLine-1]^);
  634.         Delete(Lines[TextLine]^, 1, 80-L0);
  635.         Scroll(0);
  636.       END;
  637.     END;    
  638.   END BSKey;
  639.   
  640. (* ------------------------------------------------------ *)
  641. (*  Hauptsteuerleiste                                     *)
  642.  
  643.   PROCEDURE Edit;     
  644.   VAR
  645.     Done : BOOLEAN;  
  646.     c    : CHAR;
  647.   BEGIN
  648.     Done := FALSE;
  649.     REPEAT
  650.       UpdateInfoLine;
  651.       Goto(TextLine - FirstOnScreen, TextCol - 1);
  652.       GetKeyCh(c);     
  653.       CASE c OF
  654.         ASCII.esc      : ShowError(6, FALSE);   (* normal *)
  655.                          Done := TRUE;          (* ok     *)
  656.       | ASCII.cr       : EnterKey;              (* ok     *)
  657.                          Modified := TRUE;
  658.       | ASCII.bs       : BSKey;                 (* ok     *)
  659.                          Modified := TRUE; 
  660.       | ASCII.CtrlN    : InsertLine(TextLine);  (* ok     *)
  661.                          Modified := TRUE;
  662.                          Scroll(0);
  663.       | ASCII.CtrlY    : DeleteLine(TextLine);  (* ok     *)
  664.                          Modified := TRUE;
  665.                          Scroll(0);
  666.       | Keyboard.F1    : HelpScreen;            (* ok     *)
  667.       | Keyboard.F2    : IF NOT SaveFile(FileName) THEN
  668.                            ShowError(3, FALSE);
  669.                          END;                   (* ok     *)
  670.       | Keyboard.AF2   : AltF2Key;              (* ok     *)     
  671.       | Keyboard.F3    : F3Key;                 (* ok     *)
  672.       | Keyboard.AltX  : Done := SaveFile(FileName);
  673.       | Keyboard.Ins   : ToggleInsert;          (* ok     *)
  674.       | Keyboard.Del   : DeleteKey;             (* ok     *)
  675.       | Keyboard.Down  : IF TextLine < MaxLine THEN
  676.                            IF TextLine - FirstOnScreen > 
  677.                               TextMaxY - 2 THEN
  678.                              Scroll(1);
  679.                            ELSE
  680.                              INC(TextLine); 
  681.                            END;     
  682.                          END;                       (* ok *)
  683.       | Keyboard.Up    : IF TextLine > 1 THEN
  684.                            IF TextLine < 
  685.                               FirstOnScreen + 1 THEN  
  686.                              Scroll(-1);
  687.                            ELSE
  688.                              DEC(TextLine); 
  689.                            END;    
  690.                          END;                       (* ok *)
  691.       | Keyboard.Left  : IF TextCol >  1 THEN 
  692.                            DEC(TextCol); 
  693.                          END;                       (* ok *)
  694.       | Keyboard.Right : IF TextCol < 80 THEN 
  695.                            INC(TextCol); 
  696.                          END;                       (* ok *)
  697.       | Keyboard.Home  : TextCol := 1;              (* ok *)
  698.       | Keyboard.End   : TextCol := 
  699.                                  Length(Lines[TextLine]^)+1;  
  700.       | Keyboard.PgUp  : Scroll(1-TextMaxY);        (* ok *) 
  701.       | Keyboard.PgDn  : Scroll(TextMaxY-1);        (* ok *)
  702.       | Keyboard.CtrlEnd  : FirstOnScreen := 
  703.                                      MaxLine - TextMaxY + 1;
  704.                             TextLine      := MaxLine;  
  705.                             Scroll(0);              (* ok *)
  706.       | Keyboard.CtrlHome : TextLine      := 1;
  707.                             FirstOnScreen := 1;
  708.                             Scroll(0);              (* ok *)             
  709.       ELSE
  710.         Modified := TRUE;
  711.         EditLine(TextLine, TextCol, c);             (* ok *) 
  712.       END;  
  713.     UNTIL Done;
  714.     IF Modified THEN               (* wat mutt, dat mutt! *)
  715.       (* Zumindest fragen: "geänderte Datei speichern?"   *)
  716.     END;  
  717.   END Edit;
  718.  
  719. (* ------------------------------------------------------ *)
  720.  
  721. BEGIN
  722.   Init;
  723.   Edit; 
  724.   QuitProgram;  
  725. END ModEdit.  
  726.  
  727. (* ------------------------------------------------------ *)
  728. (*                  Ende von MODEDIT.MOD                  *)
  729.