Tue, 06 Feb 2024 14:17:22 +0100
implement dnd upload (without progressbar)
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2024 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "window.h" #include "davcontroller.h" #include <ui/stock.h> #include <ui/dnd.h> #include <libidav/utils.h> static UiIcon* folder_icon; static UiIcon* file_icon; static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data); void window_init(void) { folder_icon = ui_foldericon(16); file_icon = ui_fileicon(16); } UiObject* window_create(void) { UiObject* obj = ui_window("iDAV", NULL); ui_window_size(obj, 900, 700); MainWindow* wdata = ui_malloc(obj->ctx, sizeof(MainWindow)); memset(wdata, 0, sizeof(MainWindow)); obj->window = wdata; wdata->progress = ui_int_new(obj->ctx, "progress"); // navigation bar ui_hbox(obj, .fill = UI_OFF, .margin = 8) { ui_button(obj, .icon = "Back", .onclick = action_go_back); ui_button(obj, .icon = "Forward", .onclick = action_go_forward); ui_path_textfield(obj, .fill = UI_ON, .getpathelm = dav_get_pathelm, .onactivate = action_path_selected ,.varname = "path"); ui_progressspinner(obj, .value = wdata->progress); } // main content UiModel* model = ui_model(obj->ctx, UI_ICON_TEXT, "Name", UI_STRING, "Type", UI_STRING_FREE, "Last Modified", UI_STRING_FREE, "Size", -1); model->getvalue = (ui_getvaluefunc)window_resource_table_getvalue; ui_table(obj, .fill = UI_ON, .model = model, .onactivate = action_list_activate, .ondrop = action_dnd_drop,.varname = "reslist"); // status bar ui_hbox(obj, .fill = UI_OFF) { ui_label(obj, .label = ""); } ui_model_free(obj->ctx, model); return obj; } void* window_resource_table_getvalue(DavResource *res, int col) { switch (col) { case 0: { // icon return res->iscollection ? folder_icon : file_icon; } case 1: { // resource name return res->name; } case 2: { // type return res->iscollection ? "Collection" : (res->contenttype ? res->contenttype : "Resource"); } case 3: { // last modified return util_date_str(res->lastmodified); } case 4: { // size return util_size_str(res->iscollection, res->contentlength); } } return NULL; } void window_progress(MainWindow *win, int on) { ui_set(win->progress, on); } static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data) { cxstring fpath = cx_strn(full_path, len); int protocol = 0; if(cx_strcaseprefix(fpath, CX_STR("http://"))) { protocol = 7; } else if (cx_strcaseprefix(fpath, CX_STR("https://"))) { protocol = 8; } size_t start = 0; size_t end = 0; for (size_t i = protocol; i < len; i++) { if (full_path[i] == '/') { end = i; break; } } int skip = 0; if (end == 0) { // no '/' found or first char is '/' end = len > 0 && full_path[0] == '/' ? 1 : len; } else if (end + 1 <= len) { skip++; // skip first '/' } cxmutstr base = cx_strdup(cx_strn(full_path, end)); cxmutstr base_path = cx_strdup(cx_strcast(base)); cxstring path = cx_strsubs(fpath, end+skip); cxstring *pathelms; size_t nelm = cx_strsplit_a(cxDefaultAllocator, path, CX_STR("/"), 4096, &pathelms); if (nelm == 0) { *ret_nelm = 0; return NULL; } UiPathElm* elms = (UiPathElm*)calloc(nelm + 1, sizeof(UiPathElm)); size_t n = nelm + 1; elms[0].name = base.ptr; elms[0].name_len = base.length; elms[0].path = base_path.ptr; elms[0].path_len = base_path.length; int j = 1; for (int i = 0; i < nelm; i++) { cxstring c = pathelms[i]; if (c.length == 0) { if (i == 0) { c.length = 1; } else { n--; continue; } } cxmutstr m = cx_strdup(c); elms[j].name = m.ptr; elms[j].name_len = m.length; size_t elm_path_len = c.ptr + c.length - full_path; cxmutstr elm_path = cx_strdup(cx_strn(full_path, elm_path_len)); elms[j].path = elm_path.ptr; elms[j].path_len = elm_path.length; j++; } *ret_nelm = n; return elms; } void action_go_back(UiEvent *event, void *data) { DavBrowser *browser = event->document; davbrowser_navigation_back(event->obj, browser); } void action_go_forward(UiEvent *event, void *data) { DavBrowser *browser = event->document; davbrowser_navigation_forward(event->obj, browser); } void action_path_selected(UiEvent *event, void *data) { DavBrowser *browser = event->document; char *path = event->eventdata; if (path && strlen(path) > 0) { davbrowser_query_url(event->obj, browser, path); } } void action_list_activate(UiEvent *event, void *data) { UiListSelection *selection = event->eventdata; DavBrowser *browser = event->document; if (selection->count == 1) { DavResource *res = ui_list_get(browser->resources, selection->rows[0]); if (res) { if (res->iscollection) { davbrowser_query_path(event->obj, browser, res->path); } else { // TODO } } } } void action_dnd_drop(UiEvent *event, void *data) { UiListDnd *listdnd = event->eventdata; UiDnD *dnd = listdnd->dnd; UiFileList files = ui_selection_geturis(dnd); davbrowser_upload_files(event->obj, event->document, files); }