home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- * file: LOADSAVE.C
- * purpose: dialog box routine for getting a file name from the
- * user. Has the expected listbox, editbox and file system
- * smarts. Written for the simple gui system; GUI.C, MENU.C
- * and DIALOG.C
- * system: Flash graphics library in Zortech 3.0
- * MSDOS dependencies in _dos_findfirst, _dos_findnext, path/file names
- * and wildcard usage.
- * contains:
- * short loadsave(char *search,char *choice,unsigned short status);
- * short loadsave_add_button(BUTTON *button,short (*message_handler)(MESSAGE *));
- * short loadsave_button_location(BUTTON *button,short *loc_x,short *loc_y);
- * copyright: 1992 by David Weber. All rights reserved.
- * This software can be used for any purpose as object, library or executable.
- * It cannot be sold for profit as source code.
- * history:
- * 01-13-92 - initial code
- * 01-31-93 - this code is now obsolete, see the CPP gui package
- **************************************************************/
-
- #define MSDOS 1
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <io.h>
- #include "gui.h"
- #include "loadsave.h"
-
-
- /* local data */
- static char edit_string[FILENAME_MAX+1];
- static char search_string[FILENAME_MAX+1];
- static BUTTON *extra_button[LOADSAVE_MAX_BUTTONS];
- static short (*extra_message[LOADSAVE_MAX_BUTTONS])(MESSAGE *);
- static short extra_button_count = 0;
-
-
- /* local prototypes */
- static short first_dir(char *filename);
- static short next_dir(char *filename);
- static void setup_wildcards(char *dest,char *source);
- static void merge_path_filename(char *path,char *filename);
- static short check_wildcard_or_directory(char *path);
-
-
- /* dialog box data */
-
- /* dialog ids */
- #define D_LS_OK 23991
- #define D_LS_CANCEL 23992
- #define D_LS_LISTBOX 23993
- #define D_LS_EDITBOX 23994
-
- /* dialog dimensions */
- #define D_LS_WIDTH (38*DIALOG_UNITS)
- #define D_LS_HEIGHT (15*DIALOG_UNITS)
-
- /* listbox dimensions in text cells */
- #define LISTBOX_WIDTH 12 /* MSDOS filename width */
- #define LISTBOX_HEIGHT 8
-
- /* editbox width in text cells */
- #define EDITBOX_SCREEN_WIDTH 33 /* displayed width */
- #define EDITBOX_EDIT_WIDTH FILENAME_MAX /* editable width */
-
- /* dialog box #1 */
- static TEXT dialog_ls_text1 = {"",14*DIALOG_UNITS,13*DIALOG_UNITS+DIALOG_UNITS/2,DIALOG_ACTIVE};
- static EDITBOX dialog_ls_editbox = {D_LS_EDITBOX,2*DIALOG_UNITS,11*DIALOG_UNITS+DIALOG_UNITS/2,EDITBOX_SCREEN_WIDTH*DIALOG_UNITS,EDITBOX_EDIT_WIDTH,edit_string,DIALOG_ACTIVE};
- static LISTBOX dialog_ls_listbox = {D_LS_LISTBOX,2*DIALOG_UNITS,3*DIALOG_UNITS,LISTBOX_WIDTH*DIALOG_UNITS,LISTBOX_HEIGHT*DIALOG_UNITS,first_dir,next_dir,DIALOG_ACTIVE};
- static BUTTON dialog_ls_ok = {D_LS_OK,"Ok",F10,D_LS_WIDTH-5*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
- static BUTTON dialog_ls_cancel = {D_LS_CANCEL,"Cancel",ESC,3*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
- static DIALOG_ITEM dialog_ls[] =
- {
- {DIALOG_TEXT,&dialog_ls_text1},
- {DIALOG_EDITBOX,&dialog_ls_editbox},
- {DIALOG_LISTBOX,&dialog_ls_listbox},
- {DIALOG_BUTTON,&dialog_ls_cancel},
- {DIALOG_BUTTON,&dialog_ls_ok}
- };
-
-
-
- /************************************************
- * function: short loadsave(char *search,char *choice,unsigned short status)
- * get a file name from the user with all the usual gui goodies. loadsave
- * does not open/read or create/write the file, it justs gets a name
- * parameters: search string for list box directory list. If the search string
- * is a path and filename it should contain appropriate wild cards.
- * If it is a directory then loadsave will temporarily append the
- * wildcards.
- * choice string for holding the user's selection.
- * status is either LOADSAVE_LOAD if opening a file or
- * LOADSAVE_SAVE if saving one. Also the bit flag LOADSAVE_VERIFY
- * will verify the files existence before opening it (LOAD) or
- * verify overwriting an existing file (SAVE).
- * returns: 1 if there is a valid file name in choice, 0 if error or escaped
- ************************************************/
- short loadsave(char *search,char *choice,unsigned short status)
- {
- MESSAGE message;
- short i,button_count;
-
- setup_wildcards(search_string,search); /* set up edit/list strings */
- strcpy(edit_string,search_string);
- if (status & LOADSAVE_LOAD) /* load or save? */
- dialog_ls_text1.name = "Open File";
- else
- dialog_ls_text1.name = "Save File";
- if (!dialog_open(dialog_ls,sizeof(dialog_ls)/sizeof(DIALOG_ITEM),-1,-1,D_LS_WIDTH,D_LS_HEIGHT))
- {
- extra_button_count = 0;
- return 0;
- }
- for (i = 0 ; i < extra_button_count ; i++)
- if (!dialog_add_item(DIALOG_BUTTON,extra_button[i],dialog_ls))
- {
- extra_button_count = 0;
- return 0;
- }
- button_count = extra_button_count;
- extra_button_count = 0;
- for (;;) /* loop on messages */
- {
- message_get(&message);
- for (i = 0 ; i < button_count ; i++) /* check extra buttons */
- if (message.id == extra_button[i]->id)
- if (!(*extra_message[i])(&message))
- {
- dialog_close(dialog_ls);
- return 0;
- }
- switch (message.id) /* check standard buttons */
- {
- case D_LS_LISTBOX: /* put listbox selection into editbox */
- merge_path_filename(edit_string,message.data.ptr_data);
- editbox_initialize(&dialog_ls_editbox);
- break;
- case D_LS_OK: /* user said accept it */
- case D_LS_EDITBOX:
- if (message.id == D_LS_EDITBOX && message.data.short_data.x != EDITBOX_ACCEPT)
- break;
- if (check_wildcard_or_directory(edit_string))
- { /* new fodder for list box */
- strcpy(search,edit_string);
- setup_wildcards(search_string,search);
- strcpy(edit_string,search_string);
- editbox_initialize(&dialog_ls_editbox);
- listbox_initialize(&dialog_ls_listbox);
- break;
- }
- if (status & LOADSAVE_VERIFY) /* verify? */
- {
- if (status & LOADSAVE_LOAD)
- {
- if (access(edit_string,F_OK) != 0)
- {
- message_box("File does not exist");
- break;
- }
- }
- else
- {
- if (access(edit_string,F_OK) == 0)
- {
- if (yn_box("File exists. Overwrite it") == 0)
- break;
- }
- }
- }
- dialog_close(dialog_ls);
- strcpy(choice,edit_string);
- return 1;
- case D_LS_CANCEL: /* user said outta here */
- dialog_close(dialog_ls);
- return 0;
- default: /* check if error */
- if (error_box(message.id))
- {
- dialog_close(dialog_ls);
- return 0;
- }
- break;
- }
- }
- }
-
-
- /* get first filename from search_string, returns 1 if OK or 0 if no such critter */
- /* MSDOS dependent */
- static struct find_t find_file;
- static short first_dir(char *filename)
- {
- if (_dos_findfirst(search_string,FA_NORMAL,&find_file) != 0)
- return 0;
- strncpy(filename,find_file.name,LISTBOX_WIDTH);
- filename[LISTBOX_WIDTH] = 0;
- strlwr(filename);
- return 1;
- }
-
-
- /* get next filename, returns 1 if OK or 0 if no such critter */
- /* MSDOS dependent */
- static short next_dir(char *filename)
- {
- if (_dos_findnext(&find_file) != 0)
- return 0;
- strncpy(filename,find_file.name,LISTBOX_WIDTH);
- filename[LISTBOX_WIDTH] = 0;
- strlwr(filename);
- return 1;
- }
-
-
- /* set up wildcards appropriately, this is MSDOS dependent */
- static struct find_t temp_file;
- static void setup_wildcards(char *dest,char *source)
- {
- char *p;
-
- strcpy(dest,source); /* load source string */
- strlwr(dest); /* make it lowercase pretty */
- p = dest + strlen(dest) - 1;
- if (*p == ':') /* drive only? */
- strcat(dest,".\\*.*");
- else if (*p == '\\') /* path only? */
- strcat(dest,"*.*");
- else if (*p == '.') /* current directory or filename.ext */
- if (strchr(".:\\",*(p-1)) != NULL || p == dest)
- strcat(dest,"\\*.*");
- if (strpbrk(dest,"?*") == NULL) /* wildcards? */
- {
- if (_dos_findfirst(dest,FA_DIREC,&temp_file) == 0) /* directory? */
- if (temp_file.attrib & FA_DIREC)
- strcat(dest,"\\*.*");
- }
- }
-
-
- /* merge the filename into the path accounting for wildcards and other obscenities */
- /* MSDOS dependent */
- static void merge_path_filename(char *path,char *filename)
- {
- char *p;
-
- p = path + strlen(path) - 1;
- if (*p == '\\') /* strip trailing backslash, if any */
- *p = 0;
- for ( ; p >= path ; p--) /* find out where to cut off path */
- if (*p == '\\' || *p == ':')
- { /* directory break in path string */
- p++;
- strcpy(p,filename);
- return;
- }
- strcpy(path,filename); /* replace path with filename */
- }
-
-
- /* see if path refers to a wildcard or a directory */
- static short check_wildcard_or_directory(char *path)
- {
- char *p;
-
- for (p = path+strlen(path)-1 ; p >= path ; p--) /* strip trailing blanks */
- if (*p == ' ')
- *p = 0;
- else
- break;
- if (p <= path) /* blank path, use default directory */
- return 1;
- if (*p == ':' || (*p == '\\' && *(p-1) == ':')) /* just a drive? */
- return 1;
- if (*p == '\\') /* strip trailing backslash, if any */
- *p = 0;
- if (strpbrk(path,"?*") != NULL) /* wildcards? */
- return 1;
- if (_dos_findfirst(path,FA_DIREC,&temp_file) == 0)
- if (temp_file.attrib & FA_DIREC) /* directory? */
- return 1;
- return 0;
- }
-
-
- /************************************************
- * function: short loadsave_add_button(BUTTON *button,short (*message_handler)(MESSAGE *))
- * adds a button to the next loadsave call. If the button
- * is pressed the button id will be sent out as a message to the handler.
- * The handler should return 1 if OK or 0 if loadsave() is to be aborted
- * Note: this is a one shot function and should be called before
- * each invocation of loadsave()
- * parameters: pointer to button to add and function pointer of message handler
- * returns: 1 if button added or 0 if failed
- ************************************************/
- short loadsave_add_button(BUTTON *button,short (*message_handler)(MESSAGE *))
- {
- if (extra_button_count >= LOADSAVE_MAX_BUTTONS)
- return 0;
- extra_button[extra_button_count] = button;
- extra_message[extra_button_count] = message_handler;
- button->loc_x = D_LS_WIDTH-(2+strlen(button->name))*DIALOG_UNITS;
- button->loc_y = (9-(2*extra_button_count))*DIALOG_UNITS+DIALOG_UNITS/2;
- extra_button_count++;
- return 1;
- }
-
-
- /************************************************
- * function: short loadsave_button_location(BUTTON *button,short *loc_x,short *loc_y)
- * get screen location of an extra button
- * parameters: pointer to added button, storage for x and y location in DIALOG_UNITS
- * from lower left screen corner. loc_x and loc_y are suitable for passing
- * to dialog_open().
- * returns:
- * 1 if valid coordinates or 0 if failed
- ************************************************/
- short loadsave_button_location(BUTTON *button,short *loc_x,short *loc_y)
- {
- short i;
-
- for (i = 0 ; i < LOADSAVE_MAX_BUTTONS ; i++)
- if (extra_button[i] == button)
- {
- *loc_x = (fg.displaybox[FG_X2]-fg.displaybox[FG_X1])/2 - (D_LS_WIDTH*gui_char_width)/(2*DIALOG_UNITS);
- *loc_x = (*loc_x/gui_char_width)*DIALOG_UNITS + button->loc_x;
- *loc_y = (fg.displaybox[FG_Y2]-fg.displaybox[FG_Y1])/2 - (D_LS_HEIGHT*gui_char_height)/(2*DIALOG_UNITS);
- *loc_y = (*loc_y/gui_char_height)*DIALOG_UNITS + button->loc_y;
- return 1;
- }
- return 0;
- }