application/davcontroller.c

changeset 97
5a3d27b8e6b0
parent 95
e92c72705da4
--- a/application/davcontroller.c	Wed Nov 27 18:53:11 2024 +0100
+++ b/application/davcontroller.c	Thu Nov 28 18:03:12 2024 +0100
@@ -44,6 +44,7 @@
 DavBrowser* davbrowser_create(UiObject *toplevel) {
     DavBrowser *doc = ui_document_new(sizeof(DavBrowser));
     UiContext *ctx = ui_document_context(doc);
+    CxMempool *mp = ui_cx_mempool(ctx);
     doc->window = toplevel;
     doc->ctx = ctx;
 
@@ -52,6 +53,7 @@
     doc->navstack_pos = 0;
 
     doc->dav_queue = ui_threadpool_create(1);
+    cxMempoolRegister(mp, doc->dav_queue, (cx_destructor_func)ui_threadpool_destroy);
     
     doc->res_open_inprogress = cxHashMapCreate(ctx->allocator, CX_STORE_POINTERS, 4);
 
@@ -871,12 +873,16 @@
 
 
 
-DavResourceViewer* dav_resourceviewer_create(DavSession *sn, const char *path, DavResourceViewType type) {
+DavResourceViewer* dav_resourceviewer_create(UiObject *toplevel, DavSession *sn, const char *path, DavResourceViewType type) {
     DavResourceViewer *doc = ui_document_new(sizeof(DavResourceViewer));
     UiContext *ctx = ui_document_context(doc);
+    CxMempool *mp = ui_cx_mempool(ctx);
+    doc->obj = toplevel;
     doc->ctx = ctx;
     
     doc->sn = dav_session_clone(sn);
+    doc->dav_queue = ui_threadpool_create(1);
+    cxMempoolRegister(mp, doc->dav_queue, (cx_destructor_func)ui_threadpool_destroy);
     doc->path = strdup(path);
     doc->type = type;
     
@@ -896,6 +902,13 @@
     doc->info_etag = ui_string_new(ctx, "info_etag");
     doc->info_size = ui_string_new(ctx, "info_size");
     
+    doc->property_type = ui_int_new(ctx, NULL);
+    doc->property_ns = ui_string_new(ctx, NULL);
+    doc->property_name = ui_string_new(ctx, NULL);
+    doc->property_nsdef = ui_string_new(ctx, NULL);
+    doc->property_value = ui_text_new(ctx, NULL);
+    doc->property_errormsg = ui_string_new(ctx, NULL);
+        
     return doc;
 }
 
@@ -1017,8 +1030,13 @@
         DavPropertyList *prop = ui_malloc(doc->ctx, sizeof(DavPropertyList));
         prop->ns = properties[i].ns ? ui_strdup(doc->ctx, properties[i].ns) : NULL;
         prop->name = ui_strdup(doc->ctx, properties[i].name);
+        prop->value_simplified = NULL;
+        prop->value_full = NULL;
+        prop->update = FALSE;
+        prop->isnew = FALSE;
 
         DavXmlNode *xval = dav_get_property_ns(res, prop->ns, prop->name);
+        prop->xml = xval;
         if(xval) {
             if(dav_xml_isstring(xval)) {
                 char *value = dav_xml_getstring(xval);
@@ -1090,6 +1108,7 @@
 
 static void uithr_upload_text_finished(UiEvent *event, void *data) {
     ResourceViewerUploadFile *upload = data;
+    ui_object_unref(event->obj);
     
     if(upload->error) {
         cxmutstr errormsg = cx_asprintf("Upload failed: %d", upload->sn->error); // TODO: add full error message
@@ -1098,31 +1117,129 @@
         ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED);
     }
     
-    dav_session_destroy(upload->sn);
-    free(upload->path);
     free(upload->text.ptr);
     free(upload);
 }
 
+static int jobthr_store_properties(void *data) {
+    DavResourceViewer *res = data;
+    res->error = dav_store(res->current);
+    return 0;
+}
+
+static void uithr_store_properties_finished(UiEvent *event, void *data) {
+    DavResourceViewer *res = data;
+    ui_object_unref(event->obj);
+    if(res->error) {
+        cxmutstr errormsg = cx_asprintf("Proppatch failed: %d", res->sn->error); // TODO: add full error message
+        ui_dialog(event->obj, .title = "Error", .content = errormsg.ptr, .closebutton_label = "OK");
+        free(errormsg.ptr);
+        ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED);
+        res->properties_modified = TRUE;
+    } else {
+        CxList *properties = res->properties->data;
+        CxIterator i = cxListIterator(properties);
+        cx_foreach(DavPropertyList *, prop, i) {
+            prop->update = FALSE;
+            prop->isnew = FALSE;
+        }
+    }
+}
+
 void dav_resourceviewer_save(UiObject *ui, DavResourceViewer *res) {
     if(res->type == DAV_RESOURCE_VIEW_TEXT) {
-        DavSession *newsn = dav_session_clone(res->current->session);
         ResourceViewerUploadFile *upload = malloc(sizeof(ResourceViewerUploadFile));
         upload->ui = ui;
-        upload->sn = newsn;
-        upload->path = strdup(res->current->path);
+        upload->sn = res->sn;
+        upload->path = res->current->path;
         char *text = ui_get(res->text);
-        size_t textlen = strlen(text);
-        upload->text = cx_strdup(cx_strn(text, textlen));
-        ui_job(ui, jobthr_upload_text, upload, uithr_upload_text_finished, upload);
-        ui_unset_group(ui->ctx, RESOURCEVIEWER_STATE_MODIFIED);
+        upload->text = cx_strdup(cx_str(text));
+        ui_object_ref(res->obj);
+        ui_threadpool_job(res->dav_queue, ui, jobthr_upload_text, upload, uithr_upload_text_finished, upload);
     }
+    
+    if(res->properties_modified) {
+        CxList *properties = res->properties->data;
+        CxIterator i = cxListIterator(properties);
+        cx_foreach(DavPropertyList *, prop, i) {
+            if(prop->update) {
+                if(prop->value_full) {
+                    // text
+                    dav_set_string_property_ns(res->current, prop->ns, prop->name, prop->value_full);
+                } else {
+                    // xml
+                    dav_set_property_ns(res->current, prop->ns, prop->name, prop->xml);
+                }
+            }
+        }
+        
+        ui_object_ref(res->obj);
+        ui_threadpool_job(res->dav_queue, ui, jobthr_store_properties, res, uithr_store_properties_finished, res);
+    }
+    
+    ui_unset_group(ui->ctx, RESOURCEVIEWER_STATE_MODIFIED);
 }
 
 void dav_resourceviewer_destroy(DavResourceViewer *res) {
     
 }
 
+void dav_resourceviewer_property_remove(DavResourceViewer *res, DavPropertyList *prop) {
+    if(!prop->isnew) {
+        dav_remove_property_ns(res->current, prop->ns, prop->name);
+        ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED);
+        res->properties_modified = TRUE;
+    }
+    
+    CxList *properties = res->properties->data;
+    cxListFindRemove(properties, prop);
+    ui_free(res->ctx, prop->ns);
+    ui_free(res->ctx, prop->name);
+    ui_free(res->ctx, prop->value_simplified);
+    ui_free(res->ctx, prop->value_full);
+    // prop->xml freed by DavSession
+    ui_free(res->ctx, prop);
+    ui_list_update(res->properties);
+}
+
+void dav_resourceviewer_property_update_text(DavResourceViewer *res, DavPropertyList *prop, const char *text) {
+    ui_free(res->ctx, prop->value_simplified);
+    ui_free(res->ctx, prop->value_full);
+    prop->xml = NULL;
+    prop->value_full = ui_strdup(res->ctx, text);
+    prop->value_simplified = NULL;
+    prop->update = TRUE;
+    
+    ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED);
+    res->properties_modified = TRUE;
+    ui_list_update(res->properties);
+}
+
+void dav_resourceviewer_property_update_xml(DavResourceViewer *res, DavPropertyList *prop, DavXmlNode *xml) {
+    
+}
+
+void dav_resourceviewer_property_add_text(DavResourceViewer *res, const char *ns, const char *name, const char *text) {
+    DavPropertyList *prop = ui_malloc(res->ctx, sizeof(DavPropertyList));
+    prop->ns = ui_strdup(res->ctx, ns);
+    prop->name = ui_strdup(res->ctx, name);
+    prop->value_simplified = NULL;
+    prop->value_full = ui_strdup(res->ctx, text);
+    prop->xml = NULL;
+    prop->isnew = TRUE;
+    prop->update = TRUE;
+    
+    ui_list_append(res->properties, prop);
+    ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED);
+    res->properties_modified = TRUE;
+    ui_list_update(res->properties);
+}
+
+void dav_resourceviewer_property_add_xml(DavResourceViewer *res, const char *ns, const char *name, const char *nsdef, DavXmlNode *xml) {
+    
+}
+
+
 
 uint64_t dav_transfer_speed(TransferProgress *progress, time_t current) {
     size_t bytes = progress->transferred_bytes - progress->speedtest_bytes;

mercurial