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