]> uap-core.de Git - note.git/commitdiff
handle note title onchange event and update note item in notes list
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 23 Mar 2025 17:38:51 +0000 (18:38 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 23 Mar 2025 17:38:51 +0000 (18:38 +0100)
application/note.c
application/note.h
application/notebook.c
application/notebook.h
application/window.c
application/window.h
ui/common/context.c
ui/common/types.c
ui/gtk/list.c

index b05b98ad6fe8e45f3b96961a63a763764bfa6be6..b965fb3fb4de678b162dc2c2e9b6cedcd5c007c3 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "store.h"
 #include "editor.h"
+#include "notebook.h"
 
 static TextNoteParagraphStyles paragraph_styles[] = {
     { "Paragraph", EDITOR_STYLE_PARAGRAPH },
@@ -130,8 +131,9 @@ void note_save(UiObject *obj, NotebookModel *notebook, Note *note) {
         // new note
         note_store_new_note_async(obj, note, NULL, NULL);
         notebook->disable_selection_events = TRUE;
+        int index = notebook->notes->count(notebook->notes);
         ui_list_append(notebook->notes, note);
-        ui_list_update(notebook->notes);
+        notebook->notes->update(notebook->notes, index);
         notebook->disable_selection_events = FALSE;
     } else {
         note_store_save_note_async(obj, note, NULL, NULL);
@@ -180,6 +182,22 @@ void note_text_style_set_code(NoteModel *note, UiBool enabled) {
 }
 
 
+
+void note_update_title(NotebookModel *notebook, Note *note) {
+    int index = notebookmode_get_note_index(notebook, note);
+    if(index < 0) {
+        return;
+    }
+    NoteModel *m = note->model;
+    m->modified = TRUE;
+    
+    char *title = ui_get(m->title);
+    cxFree(m->note_allocator, note->title);
+    note->title = cx_strdup_a(m->note_allocator, cx_str(title)).ptr;
+    
+    notebook->notes->update(notebook->notes, index);
+}
+
 const char* note_get_title(Note *note) {
     return note->title ? note->title : note->name;
 }
index c2db4173bf17f37dd479ef1e0504646a5fe1733f..e663d1ce877251fe3a8fe79f6e3d91977600db25 100644 (file)
@@ -59,6 +59,7 @@ void note_text_style_set_emphasis(NoteModel *note, UiBool enabled);
 void note_text_style_set_underline(NoteModel *note, UiBool enabled);
 void note_text_style_set_code(NoteModel *note, UiBool enabled);
 
+void note_update_title(NotebookModel *notebook, Note *note);
 
 const char* note_get_title(Note *note);
 void note_destroy(const CxAllocator *a, Note *note);
index 85d76d5305ccf1b3594b48ff9ad4d5704b053002..58ea1ac3c35d4cef76c53f6b981dffa5dd96d738 100644 (file)
@@ -270,3 +270,9 @@ void notebookmodel_add2navstack(NotebookModel *model) {
     }
     */
 }
+
+int notebookmode_get_note_index(NotebookModel *model, Note *note) {
+    CxList *list = model->notes->data;
+    size_t index = cxListFind(list, note);
+    return cxListIndexValid(list, index) ? index : -1;
+}
index ec7178d49fc3932c194b0d2d5ea9dc90c6c7c0a1..245ca85125ac399ff4697dcb4fa94d069a791dd0 100644 (file)
@@ -56,6 +56,8 @@ void notebookmodel_delete_note(NotebookModel *model);
 
 void notebookmodel_add2navstack(NotebookModel *model);
 
+int notebookmode_get_note_index(NotebookModel *model, Note *note);
+
 
 #ifdef __cplusplus
 }
index 3d8ec1de7bef0f7a3f69097d02e289667b246d21..144b1c91965e78aa4b29f2f6fa5a3aec7cce3c02 100644 (file)
@@ -73,7 +73,7 @@ void window_create() {
                 ui_vbox0(obj) {
                     ui_grid(obj, .margin = 10, .columnspacing = 10, .rowspacing = 10, .def_vfill = TRUE, .fill = UI_OFF) {
                         //ui_label(obj, .label = "Title", .vfill = TRUE);
-                        ui_textfield(obj, .varname = "note_title", .hexpand = TRUE, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED));
+                        ui_textfield(obj, .varname = "note_title", .onchange = action_note_title_changed, .hexpand = TRUE, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED));
                         ui_newline(obj);
                     }
                     ui_hbox(obj, .style_class = "note_toolbar", .margin = 10, .spacing = 4, .fill = UI_OFF) {
@@ -306,6 +306,17 @@ void action_note_activated(UiEvent *event, void *userdata) {
     }
 }
 
+void action_note_title_changed(UiEvent *event, void *userdata) {
+    MainWindow *window = event->window;
+    if(event->set) {
+        return;
+    }
+    NotebookModel *notebook = window->current_notebook;
+    if(notebook && notebook->current_note && notebook->current_note->model) {
+        note_update_title(notebook, notebook->current_note);
+    }
+}
+
 void action_textnote_style_strong(UiEvent *event, void *userdata) {
     if(event->set) {
         return; // only handle user interactions, not events triggered by ui_set
index bb21ee1a30a126f6f3e9644f18591e574558ed68..58233166f8c181c1ad2701fa3ed18f02b9806662 100644 (file)
@@ -56,6 +56,8 @@ void action_notebook_selected(UiEvent *event, void *userdata);
 void action_note_selected(UiEvent *event, void *userdata);
 void action_note_activated(UiEvent *event, void *userdata);
 
+void action_note_title_changed(UiEvent *event, void *userdata);
+
 void action_textnote_paragraph(UiEvent *event, void *userdata);
 void action_textnote_style_strong(UiEvent *event, void *userdata);
 void action_textnote_style_emphasis(UiEvent *event, void *userdata);
index 6969d1e1eb15fb6a2b1195e28bc21c1b00fa6aa0..585719440a876aff444f73c600815f475547bfb4 100644 (file)
@@ -101,7 +101,7 @@ void uic_context_attach_document(UiContext *ctx, void *document) {
         if(var_ctx->vars_unbound &&  cxMapSize(var_ctx->vars_unbound) > 0) {
             CxMapIterator i = cxMapIterator(var_ctx->vars_unbound);
             cx_foreach(CxMapEntry*, entry, i) {
-                printf("attach %.*s\n", (int)entry->key->len, entry->key->data);
+                printf("attach %s\n", entry->key->data);
                 UiVar *var = entry->value;
                 UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key);
                 if(docvar) {
index ab04faafca7a88b8f738e4e17d97bf87ee602596..8bd07a6f3f548b0f743a146c5bb507f72880b89e 100644 (file)
@@ -162,9 +162,7 @@ void ui_list_clear(UiList *list) {
 
 UIEXPORT void ui_list_update(UiList *list) {
     if(list->update) {
-        ui_setop_enable(TRUE);
         list->update(list, -1);
-        ui_setop_enable(FALSE);
     }
 }
 
index c3a2cfdd490974419e4f8a775fbb5e8b96588636..274322089c6d30d6f727568e2f7a7204126962b1 100644 (file)
@@ -579,7 +579,17 @@ void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm)
 
 void ui_listview_update2(UiList *list, int i) {
     UiListView *view = list->obj;
-    ui_update_liststore(view->liststore, list);
+    if(i < 0) {
+        ui_update_liststore(view->liststore, list);
+    } else {
+        void *value = list->get(list, i);
+        if(value) {
+            ObjWrapper *obj = obj_wrapper_new(value);
+            // TODO: if index i is selected, the selection is lost
+            // is it possible to update the item without removing it?
+            g_list_store_splice(view->liststore, i, 1, (void **)&obj, 1);
+        }
+    }
 }
 
 UiListSelection ui_listview_getselection2(UiList *list) {
@@ -639,6 +649,86 @@ void ui_combobox_setselection(UiList *list, UiListSelection selection) {
 
 #else
 
+static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, void *elm) {
+    // set column values
+    int c = 0;
+    for(int i=0;i<model->columns;i++,c++) {
+        void *data = model->getvalue(elm, c);
+
+        GValue value = G_VALUE_INIT;
+        switch(model->types[i]) {
+            case UI_STRING: 
+            case UI_STRING_FREE: {
+                g_value_init(&value, G_TYPE_STRING);
+                g_value_set_string(&value, data);
+                if(model->types[i] == UI_STRING_FREE) {
+                    free(data);
+                }
+                break;
+            }
+            case UI_INTEGER: {
+                g_value_init(&value, G_TYPE_INT);
+                intptr_t intptr = (intptr_t)data;
+                g_value_set_int(&value, (int)intptr);
+                break;
+            }
+            case UI_ICON: {
+                g_value_init(&value, G_TYPE_OBJECT);
+                UiIcon *icon = data;
+#if GTK_MAJOR_VERSION >= 4
+                g_value_set_object(&value, icon->info); // TODO: does this work?
+#else
+                if(!icon->pixbuf && icon->info) {
+                    GError *error = NULL;
+                    GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
+                    icon->pixbuf = pixbuf;
+                }
+
+                if(icon->pixbuf) {
+                    g_value_set_object(&value, icon->pixbuf);
+                }
+#endif
+                break;
+            }
+            case UI_ICON_TEXT:
+            case UI_ICON_TEXT_FREE: {
+                UiIcon *icon = data;
+#if GTK_MAJOR_VERSION >= 4
+                if(icon) {
+                    GValue iconvalue = G_VALUE_INIT;
+                    g_value_init(&iconvalue, G_TYPE_OBJECT);
+                    g_value_set_object(&iconvalue, ui_icon_pixbuf(icon));
+                    gtk_list_store_set_value(store, &iter, c, &iconvalue);
+                }
+#else
+                GValue pixbufvalue = G_VALUE_INIT;
+                if(icon) {
+                    if(!icon->pixbuf && icon->info) {
+                        GError *error = NULL;
+                        GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
+                        icon->pixbuf = pixbuf;
+                    }
+                    g_value_init(&pixbufvalue, G_TYPE_OBJECT);
+                    g_value_set_object(&pixbufvalue, icon->pixbuf);
+                    gtk_list_store_set_value(store, iter, c, &pixbufvalue);
+                }
+#endif
+                c++;
+
+                char *str = model->getvalue(elm, c);
+                g_value_init(&value, G_TYPE_STRING);
+                g_value_set_string(&value, str);
+                if(model->types[i] == UI_ICON_TEXT_FREE) {
+                    free(str);
+                }
+                break;
+            }
+        }
+
+        gtk_list_store_set_value(store, iter, c, &value);
+    }
+}
+
 static GtkListStore* create_list_store(UiList *list, UiModel *model) {
     int columns = model->columns;
     GType types[2*columns];
@@ -666,83 +756,7 @@ static GtkListStore* create_list_store(UiList *list, UiModel *model) {
             GtkTreeIter iter;
             gtk_list_store_insert (store, &iter, -1);
             
-            // set column values
-            int c = 0;
-            for(int i=0;i<columns;i++,c++) {
-                void *data = model->getvalue(elm, c);
-                
-                GValue value = G_VALUE_INIT;
-                switch(model->types[i]) {
-                    case UI_STRING: 
-                    case UI_STRING_FREE: {
-                        g_value_init(&value, G_TYPE_STRING);
-                        g_value_set_string(&value, data);
-                        if(model->types[i] == UI_STRING_FREE) {
-                            free(data);
-                        }
-                        break;
-                    }
-                    case UI_INTEGER: {
-                        g_value_init(&value, G_TYPE_INT);
-                        intptr_t intptr = (intptr_t)data;
-                        g_value_set_int(&value, (int)intptr);
-                        break;
-                    }
-                    case UI_ICON: {
-                        g_value_init(&value, G_TYPE_OBJECT);
-                        UiIcon *icon = data;
-#if GTK_MAJOR_VERSION >= 4
-                        g_value_set_object(&value, icon->info); // TODO: does this work?
-#else
-                        if(!icon->pixbuf && icon->info) {
-                            GError *error = NULL;
-                            GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
-                            icon->pixbuf = pixbuf;
-                        }
-                        
-                        if(icon->pixbuf) {
-                            g_value_set_object(&value, icon->pixbuf);
-                        }
-#endif
-                        break;
-                    }
-                    case UI_ICON_TEXT:
-                    case UI_ICON_TEXT_FREE: {
-                        UiIcon *icon = data;
-#if GTK_MAJOR_VERSION >= 4
-                        if(icon) {
-                            GValue iconvalue = G_VALUE_INIT;
-                            g_value_init(&iconvalue, G_TYPE_OBJECT);
-                            g_value_set_object(&iconvalue, ui_icon_pixbuf(icon));
-                            gtk_list_store_set_value(store, &iter, c, &iconvalue);
-                        }
-#else
-                        GValue pixbufvalue = G_VALUE_INIT;
-                        if(icon) {
-                            if(!icon->pixbuf && icon->info) {
-                                GError *error = NULL;
-                                GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
-                                icon->pixbuf = pixbuf;
-                            }
-                            g_value_init(&pixbufvalue, G_TYPE_OBJECT);
-                            g_value_set_object(&pixbufvalue, icon->pixbuf);
-                            gtk_list_store_set_value(store, &iter, c, &pixbufvalue);
-                        }
-#endif
-                        c++;
-                        
-                        char *str = model->getvalue(elm, c);
-                        g_value_init(&value, G_TYPE_STRING);
-                        g_value_set_string(&value, str);
-                        if(model->types[i] == UI_ICON_TEXT_FREE) {
-                            free(str);
-                        }
-                        break;
-                    }
-                }
-                
-                gtk_list_store_set_value(store, &iter, c, &value);
-            }
+            update_list_row(store, &iter, model, elm);
             
             // next row
             elm = list->next(list);
@@ -1039,9 +1053,18 @@ UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
 
 void ui_listview_update(UiList *list, int i) {
     UiListView *view = list->obj;
-    GtkListStore *store = create_list_store(list, view->model);
-    gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store));
-    g_object_unref(G_OBJECT(store));
+    if(i < 0) {
+        GtkListStore *store = create_list_store(list, view->model);
+        gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store));
+        g_object_unref(G_OBJECT(store));
+    } else {
+        void *elm = list->get(list, i);
+        GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget));
+        GtkTreeIter iter;
+        if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) {
+            update_list_row(GTK_LIST_STORE(store), &iter, view->model, elm);
+        }
+    }
 }
 
 UiListSelection ui_listview_getselection(UiList *list) {