]> uap-core.de Git - note.git/commitdiff
add unique name check main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 17 Jan 2026 09:18:55 +0000 (10:18 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 17 Jan 2026 09:18:55 +0000 (10:18 +0100)
application/nbconfig.c
application/nbconfig.h
ui/gtk/container.c

index 7c604a356a5151c6b3cb0b5e5ccf3401699911a9..a2d4064ad02ce34322708df682850e797b27f483 100644 (file)
@@ -87,10 +87,29 @@ void nbconfig_update_lists(NotebookConfigDialog *wdata) {
     ui_list_update(wdata->tab3_repositories);
 }
 
+void nbconfig_build_current_names_map(NotebookConfigDialog *wdata, Resource *res) {
+    NoteStore *store = note_store_get();
+    Resource *parent = note_store_get_notebook_by_id(store, res->parent_id);
+    if(parent) {
+        cxMapClear(wdata->current_names);
+        CxIterator i = cxListIterator(parent->children);
+        cx_foreach(Resource *, child, i) {
+            if(child != res) {
+                cxMapPut(wdata->current_names, child->nodename, child);
+            }
+        }
+        cxMapRehash(wdata->current_names);
+    }
+}
+
 static void nbconfig_tab1_load_group(NotebookConfigDialog *wdata, Resource *res) {
     ui_set(wdata->tab1_group_name, res->nodename);
     
     wdata->selected_group = res;
+    // save group name
+    UiContext *ctx = wdata->obj->ctx;
+    ui_free(ctx, wdata->selected_group_name);
+    wdata->selected_group_name = ui_strdup(ctx, res->nodename);
 }
 
 static void nbconfig_tab2_load_notebook(NotebookConfigDialog *wdata, Resource *res) {
@@ -105,6 +124,10 @@ static void nbconfig_tab2_load_notebook(NotebookConfigDialog *wdata, Resource *r
     }
     
     wdata->selected_notebook = res;
+    // save notebook name
+    UiContext *ctx = wdata->obj->ctx;
+    ui_free(ctx, wdata->selected_notebook_name);
+    wdata->selected_notebook_name = ui_strdup(ctx, res->nodename);
 }
 
 static int nbconfig_list_activate_event(UiEvent *event, UiList *list, void **listelm) {
@@ -143,6 +166,14 @@ static void nbconfig_group_save(NotebookConfigDialog *nbconfig) {
         return;
     }
     
+    Resource *dup = cxMapGet(nbconfig->current_names, res->nodename);
+    if(dup) {
+        fprintf(stderr, "Name %s already in use\n", res->nodename);
+        // TODO: show error in UI
+        // TODO: restore old name
+        return;
+    }
+    
     if(res->resource_id == 0) {
         note_store_new_notebook_async(application_global_obj(), res, group_created, res);
     } else {
@@ -164,6 +195,8 @@ static void nbconfig_grouplist_onselect(UiEvent *event, void *userdata) {
     nbconfig_group_save(wdata);
     nbconfig_tab1_load_group(wdata, res);
     wdata->selected_group = res;
+    
+    nbconfig_build_current_names_map(wdata, res);
 }
 
 static void nbconfig_grouplist_add(UiEvent *event, void *userdata) {
@@ -255,8 +288,10 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) {
     wdata->valuechange = TRUE;
     
     if(wdata->selected_group) {
+        char *input = ui_get(wdata->tab1_group_name);
+        
         cxFree(store->mp->allocator, wdata->selected_group->nodename);
-        wdata->selected_group->nodename = cx_strdup_a(store->mp->allocator, cx_str(ui_get(wdata->tab1_group_name))).ptr;
+        wdata->selected_group->nodename = cx_strdup_a(store->mp->allocator, cx_str(input)).ptr;
         
         UiListSelection sel = ui_list_getselection(wdata->tab1_groups);
         nbconfig_update_lists(wdata); // TODO: update only single row
@@ -264,6 +299,12 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) {
             ui_list_setselection(wdata->tab1_groups, sel.rows[0]);
         }
         ui_listselection_free(sel);
+        
+        Resource *dup = cxMapGet(wdata->current_names, input);
+        if(dup) {
+            fprintf(stderr, "Name %s already in use\n", input);
+            // TODO: show error in UI
+        }
     }
     
     wdata->valuechange = FALSE;
@@ -328,6 +369,8 @@ static void nbconfig_notebooklist_onselect(UiEvent *event, void *userdata) {
     nbconfig_tab2_load_notebook(wdata, res);
     
     wdata->selected_group = res;
+      
+    nbconfig_build_current_names_map(wdata, res);
 }
 
 static void nbconfig_notebooklist_add(UiEvent *event, void *userdata) {
@@ -502,6 +545,25 @@ static void nbconfig_close(UiEvent *event, void *userdata) {
     nbconfig_notebook_save(wdata);
 }
 
+static void nbconfig_tab_view_changed(UiEvent *event, void *userdata) {
+    NotebookConfigDialog *wdata = event->window;
+    
+    switch(event->intval) {
+        case 0: {
+            if(wdata->selected_group) {
+                nbconfig_build_current_names_map(wdata, wdata->selected_group);
+            }
+            break;
+        }
+        case 1: {
+            if(wdata->selected_notebook) {
+                nbconfig_build_current_names_map(wdata, wdata->selected_notebook);
+            }
+            break;
+        }
+    }
+}
+
 void notebook_config_dialog(void) {
     NoteStore *store = note_store_get();
     // TODO: check store->root and show different dialog, when root is missing
@@ -536,6 +598,8 @@ void notebook_config_dialog(void) {
     wdata->notebooks = cxArrayListCreate(a, CX_STORE_POINTERS, 32);
     wdata->notebook_parents = cxHashMapCreate(a, CX_STORE_POINTERS, 32);
     
+    wdata->current_names = cxHashMapCreate(a, CX_STORE_POINTERS, 16);
+    
     // fill data
     Resource *group1 = NULL;
     Resource *notebook1 = NULL;
@@ -566,7 +630,7 @@ void notebook_config_dialog(void) {
     
     // UI
     ui_grid(obj, .margin = 10, .columnspacing = 10, .rowspacing = 10, .fill = TRUE) {
-        ui_tabview(obj, .hfill = TRUE, .hexpand = TRUE, .vfill = TRUE, .vexpand = TRUE) {
+        ui_tabview(obj, .hfill = TRUE, .hexpand = TRUE, .vfill = TRUE, .vexpand = TRUE, .onchange = nbconfig_tab_view_changed) {
             ui_tab(obj, "Groups") {
                 ui_hbox(obj, .margin = 10, .spacing = 10, .fill = TRUE) {
                     ui_vbox(obj, .fill = FALSE) {
index 06ccf8e2adc22c68d9cdf0173acd7980d2a5924d..d7d917f116acd5b2e4b6c516ff3cabaa66ed43b5 100644 (file)
@@ -64,6 +64,12 @@ typedef struct NotebookConfigDialog {
     Resource *selected_group;
     Resource *selected_notebook;
     Repository *new_repository;
+    char *selected_group_name;
+    char *selected_notebook_name;
+    
+    // a map of all used names in the current context
+    // (all resource names in selected_group -> parent -> children)
+    CxMap *current_names;
     
     // set to true if currently a textfield onchange callback is running
     UiBool valuechange;
@@ -71,6 +77,8 @@ typedef struct NotebookConfigDialog {
     
 void nbconfig_update_lists(NotebookConfigDialog *wdata);
 
+void nbconfig_build_current_names_map(NotebookConfigDialog *wdata, Resource *res);
+
 void notebook_config_dialog(void);
 
 
index 7da333da50cdf2d75f557a1c17669d0bb3ebcf51..ad5297ac802ac4f3818f6c2aa65efe8d1eab0d47 100644 (file)
@@ -733,10 +733,13 @@ typedef void (*ui_tabview_set_func)(UiInteger*, int64_t);
 UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
     UiGtkTabView *data = malloc(sizeof(UiGtkTabView));
     memset(data, 0, sizeof(UiGtkTabView));
+    data->obj = obj;
     data->padding = args->padding;
     data->spacing = args->spacing;
     data->columnspacing = args->columnspacing;
     data->rowspacing = args->rowspacing;
+    data->onchange = args->onchange;
+    data->onchangedata = args->onchangedata;
     
     ui_tabview_get_func getfunc = NULL;
     ui_tabview_set_func setfunc = NULL;