diff -r 40d6af793c1a -r c254ed644edf application/davcontroller.c --- a/application/davcontroller.c Fri Feb 09 16:50:23 2024 +0100 +++ b/application/davcontroller.c Sun Feb 11 13:59:02 2024 +0100 @@ -669,41 +669,117 @@ // ------------------------------------- Path Operation (DELETE, MKCOL) ------------------------------------- enum DavPathOpType { - DAV_PATH_OP_DELETE = 0 + DAV_PATH_OP_DELETE = 0, + DAV_PATH_OP_MKCOL }; typedef struct DavPathOp { + UiObject *ui; + DavBrowser *browser; + + // operation type (delete, mkcol, ...) enum DavPathOpType op; + // clone of the browser's DavSession DavSession *sn; + // path array char **path; + // browser->resources indices size_t *list_indices; + // number of path/list_indices elements size_t nelm; + + // browser->current ptr when the PathOp started + // used in combination with collection_ctn to check if the browser list changed DavResource *collection; int64_t collection_ctn; } DavPathOp; +typedef struct DavPathOpResult { + UiObject *ui; + DavBrowser *browser; + DavResource *collection; + int64_t collection_ctn; + + char *path; + int res_index; + int result; + char *errormsg; +} DavPathOpResult; + +static int uithr_pathop_delete_error(void *data) { + DavPathOpResult *result = data; + + cxmutstr msg = cx_asprintf("Cannot delete resource %s", result->path); + ui_dialog(result->ui, .title = "Error", .content = msg.ptr, .button1_label = "OK"); + free(msg.ptr); + + if (result->errormsg) { + free(result->errormsg); + } + free(result->path); + free(result); + return 0; +} + +static int uithr_pathop_delete_sucess(void *data) { + DavPathOpResult *result = data; + + if (result->browser->current == result->collection && result->browser->res_counter == result->collection_ctn) { + ui_list_remove(result->browser->resources, result->res_index); + result->browser->resources->update(result->browser->resources, 0); + } + + free(result->path); + free(result); + return 0; +} + static int jobthr_path_op(void *data) { DavPathOp *op = data; - for (int i = 0; i < op->nelm; i++) { + + for (int i = op->nelm-1; i >= 0; i--) { if (op->path[i]) { DavResource *res = dav_resource_new(op->sn, op->path[i]); - int ret = 0; + DavPathOpResult *result = malloc(sizeof(DavPathOpResult)); + result->ui = op->ui; + result->browser = op->browser; + result->collection = op->collection; + result->collection_ctn = op->collection_ctn; + result->path = strdup(res->path); + result->result = 0; + result->res_index = op->list_indices[i]; + result->errormsg = NULL; + if (op->op == DAV_PATH_OP_DELETE) { - ret = dav_delete(res); + ui_threadfunc result_callback = uithr_pathop_delete_sucess; + if (dav_delete(res)) { + result->errormsg = op->sn->errorstr ? strdup(op->sn->errorstr) : NULL; + result_callback = uithr_pathop_delete_error; + } + ui_call_mainthread(result_callback, result); } dav_resource_free(res); + free(op->path[i]); } } + dav_session_destroy(op->sn); + free(op->path); + free(op->list_indices); + free(op); return 0; } + + void davbrowser_delete(UiObject *ui, DavBrowser *browser, UiListSelection selection) { DavPathOp *op = malloc(sizeof(DavPathOp)); + op->ui = ui; + op->browser = browser; op->op = DAV_PATH_OP_DELETE; op->sn = dav_session_clone(browser->sn); op->path = calloc(selection.count, sizeof(char*));