implement resource deletion

Fri, 09 Feb 2024 16:50:23 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 09 Feb 2024 16:50:23 +0100
changeset 26
40d6af793c1a
parent 25
915131bc3233
child 27
c254ed644edf

implement resource deletion

application/application.c file | annotate | diff | comparison | revisions
application/application.h file | annotate | diff | comparison | revisions
application/davcontroller.c file | annotate | diff | comparison | revisions
application/davcontroller.h file | annotate | diff | comparison | revisions
application/window.c file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/types.c file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
ui/ui/tree.h file | annotate | diff | comparison | revisions
ui/winui/table.cpp file | annotate | diff | comparison | revisions
ui/winui/table.h file | annotate | diff | comparison | revisions
--- a/application/application.c	Thu Feb 08 10:35:07 2024 +0100
+++ b/application/application.c	Fri Feb 09 16:50:23 2024 +0100
@@ -88,7 +88,7 @@
 	ui_toolbar_item("NewFile", .icon = "Add");
 	ui_toolbar_item("Upload", .label = "Upload", .icon = "Upload", .onclick = action_upload_file);
 	ui_toolbar_item("Download", .icon = "SaveLocal");
-	ui_toolbar_item("Remove", .icon = "Delete");
+	ui_toolbar_item("Remove", .icon = "Delete", .onclick = action_delete );
 	ui_toolbar_toggleitem("LocalBrowser", .icon = "DockLeft", .label = "Local Browser");
 	ui_toolbar_toggleitem("PreviewPane", .icon = "DockRight");
 
@@ -177,3 +177,12 @@
 void action_upload_file(UiEvent *event, void *data) {
 	ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_MULTI, file_selected, NULL);
 }
+
+void action_delete(UiEvent *event, void *data) {
+	DavBrowser *browser = event->document;
+	UiListSelection sel = ui_list_getselection(browser->resources);
+	if (sel.count > 0) {
+		davbrowser_delete(event->obj, browser, sel);
+	}
+	ui_listselection_free(sel);
+}
--- a/application/application.h	Thu Feb 08 10:35:07 2024 +0100
+++ b/application/application.h	Fri Feb 09 16:50:23 2024 +0100
@@ -62,6 +62,11 @@
 
 	DavResource *current;
 
+	/*
+	 * incremented every time current is updated 
+	 */
+	uint64_t res_counter;
+
 	CxList *navigation_stack;
 	bool navstack_enabled;
 	int navstack_pos;
@@ -104,6 +109,8 @@
 
 void action_upload_file(UiEvent *event, void *data);
 
+void action_delete(UiEvent *event, void *data);
+
 #ifdef	__cplusplus
 }
 #endif
--- 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);
+}
--- a/application/davcontroller.h	Thu Feb 08 10:35:07 2024 +0100
+++ b/application/davcontroller.h	Fri Feb 09 16:50:23 2024 +0100
@@ -58,6 +58,7 @@
 
 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files);
 
+void davbrowser_delete(UiObject *ui, DavBrowser *browser, UiListSelection selection);
 
 #ifdef	__cplusplus
 }
--- a/application/window.c	Thu Feb 08 10:35:07 2024 +0100
+++ b/application/window.c	Fri Feb 09 16:50:23 2024 +0100
@@ -221,6 +221,6 @@
 	UiListDnd *listdnd = event->eventdata;
 	UiDnD *dnd = listdnd->dnd;
 	UiFileList files = ui_selection_geturis(dnd);
-
+	
 	davbrowser_upload_files(event->obj, event->document, files);
 }
--- a/ui/common/context.c	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/common/context.c	Fri Feb 09 16:50:23 2024 +0100
@@ -321,6 +321,7 @@
             if (f->obj) {
                 t->obj = f->obj;
                 t->update = f->update;
+                t->getselection = f->getselection;
             }
 
             UiVar tmp = *from;
--- a/ui/common/types.c	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/common/types.c	Fri Feb 09 16:50:23 2024 +0100
@@ -104,6 +104,7 @@
     list->iter = NULL;
     
     list->update = NULL;
+    list->getselection = NULL;
     list->obj = NULL;
     
     if(name) {
@@ -458,6 +459,18 @@
 }
 
 
+UIEXPORT UiListSelection ui_list_getselection(UiList *list) {
+    if (list->getselection) {
+        return list->getselection(list);
+    }
+    return (UiListSelection){ 0, NULL };
+}
+
+UIEXPORT void ui_listselection_free(UiListSelection selection) {
+    if (selection.rows) {
+        free(selection.rows);
+    }
+}
 
 UIEXPORT UiStr ui_str(char *cstr) {
     return (UiStr) { cstr, NULL };
--- a/ui/ui/toolkit.h	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/ui/toolkit.h	Fri Feb 09 16:50:23 2024 +0100
@@ -157,6 +157,8 @@
 
 typedef struct UiFileList   UiFileList;
 
+typedef struct UiListSelection UiListSelection;
+
 /* begin opaque types */
 typedef struct UiContext    UiContext;
 typedef struct UiContainer  UiContainer;
@@ -329,8 +331,9 @@
     /* private - implementation dependent */
     void *data;
     
-    /* binding function */
+    /* binding functions */
     void (*update)(UiList *list, int i);
+    UiListSelection (*getselection)(UiList *list);
     /* binding object */
     void *obj;
     
@@ -338,6 +341,19 @@
     UiObserver *observers;
 };
 
+
+struct UiListSelection {
+    /*
+    * number of selected items
+    */
+    int count;
+
+    /*
+    * indices of selected rows
+    */
+    int *rows;
+};
+
 struct UiRange {
     double (*get)(UiRange *range);
     void   (*set)(UiRange *range, double value);
@@ -462,6 +478,8 @@
 UIEXPORT void  ui_list_addobsv(UiList *list, ui_callback f, void *data);
 UIEXPORT void  ui_list_notify(UiList *list);
 
+UIEXPORT UiListSelection ui_list_getselection(UiList *list);
+
 UIEXPORT UiFileList ui_filelist_copy(UiFileList list);
 UIEXPORT void ui_filelist_free(UiFileList list);
 
@@ -477,7 +495,7 @@
 
 
 
-
+UIEXPORT void ui_listselection_free(UiListSelection selection);
 
 UIEXPORT UiIcon* ui_icon(const char* name, size_t size);
 UIEXPORT UiIcon* ui_imageicon(const char* file);
--- a/ui/ui/tree.h	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/ui/tree.h	Fri Feb 09 16:50:23 2024 +0100
@@ -37,7 +37,6 @@
 
 typedef struct UiModel         UiModel;
 typedef struct UiListCallbacks UiListCallbacks;
-typedef struct UiListSelection UiListSelection;
 typedef struct UiListDnd       UiListDnd;
 
 typedef struct UiListArgs      UiListArgs;
@@ -95,18 +94,6 @@
     void *userdata;
 };
 
-struct UiListSelection {
-    /*
-     * number of selected items
-     */
-    int count;
-    
-    /*
-     * indices of selected rows
-     */
-    int *rows;
-};
-
 struct UiListDnd {
     UiListSelection selection;
     UiDnD *dnd;
@@ -150,11 +137,10 @@
 UIEXPORT UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args);
 UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args);
 
-
-void ui_table_dragsource(UIWIDGET tablewidget, int actions, char *target0, ...);
-void ui_table_dragsource_a(UIWIDGET tablewidget, int actions, char **targets, int nelm);
-void ui_table_dragdest(UIWIDGET tablewidget, int actions, char *target0, ...);
-void ui_table_dragdest_a(UIWIDGET tablewidget, int actions, char **targets, int nelm);
+void ui_table_dragsource_deprecated(UIWIDGET tablewidget, int actions, char *target0, ...);
+void ui_table_dragsource_a_deprecated(UIWIDGET tablewidget, int actions, char **targets, int nelm);
+void ui_table_dragdest_deprecated(UIWIDGET tablewidget, int actions, char *target0, ...);
+void ui_table_dragdest_a_deprecated(UIWIDGET tablewidget, int actions, char **targets, int nelm);
 
 
 #ifdef	__cplusplus
--- a/ui/winui/table.cpp	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/winui/table.cpp	Fri Feb 09 16:50:23 2024 +0100
@@ -111,6 +111,7 @@
 	if (var) {
 		UiList* list = (UiList*)var->value;
 		list->update = ui_table_update;
+		list->getselection = ui_table_selection;
 		list->obj = uitable;
 		uitable->update(list, 0);
 	}
@@ -134,6 +135,11 @@
 	table->update(list, i);
 }
 
+extern "C" UiListSelection ui_table_selection(UiList * list) {
+	UiTable* table = (UiTable*)list->obj;
+	return table->uiselection();
+}
+
 UiTable::UiTable(UiObject *obj, winrt::Microsoft::UI::Xaml::Controls::ScrollViewer scrollW, winrt::Microsoft::UI::Xaml::Controls::Grid grid) {
 	this->obj = obj;
 
--- a/ui/winui/table.h	Thu Feb 08 10:35:07 2024 +0100
+++ b/ui/winui/table.h	Fri Feb 09 16:50:23 2024 +0100
@@ -95,3 +95,4 @@
 
 extern "C" void ui_table_update(UiList * list, int i);
 
+extern "C" UiListSelection ui_table_selection(UiList * list);

mercurial