--- a/application/davcontroller.c Thu Feb 08 10:35:07 2024 +0100 +++ b/application/davcontroller.c Fri Feb 09 16:50:23 2024 +0100 @@ -63,6 +63,7 @@ ui_list_clear(browser->resources); browser->current = collection; + browser->res_counter++; for (DavResource *res = collection->children; res; res = res->next) { ui_list_append(browser->resources, res); } @@ -267,6 +268,19 @@ UiString *label_top_right; UiString *label_bottom_left; UiString *label_bottom_right; + + // The collection, the files are uploaded to + // It is only safe to access the collection ptr, if + // collection == browser->current && collection_ctn == browser->res_counter + // and obviously it can only be accessed from the UI thread + DavResource *collection; + + // copy of browser->res_counter, used for integrity check + int64_t collection_ctn; + + // current uploaded resource, created as part of the browser session + // only if collection == browser->current && collection_ctn == browser->res_counter + DavResource *current_resource; } DavFileUpload; typedef struct DUFile { @@ -348,6 +362,8 @@ typedef struct FileNameUpdate { DavFileUpload *upload; char *name; + char *path; + DavBool iscollection; } FileNameUpdate; static int uithr_update_file_label(FileNameUpdate *update) { @@ -359,6 +375,37 @@ ui_set(update->upload->label_top_right, update->name); + DavFileUpload *upload = update->upload; + DavBrowser *browser = upload->browser; + // update the resource list in the browser, if the current collection has not changed + if (upload->collection == browser->current && upload->collection_ctn == browser->res_counter) { + char *parent = util_parent_path(update->path); + cxstring parent_s = cx_str(parent); + cxstring colpath_s = cx_str(upload->collection->path); + if (parent_s.length > 0 && parent_s.ptr[parent_s.length - 1] == '/') { + parent_s.length--; + } + if (colpath_s.length > 0 && colpath_s.ptr[colpath_s.length - 1] == '/') { + colpath_s.length--; + } + + // only update, if the added resource has the current collection as parent + if (!cx_strcmp(parent_s, colpath_s)) { + DavResource *ui_res = dav_resource_new(upload->collection->session, update->path); + ui_res->iscollection = update->iscollection; + ui_res->lastmodified = time(NULL); + ui_res->creationdate = time(NULL); + upload->current_resource = ui_res; + + ui_list_append(browser->resources, ui_res); + browser->resources->update(browser->resources, 0); + } else { + upload->current_resource = NULL; // maybe not necessary + } + free(parent); + } + + free(update->path); free(update); return 0; } @@ -383,6 +430,8 @@ FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); ui_update->upload = upload; ui_update->name = strdup(res->name); + ui_update->path = strdup(res->path); + ui_update->iscollection = FALSE; ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); @@ -410,6 +459,16 @@ update_upload_labels(upload); + // update resource content length in the browser + DavBrowser *browser = upload->browser; + if (upload->collection == browser->current && upload->collection_ctn == browser->res_counter) { + if (upload->current_resource) { + upload->current_resource->contentlength = upload->current_file_upload; + browser->resources->update(browser->resources, 0); + } + } + upload->current_resource = NULL; + free(file->path); free(file->upload_path); } @@ -425,6 +484,8 @@ FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); ui_update->upload = upload; ui_update->name = strdup(res->name); + ui_update->path = strdup(res->path); + ui_update->iscollection = TRUE; ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); if (dav_create(res)) { @@ -444,6 +505,8 @@ update_upload_labels(upload); + upload->current_resource = NULL; + free(file->path); free(file->upload_path); } @@ -561,6 +624,9 @@ upload->base_path = strdup(browser->current->path); upload->queue = ui_threadpool_create(1); + upload->collection = browser->current; + upload->collection_ctn = browser->res_counter; + // create upload progress window cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path)); UiObject *dialog = ui_simple_window(wtitle.ptr, upload); @@ -598,3 +664,62 @@ // start upload and stat threads ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload); } + + +// ------------------------------------- Path Operation (DELETE, MKCOL) ------------------------------------- + +enum DavPathOpType { + DAV_PATH_OP_DELETE = 0 +}; + +typedef struct DavPathOp { + enum DavPathOpType op; + DavSession *sn; + char **path; + size_t *list_indices; + size_t nelm; + DavResource *collection; + int64_t collection_ctn; +} DavPathOp; + +static int jobthr_path_op(void *data) { + DavPathOp *op = data; + + for (int i = 0; i < op->nelm; i++) { + if (op->path[i]) { + DavResource *res = dav_resource_new(op->sn, op->path[i]); + + int ret = 0; + if (op->op == DAV_PATH_OP_DELETE) { + ret = dav_delete(res); + } + + dav_resource_free(res); + } + } + + + return 0; +} + +void davbrowser_delete(UiObject *ui, DavBrowser *browser, UiListSelection selection) { + DavPathOp *op = malloc(sizeof(DavPathOp)); + op->op = DAV_PATH_OP_DELETE; + op->sn = dav_session_clone(browser->sn); + op->path = calloc(selection.count, sizeof(char*)); + op->list_indices = calloc(selection.count, sizeof(size_t)); + op->nelm = selection.count; + + op->collection = browser->current; + op->collection_ctn = browser->res_counter; + + for (int i = 0; i < selection.count; i++) { + DavResource *res = ui_list_get(browser->resources, selection.rows[i]); + if (res) { + op->path[i] = strdup(res->path); + op->list_indices[i] = selection.rows[i]; + } + } + + ui_job(ui, jobthr_path_op, op, NULL, NULL); +}