PathMaster File Selector Programmer Documentation 89-06-26. -------------------------------------------------------------- Copyright Š 1989 by Justin V. McCormick. All Rights Reserved. The PathMaster File Selector has only two public functions; FileSelect() and ReleaseFileSelect(). The first function invokes the selection process, and the second function purges/cleans up the allocations when you are all done. All PathMaster options are controlled by the FSRequest structure that you pass to FileSelect(). You initialize this structure with the destination filename buffers, default gadget settings, callbacks, and text messages you want the selector to use. Normally, you would initialize this structure once and reuse it for every call to FileSelect(); this keeps the selector in the same "state" as the user left it. Or, you could have several FSRequest structures, one for Loading files, one for Saving, etc. You can then have separate Load and Save file selector defaults that the user can customize without conflict. Before I detail the contents of the FSRequest structure, lets document the two functions: Public Function Docs: --------------------- pathmaster/FileSelect NAME FileSelect - Invoke the PathMaster File Selector. SYNOPSIS LONG FileSelect (struct FSRequest *fsreq); D0 STACK FUNCTION Opens the selector window using the information in fsreq to initialize the selectors internal state machines. The function returns to the caller when either the user selects a name or cancels the operation. INPUTS fsreq - a pointer to an initialized FSRequest structure. RESULTS Returns 0 if allocations fail. Returns 1 if FileSelect() succeeds. Check the fsreq->fullname variable to determine whether user canceled the selection; if strlen(fsreq->fullname) == 0, then the user canceled FileSelect(). EXCEPTIONS Requires destination screen to be at least 495x171 pixels. SEE ALSO ReleaseFileSelect BUGS Sure. pathmaster/ReleaseFileSelect NAME ReleaseFileSelect - Release/Deallocate all PathMaster caches. SYNOPSIS VOID ReleaseFileSelect(VOID); FUNCTION Cleanup routine for FileSelect(). If you call FileSelect, you must call ReleaseFileSelect to return memory allocated by the selector. The function UnLocks any path locks and deallocates the cached list of entries and device names. Normally called once by main application after the file selector will no longer be used; e.g., at exit() time. However, the function can be called by the application to explicitly purge the name/device lists. This may be necessary to insure proper updating after deleting files, etc. in special applications. INPUTS RESULTS EXCEPTIONS Should not be called asynchronously while in FileSelect(). SEE ALSO FileSelect BUGS None. * --------------------------------------------------------------------- * * The FSRequest Structure: * --------------------------------------------------------------------- * Here is the control/state structure for FileSelect(): struct FSRequest { BYTE dirname[300]; BYTE filename[32]; BYTE matchpattern[32]; WORD leftedge; WORD topedge; WORD sorttype; UWORD flags; ULONG windowflags; BYTE *fullname; BYTE *ignorepattern; BYTE *pathgadstr; BYTE *filegadstr; BYTE *titlestr; BYTE *readingstr; BYTE *sortingstr; BYTE *emptydirstr; BYTE *nomatchstr; BYTE *selectfilestr; BYTE *selectstr; BYTE *cancelstr; BYTE *specgadstr; struct Screen *userscreen; struct MsgPort *userport; LONG (*specgadfunc) (struct FSRequest *, struct Window *, struct Gadget *); LONG (*dirfunc) (struct FSRequest *, struct Window *); LONG (*filefunc) (struct FSRequest *, struct Window *); LONG (*userfunc) (struct FSRequest *, struct Window *); LONG (*initfunc) (struct FSRequest *, struct Window *); LONG (*matchfunc) (struct FSRequest *, BYTE *, struct file_node *); }; * --------------------------------------------------------------------- * * FSRequest Field Descriptions: * --------------------------------------------------------------------- * Most of these fields should be initialized to NULL or all zeros. Typically, the you will only need to set a few of these fields in order to call FileSelect() - the fullname, selectstr, and cancelstr fields are the only required pointers. Please see fs.c for a complete example. ------------------- BYTE dirname[300]; The string space used to hold the current AmigaDOS directory path. The 300 byte limit effectively limits directory descent to ten subdirectories, worst case. You can fill in this string with a default directory name prior to calling FileSelect(). After FileSelect() returns, you can look at this field to get the "path" part of a full path/filename returned. ------------------- ------------------- BYTE filename[32]; The string space used to hold the current or last file name typed or clicked on by the user. You can initialize this string to hold a default filename that will appear in the file text gadget, and you can look at this field after calling FileSelect() to get just the "name" part of the full path/filename returned. ------------------- ------------------- BYTE matchpattern[32]; The string space used to hold the current or last file match pattern typed by the user. File names that match the UNIX-style pattern will be displayed; all other filenames will be hidden. By default, the selector will use a "*" pattern to match all files unless otherwise specified. You can initialize this string to hold a default pattern that will appear in the pattern text gadget, and examine the field after calling FileSelect() to see if the user changed the pattern template. ------------------- ------------------- WORD leftedge, topedge; The window position relative to the upper left of the screen you want the selector to appear at. If the user drags the selector window, the selector will update these fields so that the window will appear in that position next time FileSelect() is called using that FSRequest. ------------------- ------------------- WORD sorttype; The type of sort to apply to files and directories scanned by the selector: -1 = Do not sort entries. 0 = Alphabetize. 1 = Sort by Size. 2 = Sort by Time. This field is updated by the selector if the user clicks on one of the sort gadgets. ------------------- ------------------- UWORD flags; This is a 16-bit field that controls many of the "preference" type options for the file selector. Simply OR together the following defines (See fs.h) as desired: /* FSRequest flags */ FS_NO_DCLICK_EXIT /* Disable double-click file select exit */ FS_NO_STRING_EXIT /* Disable Return in File String Gadget exit */ FS_NO_STRING_OKAY /* Allow exit with no file name */ FS_SHOW_FILES_FIRST /* Show files first in file/dir mixture */ FS_SHOW_DIRS_FIRST /* Show dirs first in file/dir mixture */ FS_SHOW_FILES_ONLY /* Don't show dirs */ FS_SHOW_DIRS_ONLY /* Don't show files */ FS_DELAYED_SORT /* Don't sort entries till user hits slide */ ------------------- ------------------- ULONG windowflags; If non-NULL, the selector will use this value for its NewWindow.Flags. Otherwise, the selector will use its default NewWindow.Flags definition: WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | NOCAREREFRESH | ACTIVATE | RMBTRAP ------------------- ------------------- BYTE *fullname; A pointer to a 344 byte string space that you want to contain the final full path/filename selected by the user. If the string length is zero, this means that the user canceled the file selection process. You may share this space amoung several FSRequest structures. ------------------- ------------------- BYTE *ignorepattern; NULL or a pointer to a UNIX-style pattern string. Each file the selector scans is compared to this string. Files that match the string will not be displayed. This is useful, for instance, to eliminate all ".info" files from the display. Simply set FSRequest->ignorepattern = "*.info" before calling FileSelect(). ------------------- ------------------- BYTE *pathgadstr; NULL or a 4-Letter text that will appear to the left of the Directory string gadget, normally "PATH". ------------------- ------------------- BYTE *filegadstr; NULL or a 4-Letter text that will appear to the left of the File string gadget, normally "FILE". ------------------- ------------------- BYTE *titlestr; NULL or a pointer to the text you want to appear as the title in the titlebar of the selector window. This string should be no more than 28 characters long. ------------------- ------------------- BYTE *readingstr; NULL or a pointer to the text you want to appear in the selector titlebar when the selector is reading files from a device. By default this string is "Reading...". ------------------- ------------------- BYTE *sortingstr; NULL or a pointer to the text you want to appear in the selector titlebar when the selector is sorting files. By default this string is "Sorting...". ------------------- ------------------- BYTE *emptydirstr; NULL or a pointer to the text you want to appear in the selector titlebar when the selector has finished reading from a valid device and there are no files in the given path. By default this string is "Empty Directory!". ------------------- ------------------- BYTE *nomatchstr; NULL or a pointer to the text you want to appear in the selector titlebar when there are no files in the given path that match the current pattern contained in FSRequest->matchpattern. By default this string is "Nothing matched PATTERN". ------------------- ------------------- BYTE *selectfilestr; NULL or a pointer to the text you want to appear in the selector titlebar when the selector has finished reading files from a valid device and the selector is waiting for a user action. By default this string is "Select Filename:". ------------------- ------------------- BYTE *selectstr; Pointer to the text you want to appear for the select gadget. Typical examples are "OKAY", "Select", "LOAD" or "SAVE", etc. The text should not be more than 9 characters. ------------------- ------------------- BYTE *cancelstr; Pointer to the text you want to appear for the cancel gadget. Typical examples are "CANCEL!", "EXIT", "ABORT" or "QUIT", etc. The text should not be more than 9 characters. ------------------- ------------------- BYTE *specgadstr; NULL or a pointer to the text you want to appear for the special gadget. Typical examples are "DELETE", "MARK", "Queue" or "Select", etc. The text should not be more than 9 characters. You must also supply a pointer for FSRequest->specgadfunc that will be called when the user clicks on this gadget (see below). ------------------- ------------------- struct Screen *userscreen; NULL or a pointer to the custom screen you want the selector window to appear on. If the field is NULL, the selector will default to opening on the Workbench screen. ------------------- ------------------- struct MsgPort *userport; NULL or a pointer to a previously open IDCMP port. If non-NULL, the selector will include the given Port in the selectors Wait() signal mask. If the userport is signaled, the selector will call the function pointed to by FSRequest->userfunc (see below). ------------------- ------------------- LONG (*specgadfunc) (struct FSRequest *, struct Window *, struct Gadget *); NULL or a pointer to the function that will be called when the user clicks on the special gadget. You must also supply text that will appear in this gadget, FSRequest->specgadstr. When the user clicks on this gadget the selector will call your function. Your function will be passed the same FSRequest pointer you supplied to FileSelect(), a pointer to the selector window, and a pointer to the special gadget itself. Thus, you can read the currently selected filename from FSRequest->fullname and take appropriate action, perhaps changing the special gadget text and calling RefreshGList(). ------------------- ------------------- LONG (*dirfunc) (struct FSRequest *, struct Window *); NULL or a pointer to a function that will be called for each directory name the user clicks on or types into the PATH string gadget. You are passed a pointer to the same FSRequest structure that FileSelect() was called with, and a pointer to the selector window. ------------------- ------------------- LONG (*filefunc) (struct FSRequest *, struct Window *); NULL or a pointer to a function that will be called for each filename the user clicks on or types into the FILE string gadget. You are passed a pointer to the same FSRequest structure that FileSelect() was called with, and a pointer to the selector window. ------------------- ------------------- LONG (*userfunc) (struct FSRequest *, struct Window *); NULL or a pointer to a function that will be called when messages arrive at the supplied FSRequest->userport (see above). You are passed a pointer to the same FSRequest structure that FileSelect() was called with, and a pointer to the selector window. ------------------- ------------------- LONG (*initfunc) (struct FSRequest *, struct Window *); NULL or a pointer to a function that will be called immediately after the selector window pops up. You are passed a pointer to the same FSRequest structure that FileSelect() was called with, and a pointer to the selector window. This gives you an opportunity to change screen colors, set a custom window pointer for the selector, etc. in a synchronized manner. ------------------- ------------------- LONG (*matchfunc) (struct FSRequest *, BYTE *, struct file_node *); NULL or a pointer to a function that will be called for each entry the selector scans from a valid device. If your function returns TRUE, the selector will add the entry to the list. If your function returns FALSE the entry will not be added to the list of entries. You are passed a pointer to your original FSRequest and a pointer to the new file_node structure that the selector has just read from the device. The file_node contains: struct file_node { struct file_node *next; /* next file_node */ struct file_node *prev; /* previous file_node */ struct node_data *info; /* file info structure */ WORD idnum; /* numerical position */ } The node_data structure contained by each file_node holds all of the information concerning that entry. By modifying the node_data field, you can cause certain entries be invisible or to appear highlighted, or fake a directory entry to show up as a file entry in the list: /* File node structure */ struct node_data { BYTE alphadata[58]; /* ascii data */ WORD filetype; /* 0=Dir or 1=file flag */ WORD showit; /* 0=skip, 1=showable */ WORD textcolor; /* Pen Color to render with */ WORD namelength; /* Actual length of file name */ ULONG filesize; /* File size in bytes */ ULONG days; /* File creation date */ ULONG minutes; ULONG ticks; }; ------------------- Please see the User Documentation for details on the PathMaster User Interface. * --------------------------------------------------------------------- * * PathMaster Installation Notes: * --------------------------------------------------------------------- * Initialization: ---------------- It is presumed that both GfxBase and IntuitionBase are opened before calling FileSelect(), and are globally available. Since ActivateGadget() and some other 1.2 Kernel calls are used, you must open version 33 or later of these libraries or the Guru will probably visit. By default, the file selector uses a WBENCHWINDOW to open in, and does a ScreenToFront() on the window's screen after opening. You need to supply a FSRequest->userscreen pointer to your CUSTOM screen if this is not what you desire. Note, however, that the file selector window is 495 pixels wide by 171 pixels high, so it won't open on a 320 pixel wide screen. The file selector uses a globally defined TextFont to insure that Topaz 8 is used for textual information. You can change fs.h to point to a special font, however, most of the text placement assumes a non-proportional 8-point font. Error Returns and Messages: --------------------------- If FileSelect() fails to open (probably due to lack of RAM for a new window) it will return a value of ZERO (0). Otherwise it returns ONE (1). The file selector has a large table of error messages that are used to detail specific errors in the selector window titlebar. Not all of the error messages are applicable to the file selector, but they are included because other routines can share the error messages and error reporting mechanisms. You can reduce some of the text to a zero length string ("") if you wish to save on space a little, or change the messages if they are not appropriately worded for your application. Just bear in mind that some of the messages will be used by FileSelect() and must fit within the titlebar of the file selector. Before your application exits, you should call ReleaseFileSelect() to deallocate the memory that FileSelect() uses. Since the file selector builds a device list the first time it is called and then dynamically allocates and buffers the current directory, the next time FileSelect() is called the directory does not have to be re-scanned (unless, of course, the directory has been modified, in which case the file selector will automatically reŠscan the directory).