home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
dirs
/
stdfile_402.lzh
/
StdFile
/
StdFile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-17
|
22KB
|
938 lines
/* 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>
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 *)"ACCEPT", 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|SEL, 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|WINDOWDEPTH|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;
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;
if(!(STD_Window = OpenWindow(&STD_NewWindow))) {
return 0;
}
/* This optional line will activate a string gadget */
if ( IntuitionBase->lib_Version > 32 )
{
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;
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)
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);
return 0;
}
if(!Examine(dirlock, FIB)) {
UnLock(dirlock);
FreeMem(FIB, sizeof(struct FileInfoBlock));
return 0;
}
if(FIB->fib_DirEntryType < 0) {
UnLock(dirlock);
FreeMem(FIB, sizeof(struct FileInfoBlock));
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));
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));
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);
return 0;
}
FreeList(NameList);
NameList = NewList;
if(NameTable) free(NameTable);
NameTable = NewTable;
if(PatName[0]==0)
SetPatName("#?");
State = DIRECTORY;
Selected = -1;
ReCalcPattern();
}
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);
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: 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;
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;
}