1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "file_dialog.hpp"
#include "imgui_context.hpp"
#include <imgui/imgui.h>
#include <spdlog/spdlog.h>
namespace bookmouse {
using fud::FudStatus;
DialogEntry::DialogEntry(fud::DirectoryEntry&& entry) :
fud::DirectoryEntry(std::move(entry)), timeInfo{}, niceTime{}, selected{false}, valid{false}, gotTime{false}
{
auto timeInfoPtr = localtime_r(&this->modificationTime, &timeInfo);
if (timeInfoPtr == nullptr) {
return;
}
valid = true;
}
FudStatus DialogEntry::formatTime(TimeFormat& format)
{
if (!valid) {
return FudStatus::ObjectInvalid;
}
auto result = format.format(this->timeInfo);
if (result.isError())
{
return result.getError();
}
this->niceTime = result.getOkay();
return FudStatus::Success;
}
FileDialog::FileDialog(
const fud::String& directoryName,
TimeFormat& timeFormat) : m_directoryName{directoryName},
m_directory{directoryName},
m_timeFormat{timeFormat}
{
auto status = getDirectoryContents();
if (status != FudStatus::Success) {
return;
}
}
FudStatus FileDialog::getDirectoryContents() {
auto directoryStatsResult = m_directory.info();
if (directoryStatsResult.isError()) {
return directoryStatsResult.getError();
}
auto directoryStats = directoryStatsResult.getOkay();
size_t count{0};
m_directoryContents.reserve(directoryStats.links);
while (true && count < SIZE_MAX) {
auto dirEntryResult = m_directory.getNextEntry();
if (dirEntryResult.isError()) {
break;
}
auto dirEntryOpt = dirEntryResult.getOkay();
if (dirEntryOpt == std::nullopt) {
break;
}
if (dirEntryOpt->inode == directoryStats.inode) {
continue;
}
m_directoryContents.emplace_back(std::move(*dirEntryOpt));
auto status = m_directoryContents.back().formatTime(m_timeFormat);
if (status != FudStatus::Success) {
spdlog::error("Could not convert time: {}", fud::FudStatusToString(status));
}
}
return FudStatus::Success;
}
FilePickerResult FileDialog::pickFiles()
{
ImText("%s %zu", m_directory.name().c_str(), m_directoryContents.size());
if (ImTable table{"Entries", 4, ImGuiTableFlags_Borders}) {
auto colFlags = ImGuiSelectableFlags_NoAutoClosePopups;
IM_ASSERT(table);
ImNextColumn();
ImSelectable("T", &m_typeSelected, colFlags);
ImNextColumn();
ImSelectable("Name", &m_nameSelectede, colFlags);
ImNextColumn();
ImSelectable("Size", &m_sizeSelected, colFlags);
ImNextColumn();
ImSelectable("Date", &m_dateSelected, colFlags);
for (auto& entry : m_directoryContents) {
ImNextRow();
const char entryLetter = DirEntryTypeToChar(entry.entryType);
ImNextColumn();
ImText("%c", entryLetter);
ImNextColumn();
ImSelectable(entry.name.c_str(), &entry.selected, colFlags | ImGuiSelectableFlags_SpanAllColumns);
ImNextColumn();
ImText("%zu\n", entry.isDirectory() ? entry.links : entry.size);
ImNextColumn();
ImText("%s", entry.niceTime.c_str());
}
}
if (ImButton("Accept")) {
return FilePickerResult::error(FudStatus::NotImplemented);
}
ImSameLine();
if (ImButton("Cancel")) {
return FilePickerResult::error(FudStatus::NotImplemented);
}
return FilePickerResult::error(FudStatus::NotImplemented);
}
} // namespace bookmouse
|