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

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

unix.superglobalmegacorp.com

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