|
|
1.1 root 1: /*
2: Hatari - dlgFileSelect.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: A file selection dialog for the graphical user interface for Hatari.
8: */
1.1.1.7 ! root 9: const char DlgFileSelect_fileid[] = "Hatari dlgFileSelect.c : " __DATE__ " " __TIME__;
1.1 root 10:
11: #include <SDL.h>
12: #include <sys/stat.h>
13: #include <unistd.h>
14:
15: #include "main.h"
1.1.1.3 root 16: #include "scandir.h"
1.1 root 17: #include "sdlgui.h"
18: #include "file.h"
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.5 root 79: { SGCHECKBOX, SG_EXIT, 0, 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 */
1.1.1.5 root 87: static bool refreshentries; /* Do we have to update the file names in the dialog? */
1.1.1.2 root 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.
1.1.1.7 ! root 94: Returns false if it failed, true on success.
1.1 root 95: */
1.1.1.5 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");
1.1.1.7 ! root 104: return false;
1.1 root 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 */
1.1.1.7 ! root 130: if (ZIP_FileNameIsZIP(tempstr) && browsingzip == false)
1.1 root 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);
1.1.1.7 ! root 139: return true;
1.1 root 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;
1.1.1.7 ! root 197: refreshentries = true;
1.1.1.2 root 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;
1.1.1.7 ! root 211: refreshentries = true;
1.1.1.2 root 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)
1.1.1.7 ! root 255: refreshentries = true;
1.1.1.4 root 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.1.7 ! root 329: bAllowNew: true if the user is allowed to insert new file names.
1.1 root 330: */
1.1.1.5 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.1.7 ! root 337: bool reloaddir = true; /* Do we have to reload the directory file list? */
1.1 root 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;
1.1.1.7 ! root 343: bool browsingzip = false; /* Are we browsing an archive? */
1.1 root 344: zip_dir *zipfiles = NULL;
1.1.1.2 root 345: SDL_Event sdlEvent;
346:
347: ypos = 0;
1.1.1.7 ! root 348: refreshentries = true;
1.1.1.2 root 349: entries = 0;
1.1 root 350:
351: /* Allocate memory for the file and path name strings: */
352: pStringMem = malloc(4 * FILENAME_MAX);
353: path = pStringMem;
354: fname = pStringMem + FILENAME_MAX;
1.1.1.4 root 355: zipdir = pStringMem + 2 * FILENAME_MAX;
356: zipfilename = pStringMem + 3 * FILENAME_MAX;
1.1 root 357: zipfilename[0] = 0;
1.1.1.5 root 358: fname[0] = 0;
359: path[0] = 0;
1.1 root 360:
361: SDLGui_CenterDlg(fsdlg);
362: if (bAllowNew)
363: {
364: fsdlg[SGFSDLG_FILENAME].type = SGEDITFIELD;
365: fsdlg[SGFSDLG_FILENAME].flags |= SG_EXIT;
366: }
367: else
368: {
369: fsdlg[SGFSDLG_FILENAME].type = SGTEXT;
370: fsdlg[SGFSDLG_FILENAME].flags &= ~SG_EXIT;
371: }
372:
373: /* Prepare the path and filename variables */
1.1.1.4 root 374: if (path_and_name && path_and_name[0])
1.1.1.2 root 375: {
1.1.1.4 root 376: strncpy(path, path_and_name, FILENAME_MAX);
377: path[FILENAME_MAX-1] = '\0';
378: }
1.1.1.5 root 379: if (!File_DirExists(path))
1.1.1.4 root 380: {
1.1.1.5 root 381: File_SplitPath(path, path, fname, NULL);
382: if (!(File_DirExists(path) || getcwd(path, FILENAME_MAX)))
1.1.1.4 root 383: {
1.1.1.5 root 384: perror("SDLGui_FileSelect: non-existing path and CWD failed");
1.1.1.4 root 385: return NULL;
386: }
1.1.1.2 root 387: }
1.1.1.5 root 388:
1.1.1.2 root 389: File_MakeAbsoluteName(path);
390: File_MakeValidPathName(path);
1.1 root 391: File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
392: File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
393:
1.1.1.4 root 394: /* Save old mouse cursor state and enable cursor */
1.1 root 395: oldcursorstate = SDL_ShowCursor(SDL_QUERY);
396: if (oldcursorstate == SDL_DISABLE)
397: SDL_ShowCursor(SDL_ENABLE);
398:
399: do
400: {
401: if (reloaddir)
402: {
1.1.1.4 root 403: files = files_free(files);
1.1 root 404:
405: if (browsingzip)
406: {
407: files = ZIP_GetFilesDir(zipfiles, zipdir, &entries);
408: }
409: else
410: {
411: /* Load directory entries: */
412: entries = scandir(path, &files, 0, alphasort);
413: }
1.1.1.3 root 414:
415: /* Remove hidden files from the list if necessary: */
416: if (!(fsdlg[SGFSDLG_SHOWHIDDEN].state & SG_SELECTED))
417: {
418: DlgFileSelect_RemoveHiddenFiles(files);
419: }
1.1 root 420:
421: if (entries < 0)
422: {
423: fprintf(stderr, "SDLGui_FileSelect: Path not found.\n");
424: free(pStringMem);
1.1.1.5 root 425: return NULL;
1.1 root 426: }
427:
1.1.1.4 root 428: /* reload always implies refresh */
1.1.1.7 ! root 429: reloaddir = false;
! 430: refreshentries = true;
1.1 root 431: }/* reloaddir */
432:
433: /* Update the file name strings in the dialog? */
434: if (refreshentries)
435: {
1.1.1.2 root 436: if (!DlgFileSelect_RefreshEntries(files, path, browsingzip))
1.1 root 437: {
438: free(pStringMem);
1.1.1.5 root 439: return NULL;
1.1 root 440: }
1.1.1.7 ! root 441: refreshentries = false;
1.1 root 442: }
443:
444: /* Show dialog: */
1.1.1.2 root 445: retbut = SDLGui_DoDialog(fsdlg, &sdlEvent);
1.1 root 446:
447: /* Has the user clicked on a file or folder? */
1.1.1.4 root 448: if (retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos<entries)
1.1 root 449: {
450: char *tempstr;
1.1.1.4 root 451:
1.1 root 452: tempstr = malloc(FILENAME_MAX);
453: if (!tempstr)
454: {
455: perror("Error while allocating temporary memory in SDLGui_FileSelect()");
456: free(pStringMem);
1.1.1.5 root 457: return NULL;
1.1 root 458: }
459:
1.1.1.7 ! root 460: if (browsingzip == true)
1.1 root 461: {
1.1.1.4 root 462: if (!strcat_maxlen(tempstr, FILENAME_MAX,
463: zipdir, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name))
464: {
465: fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
466: free(pStringMem);
1.1.1.5 root 467: return NULL;
1.1.1.4 root 468: }
469: /* directory? */
1.1.1.3 root 470: if (File_DoesFileNameEndWithSlash(tempstr))
1.1 root 471: {
472: /* handle the ../ directory */
1.1.1.4 root 473: if (strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0)
1.1 root 474: {
475: /* close the zip file */
1.1.1.4 root 476: if (strcmp(tempstr, "../") == 0)
1.1 root 477: {
478: /* free zip file entries */
479: ZIP_FreeZipDir(zipfiles);
480: zipfiles = NULL;
481: /* Copy the path name to the dialog */
482: File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1.1.7 ! root 483: browsingzip = false;
1.1 root 484: }
485: else
486: {
1.1.1.4 root 487: /* remove "../" and previous dir from path */
488: File_PathShorten(tempstr, 2);
489: correct_zip_root(tempstr);
1.1 root 490: strcpy(zipdir, tempstr);
491: File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
492: }
493: }
494: else /* not the "../" directory */
495: {
496: strcpy(zipdir, tempstr);
497: File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
498: }
1.1.1.7 ! root 499: reloaddir = true;
1.1 root 500: /* Copy the path name to the dialog */
501: selection = -1; /* Remove old selection */
502: zipfilename[0] = '\0';
503: dlgfname[0] = 0;
504: ypos = 0;
505: }
506: else
507: {
1.1.1.4 root 508: /* not dir, select a file in the zip */
1.1 root 509: selection = retbut-SGFSDLG_ENTRY1+ypos;
510: strcpy(zipfilename, files[selection]->d_name);
511: File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE);
512: }
513:
1.1.1.4 root 514: }
515: else /* not browsingzip */
1.1 root 516: {
1.1.1.4 root 517: if (!strcat_maxlen(tempstr, FILENAME_MAX,
518: path, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name))
1.1 root 519: {
1.1.1.4 root 520: fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
521: free(pStringMem);
1.1.1.5 root 522: return NULL;
1.1.1.4 root 523: }
1.1.1.5 root 524: if (File_DirExists(tempstr))
1.1.1.4 root 525: {
526: File_HandleDotDirs(tempstr);
527: File_AddSlashToEndFileName(tempstr);
528: /* Copy the path name to the dialog */
529: File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE);
1.1 root 530: strcpy(path, tempstr);
1.1.1.7 ! root 531: reloaddir = true;
1.1 root 532: selection = -1; /* Remove old selection */
533: dlgfname[0] = 0;
534: ypos = 0;
535: }
536: else if (ZIP_FileNameIsZIP(tempstr) && zip_path != NULL)
537: {
538: /* open a zip file */
539: zipfiles = ZIP_GetFiles(tempstr);
1.1.1.7 ! root 540: if (zipfiles != NULL && browsingzip == false)
1.1 root 541: {
542: selection = retbut-SGFSDLG_ENTRY1+ypos;
543: strcpy(fname, files[selection]->d_name);
544: File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
1.1.1.7 ! root 545: browsingzip = true;
1.1.1.4 root 546: zipdir[0] = '\0'; /* zip root */
1.1 root 547: File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
1.1.1.7 ! root 548: reloaddir = true;
1.1 root 549: ypos = 0;
550: }
551:
552: }
553: else
554: {
555: /* Select a file */
556: selection = retbut-SGFSDLG_ENTRY1+ypos;
557: strcpy(fname, files[selection]->d_name);
558: File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
559: }
560:
561: } /* not browsingzip */
562:
563: free(tempstr);
564: }
565: else /* Has the user clicked on another button? */
566: {
567: switch(retbut)
568: {
569: case SGFSDLG_UPDIR: /* Change path to parent directory */
570:
1.1.1.4 root 571: if (browsingzip)
1.1 root 572: {
1.1.1.4 root 573: /* close the zip file? */
574: if (!zipdir[0])
1.1 root 575: {
576: /* free zip file entries */
577: ZIP_FreeZipDir(zipfiles);
1.1.1.7 ! root 578: browsingzip = false;
1.1 root 579: zipfiles = NULL;
580: File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
581: }
582: else
583: {
1.1.1.4 root 584: /* remove last dir from zipdir path */
585: File_PathShorten(zipdir, 1);
586: correct_zip_root(zipdir);
1.1 root 587: File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
588: zipfilename[0] = '\0';
589: }
590: } /* not a zip file: */
1.1.1.4 root 591: else
1.1 root 592: {
1.1.1.4 root 593: File_PathShorten(path, 1);
594: File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1 root 595: }
1.1.1.7 ! root 596: reloaddir = true;
1.1 root 597: break;
1.1.1.3 root 598:
599: case SGFSDLG_HOMEDIR: /* Change to home directory */
1.1.1.4 root 600: home = getenv("HOME");
601: if (home == NULL)
1.1.1.3 root 602: break;
603: if (browsingzip)
604: {
605: /* free zip file entries */
606: ZIP_FreeZipDir(zipfiles);
607: zipfiles = NULL;
1.1.1.7 ! root 608: browsingzip = false;
1.1.1.3 root 609: }
1.1.1.4 root 610: strcpy(path, home);
1.1.1.3 root 611: File_AddSlashToEndFileName(path);
1.1.1.4 root 612: File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1.1.7 ! root 613: reloaddir = true;
1.1.1.3 root 614: break;
615:
1.1 root 616: case SGFSDLG_ROOTDIR: /* Change to root directory */
1.1.1.4 root 617: if (browsingzip)
1.1 root 618: {
619: /* free zip file entries */
620: ZIP_FreeZipDir(zipfiles);
621: zipfiles = NULL;
1.1.1.7 ! root 622: browsingzip = false;
1.1 root 623: }
1.1.1.7 ! root 624: path[0] = PATHSEP; path[1] = '\0';
1.1 root 625: strcpy(dlgpath, path);
1.1.1.7 ! root 626: reloaddir = true;
1.1 root 627: break;
628: case SGFSDLG_UP: /* Scroll up */
1.1.1.2 root 629: DlgFileSelect_ScrollUp();
630: SDL_Delay(10);
1.1 root 631: break;
632: case SGFSDLG_DOWN: /* Scroll down */
1.1.1.2 root 633: DlgFileSelect_ScrollDown();
634: SDL_Delay(10);
1.1 root 635: break;
636: case SGFSDLG_FILENAME: /* User entered new filename */
637: strcpy(fname, dlgfname);
638: break;
1.1.1.3 root 639: case SGFSDLG_SHOWHIDDEN: /* Show/hide hidden files */
1.1.1.7 ! root 640: reloaddir = true;
1.1.1.3 root 641: ypos = 0;
642: break;
1.1.1.2 root 643: case SDLGUI_UNKNOWNEVENT:
644: DlgFileSelect_HandleSdlEvents(&sdlEvent);
645: break;
1.1 root 646: } /* switch */
1.1.1.4 root 647:
648: if (reloaddir)
649: {
650: /* Remove old selection */
651: selection = -1;
652: fname[0] = 0;
653: dlgfname[0] = 0;
654: ypos = 0;
655: }
1.1 root 656: } /* other button code */
657:
658:
659: } /* do */
1.1.1.4 root 660: while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL
661: && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram);
1.1 root 662:
663: if (oldcursorstate == SDL_DISABLE)
664: SDL_ShowCursor(SDL_DISABLE);
665:
1.1.1.4 root 666: files_free(files);
1.1 root 667:
668: if (browsingzip)
669: {
670: /* free zip file entries */
671: ZIP_FreeZipDir(zipfiles);
672: zipfiles = NULL;
673: }
674:
1.1.1.4 root 675: if (retbut == SGFSDLG_OKAY)
1.1 root 676: {
1.1.1.4 root 677: if (zip_path)
678: *zip_path = zip_get_path(zipdir, zipfilename, browsingzip);
679: retpath = File_MakePath(path, fname, NULL);
680: }
681: else
682: retpath = NULL;
683: free(pStringMem);
684: return retpath;
685: }
686:
687:
688: /*-----------------------------------------------------------------------*/
689: /* Let user browse for a file, confname is used as default.
690: * If bAllowNew is true, user can select new files also.
691: *
692: * If no file is selected, or there's some problem with the file,
1.1.1.7 ! root 693: * return false and clear dlgname & confname.
! 694: * Otherwise return true, set dlgname & confname to the new file name
1.1.1.4 root 695: * (dlgname is shrinked & limited to maxlen and confname is assumed
696: * to have FILENAME_MAX amount of space).
697: */
1.1.1.5 root 698: bool SDLGui_FileConfSelect(char *dlgname, char *confname, int maxlen, bool bAllowNew)
1.1.1.4 root 699: {
700: char *selname;
701:
702: selname = SDLGui_FileSelect(confname, NULL, bAllowNew);
703: if (selname)
704: {
705: if (!File_DoesFileNameEndWithSlash(selname) &&
706: (bAllowNew || File_Exists(selname)))
1.1 root 707: {
1.1.1.4 root 708: strncpy(confname, selname, FILENAME_MAX);
709: confname[FILENAME_MAX-1] = '\0';
710: File_ShrinkName(dlgname, selname, maxlen);
1.1 root 711: }
712: else
1.1.1.4 root 713: {
714: dlgname[0] = confname[0] = 0;
715: }
716: free(selname);
1.1.1.7 ! root 717: return true;
1.1 root 718: }
1.1.1.7 ! root 719: return false;
1.1 root 720: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.