home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #3
/
amigamamagazinepolishissue1998.iso
/
bazy
/
cdindexb2
/
txt
/
cdindex.mod
Wrap
Text File
|
1996-03-08
|
38KB
|
1,168 lines
MODULE CDIndex;
IMPORT
id:IntuitionD, il:IntuitionL,
gtd:GadToolsD, gtl:GadToolsL,
ed:ExecD, el:ExecL, es:ExecSupport,
dd:DosD, dl:DosL, ds:DosSupport,
gd:GraphicsD,
ie:InputEvent,
String;
(*
FROM Terminal IMPORT
WriteString, WriteInt;
FROM Arts IMPORT
BreakPoint;
*)
FROM CommoditiesSupport IMPORT
ArgInt, ArgString;
FROM Conversions IMPORT
ValToStr;
FROM UtilityD IMPORT
tagEnd;
FROM SYSTEM IMPORT
ADR, ADDRESS, CAST, TAG;
CONST
(* Gadget IDs *)
CDIDNO = 0;
INTERPRET = 1;
TITLE = 2;
TRACKLISTING = 3;
SEARCHAREA = 4;
STARTSEARCH = 5;
SEARCHPATTERN = 6;
PREVIOUS = 7;
NEXT = 8;
MESSAGE = 9;
ITEMSVISIBLE = 11; (* Soviele Items können im Listview-Gadget angezeigt werden. *)
TYPE
StringPtr = POINTER TO ARRAY [0..16383] OF CHAR;
SearchArea = (SAanywhere, SAartist, SAtitle, SAtracklisting);
SearchInfo = RECORD
buffer: StringPtr;
titlestart: LONGINT;
trackstart: LONGINT;
END;
SearchInfoPtr = POINTER TO SearchInfo;
StringList = ARRAY [0..4] OF ADDRESS;
CDData = RECORD
artist: StringPtr;
title: StringPtr;
tracks: ed.List;
END;
CDDataPtr = POINTER TO CDData;
VAR
searchareaLabels := StringList{
ADR("Anywhere"),
ADR("Artist"),
ADR("Title"),
ADR("Track listing"),
NIL};
topazfont: gd.TextAttr;
DISKSPATH: StringPtr;
(* Punktvergabe in der Suche *)
INARTIST : INTEGER; (* 10 Punkte, wenn Suchbegriff im Interpreten *)
INTITLE : INTEGER; (* 10 , Title *)
FULLWORD : INTEGER; (* 5 , ganzes Wort *)
MATCHONLY: INTEGER; (* 1 Punkt , im Wort *)
VAR
BMSkipArray: ARRAY [0..255] OF INTEGER;
searchresults: ed.List;
currentsearchresult: ed.NodePtr;
currentCDNumber: INTEGER;
totalCDsFound: INTEGER;
totalHits: INTEGER;
maxPoints: INTEGER;
itemcount, maxitems: INTEGER;
VAR
mainWindow : id.WindowPtr;
glist: id.GadgetPtr;
visualinfo: ADDRESS;
artistGadget: id.GadgetPtr;
titleGadget: id.GadgetPtr;
tracklistingGadget: id.GadgetPtr;
patternGadget: id.GadgetPtr;
searchareaGadget: id.GadgetPtr;
startsearchGadget: id.GadgetPtr;
previousGadget, nextGadget: id.GadgetPtr;
messageGadget: id.GadgetPtr;
VAR
proclevel: INTEGER;
PROCEDURE EnterProc(msg: ARRAY OF CHAR);
VAR
i: INTEGER;
BEGIN
(*
FOR i := 1 TO proclevel DO
WriteString (" ");
END;
WriteString ("--> ");
WriteString (msg);
*)
INC (proclevel);
END EnterProc;
PROCEDURE LeaveProc(msg: ARRAY OF CHAR);
VAR
i: INTEGER;
BEGIN
DEC (proclevel);
(*
FOR i := 1 TO proclevel DO
WriteString (" ");
END;
WriteString ("<-- ");
WriteString (msg);
*)
END LeaveProc;
PROCEDURE DebugMsg(msg: ARRAY OF CHAR);
VAR
i: INTEGER;
BEGIN
(*
FOR i := 1 TO proclevel DO
WriteString (" ");
END;
WriteString (msg);
*)
END DebugMsg;
(* strdup() kopiert die übergebene Zeichenkette. Der hierfür
* reservierte Speicher muß von der aufrufenden Prozedur
* mit ExecL.FreeVec() wieder freigegeben werden.
*)
PROCEDURE strdup (VAR source: ARRAY OF CHAR) : ADDRESS;
VAR
target: StringPtr;
BEGIN
EnterProc ("strdup()\n");
target := el.AllocVec(String.Length(source)+1, ed.MemReqSet{ed.memClear});
IF target # NIL THEN
String.Copy (target^, source);
END;
LeaveProc ("strdup.\n");
RETURN target;
END strdup;
PROCEDURE IsWhitespace (c: CHAR): BOOLEAN;
BEGIN
RETURN (c = " ") OR (c = "\t") OR (c = "\n");
END IsWhitespace;
PROCEDURE IsAlpha (c: CHAR) : BOOLEAN;
BEGIN
RETURN ((c >= "a") AND (c <= "z")) OR ((c >= "A") AND (c <= "Z"));
END IsAlpha;
PROCEDURE Fullword (
word: StringPtr;
startpos: INTEGER;
length: INTEGER) : BOOLEAN;
VAR
beginning, end: BOOLEAN;
BEGIN
beginning := (startpos = 0) OR NOT(IsAlpha(word^[startpos-1]));
end := NOT(IsAlpha(word^[startpos+length]));
RETURN beginning AND end;
END Fullword;
PROCEDURE IsLowerCase (VAR string: ARRAY OF CHAR): BOOLEAN;
VAR
i: INTEGER;
lowercase: BOOLEAN;
BEGIN
lowercase := TRUE;
i := 0;
WHILE ((string[i] # 0C) AND lowercase) DO
lowercase := string[i] # CAP(string[i]);
INC (i);
END;
RETURN lowercase;
END IsLowerCase;
PROCEDURE FreeSearchResultsList (searchresults: ed.ListPtr);
VAR
node, nextnode: ed.NodePtr;
BEGIN
node := searchresults^.head;
IF node # NIL THEN
WHILE (node^.succ # NIL) DO
IF node^.name # NIL THEN
el.FreeVec(node^.name);
END;
nextnode := node^.succ;
el.FreeVec (node);
node := nextnode;
END;
END;
WITH searchresults^ DO
head := NIL;
tail := NIL;
tailPred := NIL;
END;
END FreeSearchResultsList;
PROCEDURE FreeList (list: ed.ListPtr);
BEGIN
FreeSearchResultsList (list);
END FreeList;
PROCEDURE GetNodeName (pos: INTEGER; list: ed.ListPtr) : StringPtr;
VAR
node: ed.NodePtr;
BEGIN
IF (list = NIL) OR (list^.head = NIL) THEN
RETURN NIL;
END;
node := list^.head;
WHILE (node^.succ # NIL) AND (pos > 0) DO
node := node^.succ;
DEC (pos);
END;
RETURN node^.name;
END GetNodeName;
PROCEDURE FreeCDData (cddata: CDDataPtr);
BEGIN
WITH cddata^ DO
IF artist # NIL THEN
el.FreeVec (artist);
artist := NIL;
END;
IF title # NIL THEN
el.FreeVec (title);
title := NIL;
END;
FreeList (ADR(tracks));
END;
END FreeCDData;
PROCEDURE WriteList (list: ed.ListPtr);
VAR
node: ed.NodePtr;
BEGIN
(*
node := list^.head;
IF node # NIL THEN
WHILE (node^.succ # NIL) DO
WriteString (CAST(StringPtr, node^.name)^);
WriteString (" hits=");
WriteInt (node^.pri, 0);
WriteString ("\n");
node := node^.succ;
END;
ELSE
WriteString ("The list is empty.\n");
END;
*)
END WriteList;
PROCEDURE CreateMainWindow;
VAR
ng: gtd.NewGadget;
gadget: id.GadgetPtr;
newgadget: gtd.NewGadget;
screen: id.ScreenPtr;
bool: BOOLEAN;
taglist: ARRAY [0..39] OF LONGINT;
BEGIN
(* Das Hauptfenster soll auf dem Default-PublicScreen geöffnet
* werden:
*)
WITH topazfont DO
name := ADR("topaz.font");
ySize := 8;
style := gd.FontStyleSet{};
flags := gd.FontFlagSet{};
END;
screen := il.LockPubScreen(NIL);
IF screen # NIL THEN
visualinfo := gtl.GetVisualInfoA(screen, NIL);
IF visualinfo # NIL THEN
glist := NIL;
gadget := gtl.CreateContext(glist);
(* Gadgets initialisieren: *)
WITH newgadget DO
leftEdge := 68;
topEdge := 2;
width := 280;
height := 12;
gadgetText := ADR("_Artist:");
textAttr := ADR(topazfont);
flags := gtd.NewGadgetFlagSet{gtd.placetextLeft, gtd.ngHighlabel};
gadgetID := INTERPRET;
visualInfo := visualinfo;
userData := NIL;
END;
gadget := gtl.CreateGadgetA(gtd.textKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
gtd.gttxBorder, TRUE,
gtd.gttxText, ADR("© 1996 Fin Schuppenhauer"),
tagEnd));
artistGadget := gadget;
WITH newgadget DO
INC (topEdge, height + 2);
gadgetText := ADR("_Title:");
gadgetID := TITLE;
END;
gadget := gtl.CreateGadgetA(gtd.textKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
gtd.gttxBorder, TRUE,
gtd.gttxText, ADR('See "CDIndex.readme" for details.'),
tagEnd));
titleGadget := gadget;
WITH newgadget DO
INC (topEdge, height + 2);
leftEdge := 4;
width := 344;
height := 96;
gadgetText := NIL;
gadgetID := TRACKLISTING;
END;
gadget := gtl.CreateGadgetA(gtd.listviewKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
gtd.gtlvShowSelected, NIL,
tagEnd));
tracklistingGadget := gadget;
WITH newgadget DO
INC (topEdge, height - 2);
leftEdge := 76;
width := 272;
height := 12;
gadgetText := ADR("_Pattern:");
flags := gtd.NewGadgetFlagSet{gtd.placetextLeft, gtd.ngHighlabel};
gadgetID := SEARCHPATTERN;
END;
gadget := gtl.CreateGadgetA(gtd.stringKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
tagEnd));
patternGadget := gadget;
WITH newgadget DO
INC (topEdge, height + 2);
leftEdge := 4;
width := 136;
height := 14;
gadgetID := SEARCHAREA;
END;
gadget := gtl.CreateGadgetA(gtd.cycleKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
gtd.gtcyLabels, ADR(searchareaLabels),
tagEnd));
searchareaGadget := gadget;
WITH newgadget DO
INC (leftEdge, width + 4);
gadgetText := ADR("Start _Search");
flags := gtd.NewGadgetFlagSet{gtd.placetextIn};
gadgetID := STARTSEARCH;
END;
gadget := gtl.CreateGadgetA(gtd.buttonKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
tagEnd));
startsearchGadget := gadget;
WITH newgadget DO
INC (leftEdge, width + 2);
width := 32;
gadgetText := ADR("_<");
gadgetID := PREVIOUS;
END;
gadget := gtl.CreateGadgetA(gtd.buttonKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
id.gaDisabled, TRUE,
tagEnd));
previousGadget := gadget;
WITH newgadget DO
INC (leftEdge, width + 2);
gadgetText := ADR("_>");
gadgetID := NEXT;
END;
gadget := gtl.CreateGadgetA(gtd.buttonKind, gadget^, newgadget, TAG(taglist,
gtd.gtUnderscore, "_",
id.gaDisabled, TRUE,
tagEnd));
nextGadget := gadget;
WITH newgadget DO
INC (topEdge, height+2);
leftEdge := 4;
width := 344;
gadgetText := NIL;
gadgetID := MESSAGE;
END;
gadget := gtl.CreateGadgetA(gtd.textKind, gadget^, newgadget, TAG(taglist,
gtd.gttxText, ADR("Please, enter search pattern."),
gtd.gttxBorder, TRUE,
gtd.gttxJustification, id.ActivationFlagSet{id.stringRight},
tagEnd));
messageGadget := gadget;
mainWindow := il.OpenWindowTagList(NIL, TAG(taglist,
id.waLeft, ArgInt(ADR("WINX"), 0),
id.waTop, ArgInt(ADR("WINY"), 0),
id.waWidth, 360,
id.waInnerHeight, newgadget.topEdge + newgadget.height + 2,
id.waMaxWidth, screen^.width,
id.waMaxHeight, screen^.height,
id.waIDCMP, id.IDCMPFlagSet{id.refreshWindow, id.closeWindow, id.vanillaKey, id.rawKey} +
gtd.textIDCMP +
gtd.buttonIDCMP +
gtd.listviewIDCMP +
gtd.cycleIDCMP,
id.waGadgets, glist,
id.waTitle, ADR("CDIndex (Beta Release #2)"),
id.waCloseGadget, TRUE,
id.waDragBar, TRUE,
id.waDepthGadget, TRUE,
(* id.waSizeGadget, TRUE, *)
id.waSizeBBottom, TRUE,
id.waActivate, TRUE,
id.waGimmeZeroZero, TRUE,
id.waPubScreen, screen,
tagEnd));
IF mainWindow # NIL THEN
il.UnlockPubScreen (NIL, screen);
gtl.GTRefreshWindow (mainWindow, NIL);
bool := il.ActivateGadget(patternGadget, mainWindow, NIL);
END;
END;
END;
END CreateMainWindow;
PROCEDURE SetMessage (msg: StringPtr);
VAR
taglist: ARRAY [0..9] OF LONGINT;
BEGIN
gtl.GTSetGadgetAttrsA (messageGadget, mainWindow, NIL, TAG(taglist,
gtd.gttxText, msg,
tagEnd));
END SetMessage;
(* --------------------------------------------------------------- *)
PROCEDURE LoadNextFile (
filelock: dd.FileLockPtr;
fib: dd.FileInfoBlockPtr;
searchinfo: SearchInfoPtr) : BOOLEAN;
VAR
filename: ARRAY [0..1023] OF CHAR;
filehandle: dd.FileHandlePtr;
li: LONGINT;
BEGIN
EnterProc ("LoadNextFile()\n");
String.Copy (filename, DISKSPATH^);
String.Concat (filename, fib^.fileName);
DebugMsg ("loading file '");
(*
WriteString (filename);
WriteString ("'...\n");
*)
filehandle := ds.Open(ADR(filename), dd.oldFile);
IF filehandle # NIL THEN
DebugMsg (" file opened\n");
searchinfo^.buffer := el.AllocVec(fib^.size + 1, ed.MemReqSet{ed.memClear});
IF searchinfo^.buffer # NIL THEN
DebugMsg ("memory allocated\n");
li := dl.Read (filehandle, searchinfo^.buffer, fib^.size);
END;
DebugMsg ("data read\n");
(* Startpositionen des Titels und der Tracks ermitteln: *)
searchinfo^.titlestart := String.FirstPos (searchinfo^.buffer^, 0, "\n") + 1;
searchinfo^.trackstart := String.FirstPos (searchinfo^.buffer^, searchinfo^.titlestart, "\n") + 1;
DebugMsg ("positions marked\n");
ds.Close (filehandle);
END;
LeaveProc ("LoadNextFile.\n");
RETURN dl.ExNext(filelock, fib);
END LoadNextFile;
PROCEDURE LoadCDData (filename: StringPtr; cddata: CDDataPtr);
VAR
filehandle: dd.FileHandlePtr;
pathname: ARRAY [0..511] OF CHAR;
line: ARRAY [0..511] OF CHAR;
node: ed.NodePtr;
eof: BOOLEAN;
BEGIN
EnterProc ("LoadCDData\n");
FreeCDData (cddata);
maxitems := 0;
itemcount := 0;
es.NewList (ADR(cddata^.tracks));
IF filename # NIL THEN
String.Copy (pathname, DISKSPATH^);
String.Concat (pathname, filename^);
filehandle := ds.Open(ADR(pathname), dd.oldFile);
IF filehandle # NIL THEN
DebugMsg ("file opened\n");
(* Namen des Interpreten einlesen: *)
eof := (dl.FGets(filehandle, ADR(line), 512) = NIL);
IF NOT(eof) THEN
cddata^.artist := strdup(line);
cddata^.artist^[String.Length(cddata^.artist^)-1] := 0C;
(* Title einlesen: *)
eof := (dl.FGets(filehandle, ADR(line), 512) = NIL);
IF NOT(eof) THEN
cddata^.title := strdup(line);
cddata^.title^[String.Length(cddata^.title^)-1] := 0C;
END;
END;
(* Tracks einlesen und in Exec-Listenstruktur für das
* Listview-Gadget einlesen:
*)
WHILE ~eof DO
node := el.AllocVec(SIZE(ed.Node), ed.MemReqSet{ed.memClear});
IF node # NIL THEN
DebugMsg ("Node mem allocated\n");
eof := (dl.FGets(filehandle, ADR(line), 512) = NIL);
IF NOT(eof) THEN
line[String.Length(line)-1] := 0C;
node^.name := strdup(line);
el.AddTail (ADR(cddata^.tracks), node);
INC (maxitems);
END;
ELSE
eof := TRUE;
END;
END;
ds.Close (filehandle);
END;
END;
LeaveProc ("LoadCDData\n");
END LoadCDData;
(* --------------------------------------------------------------- *)
(* Initialisierung des Sprung-Arrays für die übergebene Zeichenkette.
* Das Sprungarray (BMSkipArray) gibt an, um wieviele Zeichen die
* zu vergleichende Zeichenkette verschoben werden kann, wenn ein
* Zeichen nicht übereinstimmt.
*)
PROCEDURE InitBMSearch (pattern: StringPtr; length: INTEGER);
VAR
i: INTEGER; (* Schleifenvariable *)
BEGIN
EnterProc ("InitBMSearch()\n");
FOR i := 0 TO 255 DO
BMSkipArray[i] := length;
END;
DEC (length);
FOR i := 0 TO length DO
BMSkipArray[ORD(pattern^[i])] := length-i;
END;
LeaveProc ("InitBMSearch.\n");
END InitBMSearch;
PROCEDURE InitBMUppercaseSearch (pattern: StringPtr; length: INTEGER);
VAR
i: INTEGER; (* Schleifenvariable *)
BEGIN
EnterProc ("InitBMUppercaseSearch()\n");
FOR i := 0 TO 255 DO
BMSkipArray[i] := length;
END;
DEC (length);
FOR i := 0 TO length DO
BMSkipArray[ORD(CAP(pattern^[i]))] := length-i;
END;
LeaveProc ("InitUppercaseBMSearch.\n");
END InitBMUppercaseSearch;
PROCEDURE BMUppercaseSearch (
pattern : StringPtr;
text : StringPtr;
startpos: LONGINT;
endpos : LONGINT;
patternlength: INTEGER) : LONGINT;
VAR
i,j,t: INTEGER;
BEGIN
EnterProc ("BMUppercaseSearch()\n");
DebugMsg ("searching '");
(*
WriteString (pattern^);
WriteString ("' from "); WriteInt (startpos,0);
WriteString (" to "); WriteInt (endpos, 0); WriteString("...\n");
*)
IF (startpos >= endpos) OR (text = NIL) THEN
LeaveProc ("BMUppercaseSearch\n");
RETURN endpos;
END;
IF startpos = 0 THEN
i := patternlength-1;
ELSE
i := startpos;
END;
FOR j := patternlength-1 TO 0 BY -1 DO
WHILE (CAP(text^[i]) # CAP(pattern^[j])) DO
t := BMSkipArray[ORD(CAP(text^[i]))];
IF patternlength-j > t THEN
INC (i, patternlength-j);
ELSE
INC (i, t);
END;
IF i >= endpos THEN
LeaveProc ("BMUppercaseSearch\n");
RETURN endpos;
END;
j := patternlength-1;
END;
DEC (i);
END;
LeaveProc ("BMUppercaseSearch.\n");
RETURN i+1;
END BMUppercaseSearch;
PROCEDURE BMSearch (
pattern : StringPtr;
text : StringPtr;
startpos: LONGINT;
endpos : LONGINT;
patternlength: INTEGER) : LONGINT;
VAR
i,j,t: INTEGER;
BEGIN
EnterProc ("BMSearch()\n");
DebugMsg ("searching '");
(*
WriteString (pattern^);
WriteString ("' from "); WriteInt (startpos,0);
WriteString (" to "); WriteInt (endpos, 0); WriteString("...\n");
*)
IF (startpos >= endpos) OR (text = NIL) THEN
LeaveProc ("BMSearch\n");
RETURN endpos;
END;
IF startpos = 0 THEN
i := patternlength-1;
ELSE
i := startpos;
END;
FOR j := patternlength-1 TO 0 BY -1 DO
WHILE (text^[i] # pattern^[j]) DO
t := BMSkipArray[ORD(text^[i])];
IF patternlength-j > t THEN
INC (i, patternlength-j);
ELSE
INC (i, t);
END;
IF i >= endpos THEN
LeaveProc ("BMSearch\n");
RETURN endpos;
END;
j := patternlength-1;
END;
DEC (i);
END;
LeaveProc ("BMSearch.\n");
RETURN i+1;
END BMSearch;
PROCEDURE Search (
pattern : StringPtr;
text : StringPtr;
startpos: LONGINT;
endpos : LONGINT;
searchinfo: SearchInfoPtr;
VAR points: INTEGER) : INTEGER;
VAR
hits: INTEGER; (* Sooft wurder das Muster gefunden *)
patternlength: INTEGER; (* Länge des Suchbegriffs in Zeichen *)
casesensitiveSearch: BOOLEAN;
BEGIN
EnterProc ("Search()\n");
hits := 0;
points := 0;
patternlength := String.Length(pattern^);
casesensitiveSearch := NOT(IsLowerCase(pattern^));
IF casesensitiveSearch THEN
InitBMSearch (pattern, patternlength);
ELSE
InitBMUppercaseSearch (pattern, patternlength);
END;
WHILE startpos < endpos DO
IF casesensitiveSearch THEN
startpos := BMSearch (pattern, text, startpos, endpos,
patternlength);
ELSE
startpos := BMUppercaseSearch (pattern, text, startpos, endpos, patternlength);
END;
IF startpos < endpos THEN
INC (hits);
IF startpos < searchinfo^.titlestart THEN
INC (points, INARTIST);
ELSIF (startpos >= searchinfo^.titlestart) AND (startpos < searchinfo^.trackstart) THEN
INC (points, INTITLE);
END;
IF Fullword(text, startpos, patternlength) THEN
INC (points, FULLWORD);
ELSE
INC (points, MATCHONLY);
END;
INC (startpos, 2*patternlength-1);
END;
END;
LeaveProc ("Search.\n");
RETURN hits;
END Search;
PROCEDURE ShowSearchResult (cd: ed.NodePtr; cddata: CDDataPtr);
VAR
taglist: ARRAY [0..9] OF LONGCARD;
list: ed.ListPtr;
message: ARRAY [0..79] OF CHAR;
value: ARRAY [0..15] OF CHAR;
err: BOOLEAN;
BEGIN
EnterProc ("ShowSearchResults()\n");
(* Gültigen Knoten (Node) übergeben?: *)
IF cd^.succ = NIL THEN
(* Nein! *)
gtl.GTSetGadgetAttrsA(tracklistingGadget, mainWindow, NIL, TAG(taglist,
gtd.gtlvLabels, NIL,
tagEnd));
gtl.GTSetGadgetAttrsA(artistGadget, mainWindow, NIL, TAG(taglist,
gtd.gttxText, NIL,
tagEnd));
gtl.GTSetGadgetAttrsA(titleGadget, mainWindow, NIL, TAG(taglist,
gtd.gttxText, NIL,
tagEnd));
SetMessage (ADR("Sorry, pattern not found."));
ELSE
LoadCDData (cd^.name, cddata);
list := ADR(cddata^.tracks);
gtl.GTSetGadgetAttrsA(tracklistingGadget, mainWindow, NIL, TAG(taglist,
gtd.gtlvLabels, list,
gtd.gtlvSelected, 0,
gtd.gtlvMakeVisible, 0,
tagEnd));
taglist[0] := LONGCARD(gtd.gttxText);
taglist[1] := LONGCARD(cddata^.artist);
taglist[2] := tagEnd;
gtl.GTSetGadgetAttrsA(artistGadget, mainWindow, NIL, ADR(taglist));
taglist[1] := LONGCARD(cddata^.title);
gtl.GTSetGadgetAttrsA(titleGadget, mainWindow, NIL, ADR(taglist));
message := "CD ";
ValToStr (currentCDNumber, TRUE, value, 10, -10, 0C, err);
String.Concat (message, value);
String.Concat (message, " of ");
ValToStr (totalCDsFound, TRUE, value, 10, -10, 0C, err);
String.Concat (message, value);
String.Concat (message, " Score: ");
ValToStr ((100*cd^.pri) DIV maxPoints, TRUE, value, 10, -10, 0C, err);
String.Concat (message, value);
String.Concat (message, "% (");
ValToStr (cd^.pri, TRUE, value, 10, -10, 0C, err);
String.Concat (message, value);
String.Concat (message, " points)");
SetMessage (ADR(message));
END;
LeaveProc ("ShowSearchResults\n");
END ShowSearchResult;
(* --------------------------------------------------------------- *)
PROCEDURE SetSearchPattern (
VAR searchpattern: ARRAY OF CHAR;
gadget: id.GadgetPtr);
BEGIN
EnterProc ("SetSearchPatter()\n");
String.Copy (searchpattern, CAST(StringPtr, CAST(id.StringInfoPtr, gadget^.specialInfo)^.buffer)^);
LeaveProc ("SetSearchPattern.\n");
END SetSearchPattern;
PROCEDURE StartSearch (
VAR searchpattern: ARRAY OF CHAR;
searcharea: SearchArea;
cddata: CDDataPtr);
VAR
fib: dd.FileInfoBlockPtr;
filelock: dd.FileLockPtr;
filename: ARRAY [0..127] OF CHAR;
searchinfo: SearchInfo;
startpos, endpos: LONGINT;
success: BOOLEAN;
count: INTEGER;
points: INTEGER;
node: ed.NodePtr;
taglist: ARRAY [0..9] OF LONGCARD;
BEGIN
EnterProc ("StartSearch()\n");
IF String.Length(searchpattern) = 0 THEN
SetMessage (ADR("No pattern specified!"));
RETURN;
END;
(* Previous-, Next- und Pattern-Gadget dekativieren: *)
taglist[0] := LONGCARD(id.gaDisabled);
taglist[1] := LONGCARD(TRUE);
taglist[2] := tagEnd;
gtl.GTSetGadgetAttrsA (patternGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (searchareaGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (startsearchGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (previousGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (nextGadget, mainWindow, NIL, ADR(taglist));
SetMessage (ADR("Searching..."));
currentCDNumber := 1;
totalCDsFound := 0;
totalHits := 0;
maxPoints := 0;
(* Ergebnisliste initialisieren: *)
FreeSearchResultsList (ADR(searchresults));
es.NewList (ADR(searchresults));
fib := dl.AllocDosObject(dd.dosFib, NIL);
IF fib = NIL THEN
taglist[1] := LONGCARD(FALSE);
gtl.GTSetGadgetAttrsA (patternGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (searchareaGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (startsearchGadget, mainWindow, NIL, ADR(taglist));
SetMessage (ADR("Error: Not enough memory!"));
RETURN;
END;
filelock := dl.Lock(DISKSPATH, dd.accessRead);
IF filelock = NIL THEN
dl.FreeDosObject (dd.dosFib, fib);
taglist[1] := LONGCARD(FALSE);
gtl.GTSetGadgetAttrsA (patternGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (searchareaGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (startsearchGadget, mainWindow, NIL, ADR(taglist));
SetMessage (ADR("Can't open disks directory! Check Tooltypes."));
RETURN;
END;
success := dl.Examine (filelock, fib);
WHILE success DO
searchinfo.buffer := NIL;
String.Copy (filename, fib^.fileName);
endpos := fib^.size;
success := LoadNextFile (filelock, fib, ADR(searchinfo));
startpos := 0;
CASE searcharea OF
| SAartist:
endpos := searchinfo.titlestart;
| SAtitle:
startpos := searchinfo.titlestart;
endpos := searchinfo.trackstart;
| SAtracklisting:
startpos := searchinfo.trackstart;
ELSE
END;
DebugMsg ("Suche nach '");
(*
WriteString (searchpattern);
WriteString ("' von "); WriteInt (startpos,0);
WriteString (" bis "); WriteInt (endpos, 0);
WriteString (".\n");
*)
count := Search(ADR(searchpattern), searchinfo.buffer, startpos, endpos, ADR(searchinfo), points);
IF count > 0 THEN
(* Suchergebnisse merken *)
(*
t.Format ("Suchmuster %d mal gefunden.\n", ADR(count));
*)
node := el.AllocVec(SIZE(ed.Node), ed.MemReqSet{ed.memClear});
IF node # NIL THEN
node^.pri := points; (*count;*)
node^.name := strdup(filename);
el.Enqueue (ADR(searchresults), node);
END;
INC (totalCDsFound);
INC (totalHits, count);
IF points > maxPoints THEN
maxPoints := points;
END;
ELSE
(*
WriteString ("Suchmuster NICHT gefunden.\n");
*)
END;
IF searchinfo.buffer # NIL THEN
el.FreeVec (searchinfo.buffer);
END;
END;
dl.UnLock (filelock);
dl.FreeDosObject (dd.dosFib, fib);
(* Gadgets aktualisieren und erstes Ergebnis anzeigen: *)
currentsearchresult := searchresults.head;
taglist[1] := LONGCARD(FALSE);
gtl.GTSetGadgetAttrsA (patternGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (searchareaGadget, mainWindow, NIL, ADR(taglist));
gtl.GTSetGadgetAttrsA (startsearchGadget, mainWindow, NIL, ADR(taglist));
(* Gibt es kein oder nur ein Ergebnis?: *)
taglist[1] := LONGCARD((currentsearchresult^.succ = NIL) OR (currentsearchresult^.succ^.succ = NIL));
gtl.GTSetGadgetAttrsA (nextGadget, mainWindow, NIL, ADR(taglist));
ShowSearchResult (currentsearchresult, cddata);
WriteList (ADR(searchresults));
LeaveProc ("StartSearch.\n");
END StartSearch;
PROCEDURE ViewPrevious (cddata: CDDataPtr);
VAR
taglist: ARRAY [0..9] OF LONGCARD;
BEGIN
IF currentsearchresult^.pred^.pred # NIL THEN
currentsearchresult := currentsearchresult^.pred;
DEC (currentCDNumber);
taglist[0] := LONGCARD(id.gaDisabled);
taglist[1] := LONGCARD(FALSE);
taglist[2] := tagEnd;
gtl.GTSetGadgetAttrsA (nextGadget, mainWindow, NIL, ADR(taglist));
taglist[1] := LONGCARD(currentsearchresult^.pred^.pred = NIL);
gtl.GTSetGadgetAttrsA (previousGadget, mainWindow, NIL, ADR(taglist));
ShowSearchResult (currentsearchresult, cddata);
END;
END ViewPrevious;
PROCEDURE ViewNext (cddata: CDDataPtr);
VAR
taglist: ARRAY [0..9] OF LONGCARD;
BEGIN
IF currentsearchresult^.succ^.succ # NIL THEN
currentsearchresult := currentsearchresult^.succ;
INC (currentCDNumber);
taglist[0] := LONGCARD(id.gaDisabled);
taglist[1] := LONGCARD(FALSE);
taglist[2] := tagEnd;
gtl.GTSetGadgetAttrsA (previousGadget, mainWindow, NIL, ADR(taglist));
taglist[1] := LONGCARD(currentsearchresult^.succ^.succ = NIL);
gtl.GTSetGadgetAttrsA (nextGadget, mainWindow, NIL, ADR(taglist));
ShowSearchResult (currentsearchresult, cddata);
END;
END ViewNext;
(* --------------------------------------------------------------- *)
PROCEDURE ProcessMsg;
VAR
done: BOOLEAN;
imsg: id.IntuiMessagePtr;
class: id.IDCMPFlagSet;
code: CARDINAL;
qual: ie.QualifierSet;
gadget: id.GadgetPtr;
searchpattern: ARRAY [0..255] OF CHAR;
searcharea: SearchArea;
cddata: CDData;
bool: BOOLEAN;
taglist: ARRAY [0..9] OF LONGCARD;
BEGIN
WITH cddata DO
artist := NIL;
title := NIL;
es.NewList (ADR(tracks));
END;
searcharea := SAanywhere;
done := FALSE;
WHILE NOT(done) DO
el.WaitPort (mainWindow^.userPort);
LOOP
imsg := gtl.GTGetIMsg(mainWindow^.userPort);
IF imsg = NIL THEN EXIT; END;
class := imsg^.class;
code := imsg^.code;
gadget := CAST(id.GadgetPtr, imsg^.iAddress);
qual := imsg^.qualifier;
gtl.GTReplyIMsg (imsg);
IF id.closeWindow IN class THEN
done := TRUE;
ELSIF id.refreshWindow IN class THEN
gtl.GTBeginRefresh (mainWindow);
gtl.GTEndRefresh (mainWindow, TRUE);
ELSIF id.gadgetUp IN class THEN
CASE gadget^.gadgetID OF
SEARCHPATTERN:
SetSearchPattern (searchpattern, gadget);
StartSearch (searchpattern, searcharea, ADR(cddata));
| SEARCHAREA:
searcharea := SearchArea(code);
| STARTSEARCH:
SetSearchPattern (searchpattern, patternGadget);
StartSearch (searchpattern, searcharea, ADR(cddata));
| PREVIOUS:
ViewPrevious (ADR(cddata));
| NEXT:
ViewNext (ADR(cddata));
| TRACKLISTING:
gtl.GTSetGadgetAttrsA(patternGadget, mainWindow, NIL, TAG(taglist,
gtd.gtstString, GetNodeName (code, ADR(cddata.tracks)),
tagEnd));
ELSE
END;
ELSIF id.vanillaKey IN class THEN
CASE CAP(CHAR(code)) OF
"Q","X", 33C:
done := TRUE;
| "C":
IF CHAR(code) = CAP(CHAR(code)) THEN
searcharea := SearchArea((INTEGER(searcharea) - 1) MOD 4);
ELSE
searcharea := SearchArea((INTEGER(searcharea) + 1) MOD 4);
END;
gtl.GTSetGadgetAttrsA(searchareaGadget, mainWindow, NIL, TAG(taglist,
gtd.gtcyActive, searcharea,
tagEnd));
| "P":
bool := il.ActivateGadget(patternGadget, mainWindow, NIL);
| "S":
SetSearchPattern (searchpattern, patternGadget);
StartSearch (searchpattern, searcharea, ADR(cddata));
| "A":
gtl.GTSetGadgetAttrsA(patternGadget, mainWindow, NIL, TAG(taglist,
gtd.gtstString, cddata.artist,
tagEnd));
| "T":
gtl.GTSetGadgetAttrsA(patternGadget, mainWindow, NIL, TAG(taglist,
gtd.gtstString, cddata.title,
tagEnd));
| "<":
ViewPrevious (ADR(cddata));
| ">":
ViewNext (ADR(cddata));
| 15C:
gtl.GTSetGadgetAttrsA(patternGadget, mainWindow, NIL, TAG(taglist,
gtd.gtstString, GetNodeName (itemcount, ADR(cddata.tracks)),
tagEnd));
ELSE
END;
ELSIF id.rawKey IN class THEN
CASE code OF
id.cursorUp:
IF (ie.rShift IN qual) OR (ie.lShift IN qual) THEN
itemcount := 0;
ELSIF (ie.rAlt IN qual) OR (ie.lAlt IN qual) THEN
IF (itemcount-ITEMSVISIBLE) > 0 THEN
DEC (itemcount, ITEMSVISIBLE);
ELSE
itemcount := 0;
END;
ELSE
IF itemcount > 0 THEN
DEC (itemcount);
END;
END;
gtl.GTSetGadgetAttrsA (tracklistingGadget, mainWindow, NIL, TAG(taglist,
gtd.gtlvMakeVisible, itemcount,
gtd.gtlvSelected, itemcount,
tagEnd));
| id.cursorDown:
IF (ie.rShift IN qual) OR (ie.lShift IN qual) THEN
itemcount := maxitems;
ELSIF (ie.rAlt IN qual) OR (ie.lAlt IN qual) THEN
IF (itemcount+ITEMSVISIBLE) < maxitems THEN
INC (itemcount, ITEMSVISIBLE-1);
ELSE
itemcount := maxitems;
END;
ELSE
IF itemcount < maxitems THEN
INC (itemcount);
END;
END;
gtl.GTSetGadgetAttrsA (tracklistingGadget, mainWindow, NIL, TAG(taglist,
gtd.gtlvMakeVisible, itemcount,
gtd.gtlvSelected, itemcount,
tagEnd));
| id.cursorLeft:
ViewPrevious (ADR(cddata));
| id.cursorRight:
ViewNext (ADR(cddata));
ELSE
END;
END;
END; (* LOOP *)
END; (* WHILE *);
FreeCDData (ADR(cddata));
END ProcessMsg;
PROCEDURE Shutdown;
BEGIN
il.CloseWindow (mainWindow); mainWindow := NIL;
gtl.FreeGadgets (glist);
gtl.FreeVisualInfo (visualinfo);
FreeSearchResultsList (ADR(searchresults));
END Shutdown;
BEGIN
DISKSPATH := ArgString(ADR("DISKSPATH"), ADR("EH0:PublicDomain/Disk/CeeD/Disks/"));
INTITLE := ArgInt(ADR("TITLEPOINTS"), 10);
INARTIST := ArgInt(ADR("ARTISTPOINTS"), 10);
FULLWORD := ArgInt(ADR("FULLWORDPOINTS"), 5);
MATCHONLY := ArgInt(ADR("MATCHONLYPOINTS"), 1);
CreateMainWindow;
ProcessMsg;
Shutdown;
CLOSE
IF mainWindow # NIL THEN
il.CloseWindow (mainWindow);
END;
END CDIndex.