home *** CD-ROM | disk | FTP | other *** search
Wrap
/***************************************************************************** mac_project.c: Copyright (c) Kevin Hammond 1993. All rights reserved. This module implements the Macintosh graphical project handling. *****************************************************************************/ #include "mac.h" #include <fcntl.h> #include "ctype.h" #pragma segment Project extern CursHandle watchcurs; /* Watch cursor */ extern short systemVersion; /* Which version of the system we're running */ static projfiles = 1; char projfile[256]; short projvol = 0; long projdirID = 0; short projrespath = -1; short preludevolref = 0; long preludedirID = 0; char *PreludeName = ""; extern char *askgetfile(), *getfile(), *putfile(), *readFilename(); extern Boolean doreadproject(); ListHandle SetUpDefnList(), createlist(); short GetModFromIndex(); extern ListHandle SetUpModuleList(); extern short KeyModifiers; extern pascal Boolean ListDlgFilter(); extern short dlgOtherButton; #define MAX_PITEMS 40 struct ProjStruct { Boolean PUsed; short pvrefnum; long pdirID; char *FName; char *MName; unsigned long ModTime; } ProjItems[MAX_PITEMS] = {FALSE,0,0L,NIL,NIL,0L}; #define PUSED(i) (ProjItems[i].PUsed) #define PVREFNUM(i) (ProjItems[i].pvrefnum) #define PDIRID(i) (ProjItems[i].pdirID) #define PNAME(i) (ProjItems[i].FName) #define MNAME(i) (ProjItems[i].MName) #define PMODTIME(i) (ProjItems[i].ModTime) char *safemalloc(); unsigned long getmodtime(); NewPItem(name,refnum,dirID) char *name; short refnum; long dirID; { AddPItem(name,refnum,dirID,FALSE); } int AddPItem(name,refnum,dirID,preservemodtime) char *name; short refnum; long dirID; int preservemodtime; { int i, used; int theversion; char *namebuf; i = FindAnyPItem(name,refnum,dirID,&used); if(used) return(TRUE); theversion = resetpversions(name,FALSE); if( i < 0 ) { preservemodtime = FALSE; for(i=0; i < MAX_PITEMS; ++i) if(PUSED(i)!=TRUE) break; if(i == MAX_PITEMS) return(FALSE); } namebuf = safemalloc(strlen(name)+1); strcpy(namebuf,name); resolvealias(&namebuf,&refnum,&dirID); PUSED(i) = TRUE; if(!preservemodtime) { /* Change names */ if(PNAME(i)!=NIL) free(PNAME(i)); if(MNAME(i)!=NIL && MNAME(i)!=PNAME(i)) free(PNAME(i)); PNAME(i) = MNAME(i) = namebuf; PVREFNUM(i) = refnum; PDIRID(i) = dirID; PMODTIME(i) = 0; } setmname(theversion,i); insmenuitem(Menu_Project,MNAME(i),PreludeItem+projfiles++); return(preservemodtime); } setmname(version,i) int version, i; { if(MNAME(i)!=PNAME(i) && MNAME(i) != NIL) free(MNAME(i)); MNAME(i) = PNAME(i); if(version > 0) { MNAME(i) = safemalloc(strlen(PNAME(i))+4); sprintf(MNAME(i),"%s:%d",PNAME(i),version); } } char ftolower(c) char c; { if(isupper(c)) return(tolower(c)); else return(c); } Boolean equalfiles(f1,f2) char *f1, *f2; { /* Just in case a window has a null filename -- HSL */ if (f1 == NIL || f2 == NIL) return(FALSE); for(; *f1 != '\0'; f1++, f2++) if(ftolower(*f1) != ftolower(*f2)) return(FALSE); return(*f2=='\0'); } int resetpversions(name,deleting) char *name; Boolean deleting; { int version = 0, i; if(deleting) { int count = 0, pindex; for(i=0; i < MAX_PITEMS; ++i) if(PUSED(i) && equalfiles(name,PNAME(i))) { ++count; pindex = i; } if (count == 1) { short menuitem = findmenuitem(Menu_Project,PreludeItem,projfiles+PreludeItem+1,MNAME(pindex)); setmname(0,pindex); setitem(Menu_Project,menuitem,MNAME(pindex)); return(0); } } for(i=0; i < MAX_PITEMS; ++i) if(PUSED(i) && equalfiles(name,PNAME(i))) { short menuitem = findmenuitem(Menu_Project,PreludeItem,projfiles+PreludeItem+1,MNAME(i)); setmname(++version,i); setitem(Menu_Project,menuitem,MNAME(i)); } return(version==0?0:version+1); } InitPItems() { int i; for(i=0; i < MAX_PITEMS; ++i) { PUSED(i) = FALSE; PVREFNUM(i) = 0; PDIRID(i) = 0; PMODTIME(i) = 0; PNAME(i) = MNAME(i) = NIL; } } /* I've tried to speed this up, by removing some resolvealias calls, and by limiting the search to projitems live entries. */ int FindPItem(oname,refnum,dirID) char *oname; short refnum; long dirID; { int used, i; i = FindAnyPItem(oname,refnum,dirID,&used); if(!used) return(-1); else return(i); } int FindAnyPItem(oname,refnum,dirID,used) char *oname; short refnum; long dirID; int *used; { int i; char *name = oname, *pname; short prefnum; long pdirID; int founditems = 0; resolvealias(&name,&refnum,&dirID,TRUE); for(i=0; i < MAX_PITEMS; ++i) if(PNAME(i) != NIL) { *used = PUSED(i); pname = PNAME(i); prefnum = PVREFNUM(i); pdirID = PDIRID(i); // resolvealias(&pname,&prefnum,&pdirID,FALSE); if(equalfiles(pname,name) && prefnum==refnum && pdirID==dirID) { if(name != oname) free(name); return(i); } else if (++founditems == projfiles) break; } if(name != oname) free(name); *used = FALSE; return(-1); } int FindPMItem(name) char *name; { int i; for(i=0; i < MAX_PITEMS; ++i) if(PUSED(i) && equalfiles(MNAME(i),name)) return(i); return(-1); } DelPItem(pindex) int pindex; { if(pindex >= 0) { PUSED(pindex) = FALSE; #if 0 if(PNAME(pindex)!=NIL) free(PNAME(pindex)); if(MNAME(pindex)!=NIL && MNAME(pindex)!=PNAME(pindex)) free(PNAME(pindex)); PNAME(pindex) = MNAME(pindex) = NIL; PMODTIME(pindex) = 0; PVREFNUM(pindex) = 0; PDIRID(pindex) = 0; #endif } } /* Clear the project menu. */ clearProject() { int max = CountMItems(Menu_Project); int i; /* Record the old Prelude modification time */ unsigned long modtime = PMODTIME(0); while (max >= PreludeItem) DelMenuItem(Menu_Project,max--); for(i=0; i < MAX_PITEMS; ++i) DelPItem(i); projfiles = 0; if(*PreludeName != '\0') AddPItem(PreludeName,preludevolref,preludedirID,TRUE); forgetprojresources(); forgetScriptsFrom(1); /* So the user is prompted if the project is saved */ projfile[0] = '\0'; } /* Forget the old project resources */ forgetprojresources() { if(projrespath >= 0) { CloseResFile(projrespath); projrespath = -1; } } /* Use the project resources/standard Gofer resources */ useprojectresfile(useprojfile,forget) int useprojfile, forget; { extern short goferresfile; if(useprojfile) if(projrespath >= 0) UseResFile(projrespath); else setprojresfile(projfile,projvol,projdirID); else { /* Forget the Project resources */ if(forget) forgetprojresources(); /* And get the Application resources */ UseResFile(goferresfile); } } openProject() { char *nprjfile = askgetfile(1,projtypelist,"Open Gofer Project","Open",0,Res_Dlg_SFP_Project); if(*nprjfile != '\0') (void) doreadproject(nprjfile,ReplySpec.vRefNum,ReplySpec.parID); } /* "Text" version of openProject. */ project() { long parID = *((long *)CurDirStore); short vRefNum = -1 * (*(short *)SFSaveDisk); char *prjfile = readFilename(); /* If we have a legal project file, read it */ /* We should check that the file has the correct type somewhere */ if(prjfile != NIL && *prjfile != '\0') { resolvealias(&prjfile,&vRefNum,&parID,FALSE); (void) doreadproject(prjfile,vRefNum,parID); } else { mprintf("ERROR: A project file name must be given\n"); printPrompt(); } } setprojresfile(file,volnum,dirID) char *file; short volnum; long dirID; { extern short goferresfile; /* Find the project's resource map */ projrespath = HOpenResFile(volnum,dirID,c2pstr(file),fsRdPerm); (void) p2cstr(file); } char *saveprojdialog(defaultsave) char *defaultsave; { return(putfile("Save Current Project as:", *defaultsave == '\0'? "Untitled Project": defaultsave, "Save")); } saveProject() { dosaveproject(*projfile == '\0'); } saveProjectAs() { dosaveproject(TRUE); } dosaveproject(dodialog) Boolean dodialog; { char savefile[256]; short saveref; static short volnum; static long dirID; if(dodialog) { strcpy(savefile,saveprojdialog(projfile)); if (*savefile == '\0') return; volnum = ReplySpec.vRefNum; dirID = ReplySpec.parID; updatewindows(); } else { strcpy(savefile,projfile); volnum = projvol; dirID = projdirID; } createfile(savefile,volnum,dirID,projtype); setfiletype(savefile,volnum,dirID,creator,projtype); if (hopen(savefile,volnum,dirID,fsWrPerm,&saveref) != noErr) Error("I/O ","Can't Write Project File"); else { char itemfile[256]; Boolean write_error = FALSE; short i; long count = 0; /* (Re)-set the EOF marker. Humayan forgot to do this in the new code. */ for(i=PreludeItem+1;i<PreludeItem+projfiles;++i) { GetItem(Menu_Project,i,(Str255) itemfile); count += itemfile[0] + 1; } if(SetEOF(saveref,count) != noErr) { Error("I/O ","Write of Project File Failed"); write_error = TRUE; } /* Should check vRefNum and write a full or relative path name */ for(i=PreludeItem+1;i<PreludeItem+projfiles && !write_error;++i) { GetItem(Menu_Project,i,(Str255) itemfile); count = itemfile[0] + 1; if (FSWrite (saveref,&count,(Ptr)itemfile) != noErr) { Error("I/O ","Write of Project File Failed"); write_error = TRUE; } } (void) FSClose(saveref); if(!write_error) { strcpy(projfile,savefile); projvol = volnum; projdirID = dirID; } } } /* Filter out files which are already in the project, or which are invisible. */ pascal Boolean projectFileFilter(CInfoPBPtr pb) { if (pb->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible) return(TRUE); else { char name[256]; short vrefnum = pb->hFileInfo.ioVRefNum; long dirID = pb->hFileInfo.ioFlParID; pstrcopy(pb->hFileInfo.ioNamePtr,name); p2cstr(name); return( FindPItem(name,vrefnum,dirID) != -1 ); } } loadProjectFile() { Point where; extern SFReply sfgTheReply; extern pascal short myDlgHook(); extern pascal Boolean myFilterProc(); extern pascal void sfgCleanup(); SetPt(&where,-1,-1); sfpgetfile(&where,"\Load files into project:",(FileFilterProcPtr)projectFileFilter,1,(SFTypeList)texttypelist,myDlgHook,&sfgTheReply,Res_Dlg_Load_Multiple,myFilterProc); if (sfgTheReply.good) { sfgProcessData(NewPItem); windowtofront(worksheet); updatewindows(); reloadProjectFiles(); } sfgCleanup(); } /* "Text" version of load, which adds to the Project menu correctly. */ load() { if(doload()) { windowtofront(worksheet); updatewindows(); reloadProjectFiles(); } } /* Do the load -- separated because we want to declare shorts here */ doload() { long parID = *((long *)CurDirStore); short vRefNum = -1 * (*(short *)SFSaveDisk); char *s; while (s=readFilename()) { /* If the file exists add it to the project */ if(checkFileExists(s,vRefNum,parID)) AddPItem(s,vRefNum,parID,FALSE); /* otherwise, flag an error */ else { mprintf("ERROR: couldn't find %s, load aborted\n",s); return(FALSE); } } /* Only if all files loaded OK do we want to reload the project */ return(TRUE); } reloadProjectFiles() { windowtofront(worksheet); SetCursor(*watchcurs); readScripts(0); printPrompt(); } unloadprojlist(list) ListHandle list; { Cell sel; short item, minitem = 32767, deleted = 0; int pindex; char mtitle[256]; /* Remove the selected items from the internal list */ SetPt(&sel,0,0); while(LGetSelect(TRUE,&sel,list)) { sel.v += 1; item = sel.v; if(item < minitem) minitem = item; getitem(Menu_Project,item+PreludeItem,mtitle); --projfiles; pindex = FindPMItem(mtitle); PUSED(pindex) = FALSE; resetpversions(PNAME(pindex),TRUE); DelPItem(pindex); } /* Now remove them from the menu */ SetPt(&sel,0,0); while(LGetSelect(TRUE,&sel,list)) { sel.v += 1; item = sel.v; getitem(Menu_Project,item+PreludeItem-deleted,mtitle); DelMenuItem(Menu_Project,item+PreludeItem-deleted); ++deleted; } resetScript(minitem); } unloadProjectFile() { DialogPtr projdlg; short itemhit; ListHandle unloadlist; /* Set the arrow cursor */ SetCursor(&(qd.arrow)); /* Initialise dialog */ projdlg = GetNewDialog(Res_Dlg_Unload,nil,(WindowPtr) -1); ShowWindow(projdlg); highlightDefault(projdlg); dlgOtherButton = 0; DisableButton(projdlg,OK); /* Initialise list */ unloadlist = SetUpModuleList(projdlg, Res_DItem_Unload, TRUE,FALSE,1); HLock((Handle)unloadlist); (*unloadlist)->selFlags = lNoExtend; for(;;) { ModalDialog((ModalFilterProcPtr) ListDlgFilter,&itemhit); switch(itemhit) { case Res_DItem_Unload: { Point mousePt; GrafPtr savePort; Cell cell; Boolean doubleclick; GetPort(&savePort); SetPort((*unloadlist)->port); GetMouse(&mousePt); SetPort(savePort); /* Check for a double-click in the unload list */ doubleclick = LClick(mousePt,KeyModifiers,unloadlist); SetPt(&cell,0,0); if(LGetSelect(TRUE,&cell,unloadlist)) EnableButton(projdlg,OK); if(!doubleclick) break; itemhit = OK; } case OK: { Cell cell; SetPt(&cell,0,0); if(!LGetSelect(TRUE,&cell,unloadlist)) { SysBeep(1); break; } HUnlock((Handle)unloadlist); unloadprojlist(unloadlist); LDispose(unloadlist); DisposDialog(projdlg); HiliteMenu(0); reloadProjectFiles(); return; } case CANCEL: HUnlock((Handle)unloadlist); LDispose(unloadlist); DisposDialog(projdlg); return; } } } /* "Text" version of unload, which deals with the Project menu correctly. */ unload() { int minitem; if(dounload(&minitem)) { resetScript(minitem); reloadProjectFiles(); } else printPrompt(); } dounload(minitem) int *minitem; { char *s; Boolean unloaded = FALSE; *minitem = 32767; while (s=readFilename()) { int pindex = FindPMItem(s); if(pindex > 0) { short menuitem = findmenuitem(Menu_Project,PreludeItem+1,projfiles+PreludeItem+1,MNAME(pindex)); --projfiles; PUSED(pindex) = FALSE; resetpversions(PNAME(pindex),TRUE); DelPItem(pindex); DelMenuItem(Menu_Project,menuitem); unloaded = TRUE; if(pindex < *minitem) *minitem = pindex; } else mfprintf(stderr,"Error: %s is not in the current project\n",s); } return(unloaded); } rearrangeProjectFiles() { DialogPtr rearrangedlg; ListHandle oldlist, newlist; int oldfiles = projfiles-1, newfiles = 0; Point mousePt; GrafPtr savePort; Cell cell; short itemhit; ListHandle fromlist, tolist; if(oldfiles == 0) return; /* Set the arrow cursor */ SetCursor(&(qd.arrow)); /* Initialise dialog */ rearrangedlg = GetNewDialog(Res_Dlg_Rearrange,nil,(WindowPtr) -1); ShowWindow(rearrangedlg); highlightDefault(rearrangedlg); dlgOtherButton = 0; /* Disable buttons which cannot be used initially */ DisableButton(rearrangedlg,Res_DItem_Reload); DisableButton(rearrangedlg,Res_DItem_Move); /* Initialise lists */ oldlist = SetUpModuleList(rearrangedlg,Res_DItem_OldList,TRUE,FALSE,1); newlist = createlist(rearrangedlg,Res_DItem_NewList,0,TRUE); HLock((Handle)oldlist); HLock((Handle)newlist); (*oldlist)->selFlags = lNoExtend; (*newlist)->selFlags = lNoExtend; LDoDraw(TRUE,newlist); for(;;) { ModalDialog((ModalFilterProcPtr) ListDlgFilter,&itemhit); switch(itemhit) { case Res_DItem_OldList: case Res_DItem_NewList: { fromlist = itemhit==Res_DItem_OldList?oldlist:newlist; tolist = itemhit==Res_DItem_OldList?newlist:oldlist; GetPort(&savePort); SetPort((*fromlist)->port); GetMouse(&mousePt); SetPort(savePort); SetButtonTitle(rearrangedlg,Res_DItem_Move, itemhit==Res_DItem_OldList?"Move >>":"<< Move"); EnableButton(rearrangedlg,Res_DItem_Move); unselectList(tolist); /* Check for a double-click in the list */ if(!LClick(mousePt,KeyModifiers,fromlist)) break; } case Res_DItem_Move: { /* Move selected items from old to new */ SetPt(&cell,0,0); while(LGetSelect(TRUE,&cell,fromlist)) { short row = LAddRow(1,(*tolist)->dataBounds.bottom+1,tolist); char data[256]; short size = 255; Cell newcell; SetPt(&newcell,0,row); LGetCell((Ptr)data,&size,cell,fromlist); LSetCell((Ptr)data,size,newcell,tolist); cell.v += 1; if(tolist == newlist) { EnableButton(rearrangedlg,Res_DItem_Reload); ++newfiles; } else --newfiles; } /* Remove from the original list */ SetPt(&cell,0,0); while(LGetSelect(TRUE,&cell,fromlist)) { LDelRow(1,cell.v,fromlist); } /* Reset Buttons */ DisableButton(rearrangedlg,Res_DItem_Move); if(newfiles == 0) DisableButton(rearrangedlg,Res_DItem_Reload); } break; case Res_DItem_Reload: { HUnlock((Handle)oldlist); HUnlock((Handle)newlist); rearrangeprojlist(newlist); LDispose(oldlist); LDispose(newlist); DisposDialog(rearrangedlg); HiliteMenu(0); updatewindows(); reloadProjectFiles(); return; } case CANCEL: HUnlock((Handle)oldlist); HUnlock((Handle)newlist); LDispose(oldlist); LDispose(newlist); DisposDialog(rearrangedlg); return; } } } unselectList(hlist) ListHandle hlist; { Cell cell; SetPt(&cell,0,0); while(LGetSelect(TRUE,&cell,hlist)) { LSetSelect(FALSE,cell,hlist); cell.v+=1; } } rearrangeprojlist(new) ListHandle new; { int file, i, j, max, inorder = TRUE; Cell cell; int neworder[MAX_PITEMS-1]; struct ProjStruct Temp[MAX_PITEMS-1]; char filename[256]; short size; SetPt(&cell,0,0); for(file=0; file < (*new)->dataBounds.bottom; ++file) { size = 255; LGetCell(filename,&size,cell,new); filename[size] = '\0'; neworder[file] = FindPMItem(filename); ++cell.v; } for(j = 1; j < projfiles; ++j) { int found = FALSE; for(i = 0; i < (*new)->dataBounds.bottom; ++i) if(neworder[i] == j) { found = TRUE; break; } if( !found ) neworder[file++] = j; } for(i = 1; i < projfiles; ++i) { Temp[i-1] = ProjItems[i]; } max = CountMItems(Menu_Project); while (max > PreludeItem) DelMenuItem(Menu_Project,max--); for(i = 1; i < projfiles; ++i) { inorder &= i == neworder[i-1]; ProjItems[i] = Temp[neworder[i-1]-1]; /* Force a reload for files where the ordering has changed */ if(!inorder) PMODTIME(i) = 0; } for(i = 1; i < projfiles; ++i) insmenuitem(Menu_Project,MNAME(i),PreludeItem+i-1); } findProjectFile(item) { char loadfile[256]; int pindex; short vrefnum; long dirID; getitem(Menu_Project,(short)item,loadfile); pindex = FindPMItem(loadfile); vrefnum = PVREFNUM(pindex); dirID = PDIRID(pindex); doopenfile(PNAME(pindex),vrefnum,dirID); } findPrelude() { short path; /* If not already set from resources, set the default prelude name */ if(*PreludeName == '\0') PreludeName = DEFAULT_PRELUDE_NAME; /* Look for the prelude in the Gofer folder if we don't know where it is */ if (preludevolref == 0 || preludedirID == 0) { extern short gofervol; extern long goferdirID; preludevolref = gofervol; preludedirID = goferdirID; } /* Resolve an aliased prelude */ resolvealias(&PreludeName,&preludevolref,&preludedirID,TRUE); /* Check whether the Prelude exists */ if(hopen(PreludeName,preludevolref,preludedirID,fsRdPerm,&path) != noErr) { char *prelname = askgetfile(1,texttypelist,"Where is the Gofer Prelude?","Set",Res_Dlg_Where_Prelude,Res_Dlg_SFP_Prelude); if(*prelname != '\0') { PreludeName = safemalloc(strlen(prelname)+1); strcpy(PreludeName,prelname); preludevolref = ReplySpec.vRefNum; preludedirID = ReplySpec.parID; } else { FatalError("Prelude Must Be Specified"); return; /* FatalError just sets quit now */ } } else (void) FSClose(path); } getProjectItem(n) int n; { short max = CountMItems(Menu_Project)-PreludeItem; char ptitle[256]; if(n > max || n < 0) return(-1); else { getitem(Menu_Project,(short)(PreludeItem+n),ptitle); return(FindPMItem(ptitle)); } } Boolean getprojfile(module,file,volnum,dirID) int module; char *file; short *volnum; long *dirID; { int pindex; if((pindex = getProjectItem(module)) >= 0) { char *afile = PNAME(pindex); *volnum = PVREFNUM(pindex); *dirID = PDIRID(pindex); resolvealias(&afile,volnum,dirID,FALSE); strcpy(file,afile); return(TRUE); } else return(FALSE); } Boolean getfilefor(defn,line,file,volnum,dirID,dummy) char *defn; int *line; char *file; short *volnum, *dummy; long *dirID; { int module; getName(defn,&module,line); return(getprojfile(module-1,file,volnum,dirID)); } char *scriptname(pindex) int pindex; { return(PNAME(pindex)); } /* Save and restore directories */ static short savedvrefnum; static long saveddirID; void resetdir() { #if 0 long *curdirstore = (long *)CurDirStore; short *sfsavedisk = (short *)SFSaveDisk; #endif HSetVol(NIL,savedvrefnum,saveddirID); #if 0 *curdirstore = saveddirID; *sfsavedisk = -1 * savedvrefnum; #endif } savedir(vrefnum,dirID,reset) short vrefnum; long dirID; Boolean reset; { savedvrefnum = vrefnum; saveddirID = dirID; /* if(reset)*/ resetdir(); } changedir(pindex) int pindex; { long dirID = PDIRID(pindex); short volnum = PVREFNUM(pindex); char *file = PNAME(pindex); resolvealias(&file,&volnum,&dirID,FALSE); HSetVol(NIL,volnum,dirID); } createTextFile(s) char *s; { (void) hcreate(s,savedvrefnum,saveddirID,GoferCreatorType,GoferTextType); } /* Get the modification time for a file. */ unsigned long getmodtime(name,volrefnum,dirID) char *name; short volrefnum; long dirID; { HFileParam finfo; char fname[256]; resolvealias(&name,&volrefnum,&dirID,FALSE); strcpy(fname,name); finfo.ioCompletion = NIL; finfo.ioNamePtr = c2pstr(fname); finfo.ioVRefNum = volrefnum; finfo.ioFVersNum = 0; finfo.ioFDirIndex = 0; finfo.ioDirID = dirID; PBHGetFInfo((HParmBlkPtr)&finfo,FALSE); return(finfo.ioFlMdDat); } int haschanged(pindex) int pindex; { unsigned long modtime = getmodtime(PNAME(pindex),PVREFNUM(pindex),PDIRID(pindex)); int changed; if(changed = (modtime > PMODTIME(pindex))) PMODTIME(pindex) = modtime; return(changed); } int isliterate(pindex) { return(IsLiterateFile(PVREFNUM(pindex),PDIRID(pindex),PNAME(pindex))); } int ishaskmodule(pindex) { return(IsHaskNumFile(PVREFNUM(pindex),PDIRID(pindex),PNAME(pindex))); } Boolean isUserLocked(name,volrefnum,dirID) char *name; short volrefnum; long dirID; { HFileParam finfo; char fname[256]; resolvealias(&name,&volrefnum,&dirID,FALSE); strcpy(fname,name); finfo.ioCompletion = NIL; finfo.ioNamePtr = c2pstr(fname); finfo.ioVRefNum = volrefnum; finfo.ioFVersNum = 0; finfo.ioFDirIndex = 0; finfo.ioDirID = dirID; PBHGetFInfo((HParmBlkPtr)&finfo,FALSE); return((finfo.ioFlAttrib & 1) != 0); } long getscriptlen(pindex) int pindex; { HFileParam finfo; char fname[256]; char *name = PNAME(pindex); short volnum = PVREFNUM(pindex); long dirID = PDIRID(pindex); resolvealias(&name,&volnum,&dirID,FALSE); strcpy(fname,name); finfo.ioCompletion = NIL; finfo.ioNamePtr = c2pstr(fname); finfo.ioVRefNum = volnum; finfo.ioFVersNum = 0; finfo.ioFDirIndex = 0; finfo.ioDirID = dirID; PBHGetFInfo((HParmBlkPtr)&finfo,FALSE); return(finfo.ioFlLgLen); } ListHandle createlist(dlg,item,size,drawframe) DialogPtr dlg; short item; int size; Boolean drawframe; { ListHandle hlist; Cell cell; Rect listRect, sizeRect; /* Initialise list */ GetDlgItemRect(dlg, item, &listRect); SetRect(&sizeRect,0,0,1,size); SetPt(&cell,0,0); listRect.right -= SCROLLBARWIDTH; if(drawframe) FrameDlgList(dlg,listRect); hlist = LNew(&listRect,&sizeRect,cell,NIL,(WindowPtr)dlg,TRUE,FALSE,FALSE,TRUE); HLock((Handle)hlist); LUpdate((*hlist)->port->visRgn,hlist); InsetRect(&(*hlist)->rView,4,4); HUnlock((Handle)hlist); /* Don't draw whilst creating the list */ LDoDraw(FALSE,hlist); resetDlgSearch(hlist,FALSE); return(hlist); } enableSingletons(dlg,hlist,size) DialogPtr dlg; ListHandle hlist; int size; { if(size==1) { Cell cell; SetPt(&cell,0,0); LSetSelect(TRUE,cell,hlist); EnableButton(dlg,((DialogPeek)dlg)->aDefItem); if(dlgOtherButton != 0) EnableButton(dlg,dlgOtherButton); } } Boolean smallerstring(s1,s2) char *s1, *s2; { for(;*s1!='\0';++s1,++s2) { char c1 = ftolower(*s1), c2 = ftolower(*s2); if(c1 < c2) return(TRUE); else if (c1 > c2) return(FALSE); } return(TRUE); } static short IndexedModules[MAX_PITEMS]; short GetModFromIndex(ind) short ind; { return(IndexedModules[ind]); } ListHandle SetUpModuleList(dlg,item,drawframe,sort,min) DialogPtr dlg; short item; Boolean drawframe,sort; int min; { short i, j; ListHandle hlist; Cell cell; char module[256]; char *modules[MAX_PITEMS]; hlist = createlist(dlg,item,projfiles-min,drawframe); /* Set up the module list. */ for( i=min; i < projfiles; ++i ) { getitem(Menu_Project,PreludeItem+i,module); if(sort) { IndexedModules[i-min] = i; modules[i] = safemalloc(strlen(module)+1); strcpy(modules[i],module); } else { SetPt(&cell,0,i-min); LSetCell(module,strlen(module),cell,hlist); } } /* Sort the module list. */ if(sort) { for( i=0; i < projfiles-min; ++i ) { for( j=i+1; j < projfiles-min; ++j ) { if(!smallerstring(modules[IndexedModules[i]],modules[IndexedModules[j]])) { int temp = IndexedModules[j]; IndexedModules[j] = IndexedModules[i]; IndexedModules[i] = temp; } } } /* Finally, set the contents of each cell */ for( i=0; i < projfiles-min; ++i ) { SetPt(&cell,0,i); LSetCell(modules[IndexedModules[i]],strlen(modules[IndexedModules[i]]),cell,hlist); free(modules[IndexedModules[i]]); } } enableSingletons(dlg,hlist,projfiles-min); /* Now draw the list */ LDoDraw(TRUE,hlist); HLock((Handle)hlist); LUpdate((*hlist)->port->visRgn,hlist); (*hlist)->selFlags = lOnlyOne; HUnlock((Handle)hlist); resetDlgSearch(hlist,FALSE); return(hlist); }