Annotation of previous/src/gui-sdl/dlgFileSelect.c, revision 1.1

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: */
        !             9: const char DlgFileSelect_fileid[] = "Hatari dlgFileSelect.c : " __DATE__ " " __TIME__;
        !            10: 
        !            11: #include <SDL.h>
        !            12: #include <sys/stat.h>
        !            13: #include <unistd.h>
        !            14: 
        !            15: #include "main.h"
        !            16: #include "scandir.h"
        !            17: #include "sdlgui.h"
        !            18: #include "file.h"
        !            19: #include "paths.h"
        !            20: #include "zip.h"
        !            21: 
        !            22: 
        !            23: #define SGFS_NUMENTRIES   16            /* How many entries are displayed at once */
        !            24: 
        !            25: 
        !            26: #define SGFSDLG_FILENAME  5
        !            27: #define SGFSDLG_UPDIR     6
        !            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
        !            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
        !            46: static char dlgfilenames[SGFS_NUMENTRIES][DLGFILENAMES_SIZE+1];  /* Visible file names in the dialog */
        !            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 },
        !            57:        { SGBUTTON, 0, 0, 51,1, 4,1, ".." },
        !            58:        { SGBUTTON, 0, 0, 56,1, 3,1, "~" },
        !            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 */
        !            80:        { SGCHECKBOX, SG_EXIT, 0, 2,23, 18,1, "Show hidden files" },
        !            81:        { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "Okay" },
        !            82:        { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" },
        !            83:        { -1, 0, 0, 0,0, 0,0, NULL }
        !            84: };
        !            85: 
        !            86: 
        !            87: static int ypos;                        /* First entry number to be displayed */
        !            88: static bool refreshentries;             /* Do we have to update the file names in the dialog? */
        !            89: static int entries;                     /* How many files are in the actual directory? */
        !            90: 
        !            91: 
        !            92: /*-----------------------------------------------------------------------*/
        !            93: /**
        !            94:  * Update the file name strings in the dialog.
        !            95:  * Returns false if it failed, true on success.
        !            96:  */
        !            97: static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, bool browsingzip)
        !            98: {
        !            99:        int i;
        !           100:        char *tempstr = malloc(FILENAME_MAX);
        !           101: 
        !           102:        if (!tempstr)
        !           103:        {
        !           104:                perror("DlgFileSelect_RefreshEntries");
        !           105:                return false;
        !           106:        }
        !           107: 
        !           108:        /* Copy entries to dialog: */
        !           109:        for (i=0; i<SGFS_NUMENTRIES; i++)
        !           110:        {
        !           111:                if (i+ypos < entries)
        !           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: 
        !           122:                        if (browsingzip)
        !           123:                        {
        !           124:                                if (File_DoesFileNameEndWithSlash(tempstr))
        !           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 */
        !           131:                                if (ZIP_FileNameIsZIP(tempstr) && browsingzip == false)
        !           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);
        !           140:        return true;
        !           141: }
        !           142: 
        !           143: 
        !           144: /*-----------------------------------------------------------------------*/
        !           145: /**
        !           146:  * Remove all hidden files (files with file names that begin with a dot) from
        !           147:  * the list.
        !           148:  */
        !           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: /*-----------------------------------------------------------------------*/
        !           190: /**
        !           191:  * Prepare to scroll up one entry.
        !           192:  */
        !           193: static void DlgFileSelect_ScrollUp(void)
        !           194: {
        !           195:        if (ypos > 0)
        !           196:        {
        !           197:                --ypos;
        !           198:                refreshentries = true;
        !           199:        }
        !           200: }
        !           201: 
        !           202: 
        !           203: /*-----------------------------------------------------------------------*/
        !           204: /**
        !           205:  * Prepare to scroll down one entry.
        !           206:  */
        !           207: static void DlgFileSelect_ScrollDown(void)
        !           208: {
        !           209:        if (ypos+SGFS_NUMENTRIES < entries)
        !           210:        {
        !           211:                ++ypos;
        !           212:                refreshentries = true;
        !           213:        }
        !           214: }
        !           215: 
        !           216: 
        !           217: /*-----------------------------------------------------------------------*/
        !           218: /**
        !           219:  * Handle SDL events.
        !           220:  */
        !           221: static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent)
        !           222: {
        !           223:        int oldypos = ypos;
        !           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:                {
        !           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;
        !           240:                 case SDLK_PAGEDOWN:
        !           241:                        if (ypos+2*SGFS_NUMENTRIES < entries)
        !           242:                                ypos += SGFS_NUMENTRIES;
        !           243:                        else
        !           244:                                ypos = entries-SGFS_NUMENTRIES;
        !           245:                        break;
        !           246:                 default:
        !           247:                        break;
        !           248:                }
        !           249:                break;
        !           250:        default:
        !           251:                break;
        !           252:        }
        !           253:        if (ypos < 0)
        !           254:                ypos = 0;
        !           255:        if (ypos != oldypos)
        !           256:                refreshentries = true;
        !           257: }
        !           258: 
        !           259: 
        !           260: /*-----------------------------------------------------------------------*/
        !           261: /**
        !           262:  * Free file entries
        !           263:  */
        !           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: /*-----------------------------------------------------------------------*/
        !           280: /**
        !           281:  * Copy to dst src+add if they are below maxlen and return true,
        !           282:  * otherwise return false
        !           283:  */
        !           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: /*-----------------------------------------------------------------------*/
        !           299: /**
        !           300:  * Create and return suitable path into zip file
        !           301:  */
        !           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;
        !           311:        }
        !           312:        return strdup("");
        !           313: }
        !           314: 
        !           315: /**
        !           316:  * string for zip root needs to be empty, check and correct if needed
        !           317:  */
        !           318: static void correct_zip_root(char *zippath)
        !           319: {
        !           320:        if (zippath[0] == PATHSEP && !zippath[1])
        !           321:        {
        !           322:                zippath[0] = '\0';
        !           323:        }
        !           324: }
        !           325: 
        !           326: /*-----------------------------------------------------------------------*/
        !           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:  */
        !           334: char* SDLGui_FileSelect(const char *path_and_name, char **zip_path, bool bAllowNew)
        !           335: {
        !           336:        struct dirent **files = NULL;
        !           337:        char *pStringMem;
        !           338:        char *retpath;
        !           339:        const char *home;
        !           340:        char *path, *fname;                 /* The actual file and path names */
        !           341:        bool reloaddir = true;              /* Do we have to reload the directory file list? */
        !           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;
        !           347:        bool browsingzip = false;           /* Are we browsing an archive? */
        !           348:        zip_dir *zipfiles = NULL;
        !           349:        SDL_Event sdlEvent;
        !           350: 
        !           351:        ypos = 0;
        !           352:        refreshentries = true;
        !           353:        entries = 0;
        !           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;
        !           359:        zipdir = pStringMem + 2 * FILENAME_MAX;
        !           360:        zipfilename = pStringMem + 3 * FILENAME_MAX;
        !           361:        zipfilename[0] = 0;
        !           362:        fname[0] = 0;
        !           363:        path[0] = 0;
        !           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 */
        !           378:        if (path_and_name && path_and_name[0])
        !           379:        {
        !           380:                strncpy(path, path_and_name, FILENAME_MAX);
        !           381:                path[FILENAME_MAX-1] = '\0';
        !           382:        }
        !           383:        if (!File_DirExists(path))
        !           384:        {
        !           385:                File_SplitPath(path, path, fname, NULL);
        !           386:                if (!(File_DirExists(path) || getcwd(path, FILENAME_MAX)))
        !           387:                {
        !           388:                        perror("SDLGui_FileSelect: non-existing path and CWD failed");
        !           389:                        free(pStringMem);
        !           390:                        return NULL;
        !           391:                }
        !           392:        }
        !           393: 
        !           394:        File_MakeAbsoluteName(path);
        !           395:        File_MakeValidPathName(path);
        !           396:        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
        !           397:        File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
        !           398: 
        !           399:        /* Save old mouse cursor state and enable cursor */
        !           400:        oldcursorstate = SDL_ShowCursor(SDL_QUERY);
        !           401:        if (oldcursorstate == SDL_DISABLE)
        !           402:                SDL_ShowCursor(SDL_ENABLE);
        !           403: 
        !           404:        do
        !           405:        {
        !           406:                if (reloaddir)
        !           407:                {
        !           408:                        files = files_free(files);
        !           409: 
        !           410:                        if (browsingzip)
        !           411:                        {
        !           412:                                files = ZIP_GetFilesDir(zipfiles, zipdir, &entries);
        !           413:                                if(!files)
        !           414:                                {
        !           415:                                        fprintf(stderr, "SDLGui_FileSelect: ZIP_GetFilesDir error!\n");
        !           416:                                        free(pStringMem);
        !           417:                                        return NULL;
        !           418:                                }
        !           419:                        }
        !           420:                        else
        !           421:                        {
        !           422:                                /* Load directory entries: */
        !           423:                                entries = scandir(path, &files, 0, alphasort);
        !           424:                        }
        !           425:                        
        !           426:                        /* Remove hidden files from the list if necessary: */
        !           427:                        if (!(fsdlg[SGFSDLG_SHOWHIDDEN].state & SG_SELECTED))
        !           428:                        {
        !           429:                                DlgFileSelect_RemoveHiddenFiles(files);
        !           430:                        }
        !           431: 
        !           432:                        if (entries < 0)
        !           433:                        {
        !           434:                                fprintf(stderr, "SDLGui_FileSelect: Path not found.\n");
        !           435:                                free(pStringMem);
        !           436:                                return NULL;
        !           437:                        }
        !           438: 
        !           439:                        /* reload always implies refresh */
        !           440:                        reloaddir = false;
        !           441:                        refreshentries = true;
        !           442:                }/* reloaddir */
        !           443: 
        !           444:                /* Update the file name strings in the dialog? */
        !           445:                if (refreshentries)
        !           446:                {
        !           447:                        if (!DlgFileSelect_RefreshEntries(files, path, browsingzip))
        !           448:                        {
        !           449:                                free(pStringMem);
        !           450:                                return NULL;
        !           451:                        }
        !           452:                        refreshentries = false;
        !           453:                }
        !           454: 
        !           455:                /* Show dialog: */
        !           456:                retbut = SDLGui_DoDialog(fsdlg, &sdlEvent);
        !           457: 
        !           458:                /* Has the user clicked on a file or folder? */
        !           459:                if (retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos<entries)
        !           460:                {
        !           461:                        char *tempstr;
        !           462:                        
        !           463:                        tempstr = malloc(FILENAME_MAX);
        !           464:                        if (!tempstr)
        !           465:                        {
        !           466:                                perror("Error while allocating temporary memory in SDLGui_FileSelect()");
        !           467:                                free(pStringMem);
        !           468:                                return NULL;
        !           469:                        }
        !           470: 
        !           471:                        if (browsingzip == true)
        !           472:                        {
        !           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);
        !           478:                                        return NULL;
        !           479:                                }
        !           480:                                /* directory? */
        !           481:                                if (File_DoesFileNameEndWithSlash(tempstr))
        !           482:                                {
        !           483:                                        /* handle the ../ directory */
        !           484:                                        if (strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0)
        !           485:                                        {
        !           486:                                                /* close the zip file */
        !           487:                                                if (strcmp(tempstr, "../") == 0)
        !           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);
        !           494:                                                        browsingzip = false;
        !           495:                                                }
        !           496:                                                else
        !           497:                                                {
        !           498:                                                        /* remove "../" and previous dir from path */
        !           499:                                                        File_PathShorten(tempstr, 2);
        !           500:                                                        correct_zip_root(tempstr);
        !           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:                                        }
        !           510:                                        reloaddir = true;
        !           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:                                {
        !           519:                                        /* not dir, select a file in the zip */
        !           520:                                        selection = retbut-SGFSDLG_ENTRY1+ypos;
        !           521:                                        strcpy(zipfilename, files[selection]->d_name);
        !           522:                                        File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE);
        !           523:                                }
        !           524: 
        !           525:                        }
        !           526:                        else /* not browsingzip */
        !           527:                        {
        !           528:                                if (!strcat_maxlen(tempstr, FILENAME_MAX,
        !           529:                                                   path, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name))
        !           530:                                {
        !           531:                                        fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
        !           532:                                        free(pStringMem);
        !           533:                                        return NULL;
        !           534:                                }
        !           535:                                if (File_DirExists(tempstr))
        !           536:                                {
        !           537:                                        File_HandleDotDirs(tempstr);
        !           538:                                        File_AddSlashToEndFileName(tempstr);
        !           539:                                        /* Copy the path name to the dialog */
        !           540:                                        File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE);
        !           541:                                        strcpy(path, tempstr);
        !           542:                                        reloaddir = true;
        !           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);
        !           551:                                        if (zipfiles != NULL && browsingzip == false)
        !           552:                                        {
        !           553:                                                selection = retbut-SGFSDLG_ENTRY1+ypos;
        !           554:                                                strcpy(fname, files[selection]->d_name);
        !           555:                                                File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
        !           556:                                                browsingzip = true;
        !           557:                                                zipdir[0] = '\0'; /* zip root */
        !           558:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
        !           559:                                                reloaddir = true;
        !           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: 
        !           582:                                if (browsingzip)
        !           583:                                {
        !           584:                                        /* close the zip file? */
        !           585:                                        if (!zipdir[0])
        !           586:                                        {
        !           587:                                                /* free zip file entries */
        !           588:                                                ZIP_FreeZipDir(zipfiles);
        !           589:                                                browsingzip = false;
        !           590:                                                zipfiles = NULL;
        !           591:                                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
        !           592:                                        }
        !           593:                                        else
        !           594:                                        {
        !           595:                                                /* remove last dir from zipdir path */
        !           596:                                                File_PathShorten(zipdir, 1);
        !           597:                                                correct_zip_root(zipdir);
        !           598:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
        !           599:                                                zipfilename[0] = '\0';
        !           600:                                        }
        !           601:                                }  /* not a zip file: */
        !           602:                                else
        !           603:                                {
        !           604:                                        File_PathShorten(path, 1);
        !           605:                                        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
        !           606:                                }
        !           607:                                reloaddir = true;
        !           608:                                break;
        !           609: 
        !           610:                        case SGFSDLG_HOMEDIR:               /* Change to home directory */
        !           611:                                home = Paths_GetUserHome();
        !           612:                                if (home == NULL || !*home)
        !           613:                                        break;
        !           614:                                if (browsingzip)
        !           615:                                {
        !           616:                                        /* free zip file entries */
        !           617:                                        ZIP_FreeZipDir(zipfiles);
        !           618:                                        zipfiles = NULL;
        !           619:                                        browsingzip = false;
        !           620:                                }
        !           621:                                strcpy(path, home);
        !           622:                                File_AddSlashToEndFileName(path);
        !           623:                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
        !           624:                                reloaddir = true;
        !           625:                                break;
        !           626: 
        !           627:                        case SGFSDLG_ROOTDIR:               /* Change to root directory */
        !           628:                                if (browsingzip)
        !           629:                                {
        !           630:                                        /* free zip file entries */
        !           631:                                        ZIP_FreeZipDir(zipfiles);
        !           632:                                        zipfiles = NULL;
        !           633:                                        browsingzip = false;
        !           634:                                }
        !           635:                                path[0] = PATHSEP; path[1] = '\0';
        !           636:                                strcpy(dlgpath, path);
        !           637:                                reloaddir = true;
        !           638:                                break;
        !           639:                        case SGFSDLG_UP:                    /* Scroll up */
        !           640:                                DlgFileSelect_ScrollUp();
        !           641:                                SDL_Delay(10);
        !           642:                                break;
        !           643:                        case SGFSDLG_DOWN:                  /* Scroll down */
        !           644:                                DlgFileSelect_ScrollDown();
        !           645:                                SDL_Delay(10);
        !           646:                                break;
        !           647:                        case SGFSDLG_FILENAME:              /* User entered new filename */
        !           648:                                strcpy(fname, dlgfname);
        !           649:                                break;
        !           650:                        case SGFSDLG_SHOWHIDDEN:            /* Show/hide hidden files */
        !           651:                                reloaddir = true;
        !           652:                                ypos = 0;
        !           653:                                break;
        !           654:                        case SDLGUI_UNKNOWNEVENT:
        !           655:                                DlgFileSelect_HandleSdlEvents(&sdlEvent);
        !           656:                                break;
        !           657:                        } /* switch */
        !           658:       
        !           659:                        if (reloaddir)
        !           660:                        {
        !           661:                                /* Remove old selection */
        !           662:                                selection = -1;
        !           663:                                fname[0] = 0;
        !           664:                                dlgfname[0] = 0;
        !           665:                                ypos = 0;
        !           666:                        }
        !           667:                } /* other button code */
        !           668: 
        !           669: 
        !           670:        } /* do */
        !           671:        while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL
        !           672:               && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram);
        !           673: 
        !           674:        if (oldcursorstate == SDL_DISABLE)
        !           675:                SDL_ShowCursor(SDL_DISABLE);
        !           676: 
        !           677:        files_free(files);
        !           678: 
        !           679:        if (browsingzip)
        !           680:        {
        !           681:                /* free zip file entries */
        !           682:                ZIP_FreeZipDir(zipfiles);
        !           683:                zipfiles = NULL;
        !           684:        }
        !           685: 
        !           686:        if (retbut == SGFSDLG_OKAY)
        !           687:        {
        !           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: /*-----------------------------------------------------------------------*/
        !           700: /**
        !           701:  * Let user browse for a file, confname is used as default.
        !           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,
        !           705:  * return false and clear dlgname & confname.
        !           706:  * Otherwise return true, set dlgname & confname to the new file name
        !           707:  * (dlgname is shrinked & limited to maxlen and confname is assumed
        !           708:  * to have FILENAME_MAX amount of space).
        !           709:  */
        !           710: bool SDLGui_FileConfSelect(char *dlgname, char *confname, int maxlen, bool bAllowNew)
        !           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)))
        !           719:                {
        !           720:                        strncpy(confname, selname, FILENAME_MAX);
        !           721:                        confname[FILENAME_MAX-1] = '\0';
        !           722:                        File_ShrinkName(dlgname, selname, maxlen);
        !           723:                }
        !           724:                else
        !           725:                {
        !           726:                        dlgname[0] = confname[0] = 0;
        !           727:                }
        !           728:                free(selname);
        !           729:                return true;
        !           730:        }
        !           731:        return false;
        !           732: }

unix.superglobalmegacorp.com

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