--- hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:13:16 1.1.1.3 +++ hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:13:50 1.1.1.4 @@ -6,7 +6,7 @@ A file selection dialog for the graphical user interface for Hatari. */ -const char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.3 2019/04/01 07:13:16 root Exp $"; +const char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.4 2019/04/01 07:13:50 root Exp $"; #include #include @@ -77,8 +77,8 @@ static SGOBJ fsdlg[] = { SGBUTTON, SG_TOUCHEXIT, 0, 62,6, 1,1, "\x01" }, /* Arrow up */ { SGBUTTON, SG_TOUCHEXIT, 0, 62,21, 1,1, "\x02" }, /* Arrow down */ { SGCHECKBOX, SG_EXIT, SG_SELECTED, 2,23, 18,1, "Show hidden files" }, - { SGBUTTON, 0, 0, 32,23, 8,1, "Okay" }, - { SGBUTTON, 0, 0, 50,23, 8,1, "Cancel" }, + { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "Okay" }, + { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" }, { -1, 0, 0, 0,0, 0,0, NULL } }; @@ -105,9 +105,9 @@ static int DlgFileSelect_RefreshEntries( } /* Copy entries to dialog: */ - for(i=0; id_name); - if( browsingzip ) + if (browsingzip) { if (File_DoesFileNameEndWithSlash(tempstr)) dlgfilenames[i][0] = SGFOLDER; /* Mark folders */ @@ -219,6 +219,7 @@ static void DlgFileSelect_ScrollDown(voi */ static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent) { + int oldypos = ypos; switch (pEvent->type) { case SDL_MOUSEBUTTONDOWN: @@ -230,47 +231,109 @@ static void DlgFileSelect_HandleSdlEvent case SDL_KEYDOWN: switch (pEvent->key.keysym.sym) { - case SDLK_UP: DlgFileSelect_ScrollUp(); break; - case SDLK_DOWN: DlgFileSelect_ScrollDown(); break; - case SDLK_HOME: ypos = 0; refreshentries = TRUE; break; - case SDLK_END: ypos = entries-SGFS_NUMENTRIES; refreshentries = TRUE; break; - case SDLK_PAGEUP: - if (ypos > SGFS_NUMENTRIES) - ypos -= SGFS_NUMENTRIES; - else - ypos = 0; - refreshentries = TRUE; - break; + case SDLK_UP: DlgFileSelect_ScrollUp(); break; + case SDLK_DOWN: DlgFileSelect_ScrollDown(); break; + case SDLK_HOME: ypos = 0; break; + case SDLK_END: ypos = entries-SGFS_NUMENTRIES; break; + case SDLK_PAGEUP: ypos -= SGFS_NUMENTRIES; break; case SDLK_PAGEDOWN: if (ypos+2*SGFS_NUMENTRIES < entries) ypos += SGFS_NUMENTRIES; else ypos = entries-SGFS_NUMENTRIES; - refreshentries = TRUE; break; - default: break; + default: + break; } break; + default: + break; + } + if (ypos < 0) + ypos = 0; + if (ypos != oldypos) + refreshentries = TRUE; +} + + +/*-----------------------------------------------------------------------*/ +/* + Free file entries +*/ +static struct dirent **files_free(struct dirent **files) +{ + int i; + if (files != NULL) + { + for(i=0; i= FILENAME_MAX) - { - fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); - free(pStringMem); - return FALSE; - } - - /* Free old allocated memory: */ - if (files != NULL) - { - for(i=0; i=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+yposd_name); + if (!strcat_maxlen(tempstr, FILENAME_MAX, + zipdir, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name)) + { + fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); + free(pStringMem); + return FALSE; + } + /* directory? */ if (File_DoesFileNameEndWithSlash(tempstr)) { /* handle the ../ directory */ - if(strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0) + if (strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0) { /* close the zip file */ - if( strcmp(tempstr, "../") == 0 ) + if (strcmp(tempstr, "../") == 0) { - reloaddir = refreshentries = TRUE; /* free zip file entries */ ZIP_FreeZipDir(zipfiles); zipfiles = NULL; @@ -422,16 +488,9 @@ int SDLGui_FileSelect(char *path_and_nam } else { - i=strlen(tempstr)-1; - n=0; - while(i > 0 && n < 3) - if (tempstr[i--] == PATHSEP) - n++; - if (tempstr[i+1] == PATHSEP) - tempstr[i+2] = '\0'; - else - tempstr[0] = '\0'; - + /* remove "../" and previous dir from path */ + File_PathShorten(tempstr, 2); + correct_zip_root(tempstr); strcpy(zipdir, tempstr); File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE); } @@ -447,48 +506,33 @@ int SDLGui_FileSelect(char *path_and_nam zipfilename[0] = '\0'; dlgfname[0] = 0; ypos = 0; - } else { - /* Select a file in the zip */ + /* not dir, select a file in the zip */ selection = retbut-SGFSDLG_ENTRY1+ypos; strcpy(zipfilename, files[selection]->d_name); File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE); } - } /* if browsingzip */ - else + } + else /* not browsingzip */ { - strcpy(tempstr, path); - strcat(tempstr, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name); - if( stat(tempstr, &filestat)==0 && S_ISDIR(filestat.st_mode) ) + if (!strcat_maxlen(tempstr, FILENAME_MAX, + path, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name)) { - /* Set the new directory */ + fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); + free(pStringMem); + return FALSE; + } + if (stat(tempstr, &filestat) == 0 && S_ISDIR(filestat.st_mode)) + { + File_HandleDotDirs(tempstr); + File_AddSlashToEndFileName(tempstr); + /* Copy the path name to the dialog */ + File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE); strcpy(path, tempstr); - if( strlen(path)>=3 ) - { - if (path[strlen(path)-2] == PATHSEP && path[strlen(path)-1]=='.') - path[strlen(path)-2] = 0; /* Strip a single dot at the end of the path name */ - if (path[strlen(path)-3] == PATHSEP && path[strlen(path)-2]=='.' && path[strlen(path)-1]=='.') - { - /* Handle the ".." folder */ - char *ptr; - if( strlen(path)==3 ) - path[1] = 0; - else - { - path[strlen(path)-3] = 0; - ptr = strrchr(path, PATHSEP); - if(ptr) - *(ptr+1) = 0; - } - } - } - File_AddSlashToEndFileName(path); reloaddir = TRUE; - /* Copy the path name to the dialog */ - File_ShrinkName(dlgpath, path, DLGPATH_SIZE); selection = -1; /* Remove old selection */ dlgfname[0] = 0; ypos = 0; @@ -497,15 +541,15 @@ int SDLGui_FileSelect(char *path_and_nam { /* open a zip file */ zipfiles = ZIP_GetFiles(tempstr); - if( zipfiles != NULL && browsingzip == FALSE ) + if (zipfiles != NULL && browsingzip == FALSE) { selection = retbut-SGFSDLG_ENTRY1+ypos; strcpy(fname, files[selection]->d_name); File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE); - browsingzip=TRUE; - strcpy(zipdir, ""); + browsingzip = TRUE; + zipdir[0] = '\0'; /* zip root */ File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE); - reloaddir = refreshentries = TRUE; + reloaddir = TRUE; ypos = 0; } @@ -528,63 +572,37 @@ int SDLGui_FileSelect(char *path_and_nam { case SGFSDLG_UPDIR: /* Change path to parent directory */ - if( browsingzip ) + if (browsingzip) { - /* close the zip file */ - if( strcmp(zipdir, "") == 0 ) + /* close the zip file? */ + if (!zipdir[0]) { - reloaddir = refreshentries = TRUE; /* free zip file entries */ ZIP_FreeZipDir(zipfiles); + browsingzip = FALSE; zipfiles = NULL; - /* Copy the path name to the dialog */ File_ShrinkName(dlgpath, path, DLGPATH_SIZE); - browsingzip = FALSE; - reloaddir = TRUE; - selection = -1; /* Remove old selection */ - fname[0] = 0; - dlgfname[0] = 0; - ypos = 0; } else { - i=strlen(zipdir)-1; - n=0; - while(i > 0 && n < 2) - if (zipdir[i--] == PATHSEP) - n++; - if (zipdir[i+1] == PATHSEP) - zipdir[i+2] = '\0'; - else - zipdir[0] = '\0'; - + /* remove last dir from zipdir path */ + File_PathShorten(zipdir, 1); + correct_zip_root(zipdir); File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE); - reloaddir = TRUE; - selection = -1; /* Remove old selection */ zipfilename[0] = '\0'; - dlgfname[0] = 0; - ypos = 0; } } /* not a zip file: */ - else if( strlen(path)>2 ) + else { - char *ptr; - File_CleanFileName(path); - ptr = strrchr(path, PATHSEP); - if(ptr) - *(ptr+1) = 0; - File_AddSlashToEndFileName(path); - reloaddir = TRUE; - File_ShrinkName(dlgpath, path, DLGPATH_SIZE); /* Copy the path name to the dialog */ - selection = -1; /* Remove old selection */ - fname[0] = 0; - dlgfname[0] = 0; - ypos = 0; + File_PathShorten(path, 1); + File_ShrinkName(dlgpath, path, DLGPATH_SIZE); } + reloaddir = TRUE; break; case SGFSDLG_HOMEDIR: /* Change to home directory */ - if (getenv("HOME") == NULL) + home = getenv("HOME"); + if (home == NULL) break; if (browsingzip) { @@ -593,32 +611,23 @@ int SDLGui_FileSelect(char *path_and_nam zipfiles = NULL; browsingzip = FALSE; } - strcpy(path, getenv("HOME")); + strcpy(path, home); File_AddSlashToEndFileName(path); + File_ShrinkName(dlgpath, path, DLGPATH_SIZE); reloaddir = TRUE; - strcpy(dlgpath, path); - selection = -1; /* Remove old selection */ - fname[0] = 0; - dlgfname[0] = 0; - ypos = 0; break; case SGFSDLG_ROOTDIR: /* Change to root directory */ - if( browsingzip ) + if (browsingzip) { /* free zip file entries */ ZIP_FreeZipDir(zipfiles); zipfiles = NULL; browsingzip = FALSE; } - strcpy(path, "/"); - reloaddir = TRUE; strcpy(dlgpath, path); - selection = -1; /* Remove old selection */ - fname[0] = 0; - dlgfname[0] = 0; - ypos = 0; + reloaddir = TRUE; break; case SGFSDLG_UP: /* Scroll up */ DlgFileSelect_ScrollUp(); @@ -639,27 +648,26 @@ int SDLGui_FileSelect(char *path_and_nam DlgFileSelect_HandleSdlEvents(&sdlEvent); break; } /* switch */ + + if (reloaddir) + { + /* Remove old selection */ + selection = -1; + fname[0] = 0; + dlgfname[0] = 0; + ypos = 0; + } } /* other button code */ } /* do */ - while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL && retbut!=SDLGUI_QUIT && !bQuitProgram); + while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL + && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram); if (oldcursorstate == SDL_DISABLE) SDL_ShowCursor(SDL_DISABLE); - File_makepath(path_and_name, path, fname, NULL); - - /* Free old allocated memory: */ - if (files != NULL) - { - for(i=0; i