/* jwin_file_select_ex:
  *  Displays the JWin file selector, with the message as caption.
  *  Allows the user to select a file, and stores the selection in the
  *  path buffer, whose length in bytes is given by size and should have
  *  room for at least 80 characters. The files are filtered according to
  *  the file extensions in ext. Passing NULL includes all files, "PCX;BMP"
  *  includes only files with .PCX or .BMP extensions. Returns zero if it
  *  was closed with the Cancel button or non-zero if it was OK'd.
  */
int jwin_file_select_ex(AL_CONST char *message, char *path, AL_CONST char *ext, int size, int width, int height, FONT *title_font)
{
    static attrb_state_t default_attrb_state[ATTRB_MAX] = DEFAULT_ATTRB_STATE;
    int ret;
    char *p;
    char tmp[32];
    ASSERT(message);
    ASSERT(path);
    
    if(title_font)
    {
        file_selector[0].dp2=title_font;
    }
    
    if(width == OLD_FILESEL_WIDTH)
        width = 304;
        
#ifdef HAVE_DIR_LIST
        
    if(height == OLD_FILESEL_HEIGHT)
        height = 160;
        
#else
        
    if(height == OLD_FILESEL_HEIGHT)
        height = 188;
        
#endif
        
    /* for fs_dlist_proc() */
    ASSERT(size >= 4 * uwidth_max(U_CURRENT));
    
    usetc(updir, 0);
    file_selector[FS_WIN].dp = (char *)message;
    file_selector[FS_EDIT].d1 = size/uwidth_max(U_CURRENT) - 1;
    file_selector[FS_EDIT].dp = path;
    file_selector[FS_OK].dp = (void*)get_config_text("OK");
    file_selector[FS_CANCEL].dp = (void*)get_config_text("Cancel");
    
    /* Set default attributes. */
    memcpy(attrb_state, default_attrb_state, sizeof(default_attrb_state));
    
    /* Parse extension string. */
//  if (ext)// && ugetc(ext))
    {
        parse_extension_string(ext);
    }
    
    if(!ugetc(path))
    {
    
#ifdef HAVE_DIR_LIST
    
        int drive = _al_getdrive();
        
#else
        
        int drive = 0;
#endif
        
        _al_getdcwd(drive, path, size - ucwidth(OTHER_PATH_SEPARATOR));
        fix_filename_case(path);
        fix_filename_slashes(path);
        put_backslash(path);
    }
    
    clear_keybuf();
    
    do
    {
    }
    while(gui_mouse_b());
    
    file_selector[FS_TYPES].proc = fs_dummy_proc;
    enlarge_file_selector(width, height);
    ret = popup_zqdialog(file_selector, FS_EDIT);
    
    if(fext)
    {
        zc_free(fext);
        fext = NULL;
    }
    
    if(fext_p)
    {
        _al_free(fext_p);
        fext_p = NULL;
    }
    
    if((ret == FS_CANCEL) || (ret == FS_WIN) || (!ugetc(get_filename(path))))
        return FALSE;
        
    p = get_extension(path);
    
    if((!ugetc(p)) && (ext) && (!ustrpbrk(ext, uconvert_ascii(" ,;", tmp))))
    {
        size -= ((long)(size_t)p - (long)(size_t)path + ucwidth('.'));
        
        if(size >= uwidth_max(U_CURRENT) + ucwidth(0))          /* do not end with '.' */
        {
            p += usetc(p, '.');
            ustrzcpy(p, size, ext);
        }
    }
    
    return TRUE;
}
/* fs_edit_proc:
  *  Dialog procedure for the file selector editable string.
  */
static int fs_edit_proc(int msg, DIALOG *d, int c)
{
    char *s = (char *) d->dp;
    int size = (d->d1 + 1) * uwidth_max(U_CURRENT);           /* of s (in bytes) */
    int list_size;
    int found = 0;
    char b[1024], tmp[16];
    int ch, attr;
    int i;
    
    if(msg == MSG_START)
    {
        canonicalize_filename(b, s, sizeof(b));
        ustrzcpy(s, size, b);
    }
    
    if(msg == MSG_KEY)
    {
        if((!ugetc(s)) || (ugetat(s, -1) == DEVICE_SEPARATOR))
            ustrzcat(s, size, uconvert_ascii("./", tmp));
            
        canonicalize_filename(b, s, sizeof(b));
        ustrzcpy(s, size - ucwidth(OTHER_PATH_SEPARATOR), b);
        
        ch = ugetat(s, -1);
        
        if((ch != '/') && (ch != OTHER_PATH_SEPARATOR))
        {
            if(file_exists(s, FA_RDONLY | FA_HIDDEN | FA_DIREC, &attr))
            {
                if(attr & FA_DIREC)
                    put_backslash(s);
                else
                    return D_CLOSE;
            }
            else
                return D_CLOSE;
        }
        
        object_message(file_selector+FS_FILES, MSG_START, 0);
        
        /* did we `cd ..' ? */
        if(ustrlen(updir))
        {
            /* now we have to find a directory name equal to updir */
            for(i = 0; i<flist->size; i++)
            {
                if(!ustrcmp(updir, flist->name[i]))                 /* we got it ! */
                {
                    file_selector[FS_FILES].d1 = i;
                    /* we have to know the number of visible lines in the filelist */
                    /* -1 to avoid an off-by-one problem */
                    list_size = (file_selector[FS_FILES].h-4) / text_height(font) - 1;
                    
                    if(i>list_size)
                        file_selector[FS_FILES].d2 = i-list_size;
                    else
                        file_selector[FS_FILES].d2 = 0;
                        
                    found = 1;
                    break;                                            /* ok, our work is done... */
                }
            }
            
            /* by some strange reason, we didn't find the old directory... */
            if(!found)
            {
                file_selector[FS_FILES].d1 = 0;
                file_selector[FS_FILES].d2 = 0;
            }
        }
        
        /* and continue... */
        object_message(file_selector+FS_FILES, MSG_DRAW, 0);
        object_message(d, MSG_START, 0);
        object_message(d, MSG_DRAW, 0);
        
        return D_O_K;
    }
    
    int allegro_lfn = ALLEGRO_LFN; //removes compiler warning
    
    if(msg == MSG_UCHAR)
    {
        if((c >= 'a') && (c <= 'z'))
        {
            if(!allegro_lfn)
                c = utoupper(c);
        }
        else if(c == '/')
        {
            c = OTHER_PATH_SEPARATOR;
        }
        else if(allegro_lfn)
        {
            if((c > 127) || (c < 32))
                return D_O_K;
        }
        else
        {
            if((c != OTHER_PATH_SEPARATOR) && (c != '_') &&
                    (c != DEVICE_SEPARATOR) && (c != '.') &&
                    ((c < 'A') || (c > 'Z')) && ((c < '0') || (c > '9')))
                return D_O_K;
        }
    }
    
    //   return _gui_edit_proc(msg, d, c);
    return jwin_edit_proc(msg, d, c);
}
/* fs_flist_proc:
  *  Dialog procedure for the file selector list.
  */
static int fs_flist_proc(int msg, DIALOG *d, int c)
{
    static int recurse_flag = 0;
    char *s = (char *) file_selector[FS_EDIT].dp;
    char tmp[32];
    /* of s (in bytes) */
    int size = (file_selector[FS_EDIT].d1 + 1) * uwidth_max(U_CURRENT);
    int sel = d->d1;
    int i, ret;
    int ch, count;
    
    if(msg == MSG_START)
    {
        if(!flist)
        {
            flist = (FLIST *) zc_malloc(sizeof(FLIST));
            
            if(!flist)
            {
                *allegro_errno = ENOMEM;
                return D_CLOSE;
            }
        }
        else
        {
            for(i=0; i<flist->size; i++)
                if(flist->name[i])
                    zc_free(flist->name[i]);
        }
        
        flist->size = 0;
        
        replace_filename(flist->dir, s, uconvert_ascii("*.*", tmp), sizeof(flist->dir));
        
        /* The semantics of the attributes passed to file_select_ex() is
          * different from that of for_each_file_ex() in one case: when
          * the 'd' attribute is not mentioned in the set of characters,
          * the other attributes are not taken into account for directories,
          * i.e the directories are all included. So we can't filter with
          * for_each_file_ex() in that case.
          */
        if(attrb_state[ATTRB_DIREC] == ATTRB_ABSENT)
            /* accept all dirs */
            for_each_file_ex(flist->dir, 0 , FA_LABEL, fs_flist_putter, (void *)1UL /* check */);
        else
            /* don't check */
            for_each_file_ex(flist->dir, build_attrb_flag(ATTRB_SET), build_attrb_flag(ATTRB_UNSET) | FA_LABEL, fs_flist_putter, (void *)0UL);
            
        usetc(get_filename(flist->dir), 0);
        d->d1 = d->d2 = 0;
        sel = 0;
    }
    
    if(msg == MSG_END)
    {
        if(flist)
        {
            for(i=0; i<flist->size; i++)
                if(flist->name[i])
                    zc_free(flist->name[i]);
                    
            zc_free(flist);
            flist = NULL;
        }
    }
    
    recurse_flag++;
    ret = jwin_abclist_proc(msg,d,c);                         /* call the parent procedure */
    
    recurse_flag--;
    
    if(((sel != d->d1) || (ret == D_CLOSE)) && (recurse_flag == 0))
    {
        replace_filename(s, flist->dir, flist->name[d->d1], size);
        
        /* check if we want to `cd ..' */
        if((!ustrncmp(flist->name[d->d1], uconvert_ascii("..", tmp), 2)) && (ret == D_CLOSE))
        {
            /* let's remember the previous directory */
            usetc(updir, 0);
            i = ustrlen(flist->dir);
            count = 0;
            
            while(i>0)
            {
                ch = ugetat(flist->dir, i);
                
                if((ch == '/') || (ch == OTHER_PATH_SEPARATOR))
                {
                    if(++count == 2)
                        break;
                }
                
                uinsert(updir, 0, ch);
                i--;
            }
            
            /* ok, we have the dirname in updir */
        }
        else
        {
            usetc(updir, 0);
        }
        
        object_message(file_selector+FS_EDIT, MSG_START, 0);
        object_message(file_selector+FS_EDIT, MSG_DRAW, 0);
        
        if(ret == D_CLOSE)
            return object_message(file_selector+FS_EDIT, MSG_KEY, 0);
    }
    
    return ret;
}
Exemple #4
0
int raine_file_select_ex( char *message, char *path,  char *ext, int size,int width, int height)
{
   char buf[512];
   int ret;
   char *p;

   if (width == -1)
      width = 305;

   #ifdef HAVE_DIR_LIST

      if (height == -1)
         height = 161;

   #else

      if (height == -1)
         height = 189;

   #endif

   /* for fs_dlist_proc() */
   ASSERT(size >= 4 * uwidth_max(U_CURRENT));

   ustrcpy(updir, empty_string);
   file_selector[FS_MESSAGE].dp = (char *)message;
   file_selector[FS_EDIT].d1 = size/uwidth_max(U_CURRENT) - 1;
   file_selector[FS_EDIT].dp = path;
   file_selector[FS_OK].dp = (void*)raine_get_config_text("OK");
   file_selector[FS_CANCEL].dp = (void*)raine_get_config_text("Cancel");
   fext = ext;

   if (!ugetc(path)) {
      if (!getcwd(buf, sizeof(buf)))
         buf[0]=0;
      do_uconvert(buf, U_ASCII, path, U_CURRENT, size);
      fix_filename_case(path);
      fix_filename_slashes(path);
      put_backslash(path);
   }

   clear_keybuf();

   do {
   } while (gui_mouse_b());

   stretch_dialog(file_selector, width, height);

   centre_dialog(file_selector);
   // Stupid correction of the allegro colors...
   file_selector[FS_FILES].fg = CGUI_COL_TEXT_1;
   file_selector[FS_FILES].bg = CGUI_BOX_COL_MIDDLE;
#ifdef HAVE_DIR_LIST       /* not all platforms need a directory list */
   file_selector[FS_DISKS].fg = CGUI_COL_TEXT_1;
   file_selector[FS_DISKS].bg = CGUI_BOX_COL_MIDDLE;
#endif

   ret = do_dialog(file_selector, FS_EDIT);

   if (ret == FS_CANCEL)
      return FALSE;

   p = get_extension(path);
   if ((!ugetc(p)) && (ext) && (!ustrpbrk(ext, uconvert_ascii(" ,;", NULL)))) {
      p += usetc(p, '.');
      ustrcpy(p, ext);
   }

   return TRUE;
}