]> uap-core.de Git - note.git/commitdiff
save selection when switching notebooks main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 4 Jun 2026 18:36:49 +0000 (20:36 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 4 Jun 2026 18:36:49 +0000 (20:36 +0200)
ui-rs/src/ui/toolkit.rs
ui/common/Makefile [new file with mode: 0644]
ui/common/context.c
ui/common/context.h
ui/common/types.c
ui/common/types.h
ui/common/wrapper.c
ui/common/wrapper.h
ui/gtk/list.c
ui/ui/toolkit.h

index b36bf72c99385f018d15e47accba6e06179332ea..394626b56af7ba197d2edd088eb54315746f7e5f 100644 (file)
@@ -835,6 +835,24 @@ impl<T> UiList<T> {
             ui_list_setselection2(self.ptr, index, trigger_event as i32);
         }
     }
+    
+    pub fn set_save_selection(&mut self, enable: bool) {
+        unsafe {
+            ui_list_set_save_selection(self.ptr, enable as c_int);
+        }
+    }
+
+    pub fn get_save_selection(&self) -> bool {
+        unsafe {
+            ui_list_get_save_selection(self.ptr) != 0
+        }
+    }
+
+    pub fn clear_saved_selection(&mut self) {
+        unsafe {
+            ui_list_clear_saved_selection(self.ptr);
+        }
+    }
 }
 
 impl<T> Drop for UiList<T> {
@@ -1223,6 +1241,9 @@ extern "C" {
     pub fn ui_list_get_data(list: *const ffi::UiList) -> *mut c_void;
     fn ui_list_get_iter(list: *mut ffi::UiList) -> *mut c_void;
     fn ui_list_set_iter(list: *mut ffi::UiList, iter: *mut c_void);
+    fn ui_list_set_save_selection(list: *mut ffi::UiList, value: c_int);
+    fn ui_list_get_save_selection(list: *const ffi::UiList) -> c_int;
+    fn ui_list_clear_saved_selection(list: *mut ffi::UiList);
 
     fn ui_list_update(list: *mut ffi::UiList);
     fn ui_list_update_row(list: *mut ffi::UiList, row: c_int);
diff --git a/ui/common/Makefile b/ui/common/Makefile
new file mode 100644 (file)
index 0000000..703da14
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2012 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.
+#
+
+FORCE:
+
+$(COMMON_OBJPRE)uic_action$(OBJ_EXT): common/action.c common/action.h \
+ common/../ui/toolkit.h common/context.h common/object.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_app$(OBJ_EXT): common/app.c common/app.h \
+ common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_args$(OBJ_EXT): common/args.c common/args.h \
+ common/../ui/window.h common/../ui/toolkit.h common/../ui/container.h \
+ common/../ui/display.h common/../ui/button.h common/../ui/entry.h \
+ common/../ui/menu.h common/../ui/toolbar.h common/../ui/list.h \
+ common/../ui/text.h common/../ui/webview.h common/../ui/widget.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_condvar$(OBJ_EXT): common/condvar.c common/condvar.h \
+ common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_container$(OBJ_EXT): common/container.c \
+ common/container.h common/../ui/container.h common/../ui/toolkit.h \
+ common/object.h common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_context$(OBJ_EXT): common/context.c common/context.h \
+ common/../ui/toolkit.h common/action.h common/../ui/window.h \
+ common/../ui/toolkit.h common/../ui/widget.h common/document.h \
+ common/types.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_document$(OBJ_EXT): common/document.c \
+ common/document.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_icons$(OBJ_EXT): common/icons.c common/icons.h \
+ common/../ui/icons.h common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_menu$(OBJ_EXT): common/menu.c common/menu.h \
+ common/../ui/menu.h common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_message$(OBJ_EXT): common/message.c common/message.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_object$(OBJ_EXT): common/object.c common/object.h \
+ common/../ui/toolkit.h common/context.h common/action.h \
+ common/../ui/container.h common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_properties$(OBJ_EXT): common/properties.c \
+ common/../ui/toolkit.h common/properties.h common/../ui/properties.h \
+ common/../ui/toolkit.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_threadpool$(OBJ_EXT): common/threadpool.c \
+ common/threadpool.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_toolbar$(OBJ_EXT): common/toolbar.c common/toolbar.h \
+ common/../ui/toolbar.h common/../ui/toolkit.h common/menu.h \
+ common/../ui/menu.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_types$(OBJ_EXT): common/types.c common/../ui/list.h \
+ common/../ui/toolkit.h common/types.h common/../ui/toolkit.h \
+ common/context.h common/action.h common/../ui/image.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_utils$(OBJ_EXT): common/utils.c common/utils.h \
+ common/../ui/toolkit.h common/../ui/text.h common/../ui/toolkit.h \
+ common/properties.h common/../ui/properties.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_wrapper$(OBJ_EXT): common/wrapper.c common/wrapper.h \
+ common/../ui/toolkit.h common/../ui/list.h common/../ui/toolkit.h \
+ common/../ui/text.h common/types.h
+       $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
index b3695784a16beb996d652b6a2f7e7513fee9b6ac..c2eb53df8b7a57e152c6ce4eb2308cb967a3a893 100644 (file)
@@ -71,9 +71,6 @@ UiContext* uic_context(UiObject *toplevel, CxMempool *mp) {
     ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8);
     ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0);
     
-    ctx->attach_document = uic_context_attach_document;
-    ctx->detach_document2 = uic_context_detach_document;
-    
 #if UI_GTK2 || UI_GTK3
     if(toplevel && toplevel->widget) {
         ctx->accel_group = gtk_accel_group_new();
@@ -141,29 +138,20 @@ void uic_context_destroy(UiContext *ctx, void *document) {
     cxMempoolFree(ctx->mp);
 }
 
-void uic_context_attach_document(UiContext *ctx, void *document) {
-    if(ctx->single_document_mode) {
-        if(ctx->document) {
-            uic_context_detach_document(ctx, ctx->document);
-        }
-    }
-    
-    cxListAdd(ctx->documents, document);
-    ctx->document = document;
-    
-    UiContext *doc_ctx = ui_document_context(document);
-    doc_ctx->parent = ctx;
-    doc_ctx->ref++;
-    
+void uic_context_update_bindings(UiContext *ctx) {
+    int onchange_enabled = ui_onchange_events_is_enabled();
+    int onselection_enabled = ui_selection_events_is_enabled();
+    ui_onchange_events_enable(FALSE);
+    ui_selection_events_enable(FALSE);
     // if a document variable has the same name as a parent variable,
     // move the bindings to the document
-    UiContext *var_ctx = ctx;
+    UiContext *var_ctx = ctx->parent;
     while(var_ctx) {
         CxMapIterator i = cxMapIterator(var_ctx->vars);
         cx_foreach(CxMapEntry*, entry, i) {
-            printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+            // printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
             UiVar *var = entry->value;
-            UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key);
+            UiVar *docvar = cxMapGet(ctx->vars, *entry->key);
             if(docvar) {
                 // bind var to document var
                 uic_copy_var_binding(var, docvar, TRUE);
@@ -175,13 +163,43 @@ void uic_context_attach_document(UiContext *ctx, void *document) {
     }
       
     ui_update_action_bindings(ctx);
+    
+    if(ctx->documents) {
+        CxIterator i = cxListIterator(ctx->documents);
+        cx_foreach(void *, doc, i) {
+            UiContext *subctx = ui_document_context(doc);
+            uic_context_update_bindings(subctx);
+        }
+    }
+    ui_onchange_events_enable(onchange_enabled);
+    ui_selection_events_enable(onselection_enabled);
+}
+
+void uic_context_attach_document(UiContext *ctx, void *document) {
+    if(ctx->single_document_mode) {
+        if(ctx->document) {
+            uic_context_detach_document(ctx, ctx->document);
+        }
+    }
+    
+    cxListAdd(ctx->documents, document);
+    ctx->document = document;
+    
+    UiContext *doc_ctx = ui_document_context(document);
+    doc_ctx->parent = ctx;
+    doc_ctx->ref++;
+    
+    uic_context_update_bindings(doc_ctx);
 }
 
 static void uic_context_unbind_vars(UiContext *ctx) {
+    int onchange_enabled = ui_onchange_events_is_enabled();
+    int onselection_enabled = ui_selection_events_is_enabled();
     ui_onchange_events_enable(FALSE);
+    ui_selection_events_enable(FALSE);
     CxMapIterator mi = cxMapIterator(ctx->vars);
     cx_foreach(CxMapEntry*, entry, mi) {
-        printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+        //printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
         UiVar *var = entry->value;
         // var->from && var->from_ctx && var->from_ctx != ctx
         uic_save_var(var);
@@ -201,7 +219,8 @@ static void uic_context_unbind_vars(UiContext *ctx) {
         }
     }
     
-    ui_onchange_events_enable(TRUE);
+    ui_onchange_events_enable(onchange_enabled);
+    ui_selection_events_enable(onselection_enabled);
 }
 
 void uic_context_detach_document(UiContext *ctx, void *document) {
@@ -233,7 +252,7 @@ void uic_context_detach_all(UiContext *ctx) {
     // detach documents
     i = cxListIterator(ls);
     cx_foreach(void *, doc, i) {
-        ctx->detach_document2(ctx, doc);
+        uic_context_detach_document(ctx, doc);
     }
     
     cxListFree(ls);
@@ -455,8 +474,21 @@ void uic_copy_value_binding(UiVarType type, void *from, void *to) {
         case UI_VAR_LIST: {         
             UiList *f = from;
             UiList *t = to;
+            // save selection
+            ui_list_selection_free(f->saved_selection);
+            if(f->getselection && f->save_selection) {
+                f->saved_selection = ui_list_get_selection_allocated(f);
+            } else {
+                f->saved_selection = NULL;
+            }
+    
             uic_list_copy(f, t);
             ui_list_update(t);
+            if(t->setselection && t->saved_selection) {
+                t->setselection(t, *t->saved_selection);
+            }
+            ui_list_selection_free(t->saved_selection);
+            t->saved_selection = NULL;
             break;
         }
         case UI_VAR_RANGE: {
index d692f16f2f4c5b56a43d35ba818bbc17a81dc612..75be090e2a5cabcf2514bc5d2b3236b4147e1a49 100644 (file)
@@ -80,9 +80,6 @@ struct UiContext {
     CxMap         *actions; // key: action name (string), value: UiAction
     CxList        *action_bindings; // UiActionBinding list
     
-    void (*attach_document)(UiContext *ctx, void *document);
-    void (*detach_document2)(UiContext *ctx, void *document); 
-    
     char          *title;
     
 #ifdef UI_GTK
@@ -139,6 +136,7 @@ void uic_context_remove_destructor(UiContext *ctx, void *data);
 void uic_context_prepare_close(UiContext *ctx);
 void uic_context_destroy(UiContext *ctx, void *document);
 
+void uic_context_update_bindings(UiContext *ctx);
 void uic_context_attach_document(UiContext *ctx, void *document);
 void uic_context_detach_document(UiContext *ctx, void *document);
 void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
index 7105af5ba7bdabd95ee33da1188268e908b17286..bd4d384c8582a5e96e34b40eb0abf9a236e53012 100644 (file)
@@ -121,6 +121,7 @@ UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func listini
     UiList *list = ui_malloc(ctx, sizeof(UiList));
     memset(list, 0, sizeof(UiList));
     listinit(ctx, list, userdata);
+    list->save_selection = TRUE;
     
     if(name && ctx) {
         uic_reg_var(ctx, name, UI_VAR_LIST, list);
@@ -137,6 +138,7 @@ void ui_list_free(UiContext *ctx, UiList *list) {
     } else {
         default_list_destroy(ctx, list, default_list_destroy_userdata);
     }
+    ui_list_selection_free(list->saved_selection);
     ui_free(ctx, list);
 }
 
@@ -219,6 +221,11 @@ void ui_list_notify(UiList *list) {
     ui_notify(list->observers, list);
 }
 
+void ui_list_clear_saved_selection(UiList *list) {
+    ui_list_selection_free(list->saved_selection);
+    list->saved_selection = NULL;
+}
+
 
 typedef struct {
     int  type;
@@ -806,6 +813,15 @@ void uic_range_unbind(UiRange *r) {
 }
 
 void uic_list_unbind(UiList *l) {
+    // save selection
+    ui_list_selection_free(l->saved_selection);
+    if(l->getselection && l->save_selection) {
+        l->saved_selection = ui_list_get_selection_allocated(l);
+    } else {
+        l->saved_selection = NULL;
+    }
+    
+    // unbind
     l->update = NULL;
     l->getselection = NULL;
     l->setselection = NULL;
@@ -820,6 +836,23 @@ void uic_generic_unbind(UiGeneric *g) {
 }
 
 
+
+UiListSelection* ui_list_get_selection_allocated(UiList *list) {
+    UiListSelection *sel = malloc(sizeof(UiListSelection));
+    *sel = ui_list_get_selection(list);
+    return sel;
+    
+}
+
+void ui_list_selection_free(UiListSelection *sel) {
+    if(!sel) {
+        return;
+    }
+    ui_listselection_free(*sel);
+    free(sel);
+}
+
+
 UIEXPORT int ui_list_getselection(UiList *list) {
     int selection = -1;
     if (list->getselection) {
index 2f4a5249ea8bd3e53de2e1f5608c2ba2e4054e35..8723ce0dc7685e4d1b54bd5df9ce3fc9852c55cf 100644 (file)
@@ -61,6 +61,9 @@ void uic_range_unbind(UiRange *r);
 void uic_list_unbind(UiList *l);
 void uic_generic_unbind(UiGeneric *g);
 
+UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
+UIEXPORT void ui_list_selection_free(UiListSelection *sel);
+
 void uic_list_register_observer_destructor(UiContext *ctx, UiList *list, UiObserver *observer);
   
 #ifdef __cplusplus
index 675c6882854f37ed097e943e7513abbb6ba945ee..56194e89a469c5baabd5fb7ac232eb46ac80f4c7 100644 (file)
@@ -98,6 +98,13 @@ void ui_list_set_iter(UiList *list, void *iter) {
     list->iter = iter;
 }
 
+void ui_list_set_save_selection(UiList *list, UiBool value) {
+    list->save_selection = value;
+}
+
+UiBool ui_list_get_save_selection(UiList *list) {
+    return list->save_selection;
+}
 
 /* ------------------------------ UiSublist ------------------------------ */
 
@@ -275,13 +282,6 @@ void ui_sublist_item_set_eventdata(UiSubListItem *item, void *eventdata) {
 
 /* ---------------------------- UiListSelection ---------------------------- */
 
-UiListSelection* ui_list_get_selection_allocated(UiList *list) {
-    UiListSelection *sel = malloc(sizeof(UiListSelection));
-    *sel = ui_list_get_selection(list);
-    return sel;
-    
-}
-
 int ui_list_selection_get_count(UiListSelection *sel) {
     return sel->count;
 }
@@ -299,10 +299,6 @@ UIEXPORT void ui_list_set_selected_indices(UiList *list, int *indices, int num)
     }
 }
 
-void ui_list_selection_free(UiListSelection *sel) {
-    ui_listselection_free(*sel);
-    free(sel);
-}
 
 /* -------------------------- UiTextChangedEvent -------------------------- */
 
index eff32825120bacf6e4b649a31bf450db6502836e..6f7507cc28208a16bfa18b38bcab01e9b49af8da 100644 (file)
@@ -49,6 +49,8 @@ UIEXPORT void ui_mainthread_app_unref();
 UIEXPORT void* ui_list_get_data(UiList *list);
 UIEXPORT void* ui_list_get_iter(UiList *list);
 UIEXPORT void ui_list_set_iter(UiList *list, void *iter);
+UIEXPORT void ui_list_set_save_selection(UiList *list, UiBool value);
+UIEXPORT UiBool ui_list_get_save_selection(UiList *list);
 
 UIEXPORT UiSubList* ui_sublist_new(void);
 UIEXPORT void ui_sublist_set_value(UiSubList *sublist, UiList *value);
@@ -82,11 +84,9 @@ UIEXPORT int ui_event_get_eventdatatype(UiEvent *event);
 UIEXPORT int ui_event_get_int(UiEvent *event);
 UIEXPORT int ui_event_get_set(UiEvent *event);
 
-UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
 UIEXPORT int ui_list_selection_get_count(UiListSelection *sel);
 UIEXPORT int* ui_list_selection_get_rows(UiListSelection *sel);
 UIEXPORT void ui_list_set_selected_indices(UiList *list, int *indices, int num);
-UIEXPORT void ui_list_selection_free(UiListSelection *sel);
 
 UIEXPORT int ui_text_change_event_get_type(UiTextChangeEventData *event);
 UIEXPORT int ui_text_change_event_get_begin(UiTextChangeEventData *event);
index fd686718dbb5b4e06cf0d823bbdb8de3d76ced38..72146873a2f450e2dfb1c2a4a5626ec2a7693389 100644 (file)
@@ -938,6 +938,9 @@ void ui_listview_update2(UiList *list, int i) {
     if(i < 0) {
         cxMapClear(view->bound_rows);
         ui_update_liststore(view->liststore, list);
+        free(view->selection.rows);
+        view->selection.rows = NULL;
+        view->selection.count = 0;
     } else {
         void *value = list->get(list, i);
         if(value) {
index 0184d85fb49c573d20cd421929ec7e1dac98a6ae..0e89071046fbe56047a80870f6d26030391ec1f1 100644 (file)
@@ -419,29 +419,33 @@ typedef void (*ui_list_destroy_func)(UiContext *ctx, UiList *list, void *userdat
  * abstract list
  */
 struct UiList {
-    /* destructor */
+    // destructor
     ui_list_destroy_func destroy;
-    /* get the first element */
+    // get the first element
     void*(*first)(UiList *list);
-    /* get the next element */
+    // get the next element
     void*(*next)(UiList *list);
-    /* get the nth element */
+    // get the nth element
     void*(*get)(UiList *list, int i);
-    /* get the number of elements */
+    // get the number of elements 
     int(*count)(UiList *list);
-    /* iterator changes after first() next() and get() */
+    // iterator changes after first() next() and get() 
     void *iter;
-    /* private - implementation dependent */
+    // private - implementation dependent
     void *data;
     
-    /* binding functions */
+    // binding functions 
     void (*update)(UiList *list, int i);
     UiListSelection (*getselection)(UiList *list);
     void (*setselection)(UiList *list, UiListSelection selection);
-    /* binding object */
+    // binding object
     void *obj;
+    // saved selection after unbind
+    UiListSelection *saved_selection;
+    // enable selection saving
+    UiBool save_selection;
     
-    /* list of observers */
+    // list of observers
     UiObserver *observers;
 };
 
@@ -695,6 +699,7 @@ UIEXPORT UiListSelection ui_list_get_selection(UiList *list);
 UIEXPORT void ui_list_set_selection(UiList *list, UiListSelection sel);
 UIEXPORT void ui_list_addobsv(UiList *list, ui_callback f, void *data);
 UIEXPORT void ui_list_notify(UiList *list);
+UIEXPORT void ui_list_clear_saved_selection(UiList *list);
 
 UIEXPORT int ui_list_getselection(UiList *list);
 UIEXPORT void ui_list_setselection(UiList *list, int index);