Skip to content

Commit 26cda85

Browse files
committed
[FIX] : size and date was not retrieved for file pata name with non utf8 chars (#202)
[ADD] : add a new method in IFileSystem interface for retrieve file size and date (#202)
1 parent 8c36b67 commit 26cda85

2 files changed

Lines changed: 87 additions & 45 deletions

File tree

ImGuiFileDialog.cpp

Lines changed: 84 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ SOFTWARE.
6666
defined(_WIN64) || \
6767
defined(_MSC_VER)
6868
#define _IGFD_WIN_
69-
#define stat _stati64
69+
#define stat _wstat64
7070
#define stricmp _stricmp
7171
#include <cctype>
7272
// this option need c++17
@@ -601,6 +601,26 @@ class FileSystemStd : public IGFD::IFileSystem {
601601
namespace fs = std::filesystem;
602602
return fs::is_directory(stringToPath(vFilePathName));
603603
}
604+
void GetFileDateAndSize(const std::string& vFilePathName, const IGFD::FileType& vFileType, std::string& voDate, size_t& voSize) override {
605+
namespace fs = std::filesystem;
606+
fs::path fpath(vFilePathName);
607+
try {
608+
// date
609+
size_t len{};
610+
const auto lastWriteTime = fs::last_write_time(fpath);
611+
const auto cftime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + (lastWriteTime - fs::file_time_type::clock::now()));
612+
static char timebuf[100];
613+
std::strftime(timebuf, sizeof(timebuf), DateTimeFormat, std::localtime(&cftime));
614+
voDate = timebuf;
615+
// size
616+
if (!vFileType.isDir()) {
617+
voSize = fs::file_size(fpath);
618+
}
619+
} catch (const fs::filesystem_error& e) {
620+
voSize = 0;
621+
voDate.clear();
622+
}
623+
}
604624
};
605625
#define FILE_SYSTEM_OVERRIDE FileSystemStd
606626
#else
@@ -800,6 +820,40 @@ class FileSystemDirent : public IGFD::IFileSystem {
800820
}
801821
return false;
802822
}
823+
void GetFileDateAndSize(const std::string& vFilePathName, const IGFD::FileType& vFileType, std::string& voDate, size_t& voSize) override {
824+
struct stat statInfos = {};
825+
#ifdef _IGFD_WIN_
826+
std::wstring wfpn = IGFD::Utils::UTF8Decode(vFilePathName);
827+
struct _stat64 wstatInfos{};
828+
const auto result = stat(wfpn.c_str(), &wstatInfos);
829+
if (!result) {
830+
statInfos.st_size = wstatInfos.st_size;
831+
statInfos.st_mtime = wstatInfos.st_mtime;
832+
}
833+
#else
834+
result = stat(vFilePathName.c_str(), &statInfos);
835+
#endif
836+
static char timebuf[100];
837+
if (!result) {
838+
// date
839+
size_t len = 0;
840+
#ifdef _MSC_VER
841+
struct tm _tm;
842+
errno_t err = localtime_s(&_tm, &statInfos.st_mtime);
843+
if (!err) len = strftime(timebuf, 99, DateTimeFormat, &_tm);
844+
#else // _MSC_VER
845+
struct tm* _tm = localtime(&statInfos.st_mtime);
846+
if (_tm) len = strftime(timebuf, 99, DateTimeFormat, _tm);
847+
#endif // _MSC_VER
848+
if (len) {
849+
voDate = std::string(timebuf, len);
850+
}
851+
// size
852+
if (!vFileType.isDir()) {
853+
voSize = (size_t)statInfos.st_size;
854+
}
855+
}
856+
}
803857
};
804858
#define FILE_SYSTEM_OVERRIDE FileSystemDirent
805859
#endif // USE_STD_FILESYSTEM
@@ -2207,51 +2261,37 @@ void IGFD::FileManager::m_ApplyFilteringOnFileList(const FileDialogInternal& vFi
22072261
void IGFD::FileManager::m_CompleteFileInfos(const std::shared_ptr<FileInfos>& vInfos) {
22082262
if (!vInfos.use_count()) return;
22092263

2210-
if (vInfos->fileNameExt != "." && vInfos->fileNameExt != "..") {
2211-
// _stat struct :
2212-
// dev_t st_dev; /* ID of device containing file */
2213-
// ino_t st_ino; /* inode number */
2214-
// mode_t st_mode; /* protection */
2215-
// nlink_t st_nlink; /* number of hard links */
2216-
// uid_t st_uid; /* user ID of owner */
2217-
// gid_t st_gid; /* group ID of owner */
2218-
// dev_t st_rdev; /* device ID (if special file) */
2219-
// off_t st_size; /* total size, in bytes */
2220-
// blksize_t st_blksize; /* blocksize for file system I/O */
2221-
// blkcnt_t st_blocks; /* number of 512B blocks allocated */
2222-
// time_t st_atime; /* time of last access - not sure out of ntfs */
2223-
// time_t st_mtime; /* time of last modification - not sure out of ntfs */
2224-
// time_t st_ctime; /* time of last status change - not sure out of ntfs */
2225-
2226-
std::string fpn;
2227-
2228-
// FIXME: so the condition is always true?
2229-
if (vInfos->fileType.isFile() || vInfos->fileType.isLinkToUnknown() || vInfos->fileType.isDir()) {
2230-
fpn = vInfos->filePath + IGFD::Utils::GetPathSeparator() + vInfos->fileNameExt;
2231-
}
2264+
if ((vInfos->fileNameExt == ".") || // current dir (special case, not really a dir or a file)
2265+
(vInfos->fileNameExt == "..")) { // last dir (special case, not really a dir or a file)
2266+
return;
2267+
}
22322268

2233-
struct stat statInfos = {};
2234-
char timebuf[100];
2235-
int result = stat(fpn.c_str(), &statInfos);
2236-
if (!result) {
2237-
if (!vInfos->fileType.isDir()) {
2238-
vInfos->fileSize = (size_t)statInfos.st_size;
2239-
vInfos->formatedFileSize = IGFD::Utils::FormatFileSize(vInfos->fileSize);
2240-
}
2269+
// _stat struct :
2270+
// dev_t st_dev; /* ID of device containing file */
2271+
// ino_t st_ino; /* inode number */
2272+
// mode_t st_mode; /* protection */
2273+
// nlink_t st_nlink; /* number of hard links */
2274+
// uid_t st_uid; /* user ID of owner */
2275+
// gid_t st_gid; /* group ID of owner */
2276+
// dev_t st_rdev; /* device ID (if special file) */
2277+
// off_t st_size; /* total size, in bytes */
2278+
// blksize_t st_blksize; /* blocksize for file system I/O */
2279+
// blkcnt_t st_blocks; /* number of 512B blocks allocated */
2280+
// time_t st_atime; /* time of last access - not sure out of ntfs */
2281+
// time_t st_mtime; /* time of last modification - not sure out of ntfs */
2282+
// time_t st_ctime; /* time of last status change - not sure out of ntfs */
22412283

2242-
size_t len = 0;
2243-
#ifdef _MSC_VER
2244-
struct tm _tm;
2245-
errno_t err = localtime_s(&_tm, &statInfos.st_mtime);
2246-
if (!err) len = strftime(timebuf, 99, DateTimeFormat, &_tm);
2247-
#else // _MSC_VER
2248-
struct tm* _tm = localtime(&statInfos.st_mtime);
2249-
if (_tm) len = strftime(timebuf, 99, DateTimeFormat, _tm);
2250-
#endif // _MSC_VER
2251-
if (len) {
2252-
vInfos->fileModifDate = std::string(timebuf, len);
2253-
}
2254-
}
2284+
std::string fpn;
2285+
2286+
// FIXME: so the condition is always true?
2287+
if (vInfos->fileType.isFile() || vInfos->fileType.isLinkToUnknown() || vInfos->fileType.isDir()) {
2288+
fpn = vInfos->filePath + IGFD::Utils::GetPathSeparator() + vInfos->fileNameExt;
2289+
}
2290+
2291+
m_FileSystemPtr->GetFileDateAndSize(fpn, vInfos->fileType, vInfos->fileModifDate, vInfos->fileSize);
2292+
2293+
if (!vInfos->fileType.isDir()) {
2294+
vInfos->formatedFileSize = IGFD::Utils::FormatFileSize(vInfos->fileSize);
22552295
}
22562296
}
22572297

ImGuiFileDialog.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,8 @@ class IFileSystem {
528528
virtual bool IsDirectory(const std::string& vFilePathName) = 0;
529529
// return a device list (<path, device name>) on windows, but can be used on other platforms for give to the user a list of devices paths.
530530
virtual std::vector<IGFD::PathDisplayedName> GetDevicesList() = 0;
531+
// return via argument the date and the size of a file (for solve issue regarding apis and widechars)
532+
virtual void GetFileDateAndSize(const std::string& vFilePathName, const IGFD::FileType& vFileType, std::string& voDate, size_t& voSize) = 0;
531533
};
532534

533535
class IGFD_API FileManager {
@@ -587,7 +589,7 @@ class IGFD_API FileManager {
587589
std::string fsRoot;
588590

589591
private:
590-
static void m_CompleteFileInfos(const std::shared_ptr<FileInfos>& vInfos); // set time and date infos of a file (detail view mode)
592+
void m_CompleteFileInfos(const std::shared_ptr<FileInfos>& vInfos); // set time and date infos of a file (detail view mode)
591593
void m_RemoveFileNameInSelection(const std::string& vFileName); // selection : remove a file name
592594
void m_AddFileNameInSelection(const std::string& vFileName, bool vSetLastSelectionFileName); // selection : add a file name
593595
void m_AddFile(const FileDialogInternal& vFileDialogInternal, const std::string& vPath, const std::string& vFileName,

0 commit comments

Comments
 (0)