From c40cc8283fab237bf363c91924e7bffb52e0b483 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 2 Jul 2023 02:12:26 -0500 Subject: [PATCH] IGFD: fix files with non-ASCII chars not have type on Windows --- extern/igfd/ImGuiFileDialog.cpp | 44 +++++++++++++++++++++++++++++---- extern/igfd/ImGuiFileDialog.h | 2 +- extern/igfd/dirent/dirent.h | 17 +++++++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/extern/igfd/ImGuiFileDialog.cpp b/extern/igfd/ImGuiFileDialog.cpp index 752f41005..b3d0212c9 100644 --- a/extern/igfd/ImGuiFileDialog.cpp +++ b/extern/igfd/ImGuiFileDialog.cpp @@ -46,11 +46,11 @@ SOFTWARE. #include #endif // EMSCRIPTEN #ifdef WIN32 - #define stat _stat #define stricmp _stricmp #include #include "dirent/dirent.h" // directly open the dirent file attached to this lib #define PATH_SEP '\\' + #define PATH_SEP_STR "\\" #ifndef PATH_MAX #define PATH_MAX 260 #endif // PATH_MAX @@ -60,6 +60,7 @@ SOFTWARE. #include #include #define PATH_SEP '/' + #define PATH_SEP_STR "/" #endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) #include "imgui.h" @@ -1440,10 +1441,12 @@ namespace IGFD return fileNameExt; } - void IGFD::FileManager::AddFile(const FileDialogInternal& vFileDialogInternal, const std::string& vPath, const std::string& vFileName, const char& vFileType) + void IGFD::FileManager::AddFile(const FileDialogInternal& vFileDialogInternal, const std::string& vPath, const std::string& vFileName, const char& vFileType, void* ent) { auto infos = std::make_shared(); + struct dirent* dent=(struct dirent*)ent; + infos->filePath = vPath; infos->fileNameExt = vFileName; infos->fileNameExt_optimized = prOptimizeFilenameForSearchOperations(infos->fileNameExt); @@ -1473,6 +1476,24 @@ namespace IGFD } } +#ifdef _WIN32 + SYSTEMTIME systemTime; + SYSTEMTIME localTime; + char timebuf[100]; + + infos->fileSize=dent->dwin_size; + if (FileTimeToSystemTime(&dent->dwin_mtime,&systemTime)==TRUE) { + if (SystemTimeToTzSpecificLocalTime(NULL,&systemTime,&localTime)==TRUE) { + snprintf(timebuf,99,"%d/%.2d/%.2d %.2d:%.2d",localTime.wYear,localTime.wMonth,localTime.wDay,localTime.wHour,localTime.wMinute); + } else { + snprintf(timebuf,99,"%d/%.2d/%.2d %.2d:%.2d",systemTime.wYear,systemTime.wMonth,systemTime.wDay,systemTime.wHour,systemTime.wMinute); + } + infos->fileModifDate=timebuf; + } else { + infos->fileModifDate="???"; + } +#endif + vFileDialogInternal.puFilterManager.prFillFileStyle(infos); prCompleteFileInfos(infos); @@ -1510,9 +1531,9 @@ namespace IGFD for (i = 0; i < n; i++) { struct dirent* ent = files[i]; - std::string where = path + std::string("/") + std::string(ent->d_name); + std::string where = path + std::string(PATH_SEP_STR) + std::string(ent->d_name); char fileType = 0; -#ifdef HAVE_DIRENT_TYPE +#if defined(HAVE_DIRENT_TYPE) || defined(_WIN32) if (ent->d_type != DT_UNKNOWN) { switch (ent->d_type) @@ -1522,6 +1543,9 @@ namespace IGFD case DT_DIR: fileType = 'd'; break; case DT_LNK: +#ifdef _WIN32 + fileType = 'f'; +#else DIR* dirTest = opendir(where.c_str()); if (dirTest == NULL) { @@ -1539,12 +1563,14 @@ namespace IGFD fileType = 'd'; closedir(dirTest); } +#endif break; } } else #endif // HAVE_DIRENT_TYPE { +#ifndef _WIN32 struct stat filestat; if (stat(where.c_str(), &filestat) == 0) { @@ -1557,11 +1583,12 @@ namespace IGFD fileType = 'f'; } } +#endif } auto fileNameExt = ent->d_name; - AddFile(vFileDialogInternal, path, fileNameExt, fileType); + AddFile(vFileDialogInternal, path, fileNameExt, fileType, ent); } for (i = 0; i < n; i++) @@ -1744,6 +1771,12 @@ namespace IGFD //time_t st_mtime; /* time of last modification - not sure out of ntfs */ //time_t st_ctime; /* time of last status change - not sure out of ntfs */ +#ifdef _WIN32 + if (vInfos->fileType != 'd') + { + vInfos->formatedFileSize = prFormatFileSize(vInfos->fileSize); + } +#else std::string fpn; if (vInfos->fileType == 'f' || vInfos->fileType == 'l' || vInfos->fileType == 'd') // file @@ -1778,6 +1811,7 @@ namespace IGFD vInfos->formatedFileSize = prFormatFileSize(vInfos->fileSize); vInfos->fileModifDate="???"; } +#endif } } diff --git a/extern/igfd/ImGuiFileDialog.h b/extern/igfd/ImGuiFileDialog.h index 5ab7f6c84..93db26e9d 100644 --- a/extern/igfd/ImGuiFileDialog.h +++ b/extern/igfd/ImGuiFileDialog.h @@ -883,7 +883,7 @@ namespace IGFD void prRemoveFileNameInSelection(const std::string& vFileName); // selection : remove a file name void prAddFileNameInSelection(const std::string& vFileName, bool vSetLastSelectionFileName); // selection : add a file name void AddFile(const FileDialogInternal& vFileDialogInternal, - const std::string& vPath, const std::string& vFileName, const char& vFileType); // add file called by scandir + const std::string& vPath, const std::string& vFileName, const char& vFileType, void* ent); // add file called by scandir public: FileManager(); diff --git a/extern/igfd/dirent/dirent.h b/extern/igfd/dirent/dirent.h index 0549aa27e..35d948a6f 100644 --- a/extern/igfd/dirent/dirent.h +++ b/extern/igfd/dirent/dirent.h @@ -237,6 +237,10 @@ struct _wdirent { /* File name */ wchar_t d_name[PATH_MAX+1]; + + /* Windows extensions */ + size_t dwin_size; + FILETIME dwin_mtime; }; typedef struct _wdirent _wdirent; @@ -277,6 +281,10 @@ struct dirent { /* File name */ char d_name[PATH_MAX+1]; + + /* Windows extensions */ + size_t dwin_size; + FILETIME dwin_mtime; }; typedef struct dirent dirent; @@ -516,6 +524,9 @@ _wreaddir_r( entry->d_off = 0; entry->d_reclen = sizeof (struct _wdirent); + entry->dwin_size = ((size_t)datap->nFileSizeHigh<<32) | datap->nFileSizeLow; + entry->dwin_mtime = datap->ftLastWriteTime; + /* Set result address */ *result = entry; @@ -806,6 +817,9 @@ readdir_r( entry->d_off = 0; entry->d_reclen = sizeof (struct dirent); + entry->dwin_size = ((size_t)datap->nFileSizeHigh<<32) | datap->nFileSizeLow; + entry->dwin_mtime = datap->ftLastWriteTime; + } else { /* @@ -821,6 +835,9 @@ readdir_r( entry->d_ino = 0; entry->d_off = -1; entry->d_reclen = 0; + entry->dwin_size = 0; + entry->dwin_mtime.dwHighDateTime = 0; + entry->dwin_mtime.dwLowDateTime = 0; }