// drawfind.c // // by John D. de Boer #include "twist.h" #include "twindow.h" extern GlobalOpts Opt; extern void *Sel; extern int PEOPLE,EVENTS,FIT,VSCR; extern Person ***People; extern Event ***Events; extern rect FoundPane, TopPane, EditBox, LegendBox; extern ControlRef EditField,FindButton; extern window *FindWind; int FINDS; // number of things found const int FOUNDHEIGHT = 18; static string FoundStr; // the search string as entered static stringlist FindStr; // the string(s) which have been searched for static void ***Finds; // the list of things found // Drawing content static void DrawMatch(window *W, int MATCH) { int PC; if (!W || FindStr.num<2) return; PC= (100 * MATCH) / FindStr.num; text(W," ("); textold(W,fig(PC)); text(W,"%)"); } static void DrawPerson(window *W, Person *P, point Q) { bool SI; if (!W) return; SI=Highlight(W,P); if (SI) boldtext(W,Q.x,Q.y,P->name,Opt.size); else drawtext(W,Q.x,Q.y,P->name); DrawMatch(W,P->match); } static void DrawEvent(window *W, Event *E, point Q) { bool SI; if (!W) return; SI=Highlight(W,E); if (SI) boldtext(W,Q.x,Q.y,E->name,Opt.size); else drawtext(W,Q.x,Q.y,E->name); DrawMatch(W,E->match); } static void DrawItem(window *W, void *V, int POS) { int Y; point Q; if (!W || POS<0) return; Y= top(FoundPane) - ((POS + 1) * FOUNDHEIGHT); Q.x=4; Q.y= Y + 4; if (VoidIsPers(V)) DrawPerson(W,(Person *)V,Q); else DrawEvent(W,(Event *)V,Q); penindex(W,lightgrey); beginpath(W); moveto(W,0,Y); lineto(W,right(FoundPane),Y); stroke(W); penindex(W,black); } void DrawFind(window *W) { int i; //OSErr err; if (!W) return; fillindex(W,black); beginpath(W); moveto(W,left(W->page),top(FoundPane)); lineto(W,right(W->page),top(FoundPane)); stroke(W); drawtext(W,10,top(W->page) - 30,"Find:"); framerect(W,EditBox); drawtext(W,left(LegendBox),top(LegendBox),NULL); if (!FoundStr) { fillindex(W,grey); text(W,"No search text"); fillindex(W,black); } else if (FINDS==0) { text(W,"No matches found for text: "); text(W,FoundStr); } else { textold(W,fig(FINDS)); text(W,FINDS>1 ? " matches" : " match"); text(W," found for text: "); text(W,FoundStr); } for (i=0;iwmw,EditField,kControlIndicatorPart); DrawControls(W->wmw); }// void *FindHit(mouseclick *M) { int V,i; if (!M) return NULL; if (!pointinrect(M->point,FoundPane)) return NULL; V= top(FoundPane) - M->point.y - 3; i= (V / FOUNDHEIGHT) + VSCR; if (!range(i,FINDS)) return NULL; return (*Finds)[i]; } // Matching searches static bool PersonMatch(Person *P, const char *S) { if (!P || !S) return 0; if (wordin(S,P->name,0) || wordin(S,P->aka,0)) return 1; if (wordin(S,P->info,0) || wordin(S,P->ref,0)) return 1; if (PlaceMatch(P->home,S) || PlaceMatch(P->nation,S)) return 1; if (TravelMatch(P->trav,S)) return 1; if (OccupationMatch(P,S)) return 1; return 0; } static bool EventMatch(Event *E, const char *S) { Person *P; if (!E || !S) return 0; if (wordin(S,E->name,0) || wordin(S,E->aka,0)) return 1; if (wordin(S,E->info,0) || wordin(S,E->ref,0)) return 1; if (PlaceMatch(E->place,S)) return 1; if (TravelMatch(E->trav,S)) return 1; if (TypeMatch(E,S)) return 1; P=E->pers; if (P) { if (wordin(S,P->name,0) || wordin(S,P->aka,0)) return 1; } return 0; } // "Find" action void InitFindInfo(void) { FINDS=0; Finds=(void ***)handle(0); FoundStr=NULL; initstringlist(&FindStr); } void PurgeFindInfo(void) { grafvars G; WindowPtr WP; FINDS=0; old(FoundStr); FoundStr=NULL; purgestringlist(&FindStr); if (!FindWind) return; WP=FindWind->wmw; if (!WP) return; savegraf(&G); SetPortWindowPort(WP); SetFindScroll(); restoregraf(&G); } static void AddFoundItem(void *V) { minimumsize(Finds,FINDS + 1,sizeof(void *)); (*Finds)[FINDS++]=V; } static bool InMatchOrder(const void *A, const void *B) { int M1,M2; Day *D1,*D2; if (!A) return 0; if (!B) return 1; M1= VoidIsPers(A) ? ((Person *)A)->match : ((Event *)A)->match; M2= VoidIsPers(B) ? ((Person *)B)->match : ((Event *)B)->match; if (M1>M2) return 1; if (M1life.start) : &(((Event *)A)->date.start); D2= VoidIsPers(B) ? &(((Person *)B)->life.start) : &(((Event *)B)->date.start); return DatesInOrder(D1,D2,0); } void Find(string S) { int i,j; Person *P; Event *E; PurgeFindInfo(); if (!S) return; FoundStr=copyof(S); clean(S); if (!*S) return; while (S && *S) { string F; F=first(S); if (!F) continue; addstringtolist(&FindStr,F); S=firstrem(S); } if (FindStr.num<1) return; WaitCursor(); for (i=0;imatch=0; for (j=0;jmatch++; if (P->match) AddFoundItem(P); } for (i=0;imatch=0; for (j=0;jmatch++; if (E->match) AddFoundItem(E); } lock(Finds); sort(*Finds,FINDS,&InMatchOrder); unlock(Finds); SetFindScroll(); defaultcursor(); }