home *** CD-ROM | disk | FTP | other *** search
- /* STDFILE -- Standard File Requestor. Version 2.0a 15 June 1987
- *
- * AUTHOR -- Peter da Silva US (713) 497-4372
- *
- * Copyright (c) 1987 Peter da Silva, all rights reserved.
- *
- * This module may be freely used in any product, commercial or
- * otherwise, provided credit is given for this module and
- * and provided this notice remains intact in the source. The
- * intent of this module is to provide a standard file requestor
- * such as is available on the Macintosh, in GEM on the IBM-PC
- * and Atari ST, and in the Microsoft Windows software on the
- * IBM-PC. The advantage this module has over other requestors
- * is that it minimises disk accesses: an important consideration
- * given the structure of AmigaDos directories. If you need to
- * modify it for your needs, by all means go ahead... but please
- * conform to the intent of this program as stated above. If you
- * have suggestions for improvements, by all means call me at
- * the number listed above.
- *
- * Enhancements in the current version:
- *
- * Gadgets now boxed. Display generally cleaned up.
- *
- * True "dictionary order" for searches.
- *
- * Default pattern can now be specified. Default file name now
- * specified in a single argument.
- *
- * Directories always match.
- *
- * Null pattern converted to "#?" universal wildcard.
- *
- * If you attempt to build a file name longer than 128 characters the
- * screen will flash and the operation will be aborted.
- *
- * "Volumes" gadget, using the device list code in "mounted". This
- * gadget brings up a list of all currently mounted volumes for
- * selection. Volumes leaves the directory specification intact, so
- * you can quickly return to where you left off.
- *
- * "Parent" gadget, displays parent directory.
- *
- * With these enhancements it is now possible to select any file on
- * any device without touching the keyboard. This is now release 2.0,
- * as it is significantly better than 1.0.
- *
- * Acknowledgements:
- *
- * Thanks to Jeff Lydiatt for the pattern matching code in PatMatch.c
- * Thanks to Jay Miner, =RJ= and the whole Amiga team for the Amiga
- * itself.
- *
- * Environment:
- *
- * IntuitionBase and GfxBase must be open. dos.library must be open
- * under the name "DOSBase". Link with PatMatch.o and VolList.o.
- *
- * Usage:
- *
- * #define MAXFILENAME 128
- *
- * int stdfile(title, default_file, default_pat, name);
- * char *title;
- * char *default_file;
- * char *default_pattern;
- * char name[MAXFILENAME];
- *
- * struct Screen *stdscreen;
- *
- * STDFILE puts up a file requestor (actually, it's a plain window)
- * in stdscreen. If stdscreen is NULL, the workbench screen is used.
- * The requestor looks like this (allowing for the limitations of
- * text):
- *
- * +-----------------------------------+
- * |o| Title ------------------- | | | title parameter, or "File Name"
- * |-----------------------------------|
- * | Directory: [ ] | Directory parameter, or current.
- * | File name: [ ] | Default parameter, or empty.
- * | Pattern: [ ] | Initially empty, if the user
- * | +-------------------------------+ | enters anything here it will
- * | | [Filename] | | | be used to select files. The
- * | | [Filename] | | | file display will also be empty
- * | | [Filename] |@@| | to start with to avoid excess
- * | | [Filename] |@@| | disk I/O. If the user selects
- * | | |@@| | here the directory will be
- * | | |@@| | scanned looking for files
- * | | | | | matching the specified pattern,
- * | | | | | or "#?" if no pattern is given.
- * | | | | |
- * | +-------------------------------+ | ACCEPT returns 1. CANCEL
- * | [ACCEPT] [VOLUMES] [CANCEL] | or the close gadget return 0.
- * +-----------------------------------+ VOLUMES displays volume names.
- *
- * The number of filenames displayed is specified at compile time in the
- * constant MAXFILES. The maximum size of a filename is specified in the
- * constant MAXNAME. The parameter "Default file" will be broken into
- * directory and file parts.
- */
- char *Copyright =
- "stdfile V2.0a. Copyright (c) 1987 Peter da Silva. All rights reserved.";
- #include <intuition/intuitionbase.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <exec/memory.h>
-
- extern USHORT BusyPointer;
- extern int read_dir,dir_only;
- char *malloc();
-
- #define MAXFILES 8
- #define MAXNAME 32
- #define MAXFULL (MAXNAME*4)
-
- /* SIZING PARAMS */
- #define Z NULL
- #define INDENT 6
- #define LEFTMAR (INDENT-1)
- #define BORDER 3
- #define CHSIZ 8
- #define HT CHSIZ
- #define BASELINE 6
- #define BUTWID (6*CHSIZ+INDENT*2)
-
- /* GADGET BORDERS */
- #define IN1 LEFTMAR+10*CHSIZ
- #define IN3 LEFTMAR+3
- #define IN4 -(INDENT+6*CHSIZ+1)
- #define IN5 -(INDENT+CHSIZ*2)
- #define IN6 ((WINWD-BUTWID)/3+INDENT)
- #define IN7 (((WINWD-BUTWID)*2)/3+INDENT)
- #define WD1 -(INDENT+IN1)
- #define WD3 (6*CHSIZ)
- #define WD4 (6*CHSIZ)
- #define WD5 (CHSIZ*2+2)
- #define WD6 (6*CHSIZ)
- #define WD7 (6*CHSIZ)
- #define TP1 (CHSIZ+BORDER)
- #define TP2 (TP1+HT+1)
- #define TP3 (TP2+HT+1)
- #define TP4 -(BORDER+HT4-1)
- #define TP5 (TP3+HT+BORDER)
- #define HT4 (HT+1)
- #define HT5 CHSIZ*MAXFILES+INDENT
-
- #define WINHT (TP5 + HT5 + (-TP4) + BORDER)
- #define WINWD (INDENT*4 + (MAXNAME+2)*CHSIZ)
- #define WININ (640-WINWD)/2
- #define WINTP (200-WINHT)/2
-
- #define HOMEX (INDENT+LEFTMAR)
- #define HOMEY (TP5+BORDER)
- #define LASTX (HOMEX+MAXNAME*CHSIZ)
- #define LASTY (HOMEY+MAXFILES*CHSIZ)
-
- #define BTP TP5
- #define BIN LEFTMAR
- #define BWD (WINWD-INDENT-BIN)
- #define BHT (WINHT-BTP-(-TP4+BORDER+1))
-
- #define SF GADGHCOMP|GRELWIDTH
- #define SEL SELECTED
- #define BF1 GADGHCOMP|GRELBOTTOM
- #define BF2 GADGHCOMP|GRELBOTTOM|GRELRIGHT
- #define PF GRELRIGHT
-
- #define SA RELVERIFY
- #define CEN STRINGCENTER
- #define BA RELVERIFY
- #define PA RELVERIFY
-
- #define SI(n) (APTR)&STD_String[n]
- #define G(n) &STD_Gadget[n]
- #define IMAG (APTR)&STD_Image
- #define PROP (APTR)&STD_Prop
-
- #define SG STRGADGET
- #define BG BOOLGADGET
- #define PG PROPGADGET
-
- #define FP AUTOBACKPEN
- #define BP AUTOFRONTPEN
-
- #define OKTEXT &STD_OK
- #define NOTEXT &STD_CANCEL
- #define VLTEXT &STD_VOLUME
- #define PRTEXT &STD_PARENT
-
- static int DoneFlag;
-
- #define DirName SBuffer[0]
- #define FileName SBuffer[1]
- #define PatName SBuffer[2]
- #define STRINGS 3
-
- static UBYTE SBuffer[STRINGS][MAXFULL];
- static UBYTE Undo[MAXFULL];
-
- static struct StringInfo STD_String[STRINGS] = {
- {SBuffer[0],Undo,0,MAXFULL,0},
- {SBuffer[1],Undo,0,MAXFULL,0},
- {SBuffer[2],Undo,0,MAXFULL,0}
- };
-
- static struct PropInfo STD_Prop = { AUTOKNOB|FREEVERT, 0, 0, 0, 0 };
-
- static struct IntuiText STD_OK =
- { FP, BP, JAM2, 0, 1, Z, (UBYTE *)" OK ", Z };
- static struct IntuiText STD_CANCEL =
- { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"CANCEL", Z };
- static struct IntuiText STD_VOLUME =
- { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"VOLUME", Z };
- static struct IntuiText STD_PARENT =
- { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"PARENT", Z };
-
- #define BUTTONS 4
- #define BUTVEC 8
-
- static SHORT butvecs[BUTTONS][BUTVEC*2] = {
- {
- -2, HT4,
- -2, -1,
- WD3+1,-1,
- WD3+1,HT4,
- -3, HT4,
- -3,-1,
- WD3+2,-1,
- WD3+2, HT4
- },
- {
- -2, HT4,
- -2, -1,
- WD4+1,-1,
- WD4+1,HT4,
- -3, HT4,
- -3,-1,
- WD4+2,-1,
- WD4+2, HT4
- },
- {
- -2, HT4,
- -2, -1,
- WD6+1,-1,
- WD6+1,HT4,
- -3, HT4,
- -3,-1,
- WD6+2,-1,
- WD6+2, HT4
- },
- {
- -2, HT4,
- -2, -1,
- WD7+1,-1,
- WD7+1,HT4,
- -3, HT4,
- -3,-1,
- WD7+2,-1,
- WD7+2, HT4
- }
- };
- static struct Border ButBorder[BUTTONS] = {
- {0, 0, FP, BP, JAM1, BUTVEC, butvecs[0], NULL},
- {0, 0, FP, BP, JAM1, BUTVEC, butvecs[1], NULL},
- {0, 0, FP, BP, JAM1, BUTVEC, butvecs[2], NULL},
- {0, 0, FP, BP, JAM1, BUTVEC, butvecs[3], NULL}
- };
- #define BB(n) &ButBorder[n]
-
- static struct Image STD_Image;
-
- #define DIRID 0
- #define FILID 1
- #define PATID 2
- #define YESID 3
- #define CANID 4
- #define VOLID 5
- #define PARID 6
- #define BARID 7
- #define GADGETS 8
-
- static struct Gadget STD_Gadget[GADGETS] = {
- /*NEXT, LFT, TP,WDTH, H, FLAG, ACT, TYP, REND, Z, TXT, Z, SPEC, ID, Z */
- { G(1), IN1,TP1, WD1,HT, SF, SA, SG, Z, Z, Z, Z, SI(0), 0, 0 },
- { G(2), IN1,TP2, WD1,HT, SF, SA, SG, Z, Z, Z, Z, SI(1), 1, 0 },
- { G(3), IN1,TP3, WD1,HT, SF, SA, SG, Z, Z, Z, Z, SI(2), 2, 0 },
- { G(4), IN3,TP4, WD3,HT4,BF1, BA, BG,BB(0), Z, OKTEXT, Z, Z, 3, 0 },
- { G(5), IN4,TP4, WD4,HT4,BF2, BA, BG,BB(1), Z, NOTEXT, Z, Z, 4, 0 },
- { G(6), IN6,TP4, WD6,HT4,BF1, BA, BG,BB(2), Z, VLTEXT, Z, Z, 5, 0 },
- { G(7), IN7,TP4, WD7,HT4,BF1, BA, BG,BB(3), Z, PRTEXT, Z, Z, 6, 0 },
- { NULL, IN5,TP5, WD5,HT5,PF, PA, PG, IMAG, Z, Z, Z, PROP, 7, 0 }
- };
-
- static struct NewWindow STD_NewWindow = {
- WININ, WINTP, WINWD, WINHT, -1, -1,
- REFRESHWINDOW|MOUSEBUTTONS|GADGETUP|CLOSEWINDOW,
- WINDOWDRAG|WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE,
- G(0), NULL, "File Name Requestor",
- NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN
- };
- static struct Window *STD_Window;
-
- #define NVEC 6
-
- static SHORT Vectors[NVEC*2] = {
- BIN+1, BTP,
- BIN+1, BTP+BHT,
- BIN+BWD, BTP+BHT,
- BIN+BWD, BTP,
- BIN, BTP,
- BIN, BTP+BHT
- };
-
- static struct Border STD_FileBox = {
- 0, 0, FP, BP, JAM1, NVEC, Vectors, NULL
- };
-
- static struct IntuiText STD_Text[3] = {
- { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"Directory:", NULL },
- { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"File Name:", NULL },
- { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"Pattern:", NULL }
- };
-
- static OpenFileWindow()
- {
- extern struct IntuitionBase *IntuitionBase;
- extern int windowleftedge,windowtopedge;
- int i;
-
- /* Rebuild gadget list */
- STD_NewWindow.FirstGadget = &STD_Gadget[0];
- for(i = 0; i < GADGETS; i++) {
- STD_Gadget[i].NextGadget = (i==GADGETS-1)?(0):(&STD_Gadget[i+1]);
- }
- for(i = 0; i < STRINGS; i++) {
- STD_String[i].BufferPos = strlen(SBuffer[i]);
- STD_String[i].DispPos = 0;
- }
- STD_Prop.VertBody = 0xFFFF;
- STD_Prop.VertPot = 0;
-
- STD_NewWindow.TopEdge=WINTP+windowtopedge;
- STD_NewWindow.LeftEdge=WININ+windowleftedge;
- if(!(STD_Window = OpenWindow(&STD_NewWindow))) {
- return 0;
- }
-
- /* This optional line will activate a string gadget */
- if ( IntuitionBase->lib_Version > 32 )
- {
- if (dir_only)
- ActivateGadget(G(0),STD_Window,0L);
- else
- ActivateGadget(G(1),STD_Window,0L);
- }
-
- CalcPropGadget();
- PaintFileWindow();
- return 1;
- }
-
- static CloseFileWindow()
- {
- STD_NewWindow.LeftEdge = STD_Window->LeftEdge;
- STD_NewWindow.TopEdge = STD_Window->TopEdge;
- if(STD_Window)
- CloseWindow(STD_Window);
- }
-
- static int State;
-
- #define INITIAL 0
- #define DIRECTORY 1
-
- static PaintFileWindow()
- {
- DrawBorder(STD_Window->RPort, &STD_FileBox, 0, 0);
- PrintIText(STD_Window->RPort, &STD_Text[0], LEFTMAR, TP1);
- PrintIText(STD_Window->RPort, &STD_Text[1], LEFTMAR, TP2);
- PrintIText(STD_Window->RPort, &STD_Text[2], LEFTMAR, TP3);
- if(State == DIRECTORY) PrintFileNames();
- }
-
- static int FirstFile;
- static int Selected;
- static int NumFiles;
- static struct dirent {
- struct dirent *nextfile;
- SHORT filetype;
- char *filename;
- } *NameList, **NameTable;
-
- #define FILETYPE 0
- #define DIRTYPE 1
- #define VOLTYPE 2
-
- static PrintFileNames()
- {
- int i;
-
- for(i = 0; i < MAXFILES; i++) {
- SetBPen(STD_Window->RPort, BP);
- SetAPen(STD_Window->RPort, BP);
- RectFill(STD_Window->RPort,
- HOMEX, HOMEY+i*CHSIZ,
- LASTX, HOMEY+(i+1)*CHSIZ);
- if(i+FirstFile < NumFiles)
- PrintName(i+FirstFile, i+FirstFile==Selected);
- }
- }
-
- static PrintName(file, hilite)
- int file;
- int hilite;
- {
- int i;
-
- i = file - FirstFile;
-
- Move(STD_Window->RPort, HOMEX, HOMEY+i*CHSIZ+BASELINE);
- if(hilite == 0) {
- SetBPen(STD_Window->RPort, BP);
- if(NameTable[file]->filetype == FILETYPE)
- SetAPen(STD_Window->RPort, FP);
- else
- SetAPen(STD_Window->RPort, 3);
- } else {
- SetAPen(STD_Window->RPort, BP);
- if(NameTable[file]->filetype == FILETYPE)
- SetBPen(STD_Window->RPort, FP);
- else
- SetBPen(STD_Window->RPort, 3);
- }
- Text(STD_Window->RPort,
- NameTable[file]->filename,
- strlen(NameTable[file]->filename));
- }
-
- static CalcPropGadget()
- {
- int VertPot, VertBody;
-
- if(State == INITIAL) return;
-
- if(NumFiles<=MAXFILES) {
- VertBody = 0xFFFF;
- VertPot = 0;
- FirstFile = 0;
- } else {
- VertBody = ((MAXFILES<<16)-1) / NumFiles;
- VertPot = 0;
- FirstFile = 0;
- }
-
- ModifyProp(&STD_Gadget[BARID], STD_Window, NULL,
- STD_Prop.Flags, 0, VertPot, 0, VertBody);
- }
-
- static CalcFilePosition()
- {
- int old_pos;
-
- if(State == INITIAL) return;
-
- old_pos = FirstFile;
- if(NumFiles<=MAXFILES)
- FirstFile = 0;
- else {
- int VertPot = STD_Prop.VertPot;
-
- FirstFile = ((VertPot+1)*(NumFiles-MAXFILES))>>16;
- }
- if(old_pos != FirstFile)
- PrintFileNames();
- }
-
- FreeList(list)
- struct dirent *list;
- {
- struct dirent *ptr;
-
- while(list) {
- ptr = list->nextfile;
- if(list->filename) free(list->filename);
- free(list);
- list = ptr;
- }
- }
-
- static ReadNewDir()
- {
- struct dirent *NewList, **NewTable, *ptr;
- int NewCount;
- struct FileInfoBlock *FIB;
- BPTR dirlock;
-
- SetPointer(STD_Window,&BusyPointer,22,16,0,0);
-
- if(State != DIRECTORY) {
- NameTable = 0;
- NameList = 0;
- }
- if(DirName[0])
- dirlock = Lock(DirName, ACCESS_READ);
- else {
- BPTR ram;
- ram = Lock("RAM:", ACCESS_READ);
- dirlock = CurrentDir(ram);
- CurrentDir(dirlock);
- UnLock(ram);
- }
- if(dirlock==0) {
- ClearPointer(STD_Window);
- return 0;
- }
-
- /* FIB must be long word aligned, and aztec doesn't guarantee this, so: */
- if((FIB = AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC)) == 0) {
- UnLock(dirlock);
- ClearPointer(STD_Window);
- return 0;
- }
- if(!Examine(dirlock, FIB)) {
- UnLock(dirlock);
- FreeMem(FIB, sizeof(struct FileInfoBlock));
- ClearPointer(STD_Window);
- return 0;
- }
- if(FIB->fib_DirEntryType < 0) {
- UnLock(dirlock);
- FreeMem(FIB, sizeof(struct FileInfoBlock));
- ClearPointer(STD_Window);
- return 0;
- }
- NewList = 0;
- NewCount = 0;
- while(ExNext(dirlock, FIB)) {
- NewCount += 1;
- ptr = (struct dirent *)malloc(sizeof(struct dirent));
- if(ptr==0) {
- FreeList(NewList);
- UnLock(dirlock);
- FreeMem(FIB, sizeof(struct FileInfoBlock));
- ClearPointer(STD_Window);
- return 0;
- }
- ptr->nextfile = NewList;
- ptr->filetype = (FIB->fib_DirEntryType<0)?FILETYPE:DIRTYPE;
- ptr->filename = malloc(strlen(FIB->fib_FileName)+1);
- if(ptr->filename == 0) {
- FreeList(ptr);
- UnLock(dirlock);
- FreeMem(FIB, sizeof(struct FileInfoBlock));
- ClearPointer(STD_Window);
- return 0;
- }
- strcpy(ptr->filename, FIB->fib_FileName);
- NewList = ptr;
- }
- FreeMem(FIB, sizeof(struct FileInfoBlock));
- if(DirName[0]) {
- UnLock(dirlock);
- }
- NewTable = malloc(sizeof(struct dirent *)*NewCount);
- if(NewTable==0) {
- FreeList(NewList);
- ClearPointer(STD_Window);
- return 0;
- }
- FreeList(NameList);
- NameList = NewList;
- if(NameTable) free(NameTable);
- NameTable = NewTable;
-
- if(PatName[0]==0)
- SetPatName("#?");
-
- State = DIRECTORY;
- Selected = -1;
-
- ReCalcPattern();
- ClearPointer(STD_Window);
- }
-
- static ReadVol()
- {
- struct dirent *NewList, **NewTable, *ptr;
- int NewCount;
- char name[MAXNAME];
-
- if(State != DIRECTORY) {
- NameTable = 0;
- NameList = 0;
- }
- OpenVolList();
- NewList = 0;
- NewCount = 0;
- while(ReadVolList(name)) {
- NewCount += 1;
- ptr = (struct dirent *)malloc(sizeof(struct dirent));
- if(ptr==0) {
- FreeList(NewList);
- return 0;
- }
- ptr->nextfile = NewList;
- ptr->filetype = VOLTYPE;
- ptr->filename = malloc(strlen(name)+1);
- if(ptr->filename == 0) {
- FreeList(ptr);
- return 0;
- }
- strcpy(ptr->filename, name);
- if(!(strcmp(ptr->filename,"RAM Disk:")))
- strcpy(ptr->filename,"RAM:");
- NewList = ptr;
- }
- CloseVolList();
- NewTable = malloc(sizeof(struct dirent *)*NewCount);
- if(NewTable==0) {
- FreeList(NewList);
- return 0;
- }
- FreeList(NameList);
- NameList = NewList;
- if(NameTable) free(NameTable);
- NameTable = NewTable;
-
- if(PatName[0]==0)
- SetPatName("#?");
-
- State = DIRECTORY;
- Selected = -1;
-
- ReCalcPattern();
- }
-
- static WORD PatCode[128];
-
- static patcomp()
- {
- /* This is a judgement call: that no pattern should be equivalent
- to "#?". Perhaps it should do this invisibly, by adding a
- pointer to the real pattern name and making it PatName or "#?"
- as appropriate. */
-
- if(!PatName[0])
- SetPatName("#?");
- return CmplPat(PatName, PatCode);
- }
-
- static patmatch(name)
- {
- return Match(PatName, PatCode, name);
- }
-
- /* this routine does a true dictionary search:
- *
- * Devs < devs but Devs > devices
- */
- static table_compare(p1, p2)
- struct dirent **p1, **p2;
- {
- char *s1, *s2;
- char c1, c2;
- char firstdiff;
-
- s1 = (*p1)->filename;
- s2 = (*p2)->filename;
- firstdiff = 0;
-
- while(*s1 && *s2) {
- c1 = *s1++;
- c2 = *s2++;
- if(firstdiff==0)
- firstdiff = c1 - c2;
- if(c1>='A' && c1<='Z') c1 = c1+'@';
- if(c2>='A' && c2<='Z') c2 = c2+'@';
- if(c1 != c2)
- return c1 - c2;
- }
- return firstdiff;
- }
-
- static sort_table()
- {
- qsort(NameTable, NumFiles, sizeof(struct dirent *), table_compare);
- return 1;
- }
-
- static ReCalcPattern()
- {
- if(State != DIRECTORY)
- ReadNewDir();
- else {
- struct dirent *ptr;
- patcomp();
-
- NumFiles = 0;
- for(ptr = NameList; ptr; ptr=ptr->nextfile) {
- /* Directories always match. Is this good? */
- if(ptr->filetype == DIRTYPE ||
- ptr->filetype == VOLTYPE ||
- patmatch(ptr->filename)) {
- NameTable[NumFiles] = ptr;
- NumFiles++;
- }
- }
- sort_table();
- CalcPropGadget();
- Selected = -1;
- PrintFileNames();
- }
- }
-
- static SetGadgetText(id, text)
- int id;
- char *text;
- {
- int position;
-
- position = RemoveGadget(STD_Window, G(id));
- if(position != -1) {
- strcpy(SBuffer[id], text);
- STD_String[id].BufferPos = strlen(text);
- position = AddGadget(STD_Window, G(id), -1);
- if(position != -1)
- RefreshGadgets(G(id), STD_Window, NULL);
- }
- }
-
- static SetDirName(name)
- char *name;
- {
- char buffer[MAXFULL+1], *ptr;
- int index;
- char lastchar;
-
- /* Can't enter a file name too long. */
- if(strlen(DirName) + strlen(name) + 1 > MAXFULL) {
- DisplayBeep();
- return 0;
- }
- index = 0;
- lastchar = 0;
- for(ptr = DirName; *ptr; ptr++)
- buffer[index++] = lastchar = *ptr;
- if(lastchar!='/' && lastchar!=':' && lastchar!=0)
- buffer[index++] = '/';
- strcpy(&buffer[index], name);
- SetGadgetText(DIRID, buffer);
- SetGadgetText(FILID, "");
- return 1;
- }
-
- static ReadParDir()
- {
- int i;
- int ptr;
-
- ptr = -1;
- for(i = 0; DirName[i]; i++)
- if(DirName[i]==':' || DirName[i]=='/')
- ptr = i;
- if(ptr>=0) {
- SetGadgetText(FILID, &DirName[ptr+1]);
- if(ptr==0 || DirName[ptr]==':')
- ptr++;
- DirName[ptr] = 0;
- SetGadgetText(DIRID, DirName);
- } else {
- SetGadgetText(FILID, DirName);
- if(i)
- SetGadgetText(DIRID, "");
- else
- SetGadgetText(DIRID, "/");
- }
- ReadNewDir();
- return 1;
- }
-
- static SetFileName(name)
- char *name;
- {
- /* Can't enter a file name too long. */
- if(strlen(DirName) + strlen(name) + 1 > MAXFULL) {
- DisplayBeep();
- return 0;
- }
- SetGadgetText(FILID, name);
- return 1;
- }
-
- static SetPatName(name)
- char *name;
- {
- SetGadgetText(PATID, name);
- }
-
- static ProcessGadget(id)
- int id;
- {
- switch(id) {
- case DIRID: ReadNewDir(); break;
- case FILID: if (dir_only)
- ActivateGadget(&STD_Gadget[0],STD_Window,0L);
- else
- DoneFlag = 1; break;
- case PATID: ReCalcPattern(); break;
- case BARID: CalcFilePosition(); break;
- case YESID: DoneFlag = 1; break;
- case CANID: DoneFlag = -1; break;
- case VOLID: ReadVol(); break;
- case PARID: ReadParDir(); break;
- }
- }
-
- static ProcessMouse(x, y, code, seconds, micros)
- int x, y, code;
- {
- int NewSelected;
- static int oseconds = 0, omicros = 0;
-
- if(x<HOMEX || y<HOMEY || x>=LASTX || y>=LASTY)
- return;
- if((code&SELECTUP) == SELECTUP)
- return;
- if(State != DIRECTORY) {
- ReadNewDir();
- return;
- }
- NewSelected = (y-HOMEY)/CHSIZ + FirstFile;
- if(NewSelected == Selected) {
- if(Selected != -1) {
- if(DoubleClick(oseconds, omicros, seconds, micros)) {
- if(NameTable[Selected]->filetype == DIRTYPE) {
- if(SetDirName(NameTable[Selected]->filename))
- ReadNewDir();
- } else if(NameTable[Selected]->filetype == VOLTYPE) {
- SetGadgetText(DIRID, NameTable[Selected]->filename);
- SetGadgetText(FILID, "");
- ReadNewDir();
- } else {
- if(!SetFileName(NameTable[Selected]->filename))
- Selected = -1;
- DoneFlag = 1;
- }
- }
- }
- } else {
- if(Selected != -1 &&
- Selected>=FirstFile && Selected<FirstFile+MAXFILES)
- PrintName(Selected, 0);
- Selected = NewSelected;
- if(Selected>=NumFiles)
- Selected = -1;
- else {
- if(SetFileName(NameTable[Selected]->filename))
- PrintName(Selected, 1);
- else
- Selected = -1;
- }
- }
- oseconds = seconds;
- omicros = micros;
- }
-
- stdfile(title, deffile, defpat, name)
- char *title, *deffile, *defpat, *name;
- {
- if(title)
- STD_NewWindow.Title = (UBYTE *)title;
- else
- STD_NewWindow.Title = (UBYTE *)"Enter File Name";
- if(deffile) {
- int i;
- for(i = strlen(deffile)-1; i>=0; i--) {
- if(deffile[i]==':' || deffile[i]=='/') {
- int hold;
- strcpy(FileName, &deffile[i+1]);
- if(deffile[i]==':')
- i++;
- hold = deffile[i];
- deffile[i] = 0;
- strcpy(DirName, deffile);
- deffile[i] = hold;
- break;
- }
- }
- if(i<0) {
- strcpy(FileName, deffile);
- DirName[0] = 0;
- }
- } else {
- DirName[0] = 0;
- FileName[0] = 0;
- }
- if(defpat)
- strcpy(PatName, defpat);
- else
- PatName[0] = 0;
-
- State = INITIAL;
- NameTable = 0;
- NameList = 0;
-
- if(OpenFileWindow()) {
- struct IntuiMessage *msg;
- DoneFlag = 0;
- if (read_dir)
- ReadNewDir();
- while(!DoneFlag) {
- Wait(1<<STD_Window->UserPort->mp_SigBit);
- while(msg = GetMsg(STD_Window->UserPort)) {
- switch(msg->Class) {
- case CLOSEWINDOW:
- DoneFlag = -1;
- break;
- case MOUSEBUTTONS:
- ProcessMouse(msg->MouseX, msg->MouseY,
- msg->Code,
- msg->Seconds, msg->Micros);
- break;
- case GADGETUP:
- ProcessGadget(
- ((struct Gadget *)msg->IAddress)->GadgetID
- );
- break;
- case REFRESHWINDOW:
- BeginRefresh(STD_Window);
- PaintFileWindow();
- EndRefresh(STD_Window, 1);
- break;
- }
- ReplyMsg(msg);
- }
- }
-
- CloseFileWindow();
- }
- else return 0;
-
- FreeList(NameList);
- if(NameTable) free(NameTable);
-
- if(DoneFlag==1) {
- int len;
-
- strcpy(name, DirName);
- if(FileName[0]) {
- if(len = strlen(name))
- if(name[len-1]!=':')
- strcat(name, "/");
- strcat(name, FileName);
- return 1;
- }
-
- /* Here the user has accepted the name without providing a file
- name. I return true, but false may be more appropriate. What
- do you think? */
- return 1;
- }
- return 0;
- }
-