--- hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:12:22 1.1.1.2 +++ hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:13:16 1.1.1.3 @@ -6,14 +6,14 @@ A file selection dialog for the graphical user interface for Hatari. */ -char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.2 2019/04/01 07:12:22 root Exp $"; +const char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.3 2019/04/01 07:13:16 root Exp $"; #include #include #include -#include #include "main.h" +#include "scandir.h" #include "sdlgui.h" #include "file.h" #include "zip.h" @@ -24,13 +24,15 @@ char DlgFileSelect_rcsid[] = "Hatari $Id #define SGFSDLG_FILENAME 5 #define SGFSDLG_UPDIR 6 -#define SGFSDLG_ROOTDIR 7 -#define SGFSDLG_ENTRY1 10 -#define SGFSDLG_ENTRY16 25 -#define SGFSDLG_UP 26 -#define SGFSDLG_DOWN 27 -#define SGFSDLG_OKAY 28 -#define SGFSDLG_CANCEL 29 +#define SGFSDLG_HOMEDIR 7 +#define SGFSDLG_ROOTDIR 8 +#define SGFSDLG_ENTRY1 11 +#define SGFSDLG_ENTRY16 26 +#define SGFSDLG_UP 27 +#define SGFSDLG_DOWN 28 +#define SGFSDLG_SHOWHIDDEN 29 +#define SGFSDLG_OKAY 30 +#define SGFSDLG_CANCEL 31 #define DLGPATH_SIZE 62 @@ -51,7 +53,8 @@ static SGOBJ fsdlg[] = { SGTEXT, 0, 0, 1,3, DLGPATH_SIZE,1, dlgpath }, { SGTEXT, 0, 0, 1,4, 6,1, "File:" }, { SGTEXT, 0, 0, 7,4, DLGFNAME_SIZE,1, dlgfname }, - { SGBUTTON, 0, 0, 55,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 51,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 56,1, 3,1, "~" }, { SGBUTTON, 0, 0, 60,1, 3,1, "/" }, { SGBOX, 0, 0, 1,6, 62,16, NULL }, { SGBOX, 0, 0, 62,7, 1,14, NULL }, @@ -73,8 +76,9 @@ static SGOBJ fsdlg[] = { SGTEXT, SG_EXIT, 0, 2,21, DLGFILENAMES_SIZE,1, dlgfilenames[15] }, { SGBUTTON, SG_TOUCHEXIT, 0, 62,6, 1,1, "\x01" }, /* Arrow up */ { SGBUTTON, SG_TOUCHEXIT, 0, 62,21, 1,1, "\x02" }, /* Arrow down */ - { SGBUTTON, 0, 0, 14,23, 8,1, "Okay" }, - { SGBUTTON, 0, 0, 34,23, 8,1, "Cancel" }, + { 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" }, { -1, 0, 0, 0,0, 0,0, NULL } }; @@ -116,7 +120,7 @@ static int DlgFileSelect_RefreshEntries( if( browsingzip ) { - if( tempstr[strlen(tempstr)-1] == '/' ) + if (File_DoesFileNameEndWithSlash(tempstr)) dlgfilenames[i][0] = SGFOLDER; /* Mark folders */ } else @@ -138,6 +142,51 @@ static int DlgFileSelect_RefreshEntries( /*-----------------------------------------------------------------------*/ /* + Remove all hidden files (files with file names that begin with a dot) from + the list. +*/ +static void DlgFileSelect_RemoveHiddenFiles(struct dirent **files) +{ + int i; + int nActPos = -1; + int nOldEntries; + + nOldEntries = entries; + + /* Scan list for hidden files and remove them. */ + for (i = 0; i < nOldEntries; i++) + { + /* Does file name start with a dot? -> hidden file! */ + if (files[i]->d_name[0] == '.') + { + if (nActPos == -1) + nActPos = i; + /* Remove file from list: */ + free(files[i]); + files[i] = NULL; + entries -= 1; + } + } + + /* Now close the gaps in the list: */ + if (nActPos != -1) + { + for (i = nActPos; i < nOldEntries; i++) + { + if (files[i] != NULL) + { + /* Move entry to earlier position: */ + files[nActPos] = files[i]; + files[i] = NULL; + nActPos += 1; + } + } + } +} + + +/*-----------------------------------------------------------------------*/ +/* Prepare to scroll up one entry. */ static void DlgFileSelect_ScrollUp(void) @@ -213,6 +262,8 @@ static void DlgFileSelect_HandleSdlEvent input: zip_path = pointer to buffer to contain file path within a selected zip file, or NULL if browsing zip files is disallowed. bAllowNew: TRUE if the user is allowed to insert new file names. + + TODO: This function urgently needs refactoring... it's way too big! */ int SDLGui_FileSelect(char *path_and_name, char *zip_path, BOOL bAllowNew) { @@ -304,6 +355,12 @@ int SDLGui_FileSelect(char *path_and_nam /* Load directory entries: */ entries = scandir(path, &files, 0, alphasort); } + + /* Remove hidden files from the list if necessary: */ + if (!(fsdlg[SGFSDLG_SHOWHIDDEN].state & SG_SELECTED)) + { + DlgFileSelect_RemoveHiddenFiles(files); + } if (entries < 0) { @@ -347,7 +404,7 @@ int SDLGui_FileSelect(char *path_and_nam { strcpy(tempstr, zipdir); strcat(tempstr, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name); - if(tempstr[strlen(tempstr)-1] == '/') + if (File_DoesFileNameEndWithSlash(tempstr)) { /* handle the ../ directory */ if(strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0) @@ -368,9 +425,9 @@ int SDLGui_FileSelect(char *path_and_nam i=strlen(tempstr)-1; n=0; while(i > 0 && n < 3) - if( tempstr[i--] == '/' ) + if (tempstr[i--] == PATHSEP) n++; - if(tempstr[i+1] == '/') + if (tempstr[i+1] == PATHSEP) tempstr[i+2] = '\0'; else tempstr[0] = '\0'; @@ -411,9 +468,9 @@ int SDLGui_FileSelect(char *path_and_nam strcpy(path, tempstr); if( strlen(path)>=3 ) { - if(path[strlen(path)-2]=='/' && path[strlen(path)-1]=='.') + 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]=='/' && path[strlen(path)-2]=='.' && path[strlen(path)-1]=='.') + if (path[strlen(path)-3] == PATHSEP && path[strlen(path)-2]=='.' && path[strlen(path)-1]=='.') { /* Handle the ".." folder */ char *ptr; @@ -422,7 +479,7 @@ int SDLGui_FileSelect(char *path_and_nam else { path[strlen(path)-3] = 0; - ptr = strrchr(path, '/'); + ptr = strrchr(path, PATHSEP); if(ptr) *(ptr+1) = 0; } @@ -494,9 +551,9 @@ int SDLGui_FileSelect(char *path_and_nam i=strlen(zipdir)-1; n=0; while(i > 0 && n < 2) - if( zipdir[i--] == '/' ) + if (zipdir[i--] == PATHSEP) n++; - if(zipdir[i+1] == '/') + if (zipdir[i+1] == PATHSEP) zipdir[i+2] = '\0'; else zipdir[0] = '\0'; @@ -513,7 +570,7 @@ int SDLGui_FileSelect(char *path_and_nam { char *ptr; File_CleanFileName(path); - ptr = strrchr(path, '/'); + ptr = strrchr(path, PATHSEP); if(ptr) *(ptr+1) = 0; File_AddSlashToEndFileName(path); @@ -525,6 +582,27 @@ int SDLGui_FileSelect(char *path_and_nam ypos = 0; } break; + + case SGFSDLG_HOMEDIR: /* Change to home directory */ + if (getenv("HOME") == NULL) + break; + if (browsingzip) + { + /* free zip file entries */ + ZIP_FreeZipDir(zipfiles); + zipfiles = NULL; + browsingzip = FALSE; + } + strcpy(path, getenv("HOME")); + File_AddSlashToEndFileName(path); + 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 ) { @@ -553,6 +631,10 @@ int SDLGui_FileSelect(char *path_and_nam case SGFSDLG_FILENAME: /* User entered new filename */ strcpy(fname, dlgfname); break; + case SGFSDLG_SHOWHIDDEN: /* Show/hide hidden files */ + reloaddir = TRUE; + ypos = 0; + break; case SDLGUI_UNKNOWNEVENT: DlgFileSelect_HandleSdlEvents(&sdlEvent); break;