42 #include <libidav/utils.h> |
42 #include <libidav/utils.h> |
43 |
43 |
44 DavBrowser* davbrowser_create(UiObject *toplevel) { |
44 DavBrowser* davbrowser_create(UiObject *toplevel) { |
45 DavBrowser *doc = ui_document_new(sizeof(DavBrowser)); |
45 DavBrowser *doc = ui_document_new(sizeof(DavBrowser)); |
46 UiContext *ctx = ui_document_context(doc); |
46 UiContext *ctx = ui_document_context(doc); |
|
47 CxMempool *mp = ui_cx_mempool(ctx); |
47 doc->window = toplevel; |
48 doc->window = toplevel; |
48 doc->ctx = ctx; |
49 doc->ctx = ctx; |
49 |
50 |
50 doc->navigation_stack = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
51 doc->navigation_stack = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
51 doc->navstack_enabled = true; |
52 doc->navstack_enabled = true; |
52 doc->navstack_pos = 0; |
53 doc->navstack_pos = 0; |
53 |
54 |
54 doc->dav_queue = ui_threadpool_create(1); |
55 doc->dav_queue = ui_threadpool_create(1); |
|
56 cxMempoolRegister(mp, doc->dav_queue, (cx_destructor_func)ui_threadpool_destroy); |
55 |
57 |
56 doc->res_open_inprogress = cxHashMapCreate(ctx->allocator, CX_STORE_POINTERS, 4); |
58 doc->res_open_inprogress = cxHashMapCreate(ctx->allocator, CX_STORE_POINTERS, 4); |
57 |
59 |
58 doc->path = ui_string_new(ctx, "path"); |
60 doc->path = ui_string_new(ctx, "path"); |
59 doc->resources = ui_list_new(ctx, "reslist"); |
61 doc->resources = ui_list_new(ctx, "reslist"); |
1015 DavPropName *properties = dav_get_property_names(res, &count); |
1028 DavPropName *properties = dav_get_property_names(res, &count); |
1016 for(int i=0;i<count;i++) { |
1029 for(int i=0;i<count;i++) { |
1017 DavPropertyList *prop = ui_malloc(doc->ctx, sizeof(DavPropertyList)); |
1030 DavPropertyList *prop = ui_malloc(doc->ctx, sizeof(DavPropertyList)); |
1018 prop->ns = properties[i].ns ? ui_strdup(doc->ctx, properties[i].ns) : NULL; |
1031 prop->ns = properties[i].ns ? ui_strdup(doc->ctx, properties[i].ns) : NULL; |
1019 prop->name = ui_strdup(doc->ctx, properties[i].name); |
1032 prop->name = ui_strdup(doc->ctx, properties[i].name); |
|
1033 prop->value_simplified = NULL; |
|
1034 prop->value_full = NULL; |
|
1035 prop->update = FALSE; |
|
1036 prop->isnew = FALSE; |
1020 |
1037 |
1021 DavXmlNode *xval = dav_get_property_ns(res, prop->ns, prop->name); |
1038 DavXmlNode *xval = dav_get_property_ns(res, prop->ns, prop->name); |
|
1039 prop->xml = xval; |
1022 if(xval) { |
1040 if(xval) { |
1023 if(dav_xml_isstring(xval)) { |
1041 if(dav_xml_isstring(xval)) { |
1024 char *value = dav_xml_getstring(xval); |
1042 char *value = dav_xml_getstring(xval); |
1025 if(value) { |
1043 if(value) { |
1026 prop->value_simplified = NULL; |
1044 prop->value_simplified = NULL; |
1088 return 0; |
1106 return 0; |
1089 } |
1107 } |
1090 |
1108 |
1091 static void uithr_upload_text_finished(UiEvent *event, void *data) { |
1109 static void uithr_upload_text_finished(UiEvent *event, void *data) { |
1092 ResourceViewerUploadFile *upload = data; |
1110 ResourceViewerUploadFile *upload = data; |
|
1111 ui_object_unref(event->obj); |
1093 |
1112 |
1094 if(upload->error) { |
1113 if(upload->error) { |
1095 cxmutstr errormsg = cx_asprintf("Upload failed: %d", upload->sn->error); // TODO: add full error message |
1114 cxmutstr errormsg = cx_asprintf("Upload failed: %d", upload->sn->error); // TODO: add full error message |
1096 ui_dialog(event->obj, .title = "Error", .content = errormsg.ptr, .closebutton_label = "OK"); |
1115 ui_dialog(event->obj, .title = "Error", .content = errormsg.ptr, .closebutton_label = "OK"); |
1097 free(errormsg.ptr); |
1116 free(errormsg.ptr); |
1098 ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
1117 ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
1099 } |
1118 } |
1100 |
1119 |
1101 dav_session_destroy(upload->sn); |
|
1102 free(upload->path); |
|
1103 free(upload->text.ptr); |
1120 free(upload->text.ptr); |
1104 free(upload); |
1121 free(upload); |
1105 } |
1122 } |
1106 |
1123 |
|
1124 static int jobthr_store_properties(void *data) { |
|
1125 DavResourceViewer *res = data; |
|
1126 res->error = dav_store(res->current); |
|
1127 return 0; |
|
1128 } |
|
1129 |
|
1130 static void uithr_store_properties_finished(UiEvent *event, void *data) { |
|
1131 DavResourceViewer *res = data; |
|
1132 ui_object_unref(event->obj); |
|
1133 if(res->error) { |
|
1134 cxmutstr errormsg = cx_asprintf("Proppatch failed: %d", res->sn->error); // TODO: add full error message |
|
1135 ui_dialog(event->obj, .title = "Error", .content = errormsg.ptr, .closebutton_label = "OK"); |
|
1136 free(errormsg.ptr); |
|
1137 ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
|
1138 res->properties_modified = TRUE; |
|
1139 } else { |
|
1140 CxList *properties = res->properties->data; |
|
1141 CxIterator i = cxListIterator(properties); |
|
1142 cx_foreach(DavPropertyList *, prop, i) { |
|
1143 prop->update = FALSE; |
|
1144 prop->isnew = FALSE; |
|
1145 } |
|
1146 } |
|
1147 } |
|
1148 |
1107 void dav_resourceviewer_save(UiObject *ui, DavResourceViewer *res) { |
1149 void dav_resourceviewer_save(UiObject *ui, DavResourceViewer *res) { |
1108 if(res->type == DAV_RESOURCE_VIEW_TEXT) { |
1150 if(res->type == DAV_RESOURCE_VIEW_TEXT) { |
1109 DavSession *newsn = dav_session_clone(res->current->session); |
|
1110 ResourceViewerUploadFile *upload = malloc(sizeof(ResourceViewerUploadFile)); |
1151 ResourceViewerUploadFile *upload = malloc(sizeof(ResourceViewerUploadFile)); |
1111 upload->ui = ui; |
1152 upload->ui = ui; |
1112 upload->sn = newsn; |
1153 upload->sn = res->sn; |
1113 upload->path = strdup(res->current->path); |
1154 upload->path = res->current->path; |
1114 char *text = ui_get(res->text); |
1155 char *text = ui_get(res->text); |
1115 size_t textlen = strlen(text); |
1156 upload->text = cx_strdup(cx_str(text)); |
1116 upload->text = cx_strdup(cx_strn(text, textlen)); |
1157 ui_object_ref(res->obj); |
1117 ui_job(ui, jobthr_upload_text, upload, uithr_upload_text_finished, upload); |
1158 ui_threadpool_job(res->dav_queue, ui, jobthr_upload_text, upload, uithr_upload_text_finished, upload); |
1118 ui_unset_group(ui->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
1159 } |
1119 } |
1160 |
|
1161 if(res->properties_modified) { |
|
1162 CxList *properties = res->properties->data; |
|
1163 CxIterator i = cxListIterator(properties); |
|
1164 cx_foreach(DavPropertyList *, prop, i) { |
|
1165 if(prop->update) { |
|
1166 if(prop->value_full) { |
|
1167 // text |
|
1168 dav_set_string_property_ns(res->current, prop->ns, prop->name, prop->value_full); |
|
1169 } else { |
|
1170 // xml |
|
1171 dav_set_property_ns(res->current, prop->ns, prop->name, prop->xml); |
|
1172 } |
|
1173 } |
|
1174 } |
|
1175 |
|
1176 ui_object_ref(res->obj); |
|
1177 ui_threadpool_job(res->dav_queue, ui, jobthr_store_properties, res, uithr_store_properties_finished, res); |
|
1178 } |
|
1179 |
|
1180 ui_unset_group(ui->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
1120 } |
1181 } |
1121 |
1182 |
1122 void dav_resourceviewer_destroy(DavResourceViewer *res) { |
1183 void dav_resourceviewer_destroy(DavResourceViewer *res) { |
1123 |
1184 |
1124 } |
1185 } |
|
1186 |
|
1187 void dav_resourceviewer_property_remove(DavResourceViewer *res, DavPropertyList *prop) { |
|
1188 if(!prop->isnew) { |
|
1189 dav_remove_property_ns(res->current, prop->ns, prop->name); |
|
1190 ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
|
1191 res->properties_modified = TRUE; |
|
1192 } |
|
1193 |
|
1194 CxList *properties = res->properties->data; |
|
1195 cxListFindRemove(properties, prop); |
|
1196 ui_free(res->ctx, prop->ns); |
|
1197 ui_free(res->ctx, prop->name); |
|
1198 ui_free(res->ctx, prop->value_simplified); |
|
1199 ui_free(res->ctx, prop->value_full); |
|
1200 // prop->xml freed by DavSession |
|
1201 ui_free(res->ctx, prop); |
|
1202 ui_list_update(res->properties); |
|
1203 } |
|
1204 |
|
1205 void dav_resourceviewer_property_update_text(DavResourceViewer *res, DavPropertyList *prop, const char *text) { |
|
1206 ui_free(res->ctx, prop->value_simplified); |
|
1207 ui_free(res->ctx, prop->value_full); |
|
1208 prop->xml = NULL; |
|
1209 prop->value_full = ui_strdup(res->ctx, text); |
|
1210 prop->value_simplified = NULL; |
|
1211 prop->update = TRUE; |
|
1212 |
|
1213 ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
|
1214 res->properties_modified = TRUE; |
|
1215 ui_list_update(res->properties); |
|
1216 } |
|
1217 |
|
1218 void dav_resourceviewer_property_update_xml(DavResourceViewer *res, DavPropertyList *prop, DavXmlNode *xml) { |
|
1219 |
|
1220 } |
|
1221 |
|
1222 void dav_resourceviewer_property_add_text(DavResourceViewer *res, const char *ns, const char *name, const char *text) { |
|
1223 DavPropertyList *prop = ui_malloc(res->ctx, sizeof(DavPropertyList)); |
|
1224 prop->ns = ui_strdup(res->ctx, ns); |
|
1225 prop->name = ui_strdup(res->ctx, name); |
|
1226 prop->value_simplified = NULL; |
|
1227 prop->value_full = ui_strdup(res->ctx, text); |
|
1228 prop->xml = NULL; |
|
1229 prop->isnew = TRUE; |
|
1230 prop->update = TRUE; |
|
1231 |
|
1232 ui_list_append(res->properties, prop); |
|
1233 ui_set_group(res->obj->ctx, RESOURCEVIEWER_STATE_MODIFIED); |
|
1234 res->properties_modified = TRUE; |
|
1235 ui_list_update(res->properties); |
|
1236 } |
|
1237 |
|
1238 void dav_resourceviewer_property_add_xml(DavResourceViewer *res, const char *ns, const char *name, const char *nsdef, DavXmlNode *xml) { |
|
1239 |
|
1240 } |
|
1241 |
1125 |
1242 |
1126 |
1243 |
1127 uint64_t dav_transfer_speed(TransferProgress *progress, time_t current) { |
1244 uint64_t dav_transfer_speed(TransferProgress *progress, time_t current) { |
1128 size_t bytes = progress->transferred_bytes - progress->speedtest_bytes; |
1245 size_t bytes = progress->transferred_bytes - progress->speedtest_bytes; |
1129 time_t t = current - progress->speedtest_start; |
1246 time_t t = current - progress->speedtest_start; |