61 dav_resource_free_all(browser->current); |
61 dav_resource_free_all(browser->current); |
62 } |
62 } |
63 ui_list_clear(browser->resources); |
63 ui_list_clear(browser->resources); |
64 |
64 |
65 browser->current = collection; |
65 browser->current = collection; |
|
66 browser->res_counter++; |
66 for (DavResource *res = collection->children; res; res = res->next) { |
67 for (DavResource *res = collection->children; res; res = res->next) { |
67 ui_list_append(browser->resources, res); |
68 ui_list_append(browser->resources, res); |
68 } |
69 } |
69 |
70 |
70 browser->resources->update(browser->resources, 0); |
71 browser->resources->update(browser->resources, 0); |
265 UiDouble *progress; |
266 UiDouble *progress; |
266 UiString *label_top_left; |
267 UiString *label_top_left; |
267 UiString *label_top_right; |
268 UiString *label_top_right; |
268 UiString *label_bottom_left; |
269 UiString *label_bottom_left; |
269 UiString *label_bottom_right; |
270 UiString *label_bottom_right; |
|
271 |
|
272 // The collection, the files are uploaded to |
|
273 // It is only safe to access the collection ptr, if |
|
274 // collection == browser->current && collection_ctn == browser->res_counter |
|
275 // and obviously it can only be accessed from the UI thread |
|
276 DavResource *collection; |
|
277 |
|
278 // copy of browser->res_counter, used for integrity check |
|
279 int64_t collection_ctn; |
|
280 |
|
281 // current uploaded resource, created as part of the browser session |
|
282 // only if collection == browser->current && collection_ctn == browser->res_counter |
|
283 DavResource *current_resource; |
270 } DavFileUpload; |
284 } DavFileUpload; |
271 |
285 |
272 typedef struct DUFile { |
286 typedef struct DUFile { |
273 char *path; |
287 char *path; |
274 char *upload_path; |
288 char *upload_path; |
346 |
360 |
347 |
361 |
348 typedef struct FileNameUpdate { |
362 typedef struct FileNameUpdate { |
349 DavFileUpload *upload; |
363 DavFileUpload *upload; |
350 char *name; |
364 char *name; |
|
365 char *path; |
|
366 DavBool iscollection; |
351 } FileNameUpdate; |
367 } FileNameUpdate; |
352 |
368 |
353 static int uithr_update_file_label(FileNameUpdate *update) { |
369 static int uithr_update_file_label(FileNameUpdate *update) { |
354 // replace upload->current_filename with update->name |
370 // replace upload->current_filename with update->name |
355 if (update->upload->current_file_name) { |
371 if (update->upload->current_file_name) { |
357 } |
373 } |
358 update->upload->current_file_name = update->name; |
374 update->upload->current_file_name = update->name; |
359 |
375 |
360 ui_set(update->upload->label_top_right, update->name); |
376 ui_set(update->upload->label_top_right, update->name); |
361 |
377 |
|
378 DavFileUpload *upload = update->upload; |
|
379 DavBrowser *browser = upload->browser; |
|
380 // update the resource list in the browser, if the current collection has not changed |
|
381 if (upload->collection == browser->current && upload->collection_ctn == browser->res_counter) { |
|
382 char *parent = util_parent_path(update->path); |
|
383 cxstring parent_s = cx_str(parent); |
|
384 cxstring colpath_s = cx_str(upload->collection->path); |
|
385 if (parent_s.length > 0 && parent_s.ptr[parent_s.length - 1] == '/') { |
|
386 parent_s.length--; |
|
387 } |
|
388 if (colpath_s.length > 0 && colpath_s.ptr[colpath_s.length - 1] == '/') { |
|
389 colpath_s.length--; |
|
390 } |
|
391 |
|
392 // only update, if the added resource has the current collection as parent |
|
393 if (!cx_strcmp(parent_s, colpath_s)) { |
|
394 DavResource *ui_res = dav_resource_new(upload->collection->session, update->path); |
|
395 ui_res->iscollection = update->iscollection; |
|
396 ui_res->lastmodified = time(NULL); |
|
397 ui_res->creationdate = time(NULL); |
|
398 upload->current_resource = ui_res; |
|
399 |
|
400 ui_list_append(browser->resources, ui_res); |
|
401 browser->resources->update(browser->resources, 0); |
|
402 } else { |
|
403 upload->current_resource = NULL; // maybe not necessary |
|
404 } |
|
405 free(parent); |
|
406 } |
|
407 |
|
408 free(update->path); |
362 free(update); |
409 free(update); |
363 return 0; |
410 return 0; |
364 } |
411 } |
365 |
412 |
366 static int qthr_file_upload(void *data) { |
413 static int qthr_file_upload(void *data) { |
381 DavResource *res = dav_resource_new(sn, f->upload_path); |
428 DavResource *res = dav_resource_new(sn, f->upload_path); |
382 |
429 |
383 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); |
430 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); |
384 ui_update->upload = upload; |
431 ui_update->upload = upload; |
385 ui_update->name = strdup(res->name); |
432 ui_update->name = strdup(res->name); |
|
433 ui_update->path = strdup(res->path); |
|
434 ui_update->iscollection = FALSE; |
386 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); |
435 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); |
387 |
436 |
388 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); |
437 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); |
389 if (dav_store(res)) { |
438 if (dav_store(res)) { |
390 f->error = sn->error; |
439 f->error = sn->error; |
407 |
456 |
408 double progress = upload_progress(upload); |
457 double progress = upload_progress(upload); |
409 ui_set(upload->progress, upload_progress(upload)); |
458 ui_set(upload->progress, upload_progress(upload)); |
410 |
459 |
411 update_upload_labels(upload); |
460 update_upload_labels(upload); |
|
461 |
|
462 // update resource content length in the browser |
|
463 DavBrowser *browser = upload->browser; |
|
464 if (upload->collection == browser->current && upload->collection_ctn == browser->res_counter) { |
|
465 if (upload->current_resource) { |
|
466 upload->current_resource->contentlength = upload->current_file_upload; |
|
467 browser->resources->update(browser->resources, 0); |
|
468 } |
|
469 } |
|
470 upload->current_resource = NULL; |
412 |
471 |
413 free(file->path); |
472 free(file->path); |
414 free(file->upload_path); |
473 free(file->upload_path); |
415 } |
474 } |
416 |
475 |
423 res->iscollection = TRUE; |
482 res->iscollection = TRUE; |
424 |
483 |
425 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); |
484 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate)); |
426 ui_update->upload = upload; |
485 ui_update->upload = upload; |
427 ui_update->name = strdup(res->name); |
486 ui_update->name = strdup(res->name); |
|
487 ui_update->path = strdup(res->path); |
|
488 ui_update->iscollection = TRUE; |
428 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); |
489 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update); |
429 |
490 |
430 if (dav_create(res)) { |
491 if (dav_create(res)) { |
431 f->error = sn->error; |
492 f->error = sn->error; |
432 } |
493 } |
558 upload->browser = browser; |
621 upload->browser = browser; |
559 upload->sn = upload_session; |
622 upload->sn = upload_session; |
560 upload->files = files; |
623 upload->files = files; |
561 upload->base_path = strdup(browser->current->path); |
624 upload->base_path = strdup(browser->current->path); |
562 upload->queue = ui_threadpool_create(1); |
625 upload->queue = ui_threadpool_create(1); |
|
626 |
|
627 upload->collection = browser->current; |
|
628 upload->collection_ctn = browser->res_counter; |
563 |
629 |
564 // create upload progress window |
630 // create upload progress window |
565 cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path)); |
631 cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path)); |
566 UiObject *dialog = ui_simple_window(wtitle.ptr, upload); |
632 UiObject *dialog = ui_simple_window(wtitle.ptr, upload); |
567 ui_context_closefunc(dialog->ctx, upload_window_closed, NULL); |
633 ui_context_closefunc(dialog->ctx, upload_window_closed, NULL); |
596 ui_show(dialog); |
662 ui_show(dialog); |
597 |
663 |
598 // start upload and stat threads |
664 // start upload and stat threads |
599 ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload); |
665 ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload); |
600 } |
666 } |
|
667 |
|
668 |
|
669 // ------------------------------------- Path Operation (DELETE, MKCOL) ------------------------------------- |
|
670 |
|
671 enum DavPathOpType { |
|
672 DAV_PATH_OP_DELETE = 0 |
|
673 }; |
|
674 |
|
675 typedef struct DavPathOp { |
|
676 enum DavPathOpType op; |
|
677 DavSession *sn; |
|
678 char **path; |
|
679 size_t *list_indices; |
|
680 size_t nelm; |
|
681 DavResource *collection; |
|
682 int64_t collection_ctn; |
|
683 } DavPathOp; |
|
684 |
|
685 static int jobthr_path_op(void *data) { |
|
686 DavPathOp *op = data; |
|
687 |
|
688 for (int i = 0; i < op->nelm; i++) { |
|
689 if (op->path[i]) { |
|
690 DavResource *res = dav_resource_new(op->sn, op->path[i]); |
|
691 |
|
692 int ret = 0; |
|
693 if (op->op == DAV_PATH_OP_DELETE) { |
|
694 ret = dav_delete(res); |
|
695 } |
|
696 |
|
697 dav_resource_free(res); |
|
698 } |
|
699 } |
|
700 |
|
701 |
|
702 return 0; |
|
703 } |
|
704 |
|
705 void davbrowser_delete(UiObject *ui, DavBrowser *browser, UiListSelection selection) { |
|
706 DavPathOp *op = malloc(sizeof(DavPathOp)); |
|
707 op->op = DAV_PATH_OP_DELETE; |
|
708 op->sn = dav_session_clone(browser->sn); |
|
709 op->path = calloc(selection.count, sizeof(char*)); |
|
710 op->list_indices = calloc(selection.count, sizeof(size_t)); |
|
711 op->nelm = selection.count; |
|
712 |
|
713 op->collection = browser->current; |
|
714 op->collection_ctn = browser->res_counter; |
|
715 |
|
716 for (int i = 0; i < selection.count; i++) { |
|
717 DavResource *res = ui_list_get(browser->resources, selection.rows[i]); |
|
718 if (res) { |
|
719 op->path[i] = strdup(res->path); |
|
720 op->list_indices[i] = selection.rows[i]; |
|
721 } |
|
722 } |
|
723 |
|
724 ui_job(ui, jobthr_path_op, op, NULL, NULL); |
|
725 } |