Annotation of hatari/src/gui-sdl/dlgFileSelect.c, revision 1.1.1.4

1.1       root        1: /*
                      2:   Hatari - dlgFileSelect.c
                      3:  
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6:  
                      7:   A file selection dialog for the graphical user interface for Hatari.
                      8: */
1.1.1.4 ! root        9: const char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.21 2008/02/29 20:24:21 thothy Exp $";
1.1       root       10: 
                     11: #include <SDL.h>
                     12: #include <sys/stat.h>
                     13: #include <unistd.h>
                     14: 
                     15: #include "main.h"
1.1.1.3   root       16: #include "scandir.h"
1.1       root       17: #include "sdlgui.h"
                     18: #include "file.h"
                     19: #include "zip.h"
                     20: 
                     21: 
1.1.1.2   root       22: #define SGFS_NUMENTRIES   16            /* How many entries are displayed at once */
                     23: 
                     24: 
1.1       root       25: #define SGFSDLG_FILENAME  5
                     26: #define SGFSDLG_UPDIR     6
1.1.1.3   root       27: #define SGFSDLG_HOMEDIR   7
                     28: #define SGFSDLG_ROOTDIR   8
                     29: #define SGFSDLG_ENTRY1    11
                     30: #define SGFSDLG_ENTRY16   26
                     31: #define SGFSDLG_UP        27
                     32: #define SGFSDLG_DOWN      28
                     33: #define SGFSDLG_SHOWHIDDEN  29
                     34: #define SGFSDLG_OKAY      30
                     35: #define SGFSDLG_CANCEL    31
1.1       root       36: 
                     37: 
                     38: #define DLGPATH_SIZE 62
                     39: static char dlgpath[DLGPATH_SIZE+1];    /* Path name in the dialog */
                     40: 
                     41: #define DLGFNAME_SIZE 56
                     42: static char dlgfname[DLGFNAME_SIZE+1];  /* Name of the selected file in the dialog */
                     43: 
                     44: #define DLGFILENAMES_SIZE 59
1.1.1.2   root       45: static char dlgfilenames[SGFS_NUMENTRIES][DLGFILENAMES_SIZE+1];  /* Visible file names in the dialog */
1.1       root       46: 
                     47: /* The dialog data: */
                     48: static SGOBJ fsdlg[] =
                     49: {
                     50:        { SGBOX, 0, 0, 0,0, 64,25, NULL },
                     51:        { SGTEXT, 0, 0, 25,1, 13,1, "Choose a file" },
                     52:        { SGTEXT, 0, 0, 1,2, 7,1, "Folder:" },
                     53:        { SGTEXT, 0, 0, 1,3, DLGPATH_SIZE,1, dlgpath },
                     54:        { SGTEXT, 0, 0, 1,4, 6,1, "File:" },
                     55:        { SGTEXT, 0, 0, 7,4, DLGFNAME_SIZE,1, dlgfname },
1.1.1.3   root       56:        { SGBUTTON, 0, 0, 51,1, 4,1, ".." },
                     57:        { SGBUTTON, 0, 0, 56,1, 3,1, "~" },
1.1       root       58:        { SGBUTTON, 0, 0, 60,1, 3,1, "/" },
                     59:        { SGBOX, 0, 0, 1,6, 62,16, NULL },
                     60:        { SGBOX, 0, 0, 62,7, 1,14, NULL },
                     61:        { SGTEXT, SG_EXIT, 0, 2,6, DLGFILENAMES_SIZE,1, dlgfilenames[0] },
                     62:        { SGTEXT, SG_EXIT, 0, 2,7, DLGFILENAMES_SIZE,1, dlgfilenames[1] },
                     63:        { SGTEXT, SG_EXIT, 0, 2,8, DLGFILENAMES_SIZE,1, dlgfilenames[2] },
                     64:        { SGTEXT, SG_EXIT, 0, 2,9, DLGFILENAMES_SIZE,1, dlgfilenames[3] },
                     65:        { SGTEXT, SG_EXIT, 0, 2,10, DLGFILENAMES_SIZE,1, dlgfilenames[4] },
                     66:        { SGTEXT, SG_EXIT, 0, 2,11, DLGFILENAMES_SIZE,1, dlgfilenames[5] },
                     67:        { SGTEXT, SG_EXIT, 0, 2,12, DLGFILENAMES_SIZE,1, dlgfilenames[6] },
                     68:        { SGTEXT, SG_EXIT, 0, 2,13, DLGFILENAMES_SIZE,1, dlgfilenames[7] },
                     69:        { SGTEXT, SG_EXIT, 0, 2,14, DLGFILENAMES_SIZE,1, dlgfilenames[8] },
                     70:        { SGTEXT, SG_EXIT, 0, 2,15, DLGFILENAMES_SIZE,1, dlgfilenames[9] },
                     71:        { SGTEXT, SG_EXIT, 0, 2,16, DLGFILENAMES_SIZE,1, dlgfilenames[10] },
                     72:        { SGTEXT, SG_EXIT, 0, 2,17, DLGFILENAMES_SIZE,1, dlgfilenames[11] },
                     73:        { SGTEXT, SG_EXIT, 0, 2,18, DLGFILENAMES_SIZE,1, dlgfilenames[12] },
                     74:        { SGTEXT, SG_EXIT, 0, 2,19, DLGFILENAMES_SIZE,1, dlgfilenames[13] },
                     75:        { SGTEXT, SG_EXIT, 0, 2,20, DLGFILENAMES_SIZE,1, dlgfilenames[14] },
                     76:        { SGTEXT, SG_EXIT, 0, 2,21, DLGFILENAMES_SIZE,1, dlgfilenames[15] },
                     77:        { SGBUTTON, SG_TOUCHEXIT, 0, 62,6, 1,1, "\x01" },           /* Arrow up */
                     78:        { SGBUTTON, SG_TOUCHEXIT, 0, 62,21, 1,1, "\x02" },          /* Arrow down */
1.1.1.3   root       79:        { SGCHECKBOX, SG_EXIT, SG_SELECTED, 2,23, 18,1, "Show hidden files" },
1.1.1.4 ! root       80:        { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "Okay" },
        !            81:        { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" },
1.1       root       82:        { -1, 0, 0, 0,0, 0,0, NULL }
                     83: };
                     84: 
                     85: 
1.1.1.2   root       86: static int ypos;                        /* First entry number to be displayed */
                     87: static BOOL refreshentries;             /* Do we have to update the file names in the dialog? */
                     88: static int entries;                     /* How many files are in the actual directory? */
                     89: 
1.1       root       90: 
                     91: /*-----------------------------------------------------------------------*/
                     92: /*
                     93:   Update the file name strings in the dialog.
                     94:   Returns FALSE if it failed, TRUE on success.
                     95: */
1.1.1.2   root       96: static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, BOOL browsingzip)
1.1       root       97: {
                     98:        int i;
                     99:        char *tempstr = malloc(FILENAME_MAX);
                    100: 
                    101:        if (!tempstr)
                    102:        {
                    103:                perror("DlgFileSelect_RefreshEntries");
                    104:                return FALSE;
                    105:        }
                    106: 
                    107:        /* Copy entries to dialog: */
1.1.1.4 ! root      108:        for (i=0; i<SGFS_NUMENTRIES; i++)
1.1       root      109:        {
1.1.1.4 ! root      110:                if (i+ypos < entries)
1.1       root      111:                {
                    112:                        struct stat filestat;
                    113:                        /* Prepare entries: */
                    114:                        strcpy(tempstr, "  ");
                    115:                        strcat(tempstr, files[i+ypos]->d_name);
                    116:                        File_ShrinkName(dlgfilenames[i], tempstr, DLGFILENAMES_SIZE);
                    117:                        /* Mark folders: */
                    118:                        strcpy(tempstr, path);
                    119:                        strcat(tempstr, files[i+ypos]->d_name);
                    120: 
1.1.1.4 ! root      121:                        if (browsingzip)
1.1       root      122:                        {
1.1.1.3   root      123:                                if (File_DoesFileNameEndWithSlash(tempstr))
1.1       root      124:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
                    125:                        }
                    126:                        else
                    127:                        {
                    128:                                if( stat(tempstr, &filestat)==0 && S_ISDIR(filestat.st_mode) )
                    129:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
                    130:                                if (ZIP_FileNameIsZIP(tempstr) && browsingzip == FALSE)
                    131:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark .ZIP archives as folders */
                    132:                        }
                    133:                }
                    134:                else
                    135:                        dlgfilenames[i][0] = 0;  /* Clear entry */
                    136:        }
                    137: 
                    138:        free(tempstr);
                    139:        return TRUE;
                    140: }
                    141: 
                    142: 
                    143: /*-----------------------------------------------------------------------*/
                    144: /*
1.1.1.3   root      145:   Remove all hidden files (files with file names that begin with a dot) from
                    146:   the list.
                    147: */
                    148: static void DlgFileSelect_RemoveHiddenFiles(struct dirent **files)
                    149: {
                    150:        int i;
                    151:        int nActPos = -1;
                    152:        int nOldEntries;
                    153: 
                    154:        nOldEntries = entries;
                    155: 
                    156:        /* Scan list for hidden files and remove them. */
                    157:        for (i = 0; i < nOldEntries; i++)
                    158:        {
                    159:                /* Does file name start with a dot? -> hidden file! */
                    160:                if (files[i]->d_name[0] == '.')
                    161:                {
                    162:                        if (nActPos == -1)
                    163:                                nActPos = i;
                    164:                        /* Remove file from list: */
                    165:                        free(files[i]);
                    166:                        files[i] = NULL;
                    167:                        entries -= 1;
                    168:                }
                    169:        }
                    170: 
                    171:        /* Now close the gaps in the list: */
                    172:        if (nActPos != -1)
                    173:        {
                    174:                for (i = nActPos; i < nOldEntries; i++)
                    175:                {
                    176:                        if (files[i] != NULL)
                    177:                        {
                    178:                                /* Move entry to earlier position: */
                    179:                                files[nActPos] = files[i];
                    180:                                files[i] = NULL;
                    181:                                nActPos += 1;
                    182:                        }
                    183:                }
                    184:        }
                    185: }
                    186: 
                    187: 
                    188: /*-----------------------------------------------------------------------*/
                    189: /*
1.1.1.2   root      190:   Prepare to scroll up one entry.
                    191: */
                    192: static void DlgFileSelect_ScrollUp(void)
                    193: {
                    194:        if (ypos > 0)
                    195:        {
                    196:                --ypos;
                    197:                refreshentries = TRUE;
                    198:        }
                    199: }
                    200: 
                    201: 
                    202: /*-----------------------------------------------------------------------*/
                    203: /*
                    204:   Prepare to scroll down one entry.
                    205: */
                    206: static void DlgFileSelect_ScrollDown(void)
                    207: {
                    208:        if (ypos+SGFS_NUMENTRIES < entries)
                    209:        {
                    210:                ++ypos;
                    211:                refreshentries = TRUE;
                    212:        }
                    213: }
                    214: 
                    215: 
                    216: /*-----------------------------------------------------------------------*/
                    217: /*
                    218:   Handle SDL events.
                    219: */
                    220: static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent)
                    221: {
1.1.1.4 ! root      222:        int oldypos = ypos;
1.1.1.2   root      223:        switch (pEvent->type)
                    224:        {
                    225:         case SDL_MOUSEBUTTONDOWN:
                    226:                if (pEvent->button.button == SDL_BUTTON_WHEELUP)
                    227:                        DlgFileSelect_ScrollUp();
                    228:                else if (pEvent->button.button == SDL_BUTTON_WHEELDOWN)
                    229:                        DlgFileSelect_ScrollDown();
                    230:                break;
                    231:         case SDL_KEYDOWN:
                    232:                switch (pEvent->key.keysym.sym)
                    233:                {
1.1.1.4 ! root      234:                 case SDLK_UP:       DlgFileSelect_ScrollUp(); break;
        !           235:                 case SDLK_DOWN:     DlgFileSelect_ScrollDown(); break;
        !           236:                 case SDLK_HOME:     ypos = 0; break;
        !           237:                 case SDLK_END:      ypos = entries-SGFS_NUMENTRIES; break;
        !           238:                 case SDLK_PAGEUP:   ypos -= SGFS_NUMENTRIES; break;
1.1.1.2   root      239:                 case SDLK_PAGEDOWN:
                    240:                        if (ypos+2*SGFS_NUMENTRIES < entries)
                    241:                                ypos += SGFS_NUMENTRIES;
                    242:                        else
                    243:                                ypos = entries-SGFS_NUMENTRIES;
                    244:                        break;
1.1.1.4 ! root      245:                 default:
        !           246:                        break;
1.1.1.2   root      247:                }
                    248:                break;
1.1.1.4 ! root      249:        default:
        !           250:                break;
        !           251:        }
        !           252:        if (ypos < 0)
        !           253:                ypos = 0;
        !           254:        if (ypos != oldypos)
        !           255:                refreshentries = TRUE;
        !           256: }
        !           257: 
        !           258: 
        !           259: /*-----------------------------------------------------------------------*/
        !           260: /*
        !           261:   Free file entries
        !           262: */
        !           263: static struct dirent **files_free(struct dirent **files)
        !           264: {
        !           265:        int i;
        !           266:        if (files != NULL)
        !           267:        {
        !           268:                for(i=0; i<entries; i++)
        !           269:                {
        !           270:                        free(files[i]);
        !           271:                }
        !           272:                free(files);
        !           273:        }
        !           274:        return NULL;
        !           275: }
        !           276: 
        !           277: 
        !           278: /*-----------------------------------------------------------------------*/
        !           279: /*
        !           280:   Copy to dst src+add if they are below maxlen and return true,
        !           281:   otherwise return false
        !           282: */
        !           283: static int strcat_maxlen(char *dst, int maxlen, const char *src, const char *add)
        !           284: {
        !           285:        int slen, alen;
        !           286:        slen = strlen(src);
        !           287:        alen = strlen(add);
        !           288:        if (slen + alen < maxlen)
        !           289:        {
        !           290:                strcpy(dst, src);
        !           291:                strcpy(dst+slen, add);
        !           292:                return 1;
        !           293:        }
        !           294:        return 0;
        !           295: }
        !           296: 
        !           297: /*-----------------------------------------------------------------------*/
        !           298: /*
        !           299:   Create and return suitable path into zip file
        !           300: */
        !           301: static char* zip_get_path(const char *zipdir, const char *zipfilename, int browsingzip)
        !           302: {
        !           303:        if (browsingzip)
        !           304:        {
        !           305:                char *zippath;
        !           306:                zippath = malloc(strlen(zipdir) + strlen(zipfilename) + 1);
        !           307:                strcpy(zippath, zipdir);
        !           308:                strcat(zippath, zipfilename);
        !           309:                return zippath;
1.1.1.2   root      310:        }
1.1.1.4 ! root      311:        return strdup("");
1.1.1.2   root      312: }
                    313: 
1.1.1.4 ! root      314: /* string for zip root needs to be empty, check and correct if needed */
        !           315: static void correct_zip_root(char *zippath)
        !           316: {
        !           317:        if (zippath[0] == PATHSEP && !zippath[1])
        !           318:        {
        !           319:                zippath[0] = '\0';
        !           320:        }
        !           321: }
1.1.1.2   root      322: 
                    323: /*-----------------------------------------------------------------------*/
                    324: /*
1.1       root      325:   Show and process a file selection dialog.
1.1.1.4 ! root      326:   Returns path/name user selected or NULL if user canceled
        !           327:   input: zip_path = pointer's pointer to buffer to contain file path
        !           328:   within a selected zip file, or NULL if browsing zip files is disallowed.
1.1       root      329:   bAllowNew: TRUE if the user is allowed to insert new file names.
                    330: */
1.1.1.4 ! root      331: char* SDLGui_FileSelect(const char *path_and_name, char **zip_path, BOOL bAllowNew)
1.1       root      332: {
                    333:        struct dirent **files = NULL;
                    334:        char *pStringMem;
1.1.1.4 ! root      335:        char *retpath;
        !           336:        char *home, *path, *fname;          /* The actual file and path names */
1.1       root      337:        BOOL reloaddir = TRUE;              /* Do we have to reload the directory file list? */
                    338:        int retbut;
                    339:        int oldcursorstate;
                    340:        int selection = -1;                 /* The actual selection, -1 if none selected */
                    341:        char *zipfilename;                  /* Filename in zip file */
                    342:        char *zipdir;
                    343:        BOOL browsingzip = FALSE;           /* Are we browsing an archive? */
                    344:        zip_dir *zipfiles = NULL;
1.1.1.2   root      345:        SDL_Event sdlEvent;
                    346:        struct stat filestat;
                    347: 
                    348:        ypos = 0;
                    349:        refreshentries = TRUE;
                    350:        entries = 0;
1.1       root      351: 
                    352:        /* Allocate memory for the file and path name strings: */
                    353:        pStringMem = malloc(4 * FILENAME_MAX);
                    354:        path = pStringMem;
                    355:        fname = pStringMem + FILENAME_MAX;
1.1.1.4 ! root      356:        zipdir = pStringMem + 2 * FILENAME_MAX;
        !           357:        zipfilename = pStringMem + 3 * FILENAME_MAX;
1.1       root      358:        zipfilename[0] = 0;
                    359: 
                    360:        SDLGui_CenterDlg(fsdlg);
                    361:        if (bAllowNew)
                    362:        {
                    363:                fsdlg[SGFSDLG_FILENAME].type = SGEDITFIELD;
                    364:                fsdlg[SGFSDLG_FILENAME].flags |= SG_EXIT;
                    365:        }
                    366:        else
                    367:        {
                    368:                fsdlg[SGFSDLG_FILENAME].type = SGTEXT;
                    369:                fsdlg[SGFSDLG_FILENAME].flags &= ~SG_EXIT;
                    370:        }
                    371: 
                    372:        /* Prepare the path and filename variables */
1.1.1.4 ! root      373:        if (path_and_name && path_and_name[0])
1.1.1.2   root      374:        {
1.1.1.4 ! root      375:                strncpy(path, path_and_name, FILENAME_MAX);
        !           376:                path[FILENAME_MAX-1] = '\0';
        !           377:        }
        !           378:        else
        !           379:        {
        !           380:                if (!getcwd(path, FILENAME_MAX))
        !           381:                {
        !           382:                        perror("SDLGui_FileSelect");
        !           383:                        return NULL;
        !           384:                }
1.1.1.2   root      385:        }
1.1.1.4 ! root      386:        if (stat(path, &filestat) == 0 && S_ISDIR(filestat.st_mode))
        !           387:        {
        !           388:                File_AddSlashToEndFileName(path);
        !           389:                fname[0] = 0;
        !           390:        }
        !           391:        else
        !           392:                File_SplitPath(path, path, fname, NULL);
1.1.1.2   root      393:        File_MakeAbsoluteName(path);
                    394:        File_MakeValidPathName(path);
1.1       root      395:        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
                    396:        File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
                    397: 
1.1.1.4 ! root      398:        /* Save old mouse cursor state and enable cursor */
1.1       root      399:        oldcursorstate = SDL_ShowCursor(SDL_QUERY);
                    400:        if (oldcursorstate == SDL_DISABLE)
                    401:                SDL_ShowCursor(SDL_ENABLE);
                    402: 
                    403:        do
                    404:        {
                    405:                if (reloaddir)
                    406:                {
1.1.1.4 ! root      407:                        files = files_free(files);
1.1       root      408: 
                    409:                        if (browsingzip)
                    410:                        {
                    411:                                files = ZIP_GetFilesDir(zipfiles, zipdir, &entries);
                    412:                        }
                    413:                        else
                    414:                        {
                    415:                                /* Load directory entries: */
                    416:                                entries = scandir(path, &files, 0, alphasort);
                    417:                        }
1.1.1.3   root      418:                        
                    419:                        /* Remove hidden files from the list if necessary: */
                    420:                        if (!(fsdlg[SGFSDLG_SHOWHIDDEN].state & SG_SELECTED))
                    421:                        {
                    422:                                DlgFileSelect_RemoveHiddenFiles(files);
                    423:                        }
1.1       root      424: 
                    425:                        if (entries < 0)
                    426:                        {
                    427:                                fprintf(stderr, "SDLGui_FileSelect: Path not found.\n");
                    428:                                free(pStringMem);
                    429:                                return FALSE;
                    430:                        }
                    431: 
1.1.1.4 ! root      432:                        /* reload always implies refresh */
1.1       root      433:                        reloaddir = FALSE;
                    434:                        refreshentries = TRUE;
                    435:                }/* reloaddir */
                    436: 
                    437:                /* Update the file name strings in the dialog? */
                    438:                if (refreshentries)
                    439:                {
1.1.1.2   root      440:                        if (!DlgFileSelect_RefreshEntries(files, path, browsingzip))
1.1       root      441:                        {
                    442:                                free(pStringMem);
                    443:                                return FALSE;
                    444:                        }
                    445:                        refreshentries = FALSE;
                    446:                }
                    447: 
                    448:                /* Show dialog: */
1.1.1.2   root      449:                retbut = SDLGui_DoDialog(fsdlg, &sdlEvent);
1.1       root      450: 
                    451:                /* Has the user clicked on a file or folder? */
1.1.1.4 ! root      452:                if (retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos<entries)
1.1       root      453:                {
                    454:                        char *tempstr;
1.1.1.4 ! root      455:                        
1.1       root      456:                        tempstr = malloc(FILENAME_MAX);
                    457:                        if (!tempstr)
                    458:                        {
                    459:                                perror("Error while allocating temporary memory in SDLGui_FileSelect()");
                    460:                                free(pStringMem);
                    461:                                return FALSE;
                    462:                        }
                    463: 
1.1.1.4 ! root      464:                        if (browsingzip == TRUE)
1.1       root      465:                        {
1.1.1.4 ! root      466:                                if (!strcat_maxlen(tempstr, FILENAME_MAX,
        !           467:                                                   zipdir, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name))
        !           468:                                {
        !           469:                                        fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
        !           470:                                        free(pStringMem);
        !           471:                                        return FALSE;
        !           472:                                }
        !           473:                                /* directory? */
1.1.1.3   root      474:                                if (File_DoesFileNameEndWithSlash(tempstr))
1.1       root      475:                                {
                    476:                                        /* handle the ../ directory */
1.1.1.4 ! root      477:                                        if (strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0)
1.1       root      478:                                        {
                    479:                                                /* close the zip file */
1.1.1.4 ! root      480:                                                if (strcmp(tempstr, "../") == 0)
1.1       root      481:                                                {
                    482:                                                        /* free zip file entries */
                    483:                                                        ZIP_FreeZipDir(zipfiles);
                    484:                                                        zipfiles = NULL;
                    485:                                                        /* Copy the path name to the dialog */
                    486:                                                        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
                    487:                                                        browsingzip = FALSE;
                    488:                                                }
                    489:                                                else
                    490:                                                {
1.1.1.4 ! root      491:                                                        /* remove "../" and previous dir from path */
        !           492:                                                        File_PathShorten(tempstr, 2);
        !           493:                                                        correct_zip_root(tempstr);
1.1       root      494:                                                        strcpy(zipdir, tempstr);
                    495:                                                        File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    496:                                                }
                    497:                                        }
                    498:                                        else /* not the "../" directory */
                    499:                                        {
                    500:                                                strcpy(zipdir, tempstr);
                    501:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    502:                                        }
                    503:                                        reloaddir = TRUE;
                    504:                                        /* Copy the path name to the dialog */
                    505:                                        selection = -1;                /* Remove old selection */
                    506:                                        zipfilename[0] = '\0';
                    507:                                        dlgfname[0] = 0;
                    508:                                        ypos = 0;
                    509:                                }
                    510:                                else
                    511:                                {
1.1.1.4 ! root      512:                                        /* not dir, select a file in the zip */
1.1       root      513:                                        selection = retbut-SGFSDLG_ENTRY1+ypos;
                    514:                                        strcpy(zipfilename, files[selection]->d_name);
                    515:                                        File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE);
                    516:                                }
                    517: 
1.1.1.4 ! root      518:                        }
        !           519:                        else /* not browsingzip */
1.1       root      520:                        {
1.1.1.4 ! root      521:                                if (!strcat_maxlen(tempstr, FILENAME_MAX,
        !           522:                                                   path, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name))
1.1       root      523:                                {
1.1.1.4 ! root      524:                                        fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
        !           525:                                        free(pStringMem);
        !           526:                                        return FALSE;
        !           527:                                }
        !           528:                                if (stat(tempstr, &filestat) == 0 && S_ISDIR(filestat.st_mode))
        !           529:                                {
        !           530:                                        File_HandleDotDirs(tempstr);
        !           531:                                        File_AddSlashToEndFileName(tempstr);
        !           532:                                        /* Copy the path name to the dialog */
        !           533:                                        File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE);
1.1       root      534:                                        strcpy(path, tempstr);
                    535:                                        reloaddir = TRUE;
                    536:                                        selection = -1;                /* Remove old selection */
                    537:                                        dlgfname[0] = 0;
                    538:                                        ypos = 0;
                    539:                                }
                    540:                                else if (ZIP_FileNameIsZIP(tempstr) && zip_path != NULL)
                    541:                                {
                    542:                                        /* open a zip file */
                    543:                                        zipfiles = ZIP_GetFiles(tempstr);
1.1.1.4 ! root      544:                                        if (zipfiles != NULL && browsingzip == FALSE)
1.1       root      545:                                        {
                    546:                                                selection = retbut-SGFSDLG_ENTRY1+ypos;
                    547:                                                strcpy(fname, files[selection]->d_name);
                    548:                                                File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
1.1.1.4 ! root      549:                                                browsingzip = TRUE;
        !           550:                                                zipdir[0] = '\0'; /* zip root */
1.1       root      551:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
1.1.1.4 ! root      552:                                                reloaddir = TRUE;
1.1       root      553:                                                ypos = 0;
                    554:                                        }
                    555: 
                    556:                                }
                    557:                                else
                    558:                                {
                    559:                                        /* Select a file */
                    560:                                        selection = retbut-SGFSDLG_ENTRY1+ypos;
                    561:                                        strcpy(fname, files[selection]->d_name);
                    562:                                        File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
                    563:                                }
                    564: 
                    565:                        } /* not browsingzip */
                    566: 
                    567:                        free(tempstr);
                    568:                }
                    569:                else    /* Has the user clicked on another button? */
                    570:                {
                    571:                        switch(retbut)
                    572:                        {
                    573:                        case SGFSDLG_UPDIR:                 /* Change path to parent directory */
                    574: 
1.1.1.4 ! root      575:                                if (browsingzip)
1.1       root      576:                                {
1.1.1.4 ! root      577:                                        /* close the zip file? */
        !           578:                                        if (!zipdir[0])
1.1       root      579:                                        {
                    580:                                                /* free zip file entries */
                    581:                                                ZIP_FreeZipDir(zipfiles);
1.1.1.4 ! root      582:                                                browsingzip = FALSE;
1.1       root      583:                                                zipfiles = NULL;
                    584:                                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
                    585:                                        }
                    586:                                        else
                    587:                                        {
1.1.1.4 ! root      588:                                                /* remove last dir from zipdir path */
        !           589:                                                File_PathShorten(zipdir, 1);
        !           590:                                                correct_zip_root(zipdir);
1.1       root      591:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    592:                                                zipfilename[0] = '\0';
                    593:                                        }
                    594:                                }  /* not a zip file: */
1.1.1.4 ! root      595:                                else
1.1       root      596:                                {
1.1.1.4 ! root      597:                                        File_PathShorten(path, 1);
        !           598:                                        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1       root      599:                                }
1.1.1.4 ! root      600:                                reloaddir = TRUE;
1.1       root      601:                                break;
1.1.1.3   root      602: 
                    603:                        case SGFSDLG_HOMEDIR:               /* Change to home directory */
1.1.1.4 ! root      604:                                home = getenv("HOME");
        !           605:                                if (home == NULL)
1.1.1.3   root      606:                                        break;
                    607:                                if (browsingzip)
                    608:                                {
                    609:                                        /* free zip file entries */
                    610:                                        ZIP_FreeZipDir(zipfiles);
                    611:                                        zipfiles = NULL;
                    612:                                        browsingzip = FALSE;
                    613:                                }
1.1.1.4 ! root      614:                                strcpy(path, home);
1.1.1.3   root      615:                                File_AddSlashToEndFileName(path);
1.1.1.4 ! root      616:                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1.1.3   root      617:                                reloaddir = TRUE;
                    618:                                break;
                    619: 
1.1       root      620:                        case SGFSDLG_ROOTDIR:               /* Change to root directory */
1.1.1.4 ! root      621:                                if (browsingzip)
1.1       root      622:                                {
                    623:                                        /* free zip file entries */
                    624:                                        ZIP_FreeZipDir(zipfiles);
                    625:                                        zipfiles = NULL;
                    626:                                        browsingzip = FALSE;
                    627:                                }
                    628:                                strcpy(path, "/");
                    629:                                strcpy(dlgpath, path);
1.1.1.4 ! root      630:                                reloaddir = TRUE;
1.1       root      631:                                break;
                    632:                        case SGFSDLG_UP:                    /* Scroll up */
1.1.1.2   root      633:                                DlgFileSelect_ScrollUp();
                    634:                                SDL_Delay(10);
1.1       root      635:                                break;
                    636:                        case SGFSDLG_DOWN:                  /* Scroll down */
1.1.1.2   root      637:                                DlgFileSelect_ScrollDown();
                    638:                                SDL_Delay(10);
1.1       root      639:                                break;
                    640:                        case SGFSDLG_FILENAME:              /* User entered new filename */
                    641:                                strcpy(fname, dlgfname);
                    642:                                break;
1.1.1.3   root      643:                        case SGFSDLG_SHOWHIDDEN:            /* Show/hide hidden files */
                    644:                                reloaddir = TRUE;
                    645:                                ypos = 0;
                    646:                                break;
1.1.1.2   root      647:                        case SDLGUI_UNKNOWNEVENT:
                    648:                                DlgFileSelect_HandleSdlEvents(&sdlEvent);
                    649:                                break;
1.1       root      650:                        } /* switch */
1.1.1.4 ! root      651:       
        !           652:                        if (reloaddir)
        !           653:                        {
        !           654:                                /* Remove old selection */
        !           655:                                selection = -1;
        !           656:                                fname[0] = 0;
        !           657:                                dlgfname[0] = 0;
        !           658:                                ypos = 0;
        !           659:                        }
1.1       root      660:                } /* other button code */
                    661: 
                    662: 
                    663:        } /* do */
1.1.1.4 ! root      664:        while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL
        !           665:               && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram);
1.1       root      666: 
                    667:        if (oldcursorstate == SDL_DISABLE)
                    668:                SDL_ShowCursor(SDL_DISABLE);
                    669: 
1.1.1.4 ! root      670:        files_free(files);
1.1       root      671: 
                    672:        if (browsingzip)
                    673:        {
                    674:                /* free zip file entries */
                    675:                ZIP_FreeZipDir(zipfiles);
                    676:                zipfiles = NULL;
                    677:        }
                    678: 
1.1.1.4 ! root      679:        if (retbut == SGFSDLG_OKAY)
1.1       root      680:        {
1.1.1.4 ! root      681:                if (zip_path)
        !           682:                        *zip_path = zip_get_path(zipdir, zipfilename, browsingzip);
        !           683:                retpath = File_MakePath(path, fname, NULL);
        !           684:        }
        !           685:        else
        !           686:                retpath = NULL;
        !           687:        free(pStringMem);
        !           688:        return retpath;
        !           689: }
        !           690: 
        !           691: 
        !           692: /*-----------------------------------------------------------------------*/
        !           693: /* Let user browse for a file, confname is used as default.
        !           694:  * If bAllowNew is true, user can select new files also.
        !           695:  * 
        !           696:  * If no file is selected, or there's some problem with the file,
        !           697:  * return FALSE and clear dlgname & confname.
        !           698:  * Otherwise return TRUE, set dlgname & confname to the new file name
        !           699:  * (dlgname is shrinked & limited to maxlen and confname is assumed
        !           700:  * to have FILENAME_MAX amount of space).
        !           701:  */
        !           702: BOOL SDLGui_FileConfSelect(char *dlgname, char *confname, int maxlen, BOOL bAllowNew)
        !           703: {
        !           704:        char *selname;
        !           705:        
        !           706:        selname = SDLGui_FileSelect(confname, NULL, bAllowNew);
        !           707:        if (selname)
        !           708:        {
        !           709:                if (!File_DoesFileNameEndWithSlash(selname) &&
        !           710:                    (bAllowNew || File_Exists(selname)))
1.1       root      711:                {
1.1.1.4 ! root      712:                        strncpy(confname, selname, FILENAME_MAX);
        !           713:                        confname[FILENAME_MAX-1] = '\0';
        !           714:                        File_ShrinkName(dlgname, selname, maxlen);
1.1       root      715:                }
                    716:                else
1.1.1.4 ! root      717:                {
        !           718:                        dlgname[0] = confname[0] = 0;
        !           719:                }
        !           720:                free(selname);
        !           721:                return TRUE;
1.1       root      722:        }
1.1.1.4 ! root      723:        return FALSE;
1.1       root      724: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.