PROGRAM Adressenverwaltung;

{
       Gemeinschaftsproduktion einer Adressenverwaltung
   
              geschrieben in MaxonPascal3 von
  
                 
                 Bombersoft  &  Røgersøft                                             
               
  
            (Björn Schotte und Michael Klein)
                                                              }
                     

{$opt q}

USES Intuition, ExecSupport, Graphics, Gadtools;

{$incl "dos.lib",
       "diskfont.lib",
       "workbench/startup.h",
       "icon.lib",
       "asl.lib",
       {"rexxsyslib.lib",
       "gadtools.lib",}
       "intuition/intuition_functions.h",
       "wb.lib"}

CONST
{  RexxName = "ADDIPRO";}
  AppName  = "AddiPro.2";
  
  verstag = "$VER: AddiPro V0.90 (10.11.1995)";
  
  { Fensterbreiten und -höhen bei Topaz80-Font }
  MainWinWidth  = 458;
  EditWinWidth  = 624;
  EditWinHeight = 175;

  MainIDCMP = IDCMP_GADGETUP OR
              IDCMP_GADGETDOWN OR
              IDCMP_MOUSEBUTTONS OR
              IDCMP_CLOSEWINDOW OR
              IDCMP_INTUITICKS OR
              IDCMP_CHANGEWINDOW OR
              IDCMP_MOUSEMOVE OR
              IDCMP_MENUPICK OR
              IDCMP_RAWKEY;
              
  { ** Gadget-Nummern des Hauptwindows ** }
  M_LV           =  1;
  M_NEU          =  2;
  M_ÄNDERN       =  3;
  M_LÖSCHEN      =  4;
  M_SUCHEN       =  5;
  M_SORTIEREN    =  6; 
  M_BLÄTTERN     =  7;
  M_SERIENDRUCK  =  8;
  M_FORMULARDRUCK=  9;
  M_LISTENDRUCK  = 10;


  { ** Datensatzlänge in Zeichen ** }
  namelength    = 31;
  vnamelength   = 21;
  strasselength = 31;
  ortlength     = 31;
  plzlength     = 8;
  tellength     = 21;
  faxlength     = 21;
  geblength     = 13;
  EMaillength   = 30;
  AnLength      = 10;
  komlength     = 80;

  { -- Kennung für die Adressdatei -- }
  kennung = "AddiPro-Datei";

{  { -- Default PopKey für Commodity -- }
  DefHotKey = "lcommand control a";}

TYPE
  String256 = STRING[256];
  String200 = STRING[200];

  WaitPointerTyp = ARRAY[1..36] OF WORD;

 tname=STRING[namelength];
 tvname=STRING[vnamelength];
 tStrasse=STRING[strasselength];
 tort=STRING[ortlength];
 tplz=STRING[plzlength];
 ttel=STRING[tellength];
 tfax=STRING[faxlength];
 tgeb=STRING[geblength];
 temail=STRING[EMaillength];
 tanrede=STRING[AnLength];
 tkom=STRING[komlength];
 
 { ** Hauptdaten-Record ** }
 p_person=^person;
 Person=RECORD
   pn       :   node;
   name     :   tname;
   vorname  :   tvname;
   strasse  :   tstrasse;
   ort      :   tort;
   plz      :   tplz;
   tel      :   ttel;
   fax      :   tfax;
   geb      :   tgeb;
   email1,
   email2   :   temail;
   select   :   array[1..10] of boolean;
   anrede   :   byte;
   anrede_s :   tAnrede;
   kommentar:   tkom; 
 END; 

VAR
  iconname                      : STRING256;STATIC; {name der icondatei}
  eigenname                     : STRING256;STATIC {name des Programms}
  prefsfile                     : STRING;STATIC;
  MyAppIcon                     : p_AppIcon;STATIC;
  iconified                     : BOOLEAN;STATIC;
  Mens                          : ARRAY[1..15] OF NewMenu;STATIC;
  MyMen                         : p_Menu;STATIC;
  nbuf                          : tname;STATIC; { Für die STRING-Gadgets }
  vbuf                          : tvname;STATIC;
  sbuf                          : tstrasse;STATIC;
  obuf                          : tort;STATIC;
  pbuf                          : tplz;STATIC;
  tbuf                          : ttel;STATIC;
  fbuf                          : tfax;STATIC;
  gbuf                          : tgeb;STATIC;
  kombuf                        : tkom;STATIC;
  em1buf,em2buf                 : tEMail;STATIC;
  PList                         : p_List;STATIC;  { Unsere List }
  PNode                         : p_Person;STATIC; { Unser Record (Pointer) }
  a                             : STR;STATIC;
  gl,gad,gl1,gad1,KlickG,
  gad2,gl2,ÜberGl               : p_Gadget;STATIC;
  mgad                          : ARRAY[1..15] OF p_Gadget;STATIC;
  egad                          : ARRAY[1..24] OF p_Gadget;STATIC;
  agad                          : ARRAY[1..2] OF p_Gadget;STATIC;
  wp,wp1,wp2                    : p_Window;STATIC;
  t                             : ARRAY[1..15] OF TagItem;STATIC;
  ng                            : NewGadget;STATIC;
  ps                            : p_Screen;STATIC;
  vi                            : PTR; STATIC;
  msg                           : p_IntuiMessage;STATIC;
  l                             : LONG;STATIC;
  done,dummy,ok                 : BOOLEAN;STATIC;
  class,qual,code               : LONG;STATIC;
  err                           : WORD;STATIC;
  i,j,k                         : INTEGER;STATIC;
  xoff, yoff                    : INTEGER;STATIC; 
  tattr                         : TextAttr;STATIC;
  GadNum                        : CARDINAL;STATIC;
  Anzahl                        : LONGINT;STATIC;
  pfad,datei                    : String200;STATIC;
  f,f1                          : Text;STATIC;
  erkenn                        : STRING;STATIC;
  AktuellePerson,DPerson        : p_Person;STATIC;
  es                            : EasyStruct;STATIC;
  s                             : STRING200;STATIC;
  Knoten                        : p_Node;STATIC;
  SelectTexte                   : ARRAY[1..10] OF STRING[11];STATIC;
  DruckerAusgabe                : STRING[80];STATIC;
  port                          : p_MsgPort;STATIC;
  MainReq,BlättReq              : Requester;STATIC;
  WaitPointerData               : WaitPointerTyp;STATIC;
  WaitPointer                   : PTR;STATIC;
  OS39                          : BOOLEAN;STATIC;
  psfont,myfont                 : p_TextFont;STATIC;
  WBR,WBB,psh,psw,FontX,FontY,
  ww,wh                         : INTEGER;STATIC;
  MyTattr                       : p_TextAttr;STATIC;
  AktuellGewählt                : LONG;STATIC;
  AddiProid, prefsid, verid,
  AppSig{,edisig}               : LONG;STATIC;
  suchbuf,passwort              : STRING;STATIC;
  anredebuf                     : tAnrede;STATIC;
  sgad                          : ARRAY[1..20] OF p_Gadget;STATIC;
  MXLabels                      : ARRAY[1..8] OF STR; STATIC;
  anrede_z                      : INTEGER;STATIC;
  anrede_s                      : tAnrede;STATIC;
  prozentwin                    : p_Window;STATIC;
  DoppelKlick                   : BOOLEAN;STATIC;
  Iconsave,autoload,verschluesseln: BOOLEAN;STATIC; {für Voreinstellungen}
  druckwin,                       {ob das Druckwindow offen ist?}
  vonmain                       : BOOLEAN;STATIC; {Wenn man vom Mainwindow kam}
  {*}signalmasc,oldsecs, oldmics              : LONG;STATIC;
  pubname                       : STR;STATIC;
  EditorPort,AppPort            : p_MsgPort;STATIC;
  AppWin                        : p_AppWindow;STATIC;
 {Fensterkoordinatenvariablen}
  MainWinHeight,          { normalerweise konstant, aber wegen Listview unter OS2.04}
  EditWinLeft, EditWinTop,
  Suchpfadwinleft,suchpfadwintop,
  selectwinleft,selectwintop,
  BlätterWinLeft, BlätterWinTop,
  EinstellWinLeft, EinstellWinTop,
  druckwinleft, druckwintop,
  suchwinleft,suchwintop,
  Seriendruckwinleft,Seriendruckwintop,
  Formulardruckwinleft,Formulardruckwintop,
  aslf_width,aslf_height,
  aslf_topedge,aslf_leftedge,
  Sortierwinleft,sortierwintop,
  Listendruckwinleft,Listendruckwintop:INTEGER;STATIC;
  BlätterGl                     : p_Gadget;STATIC;
  BlätterWp,serdruck,fordruck   : p_Window;STATIC;
  serverp                       : p_MsgPort;STATIC;
  editor, textanzeiger          : STRING[256];STATIC;
  ff,fd,ff1,fd1,ff2,fd2         : STRING[200];STATIC;
  si                            : p_stringinfo;STATIC;
  druckmask                     : LONG;STATIC;
  c                             : CHAR;STATIC;

{$path"AddiPro:Editor/";
  incl"errors.h",
      "allgemein.h",
      "winclose.h",
      "listen.h",
      "oberfläche.h",
      "druckmenü.h",
      "prefs.h",
      "sortieren.h",
      "dateioperationen.h"}
      
PROCEDURE CloseLibs;
{ -- Schliesst die geöffneten Libraries -- }
BEGIN
  IF WorkbenchBase <> NIL THEN CloseLibrary(WorkbenchBase);
  IF GadToolsBase <> NIL THEN CloseLibrary(GadToolsBase);
{  IF RexxSysBase <> NIL THEN CloseLibrary(RexxSysBase);}
  IF DiskFontBase <> NIL THEN CloseLibrary(DiskFontBase);
  IF IconBase <> NIL THEN CloseLibrary(IconBase);
  IF ASLBase <> NIL THEN CloseLibrary(ASLBase);
  IF DOSBase <> NIL THEN CloseLibrary(DOSBase);
END;

{ ** CleanUp - Routine
  **
  ** 24.10.1995:
  **
  **  - Serienbrief-Fenster wird nun bei Programmende
  **    geschlossen, was vorher NICHT der Fall war
  **}
PROCEDURE CleanUp(why:String200; rc:INTEGER);
BEGIN
  IF serdruck <> NIL THEN serienende;
  CloseMainWin;                                     { Hauptfenster schliessen }
  IF vi <> NIL THEN FreeVisualInfo(vi);             { VisualInfo freigeben    }
  IF ps <> NIL THEN UnLockPubScreen(NIL,ps)         { Publicscreen freigeben  }
  IF WaitPointer <> NIL THEN FreeVec(WaitPointer);  { WaitPointer freigeben   }
  IF why <> "" THEN i := MeldReq(ERRTIT,why,"ok");
  closett;
  CloseLibs;
  HALT(rc);
END;

{ ** Öffnet die benötigten Libraries
  **
  ** }
PROCEDURE OpenLibs;
BEGIN
  ASLBase := NIL; IconBase := NIL; 
  DiskfontBase := NIL; {RexxSysBase := NIL;} GadToolsBase := NIL;
  WorkbenchBase := NIL;
  
  DOSBase := OpenLibrary("dos.library",37);
  IF DOSBase = NIL THEN CleanUp(ERRNO_DOS, 20);
  ASLBase := OpenLibrary("asl.library",37);
  IF ASLBase = NIL THEN CleanUp(ERRNO_ASL, 20);
  IconBase := OpenLibrary("icon.library",0);
  IF IconBase = NIL THEN CleanUp(ERRNO_ICON,20);
  DiskfontBase := OpenLibrary("diskfont.library",0);
  IF DiskfontBase = NIL THEN CleanUp(ERRNO_DISKFONT,20);
{  RexxSysBase := OpenLibrary("rexxsyslib.library",0);
  IF RexxSysBasE = NIL THEN CleanUp(ERRNO_REXX,20);}
  GadToolsBase := OpenLibrary("gadtools.library",37);
  IF GadToolsBase = NIL THEN CleanUp(ERRNO_GADTOOLS,20);
  WorkbenchBase := OpenLibrary("workbench.library", 37);
  IF WorkbenchBase = NIL THEN CleanUp(ERRNO_WB,20);
END;

{ ** Überprüft, ob Kick-Version 37+ vorhanden
  **
  ** 24.10.1995:
  **
  **  - Bei Start von Workbench erscheint nun ein
  **    EasyRequester, falls kein Kick 37+ vorhanden.
  ** }
PROCEDURE Versionsprüfung;
VAR
  lib : p_Library;
BEGIN
  lib := IntuitionBase;
  IF lib^.lib_Version < 37 THEN
  BEGIN
    DisplayBeep(NIL);
    IF FromWB THEN i := MeldReq(ERRTIT,
                                "AddiPro ist nur ab OS2.04 lauffähig!",
                                "OK")
    ELSE Writeln("Nur ab OS2.04 lauffähig !!");
    HALT(20);
  END;
  { Ist schon Kick3.0+ vorhanden ?? }
  OS39 := (lib^.lib_Version >= 39);
END;

PROCEDURE FreePs;
{ Freigeben des gelockten PublicScreens }
BEGIN
  IF ps <> NIL THEN UnLockPubScreen(NIL, ps);
  ps := NIL;
END;

PROCEDURE GetPubScr;
{ -- Holt sich alles vom PublicScreen (X/Y-Offsets) und die VisualInfo -- }
BEGIN
  ps:=NIL;
  IF pubname<>"" THEN ps := LockPubScreen(pubname)
                 ELSE ps := LockPubScreen(NIL);
  IF ps<>NIL THEN
  BEGIN
    AddExitServer(FreePs);
    vi:=GetVisualInfoA(ps,NIL);
    { -- Die nächsten 7 Daten werden für fontsensitives Programmieren -- }
    { -- gebraucht                                                    -- }
    psfont := ps^.RastPort.Font;
    wbr := ps^.WBorRight;
    wbb := ps^.WBorBottom;
    psw := ps^.Width;
    psh := ps^.Height;
    xoff := ps^.WBorLeft;
    yoff := ps^.BarHeight;
    { ------------------------------------------------------------------ }
    IF vi = NIL THEN
    BEGIN
      i := MeldReq("AddiPro","Kann keine VisualInfo bekommen","OK");
      HALT(20);
    END;
  END ELSE
  BEGIN
    i := MeldReq("AddiPro","Kann den Publicscreen nicht locken","OK");
    HALT(20);
  END;
  tattr := TextAttr("topaz.font",8,0,0);
  ComputeFont(0,0);
END;

{ ** Kleine Copyright-Prozedur
  **
  ** 24.10.1995:
  **
  **   - etwas am Text geändert, nicht so wichtig.
  ** }
PROCEDURE Über;
VAR
  es   : EasyStruct;
  s    : STRING[300];
BEGIN
  s := "       *** AddiPro V0.9ß ***"+
       CHR(10)+
       "(c) 1995 by Björn Schotte/Michael Klein"+
       CHR(10)+
       CHR(10)+
       "Adressen der Autoren:"+
       CHR(10)+
       CHR(10)+
       "  Björn Schotte"+CHR(10)+
       "  Am Burkardstuhl 45"+CHR(10)+
       "  D-97267 Himmelstadt"+CHR(10)+
       "  EMail: bjoern@bomber.mayn.de"+CHR(10)+
       CHR(10)+
       "- RogerSoft -"+CHR(10)+
       "  Michael Klein"+CHR(10)+
       "  Am Wasserturm 6"+CHR(10)+
       "  D-67346 Speyer"+CHR(10)+
       "  EMail: ujqc@rz.uni-karlsruhe.de";
  es := EasyStruct(SizeOf(EasyStruct),0,"Über AddiPro...",^s,"ok");
  i := EasyRequestArgs(wp,^es,NIL,NIL);
  s:=" Mit Dank an die Betatester:"+CHR(10)+CHR(10)+
     " Røgersøft & Bombersoft ;-) , PackMAN, Wurzelsepp"+CHR(10)+
     " Cyberzerk D-Sign System, Manfred Tenzler, Thorsten Mahr"+CHR(10)+
     " und alle, die ich vergessen habe !";
  es := EasyStruct(SizeOf(EasyStruct),0,"Betatesting done by :",^s,"ok");
  i := EasyRequestArgs(wp,^es,NIL,NIL);
END;

FUNCTION ÖffneEditFenster : BOOLEAN;
{ -- Editfenster öffnen -- }
VAR
  t : ARRAY[1..13] OF TagItem;
BEGIN
  SetEditGads;
  t[1] := TagItem(WA_InnerWidth,ww);
  t[2] := TagItem(WA_InnerHeight,wh);
  t[3] := TagItem(WA_Flags,WFLG_DRAGBAR+WFLG_DEPTHGADGET+WFLG_ACTIVATE+
                           WFLG_CLOSEGADGET+WFLG_HASZOOM+WFLG_RMBTRAP);
  t[4] := TagItem(WA_Idcmp,IDCMP_CLOSEWINDOW+IDCMP_GADGETUP+
                           IDCMP_CHANGEWINDOW+IDCMP_RAWKEY+
         IDCMP_GADGETDOWN);
  t[5].ti_Tag := WA_Title;
  t[5].ti_Data := "Editfenster";
  t[6] := TagItem(WA_MinWidth, 100);
  t[7] := TagItem(WA_MinHeight, yoff);
  t[8] := TagItem(WA_Gadgets, LONG(gl1));
  t[9] := TagItem(WA_Left, EditWinLeft);
  t[10] := TagItem(WA_Top, EditWinTop);
  t[11].ti_Tag := TAG_DONE;
  IF pubname <> "" THEN
  BEGIN
    t[11] := TagItem(WA_PubScreenFallBack, 1);
    t[12] := TagItem(WA_PubScreenName, LONG(pubname));
    t[13].ti_Tag := TAG_DONE;
  END;

  wp1 := OpenWindowTagList(NIL, ^t);
  IF wp1 = NIL THEN
  BEGIN
    FreeGadgets(gl1);
    DisplayBeep(NIL);
    ÖffneEditFenster := FALSE;
    EXIT;
  END;
  ÖffneEditFenster := TRUE;
END;

PROCEDURE Edit(VAR p:p_Person; ändern:BOOLEAN);
{ -- Die eigentliche Edit-Prozedur. Parameter:               --
  -- p : Beim Neuanlegen eines Datensatzes ein NIL,          --
  --     ansonsten ein schon vorhandener                     --
  -- ändern: Je nachdem, welchen Wert ändern hat, wird       --
  --         die vorhandene Person dargestellt und geändert, --
  --         ansonsten neu eingerichtet zum Schluß !!        -- }
VAR
  abbruch,ok : BOOLEAN;
  b          : STRING[50];
  x          : STR;

  PROCEDURE Changer(Nr:INTEGER);
  VAR
    dummy : BOOLEAN;
  BEGIN
    dummy := (egad[Nr+13]^.Flags AND SELECTED) = SELECTED;
    t[1] := TagItem(GTCB_Checked,ORD(NOT dummy))
    t[2].ti_Tag := TAG_DONE;
    GT_SetGadgetAttrsA(egad[Nr+13],wp1,NIL,^t);
  END;

BEGIN
  nbuf := ""; vbuf := ""; sbuf := ""; pbuf := ""; obuf := ""; tbuf := "";
  fbuf := ""; gbuf := ""; em1buf := ""; em2buf := "";
  kombuf := "";
  anredebuf := ""; anrede_z := 0;
  
  IF ändern THEN
  BEGIN
    nbuf      := p^.Name;
    vbuf      := p^.Vorname;
    sbuf      := p^.Strasse;
    pbuf      := p^.PLZ;
    obuf      := p^.Ort;
    tbuf      := p^.Tel;
    fbuf      := p^.Fax;
    gbuf      := p^.Geb;
    em1buf    := p^.EMail1;
    em2buf    := p^.EMail2;
    anrede_z  := p^.anrede;
    anredebuf := p^.anrede_s;
    kombuf    := p^.kommentar;
  END;
  dummy := ÖffneEditFenster;
  IF dummy THEN
  BEGIN
    Rahmen(wp1,2,2,508,123,TRUE);
    Rahmen(wp1,2,126,618,28,TRUE);
    Rahmen(wp1,2,155,618,20,TRUE);
    Rahmen(wp1,511,2,110,123,TRUE);
    IF ändern THEN
    BEGIN
      FOR i := 1 TO 10 DO
      BEGIN
        t[1] := TagItem(GTCB_Checked,LONG(p^.select[i]));
        t[2].ti_Tag := TAG_DONE;
        GT_SetGadgetAttrsA(egad[i+13],wp1,NIL,^t);
      END;
    END;
    GT_RefreshWindow(wp1,NIL);
    dummy := FALSE;
    abbruch := FALSE;
    ok := ActivateGadget(egad[1],wp1,NIL);
    REPEAT
      GetMessage(wp1,class,code,qual,GadNum);
      CASE class OF
        IDCMP_CLOSEWINDOW : BEGIN
                              dummy := TRUE;
                              abbruch := TRUE;
                            END;
        IDCMP_RAWKEY:
          CASE code OF
            54     : ok := ActivateGadget(egad[1],wp1,NIL);
            52     : ok := ActivateGadget(egad[2],wp1,NIL);
            32     : ok := ActivateGadget(egad[3],wp1,NIL);
            25     : ok := ActivateGadget(egad[4],wp1,NIL);
            24     : ok := ActivateGadget(egad[5],wp1,NIL);
            20     : ok := ActivateGadget(egad[6],wp1,NIL);
            35     : ok := ActivateGadget(egad[7],wp1,NIL);
            36     : ok := ActivateGadget(egad[8],wp1,NIL);
             1     : ok := ActivateGadget(egad[9],wp1,NIL);
             2     : ok := ActivateGadget(egad[10],wp1,NIL);
             3..5  : BEGIN
                       anrede_z := code-3;
                       t[1] := TagItem(GTMX_Active, anrede_z);
                       t[2].ti_Tag := TAG_DONE;
                       GT_SetGadgetAttrsA(egad[24],wp1,NIL,^t);
                       t[1] := TagItem(GA_Disabled, 1);
                       GT_SetGadgetAttrsA(egad[25],wp1,NIL,^t);
                     END;  
            43     : BEGIN
                       anrede_z := 3;
                       t[1] := TagItem(GTMX_Active, anrede_z);
                       t[2].ti_Tag := TAG_DONE;
                       GT_SetGadgetAttrsA(egad[24],wp1,NIL,^t);
                       t[1] := TagItem(GA_Disabled, 0);
                       GT_SetGadgetAttrsA(egad[25],wp1,NIL,^t);
                       ok := ActivateGadget(egad[25],wp1,NIL);
                     END;   
            26     : BEGIN
                       ButSelecter(wp1,egad[12]);
                       dummy := TRUE;
                     END;
            53,69  : BEGIN
                       ButSelecter(wp1,egad[13]);
                       dummy := TRUE;
                       abbruch := TRUE;
                     END;
            80..89 : Changer(code - 79);
          ELSE
          END;
        IDCMP_GADGETUP:
          CASE GadNum OF
            1..10 : ok := ActivateGadget(egad[GadNum+1],wp1,NIL);
            12 : dummy := TRUE;
            13 : BEGIN
                   dummy := TRUE;
                   abbruch := TRUE;
                 END;
            25 : anrede_s := GetString(egad[25]);    
          ELSE END;
    IDCMP_GADGETDOWN:
      CASE GadNum OF
        24 : BEGIN
               anrede_z := code;
               IF anrede_z < 3 THEN
               BEGIN
                 t[1] := TagItem(GA_Disabled, 1);
                 t[2].ti_Tag := TAG_DONE;
                 GT_SetGadgetAttrsA(egad[25],wp1,NIL,^t);
               END ELSE
               BEGIN
                 t[1] := TagItem(GA_Disabled, 0);
                 t[2].ti_Tag := TAG_DONE;
                 GT_SetGadgetAttrsA(egad[25],wp1,NIL,^t);
                 ok := ActivateGadget(egad[25],wp1,NIL);
               END;
             END;  
      ELSE END;   
      ELSE END;
    UNTIL dummy;
    IF abbruch = FALSE THEN
    BEGIN
      IF ändern THEN
      BEGIN
        p^.Name    := GetString(egad[1]);
        p^.Vorname := GetString(egad[2]);
        p^.Strasse := GetString(egad[3]);
        p^.PLZ     := GetString(egad[4]);
        p^.Ort     := GetString(egad[5]);
        p^.Tel     := GetString(egad[6]);
        p^.Fax     := GetString(egad[7]);
        p^.Geb     := GetString(egad[8]);
        p^.EMail1  := GetString(egad[9]);
        p^.EMail2  := GetString(egad[10]);
        p^.anrede  := anrede_z;
        IF anrede_z = 3 THEN p^.anrede_s:= anrede_s ELSE p^.anrede_s := "";
        p^.kommentar := GetString(egad[11]);
        
        FOR i := 1 TO 10 DO p^.select[i] := ( (egad[i+13]^.Flags AND SELECTED)=SELECTED );
        s := p^.Name+", "+p^.Vorname;
        x := s;
        FreeVec(PTR(p^.pn.ln_Name));
        p^.pn.ln_Name := PTR(AllocVec(Length(x)+1,MEMF_ANY));
        CopyMem(PTR(x),PTR(p^.pn.ln_Name),Length(x)+1);
      END ELSE
      BEGIN
        New(PNode);
        PNode^.name    := GetString(egad[1]);
        PNode^.vorname := GetString(egad[2]);
        PNode^.strasse := GetString(egad[3]);
        PNode^.plz     := GetString(egad[4]);
        PNode^.ort     := GetString(egad[5]);
        PNode^.tel     := GetString(egad[6]);
        PNode^.fax     := GetString(egad[7]);
        PNode^.geb     := GetString(egad[8]);
        PNode^.EMail1  := GetString(egad[9]);
        PNode^.EMail2  := GetString(egad[10]);
        PNode^.anrede  := anrede_z;
        PNode^.kommentar := GetString(egad[11]);
        IF anrede_z = 3 THEN PNode^.anrede_s := anrede_s ELSE PNode^.anrede_s := "";
        PNode^.pn.ln_succ := NIL;
        PNode^.pn.ln_pred := NIL;
        PNode^.pn.ln_Type := NT_UNKNOWN;
        PNode^.pn.ln_Pri := 0;
        FOR i := 1 TO 10 DO PNode^.select[i] := ( (egad[i+13]^.Flags AND SELECTED)=SELECTED );
        b := GetString(egad[1])+", "+GetString(egad[2]);
        x := b;
        NeuePerson(PNode,x);
        Inc(Anzahl);
      END;
      IF vonmain THEN 
     BEGIN
      ComputeFont(MainWinWidth,MainWinHeight);
     END
    ELSE
     BEGIN
      ComputeFont(325,140)
     END;
      t[1] := TagItem(GTLV_Labels,LONG(PList));
      t[2] := TagItem(GTLV_Selected, AktuellGewählt);
      t[3].ti_Tag := TAG_DONE;
      GT_SetGadgetAttrsA(mgad[1],wp,NIL,^t);
      GhostGadget(mgad[M_SUCHEN],wp,FALSE);
      GhostGadget(mgad[M_SORTIEREN],wp,FALSE);
      GhostGadget(mgad[M_ÄNDERN],wp,FALSE);
      GhostGadget(mgad[M_BLÄTTERN],wp,FALSE);
      GhostGadget(mgad[M_LÖSCHEN],wp,FALSE);
      GhostGadget(mgad[M_SERIENDRUCK],wp,FALSE);
      GhostGadget(mgad[M_FORMULARDRUCK],wp,FALSE);
      GhostGadget(mgad[M_LISTENDRUCK],wp,FALSE);
      GT_RefreshWindow(wp,NIL);
      IF Anzahl = 1 THEN AktuellePerson := SucheNode(0);
    END;
    EditWinLeft := wp1^.LeftEdge;
    EditWinTop := wp1^.TopEdge;
    CloseWindow(wp1);
    wp1 := NIL;
    FreeGadgets(gl1);
    gl1 := NIL;
    ComputeFont(MainWinWidth,MainWinHeight);
  END;
 {***!!***} dummy:=FALSE; 
END;


{ ** Löscht einen Datensatz, mit Sicherheitsabfrage
  **
  ** 24.10.1995:
  **
  **  - Kleines "MakeUp" am Sicherheitsrequester
  **  - "Handgemachtes" EasyRequestArgs() durch
  **    MeldReq() ersetzt.
  ** }
PROCEDURE DatensatzLöschen;
VAR letzter:BOOLEAN;
BEGIN
  IF AktuellePerson <> NIL THEN
  BEGIN
    s := "Wollen Sie den Datensatz"+CHR(10)+"'"+
         AktuellePerson^.pn.ln_Name+"'"+CHR(10)+
         "wirklich löschen ????";
    l := MeldReq("!!! ACHTUNG !!!",s,"JA|NEIN!");
    IF l = 1 THEN { OK angeklickt }
    BEGIN
     letzter:=FALSE;
     IF aktuelleperson = p_person(plist^.lh_tailpred) THEN letzter:=TRUE;
     LöscheNode(AktuellePerson);
     Dec(Anzahl);
     IF (Anzahl = 0) THEN
        AktuellePerson := NIL
      ELSE
       IF letzter THEN aktuelleperson:=  p_person(plist^.lh_tailpred)
                  ELSE AktuellePerson := SucheNode(AktuellGewählt);
      t[1] := TagItem(GTLV_Labels,LONG(PList));
      t[2].ti_Tag := GTLV_Selected
      IF Anzahl = 0 THEN
        t[2].ti_Data := NOT 0
      ELSE
        t[2].ti_Data := AktuellGewählt;
      t[3].ti_Tag := TAG_DONE;
      GT_SetGadgetAttrsA(mgad[1],wp,NIL,^t);
      IF Anzahl = 0 THEN
      BEGIN
        { Gadgets deaktivieren: }
        GhostGadget(mgad[M_SUCHEN],wp,TRUE);
        GhostGadget(mgad[M_SORTIEREN],wp,TRUE);
        GhostGadget(mgad[M_ÄNDERN],wp,TRUE);
        GhostGadget(mgad[M_BLÄTTERN],wp,TRUE);
        GhostGadget(mgad[M_LÖSCHEN],wp,TRUE);
        GhostGadget(mgad[M_SERIENDRUCK],wp,TRUE);
        GhostGadget(mgad[M_FORMULARDRUCK],wp,TRUE);
        GhostGadget(mgad[M_LISTENDRUCK],wp,TRUE);
      END;
    END;
  END;
END;

{ -- Löscht alle Datensätze -- }
PROCEDURE AllesLöschen;
BEGIN
  IF anzahl = 0 THEN EXIT;
  s := "Wollen Sie wirklich alle "+IntStr(anzahl)+CHR(10)+
       "Datensätze löschen ???";
  es := EasyStruct(SizeOf(EasyStruct),0,"!!! ACHTUNG !!!",s,"JA|NEIN!");
  l := EasyRequestArgs(wp,^es,NIl,NIL);
  IF l = 1 THEN
  BEGIN
    s := "Sind Sie ganz sicher ??";
    es := EasyStruct(SizeOf(EasyStruct),0,"??? Wirklich ???",s,"JA|NEIN!");
    l := EasyRequestArgs(wp,^es,NIl,NIL);
    IF l = 1 THEN
    BEGIN
      DeleteAllPersons;
      New(PList);
      NewList(PList);
      t[1] := TagItem(GTLV_Labels,LONG(NIL));
      t[2].ti_Tag := TAG_DONE;
      GT_SetGadgetAttrsA(mgad[1],wp,NIL,^t);
      Anzahl := 0;
      AktuellGewählt := 0;
      AktuellePerson := NIL;
      GhostGadget(mgad[M_SUCHEN],wp,TRUE);
      GhostGadget(mgad[M_SORTIEREN],wp,TRUE);
      GhostGadget(mgad[M_ÄNDERN],wp,TRUE);
      GhostGadget(mgad[M_BLÄTTERN],wp,TRUE);
      GhostGadget(mgad[M_LÖSCHEN],wp,TRUE);
      GhostGadget(mgad[M_SERIENDRUCK],wp,TRUE);
      GhostGadget(mgad[M_FORMULARDRUCK],wp,TRUE);
      GhostGadget(mgad[M_LISTENDRUCK],wp,TRUE);
    END;
  END;
END;

{$incl "blättern.h","suchen.h"}

{ ** Kreiert die Menüs für das Hauptfenster
  ** von AddiPro.
  **
  ** 24.10.1995:
  **
  **  - Menüpunkt "Iconify" wird gesperrt, falls AddiPro
  **    von der Shell gestartet wurde.
  **}
PROCEDURE MainMenus;
VAR
  dummy : BOOLEAN;
BEGIN
  Mens[ 1] := NewMenu(NM_TITLE,0,"Projekt",NIL,0,0,NIL);
  Mens[ 2] := NewMenu(NM_ITEM ,0,"Laden","L",0,0,NIL);
  Mens[ 3] := NewMenu(NM_ITEM ,0,"Anhängen","N",0,0,NIL);
  Mens[ 4] := NewMenu(NM_ITEM ,0,"Speichern","S",0,0,NIL);
  Mens[ 5] := NewMenu(NM_ITEM ,0,"Speichern als...","A",0,0,NIL);
  Mens[ 6] := NewMenu(NM_ITEM ,0,STR(NM_BARLABEL),NIL,0,0,NIL);
  Mens[ 7] := NewMenu(NM_ITEM ,0,"Über...","?",0,0,NIL);
  Mens[ 8] := NewMenu(NM_ITEM ,0,STR(NM_BARLABEL),NIL,0,0,NIL);
  Mens[ 9] := NewMenu(NM_ITEM ,0,"Iconify","I",0,0,NIL);
  IF NOT FromWB THEN Mens[9].nm_Flags := NM_ITEMDISABLED;
  Mens[10] := NewMenu(NM_ITEM ,0,"Verlassen","Q",0,0,NIL);
  
  Mens[11] := NewMenu(NM_TITLE,0,"Extras",NIL,0,0,NIL);
  Mens[12] := NewMenu(NM_ITEM ,0,"Alle Adressen löschen",NIL,0,0,NIL);
  Mens[13] := NewMenu(NM_ITEM ,0,STR(NM_BARLABEL),NIL,0,0,NIL);
  Mens[14] := NewMenu(NM_ITEM ,0,"Voreinstellungen...","V",0,0,NIL);
  Mens[15].nm_Type := NM_END;
  t[1] := TagItem(GTMN_NewLookMenus, 1);
  t[2].ti_Tag := TAG_DONE;
  
  MyMen := CreateMenusA(^Mens,^t);
  
  IF MyMen = NIL THEN
  BEGIN
    FreeGadgets(gl);
    CloseWindow(wp);
    FreeVisualInfo(vi);
    UMeld("Menü konnte nicht erzeugt werden !!");
    HALT(20);
  END;
  
  dummy := LayoutMenusA(MyMen, vi, ^t);
  
  dummy := SetMenuStrip(wp, MyMen);
END;

{ -- Die Hauptprozedur -- }
PROCEDURE Main;
VAR
  ww,wh,
  oldclicked        : INTEGER;
  winmask,
  mask,secs,mics    : LONG;
  msg               : p_IntuiMessage;
  MenNum, ItNum,
  code              : INTEGER;
  amsg              : p_AppMessage;
  wba               : p_WBArg;
  mylock            : BPTR;

 PROCEDURE mainwinopen;
   BEGIN
 {***}  IF NOT OS39 THEN mainwinheight:=mainwinheight+12;
   ComputeFont(MainWinWidth,MainWinHeight);
   ww := ComputeX(MainWinWidth);
   wh := ComputeY(MainWinHeight);
  { IF NOT iconified THEN} SetMainGads;
   t[1] := TagItem(WA_InnerWidth,ww);
   t[2] := TagItem(WA_InnerHeight,wh);
   t[3] := TagItem(WA_IDCMP,MainIDCMP);
   t[4] := TagItem(WA_Flags, WFLG_ACTIVATE+
                             WFLG_CLOSEGADGET+
                             WFLG_DRAGBAR+
                             WFLG_DEPTHGADGET+
                             WFLG_HASZOOM+
                             WFLG_NEWLOOKMENUS);
   t[5] := TagItem(WA_Gadgets, LONG(gl));
   t[6] := TagItem(WA_MaxWidth, psw);
   t[7] := TagItem(WA_MaxHeight, psh);
   t[8] := TagItem(WA_MinWidth, 200);
   t[9] := TagItem(WA_MinHeight, yoff);
   t[10].ti_Tag := WA_Title;
   t[10].ti_Data := "AddiPro V0.90ß - Hauptfenster - ";
   t[11].ti_Tag := TAG_DONE;
   IF pubname <> "" THEN
   BEGIN
     t[11] := TagItem(WA_PubScreenFallBack, 1);
     t[12] := TagItem(WA_PubScreenName, LONG(pubname));
     t[13].ti_Tag := TAG_DONE;
   END;
   wp := OpenWindowTagList(NIL,^t);
   IF wp = NIL THEN
   BEGIN
     FreeGadgets(gl);
     FreeVisualInfo(vi);
     UMeld("Konnte kein Fenster öffnen !!");
     HALT(20);
   END;
   AppWin := AddAppWindowA(1,0,wp,AppPort,NIL);
   IF AppWin = NIL THEN
   BEGIN
     CloseWindow(wp);
     FreeGadgets(gl);
     FreeVisualInfo(vi);
     UMeld("Konnte kein AppFenster kreieren !!");
     HALT(20);
   END;
   MainMenus;
  END;

{ ** Iconify-Routine
  **
  ** vorgeschrieben von Michael Klein, korrigiert
  ** und gepflegt von Björn Schotte
  **}
PROCEDURE IconifyMe;
VAR
  { ** Korrigiert 24.10.1995: War vorher vom Typ
    ** p_Message, was zu einem Absturz führte
    **} 
  dummymsg : p_AppMessage;
BEGIN
  { ** Korrigiert 24.10.1995 von Björn Schotte
    ** einige Intuition-Calls wurden in der
    ** falschen Reihenfolge aufgerufen
    ** }
  iconified := TRUE;
  eigenname := holeEigenname;
  
  { ** Icon besorgen, falls keins besorgt werden
    ** konnte, wird ein Standard-Icon genommen.
    **}
  dobj      := GetDiskObjectNew(eigenname);
  myappicon := AddAppIconA(0,0,'Addipro',AppPort,NIL,dobj,NIL);
  IF myappicon = NIL THEN
  BEGIN
    { ** AppIcon konnte nicht kreiert werden,
      ** Fehlermeldung ausgeben und normal
      ** weiterarbeiten
      **}
    FreeDiskObject(dobj);
    i := MeldReq("Fehler!","Nicht genug Speicher frei!","OK");
    iconified := FALSE;
    EXIT;
  END;
  { ** Hier richtige Reihenfolge eingefügt
    ** Zuerst Gadget-Liste entfernen, dann
    ** die Menü-Leiste, dann alles weitere
    **}  
  err := RemoveGList(wp,wp^.FirstGadget,-1);
  ClearMenuStrip(wp);
  dummy := RemoveAppWindow(AppWin);
  CloseWindow(wp);
  FreeGadgets(gl); 
  FreeVisualInfo(vi);
  freeps;
  { ** Auf Nachricht vom AppIcon warten... ** }
  REPEAT
    dummymsg := p_AppMessage(WaitPort(AppPort));
    dummymsg := p_AppMessage(GetMsg(AppPort)); 
    ReplyMsg(p_Message(dummymsg));
  UNTIL dummymsg^.am_Numargs=0;
  { ** AppIcon entfernen, Fenster öffnen und normal weiterarbeiten ** }
  dummy:=RemoveAppIcon(myAppIcon);
  FreeDiskObject(dobj);
  dobj:=NIL;                       {uuups!}
  getpubscr;
  mainwinopen;
  GT_RefreshWindow(wp,NIL);
  iconified:=FALSE;
  opentt;
END;
     
BEGIN
  iconified:=FALSE;
  oldclicked := -1;
  mainwinopen;
  IF FROMWB THEN 
   IF getwbargs THEN Dateiladen(FALSE) 
                ELSE IF autoload THEN DateiLaden(FALSE)
  ELSE IF autoload THEN DateiLaden(FALSE);  { knobel ;-) }
    
  GT_RefreshWindow(wp,NIL);
  done := FALSE;
  druckwin:=FALSE;
  REPEAT
    winmask := LONG(1) SHL LONG(wp^.UserPort^.mp_SigBit);
    AppSig := LONG(1) SHL LONG(AppPort^.mp_SigBit);
    IF druckwin THEN 
     druckmask :=(LONG(1) SHL LONG(serdruck^.userport^.mp_SigBit))
     ELSE druckmask:=LONG(0);
    signalmasc:=(winmask OR Appsig OR druckmask);
    mask := _Wait(signalmasc);
    IF (mask AND AppSig) = AppSig THEN
    BEGIN
      amsg := p_AppMessage(GetMsg(AppPort));
      WHILE amsg <> NIL DO
      BEGIN
        CASE amsg^.am_Type OF
          MTYPE_APPWINDOW:
            BEGIN
              wba := amsg^.am_ArgList;
              mylock := CurrentDir(wba^.wa_Lock);
              datei := wba^.wa_Name;
              dummy := GetCurrentDirName(^pfad,256);
              mylock := CurrentDir(mylock);
              DateiLaden(FALSE);
            END;
        ELSE END;
        ReplyMsg(p_Message(amsg));
        amsg := p_AppMessage(GetMsg(AppPort));
      END;
    END ELSE IF (mask AND winmask) = winmask THEN
    BEGIN
       msg := GT_GetIMsg(wp^.UserPort);
       WHILE msg <> NIL DO
       BEGIN
         class := msg^.Class;
         code := msg^.Code;
         qual := msg^.Qualifier;
         secs := msg^.Seconds;
         mics := msg^.Micros;
         IF class IN [IDCMP_GADGETUP, IDCMP_GADGETDOWN] THEN
         BEGIN
           KlickG := msg^.IAddress;
           GadNum := KlickG^.GadgetID;
           IF DoubleClick(oldsecs,oldmics,secs,mics) THEN DoppelKlick := TRUE
           ELSE
           BEGIN
             oldsecs := secs;
             oldmics := mics;
             DoppelKlick := FALSE;
           END;
         END;
         GT_ReplyIMsg(msg);
         CASE class OF
            IDCMP_CLOSEWINDOW : done := TRUE;
            IDCMP_RAWKEY: 
              CASE code OF
                54: BEGIN
                      ButSelecter(wp,mgad[M_NEU]);
                      SetBusyWindow(wp,MainReq);
                      DPerson := NIL;
                      Edit(DPerson,FALSE);
                      UnBusyWindow(wp,MainReq);
                    END;
                42: BEGIN
                      IF (mgad[M_ÄNDERN]^.Flags AND GADGDISABLED)=0 THEN
                      BEGIN
                        ButSelecter(wp,mgad[M_ÄNDERN]);
                        SetBusyWindow(wp,MainReq);
                        Edit(AktuellePerson,TRUE);
                        UnBusyWindow(wp,MainReq);
                      END;
                    END;
                41: BEGIN
                      IF (mgad[M_LÖSCHEN]^.Flags AND GADGDISABLED)=0 THEN
                      BEGIN
                        ButSelecter(wp,mgad[M_LÖSCHEN]);
                        DatensatzLöschen;
                      END;
                    END;
                51: BEGIN
                      IF (mgad[M_SUCHEN]^.Flags AND GADGDISABLED)=0 THEN
                      BEGIN
                        ButSelecter(wp,mgad[M_SUCHEN]);
                        SetBusyWindow(wp,MainReq);
                        Suchen;
                        UnBusyWindow(wp,MainReq);
                      END;
                    END;
                24: BEGIN
                      ButSelecter(wp,mgad[M_SORTIEREN]);
{                      SetBusyWindow(wp,MainReq);}
                      sortieren;
{                      UnBusyWindow(wp,Mainreq);}
                     END;
                53: BEGIN
                       IF (mgad[10]^.Flags AND GADGDISABLED)=0 THEN
                       BEGIN
                         ButSelecter(wp,mgad[M_BLÄTTERN]);
                         SetBusyWindow(wp,MainReq);
                         Blättern(AktuellePerson);
                         UnBusyWindow(wp,MainReq);
                       END;
                    END;
                76: BEGIN
                      IF (AktuellGewählt-1>=0) AND (Anzahl > 0) THEN
                      BEGIN
                        Dec(AktuellGewählt);
                        t[1] := TagItem(GTLV_Selected,AktuellGewählt);
                        { GTLV_MakeVisible (erst ab OS3.0 !!) }
                        t[2] := TagItem(GTLV_MakeVisible,AktuellGewählt);
                        t[3].ti_Tag := TAG_DONE;
                        GT_SetGadgetAttrsA(mgad[1],wp,NIL,^t);
                        AktuellePerson := SucheNode(AktuellGewählt);
                        GhostGadget(mgad[M_ÄNDERN],wp,FALSE);       
                        GhostGadget(mgad[M_LÖSCHEN],wp,FALSE);      
                      END;
                    END;
                77: BEGIN
                      IF (AktuellGewählt+1<=Anzahl-1) AND (Anzahl > 0) THEN
                      BEGIN
                        Inc(AktuellGewählt);
                        t[1] := TagItem(GTLV_Selected,AktuellGewählt);
                        t[2] := TagItem(GTLV_MakeVisible,AktuellGewählt);
                        t[3].ti_Tag := TAG_DONE;
                        GT_SetGadgetAttrsA(mgad[1],wp,NIL,^t);
                        AktuellePerson := SucheNode(AktuellGewählt);
                        GhostGadget(mgad[M_ÄNDERN],wp,FALSE);       
                        GhostGadget(mgad[M_LÖSCHEN],wp,FALSE);      
                      END;
                    END;
        
                33: BEGIN
                      ButSelecter(wp,mgad[M_SERIENDRUCK]);
                      Setbusywindow(wp,Mainreq);      
                      unbusywindow(wp,mainreq);
                      IF serdruck=NIL THEN serienbrief;
                    END;

                35: BEGIN
                      ButSelecter(wp,mgad[M_FORMULARDRUCK]);
                      Setbusywindow(wp,Mainreq); 
                      formularmodus;
                      unbusywindow(wp,mainreq);
                    END;

                40: BEGIN
                      ButSelecter(wp,mgad[M_LISTENDRUCK]);
                      Setbusywindow(wp,Mainreq);      
                      unbusywindow(wp,mainreq);
                    END;
              ELSE 
              END;
            IDCMP_MENUPICK:
              BEGIN
                mennum := MENUNUM(code);
                itnum  := ITEMNUM(code);
                CASE mennum OF
                  0 : CASE itnum OF
                        0 : BEGIN
                              SetBusyWindow(wp, MainReq);
                              DateiLaden(TRUE);
                              UnBusyWindow(wp, MainReq);
                            END;
                        1 : BEGIN
                             anhaengen;
                            END; 
                        2 : BEGIN
                              SetBusyWindow(wp, MainReq);
                              DateiSpeichern(FALSE);
                              UnBusyWindow(wp, MainReq);
                            END;
                        3 : BEGIN
                              SetBusyWindow(wp, MainReq);
                              DateiSpeichern(TRUE);
                              UnBusyWindow(wp, MainReq);
                            END;
                        5 : BEGIN
                              SetBusyWindow(wp, MainReq);
                              Über;
                              UnBusyWindow(wp, MainReq);
                            END;
                        7 : IconifyMe;       
                        8 : done := TRUE;
                      ELSE END; 
                  1 : CASE itnum OF
                        0 : BEGIN
                              SetBusyWindow(wp,MainReq);                         
                              AllesLöschen;
                              UnBusyWindow(wp, MainReq);
                            END;
                        2 : BEGIN
                              SetBusyWindow(wp,MainReq);                         
                              Voreinstellungen;
                              UnBusyWindow(wp, MainReq);
                            END;
                      ELSE END;
                ELSE END;
              END;
            IDCMP_CHANGEWINDOW: GT_RefreshWindow(wp, NIL);
            IDCMP_GADGETUP:
              CASE GadNum OF
                M_LV :
                  BEGIN
                    AktuellePerson := SucheNode(code);
                    AktuellGewählt := code;
                    GhostGadget(mgad[M_ÄNDERN],wp,FALSE);
                    GhostGadget(mgad[M_LÖSCHEN],wp,FALSE);        
                    { ** Doppelklick auf einen Eintrag -> Eintrag edieren ** }    
                    IF (DoppelKlick) AND (AktuellGewählt = oldclicked) THEN
                    BEGIN
                      oldclicked := -1;
                      SetBusyWindow(wp,MainReq);
                      Edit(AktuellePerson,TRUE);
                      UnBusyWindow(wp,MainReq);
                    END ELSE oldclicked := code;
                  END;
                  
                M_NEU :
                  BEGIN
                    vonmain:=TRUE;
                    SetBusyWindow(wp,MainReq);
                    DPerson := NIL;
                    Edit(DPerson,FALSE);
                    UnBusyWindow(wp,MainReq);
                  END;
                  
                M_ÄNDERN :
                  BEGIN
                    vonmain:=TRUE;
                    SetBusyWindow(wp,MainReq);
                    Edit(AktuellePerson,TRUE);
                    UnBusyWindow(wp,MainReq);
                  END;
                  
                M_LÖSCHEN:
                  DatensatzLöschen;
                  
                M_SUCHEN:
                  BEGIN
                   SetBusyWindow(wp,MainReq)
                   Suchen;
                   UnBusyWindow(wp,Mainreq);
                  END; 
      
                M_SORTIEREN:
                  BEGIN
{                   Setbusywindow(wp,Mainreq);}
                   sortieren;                   
{                   UnBusyWindow(wp,Mainreq);}
                  END; 
      
                M_SERIENDRUCK:
                  BEGIN
                   Setbusywindow(wp,Mainreq);      
                   unbusywindow(wp,mainreq);
                   IF serdruck=NIL THEN serienbrief;
                  END;

                M_FORMULARDRUCK:
                  BEGIN
                   Setbusywindow(wp,Mainreq);
                   Formularmodus;
                   unbusywindow(wp,mainreq);
                  END;
      
                M_LISTENDRUCK:
                  BEGIN
                   Setbusywindow(wp,Mainreq);      
                   unbusywindow(wp,mainreq);
                  END;
 
                M_BLÄTTERN :
                  BEGIN
                    SetBusyWindow(wp,MainReq);
                    Blättern(AktuellePerson);
                    UnBusyWindow(wp,MainReq);
                  END;
              ELSE END;
         ELSE END;
         msg := GT_GetIMsg(wp^.UserPort);
       END;
    END
   ELSE IF druckwin AND ((mask AND druckmask) = druckmask) THEN
    BEGIN
     serienbriefmsg;
    END;
  UNTIL done;
  dummy := RemoveAppWindow(AppWin);
END;

PROCEDURE InitProgAdrs;
VAR
  b : STRING;
  x : STR;
BEGIN
  New(PNode);
  PNode^.Name := "Schotte";
  PNode^.Vorname := "Björn";
  PNode^.Strasse := "Am Burkardstuhl 45";
  PNode^.Ort := "Himmelstadt";
  PNode^.Plz := "97267";
  PNode^.tel := "09364 89849";
  PNode^.fax := "";
  PNode^.geb := "30.09.1978";
  PNode^.EMail1 := "bjoern@bomber.mayn.de";
  PNode^.EMail2 := "";
  PNode^.anrede := 1;
  PNode^.anrede_s := "";
  PNode^.kommentar := "Programmierer von AddiPro";
  b := PNode^.name+", "+PNode^.vorname;
  x := b;
  NeuePerson(PNode,x);
  New(PNode);
  PNode^.Name := "Klein";
  PNode^.Vorname := "Michael";
  PNode^.Strasse := "Am Wasserturm 6";
  PNode^.Ort := "Speyer";
  PNode^.Plz := "67346";
  PNode^.tel := "06232 77425";
  PNode^.fax := "";
  PNode^.geb := "02.05.1973";
  PNode^.EMail1 := "ujqc@rz.uni-karlsruhe.de";
  PNode^.EMail2 := "";
  PNode^.anrede := 1;
  PNode^.anrede_s := "";
  PNode^.kommentar := "Programmierer von AddiPro";
  b := PNode^.name+", "+PNode^.vorname;
  x := b;
  NeuePerson(PNode,x);
  Anzahl := 2;
  AktuellePerson := p_Person(PList^.lh_Head);
  AktuellGewählt := 0;
END;

{ -- Initialisiert alle Variablen -- }
PROCEDURE InitVars;
VAR s:STRING;
BEGIN
  IF NOT OS39 THEN
  BEGIN
    { Kickstart 2.x-Support für Wartezeiger ! }
    WaitPointerData:=WaitPointerTyp($0000,$0000,
                                    $0400,$07C0,$0000,$07C0,$0100,$0380,$0000,$07E0,
                                    $07C0,$1FF8,$1FF0,$3FEC,$3FF8,$7FDE,$3FF8,$7FBE,
                                    $7FFC,$FF7F,$7EFC,$FFFF,$7FFC,$FFFF,$3FF8,$7FFE,
                                    $3FF8,$7FFE,$1FF0,$3FFC,$07C0,$1FF8,$0000,$07E0,
                                    $0000,$0000);
    WaitPointer    := AllocVec(72,MEMF_CHIP);
    IF WaitPointer = NIL THEN CleanUp(ERRNO_MEMORY, 20);
    CopyMem(^WaitPointerData,WaitPointer,72);
  END;
  mainwinheight:={132}146;
  Anzahl         := 0;
  tattr          := TextAttr("topaz.font",8,0,0);
  AktuellePerson := NIL;
  AktuellGewählt := -1;
  pfad           := "";
  datei          := "";
  DruckerAusgabe := "PRT:";
  pubname        := "";
  passwort:='geht leider noch nicht !!!';
  ff := "";
  fd := "PRT:";
  ff1 := "";
  fd1 := "";
  ff2 := "";
  fd2 := "";
  FOR i := 1 TO 10 DO
    SelectTexte[i] := "Gruppe "+intstr(i);
  PList := NIL;
  New(PList);
  NewList(PList);
  InitProgAdrs;
  oldsecs := 0;
  oldmics := 0;
  AppPort := NIL;
  EditWinLeft := 0;
  EditWinTop := 0;
  BlätterWinLeft := 0;
  BlätterWinTop := 0;
  EinstellWinLeft := 0;
  EinstellWinTop := 0;
  aslf_width:=200;
  aslf_height:=200;
  aslf_topedge:=0;
  aslf_leftedge:=0;
  editor:='c:ed';
  textanzeiger:='c:ppmore';   
  druckwinleft:=50;
  druckwintop:=100;
  Seriendruckwinleft:=50;
  Seriendruckwintop:=0;
  Formulardruckwinleft:=90;
  Formulardruckwintop:=0;
  Listendruckwinleft:=0;
  Listendruckwintop:=0;
  suchwinleft:=0;
  suchwintop:=0;
  Sortierwinleft:=0;
  sortierwintop:=0;
  suchbuf:='';
  Suchpfadwinleft:=0;
  suchpfadwintop:=0;
  selectwinleft:=0;
  selectwintop:=0;
  verschluesseln:=FALSE;
  iconsave:=FALSE;
  autoload:=FALSE;
  serdruck:=NIL;
    { -- Filename der Voreinstellungsdatei (Select-Texte etc.) -- } 
  prefsfile:="ENVARC:AddiPro.env";
  IF holett('PREFSFILE',s) THEN prefsfile:=s;
  eigenname:=holeeigenname;
  IF holett('ICON',s) THEN iconname:=s;
END;

PROCEDURE WBKram;
VAR  s      : STRING;
  
BEGIN
 IF holett('PFAD',s) THEN pfad:=s;
 IF holett('PUBSCREEN',s) THEN pubname:=s;
END;

PROCEDURE DeleteAnyPort(VAR port:p_MsgPort);
VAR
  msg : p_Message;
BEGIN
  Forbid;
  IF Port <> NIL THEN
  BEGIN
    msg := GetMsg(Port);
    WHILE msg <> NIL DO
    BEGIN
      ReplyMsg(msg);
      msg := GetMsg(Port);
    END;
    RemPort(Port);
    DeleteMsgPort(Port);
  END;
  Port := NIL;
  Permit;
END;

{ -- AppIcon/AppWindow-Port -- }
PROCEDURE InitAppPort;
BEGIN
  AppPort := CreateMsgPort;
  IF AppPort = NIL THEN
  BEGIN
    UMeld("Kann keinen Messageport kreieren !!");
    HALT(20);
  END;
  AppPort^.mp_Node.ln_Name := AppName;
  AppPort^.mp_Node.ln_Pri  := 0;
  AppPort^.mp_SigTask      := FindTask(NIL);
  AddPort(AppPort);
END;

PROCEDURE DeleteAppPort;
BEGIN
  DeleteAnyPort(AppPort);
END;



{ -- Kleines Hauptprogramm -- }
BEGIN
  Versionsprüfung;
  OpenLibs;
  opentt;
  InitVars;
  InitAppPort;
  AddExitServer(DeleteAppPort);
  WBKram;
  GetPubScr;
  LoadPrefs;
  Main;
  IF Anzahl > 0 THEN DeleteAllPersons;
  CleanUp("",0);
END.
