feat: filesystem and Files app support for >64 file entries, 64-bit sizes, async ops, GUI toolkit improvements to devexplorer app
This commit is contained in:
@@ -8,34 +8,25 @@
|
||||
|
||||
namespace filemanager {
|
||||
|
||||
static bool path_is_same_or_descendant(const char* path, const char* root) {
|
||||
if (!path || !root) return false;
|
||||
|
||||
int root_len = montauk::slen(root);
|
||||
while (root_len > 0 && root[root_len - 1] == '/') root_len--;
|
||||
if (root_len <= 0) return false;
|
||||
|
||||
for (int i = 0; i < root_len; i++) {
|
||||
if (path[i] == '\0' || path[i] != root[i]) return false;
|
||||
}
|
||||
return path[root_len] == '\0' || path[root_len] == '/';
|
||||
}
|
||||
|
||||
static void filemanager_load_clipboard(FileManagerState* fm, bool is_cut) {
|
||||
if (filemanager_is_computer_view(fm) || filemanager_is_virtual_view(fm)) return;
|
||||
if (fm->entry_count <= 0) return;
|
||||
|
||||
int sel[64];
|
||||
int n = filemanager_collect_selection(fm, sel, 64);
|
||||
if (n <= 0) return;
|
||||
int* sel = (int*)montauk::malloc((uint64_t)fm->entry_count * sizeof(int));
|
||||
if (!sel) return;
|
||||
int n = filemanager_collect_selection(fm, sel, fm->entry_count);
|
||||
if (n <= 0) { montauk::mfree(sel); return; }
|
||||
if (!filemanager_ensure_clipboard_capacity(fm, n)) { montauk::mfree(sel); return; }
|
||||
|
||||
int out = 0;
|
||||
for (int i = 0; i < n && out < 64; i++) {
|
||||
for (int i = 0; i < n && out < fm->clipboard_cap; i++) {
|
||||
int idx = sel[i];
|
||||
if (fm->entry_types[idx] == FM_ENTRY_DRIVE) continue;
|
||||
filemanager_build_fullpath(fm->clipboard_paths[out], 256,
|
||||
fm->current_path, fm->entry_names[idx]);
|
||||
out++;
|
||||
}
|
||||
montauk::mfree(sel);
|
||||
if (out == 0) return;
|
||||
|
||||
fm->clipboard_count = out;
|
||||
@@ -51,35 +42,9 @@ void filemanager_do_cut(FileManagerState* fm) {
|
||||
}
|
||||
|
||||
void filemanager_do_paste(FileManagerState* fm) {
|
||||
if (fm->clipboard_count <= 0 ||
|
||||
filemanager_is_computer_view(fm) || filemanager_is_virtual_view(fm)) return;
|
||||
|
||||
bool any_ok = false;
|
||||
bool clear_clipboard = fm->clipboard_is_cut;
|
||||
for (int i = 0; i < fm->clipboard_count; i++) {
|
||||
const char* src = fm->clipboard_paths[i];
|
||||
const char* basename = path_basename(src);
|
||||
char dst[512];
|
||||
filemanager_build_fullpath(dst, 512, fm->current_path, basename);
|
||||
if (montauk::streq(dst, src)) continue;
|
||||
|
||||
const char* probe[1];
|
||||
int probe_count = montauk::readdir(src, probe, 1);
|
||||
bool src_is_dir = (probe_count >= 0);
|
||||
if (src_is_dir && path_is_same_or_descendant(dst, src)) continue;
|
||||
|
||||
bool ok = src_is_dir ? filemanager_copy_dir_recursive(src, dst)
|
||||
: filemanager_copy_file(src, dst);
|
||||
any_ok = any_ok || ok;
|
||||
|
||||
if (ok && fm->clipboard_is_cut) {
|
||||
if (src_is_dir) filemanager_delete_recursive(src);
|
||||
else montauk::fdelete(src);
|
||||
}
|
||||
}
|
||||
|
||||
if (clear_clipboard) fm->clipboard_count = 0;
|
||||
if (any_ok) filemanager_read_dir(fm);
|
||||
// Copy/move runs on a worker thread with a progress dialog (a small single
|
||||
// file pastes inline). Same-volume moves use rename (instant, no copy).
|
||||
filemanager_start_paste_job(fm);
|
||||
}
|
||||
|
||||
void filemanager_start_rename(FileManagerState* fm) {
|
||||
@@ -157,13 +122,16 @@ void filemanager_new_folder(FileManagerState* fm) {
|
||||
|
||||
void filemanager_delete_selected(FileManagerState* fm) {
|
||||
if (filemanager_is_computer_view(fm) || filemanager_is_virtual_view(fm)) return;
|
||||
if (fm->entry_count <= 0) return;
|
||||
|
||||
int sel[64];
|
||||
int n = filemanager_collect_selection(fm, sel, 64);
|
||||
if (n <= 0) return;
|
||||
int* sel = (int*)montauk::malloc((uint64_t)fm->entry_count * sizeof(int));
|
||||
if (!sel) return;
|
||||
int n = filemanager_collect_selection(fm, sel, fm->entry_count);
|
||||
if (n <= 0) { montauk::mfree(sel); return; }
|
||||
|
||||
// Filter out drives.
|
||||
int filtered[64];
|
||||
int* filtered = (int*)montauk::malloc((uint64_t)n * sizeof(int));
|
||||
if (!filtered) { montauk::mfree(sel); return; }
|
||||
int fn = 0;
|
||||
bool any_dir = false;
|
||||
for (int i = 0; i < n; i++) {
|
||||
@@ -172,7 +140,8 @@ void filemanager_delete_selected(FileManagerState* fm) {
|
||||
filtered[fn++] = idx;
|
||||
if (fm->is_dir[idx]) any_dir = true;
|
||||
}
|
||||
if (fn == 0) return;
|
||||
montauk::mfree(sel);
|
||||
if (fn == 0) { montauk::mfree(filtered); return; }
|
||||
|
||||
// Anything with a directory or multi-item selection: confirm first.
|
||||
if (any_dir || fn > 1) {
|
||||
@@ -181,6 +150,7 @@ void filemanager_delete_selected(FileManagerState* fm) {
|
||||
} else {
|
||||
filemanager_show_bulk_delete_confirmation(fm, filtered, fn);
|
||||
}
|
||||
montauk::mfree(filtered);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,6 +158,7 @@ void filemanager_delete_selected(FileManagerState* fm) {
|
||||
char fullpath[512];
|
||||
filemanager_build_fullpath(fullpath, 512,
|
||||
fm->current_path, fm->entry_names[filtered[0]]);
|
||||
montauk::mfree(filtered);
|
||||
montauk::fdelete(fullpath);
|
||||
filemanager_clear_multi_selection(fm);
|
||||
filemanager_read_dir(fm);
|
||||
|
||||
Reference in New Issue
Block a user