home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / cdrom / jukebox_2.1 / jukebox-extensions / source / catviewer.c next >
C/C++ Source or Header  |  1996-01-02  |  18KB  |  706 lines

  1. /* JB-CatViewer -- soll die JukeBox Katalogdateien komfortabler anzeigen */
  2.  
  3. /* INCLUDE */
  4.  
  5. #include <exec/lists.h>
  6. #include <exec/memory.h>
  7. #include <intuition/intuition.h>
  8. #include <libraries/gadtools.h>
  9. #include <clib/alib_protos.h>
  10. #if defined(_DCC)
  11.   #include <clib/intuition_protos.h>
  12.   #include <clib/graphics_protos.h>
  13.   #include <clib/gadtools_protos.h>
  14.   #include <clib/exec_protos.h>
  15.   #include <clib/dos_protos.h>
  16. #else
  17.   #include <proto/intuition.h>
  18.   #include <proto/graphics.h>
  19.   #if defined(__GNUC__)
  20.     #define GT_SetGadgetAttrsA _GT_SetGadgetAttrsA
  21.   #endif
  22.   #include <proto/gadtools.h>
  23.   #if defined(__GNUC__)
  24.     #undef GT_SetGadgetAttrsA
  25.   #endif
  26.   #include <proto/exec.h>
  27.   #include <proto/dos.h>
  28. #endif
  29. #include <string.h>
  30.  
  31. struct VolNode {
  32.    struct Node    ExecNode;
  33.    UBYTE          Pad[2];
  34.    struct MinList TitleHeader;
  35.  };
  36.  
  37. struct FindPara {
  38.    BYTE Success,Pad[3];
  39.    LONG Position;
  40.  };
  41.  
  42. /* P R O T O T Y P E N */
  43.  
  44. void AdjustGadgets(void);
  45. int MakeGadgets(void);
  46. void RemoveGadgets(void);
  47. int MakeLists(void);
  48. void CatchNextString(char *,LONG,struct FindPara *);
  49. struct VolNode *MakeVolNode(char *);
  50. struct Node *MakeNode(char *);
  51. struct MinList *TitleHeaderOfNthVolNode(int);
  52. void FindStr(char *,char *,struct FindPara *);
  53. int CompareFrag(char *,char *);
  54. void ShowMsg(STRPTR);
  55. void Search(int,char *);
  56. void SearchMessage(char *,char *);
  57.  
  58. /*
  59. ** NewList als Makro
  60. */
  61. /* DEFINES */
  62.  
  63. /*
  64. #define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
  65.                     (l)->lh_Tail = NULL, \
  66.                     (l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
  67. */ /* deaktiviert, benutzt amiga.lib NewList! */
  68.  
  69. #define SEARCHLEN 50
  70.  
  71. #define NOTHINGFOUND 0
  72. #define STRINGFOUND  1
  73. #define CROSSFOUND   2
  74.  
  75. #define FROMTOP 0
  76. #define CONTINUE 1
  77. #define INIT 2
  78.  
  79. #define POOLSIZE     4096
  80. #define TRESHSIZE    1024
  81.  
  82. #define DEFAULTIN  "musiccatalog.cat"
  83. #define DEFAULTLEFT "CD"
  84. #define DEFAULTRIGHT "Titel"
  85. #define DEFAULTSEARCH "weitersuchen"
  86. #define DEFAULTFOUND "Text gefunden!"
  87. #define NOMEM        "Not enough memory!\n"
  88. #define ARGSPATTERN "INFILE,LEFTTEXT,RIGHTTEXT,SEARCHTEXT,FOUNDTEXT"
  89.  
  90.  
  91. /* Globale Variablen und Strukturen */
  92.  
  93. const char VERSION[]="$VER: JukeBox-CatView V1.03 by P. Kursawe 1996";
  94.  
  95. /* libnix specials */
  96.  
  97. int __nocommandline = 1;
  98. int __initlibraries = 1;
  99.  
  100.  
  101. struct GfxBase *GfxBase = NULL;
  102. struct IntuitionBase *IntuitionBase = NULL;
  103. struct Library *GadToolsBase=NULL;
  104. struct DosLibrary *DOSBase= NULL;
  105. struct Gadget *gg1ptr = NULL;
  106. struct Gadget *gg2ptr = NULL;
  107. struct Gadget *gg4ptr = NULL;
  108. struct Gadget *gg3ptr = NULL;
  109. struct Gadget *glistptr = NULL;
  110. struct Gadget *context = NULL;
  111. struct VisualInfo *vi = NULL;
  112. struct Gadget *dummygg = NULL;
  113. struct Window *mywindow = NULL;
  114.  
  115. struct MinList Header;
  116.  
  117. APTR mempool;
  118. struct RDArgs *rdargs = NULL;
  119. ULONG Kommandoparameter[] = {
  120.                  (ULONG)DEFAULTIN,
  121.                  (ULONG)DEFAULTLEFT,
  122.                  (ULONG)DEFAULTRIGHT,
  123.                 (ULONG)DEFAULTSEARCH,
  124.                 (ULONG)DEFAULTFOUND
  125.                  };
  126.  
  127.  
  128. char searchstrbuf[SEARCHLEN] = "#?TEXT#?";
  129.  
  130. struct TagItem gg1tags[]={GTLV_Labels,0,GTLV_ShowSelected,TAG_DONE,0};
  131. struct TagItem gg2tags[]={GTLV_Labels,0,GTLV_ReadOnly,TRUE,TAG_DONE,0};
  132. struct TagItem gg3tags[]={GTST_String,(ULONG)&searchstrbuf,GTST_MaxChars,SEARCHLEN,TAG_DONE,0};
  133.  
  134.  
  135.  
  136. struct TextAttr normalfont;
  137.  
  138. struct NewGadget gadget1= 
  139.             {
  140.              0,0,0,0,NULL,&normalfont,1,PLACETEXT_BELOW,0,0
  141.             };
  142. struct NewGadget gadget2=
  143.             {
  144.              0,0,0,0,NULL,&normalfont,2,PLACETEXT_BELOW,0,0
  145.             };
  146. struct NewGadget gadget4=
  147.                         {
  148.                          0,0,0,0,NULL,&normalfont,4,PLACETEXT_IN,0,0
  149.                         };
  150. struct NewGadget gadget3 = 
  151.                {
  152.                 0,0,0,0,NULL,&normalfont,3,0,0,0   
  153.                 };
  154.  
  155. int FontHeight;
  156.  
  157. struct StringInfo * strinf; /* Zwischenspeicher wegen Typecasting */
  158.  
  159. int main()
  160. {
  161.  static struct TagItem wintags[]=
  162.                 {
  163.                  WA_Flags,WFLG_SIZEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE,
  164.                  WA_Left,0,
  165.                  WA_Top,15,
  166.                  WA_MinWidth,400,
  167.                  WA_MinHeight,115,
  168.                  WA_MaxWidth,-1,
  169.                  WA_MaxHeight,-1,
  170.                  WA_Title,(ULONG)"JukeBox Catalog Viewer",
  171.                  WA_Width,640,
  172.                  WA_Height,184,
  173.                  WA_IDCMP,IDCMP_CLOSEWINDOW|LISTVIEWIDCMP|IDCMP_NEWSIZE,
  174.                  TAG_DONE,0
  175.                 };
  176.  struct IntuiMessage *imsg;
  177.  struct Gadget *address;
  178.  ULONG imClass;
  179.  UWORD imCode;
  180.  if((mempool=LibCreatePool(MEMF_CLEAR,POOLSIZE,TRESHSIZE)) == NULL)
  181.   return;
  182.  NewList((struct List *)&Header);
  183.  if((DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37L)))
  184.   {
  185.    if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L)))
  186.     {
  187.      if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L)))
  188.       {
  189.        if((GadToolsBase=OpenLibrary("gadtools.library",37L)))
  190.     {
  191.      /* hier sind alle Libraries offen */
  192.      rdargs=ReadArgs(ARGSPATTERN,Kommandoparameter,NULL);
  193.      gadget1.ng_GadgetText=(UBYTE *)Kommandoparameter[1];
  194.      gadget2.ng_GadgetText=(UBYTE *)Kommandoparameter[2];
  195.      gadget4.ng_GadgetText=(UBYTE *)Kommandoparameter[3];
  196.      if((mywindow=OpenWindowTagList(NULL,wintags)))
  197.       {
  198.        /* Verzweifelter Versuch, den richtigen Font zu nehmen */
  199.            FontHeight = mywindow->IFont->tf_YSize;
  200.            normalfont.ta_YSize = FontHeight;
  201.            normalfont.ta_Name = mywindow->IFont->tf_Message.mn_Node.ln_Name;
  202.            normalfont.ta_Style = mywindow->IFont->tf_Style;
  203.            normalfont.ta_Flags = mywindow->IFont->tf_Flags;
  204.            
  205.            /* daran ändert sich nix... */
  206.            gadget4.ng_Height = FontHeight+6;
  207.            gadget3.ng_Height = FontHeight+6;
  208.            gadget1.ng_LeftEdge = mywindow->BorderLeft+5;
  209.            gadget1.ng_TopEdge  = mywindow->BorderTop+5;
  210.            gadget2.ng_TopEdge  = gadget1.ng_TopEdge;
  211.            gadget3.ng_LeftEdge = gadget1.ng_LeftEdge;
  212.  
  213.  
  214.        AdjustGadgets();
  215.        if((MakeLists()))
  216.         {
  217.           if((MakeGadgets()))
  218.           {
  219.            Search(INIT,""); /* in C++ waere das schoener zu loesen... */
  220.            for(;;)
  221.         {
  222.          if(Wait(1L<<mywindow->UserPort->mp_SigBit|SIGBREAKF_CTRL_C)&SIGBREAKF_CTRL_C)
  223.           break;
  224.          while((imsg=GT_GetIMsg(mywindow->UserPort)) != NULL)
  225.           {
  226.            imClass = imsg->Class;
  227.            imCode  = imsg->Code;
  228.            address = imsg->IAddress;
  229.            GT_ReplyIMsg(imsg);
  230.                  
  231.                  strinf = (struct StringInfo *)gg3ptr->SpecialInfo; /*Wie sonst soll man den korrekt dereferenzieren? */
  232.  
  233.            switch(imClass)
  234.             {
  235.              case IDCMP_CLOSEWINDOW:
  236.               goto ende;
  237.              case IDCMP_GADGETUP:
  238.               if(address->GadgetID==1)
  239.                {
  240.                 gg2tags[0].ti_Data=(ULONG)TitleHeaderOfNthVolNode(imCode);
  241.                 GT_SetGadgetAttrsA(gg2ptr,mywindow,NULL,gg2tags);
  242.                }
  243.               if(address->GadgetID==4)
  244.                {
  245.             Search(CONTINUE,(char *)strinf->Buffer);
  246.                }
  247.               if(address->GadgetID==3)
  248.                {
  249.                 Search(FROMTOP,(char *)strinf->Buffer);
  250.                }
  251.               break;
  252.              case IDCMP_NEWSIZE:
  253.               strcpy(searchstrbuf,(char *)strinf->Buffer);
  254.               RemoveGadgets();
  255.               AdjustGadgets();
  256.               MakeGadgets();
  257.              default:
  258.               break;
  259.             }
  260.           }
  261.         }
  262.     ende:
  263.            RemoveGadgets();
  264.           }
  265.          else
  266.           {
  267.            ShowMsg("Could not allocate Gadgets.\n");
  268.           }
  269.          LibDeletePool(mempool);
  270.         }
  271.        else
  272.         {
  273.          ShowMsg("Could not build lists\n");
  274.         }
  275.        CloseWindow(mywindow);
  276.       }
  277.       FreeArgs(rdargs);
  278.      /* alle Libraries schließen */
  279.      CloseLibrary(GadToolsBase);
  280.     }
  281.        else
  282.         {
  283.          ShowMsg("Can't open gadtools.library V37.\n");
  284.         }
  285.        CloseLibrary((struct Library *)IntuitionBase);
  286.       }
  287.      else
  288.       {
  289.        ShowMsg("Can't open intuition.library V37.\n");
  290.       }
  291.      CloseLibrary((struct Library *)GfxBase);
  292.     }
  293.    else
  294.     {
  295.      ShowMsg("Can't open graphics.library V37.\n");
  296.     }
  297.    CloseLibrary((struct Library *)DOSBase);
  298.   }
  299.  return 0;
  300. }
  301.  
  302. /* -------------------------------------- */
  303. /*            UNTERROUTINEN               */
  304. /* -------------------------------------- */
  305.  
  306. void AdjustGadgets(void)
  307.  {
  308.   gadget1.ng_Height   = mywindow->Height - mywindow->BorderBottom - 2*FontHeight - 16 - gadget1.ng_TopEdge;
  309.   if(gadget1.ng_Height < 5)
  310.    {
  311.     gadget1.ng_Height = 5;
  312.    }
  313.   gadget1.ng_Width    = ( (mywindow->Width - mywindow->BorderLeft - mywindow-> BorderRight - 15) / 2);
  314.    if(gadget1.ng_Width < 10)
  315.     {
  316.      gadget1.ng_Width = 10;
  317.     }
  318.  
  319.   gadget2.ng_LeftEdge = gadget1.ng_Width + gadget1.ng_LeftEdge + 5;
  320.   gadget2.ng_Height   = gadget1.ng_Height;
  321.   gadget2.ng_Width    = gadget1.ng_Width;
  322.  
  323.   gadget4.ng_TopEdge = gadget1.ng_TopEdge + gadget1.ng_Height + FontHeight + 5;
  324.   gadget4.ng_Width = 200; /* sollte reichen...*/
  325.   gadget4.ng_LeftEdge = gadget2.ng_LeftEdge + gadget2.ng_Width - gadget4.ng_Width;
  326.  
  327.   gadget3.ng_TopEdge = gadget4.ng_TopEdge;
  328.   gadget3.ng_Width = gadget2.ng_LeftEdge + gadget2.ng_Width - gadget4.ng_Width - 5 - gadget3.ng_LeftEdge;
  329.  }
  330.  
  331. /* Muß hier Gadgets belegen und einbinden. */
  332.  
  333. int MakeGadgets(void)
  334.  {
  335.  
  336.   int ret=FALSE;
  337.  
  338.   if((vi=GetVisualInfoA(mywindow->WScreen,NULL)))
  339.    {
  340.  
  341.     gadget1.ng_VisualInfo = vi;
  342.     gadget2.ng_VisualInfo = vi;
  343.     gadget4.ng_VisualInfo = vi;
  344.     gadget3.ng_VisualInfo = vi;
  345.  
  346.     if((dummygg=CreateContext(&glistptr)))
  347.      {
  348.       if((gg1ptr=CreateGadgetA(LISTVIEW_KIND,dummygg,&gadget1,gg1tags)))
  349.        {
  350.     if((gg2ptr=CreateGadgetA(LISTVIEW_KIND,gg1ptr,&gadget2,gg2tags)))
  351.      {
  352.       if((gg4ptr=CreateGadgetA(BUTTON_KIND,gg2ptr,&gadget4,NULL)))
  353.        {
  354.         if((gg3ptr=CreateGadgetA(STRING_KIND,gg4ptr,&gadget3,gg3tags)))
  355.          {
  356.           ret=TRUE;
  357.           strinf = (struct StringInfo *)gg3ptr->SpecialInfo;
  358.           strcpy((char *)strinf->Buffer,searchstrbuf);
  359.           EraseRect(mywindow->RPort,mywindow->BorderLeft,mywindow->BorderTop,mywindow->Width-mywindow->BorderRight-1,mywindow->Height-mywindow->BorderBottom-1);
  360.           AddGList(mywindow,glistptr,-1,-1,0);
  361.           RefreshWindowFrame(mywindow);
  362.           GT_RefreshWindow(mywindow,0);
  363.          }
  364.            }
  365.      }
  366.     else
  367.      {
  368.       FreeGadgets(glistptr);
  369.       glistptr = NULL;
  370.      }
  371.        }
  372.      }
  373.     else
  374.      {
  375.       FreeVisualInfo(vi);
  376.      }
  377.    }
  378.   return(ret);
  379.  }
  380.  
  381. void RemoveGadgets(void)
  382.  {
  383.   if((glistptr))
  384.    {
  385.     RemoveGList(mywindow,glistptr,-1);
  386.     FreeGadgets(glistptr);
  387.     FreeVisualInfo(vi);
  388.    }
  389.  }
  390.  
  391. int MakeLists(void)
  392.  {
  393.   struct FileInfoBlock *fib = NULL;
  394.   struct VolNode *voln=NULL;
  395.   struct Node *node=NULL;
  396.   struct FindPara Paras;
  397.   BPTR filehandle = NULL;
  398.   BYTE *buffer;
  399.   int ret = FALSE;
  400.   LONG pos=0;
  401.   Paras.Success = CROSSFOUND; Paras.Position = 0;
  402.  
  403.   if((fib=AllocDosObject(DOS_FIB,NULL)))
  404.    {
  405.     if((filehandle=Open((char *)Kommandoparameter[0],MODE_OLDFILE)))
  406.      {
  407.       if(DOSTRUE==ExamineFH(filehandle,fib))
  408.        {
  409.         if((buffer=LibAllocPooled(mempool,fib->fib_Size)))
  410.          {
  411.            Read(filehandle,buffer,fib->fib_Size);
  412.           /* Eigentliche Bearbeitung der Textdatei */
  413.        gg1tags[0].ti_Data=(ULONG)&Header;
  414.       while((Paras.Success != NOTHINGFOUND)&&((int)pos < (int)buffer + (int)fib->fib_Size))
  415.        {
  416.             pos=pos+Paras.Position;
  417.         switch(Paras.Success)
  418.          {
  419.           case STRINGFOUND:
  420.            pos=Paras.Position;
  421.            if((voln))
  422.             {
  423.              if((node=MakeNode(&buffer[pos])))
  424.               {
  425.                AddTail((struct List *)&voln->TitleHeader,node);
  426.               }
  427.                 }
  428.            pos=pos+strlen(&buffer[pos]);
  429.            break;
  430.           case CROSSFOUND:
  431.            pos = pos + Paras.Position;
  432.            CatchNextString(buffer,pos,&Paras);
  433.            if(Paras.Success == STRINGFOUND)
  434.             {
  435.              pos=Paras.Position;
  436.              if((voln=MakeVolNode(&buffer[pos])))
  437.               {
  438.                AddTail((struct List *)&Header,&voln->ExecNode);
  439.                ret=TRUE;
  440.               }
  441.              pos=pos+strlen(&buffer[pos]);
  442.             }
  443.            break;
  444.           default:
  445.            break;
  446.          }
  447.             CatchNextString(buffer,pos,&Paras);
  448.            }
  449.           /* fertig.... */
  450.       LibFreePooled(mempool,buffer,fib->fib_Size);
  451.          }
  452.         else
  453.          {
  454.           ShowMsg(NOMEM);
  455.          }
  456.        }
  457.       else
  458.        {
  459.         ShowMsg("Examine failed.\n");
  460.        }
  461.       Close(filehandle);
  462.      }
  463.     else
  464.      {
  465.       ShowMsg("Could not open \"");
  466.       ShowMsg((char *)Kommandoparameter[0]);
  467.       ShowMsg("\".\n");
  468.      }
  469.     FreeDosObject(DOS_FIB,fib);
  470.    }
  471.   else
  472.    {
  473.     ShowMsg("Could not allocate FileInfoBlock.\n");
  474.    }
  475.   return(ret);
  476.  }
  477.  
  478. /* Sucht einen String */
  479.  
  480. void CatchNextString(char *Puffer,LONG position,struct FindPara *parameter)
  481.  {
  482.   LONG posbak=0;
  483.   FindStr(&Puffer[position],">=\"",parameter);
  484.   if(parameter->Success == STRINGFOUND)
  485.    {
  486.     parameter->Position=parameter->Position+3;
  487.     position= position + parameter->Position;
  488.     FindStr(&Puffer[position],"\"",parameter);
  489.     if(parameter->Success != NOTHINGFOUND)
  490.      {
  491.       while(parameter->Success==CROSSFOUND)
  492.        {
  493.         posbak=parameter->Position+posbak;
  494.         FindStr(&Puffer[posbak+position],"\"",parameter);
  495.        }
  496.       Puffer[position + parameter->Position+posbak]=0;
  497.       parameter->Position=position;
  498.      }
  499.     else
  500.      {
  501.       parameter->Success=NOTHINGFOUND;
  502.      }
  503.    }
  504.  }
  505.  
  506. /* Erzeugt Nodes mit Eintrag fuer Liste der Titel */
  507.  
  508. struct VolNode *MakeVolNode(char string[])
  509.  {
  510.   struct VolNode *mem;
  511.  
  512.   if((mem=LibAllocPooled(mempool,sizeof(struct VolNode)+strlen(string)+1)))
  513.    {
  514.     mem->ExecNode.ln_Name=(char *)(mem+1);
  515.     NewList((struct List *)&mem->TitleHeader);
  516.     strcpy((char *)(mem+1),string);
  517.    }
  518.   else
  519.    {
  520.     ShowMsg(NOMEM);
  521.    }
  522.   return mem;
  523.  }
  524.  
  525. /* Erzeugt stinknormale Nodes (mit Name dahinter, natürlich! */
  526.  
  527. struct Node *MakeNode(char string[])
  528.  {
  529.   struct Node *mem;
  530.  
  531.   if((mem=LibAllocPooled(mempool,sizeof(struct Node)+strlen(string)+1)))
  532.    {
  533.     mem->ln_Name=(char *)(mem+1);
  534.     strcpy((char *)(mem+1),string);
  535.    }
  536.   else
  537.    {
  538.     ShowMsg(NOMEM);
  539.    }
  540.   return(mem);
  541.  }
  542.  
  543. /* Gibt einen Zeiger auf den TitleHeader der n-ten VolNode zurück, NULL, falls leer! */
  544.  
  545. struct MinList *TitleHeaderOfNthVolNode(int Number)
  546.  {
  547.   struct MinList *titleheader = NULL;
  548.   struct VolNode *voln = NULL;
  549.   int IsNumber = 0;
  550.   voln = (struct VolNode *)Header.mlh_Head;
  551.   for(;IsNumber < Number;IsNumber++)
  552.    {
  553.     voln = (struct VolNode *)voln->ExecNode.ln_Succ;
  554.    }
  555.   titleheader=&voln->TitleHeader;
  556.   if((struct MinList *)titleheader->mlh_TailPred == titleheader)
  557.    {
  558.     titleheader = NULL;
  559.    }
  560.   return(titleheader);
  561.  }
  562.  
  563. /* Suche StringB in StringA, gebe Byte des Fundes zurück oder 0. Sucht maximal 5000 Bytes lang! */
  564. /* Gibt Erfolgsmeldung in der Struktur, wenn Kreuz zeigt Position 1 hinter Kreuz! */
  565.  
  566. void FindStr(char *StringA,char *StringB,struct FindPara *result)
  567.  {
  568.   LONG ret = 0;
  569.  
  570.   while(ret < 5000)
  571.    {
  572.     if(StringA[ret]=='#')
  573.      {
  574.       result->Success = CROSSFOUND;
  575.       result->Position = ret+1;
  576.       return;
  577.      }
  578.     if(StringA[ret]==StringB[0])
  579.      {
  580.       if(CompareFrag(&StringA[ret],StringB)==TRUE)
  581.        {
  582.         result->Position = ret;
  583.         result->Success = STRINGFOUND;
  584.         return;
  585.        }
  586.      }
  587.      ret++;
  588.    }
  589.    result->Success = NOTHINGFOUND;
  590.    return;
  591.  }
  592.  
  593. /* Überprüft, ob Frag der Anfang von Text ist. (Bsp: Te in Test, nicht aber Te in DerTest) */
  594.  
  595. int CompareFrag(char *Text,char *Frag)
  596.  {
  597.   LONG cnt = 0;
  598.   while(Frag[cnt] != 0)
  599.    {
  600.     if(Frag[cnt]!=Text[cnt])
  601.      {
  602.       return(FALSE);
  603.      }
  604.     cnt++;
  605.    }
  606.   return(TRUE);
  607.  }
  608.  
  609. /* gibt nur ne Meldung aus ;) */
  610.  
  611. void ShowMsg(STRPTR msg)
  612.  {
  613.   PutStr(msg);
  614.  }
  615.  
  616.  
  617. /* durchsucht die liste, gibt selbsttaetig Erfolgsmeldung */
  618.  
  619. void Search(int task,char * texttofind)
  620.  {
  621.   
  622.   static struct VolNode * currentvol;
  623.   static struct VolNode * lastfoundvol;
  624.   static int volnodecounter, nodecounter;
  625.   static struct Node * currentnode;
  626.   static char patternbuf[SEARCHLEN*2+2];
  627.   
  628.   if(ParsePatternNoCase(texttofind,patternbuf,SEARCHLEN*2+2) == -1)
  629.    {
  630.     return;
  631.    }
  632.  
  633.  switch(task)
  634.   {
  635.    case INIT:
  636.      volnodecounter = 0;
  637.      nodecounter = 0;
  638.      currentnode = NULL;
  639.      currentvol = (struct VolNode *)Header.mlh_Head;
  640.      lastfoundvol = NULL;
  641.      return;
  642.     break;
  643.    case CONTINUE:
  644.     lastfoundvol = currentvol;
  645.     break;
  646.    case FROMTOP:
  647.      currentnode = 0;
  648.      lastfoundvol = 0;
  649.      currentvol = (struct VolNode *)Header.mlh_Head;
  650.      volnodecounter = 0;
  651.      nodecounter = 0;
  652.     break;
  653.   }
  654.  
  655.  while(currentvol != (struct VolNode *)&Header.mlh_Tail)
  656.   {
  657.    /* Volumes scannen */
  658.    if((MatchPatternNoCase(patternbuf,(char *)(currentvol+1))!=NULL) && (lastfoundvol != currentvol))
  659.     {
  660.      SearchMessage((char *)(currentvol+1),"---");
  661.      return;
  662.     }
  663.    if(currentvol->TitleHeader.mlh_TailPred != (struct MinNode *)¤tvol->TitleHeader)
  664.     {
  665.      /* Titeleintraege scannen */
  666.  
  667.     if(currentnode == 0)
  668.      {
  669.       currentnode = (struct Node *)currentvol->TitleHeader.mlh_Head;
  670.      }
  671.      
  672.      while(currentnode != (struct Node *)¤tvol->TitleHeader.mlh_Tail)
  673.       {
  674.        if(MatchPatternNoCase(patternbuf,(char*)(currentnode+1))!=NULL)
  675.         {
  676.          SearchMessage((char *)(currentvol+1),(char *)(currentnode+1));
  677.          currentnode = currentnode->ln_Succ;
  678.          nodecounter++;
  679.          return;
  680.         }
  681.        nodecounter++;
  682.        currentnode = currentnode->ln_Succ;
  683.       }
  684.    currentnode = 0;
  685.    nodecounter = 0;
  686.    volnodecounter++;
  687.      
  688.     }
  689.    currentvol = (struct VolNode *)currentvol->ExecNode.ln_Succ;
  690.   }
  691.   DisplayBeep(mywindow->WScreen);
  692.  }
  693.  
  694. void SearchMessage(char * voltext,char * nodetext)
  695.  {
  696.   static struct EasyStruct myeasystruct = {
  697.    sizeof(struct EasyStruct),0,0,"%s: %s\n%s: %s","OK"
  698.    };
  699.   static char * myarglist[4];
  700.   myeasystruct.es_Title = (UBYTE *)Kommandoparameter[4];
  701.   myarglist[0] = (char *)Kommandoparameter[1];
  702.   myarglist[1] = voltext;
  703.   myarglist[2] = (char *)Kommandoparameter[2];
  704.   myarglist[3] = nodetext;  
  705.   EasyRequestArgs(mywindow,&myeasystruct,NULL,myarglist);
  706.  }