Tue, 30 Jan 2024 11:58:11 +0100
don't change the path bar value if the new path is a prefix of the current path
/* * 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 "davcontroller.h" #include "window.h" #include <cx/printf.h> #include <libidav/utils.h> DavBrowser* davbrowser_create(UiObject *toplevel) { DavBrowser *doc = ui_document_new(sizeof(DavBrowser)); UiContext *ctx = ui_document_context(doc); doc->ctx = ctx; doc->dav_queue = ui_threadpool_create(1); doc->path = ui_string_new(ctx, "path"); doc->resources = ui_list_new(ctx, "reslist"); return doc; } void davbrowser_set_collection(UiObject *ui, DavBrowser *browser, DavResource *collection) { ui_list_clear(browser->resources); for (DavResource *res = collection->children; res; res = res->next) { ui_list_append(browser->resources, res); } browser->resources->update(browser->resources, 0); } // ------------------------------ davbrowser_connect2repo ------------------------------ void davbrowser_connect2repo(UiObject *ui, DavBrowser *browser, DavCfgRepository *repo) { DavSession *sn = dav_session_new(application_dav_context(), repo->url.value.ptr); if (repo->user.value.ptr && repo->password.value.ptr) { cxmutstr decodedpw = dav_repository_get_decodedpassword(repo); dav_session_set_auth(sn, repo->user.value.ptr, decodedpw.ptr); free(decodedpw.ptr); } browser->sn = sn; browser->repo_base = cx_strdup(cx_strn(repo->name.value.ptr, repo->name.value.length)).ptr; ui_set(browser->path, repo->name.value.ptr); davbrowser_query_path(ui, browser, ""); } // ------------------------------ davbrowser_query_path ------------------------------ typedef struct DavBrowserQueryPath { UiThreadpool *pool; DavBrowser *browser; char *path; DavResource *result; } DavBrowserQueryPath; static int browser_query_path(void *data) { DavBrowserQueryPath *query = data; DavSession *sn = query->browser->sn; DavResource *res = dav_query(sn, "select `idav:crypto-name`,`idav:crypto-key`,D:lockdiscovery from %s with depth = 1 order by iscollection desc, name", query->path); query->result = res; return 0; } static void browser_query_finished(UiEvent *event, void *data) { DavBrowserQueryPath *query = data; DavBrowser *browser = event->document; if (query->pool == browser->dav_queue) { if (query->result) { davbrowser_set_collection(event->obj, browser, query->result); } else { // TODO: error } window_progress(event->window, 0); } else { // operation aborted if (query->result) { dav_resource_free_all(query->result); } } free(query->path); free(query); } void davbrowser_query_path(UiObject *ui, DavBrowser *browser, const char *path) { // for comparison, we need the current base_url/repo_name + path size_t len = path ? strlen(path) : 0; if (len == 1 && *path == '/') { path = ""; } // check if the new path is a prefix of the current path // if not, we have to set the pathbar string to the new path char *full_path = util_concat_path(browser->repo_base, path); char *full_path_col = util_concat_path(full_path, "/"); char *current_path = ui_get(browser->path); cxstring cpath = cx_str(current_path); cxstring newc = cx_str(full_path_col); if (!cx_strprefix(cpath, newc)) { ui_set(browser->path, full_path); } free(full_path); free(full_path_col); DavBrowserQueryPath *query = malloc(sizeof(DavBrowserQueryPath)); query->pool = browser->dav_queue; query->browser = browser; query->path = strdup(path); query->result = NULL; ui_threadpool_job(browser->dav_queue, ui, browser_query_path, query, browser_query_finished, query); window_progress(ui->window, 1); } void davbrowser_query_url(UiObject *ui, DavBrowser *browser, const char *url) { if (browser->repo_base) { cxstring base = cx_str(browser->repo_base); cxstring newurl = cx_str(url); if (cx_strprefix(newurl, base)) { const char *path = url + base.length; davbrowser_query_path(ui, browser, path); return; } } // TODO: }