--- a/application/davcontroller.c Tue Feb 06 19:01:52 2024 +0100 +++ b/application/davcontroller.c Wed Feb 07 17:10:01 2024 +0100 @@ -255,10 +255,18 @@ size_t uploaded_files; size_t uploaded_directories; + DavBool upload_file; + size_t current_file_size; + size_t current_file_upload; + + char *current_file_name; + UiObject *dialog; UiDouble *progress; - UiString *file_label; - UiString *speed_label; + UiString *label_top_left; + UiString *label_top_right; + UiString *label_bottom_left; + UiString *label_bottom_right; } DavFileUpload; typedef struct DUFile { @@ -274,6 +282,76 @@ return ((double)upload->uploaded_bytes / (double)upload->total_bytes) * 100; } +static void update_upload_labels(DavFileUpload *upload) { + char *sz_total = util_size_str(FALSE, upload->total_bytes); + char *sz_uploaded = util_size_str2(FALSE, upload->uploaded_bytes, upload->total_bytes, 2); + char *sz_uploaded_end = strchr(sz_uploaded, ' '); + if (sz_uploaded_end) { + *sz_uploaded_end = 0; + } + + cxmutstr label1 = cx_asprintf( + "%s/%s %zu/%zu files", + sz_uploaded, + sz_total, + upload->uploaded_files+upload->uploaded_directories, + upload->total_files+upload->total_directories); + ui_set(upload->label_top_left, label1.ptr); + + free(sz_total); + free(label1.ptr); + + + cxmutstr file_label = cx_asprintf("%s (%.0f%%)", upload->current_file_name, ((float)upload->current_file_upload/(float)upload->current_file_size)*100); + ui_set(upload->label_top_right, file_label.ptr); + + free(file_label.ptr); +} + +static int uithr_update_upload_labels(void *data) { + update_upload_labels(data); + return 0; +} + +static void upload_dav_progress(DavResource *res, int64_t total, int64_t now, void *data) { + DavFileUpload *upload = data; + if (upload->upload_file) { + if (now > upload->current_file_size) { + // current_file_size is not accurate (either the file was changed after the last stat + // or we have some extra bytes because of encryption + // adjust current_file_size and the total upload size + int64_t extra = now - upload->current_file_size; + upload->current_file_size += extra; + upload->total_bytes += extra; + } + + int64_t new_progress = now - upload->current_file_upload; + upload->uploaded_bytes += new_progress; + upload->current_file_upload = now; + + ui_call_mainthread(uithr_update_upload_labels, upload); + } +} + + +typedef struct FileNameUpdate { + DavFileUpload *upload; + char *name; +} FileNameUpdate; + +static int uithr_update_file_label(FileNameUpdate *update) { + // replace upload->current_filename with update->name + if (update->upload->current_file_name) { + free(update->upload->current_file_name); + } + update->upload->current_file_name = update->name; + + ui_set(update->upload->label_top_right, update->name); + + free(update); + return 0; +} + static int qthr_file_upload(void *data) { DUFile *f = data; DavFileUpload *upload = f->upload; @@ -285,7 +363,17 @@ return 0; } + upload->upload_file = TRUE; + upload->current_file_size = f->bytes; + upload->current_file_upload = 0; + DavResource *res = dav_resource_new(sn, f->upload_path); + + FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); + ui_update->upload = upload; + ui_update->name = strdup(res->name); + ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); + dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); if (dav_store(res)) { f->error = sn->error; @@ -294,6 +382,8 @@ fclose(in); + upload->upload_file = FALSE; + return 0; } @@ -302,11 +392,13 @@ DavFileUpload *upload = file->upload; upload->uploaded_files++; - upload->uploaded_bytes += file->bytes; + //upload->uploaded_bytes += file->bytes; double progress = upload_progress(upload); ui_set(upload->progress, upload_progress(upload)); + update_upload_labels(upload); + free(file->path); free(file->upload_path); } @@ -319,6 +411,11 @@ DavResource *res = dav_resource_new(sn, f->upload_path); res->iscollection = TRUE; + FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); + ui_update->upload = upload; + ui_update->name = strdup(res->name); + ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); + if (dav_create(res)) { f->error = sn->error; } @@ -334,6 +431,8 @@ upload->uploaded_directories++; + update_upload_labels(upload); + free(file->path); free(file->upload_path); } @@ -372,7 +471,7 @@ cxListRemove(stack, 0); SYS_STAT s; - if (!stat(f->path, &s)) { + if (!sys_stat(f->path, &s)) { if (S_ISDIR(s.st_mode)) { f->isdirectory = TRUE; upload->total_directories++; @@ -421,6 +520,8 @@ static void uithr_upload_scan_finished(UiEvent *event, void *data) { DavFileUpload *upload = data; + + update_upload_labels(upload); } @@ -437,6 +538,8 @@ DavFileUpload *upload = malloc(sizeof(DavFileUpload)); memset(upload, 0, sizeof(DavFileUpload)); + dav_session_set_progresscallback(upload_session, NULL, upload_dav_progress, upload); + upload->ui = ui; upload->browser = browser; upload->sn = upload_session; @@ -445,21 +548,34 @@ upload->queue = ui_threadpool_create(1); // create upload progress window - UiObject *dialog = ui_simple_window("Upload", upload); + cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path)); + UiObject *dialog = ui_simple_window(wtitle.ptr, upload); + free(wtitle.ptr); upload->dialog = dialog; - ui_window_size(dialog, 450, 120); + ui_window_size(dialog, 550, 120); upload->progress = ui_double_new(dialog->ctx, NULL); - upload->file_label = ui_string_new(dialog->ctx, NULL); - upload->speed_label = ui_string_new(dialog->ctx, NULL); + upload->label_top_left = ui_string_new(dialog->ctx, NULL); + upload->label_top_right = ui_string_new(dialog->ctx, NULL); + upload->label_bottom_left = ui_string_new(dialog->ctx, NULL); + upload->label_bottom_right = ui_string_new(dialog->ctx, NULL); - ui_vbox(dialog, .margin = 10, .spacing = 10) { - ui_llabel(dialog, .value = upload->file_label); - ui_progressbar(dialog, .value = upload->progress); - ui_llabel(dialog, .value = upload->speed_label); + ui_grid(dialog, .margin = 10, .spacing = 10, .fill = TRUE) { + ui_llabel(dialog, .value = upload->label_top_left, .hexpand = TRUE); + ui_rlabel(dialog, .value = upload->label_top_right); + ui_newline(dialog); + + ui_progressbar(dialog, .value = upload->progress, .colspan = 2, .hexpand = TRUE); + ui_newline(dialog); + + ui_llabel(dialog, .value = upload->label_bottom_left); + ui_rlabel(dialog, .value = upload->label_bottom_right); + ui_newline(dialog); } - ui_set(upload->file_label, ""); - ui_set(upload->speed_label, ""); + ui_set(upload->label_top_left, ""); + ui_set(upload->label_top_right, ""); + ui_set(upload->label_bottom_left, ""); + ui_set(upload->label_bottom_right, ""); ui_set(upload->progress, 0); ui_show(dialog);