home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /* FindFile */
- /* Version 1.01 */
- /* August 30, 1992 */
- /* */
- /* This is a file-find utility with a 2.0-style GadTools interface. It */
- /* doesn't support the CLI, although it can be run from the CLI; it is */
- /* meant as a Workbench utility. */
- /* */
- /* This program is Copyright ©1992 by Dave Schreiber, All Rights Reserved. */
- /* This program may not be sold for more than a small copying and shipping */
- /* and handling fee, except by written permission of Dave Schreiber. */
- /* */
- /* To compile, type: */
- /* lmk */
- /* */
- /* Version List: */
- /* 1.01 - Changed the default wildcard from '*' to '#?' (since '*' */
- /* needs to be explicitly turned on under Workbench 2.04 and not */
- /* everyone has it turned on). */
- /* August 30, 1992 */
- /* 1.00 - First release (August 27, 1992) */
- /* */
- /***************************************************************************/
-
- /*System headers*/
-
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <utility/tagitem.h>
- #include <intuition/intuition.h>
- #include <intuition/gadgetclass.h>
-
- #include <libraries/gadtools.h>
- #include <libraries/asl.h>
- #include <libraries/iffparse.h>
- #include <workbench/workbench.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/gadtools.h>
- #include <proto/asl.h>
- #include <proto/iffparse.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/wb.h>
-
- /*Program-specific headers*/
-
- #include "FF.h"
- #include "GUI.h"
- #include "Lists.h"
-
- /*SAS/C V5.10 doesn't have these (2.04) function calls in it's copy of*/
- /*amiga.lib, so these are necessary*/
-
- #pragma libcall DOSBase ParsePatternNoCase 3C6 32103
- #pragma libcall DOSBase MatchPatternNoCase 3CC 2102
-
-
- /*All the libraries we need*/
- struct Library *IntuitionBase,*GfxBase,*GadToolsBase,*AslBase,
- *WorkbenchBase,*IFFParseBase;
-
- /*Flags for user settings*/
- BOOL Links=FALSE; /*Recur into linked directories?*/
- BOOL Recur=TRUE; /*Recur at all?*/
- BOOL Wildcards=TRUE; /*Treat the 'Search For:' field as having wildcards?*/
-
- /*The linked list of files*/
- struct List *fileList=NULL;
-
- /*The linked list of a file's path components*/
- struct List *dirList=NULL;
-
- /*The message port for the AppWindow*/
- struct MsgPort *appMsgPort=NULL;
-
- /*This holds the AppWindow data*/
- struct AppWindow *appWdw=NULL;
-
- /*The ordinal number (in the filelist) of the current filename*/
- ULONG currentFilename=~0;
-
- /*This contains the four pointer images that are animated during a find*/
- /*They are not in proper "pointer" format, and must be interleaved and put*/
- /*into pointerData, below. This is done in setupPointerBuffers()*/
-
- USHORT PointerImageData[4][26] =
- {
- {
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xC000,0x01C0,0x1FC0,
- 0xFC00,0xC000,0x01C0,0x1FC0,0xFC00,0xC000,0x01C0,0x1FC0,
- 0xFC00,0xC000
- },
- {
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0x01C0,0x1FC0,0xFC00,
- 0xC000,0x01C0,0x1FC0,0xFC00,0xC000,0x01C0,0x1FC0,0xFC00,
- 0xC000,0x01C0
- },
- {
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0x1FC0,0xFC00,0xC000,
- 0x01C0,0x1FC0,0xFC00,0xC000,0x01C0,0x1FC0,0xFC00,0xC000,
- 0x01C0,0x1FC0
- },
- {
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,
- 0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFFC0,0xFC00,0xC000,0x01C0,
- 0x1FC0,0xFC00,0xC000,0x01C0,0x1FC0,0xFC00,0xC000,0x01C0,
- 0x1FC0,0xFC00
- }
- };
-
- USHORT chip pointerData[4][30];
-
- /*This keeps track of what 'frame' the pointer 'animation' is at*/
- UBYTE pointerCount=0;
-
- /*The version string. Do a 'version FF' to display it*/
- char *version="$VER: FindFile V1.01 (30.8.92)";
-
- ULONG numFiles;
-
- /*****************************************************************************/
- /* The first second contains the kernel of file-finding code */
- /*****************************************************************************/
-
- void _main(void)
- {
- char Pattern[256];
- char Directory[256];
- FindStat result=FIND_CONTINUE;
-
- /*Copy and interleave the pointer image data*/
- setupPointerBuffers();
-
- /*Open all the libraries that we need*/
- IntuitionBase=(struct Library *)OpenLibrary("intuition.library",37L);
- GfxBase=(struct Library *)OpenLibrary("graphics.library",37L);
- AslBase=(struct Library *)OpenLibrary("asl.library",37L);
- GadToolsBase=(struct Library *)OpenLibrary("gadtools.library",37L);
- WorkbenchBase=(struct Library *)OpenLibrary("workbench.library",37L);
- IFFParseBase=(struct Library *)OpenLibrary("iffparse.library",37L);
-
- /*If any of them didn't open, abort*/
- if(IntuitionBase==NULL || GfxBase==NULL || AslBase==NULL ||
- GadToolsBase==NULL || IFFParseBase==NULL)
- cleanup(100);
-
- /*Get the visual info, etc.*/
- if(SetupScreen()==0)
- {
- /*Open the window*/
- if(OpenProject0Window()==0)
- {
- /*Create the AppWindow message port and, if successful, make*/
- /*the window into an AppWindow*/
- if((appMsgPort=CreateMsgPort())!=NULL)
- appWdw=(struct AppWindow *)AddAppWindowA(1,0,Project0Wnd,
- appMsgPort,NULL);
-
- /*Loop until the user tells us to quit*/
- /*getUserSelections() either returns FALSE, in which case we*/
- /*quit, or TRUE, in which case we search*/
- while((result!=FIND_CLOSE) && getUserSelections())
- {
- /*Get the 'Search for' string*/
- strcpy(Pattern,((struct StringInfo *)
- (Project0Gadgets[GD_Pattern]->SpecialInfo))->Buffer);
-
- /*If there is no pattern or search string, print an error*/
- if(Pattern[0]==0)
- printError("Please enter a search pattern or name",NULL,NULL);
- else /*Otherwise, do the search*/
- {
- /*There is no current filename*/
- currentFilename=~0;
-
- /*Create the 'busy' pointer*/
- setBusyPointer();
-
- /*We don't want to be bothered with AppWindow messages while*/
- /*searching*/
- if(appWdw!=NULL)
- RemoveAppWindow(appWdw);
-
- /*Delete an old file list, if one exists, and initialize a*/
- /*fresh list*/
- initFileList();
-
- /*Disable all the gadgets that can be disabled, but enable */
- /*the 'Stop' gadget*/
- disableWindowGadgets();
-
- /*Get the 'Search for' string*/
- strcpy(Pattern,((struct StringInfo *)
- (Project0Gadgets[GD_Pattern]->SpecialInfo))->Buffer);
-
- /*Get the 'Directory' string*/
- strcpy(Directory,((struct StringInfo *)
- (Project0Gadgets[GD_Dir]->SpecialInfo))->Buffer);
-
- numFiles=0;
- /*And do the search*/
- result=findFiles(Directory,Pattern,Recur);
-
- /*The search is finished at this point, so enable all window*/
- /*gadgets except for the Stop gadget, which is disabled*/
- enableWindowGadgets();
-
- /*Restore the old pointer*/
- restorePointer();
-
- /*Reset the AppWindow, if it existed in the first place*/
- if(appMsgPort!=NULL)
- appWdw=(struct AppWindow *)AddAppWindowA(1,0,Project0Wnd,
- appMsgPort,NULL);
- }
- /*And loop back for another round...*/
- }
-
- /*The user wants to quit, so delete the AppWindow if it was created*/
- if(appWdw!=NULL)
- {
- RemoveAppWindow(appWdw);
- DeleteMsgPort(appMsgPort);
- }
-
- /*Delete the file and directory lists, if any exist*/
- deleteFileList();
- deleteDirList();
-
- /*Close the window*/
- CloseProject0Window();
- }
-
- /*Delete the visual info, etc.*/
- CloseDownScreen();
-
- /*Close libraries and exit with no errors*/
- cleanup(0);
- }
- }
-
- /*This is the interface between the main part of the program and the*/
- /*recursive function that actually finds files.*/
- FindStat findFiles(char *startingDir,char *pattern,BOOL recur)
- {
- char patResult[516];
- BPTR fileLock;
- UWORD c;
- FindStat result=FIND_CONTINUE;
-
- /*Clear the buffer that will hold the working pattern*/
- for(c=0;c<516;c++)
- patResult[c]=0;
-
- /*If the user specified that the 'Search For' string didn't contain*/
- /*a literal, create a working pattern from the given pattern*/
- if(Wildcards)
- ParsePatternNoCase(pattern,patResult,256);
- else
- /*Otherwise, just use the string as is*/
- strcpy(patResult,pattern);
-
- /*Get a lock on the first directory*/
- fileLock=Lock(startingDir,ACCESS_READ);
-
- if(fileLock==NULL)
- return(FIND_CONTINUE);
-
- /*And start the find*/
- result=doFileFind(fileLock,patResult,recur);
-
- /*We're done, so unlock the lock on the starting directory*/
- UnLock(fileLock);
-
- /*And return the result of the search (quit or continue)*/
- return(result);
- }
-
- char findFileName[256]; // Needs to be extern
-
- /*This is the recursive part of the file-search process. It goes through*/
- /*each file, checking to see if a name matches the given literal/pattern.*/
- /*If a directory is found, and if the user specified directory recursion,*/
- /*we call doFileFind(), giving it a lock on the subdirectory to search.*/
- FindStat doFileFind(BPTR startLock,char *pattern,BOOL recur)
- {
- struct TagItem tag;
- struct FileInfoBlock *curFib;
- BPTR oldLock;
- BPTR fileLock;
- BOOL success;
- FindStat result=FIND_CONTINUE;
-
- tag.ti_Tag=TAG_DONE;
- tag.ti_Data=0;
-
- /*Allocate a FileInfoBlock to hold the results from Execute()/ExNext().*/
- if((curFib=AllocDosObject(DOS_FIB,&tag))!=NULL)
- {
- /*Make the search directory into the current directory*/
- oldLock=CurrentDir(startLock);
-
- /*Get the name of the first directory*/
- success=Examine(startLock,curFib);
-
- /*Get the name of the first file/dir in the directory*/
- success=ExNext(startLock,curFib);
-
- /*Loop while we keep finding files and the user doesn't abort*/
- while(success && result==FIND_CONTINUE)
- {
- /*Update the pointer, to let the user know we're still alive*/
- updateBusyPointer();
-
- /*Get the name of the directory that the file is in*/
- NameFromLock(startLock,findFileName,255);
- if(findFileName[0]!=(char)0 &&
- findFileName[strlen(findFileName)-1]!=':')
- strcat(findFileName,"/");
- strcat(findFileName,curFib->fib_FileName);
-
- /*If we're doing a wildcard search, check to see if the file-*/
- /*name matches the pattern*/
- if(Wildcards)
- {
- if(MatchPatternNoCase(pattern,curFib->fib_FileName))
- updateFileList(findFileName,curFib->fib_FileName,
- curFib->fib_DirEntryType);
- }
- else
- /*If not, just do a regular string compare*/
- if(stricmp(pattern,curFib->fib_FileName)==0)
- updateFileList(findFileName,curFib->fib_FileName,
- curFib->fib_DirEntryType);
-
- /*Check to see if the user wants to abort, see a filename*/
- /*listed, etc.*/
- result=checkUserStatus();
-
- /*If this is a directory, and if we can recur into directories,*/
- /*and if this is a link to a directory and recuring into that */
- /*is OK, and if the user didn't abort, AND if the file isn't */
- /*a soft link (in which case we can't tell if its a file or a */
- /*directory), then descend into the directory.*/
- if(curFib->fib_DirEntryType > 0 && recur && result==FIND_CONTINUE
- && (Links || curFib->fib_DirEntryType != ST_LINKDIR)
- && (curFib->fib_DirEntryType != ST_SOFTLINK))
- {
- fileLock=Lock(curFib->fib_FileName,SHARED_LOCK);
- if(fileLock!=NULL)
- result=doFileFind(fileLock,pattern,TRUE);
- UnLock(fileLock);
- }
- else
- numFiles++;
-
- /*Get the next file/dir name*/
- success=ExNext(startLock,curFib);
- }
-
- /*We're done, so restore the current directory to it's entry value*/
- CurrentDir(oldLock);
-
- /*Free the FileInfoBlock that was allocated*/
- FreeDosObject(DOS_FIB,curFib);
- }
-
- /*Return the result of the search*/
- return(result);
- }
-
- /*This handles closing libraries and exiting. It will only close those*/
- /*libraries that were actually opened.*/
- void cleanup(ULONG err)
- {
- if(IntuitionBase!=NULL)
- CloseLibrary((struct Library *)IntuitionBase);
-
- if(GfxBase!=NULL)
- CloseLibrary((struct Library *)GfxBase);
-
- if(GadToolsBase!=NULL)
- CloseLibrary(GadToolsBase);
-
- if(AslBase!=NULL)
- CloseLibrary(AslBase);
-
- if(WorkbenchBase!=NULL)
- CloseLibrary(WorkbenchBase);
-
- if(IFFParseBase!=NULL)
- CloseLibrary(IFFParseBase);
-
- exit(err);
- }
-
- /*****************************************************************************/
- /* The next section is the code that handles computer-human interaction */
- /*****************************************************************************/
-
- /*This code handles input before a search takes place*/
- /*It returns TRUE if the user wants to start a search, or FALSE if she wants*/
- /*to quit*/
- BOOL getUserSelections(void)
- {
- struct IntuiMessage *mesg;
- ULONG class;
- UWORD code;
- struct Gadget *gad;
- char dirName[256];
- struct TagItem tags[2];
- ULONG sigbit;
- struct AppMessage *amsg;
-
- tags[0].ti_Tag=GTCB_Checked;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- /*Loop until we return*/
- while(TRUE)
- {
- /*Wait for input*/
- if(appWdw!=NULL)
- sigbit=Wait(1<<Project0Wnd->UserPort->mp_SigBit|1<<appMsgPort->mp_SigBit);
- else
- sigbit=Wait(1<<Project0Wnd->UserPort->mp_SigBit);
-
- /*Is it a non-AppWindow event?*/
- if(sigbit & (1<<Project0Wnd->UserPort->mp_SigBit))
- {
- /*Get the message*/
- mesg=GT_GetIMsg(Project0Wnd->UserPort);
-
- /*Loop while messages are forthcoming*/
- while(mesg!=NULL)
- {
- class=mesg->Class;
- code=mesg->Code;
- gad=(struct Gadget *)mesg->IAddress;
- GT_ReplyIMsg(mesg);
-
- /*Determine what class of message was received*/
- switch(class)
- {
- /*Window close*/
- case IDCMP_CLOSEWINDOW:
- return(FALSE);
-
- /*Menu choice*/
- case IDCMP_MENUPICK:
- if(!handleMenuInput(code))
- return(FALSE);
- break;
-
- /*Gadget press*/
- case IDCMP_GADGETUP:
- switch(gad->GadgetID)
- {
- /*The three checkbox gadgets*/
- case GD_Recur:
- tags[0].ti_Tag=GA_Disabled;
- if(Recur=!Recur)
- tags[0].ti_Data=FALSE;
- else
- tags[0].ti_Data=TRUE;
-
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Links],
- Project0Wnd,NULL, tags);
-
- tags[0].ti_Tag=GTCB_Checked;
- break;
- case GD_Links:
- Links=!Links;
- break;
- case GD_Wildcards:
- Wildcards=!Wildcards;
- break;
-
- /*This activates the 'Directory' string gadget when*/
- /*the user presses 'RETURN' while in the 'Search for'*/
- /*gadget.*/
- case GD_Pattern:
- ActivateGadget(Project0Gadgets[GD_Dir],Project0Wnd,NULL);
- break;
-
- /*The browse gadget*/
- case GD_Browse:
- /*Copy the current 'Directory' string into*/
- /*a buffer to give to the file requester*/
- strcpy(dirName,((struct StringInfo *)
- (Project0Gadgets[GD_Dir]->SpecialInfo))->Buffer);
-
- /*Call the file requester (the NULL means that we */
- /*don't want a filename returned, just a directory*/
- browse("Please select a directory",dirName,NULL);
-
- /*Place the directory name into the string gadget*/
- tags[0].ti_Tag=GTST_String;
- tags[0].ti_Data=(ULONG)dirName;
-
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Dir],
- Project0Wnd,NULL, tags);
-
- /*Restore this value to this array position, so that*/
- /*the VANILLAKEY toggles below don't have to worry*/
- /*about setting it*/
- tags[0].ti_Tag=GTCB_Checked;
- break;
-
- /*The user made a selection from the file list. Fill*/
- /*the directory component list with appropriate info.*/
- case GD_FileList:
- putInDirList(code);
- break;
-
- /*Start the search*/
- case GD_Go:
- return(TRUE);
- break;
- }
- break;
-
- /*Keyboard gadget equivalents*/
- case IDCMP_VANILLAKEY:
- switch(code)
- {
- /*Browse, same as above*/
- case 'r':
- case 'R':
- strcpy(dirName,((struct StringInfo *)
- (Project0Gadgets[GD_Dir]->SpecialInfo))->Buffer);
-
- browse("Please select a directory",dirName,NULL);
- tags[0].ti_Tag=GTST_String;
- tags[0].ti_Data=(ULONG)dirName;
-
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Dir],
- Project0Wnd,NULL, tags);
-
- tags[0].ti_Tag=GTCB_Checked;
- break;
-
- /*Search for*/
- case 'f':
- case 'F':
- ActivateGadget(Project0Gadgets[GD_Pattern],Project0Wnd,
- NULL);
- break;
-
- /*Directory*/
- case 'd':
- case 'D':
- ActivateGadget(Project0Gadgets[GD_Dir],Project0Wnd,NULL);
- break;
-
- /*Go*/
- case 'g':
- case 'G':
- return(TRUE);
-
- /*Subdirectory recursion toggle*/
- case 'b':
- case 'B':
- tags[0].ti_Data=(Recur=!Recur);
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Recur],
- Project0Wnd,NULL, tags);
- tags[0].ti_Tag=GA_Disabled;
- if(Recur)
- tags[0].ti_Data=FALSE;
- else
- tags[0].ti_Data=TRUE;
-
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Links],
- Project0Wnd,NULL, tags);
-
- tags[0].ti_Tag=GTCB_Checked;
- break;
-
- /*'Descend into links' toggle*/
- case 'l':
- case 'L':
- if(Recur)
- {
- tags[0].ti_Data=(Links=!Links);
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Links],
- Project0Wnd,NULL, tags);
- }
- break;
-
- /*'Treat "Search for" as pattern' toggle*/
- case 'w':
- case 'W':
- tags[0].ti_Data=(Wildcards=!Wildcards);
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Wildcards],
- Project0Wnd,NULL, tags);
- break;
-
- }
- break;
- }
- /*Get the next input event*/
- mesg=GT_GetIMsg(Project0Wnd->UserPort);
- }
- }
-
- /*Check to see if this was an AppWindow event*/
- if(sigbit & (1<<appMsgPort->mp_SigBit))
- {
- BPTR dirLock;
-
- /*Loop while there are AppWindow events, although if the user*/
- /*drags multiple icons into the window at once, only the first*/
- /*one will be used*/
- while((amsg=(struct AppMessage *)GetMsg(appMsgPort))!=NULL)
- {
- /*Get the lock associated with the directory of the icon*/
- dirLock=amsg->am_ArgList[0].wa_Lock;
-
- /*Get the directory name*/
- NameFromLock(dirLock,dirName,255);
-
- /*Place that directory name into the 'Directory' string gadget*/
- tags[0].ti_Tag=GTST_String;
- tags[0].ti_Data=(ULONG)dirName;
-
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Dir],
- Project0Wnd,NULL, tags);
- tags[0].ti_Tag=GTCB_Checked;
-
- /*Reply to the AppWindow message*/
- ReplyMsg((struct Message *)amsg);
- }
- }
- }
- }
-
- /*Prepare window gadgets for the start of a search*/
- void disableWindowGadgets(void)
- {
- struct TagItem tags[2];
- UBYTE gad;
-
- tags[0].ti_Tag=GA_Disabled;
- tags[0].ti_Data=TRUE;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=0;
-
- /*Disable each gadget, except for 'Stop' (which is already disabled)*/
- for(gad=0;gad<10;gad++)
- {
- /*and the two listview gadgets (the file and dir lists), since*/
- /*they can't be disabled*/
- if(gad==GD_FileList)
- gad+=2;
-
- GT_SetGadgetAttrsA(Project0Gadgets[gad],Project0Wnd,NULL,tags);
- }
-
- /*Enable the 'Stop' gadget*/
- tags[0].ti_Data=FALSE;
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Stop],Project0Wnd,NULL,tags);
-
- }
-
- /*The inverse of disableWindowGadgets(), called when a search is complete*/
- void enableWindowGadgets(void)
- {
- struct TagItem tags[2];
- UBYTE gad;
-
- tags[0].ti_Tag=GA_Disabled;
- tags[0].ti_Data=FALSE;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=0;
-
- /*Enable all gadgets except for the listviews and Stop gadget*/
- for(gad=0;gad<10;gad++)
- {
- if(gad==GD_FileList)
- gad+=2;
-
- if(gad!=GD_Links || Recur)
- GT_SetGadgetAttrsA(Project0Gadgets[gad],Project0Wnd,NULL,tags);
- }
-
- /*Disable the 'Stop' gadget*/
- tags[0].ti_Data=TRUE;
- GT_SetGadgetAttrsA(Project0Gadgets[GD_Stop],Project0Wnd,NULL,tags);
- }
-
- /*Get user input while a search is progressing*/
- FindStat checkUserStatus(void)
- {
- struct IntuiMessage *mesg;
- ULONG class;
- UWORD code;
- struct Gadget *gad;
-
- /*Get a message, if one exists (we don't Wait() since we want to return*/
- /*immediately if we don't get input*/
- mesg=GT_GetIMsg(Project0Wnd->UserPort);
- while(mesg!=NULL)
- {
- class=mesg->Class;
- code=mesg->Code;
- gad=(struct Gadget *)mesg->IAddress;
- GT_ReplyIMsg(mesg);
-
- switch(class)
- {
- /*Gadget release; it can only be one of two*/
- case IDCMP_GADGETUP:
- switch(gad->GadgetID)
- {
- /*Abort the search*/
- case GD_Stop:
- return(FIND_STOP);
-
- /*Put the directory components of the chosen filename into*/
- /*the directory list*/
- case GD_FileList:
- putInDirList(code);
- break;
- break;
- }
-
- /*The keyboard equivalent of 'Stop'*/
- case IDCMP_VANILLAKEY:
- if(code=='s' || code=='S')
- return(FIND_STOP);
- break;
-
- /*Menu selections*/
- /*Needs to be reworked*/
- case IDCMP_MENUPICK:
- if(!handleMenuInput(code))
- return(FIND_CLOSE);
- break;
-
- /*Close gadget*/
- case IDCMP_CLOSEWINDOW:
- return(FIND_CLOSE);
- }
- /*Get the next message*/
- mesg=GT_GetIMsg(Project0Wnd->UserPort);
- }
-
- /*If we've reached this point, the user hasn't pressed 'Stop', so */
- /*continue searching*/
- return(FIND_CONTINUE);
- }
-
- /*Tags for the file requester*/
- struct TagItem fileReqTags[8]=
- {
- {ASL_Hail,NULL},
- {ASL_Height,193},
- {ASL_Width,200},
- {ASL_TopEdge,5},
- {ASL_LeftEdge,10},
- {ASL_Dir,NULL},
- {ASL_File,NULL},
- {TAG_DONE,NULL}
- };
-
- /*This function brings up a file requester*/
- /*(hail==The title of the requester window)*/
- BOOL browse(char *hail,char *dir,char *name)
- {
- BOOL stat;
- struct FileRequester *fr;
- fileReqTags[0].ti_Data=(ULONG)hail;
- fileReqTags[5].ti_Data=(ULONG)dir;
- fileReqTags[6].ti_Data=(ULONG)name;
-
- /*Open the requester*/
- if((fr=(struct FileRequester *)AllocAslRequest(ASL_FileRequest,
- fileReqTags))!=NULL)
- {
- /*If the user didn't click on CANCEL*/
- if(stat=AslRequest(fr,NULL))
- {
- /*If the user wants the directory name, return it*/
- if(dir!=NULL)
- strcpy(dir,fr->rf_Dir);
-
- /*Likewise for the filename*/
- if(name!=NULL)
- strcpy(name,fr->rf_File);
- }
-
- /*Delete the file requester structure*/
- FreeAslRequest(fr);
- }
-
- return(stat);
- }
-
- BOOL handleMenuInput(UWORD menuNumber)
- {
- while(menuNumber!=MENUNULL)
- {
- if(MENUNUM(menuNumber)==0)
- {
- switch(ITEMNUM(menuNumber))
- {
- case 0:
- if(fileList!=NULL &&
- getItem(fileList,0)!=NULL)
- saveFileList(SUBNUM(menuNumber)==0);
- else
- printError("There is no list to save",NULL,NULL);
- break;
- case 2:
- printError("FindFile V1.01","August 30, 1992",
- "©1992 Dave Schreiber");
- break;
- case 4:
- return(FALSE);
- }
- }
- else
- if(ITEMNUM(menuNumber)==0)
- {
- if(SUBNUM(menuNumber)==0)
- copyNameToClipboard(TRUE);
- else
- copyNameToClipboard(FALSE);
- }
- else
- if(SUBNUM(menuNumber)==0)
- clipFileList(TRUE);
- else
- clipFileList(FALSE);
-
- menuNumber=((struct MenuItem *)ItemAddress(Project0Menus,menuNumber))->NextSelect;
- }
- return(TRUE);
- }
-
-
- /*****************************************************************************/
- /* The next section handles the file and directory lists */
- /*****************************************************************************/
-
- /*Intialize the file list*/
- void initFileList(void)
- {
- /*This will delete an old file list, if one exists*/
- deleteFileList();
-
- /*Create a new list*/
- initList(&fileList);
- return;
- }
-
- /*Add a name to the file list*/
- void updateFileList(char *name,char *nameOnly,LONG dirEntryType)
- {
- struct TagItem tags[2];
- char prefixedName[40];
-
- tags[0].ti_Tag=GTLV_Labels;
- tags[0].ti_Data=~0L;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- switch(dirEntryType)
- {
- case ST_USERDIR:
- strcpy(prefixedName,"(dir) ");
- break;
- case ST_LINKDIR:
- strcpy(prefixedName,"<hld> ");
- break;
- case ST_SOFTLINK:
- strcpy(prefixedName,"<sl> ");
- break;
- case ST_LINKFILE:
- strcpy(prefixedName,"<hl> ");
- break;
- default:
- strcpy(prefixedName," ");
- break;
- }
- strcat(prefixedName,nameOnly);
-
- /*Update the list*/
- Forbid();
- addItem(fileList,name,prefixedName,TRUE);
- Permit();
-
- /*Inform Intuition/Gadtools of the change*/
- tags[0].ti_Data=(ULONG)fileList;
- GT_SetGadgetAttrsA(Project0Gadgets[GD_FileList], Project0Wnd,NULL, tags);
-
- return;
- }
-
- /*Delete the file list, if one exists*/
- void deleteFileList(void)
- {
- struct TagItem tags[2];
-
- tags[0].ti_Tag=GTLV_Labels;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- /*If there is a list*/
- if(fileList!=NULL)
- {
- tags[0].ti_Data=0L;
-
- /*Detach the list from the file listview gadget*/
- GT_SetGadgetAttrsA(Project0Gadgets[GD_FileList], Project0Wnd,NULL, tags);
-
- /*Delete the list itself*/
- freeList(&fileList);
- }
-
- return;
- }
-
- /*Put a filename into the directory listview*/
- void putInDirList(UWORD code)
- {
- dosNameNode *name;
- char filename[256];
- char part[36];
- char finalPart[40];
- char *currentPart;
- int s=0;
- struct TagItem tags[2];
- BOOL first=TRUE;
-
- currentFilename=code;
- tags[0].ti_Tag=GTLV_Labels;
- tags[0].ti_Data=~0L;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- /*Delete a previous directory component list, if one exists*/
- deleteDirList();
-
- /*Initialize a new list*/
- initList(&dirList);
-
- /*Get the node corresponding to the name that the user selected*/
- name=getItem(fileList,code);
-
- /*Get the filename*/
- strcpy(filename,name->fullFilename);
-
- /*This pointer points to the part of the filename that we're currently*/
- /*working on*/
- currentPart=filename;
-
- /*Loop until we run out of filename*/
- while(*currentPart!=0)
- {
- s=0;
-
- /*Copy a filename component to 'part'*/
- do
- {
- part[s++]=*currentPart++;
- }
- while(part[s-1]!=':' && part[s-1]!='/' && part[s-1]!=0);
-
- /*If the component ends with a 0, it is the actual filename*/
- if(part[s-1]==0)
- {
- currentPart--;
-
- /*Indent 2 spaces*/
- strcpy(finalPart," ");
- strcat(finalPart,&name->node.ln_Name[STARTOFNAME]);
- }
- /*Ends with a ':'? Its the device name (no indent)*/
- else if(part[s-1]==':')
- {
- part[s]=0;
- strcpy(finalPart,part);
- }
- /*Otherwise, ending with a slash==directory name*/
- else if(part[s-1]=='/')
- {
- part[s-1]=0;
-
- /*Indent with one space*/
- strcpy(finalPart," ");
- strcat(finalPart,part);
- }
-
-
- /*If this isn't the first item in the list, detach the list from the*/
- /*dirlist listview*/
- if(!first)
- GT_SetGadgetAttrsA(Project0Gadgets[GD_DirList], Project0Wnd,NULL, tags);
- else
- first=FALSE;
-
- /*Add the item to the list*/
- addItem(dirList,finalPart,NULL,FALSE);
- tags[0].ti_Data=(ULONG)dirList;
-
- /*Update the listview*/
- GT_SetGadgetAttrsA(Project0Gadgets[GD_DirList], Project0Wnd,NULL, tags);
- }
-
- return;
- }
-
- /*Delete the directory component list, if it exists*/
- void deleteDirList(void)
- {
- struct TagItem tags[2];
-
- tags[0].ti_Tag=GTLV_Labels;
- tags[0].ti_Data=0L;
- tags[1].ti_Tag=TAG_DONE;
- tags[1].ti_Data=NULL;
-
- if(dirList!=NULL)
- {
- /*Detach the list from the listview*/
- GT_SetGadgetAttrsA(Project0Gadgets[GD_DirList], Project0Wnd,NULL, tags);
-
- /*And delete it*/
- freeList(&dirList);
- }
-
- return;
- }
-
- /*****************************************************************************/
- /* This code handles error and status reporting */
- /*****************************************************************************/
-
- struct EasyStruct errorReq=
- {
- sizeof(struct EasyStruct),
- 0,
- "Program Request...",
- NULL,
- "Ok"
- };
-
- /*The three possible formatting strings*/
- char *oneLine="%s";
- char *twoLine="%s\n%s";
- char *threeLine="%s\n%s\n%s";
-
- /*Print a one, two, or three line error message in an EasyRequester*/
- void printError(char *first,char *second,char *third)
- {
- APTR args[4];
- args[0]=args[3]=NULL;
-
- /*Three lines*/
- if(third!=NULL)
- {
- args[2]=third;
- args[1]=second;
- args[0]=first;
- errorReq.es_TextFormat=threeLine;
- }
- /*Two lines*/
- else if(second!=NULL)
- {
- args[1]=second;
- args[0]=first;
- errorReq.es_TextFormat=twoLine;
- }
- /*One line*/
- else if(first!=NULL)
- {
- args[0]=first;
- errorReq.es_TextFormat=oneLine;
- }
-
- /*Put up the requester*/
- EasyRequestArgs(NULL,&errorReq,NULL,args);
- return;
- }
-
- /*Copy the pointer imagery from a buffer holding Gadget Image style image data*/
- /*to a chip memory buffer that will hold the images in the interleaved format*/
- /*required by the Amiga's sprite machinery*/
- void setupPointerBuffers(void)
- {
- UBYTE pointer,value;
-
- /*For each of the four pointer animation 'frames'*/
- for(pointer=0;pointer<4;pointer++)
- {
- /*Initialize the required 0 at the beginning and end of the sprite data*/
- pointerData[pointer][0]=pointerData[pointer][1]=0;
- pointerData[pointer][28]=pointerData[pointer][29]=0;
-
- /*Copy the data over*/
- for(value=0;value<13;value++)
- {
- pointerData[pointer][2*value+2]=PointerImageData[pointer][value];
- pointerData[pointer][2*value+3]=PointerImageData[pointer][value+13];
- }
- }
- return;
- }
-
- /*Set the pointer to 'frame' 0 of the busy-pointer animation*/
- void setBusyPointer(void)
- {
- pointerCount=0;
-
- SetPointer(Project0Wnd,pointerData[0],13,10,-1,0);
- return;
- }
-
- /*Advance to the next 'frame' of the pointer animation*/
- void updateBusyPointer()
- {
- /*If at the end, loop back*/
- if(++pointerCount==4)
- pointerCount=0;
-
- SetPointer(Project0Wnd,pointerData[pointerCount],13,10,-1,0);
- return;
- }
-
- /*Remove the busy-pointer animation and restore the system pointer*/
- void restorePointer()
- {
- ClearPointer(Project0Wnd);
- return;
- }
-
- /*****************************************************************************/
- /* The next section handles clipboard I/O */
- /*****************************************************************************/
-
- struct IFFHandle *iff=NULL;
- struct ContextNode *cn;
-
- /*Open the clipboard and create an iffparse.library parsing instance to*/
- /*be used for communication with the clipboard (all data is written out*/
- /*in FTXT format.*/
- /*Returns TRUE if successful, FALSE if not*/
- BOOL openClipboard(UBYTE unit)
- {
- /*Get the IFF handle*/
- if((iff=(struct IFFHandle *)AllocIFF())!=NULL)
- {
- /*Open the clipboard*/
- if((iff->iff_Stream=(ULONG)OpenClipboard(unit))!=NULL)
- {
- /*Initialize the IFF handle*/
- InitIFFasClip(iff);
-
- /*and open it*/
- if(OpenIFF(iff,IFFF_WRITE)==0)
- {
- /*Create a 'FORM FTXT' header*/
- if(PushChunk(iff,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN)==0)
- {
- /*Create a 'CHRS' chunk*/
- if(PushChunk(iff,0,ID_CHRS,IFFSIZE_UNKNOWN)==0)
- return(TRUE);
-
- PopChunk(iff);
- }
- CloseIFF(iff);
- }
- CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
- }
- FreeIFF(iff);
- }
- return(FALSE);
- }
-
- /*Write a given string to the clipboard*/
- void writeStringToClipboard(char *string,ULONG stringLen)
- {
- if(stringLen==~0)
- WriteChunkBytes(iff,string,strlen(string));
- else
- WriteChunkBytes(iff,string,stringLen);
- return;
- }
-
- /*Close the clipboard*/
- void closeClipboard(void)
- {
- PopChunk(iff);
- PopChunk(iff);
- CloseIFF(iff);
- CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
- FreeIFF(iff);
-
- return;
- }
-
- /*Copy the currently selected filename to the clipboard*/
- void copyNameToClipboard(BOOL full)
- {
- dosNameNode *name;
-
- /*If there is a current filename...*/
- if(currentFilename!=~0)
- {
- /*Get the name*/
- name=getItem(fileList,currentFilename);
-
- /*IF the clipboard was opened successfully*/
- if(openClipboard(0))
- {
- /*Write the full path name*/
- if(full)
- writeStringToClipboard(name->fullFilename,~0L);
- else
- /*Or just the filename*/
- writeStringToClipboard(&name->node.ln_Name[STARTOFNAME],~0L);
-
- /*Close the clipboard*/
- closeClipboard();
- }
- }
-
- return;
- }
-
- /*Send the entire file list to the clipboard*/
- void clipFileList(BOOL full)
- {
- dosNameNode *filename=(dosNameNode *)fileList->lh_Head;
- if(filename==NULL)
- return;
-
- /*Open the clipboard*/
- if(openClipboard(0))
- {
- /*For each name in the list*/
- while(filename->node.ln_Succ!=NULL)
- {
- /*Write either the*/
- if(full)
- /*Full directory path*/
- writeStringToClipboard(filename->fullFilename,~0);
- else
- /*Or just the filename*/
- writeStringToClipboard(&filename->node.ln_Name[STARTOFNAME],~0);
-
- /*End each line with a line feed*/
- writeStringToClipboard("\n",1);
-
- /*Get the next filename*/
- filename=(dosNameNode *)filename->node.ln_Succ;
- }
- /*Close the clipboard*/
- closeClipboard();
- }
- return;
- }
-
-
- /*****************************************************************************/
- /* The next section is the code that handles disk I/O */
- /*****************************************************************************/
-
- static char saveDirName[256]={NULL};
-
- static char saveFilename[36]={NULL};
-
- /*This function save a file list to a file*/
- void saveFileList(BOOL full)
- {
- char fullFilename[256];
- dosNameNode *filename;
- BPTR filePointer;
- BOOL stat;
-
- /*Get the filename*/
- stat=browse("Please select a filename",saveDirName,saveFilename);
-
- /*If we didn't get a name, or the user pressed CANCEL, or there is no*/
- /*filelist, return*/
- if(saveFilename[0]==0 || !stat || (fileList==NULL))
- return;
-
- /*Create the full filename*/
- strcpy(fullFilename,saveDirName);
- if(fullFilename[strlen(fullFilename)-1]!=':' && fullFilename[0]!=0)
- strcat(fullFilename,"/");
- strcat(fullFilename,saveFilename);
-
- /*Get the first item in the file list*/
- filename=getItem(fileList,0);
-
- /*Open the file*/
- if((filePointer=Open(fullFilename,MODE_NEWFILE))!=NULL)
- {
- /*Loop through each filename*/
- while(filename->node.ln_Succ!=NULL)
- {
- /*Write out either the */
- if(full)
- /*Full pathname*/
- Write(filePointer,filename->fullFilename,strlen(filename->fullFilename));
- else
- /*Or just the filename*/
- Write(filePointer,&filename->node.ln_Name[STARTOFNAME+1],
- strlen(filename->node.ln_Name)-STARTOFNAME);
-
- /*Append with a carrage return*/
- Write(filePointer,"\n",1);
-
- /*Get the next node*/
- filename=(dosNameNode *)filename->node.ln_Succ;
- }
- /*Close the file*/
- Close(filePointer);
- }
-
- return;
- }
-
- /*End of FF.c*/
-
-