|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.