home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / UTILITY / PATHEDIT.M < prev    next >
Encoding:
Text File  |  1990-06-25  |  43.4 KB  |  1,470 lines

  1.  
  2. (*                                 PathEdit
  3.  *                                 ========
  4.  *
  5.  *      Dieses Modul dient zum Editieren der aktuellen Pfadlisten.
  6.  *
  7.  *      -- Alle Menus können über Tastendruck und Mausklick bedient werden.
  8.  *      -- Beim Edieren kann durch <Help> ein Fenster geöffnet werden, das
  9.  *         einen Kurzbeschreibung enthält.
  10.  *      -- Die Maximallänge der Pfade wird durch die Konstante 'MaxLen'
  11.  *         bestimmt.
  12.  *      -- Werden neue Einträge zu einer Pfadliste hinzugefügt, so führt
  13.  *         dies dazu, daß Speicher vom Betriebssystem angefordert werden
  14.  *         muß, der oberhalb des Programmbereichs von 'PathEdit' liegen kann.
  15.  *         Dies führt dann zu einem häßlichen 'Speicherloch'!
  16.  *         Um dies zu umgehen, kann man an die Pfadliste im 'SHELL.INF'-
  17.  *         File 'leere' Einträge anhängen. Ein solcher Entrag besteht nur
  18.  *         aus einem '.'.
  19.  *
  20.  *----------------------------------------------------------------------------
  21.  *
  22.  *      Autor : Manuel Chakravarty      Erstellungsbeginn: 09.03.1988
  23.  *
  24.  *      System: MEGAMAX Modula-2 V 1.0  Interne Version : V#0209
  25.  *
  26.  *
  27.  * 01.04.88 | 1.0  MCH  | Erste veröffentlichte Version
  28.  * 15.04.88 | 1.1  TT   | Deutsche Texte; Default-Pfade auch bestimmbar;
  29.  *                        Bei F3 kein Address-Error, wenn Cursor auf EOL;
  30.  *                        Close-Klick bei CHWdw und EditWdw möglich.
  31.  *
  32.  *----------------------------------------------------------------------------
  33.  *)
  34.  
  35.  
  36. MODULE PathEdit;
  37. (*$R-*)
  38.  
  39. FROM SYSTEM IMPORT ADDRESS, ADR;
  40.  
  41. FROM Storage IMPORT ALLOCATE, SysAlloc, DEALLOCATE;
  42.  
  43. FROM Lists IMPORT LCarrier, List,
  44.                   ResetList, InsertEntry, RemoveEntry, AppendEntry,
  45.                   CurrentEntry, NextEntry, PrevEntry, NoOfEntries,
  46.                   SysCreateList, DeleteList, ListEmpty;
  47.  
  48. FROM PathCtrl IMPORT PathEntry, PathList;
  49.  
  50. FROM ShellMsg IMPORT StdPaths, DefPaths, ImpPaths, ModPaths, SymPaths, SrcPaths;
  51.  
  52. FROM Strings IMPORT String,
  53.                     Length, Assign, Delete, Append, Insert, Space, Upper;
  54.  
  55. FROM GrafBase IMPORT Point, Rectangle,
  56.                      Rect;
  57.  
  58. FROM GEMGlobals IMPORT GemChar, MButtonSet, SpecialKeySet, MouseButton;
  59.  
  60. FROM GEMEnv IMPORT RC, GemHandle, DeviceHandle,
  61.                    InitGem, CurrGemHandle, ExitGem;
  62.  
  63. FROM AESEvents IMPORT Event, RectEnterMode;
  64.  
  65. FROM AESForms IMPORT FormAlert;
  66.  
  67. FROM EventHandler IMPORT EventProc, HandleEvents;
  68.  
  69. FROM TextWindows IMPORT Window, ShowMode, ForceMode, WindowQuality,
  70.                         WQualitySet, DetectMode, DetectResult,
  71.                         Open, Close, WriteString, WriteLn, GotoXY, WritePg,
  72.                         Write, Read, CondRead, Show, Hide, DetectChar,
  73.                         WasClosed, GetPos;
  74.  
  75.  
  76. CONST   (* Auswahl der Sprache für die Texte *)
  77.         German          = TRUE;
  78.         English         = FALSE;
  79.  
  80.         MaxPaths        = 30;   (*  Maximale Anzahl von Pfaden pro Liste   *)
  81.         MaxLen          = 30;   (*  Maximale Pfadlänge (Siehe 'Paths' bzw.
  82.                                  *  Konstante 'pathSize' in 'MShell'.)
  83.                                  *)
  84.         LineOffset      = 3;
  85.  
  86. (*$? German:
  87.         EOLMsg          = '[Ende der Liste]';
  88. *)
  89. (*$? English:
  90.         EOLMsg          = '[End of list]';
  91. *)
  92.  
  93. TYPE    PtrPathList     = POINTER TO PathList;
  94.         PathsNoSet      = SET OF [0..MaxPaths - 1];
  95.         WindowRec       = RECORD
  96.                             used        : BOOLEAN;
  97.                             hdl         : Window;
  98.                             list        : PathList;
  99.                             marked      : PathsNoSet;
  100.                             org         : PtrPathList;
  101.                             changed     : BOOLEAN;
  102.                             headline    : String;
  103.                           END;
  104.         
  105. VAR     EditWdw, ShowWdw,
  106.         CHWdw           : WindowRec;
  107.         EventProcs      : ARRAY [1..2] OF EventProc;
  108.         
  109.         Dev             : DeviceHandle;
  110.         Gem             : GemHandle;
  111.         Quit            : BOOLEAN;
  112.         
  113.         VoidO, OK       : BOOLEAN;
  114.         VoidC           : CARDINAL;
  115.         VoidADR         : ADDRESS;
  116.         
  117.         
  118. (*  CursOn -- Erzeugt VT-52-Code für 'Cursor sichtbar machen'.
  119.  *)
  120.  
  121. PROCEDURE CursOn (hdl:Window);
  122.  
  123. BEGIN
  124.   Write (hdl, 33C); Write (hdl, 'e');
  125. END CursOn;
  126.         
  127. (*  CursOff -- Erzeugt VT-52-Code für 'Cursor unsichtbar machen'.
  128.  *)
  129.  
  130. PROCEDURE CursOff (hdl:Window);
  131.  
  132. BEGIN
  133.   Write (hdl, 33C); Write (hdl, 'f');
  134. END CursOff;
  135.         
  136. (*  ReverseOn -- Erzeugt VT-52-Code für 'Inverse Schrift'.
  137.  *)
  138.  
  139. PROCEDURE ReverseOn (hdl:Window);
  140.  
  141. BEGIN
  142.   Write (hdl, 33C); Write (hdl, 'p');
  143. END ReverseOn;
  144.         
  145. (*  ReverseOff -- Erzeugt VT-52-Code für 'Normale Schrift'.
  146.  *)
  147.  
  148. PROCEDURE ReverseOff (hdl:Window);
  149.  
  150. BEGIN
  151.   Write (hdl, 33C); Write (hdl, 'q');
  152. END ReverseOff;
  153.         
  154. PROCEDURE ClearEndOfLine (hdl:Window);
  155.  
  156. BEGIN
  157.   Write (hdl, 33C); Write (hdl, 'K'); (*  Clear end of line  *)
  158. END ClearEndOfLine;
  159.         
  160. (* SetListToElemNo -- Positioniert den Listenzeiger der Liste 'l' auf das
  161.  *                    'no'te Listenelement. Besitzt die Liste nicht genug
  162.  *                    Elemente so wird 'success = FALSE' geliefert, sonst
  163.  *                    'success = TRUE'. (Erste Elem. hat Pos. = 0)
  164.  *)
  165.  
  166. PROCEDURE SetListToElemNo (VAR l:PathList; no:CARDINAL; VAR success:BOOLEAN);
  167.  
  168. BEGIN
  169.   ResetList (l);
  170.   LOOP
  171.     success:=(NextEntry (l) # NIL);
  172.     IF ~ success OR (no = 0) THEN EXIT  (*  Schleifenaussprung!  *)
  173.     ELSE DEC (no) END;
  174.   END;
  175. END SetListToElemNo;
  176.  
  177. (*  InsertListIntoList -- Die List 'source' wird in die List 'dest' eingefügt.
  178.  *                        Dabei wird bei dem 'pos'ten Element von 'dest' mit
  179.  *                        dem Einfügen begonnen. (Erste Elem. hat Pos. = 0)
  180.  *                        Die Liste 'source' wird dabei gelöscht.
  181.  *)
  182.  
  183. PROCEDURE InsertListIntoList (VAR source, dest:PathList; pos:CARDINAL);
  184.  
  185. VAR     entry   : PathEntry;
  186.         success : BOOLEAN;
  187.  
  188. BEGIN
  189.   SetListToElemNo (dest, pos, success);
  190.   VoidADR:=PrevEntry (dest);
  191.   WHILE ~ ListEmpty (source) DO
  192.     ResetList (source);
  193.     entry:=NextEntry (source);
  194.     RemoveEntry (source, VoidO);
  195.     IF success THEN
  196.       InsertEntry (dest, entry, VoidO)
  197.     ELSE
  198.       AppendEntry (dest, entry, VoidO)
  199.     END;
  200.   END;
  201.   DeleteList (source, VoidO);
  202. END InsertListIntoList;
  203.  
  204. (*  EraseList -- Löscht eine vollständige List.
  205.  *)
  206.  
  207. PROCEDURE EraseList (VAR l:PathList);
  208.  
  209. VAR     err     : BOOLEAN;
  210.         entry   : PathEntry;
  211.  
  212. BEGIN
  213.   ResetList (l);
  214.   entry:=PrevEntry (l);
  215.   RemoveEntry (l, err);
  216.   WHILE ~ err DO
  217.     DISPOSE (entry);
  218.     entry:=CurrentEntry (l);
  219.     RemoveEntry (l, err);
  220.   END;
  221.   DeleteList (l, VoidO);
  222. END EraseList;
  223.  
  224. (*  CopyList -- Erzeugt eine Kopie der Liste 'l'. Die Kopie belegt einen
  225.  *              vollständig eigenen Speicherbereich. 'success = FALSE', falls
  226.  *              der benötigte Speicherplatz nicht alloc. werdewn konnte.
  227.  *)
  228.  
  229. PROCEDURE CopyList (VAR copy:PathList;l:PathList; VAR success:BOOLEAN);
  230.  
  231. VAR     entry, entry2   : PathEntry;
  232.  
  233. BEGIN
  234.   SysCreateList (copy, success); success:=~ success;
  235.   IF ~ success THEN RETURN END;
  236.   
  237.   ResetList (l);
  238.   entry:=NextEntry (l);
  239.   WHILE entry # NIL DO          (*  Für jedes Listenelement ein mal  *)
  240.   
  241.     SysAlloc (entry2, SIZE (entry2^));
  242.     IF entry2 = NIL THEN EraseList (copy); success:=FALSE; RETURN END;
  243.     Assign (entry^, entry2^, VoidO);
  244.     AppendEntry (copy, entry2, success); success:=~ success;
  245.     IF ~ success THEN DISPOSE (entry2); EraseList (copy); RETURN END;
  246.     entry:=NextEntry (l);
  247.     
  248.   END;
  249. END CopyList;
  250.  
  251. (*  WriteList -- Gibt die List 'wdw.list' in das Fenster 'wdw.hdl' aus.
  252.  *               Der Fensterinhalt wird vorher gelöscht und in die ersten
  253.  *               drei Zeilen wird die Überschrift 'wdw.headline' ausgegeben.
  254.  *)
  255.         
  256. PROCEDURE WriteList (wdw:WindowRec);
  257.  
  258.   (*  write0 -- Rekursive Proc., die alle Elemente der Liste 'l' untereinander
  259.    *            ausgibt, die zwischen dem aktuellen Listenelement und dem
  260.    *            Listenende liegen (inklusive).
  261.    *)
  262.  
  263.   PROCEDURE write0 (l:PathList);
  264.   
  265.   VAR   elem    : PathEntry;
  266.   
  267.   BEGIN
  268.     elem:=NextEntry (l);
  269.     IF elem # NIL THEN
  270.       WriteString (wdw.hdl, elem^); WriteLn (wdw.hdl);
  271.       write0 (l);
  272.     END;
  273.   END write0;
  274.   
  275. BEGIN
  276.   WITH wdw DO
  277.   
  278.     WritePg (hdl);              (*  Überschrift  *)
  279.     ReverseOn (hdl);
  280.     WriteLn (hdl); WriteString (hdl, headline); WriteLn (hdl); WriteLn (hdl);
  281.     ReverseOff (hdl);
  282.     
  283.     ResetList (list);
  284.     write0 (list);              (*  Liste  *)
  285.     
  286.     WriteString (hdl, EOLMsg);  (*  End of list message  *)
  287.     
  288.   END;
  289. END WriteList;
  290.  
  291. (*  CopyMarked -- Erzeugt eine Liste, die aus Kopien der markierten Elemente
  292.  *                von 'rec' besteht. Ist 'success = FALSE' so war nicht mehr
  293.  *                genug Speicher vorhanden.
  294.  *)
  295.  
  296. PROCEDURE CopyMarked (VAR list:PathList; rec:WindowRec; VAR success:BOOLEAN);
  297.  
  298. VAR     no      : CARDINAL;
  299.         entry,
  300.         entry2  : PathEntry;
  301.  
  302. BEGIN
  303.   SysCreateList (list, success); success:=~ success;
  304.   IF ~ success THEN RETURN END;
  305.   
  306.   ResetList (rec.list);
  307.   no:=0; entry:=NextEntry (rec.list);
  308.   WHILE entry # NIL DO
  309.   
  310.     IF no IN rec.marked THEN    (*  Markiert? => Kopieren  *)
  311.       SysAlloc (entry2, SIZE (entry^));
  312.       IF entry2 = NIL THEN EraseList (list); success:=FALSE; RETURN END;
  313.       Assign (entry^, entry2^, VoidO);
  314.       AppendEntry (list, entry2, success); success:=~ success;
  315.       IF ~ success THEN DISPOSE (entry2); EraseList (list); RETURN END;
  316.     END;
  317.     
  318.     INC (no); entry:=NextEntry (rec.list);
  319.     
  320.   END;
  321. END CopyMarked;
  322.  
  323. (*  OutOfMemory -- Meldet dem User, daß der Speicherplatz für diese Anwendung
  324.  *                 nicht ausreicht und leitet die Prgm.terminierung ein.
  325.  *)
  326.  
  327. PROCEDURE OutOfMemory;
  328.  
  329. BEGIN
  330.   (*$? German:
  331.     FormAlert(1, '[3][Kein Speicherplatz mehr !][ Ende ]', VoidC);
  332.   *)
  333.   (*$? English:
  334.     FormAlert(1, '[3][Out of memory!][ Quit ]', VoidC);
  335.   *)
  336.   Quit:=TRUE;
  337. END OutOfMemory;
  338.  
  339. (*  SetList -- Initialisiert das Window-RECORD 'wdw' derart, daß ihm die
  340.  *             Liste 'ptrl^' und die Überschrift 'headline' zugewiesen werden.
  341.  *             Ist 'backUp = TRUE', so wird eine Kopie der Orginalliste
  342.  *             erzeugt, so das es möglich ist die Liste zu edieren, ohne
  343.  *             gleich das Orginal zu zerstören.
  344.  *)
  345.  
  346. PROCEDURE SetList (VAR wdw:WindowRec;ptrl:PtrPathList;head:String;
  347.                    backUp:BOOLEAN);
  348.  
  349. BEGIN
  350.   WITH wdw DO
  351.     used:=TRUE;         (*  REC als benutzt markieren  *)
  352.     
  353.     IF backUp THEN
  354.     
  355.       (*  Liste kopieren  *)
  356.     
  357.       org:=ptrl;
  358.       CopyList (list, ptrl^, OK);
  359.       IF ~ OK THEN
  360.         OutOfMemory;
  361.         RETURN;
  362.       END;
  363.       
  364.     ELSE list:=ptrl^; END;
  365.     
  366.     changed:=FALSE;
  367.     headline:=head;
  368.     WriteList (wdw);    (*  Liste ins Fenster schreiben  *)
  369.     Show (hdl);         (*  und Fenster anzeigen  *)
  370.   END;
  371. END SetList;
  372.  
  373. (*  FreeWdw -- Die für den Ediervorgang erzeugt Listenkopie wird wieder frei-
  374.  *             gegeben. Vorher wird geprüft ob die Liste verändert wurde.
  375.  *             Falls ja, wird der Benutzer gefragt, ob er diese Änderungen
  376.  *             übernehmen möchte.
  377.  *             Ist dies der Fall, so wird die Orginalliste derart verändert,
  378.  *             das möglichst kein 'Speicherloch' entsteht.
  379.  *)
  380.  
  381. PROCEDURE FreeWdw (VAR wdw:WindowRec);
  382.  
  383. CONST   Yes     = 1;
  384.  
  385. VAR     but     : CARDINAL;
  386.         entry,
  387.         entry2  : PathEntry;
  388.  
  389. BEGIN
  390.   IF wdw.changed THEN
  391.     (*$? German:
  392.       FormAlert (Yes, '[2][Änderungen speichern ?][ Ja |Nein]', but);
  393.     *)
  394.     (*$? English:
  395.       FormAlert (Yes, '[2][Fix changed list ?][ Yes | No ]', but);
  396.     *)
  397.     IF but = Yes THEN
  398.     
  399.       (*  Orginalliste aktuallisieren:
  400.        *
  401.        *    Zuerst werden alle schon vorhandenene Elemente der Org.liste
  402.        *    auf den neusten Stand gebracht. Wird erst das Ende der Org.-
  403.        *    liste erreicht, so wird diese notgedrungen mit neu alloc.
  404.        *    Speicher erweitert (Pech!!?). Wird aber zuerst das Ende der
  405.        *    modifizierten Liste erreicht, so wird der überflüssige Teil
  406.        *    der Org.liste freigegeben.
  407.        *)
  408.     
  409.       ResetList (wdw.org^);             (*  Listen von Anfang an bearbeiten  *)
  410.       ResetList (wdw.list);
  411.       entry:=NextEntry (wdw.org^);      (*  Ersten Eintrag holen  *)
  412.       entry2:=NextEntry (wdw.list);
  413.       WHILE (entry # NIL) OR (entry2 # NIL) DO
  414.       
  415.         IF entry # NIL THEN
  416.           IF entry2 # NIL THEN
  417.             
  418.             (*  Beide Listen besitzen noch einen Eintrag => Zuweisung  *)
  419.             
  420.             Assign (entry2^, entry^, VoidO);
  421.             
  422.           ELSE
  423.           
  424.             (*  Orginalliste ist zu lang => Überflüssigen Speicherplatz frei-
  425.              *                              geben.
  426.              *)
  427.           
  428.             entry2:=PrevEntry (wdw.list);
  429.             RemoveEntry (wdw.org^, VoidO);
  430.             DISPOSE (entry);
  431.             
  432.           END;
  433.         ELSE
  434.         
  435.           (*  Orginalliste ist zu kurz => Neuen Eintrag an die Orginalliste
  436.            *                              anhängen. (Speicherloch!)
  437.            *)
  438.         
  439.           RemoveEntry (wdw.list, VoidO);
  440.           AppendEntry (wdw.org^, entry2, VoidO);
  441.           entry:=PrevEntry (wdw.org^);
  442.           
  443.         END;
  444.         
  445.         entry:=NextEntry (wdw.org^);    (*  Nächster Eintrag  *)
  446.         entry2:=NextEntry (wdw.list);
  447.       
  448.       END;
  449.       
  450.     END;
  451.   END;
  452.   EraseList (wdw.list);         (*  Listenkopie freigeben,  *)
  453.   Hide (wdw.hdl);               (*  Fenster vom Screen entfernen  *)
  454.   wdw.used:=FALSE;              (*  und als unbenutzt kennzeichnen  *)
  455. END FreeWdw;
  456.         
  457.  
  458. (*$J-*)
  459. FORWARD MainMenuKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  460.  
  461. FORWARD MainMenuButHdler (clicks:CARDINAL;loc:Point;
  462.                           buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  463. (*$J=*)
  464.  
  465. (*  SwitchToMainMenu -- Versetzt das Programm in einen Zustand, in dem es
  466.  *                      die Auswahl eines Eintrags aus dem Hauptmenu erwartet.
  467.  *)
  468.                      
  469. PROCEDURE SwitchToMainMenu;
  470.  
  471.   PROCEDURE wLn (str:ARRAY OF CHAR);
  472.   
  473.   BEGIN
  474.     WriteString (CHWdw.hdl, '            ');
  475.     WriteString (CHWdw.hdl, str); WriteLn (CHWdw.hdl);
  476.   END wLn;
  477.  
  478. BEGIN
  479.  
  480.   (*  Hauptmenu im COMMAND/HELP-Fenster anzeigen  *)
  481.   
  482.   WITH CHWdw DO
  483.     WritePg (hdl);
  484.     WriteLn (hdl); WriteLn (hdl);
  485.     (*$? German:
  486.       wLn ('1.....Default-Pfade');
  487.       wLn ('2.....DEF-Pfade');
  488.       wLn ('3.....IMP-Pfade');
  489.       wLn ('4.....MOD-Pfade');
  490.       wLn ('5.....Source-Pfade');
  491.       wLn ('6.....Symbol-Pfade');
  492.       WriteLn (hdl);
  493.       wLn ('0.....Ende'); WriteLn (hdl); WriteLn (hdl);
  494.       WriteString (hdl, '   Wähle Taste <0..6> oder mit Maus.');
  495.     *)
  496.     (*$? English:
  497.       wLn ('1.....Default Paths');
  498.       wLn ('2.....DEF Paths');
  499.       wLn ('3.....IMP Paths');
  500.       wLn ('4.....MOD Paths');
  501.       wLn ('5.....Source Paths');
  502.       wLn ('6.....Symbol Paths');
  503.       WriteLn (hdl);
  504.       wLn ('0.....Quit'); WriteLn (hdl); WriteLn (hdl);
  505.       WriteString (hdl, '   Select with <0..6> or with the mouse.');
  506.     *)
  507.     Show (hdl);
  508.     used:=TRUE;
  509.   END;
  510.   
  511.   (*  Diejenigen Proceduren zur Ereignissbehandlung festlegen, die die
  512.    *  Auswahl des Benutzers verarbeiten.
  513.    *)
  514.    
  515.   EventProcs[1].event:=keyboard;            (*  Proc. für Tastaturereignisse  *)
  516.   EventProcs[1].keyHdler:=MainMenuKeyHdler;
  517.   EventProcs[2].event:=mouseButton;
  518.   EventProcs[2].butHdler:=MainMenuButHdler; (*  Proc. für Mausknopfereignisse *)
  519. END SwitchToMainMenu;
  520.  
  521. (*$J-*)
  522. FORWARD EditKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  523.  
  524. FORWARD EditButHdler (clicks:CARDINAL;loc:Point;
  525.                       buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  526. (*$J=*)
  527.  
  528. (*  ShowHelp -- "Toggle" Fenster mit Hilfstext (Tastaturbelegung)
  529.  *)
  530.                           
  531. PROCEDURE ShowHelp;
  532.  
  533.   PROCEDURE wLn (str:ARRAY OF CHAR);
  534.   
  535.   BEGIN
  536.     WriteString (CHWdw.hdl, str); WriteLn (CHWdw.hdl);
  537.   END wLn;
  538.  
  539. BEGIN
  540.   WITH CHWdw DO
  541.     IF used THEN Hide (hdl); used:=FALSE;  (*  Fenster entfernen  *)
  542.     ELSE
  543.       
  544.       (*  Hilfstext ins COMMAND/HELP-Fenster schreiben  *)
  545.       
  546.       WritePg (hdl);
  547.       ReverseOn (hdl);
  548.       (*$? German:
  549.         wLn (' Bedienungshilfe'); WriteLn (hdl);
  550.         ReverseOff (hdl);
  551.         wLn ('-- Maus o. Cursortasten zum Positionieren,');
  552.         wLn ('   Maus wählt Pfade, wenn im Kopiermodus.');
  553.         wLn ('-- <Backspace> u. <Delete> löschen Zeichen');
  554.         wLn ('-- <Insert> fügt Leerzeichen ein.');
  555.         wLn ('-- <Clr> entfernt ganze Liste.');
  556.         wLn ('-- <F1> zum Kopieren anderer Listen');
  557.         wLn ('        (Wählt Pfade im Kopiermodus)');
  558.         wLn ('-- <F2> fügt eine Zeile ein.');
  559.         wLn ('-- <F3> löscht aktuelle Zeile.');
  560.         wLn (' + <Shift> entfernt die Zeile.');
  561.         wLn ('-- <F10> beendet die Eingabe.');
  562.       *)
  563.       (*$? English:
  564.         wLn (' Help-Table'); WriteLn (hdl);
  565.         ReverseOff (hdl);
  566.         wLn ('-- Mouse or cursor-keys to move the cursor');
  567.         wLn ('   Mouse selects paths while in copy-mode');
  568.         wLn ('-- <Backspace> and <Delete> to delete char');
  569.         wLn ('-- <Insert> to insert one blank');
  570.         wLn ('-- <Clr> to erase entire list');
  571.         wLn ('-- <F1> to copy from another list');
  572.         wLn ('        (Selects paths while in copy-mode)');
  573.         wLn ('-- <F2> to insert one line');
  574.         wLn ('-- <F3> to clear the current line');
  575.         wLn (' + <Shift> to delete the current line');
  576.         wLn ('-- <F10> to leave edit mode');
  577.       *)
  578.       
  579.       Show (CHWdw.hdl);         (*  Fenster anzeigen  *)
  580.       used:=TRUE;
  581.       
  582.     END;
  583.   END;
  584. END ShowHelp;
  585.  
  586. (*  PosEdCurs -- Positioniert den Cursor im Edit-Fenster. Dabei wird darauf
  587.  *               geachtet, daß sich der Cursor immer im Bereich der ange-
  588.  *               zeigten Pfade befindet.
  589.  *)
  590.  
  591. PROCEDURE PosEdCurs (col,row:CARDINAL);
  592.  
  593. VAR     r, no           : INTEGER;
  594.         oldCol, oldRow,
  595.         l               : CARDINAL;
  596.         success         : BOOLEAN;
  597.         entry           : PathEntry;
  598.  
  599. BEGIN
  600.   WITH EditWdw DO
  601.   
  602.     r:=INTEGER (row) - LineOffset;
  603.     IF r < 0 THEN r:=0 END;               (*  Begrenzung nach oben  *)
  604.     no:=NoOfEntries (list);
  605.     IF r > no THEN r:=no END;             (*  Begrenzung nach unten  *)
  606.     SetListToElemNo (list, r, success);
  607.     IF success THEN                       (*  Begrenzung horizontal  *)
  608.       entry:=CurrentEntry (list);
  609.       l:=Length (entry^);
  610.       IF col > l THEN col:=l END;
  611.     ELSE col:=0 END;
  612.     row:=CARDINAL (r) + LineOffset;
  613.     
  614.     (*  Die Cursorposition wird nur verändert, falls sich der Cursor noch
  615.      *  nicht an der gewünschten Position befindet (Verhindert unötiges
  616.      *  Geflimmer).
  617.      *)
  618.   
  619.     GetPos (hdl, oldCol, oldRow);
  620.     IF (oldRow # CARDINAL (row)) OR (oldCol # col) THEN
  621.       GotoXY (hdl, col, row)
  622.     END;
  623.     
  624.   END;
  625. END PosEdCurs;
  626.  
  627. (*  SwitchToEdit -- Versetzt das Programm in einen Zustand, in dem es auf
  628.  *                  Befehle zum Edieren, der Pfade im Edit-Fenster wartet.
  629.  *                  Ist die übergebene Liste 'ptrlist^' nicht richtig init.,
  630.  *                  wird ein Alert ausgelöst und 'success =FALSE' geliefert.
  631.  *)
  632.  
  633. PROCEDURE SwitchToEdit (ptrlist:PtrPathList; name:String; VAR success:BOOLEAN);
  634.  
  635. BEGIN
  636.  
  637.   (*  Überprüfen ob Liste korrekt init. ist.  *)
  638.  
  639.   success:=(ptrlist^.root # LCarrier (NIL));
  640.   IF ~ success THEN
  641.     (*$? English:
  642.       FormAlert (1,'[3][List is not initialized!][ Abort ]', VoidC);
  643.     *)
  644.     (*$? German:
  645.       FormAlert (1,'[3][Liste ist nicht initialisiert!][ Abbruch ]', VoidC);
  646.     *)
  647.     RETURN
  648.   END;
  649.  
  650.   (*  Edit-Fenster init., Cursor positionieren und sichtbar machen  *)
  651.   
  652.   SetList (EditWdw, ptrlist, name, TRUE); IF Quit THEN RETURN END;
  653.   PosEdCurs (0,LineOffset);
  654.   CursOn (EditWdw.hdl);
  655.   
  656.   (*  Ereignissverarbeitende Proc.s einsetzen, die Edierkommandos entgegen-
  657.    *  nehmen.
  658.    *)
  659.    
  660.   EventProcs[1].event:=keyboard;
  661.   EventProcs[1].keyHdler:=EditKeyHdler;
  662.   EventProcs[2].event:=mouseButton;
  663.   EventProcs[2].butHdler:=EditButHdler;
  664. END SwitchToEdit;
  665.  
  666. (*$J-*)
  667. FORWARD CopyKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  668.  
  669. FORWARD CopyButHdler (clicks:CARDINAL;loc:Point;
  670.                       buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  671. (*$J=*)
  672.  
  673. (*  RestoreNormalEdit -- Schaltet vom Kopiermodus auf den normalen Ediermodus
  674.  *                       zurück.
  675.  *)
  676.                           
  677. PROCEDURE RestoreNormalEdit;
  678.  
  679. VAR     list    : PathList;
  680.         col,row : CARDINAL;
  681.  
  682. BEGIN
  683.  
  684.   (*  Markierte Listenelemente in die Liste im Edit-Fenster kopieren  *)
  685.   
  686.   CopyMarked (list, ShowWdw, OK);
  687.   IF ~ OK THEN OutOfMemory
  688.   ELSE
  689.     GetPos (EditWdw.hdl, col, row);
  690.     IF ~ ListEmpty (list) THEN EditWdw.changed:=TRUE END;
  691.     InsertListIntoList (list, EditWdw.list, row - 3)
  692.   END;
  693.   
  694.   (*  Veränderte Liste anzeigen, Cursor positionieren und sichtbar machen  *)
  695.   
  696.   WriteList (EditWdw);
  697.   PosEdCurs (col,row);
  698.   CursOn (EditWdw.hdl);
  699.   
  700.   (*  Proc.s einhängen, die die Edierkommandos entgegen nehmen  *)
  701.   
  702.   EventProcs[1].event:=keyboard;
  703.   EventProcs[1].keyHdler:=EditKeyHdler;
  704.   EventProcs[2].event:=mouseButton;
  705.   EventProcs[2].butHdler:=EditButHdler;
  706. END RestoreNormalEdit;
  707.  
  708. (*  PosShowCurs -- Positioniert den Cursor im Kopierfenster (Zeilenweise).
  709.  *)
  710.  
  711. PROCEDURE PosShowCurs (row:CARDINAL);
  712.  
  713. VAR     r       : CARDINAL;
  714.         rg      : INTEGER;
  715.  
  716. BEGIN
  717.  
  718.   (*  Positionierbereich des Cursors wird auf den Anzeigebereich der Pfade
  719.    *  beschränkt.
  720.    *)
  721.    
  722.   rg:=INTEGER (row) - 3;
  723.   IF rg < 0 THEN rg:=0 END;
  724.   r:=NoOfEntries (ShowWdw.list);
  725.   IF rg > INTEGER (r) THEN rg:=INTEGER (r) END;
  726.   row:=CARDINAL (rg + 3);
  727.   
  728.   (*  Pos. nur verändern, wenn neue Pos. ungleich alter Pos. ist  *)
  729.   
  730.   GetPos (ShowWdw.hdl, VoidC,r);
  731.   IF r # row THEN GotoXY (ShowWdw.hdl, 0,row) END;
  732. END PosShowCurs;
  733.  
  734. (*  SelectCopyPath -- Ein Pfad im Kopierfenster wurde angewählt (F1 oder
  735.  *                    angeklickt). Sein Status, markiert oder nicht, wird
  736.  *                    in dieser Proc. umgeschaltet.
  737.  *)
  738.  
  739. PROCEDURE SelectCopyPath (row:CARDINAL);
  740.  
  741. VAR     no              : CARDINAL;
  742.         entry           : PathEntry;
  743.         success         : BOOLEAN;
  744.         
  745.   (*  reWrite -- Der aktuelle Eintrag ('entry') wird ins Fenster geschrieben.
  746.    *             Ist 'reverse = TRUE', so wird er invertiert dargestellt,
  747.    *             sonst normal.
  748.    *)
  749.  
  750.   PROCEDURE reWrite (reverse:BOOLEAN);
  751.  
  752.   BEGIN
  753.     WITH ShowWdw DO
  754.       IF reverse THEN ReverseOn (hdl) END;
  755.       GotoXY (hdl, 0,row);
  756.       WriteString (hdl, entry^);
  757.       ClearEndOfLine (hdl);
  758.       GotoXY (hdl, 0,row);
  759.       IF reverse THEN ReverseOff (hdl) END;
  760.     END;
  761.   END reWrite;
  762.   
  763.   (*  getEntry -- Ermittelt aktuellen ('no'ten) Eintrag.
  764.    *)
  765.   
  766.   PROCEDURE getEntry;
  767.   
  768.   BEGIN
  769.     SetListToElemNo (ShowWdw.list, no, success);
  770.     entry:=CurrentEntry (ShowWdw.list);
  771.   END getEntry;
  772.   
  773. BEGIN
  774.   no:=row - 3;
  775.   getEntry;
  776.   IF success THEN WITH ShowWdw DO
  777.   
  778.     (*  Toggle State  *)
  779.     
  780.     IF no IN marked THEN EXCL (marked, no) ELSE INCL (marked, no) END;
  781.     
  782.     reWrite (no IN marked);  (*  and write Path (invers or normal)  *)
  783.     
  784.   END END;
  785. END SelectCopyPath;
  786.  
  787. (*  StartCopyMode -- Leitet den Kopiermodus ein.
  788.  *)
  789.  
  790. PROCEDURE StartCopyMode;
  791.  
  792. BEGIN
  793.  
  794.   (*  Liste und Cursor anzeigen  *)
  795.   
  796.   WriteList (ShowWdw);
  797.   PosShowCurs (3);
  798.   CursOn (ShowWdw.hdl);
  799.   
  800.   (*  Proc.s setzen, die die Auswahlbefehle des Kopiermodus akzeptieren  *)
  801.   
  802.   EventProcs[1].event:=keyboard;
  803.   EventProcs[1].keyHdler:=CopyKeyHdler;
  804.   EventProcs[2].event:=mouseButton;
  805.   EventProcs[2].butHdler:=CopyButHdler;
  806. END StartCopyMode;
  807.  
  808.  
  809. (*$J-*)
  810. FORWARD CSelKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  811.  
  812. FORWARD CSelButHdler (clicks:CARDINAL;loc:Point;
  813.                       buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  814. (*$J=*)
  815.                       
  816. (*  SwitchToCopy -- Initalisiert den Kopiermodus, indem die Liste erfragt
  817.  *                  wird, aus der kopiert werden soll.
  818.  *)
  819.                           
  820. PROCEDURE SwitchToCopy;
  821.  
  822.   PROCEDURE wLn (str:ARRAY OF CHAR);
  823.   
  824.   BEGIN
  825.     WriteString (ShowWdw.hdl, Space ((MaxLen - 18) DIV 2));
  826.     WriteString (ShowWdw.hdl, str); WriteLn (ShowWdw.hdl);
  827.   END wLn;
  828.  
  829. BEGIN
  830.  
  831.   (*  Listenauswahl-Menu anzeigen  *)
  832.   
  833.   WITH ShowWdw DO
  834.     WritePg (hdl);
  835.     WriteLn (hdl);
  836.     (*$? German:
  837.       wLn ('    Kopiere von'); WriteLn (hdl);
  838.       wLn ('1.....Default-Pfaden');
  839.       wLn ('2.....DEF-Pfaden');
  840.       wLn ('3.....IMP-Pfaden');
  841.       wLn ('4.....MOD-Pfaden');
  842.       wLn ('5.....Source-Pfaden');
  843.       wLn ('6.....Symbol-Pfaden');
  844.       WriteLn (hdl); WriteLn (hdl);
  845.       wLn ('Wähle Taste <1..6>');
  846.       wLn ('oder wähle mit Maus.');
  847.     *)
  848.     (*$? English:
  849.       wLn ('    Copy from'); WriteLn (hdl);
  850.       wLn ('1.....Default Paths');
  851.       wLn ('2.....DEF Paths');
  852.       wLn ('3.....IMP Paths');
  853.       wLn ('4.....MOD Paths');
  854.       wLn ('5.....Source Paths');
  855.       wLn ('6.....Symbol Paths');
  856.       WriteLn (hdl); WriteLn (hdl);
  857.       wLn ('Select with <1..6>');
  858.       wLn ('or with the mouse.');
  859.     *)
  860.     Show (hdl);
  861.     used:=TRUE;
  862.     marked:=PathsNoSet {};
  863.   END;
  864.   
  865.   (*  Proc.s einsetzen, die eine Auswahl aus dem Listenauswahl-Menu ver-
  866.    *  arbeiten.
  867.    *)
  868.   
  869.   EventProcs[1].event:=keyboard;
  870.   EventProcs[1].keyHdler:=CSelKeyHdler;
  871.   EventProcs[2].event:=mouseButton;
  872.   EventProcs[2].butHdler:=CSelButHdler;
  873. END SwitchToCopy;
  874.  
  875. TYPE    MainCommand     = (quit, edDft, edDef, edImp, edMod, edSrc, edSym);
  876.  
  877. (*  DoMainCommand -- Führt eine Befehl aus dem Hauptmenu aus.
  878.  *)
  879.  
  880. PROCEDURE DoMainCommand (cmd:MainCommand);
  881.  
  882. VAR     success : BOOLEAN;
  883.  
  884. BEGIN
  885.   CASE cmd OF
  886.   
  887.     quit        : Quit:=TRUE|   (*  Prgm.terminierung einleiten  *)
  888.     
  889.     (*  Edieren einer Pfadliste einleiten  *)
  890.     
  891.     (*$? German:
  892.       edDft: SwitchToEdit (ADR (StdPaths), ' Default-Pfade ', success)|
  893.       edDef: SwitchToEdit (ADR (DefPaths), ' Definitions-Pfade ', success)|
  894.       edImp: SwitchToEdit (ADR (ImpPaths), ' Implementations-Pfade ', success)|
  895.       edMod: SwitchToEdit (ADR (ModPaths), ' Hauptmodul-Pfade ', success)|
  896.       edSrc: SwitchToEdit (ADR (SrcPaths), ' Source-Pfade ', success)|
  897.       edSym: SwitchToEdit (ADR (SymPaths), ' Symbol-Pfade ', success)|
  898.     *)
  899.     (*$? English:
  900.       edDft: SwitchToEdit (ADR (StdPaths), ' Default Paths ', success)|
  901.       edDef: SwitchToEdit (ADR (DefPaths), ' Definition Paths ', success)|
  902.       edImp: SwitchToEdit (ADR (ImpPaths), ' Implementation Paths ', success)|
  903.       edMod: SwitchToEdit (ADR (ModPaths), ' Main Module Paths ', success)|
  904.       edSrc: SwitchToEdit (ADR (SrcPaths), ' Source Paths ', success)|
  905.       edSym: SwitchToEdit (ADR (SymPaths), ' Symbol Paths ', success)|
  906.     *)
  907.   END;
  908.   
  909.   IF success THEN
  910.     Hide (CHWdw.hdl);  (*  Hauptmenufenster deaktivieren  *)
  911.     CHWdw.used:=FALSE;
  912.   END;
  913. END DoMainCommand;
  914.  
  915. TYPE    CopyListCmd = (copyDft, copyDef, copyImp, copyMod, copySrc, copySym);
  916.  
  917. (*  SetCopyList -- Bearbeitet eine Auswahl aus dem Listenauswahl-Menu.
  918.  *)
  919.  
  920. PROCEDURE SetCopyList (cmd:CopyListCmd);
  921.  
  922.   PROCEDURE set0 (l:PathList; name:ARRAY OF CHAR);
  923.   
  924.   BEGIN
  925.     ShowWdw.list:=l;
  926.     Assign (name, ShowWdw.headline, VoidO);
  927.   END set0;
  928.  
  929. BEGIN
  930.   CASE cmd OF   (*  Entsprechende Liste wird gesetzt  *)
  931.   
  932.     (*$? German:
  933.       copyDft     : set0 (StdPaths, ' Default-Pfade ')|
  934.       copyDef     : set0 (DefPaths, ' Definitions-Pfade ')|
  935.       copyImp     : set0 (ImpPaths, ' Implementations-Pfade ')|
  936.       copyMod     : set0 (ModPaths, ' Hauptmodul-Pfade ')|
  937.       copySrc     : set0 (SrcPaths, ' Source-Pfade ')|
  938.       copySym     : set0 (SymPaths, ' Symbol-Pfade ')|
  939.     *)
  940.     (*$? English:
  941.       copyDft     : set0 (StdPaths, ' Default Paths ')|
  942.       copyDef     : set0 (DefPaths, ' Definition Paths ')|
  943.       copyImp     : set0 (ImpPaths, ' Implementation Paths ')|
  944.       copyMod     : set0 (ModPaths, ' Main Module Paths ')|
  945.       copySrc     : set0 (SrcPaths, ' Source Paths ')|
  946.       copySym     : set0 (SymPaths, ' Symbol Paths ')|
  947.     *)
  948.     
  949.   END;
  950.   
  951.   StartCopyMode;  (*  und der Kopiermodus eingeleitet  *)
  952. END SetCopyList;
  953.  
  954.  
  955. (*  MainMenuKeyHdler -- Akzeptiert die Tastaturereignisse, während der Aus-
  956.  *                      wahl aus dem Hauptmenu.
  957.  *)
  958.  
  959. PROCEDURE MainMenuKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  960.  
  961. BEGIN
  962.   CASE ch.ascii OF
  963.     '0' : DoMainCommand (quit)|
  964.     '1' : DoMainCommand (edDft)|
  965.     '2' : DoMainCommand (edDef)|
  966.     '3' : DoMainCommand (edImp)|
  967.     '4' : DoMainCommand (edMod)|
  968.     '5' : DoMainCommand (edSrc)|
  969.     '6' : DoMainCommand (edSym)|
  970.   ELSE
  971.   END;
  972.   RETURN FALSE;
  973. END MainMenuKeyHdler;
  974.  
  975. (*  MainMenuButHdler -- Akzeptiert die Mausknopfereignisse, während der Aus-
  976.  *                      wahl aus dem Hauptmenu.
  977.  *)
  978.  
  979. PROCEDURE MainMenuButHdler (clicks:CARDINAL;loc:Point;
  980.                             buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  981.                             
  982. VAR     p       : Point;
  983.         hdl     : Window;
  984.         col, row: CARDINAL;
  985.         box     : Rectangle;
  986.         result  : DetectResult;
  987.                      
  988. BEGIN
  989.   p:=loc;
  990.   DetectChar (CHWdw.hdl,0, takePnt,p,
  991.               hdl, col,row, box, result);
  992.   IF result = foundChar THEN
  993.     CASE row OF
  994.       9   : DoMainCommand (quit)|
  995.       2   : DoMainCommand (edDft)|
  996.       3   : DoMainCommand (edDef)|
  997.       4   : DoMainCommand (edImp)|
  998.       5   : DoMainCommand (edMod)|
  999.       6   : DoMainCommand (edSrc)|
  1000.       7   : DoMainCommand (edSym)|
  1001.     ELSE
  1002.     END;
  1003.   END;
  1004.   RETURN FALSE;
  1005. END MainMenuButHdler;
  1006.  
  1007.  
  1008. (*  EditKeyHdler -- Akzeptiert die Tastaturereignisse während des Ediermodus.
  1009.  *)
  1010.  
  1011. PROCEDURE EditKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  1012.  
  1013. CONST   backspace       = 14;   (*  Liste alle Scancodes für Sonderfunktionen *)
  1014.         return          = 28;
  1015.         f1              = 59;
  1016.         f2              = 60;
  1017.         f3              = 61;
  1018.         f10             = 68;
  1019.         shiftf3         = 86;
  1020.         clr             = 71;
  1021.         up              = 72;
  1022.         left            = 75;
  1023.         right           = 77;
  1024.         down            = 80;
  1025.         insert          = 82;
  1026.         delete          = 83;
  1027.         help            = 98;
  1028.         
  1029. VAR     col, row        : CARDINAL;
  1030.         entry           : PathEntry;
  1031.         success         : BOOLEAN;
  1032.         
  1033.   (*  move -- Bewegt den Cursor um 'c' Spalten und 'r' Zeilen.
  1034.    *)
  1035.  
  1036.   PROCEDURE move (c,r:INTEGER);
  1037.  
  1038.   BEGIN
  1039.     IF (INTEGER (col) + c) >= 0 THEN col:=INTEGER (col) + c
  1040.     ELSE
  1041.       col:=MaxLen;
  1042.       r:=r - 1;
  1043.     END;
  1044.     IF (INTEGER (row) + r) >= 0 THEN row:=INTEGER (row) + r END;
  1045.   END move;
  1046.   
  1047.   (*  reWrite -- Schreibt den aktuellen Eintrag in das Fenster.
  1048.    *)
  1049.   
  1050.   PROCEDURE reWrite;
  1051.  
  1052.   BEGIN
  1053.     WITH EditWdw DO
  1054.       GotoXY (hdl, 0, row);
  1055.       WriteString (hdl, entry^);
  1056.       Write (hdl, 33C); Write (hdl, 'K'); (*  Clear end of line  *)
  1057.       GotoXY (hdl, col,row);
  1058.     END;
  1059.   END reWrite;
  1060.   
  1061.   (*  getEntry -- Ermittelt den aktuellen ('no'ten) Eintrag.
  1062.    *              Ergebniss in 'entry', außerdem ist der aktuellen Eintrag
  1063.    *              in dem Listen-Carrier entsprechend gesetzt.
  1064.    *              'success = FALSE', falls der Eintrag nicht existiert.
  1065.    *)
  1066.   
  1067.   PROCEDURE getEntry;
  1068.   
  1069.   BEGIN
  1070.     SetListToElemNo (EditWdw.list, row - 3, success);
  1071.     entry:=CurrentEntry (EditWdw.list);
  1072.   END getEntry;
  1073.   
  1074.   (*  writeHole -- Schreibt die komplette Liste erneut in das Fesnter.
  1075.    *)
  1076.   
  1077.   PROCEDURE writeHole;
  1078.   
  1079.   BEGIN
  1080.     WriteList (EditWdw);
  1081.   END writeHole;
  1082.   
  1083.   
  1084. VAR     err     : BOOLEAN;
  1085.         l       : CARDINAL;
  1086.   
  1087. BEGIN
  1088.  
  1089.   (*  Cursorposition ermitteln und Cursor verstecken  *)
  1090.   
  1091.   GetPos (EditWdw.hdl, col,row);
  1092.   CursOff (EditWdw.hdl);
  1093.   
  1094.   CASE ORD (ch.scan) OF     (*  Sondertasten auswerten  *)
  1095.   
  1096.     f10         : Hide (EditWdw.hdl); FreeWdw (EditWdw);
  1097.                   SwitchToMainMenu; RETURN FALSE|       (*  Edieren beenden  *)
  1098.  
  1099.     help        : ShowHelp|             (*  Hilfstext anzeigen  *)
  1100.  
  1101.     up          : move (0,-1)|          (*  Cursor eine Zeile nach oben  *)
  1102.     left        : move (-1,0)|          (*  Cursor eine Spalte nach links  *)
  1103.     right       : move (1,0)|           (*  Cursor eine Spalte nach rechts *)
  1104.     down        : move (0,1)|           (*  Cursor eine Zeile nach unten  *)
  1105.     return      : col:=0; move (0,1)|   (*  Unten + Zeilenanfang  *)
  1106.     
  1107.     backspace   : getEntry;             (*  Del. char left from Curs.  *)
  1108.                   IF success AND (col # 0) THEN
  1109.                     col:=col - 1;
  1110.                     Delete (entry^, col,1, VoidO);
  1111.                     reWrite;
  1112.                     EditWdw.changed:=TRUE;
  1113.                   END|
  1114.     delete      : getEntry;             (*  Del. char at Curs.pos  *)
  1115.                   IF success THEN
  1116.                     Delete (entry^, col,1, VoidO);
  1117.                     reWrite;
  1118.                     EditWdw.changed:=TRUE;
  1119.                   END|
  1120.     insert      : getEntry;             (* Starting from Curs.pos, shift right*)
  1121.                   IF success THEN
  1122.                     IF Length (entry^) < MaxLen THEN
  1123.                       Insert (' ', col, entry^, VoidO);
  1124.                       reWrite;
  1125.                       EditWdw.changed:=TRUE;
  1126.                     END;
  1127.                   END|
  1128.                   
  1129.     clr         : EraseList (EditWdw.list);  (*  Lösche die gesamte Liste  *)
  1130.                   SysCreateList (EditWdw.list, VoidO);
  1131.                   writeHole;
  1132.                   EditWdw.changed:=TRUE|
  1133.     
  1134.     f1          : SwitchToCopy|         (*  Kopiere von anderer Liste  *)
  1135.     f2          : getEntry;             (*  Insert one line before curr. line *)
  1136.                   SysAlloc (entry, SIZE (entry^));
  1137.                   IF entry = NIL THEN OutOfMemory; RETURN FALSE END;
  1138.                   entry^:='';
  1139.                   VoidADR:=PrevEntry (EditWdw.list);
  1140.                   InsertEntry (EditWdw.list, entry, err);
  1141.                   IF err THEN OutOfMemory; DISPOSE (entry); RETURN FALSE END;
  1142.                   writeHole;
  1143.                   EditWdw.changed:=TRUE|
  1144.     f3          : getEntry;             (*  Erase contents of curr. line  *)
  1145.                   IF success THEN
  1146.                     entry^:='';
  1147.                     reWrite;
  1148.                     EditWdw.changed:=TRUE
  1149.                   END|
  1150.     shiftf3     : getEntry;             (*  Delete curr. entry  *)
  1151.                   IF success THEN
  1152.                     RemoveEntry (EditWdw.list, VoidO);
  1153.                     DISPOSE (entry);
  1154.                     writeHole;
  1155.                     EditWdw.changed:=TRUE
  1156.                   END|
  1157.  
  1158.   ELSE
  1159.   
  1160.     WITH EditWdw DO
  1161.       IF (ch.ascii >= ' ') AND (ORD (ch.ascii) < 128) THEN
  1162.       
  1163.         (*  Verarbeite Tastendrücke im Bereich der sichtbaren Zeichen  *)
  1164.         
  1165.         getEntry;       (*  Ermittle aktuellen Eintrag  *)
  1166.         
  1167.         IF ~ success THEN   (*  Ex. nicht => Neuen Eintrag anfügen  *)
  1168.         
  1169.           SysAlloc (entry, SIZE (entry^));      (*  Alloc.  *)
  1170.           IF entry = NIL THEN
  1171.             OutOfMemory; RETURN FALSE
  1172.           END;
  1173.           entry^:='';                           (*  Löschen und anfügen  *)
  1174.           AppendEntry (list, entry, success); success:=~ success;
  1175.           IF ~ success THEN
  1176.             DISPOSE (entry);
  1177.             OutOfMemory;
  1178.             RETURN FALSE
  1179.           END;
  1180.           ClearEndOfLine (hdl);;                (*  Darstellen  *)
  1181.           GotoXY (hdl, col, row + 1);
  1182.           WriteString (hdl, EOLMsg);
  1183.           GotoXY (hdl, col, row);
  1184.           
  1185.         END;
  1186.         
  1187.         Upper (ch.ascii);   (*  Nur Großbuchstaben in Pfadlisten  *)
  1188.         l:=Length (entry^);
  1189.         IF col < l THEN
  1190.           entry^[col]:=ch.ascii                 (*  Überschreiben  *)
  1191.         ELSE
  1192.           Append (ch.ascii, entry^, VoidO)      (*  oder anhängen  *)
  1193.         END;
  1194.         Write (hdl, ch.ascii);                  (*  Zeichen darstellen  *)
  1195.         IF col < (MaxLen - 1) THEN INC (col) END;
  1196.         changed:=TRUE;
  1197.         
  1198.       END;
  1199.     END;
  1200.   
  1201.   END;
  1202.   
  1203.   (*  Neue Cursorpos. setzen und Cursor sichtbar machen  *)
  1204.   
  1205.   PosEdCurs (col,row);
  1206.   IF (CARDINAL (LONG (ch.scan)) # f1) THEN CursOn (EditWdw.hdl) END;
  1207.   
  1208.   RETURN FALSE;
  1209. END EditKeyHdler;
  1210.  
  1211. (*  EditButHdler -- Akzeptiert die Mausknopfereignisse während des Ediermodus.
  1212.  *)
  1213.  
  1214. PROCEDURE EditButHdler (clicks:CARDINAL;loc:Point;
  1215.                         buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  1216.                      
  1217. VAR     p               : Point;
  1218.         hdl             : Window;
  1219.         col, row        : CARDINAL;
  1220.         box             : Rectangle;
  1221.         result          : DetectResult;
  1222.                      
  1223. BEGIN
  1224.   p:=loc;
  1225.   DetectChar (EditWdw.hdl,0, takePnt,p,
  1226.               hdl, col,row, box, result);
  1227.               
  1228.   (*  Falls Klick im Fenster, so wird der Cursor unter dem Mauszeiger pos.  *)
  1229.   
  1230.   IF result = foundChar THEN PosEdCurs (col,row) END;
  1231.   RETURN FALSE;
  1232. END EditButHdler;
  1233.  
  1234. (*  CopyKeyHdler -- Akzeptiert die Tastaturereignisse während des Kopiermodus.
  1235.  *)
  1236.  
  1237. PROCEDURE CopyKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  1238.  
  1239. CONST   f1              = 59;   (*  Scancodes der benötigten Sondertasten  *)
  1240.         f10             = 68;
  1241.         up              = 72;
  1242.         down            = 80;
  1243.         help            = 98;
  1244.         
  1245. VAR     col, row        : CARDINAL;
  1246.         entry           : PathEntry;
  1247.         success         : BOOLEAN;
  1248.         
  1249.   (*  Bewegt den Cursor um 'r' Zeilen
  1250.    *)
  1251.  
  1252.   PROCEDURE move (r:INTEGER);
  1253.  
  1254.   BEGIN
  1255.     IF (INTEGER (row) + r) >= 0 THEN row:=INTEGER (row) + r END;
  1256.   END move;
  1257.   
  1258. VAR     err     : BOOLEAN;
  1259.         l       : CARDINAL;
  1260.   
  1261. BEGIN
  1262.   GetPos (ShowWdw.hdl, col,row);
  1263.   CursOff (ShowWdw.hdl);
  1264.   CASE ORD (ch.scan) OF
  1265.   
  1266.     f10         : Hide (ShowWdw.hdl); ShowWdw.used:=FALSE;
  1267.                   RestoreNormalEdit; RETURN FALSE| (*  Ende des Kopierenmodus *)
  1268.                   
  1269.     help        : ShowHelp|     (*  Helptable anzeigen  *)
  1270.     
  1271.     up          : move (-1)|    (*  Cursor einen Zeile nach oben  *)
  1272.     down        : move (1)|     (*  Cursor einen Zeile nach unten  *)
  1273.     
  1274.     f1          : SelectCopyPath (row)|  (*  Aktuellen Eintrag anwählen  *)
  1275.  
  1276.   ELSE
  1277.   END;
  1278.   PosShowCurs (row);
  1279.   CursOn (ShowWdw.hdl);
  1280.   RETURN FALSE;
  1281. END CopyKeyHdler;
  1282.  
  1283. (*  CopyButHdler -- Akzeptiert die Mausknopfereignisse während des Kopiermodus.
  1284.  *)
  1285.  
  1286. PROCEDURE CopyButHdler (clicks:CARDINAL;loc:Point;
  1287.                         buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  1288.                      
  1289. VAR     p               : Point;
  1290.         hdl             : Window;
  1291.         row, r          : CARDINAL;
  1292.         box             : Rectangle;
  1293.         result          : DetectResult;
  1294.                      
  1295. BEGIN
  1296.   p:=loc;
  1297.   DetectChar (ShowWdw.hdl,0, takePnt,p,
  1298.               hdl, VoidC,row, box, result);
  1299.               
  1300.   (*  Falls Klick im Fenster, so wird der Cursor pos. und der entsprechnede
  1301.    *  Eintrag selektiert.
  1302.    *)
  1303.    
  1304.   IF result = foundChar THEN
  1305.     CursOff (ShowWdw.hdl);
  1306.     PosShowCurs (row);
  1307.     GetPos (ShowWdw.hdl, VoidC,r);
  1308.     IF row = r THEN SelectCopyPath (row) END;
  1309.     CursOn (ShowWdw.hdl);
  1310.   END;
  1311.   RETURN FALSE;
  1312. END CopyButHdler;
  1313.  
  1314.  
  1315. (*  CSelKeyHdler -- Akzeptiert die Tastaturereignisse, während des Listen-
  1316.  *                  auswahl-Menus.
  1317.  *)
  1318.  
  1319. PROCEDURE CSelKeyHdler (VAR ch:GemChar; VAR keys: SpecialKeySet) :BOOLEAN;
  1320.  
  1321. BEGIN
  1322.   CASE ch.ascii OF
  1323.     '1' : SetCopyList (copyDft)|
  1324.     '2' : SetCopyList (copyDef)|
  1325.     '3' : SetCopyList (copyImp)|
  1326.     '4' : SetCopyList (copyMod)|
  1327.     '5' : SetCopyList (copySrc)|
  1328.     '6' : SetCopyList (copySym)|
  1329.   ELSE
  1330.   END;
  1331.   RETURN FALSE;
  1332. END CSelKeyHdler;
  1333.  
  1334. (*  CSelButHdler -- Akzeptiert die Mausknopfereignisse, während des Listen-
  1335.  *                  auswahl-Menus.
  1336.  *)
  1337.  
  1338. PROCEDURE CSelButHdler (clicks:CARDINAL;loc:Point;
  1339.                             buts:MButtonSet;keys:SpecialKeySet) :BOOLEAN;
  1340.                             
  1341. VAR     p       : Point;
  1342.         hdl     : Window;
  1343.         col, row: CARDINAL;
  1344.         box     : Rectangle;
  1345.         result  : DetectResult;
  1346.                      
  1347. BEGIN
  1348.   p:=loc;
  1349.   DetectChar (ShowWdw.hdl,0, takePnt,p,
  1350.               hdl, col,row, box, result);
  1351.   IF result = foundChar THEN
  1352.     CASE row OF
  1353.       3   : SetCopyList (copyDft)|
  1354.       4   : SetCopyList (copyDef)|
  1355.       5   : SetCopyList (copyImp)|
  1356.       6   : SetCopyList (copyMod)|
  1357.       7   : SetCopyList (copySrc)|
  1358.       8   : SetCopyList (copySym)|
  1359.     ELSE
  1360.     END;
  1361.   END;
  1362.   RETURN FALSE;
  1363. END CSelButHdler;
  1364.  
  1365.  
  1366. (*  Master -- Verteilt die Events.
  1367.  *)
  1368.  
  1369. PROCEDURE Master;
  1370.  
  1371. BEGIN
  1372.   REPEAT
  1373.     HandleEvents (1, MButtonSet{msBut1},MButtonSet{msBut1},
  1374.                   lookForEntry,Rect (0,0,0,0), lookForEntry,Rect (0,0,0,0),
  1375.                   0L,
  1376.                   EventProcs,2);
  1377.     IF EditWdw.used & WasClosed (EditWdw.hdl) THEN
  1378.       Hide (EditWdw.hdl); FreeWdw (EditWdw); SwitchToMainMenu
  1379.     ELSIF CHWdw.used & WasClosed (CHWdw.hdl) THEN
  1380.       DoMainCommand (quit)
  1381.     END
  1382.   UNTIL Quit;
  1383. END Master;
  1384.  
  1385.  
  1386. PROCEDURE InitModule () :BOOLEAN;
  1387.  
  1388. VAR     success : BOOLEAN;
  1389.         ch      : CHAR;
  1390.  
  1391. BEGIN
  1392.   Quit:=FALSE;
  1393.   
  1394.   (*  Beim GEM anmelden.
  1395.    *)
  1396.   
  1397.   InitGem (RC, Dev, OK);
  1398.   IF ~ OK THEN RETURN FALSE END;
  1399.   Gem:=CurrGemHandle ();
  1400.   
  1401.   (*  Benötigte Fenster anfordern.
  1402.    *)
  1403.   
  1404.   CHWdw.used:=FALSE;
  1405.   Open (CHWdw.hdl, 42,13, WQualitySet{movable, closable, titled}, hideWdw,
  1406.         noForce, ' PathEdit by MCH / V1.1 ', -1,-1,-1,-1, OK);
  1407.   IF ~ OK THEN RETURN FALSE END;
  1408.  
  1409.   EditWdw.used:=FALSE;
  1410.   Open (EditWdw.hdl, MaxLen,MaxPaths + 4, WQualitySet{movable, closable,
  1411.     titled, dynamic}, hideWdw, forceCursor, ' Edit-Window ', -1,-1,60,-1, OK);
  1412.   success:=OK;
  1413.  
  1414.   ShowWdw.used:=FALSE;
  1415.   Open (ShowWdw.hdl, MaxLen,MaxPaths + 4, WQualitySet{movable, titled, dynamic},
  1416.         hideWdw, forceCursor, ' Copy-Window ', -1,-1,50,15, OK);
  1417.   success:=success AND OK;
  1418.   
  1419.   IF ~ success THEN WITH CHWdw DO
  1420.   
  1421.     (*  Fehlermeldung und Term., falls nicht genug Fenster erzeugt werden
  1422.      *  können.
  1423.      *)
  1424.      
  1425.     WriteLn (hdl); WriteLn (hdl);
  1426.     ReverseOn (hdl);
  1427.     (*$? German:
  1428.       WriteString (hdl, 'Es ist nicht genügend Speicherplatz vorhanden !');
  1429.     *)
  1430.     (*$? English:
  1431.       WriteString (hdl, 'Out of memory !');
  1432.     *)
  1433.     ReverseOff (hdl);
  1434.     WriteLn (hdl); WriteLn (hdl);
  1435.     (*$? German:
  1436.       WriteString (hdl, 'Bitte irgendeine Taste drücken...'); Read (hdl, ch);
  1437.     *)
  1438.     (*$? English:
  1439.       WriteString (hdl, 'Press any key...'); Read (hdl, ch);
  1440.     *)
  1441.  
  1442.   END END;
  1443.   
  1444.   SwitchToMainMenu;     (*  Mit dem Hauptmenu anfangen  *)
  1445.   
  1446.   IF ~ success THEN ExitGem (Gem) END;
  1447.   
  1448.   RETURN success
  1449. END InitModule;
  1450.  
  1451. PROCEDURE ExitModule;
  1452.  
  1453. BEGIN
  1454.   (*  Fenster freigeben.
  1455.    *)
  1456.   Close (ShowWdw.hdl);
  1457.   Close (EditWdw.hdl); IF EditWdw.used THEN EraseList (EditWdw.list) END;
  1458.   Close (CHWdw.hdl);
  1459.   
  1460.   ExitGem (Gem);        (*  Beim GEM abmelden  *)
  1461. END ExitModule;
  1462.  
  1463.  
  1464. BEGIN
  1465.   IF InitModule () THEN
  1466.     Master;
  1467.     ExitModule;
  1468.   END;
  1469. END PathEdit.
  1470.