some toolkit fixes

Sun, 09 Jun 2024 17:00:22 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 09 Jun 2024 17:00:22 +0200
changeset 35
834d9c15a69f
parent 34
98e041f2f9a2
child 36
9f3448a10d11

some toolkit fixes

application/application.c file | annotate | diff | comparison | revisions
application/application.h file | annotate | diff | comparison | revisions
ui/common/threadpool.c file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/gtk/menu.h file | annotate | diff | comparison | revisions
ui/gtk/text.c file | annotate | diff | comparison | revisions
--- 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);
 }
--- 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 <ui/ui.h>
 
@@ -40,46 +40,46 @@
 
 #include <cx/linked_list.h>
 
-#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
 
--- 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 <pthread.h>
 
@@ -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;
 }
 
--- 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);    
 }
--- 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);
--- 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);

mercurial