# HG changeset patch # User Olaf Wintermann # Date 1717945222 -7200 # Node ID 834d9c15a69fc6e4738739d9273f8473294a5fc4 # Parent 98e041f2f9a2a23de87ec09680b691fe4700307a some toolkit fixes diff -r 98e041f2f9a2 -r 834d9c15a69f application/application.c --- a/application/application.c Sun Jun 09 16:43:40 2024 +0200 +++ b/application/application.c Sun Jun 09 17:00:22 2024 +0200 @@ -40,38 +40,38 @@ static DavContext* davctx; void application_init(void) { - davctx = dav_context_new(); - dav_context_set_mtsafe(davctx, true); + davctx = dav_context_new(); + dav_context_set_mtsafe(davctx, true); - application_create_menu(); + application_create_menu(); } void application_startup(UiEvent* event, void* data) { - if (load_config(davctx)) { - // TODO: error - exit(-1); - } + if (load_config(davctx)) { + // TODO: error + exit(-1); + } - window_init(); + window_init(); - // create document for global settings (repolist, ...) - DavApp *app = application_create_app_document(); - UiContext *global = ui_global_context(); - ui_attach_document(global, app); + // create document for global settings (repolist, ...) + DavApp *app = application_create_app_document(); + UiContext *global = ui_global_context(); + ui_attach_document(global, app); - // create new window - UiObject *win = window_create(); - // create new browser document and attach it to the main window - DavBrowser *doc = davbrowser_create(win); - ui_attach_document(win->ctx, doc); + // create new window + UiObject *win = window_create(); + // create new browser document and attach it to the main window + DavBrowser *doc = davbrowser_create(win); + ui_attach_document(win->ctx, doc); - ui_show(win); + ui_show(win); } static void* davrepo_getname(void *elm, int unused) { - DavCfgRepository *repo = elm; - return repo->name.value.ptr; + DavCfgRepository *repo = elm; + return repo->name.value.ptr; } void application_create_menu(void) { @@ -115,135 +115,135 @@ DavApp* application_create_app_document(void) { - DavApp *doc = ui_document_new(sizeof(DavApp)); - UiContext *ctx = ui_document_context(doc); - doc->repos = ui_list_new(ctx, "repolist"); + DavApp *doc = ui_document_new(sizeof(DavApp)); + UiContext *ctx = ui_document_context(doc); + doc->repos = ui_list_new(ctx, "repolist"); - // create repo list - application_update_repolist(doc); + // create repo list + application_update_repolist(doc); - return doc; + return doc; } void application_update_repolist(DavApp *app) { - DavConfig *config = get_config(); - DavCfgRepository *repo = config->repositories; + DavConfig *config = get_config(); + DavCfgRepository *repo = config->repositories; - ui_list_clear(app->repos); + ui_list_clear(app->repos); - for (DavCfgRepository *repo = config->repositories; repo; repo = repo->next) { - ui_list_append(app->repos, repo); - } + for (DavCfgRepository *repo = config->repositories; repo; repo = repo->next) { + ui_list_append(app->repos, repo); + } } DavContext* application_dav_context(void) { - return davctx; + return davctx; } void action_window_new(UiEvent *event, void *data) { - UiObject *win = window_create(); - // create new browser document and attach it to the main window - DavBrowser *doc = davbrowser_create(win); - ui_attach_document(win->ctx, doc); + UiObject *win = window_create(); + // create new browser document and attach it to the main window + DavBrowser *doc = davbrowser_create(win); + ui_attach_document(win->ctx, doc); - ui_show(win); + ui_show(win); } void action_refresh(UiEvent *event, void *data) { - DavBrowser *browser = event->document; - if (browser->current) { - davbrowser_query_path(event->obj, browser, browser->current->path); - } + DavBrowser *browser = event->document; + if (browser->current) { + davbrowser_query_path(event->obj, browser, browser->current->path); + } } void action_repo_selected(UiEvent *event, void *data) { - DavCfgRepository *repo = event->eventdata; - DavBrowser *browser = event->document; - davbrowser_connect2repo(event->obj, browser, repo, ""); + DavCfgRepository *repo = event->eventdata; + DavBrowser *browser = event->document; + davbrowser_connect2repo(event->obj, browser, repo, ""); } static void file_selected(UiEvent *event, void *data) { - UiFileList *files = event->eventdata; - if (files && files->nfiles > 0) { - // files will be freed by the filedialog handler, therefore we need a copy - UiFileList uploadList = ui_filelist_copy(*files); // uploadList will be freed by davbrowser_upload_files - davbrowser_upload_files(event->obj, event->document, uploadList); - } - + UiFileList *files = event->eventdata; + if (files && files->nfiles > 0) { + // files will be freed by the filedialog handler, therefore we need a copy + UiFileList uploadList = ui_filelist_copy(*files); // uploadList will be freed by davbrowser_upload_files + davbrowser_upload_files(event->obj, event->document, uploadList); + } + } static void download_location_selected(UiEvent *event, void *data) { - DavBrowser *browser = event->document; - DavResource *reslist = data; - UiFileList *flist = event->eventdata; + DavBrowser *browser = event->document; + DavResource *reslist = data; + UiFileList *flist = event->eventdata; - if (flist && flist->nfiles > 0) { - davbrowser_download(event->obj, browser, reslist, flist->files[0]); - } else { - dav_session_destroy(reslist->session); - } + if (flist && flist->nfiles > 0) { + davbrowser_download(event->obj, browser, reslist, flist->files[0]); + } else { + dav_session_destroy(reslist->session); + } } void action_download(UiEvent *event, void *data) { - DavBrowser *browser = event->document; - UiListSelection sel = ui_list_getselection(browser->resources); - if (sel.count > 0) {; - const char *initialFileName = NULL; - if (sel.count == 1) { - DavResource *res = ui_list_get(browser->resources, sel.rows[0]); - if (res && !res->iscollection) { - initialFileName = res->name; - } - } + DavBrowser *browser = event->document; + UiListSelection sel = ui_list_getselection(browser->resources); + if (sel.count > 0) {; + const char *initialFileName = NULL; + if (sel.count == 1) { + DavResource *res = ui_list_get(browser->resources, sel.rows[0]); + if (res && !res->iscollection) { + initialFileName = res->name; + } + } - // create a copy of the current session and all selected resources - DavSession *sn = dav_session_clone(browser->sn); - DavResource *first = NULL; - DavResource *last = NULL; - for (int i = 0; i < sel.count; i++) { - // get selected resource - DavResource *res = ui_list_get(browser->resources, sel.rows[i]); - // copy resource - DavResource *res_copy = dav_resource_new(sn, res->path); - res_copy->iscollection = res->iscollection; - res_copy->contentlength = res->contentlength; - res_copy->lastmodified = res->lastmodified; - res_copy->creationdate = res->creationdate; + // create a copy of the current session and all selected resources + DavSession *sn = dav_session_clone(browser->sn); + DavResource *first = NULL; + DavResource *last = NULL; + for (int i = 0; i < sel.count; i++) { + // get selected resource + DavResource *res = ui_list_get(browser->resources, sel.rows[i]); + // copy resource + DavResource *res_copy = dav_resource_new(sn, res->path); + res_copy->iscollection = res->iscollection; + res_copy->contentlength = res->contentlength; + res_copy->lastmodified = res->lastmodified; + res_copy->creationdate = res->creationdate; - // link resources - if (!first) { - first = res_copy; - } - if (last) { - res_copy->prev = last; - last->next = res_copy; - } - last = res_copy; - } + // link resources + if (!first) { + first = res_copy; + } + if (last) { + res_copy->prev = last; + last->next = res_copy; + } + last = res_copy; + } - if (initialFileName) { - ui_savefiledialog(event->obj, initialFileName, download_location_selected, first); - } else { - ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_FOLDER, download_location_selected, first); - } - } + if (initialFileName) { + ui_savefiledialog(event->obj, initialFileName, download_location_selected, first); + } else { + ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_FOLDER, download_location_selected, first); + } + } } void action_upload_file(UiEvent *event, void *data) { - ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_MULTI, file_selected, NULL); + ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_MULTI, file_selected, NULL); } void action_delete(UiEvent *event, void *data) { - DavBrowser *browser = event->document; - UiListSelection sel = ui_list_getselection(browser->resources); - if (sel.count > 0) { - davbrowser_delete(event->obj, browser, sel); - } - ui_listselection_free(sel); + DavBrowser *browser = event->document; + UiListSelection sel = ui_list_getselection(browser->resources); + if (sel.count > 0) { + davbrowser_delete(event->obj, browser, sel); + } + ui_listselection_free(sel); } void action_newfile(UiEvent *event, void *data) { @@ -252,13 +252,13 @@ static void newfolderdialog_result(UiEvent *event, void *data) { - DavBrowser *browser = event->document; - char *path = event->eventdata; - if (event->intval == 1) { - davbrowser_mkcol(event->obj, browser, path); - } + DavBrowser *browser = event->document; + char *path = event->eventdata; + if (event->intval == 1) { + davbrowser_mkcol(event->obj, browser, path); + } } void action_mkcol(UiEvent *event, void *data) { - ui_dialog(event->obj, .content = "New Folder", .input = TRUE, .button1_label = "Create Folder", .button2_label = "Close", .result = newfolderdialog_result); + ui_dialog(event->obj, .content = "New Folder", .input = TRUE, .button1_label = "Create Folder", .button2_label = "Close", .result = newfolderdialog_result); } diff -r 98e041f2f9a2 -r 834d9c15a69f application/application.h --- a/application/application.h Sun Jun 09 16:43:40 2024 +0200 +++ b/application/application.h Sun Jun 09 17:00:22 2024 +0200 @@ -27,7 +27,7 @@ */ #ifndef IDAV_APPLICATION_H -#define IDAV_APPLICATION_H +#define IDAV_APPLICATION_H #include @@ -40,46 +40,46 @@ #include -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif typedef struct DavApp { - DavConfig *dav_config; - UiList *repos; + DavConfig *dav_config; + UiList *repos; } DavApp; /* * main window document object */ typedef struct DavBrowser { - UiContext *ctx; - DavSession *sn; - UiThreadpool *dav_queue; + UiContext *ctx; + DavSession *sn; + UiThreadpool *dav_queue; - char *repo_base; + char *repo_base; - DavResource *current; + DavResource *current; - /* - * incremented every time current is updated - */ - uint64_t res_counter; + /* + * incremented every time current is updated + */ + uint64_t res_counter; - CxList *navigation_stack; - bool navstack_enabled; - int navstack_pos; + CxList *navigation_stack; + bool navstack_enabled; + int navstack_pos; - /* - * path textfield value - */ - UiString *path; + /* + * path textfield value + */ + UiString *path; - /* - * children of the current collection - */ - UiList *resources; + /* + * children of the current collection + */ + UiList *resources; } DavBrowser; void application_init(void); @@ -117,7 +117,7 @@ void action_mkcol(UiEvent *event, void *data); -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff -r 98e041f2f9a2 -r 834d9c15a69f ui/common/threadpool.c --- a/ui/common/threadpool.c Sun Jun 09 16:43:40 2024 +0200 +++ b/ui/common/threadpool.c Sun Jun 09 17:00:22 2024 +0200 @@ -27,6 +27,7 @@ */ #include "threadpool.h" +#include "context.h" #include @@ -70,7 +71,7 @@ if(job == &kill_job) { break; } - + job->callback(job->data); free(job); @@ -145,17 +146,35 @@ UiThreadpool* ui_threadpool_create(int nthreads) { - return threadpool_new(nthreads, nthreads); + UiThreadpool *pool = threadpool_new(nthreads, nthreads); + threadpool_start(pool); // TODO: check return value + return pool; } void ui_threadpool_destroy(UiThreadpool* pool) { } +static int ui_threadpool_job_finish(void *data) { + UiJob *job = data; + UiEvent event; + event.obj = job->obj; + event.window = job->obj->window; + event.document = job->obj->ctx->document; + event.intval = 0; + event.eventdata = NULL; + job->finish_callback(&event, job->finish_data); + free(job); + return 0; +} + static void* ui_threadpool_job_func(void *data) { UiJob *job = data; - - free(job); + if (!job->job_func(job->job_data) && job->finish_callback) { + ui_call_mainthread(ui_threadpool_job_finish, job); + } else { + free(job); + } return NULL; } diff -r 98e041f2f9a2 -r 834d9c15a69f ui/gtk/menu.c --- a/ui/gtk/menu.c Sun Jun 09 16:43:40 2024 +0200 +++ b/ui/gtk/menu.c Sun Jun 09 17:00:22 2024 +0200 @@ -243,6 +243,7 @@ ls->menu = GTK_MENU_SHELL(p); ls->index = index; ls->oldcount = 0; + ls->getvalue = il->getvalue; UiVar* var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST); ls->list = var->value; @@ -274,26 +275,29 @@ } } - char *str = ui_list_first(list->list); - if(str) { + void* elm = ui_list_first(list->list); + if(elm) { GtkWidget *widget = gtk_separator_menu_item_new(); gtk_menu_shell_insert(list->menu, widget, list->index); gtk_widget_show(widget); } + + ui_getvaluefunc getvalue = list->getvalue; int i = 1; - while(str) { - GtkWidget *widget = gtk_menu_item_new_with_label(str); + while(elm) { + char *label = (char*) (getvalue ? getvalue(elm, 0) : elm); + + GtkWidget *widget = gtk_menu_item_new_with_label(label); gtk_menu_shell_insert(list->menu, widget, list->index + i); gtk_widget_show(widget); if(list->callback) { - // TODO: use mempool UiEventData *event = malloc(sizeof(UiEventData)); event->obj = list->object; event->userdata = list->userdata; event->callback = list->callback; event->value = i - 1; - event->customdata = NULL; + event->customdata = elm; g_signal_connect( widget, @@ -307,7 +311,7 @@ event); } - str = ui_list_next(list->list); + elm = ui_list_next(list->list); i++; } @@ -319,7 +323,7 @@ evt.obj = event->obj; evt.window = event->obj->window; evt.document = event->obj->ctx->document; - evt.eventdata = NULL; + evt.eventdata = event->customdata; evt.intval = event->value; event->callback(&evt, event->userdata); } diff -r 98e041f2f9a2 -r 834d9c15a69f ui/gtk/menu.h --- a/ui/gtk/menu.h Sun Jun 09 16:43:40 2024 +0200 +++ b/ui/gtk/menu.h Sun Jun 09 17:00:22 2024 +0200 @@ -44,13 +44,14 @@ typedef void(*ui_menu_add_f)(GtkWidget *, int, UiMenuItemI*, UiObject*); struct UiActiveMenuItemList { - UiObject *object; - GtkMenuShell *menu; - int index; - int oldcount; - UiList *list; - ui_callback callback; - void *userdata; + UiObject *object; + GtkMenuShell *menu; + int index; + int oldcount; + UiList *list; + ui_getvaluefunc getvalue; + ui_callback callback; + void *userdata; }; GtkWidget *ui_create_menubar(UiObject *obj); diff -r 98e041f2f9a2 -r 834d9c15a69f ui/gtk/text.c --- a/ui/gtk/text.c Sun Jun 09 16:43:40 2024 +0200 +++ b/ui/gtk/text.c Sun Jun 09 17:00:22 2024 +0200 @@ -847,6 +847,9 @@ int ui_pathtextfield_update(UiPathTextField* pathtf, const char *full_path) { size_t full_path_len = strlen(full_path); + if(full_path_len == 0) { + return 1; + } size_t nelm = 0; UiPathElm* path_elm = pathtf->getpathelm(full_path, full_path_len, &nelm, pathtf->getpathelmdata);