]> uap-core.de Git - note.git/commitdiff
add backend initialization error handling
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 10 May 2026 09:29:20 +0000 (11:29 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 10 May 2026 09:29:20 +0000 (11:29 +0200)
21 files changed:
application/src/backend.rs
application/src/main.rs
ui/common/container.c
ui/common/object.c
ui/common/object.h
ui/gtk/button.c
ui/gtk/container.c
ui/gtk/container.h
ui/gtk/toolkit.c
ui/gtk/window.c
ui/motif/container.c
ui/motif/container.h
ui/motif/window.c
ui/qt/container.cpp
ui/qt/container.h
ui/qt/text.cpp
ui/server/container.c
ui/server/container.h
ui/ui/button.h
ui/ui/container.h
ui/ui/toolkit.h

index 8cff0884431b9afd1749918661ef89df88b04ff6..fa8c4d8a478e76f96754df0d6b515a09031aeadd 100644 (file)
@@ -47,7 +47,7 @@ impl Backend {
 
     pub fn load_profile(
         &self,
-        profile_id: i32,
+        profile_id: Option<i32>,
         host: &str,
         user: &str,
     ) -> Result<usersettings::Model, DbErr> {
@@ -56,22 +56,21 @@ impl Backend {
         let user = user.to_string();
 
         let profile: usersettings::Model = self.rt.block_on(async {
-
-            // -------------------------------------------------
-            // explicit profile id
-            // -------------------------------------------------
-            if profile_id != 0 {
-                if let Some(model) = UserSettings::find_by_id(profile_id)
+            // If a profile id was specified, we are trying to use that,
+            // but if it doesn't exist, an error is returned
+            if let Some(id) = profile_id {
+                if let Some(model) = UserSettings::find_by_id(id)
                     .one(&self.db)
                     .await?
                 {
                     return Ok::<usersettings::Model, DbErr>(model);
+                } else {
+                    let err = format!("user settings {} not found", id);
+                    return Err::<usersettings::Model, DbErr>(DbErr::RecordNotFound(err));
                 }
             }
 
-            // -------------------------------------------------
-            // existing host/user profile
-            // -------------------------------------------------
+            // Try to find a profile for the specified host/user
             if let Some(model) = UserSettings::find()
                 .filter(usersettings::Column::Host.eq(host.clone()))
                 .filter(usersettings::Column::User.eq(user.clone()))
@@ -81,13 +80,12 @@ impl Backend {
                 return Ok::<usersettings::Model, DbErr>(model);
             }
 
-            // -------------------------------------------------
-            // create new profile
-            // -------------------------------------------------
+            // Create new profile
+            let profile_name = format!("{}/{}", host, user);
             let active = usersettings::ActiveModel {
                 host: Set(host),
                 user: Set(user),
-                profile: Set("default".to_string()),
+                profile: Set(profile_name),
                 root_id: Set(0),
 
                 ..Default::default()
@@ -96,7 +94,6 @@ impl Backend {
             let inserted = active.insert(&self.db).await?;
 
             Ok::<usersettings::Model, DbErr>(inserted)
-
         })?;
 
         Ok(profile)
index 270962178596f609c66bb13da82d9f3dcd48c9f9..537c18deae3eb9e40e22bc1ac878ccd622cb455e 100644 (file)
@@ -29,6 +29,7 @@
 mod window;
 mod backend;
 
+use std::env;
 use ui_rs::{ui};
 use ui_rs::ui::*;
 use crate::backend::Backend;
@@ -37,24 +38,64 @@ use crate::window::*;
 fn main() {
     ui::app_init("note");
 
-    let backend_result = Backend::new();
-    if !backend_result.is_ok() {
-        println!("Error while initializing backend");
-        return;
-    }
-    let mut backend = backend_result.unwrap();
-    backend.migrate().unwrap(); // todo: check error
-    let settings_result = backend.load_profile(0, "testhost", "testuser");
-    if !settings_result.is_ok() {
-        println!("Error while loading profile");
-        return;
-    }
-    backend.current_profile = Some(settings_result.unwrap());
+    let backend = match init_backend() {
+        Ok(backend) => backend,
+        Err(e) => {
+            app_run_startup_error(e.title.as_str(), e.message.as_str());
+            return;
+        }
+    };
 
     let mut app = App { backend: backend };
     ui::app_run::<MainWindow>(&mut app);
 }
 
+struct ErrMsg {
+    title: String,
+    message: String
+}
+
+/// Initializes the backend
+///
+/// This includes:
+///
+///  - Connecting to the database
+///  - Migrating the database
+///  - Getting the user profile / settings
+///
+/// If no profile exists yet, a new profile is created
+fn init_backend() -> Result<Backend, ErrMsg> {
+    let mut backend = match Backend::new() {
+        Ok(backend) => backend,
+        Err(e) => return Err( ErrMsg {
+                title: "Backend initialization failed".to_string(),
+                message: e.to_string()
+            })
+    };
+
+    match backend.migrate() {
+        Ok(_) => (),
+        Err(e) => return Err(ErrMsg {
+                title: "Database migration failed".to_string(),
+                message: e.to_string()
+            })
+    };
+
+    let host = hostname();
+    let user = username();
+
+    let profile = match backend.load_profile(None, host.as_str(), user.as_str()) {
+        Ok(profile) => profile,
+        Err(e) => return Err(ErrMsg {
+            title: "Cannot load user settings".to_string(),
+            message: e.to_string()
+        })
+    };
+    backend.current_profile = Some(profile);
+
+    Ok(backend)
+}
+
 struct App {
     backend: Backend,
 }
@@ -80,4 +121,55 @@ fn create_toolbar(app: &AppContext<MainWindow>) {
     app.toolbar_add_default("go_back", ToolbarItemPosition::Left);
     app.toolbar_add_default("go_forward", ToolbarItemPosition::Left);
     app.toolbar_add_default("new_note", ToolbarItemPosition::Left);
-}
\ No newline at end of file
+}
+
+
+fn username() -> String {
+    env::var("USER")
+        .or_else(|_| env::var("USERNAME"))
+        .unwrap_or_else(|_| "unknown".to_string())
+}
+
+#[cfg(unix)]
+fn hostname() -> String {
+    use std::ffi::CStr;
+    use std::os::raw::{c_char, c_int};
+
+    unsafe extern "C" {
+        fn gethostname(name: *mut c_char, len: usize) -> c_int;
+    }
+
+    let mut buf = [0u8; 256];
+
+    unsafe {
+        if gethostname(buf.as_mut_ptr() as *mut c_char, buf.len()-1) != 0 {
+            return "unknown".into();
+        }
+
+        // Ensure termination
+        buf[buf.len() - 1] = 0;
+
+        CStr::from_ptr(buf.as_ptr() as *const c_char)
+            .to_string_lossy()
+            .into_owned()
+    }
+}
+
+#[cfg(windows)]
+fn hostname() -> String {
+    #[link(name = "Kernel32")]
+    unsafe extern "system" {
+        fn GetComputerNameW(lpBuffer: *mut u16, nSize: *mut u32) -> i32;
+    }
+
+    let mut buf = [0u16; 256];
+    let mut size = buf.len() as u32;
+
+    unsafe {
+        if GetComputerNameW(buf.as_mut_ptr(), &mut size) == 0 {
+            return "unknown".into();
+        }
+
+        String::from_utf16_lossy(&buf[..size as usize])
+    }
+}
index 6f0dde99465680b45d09170db06832b5d64836a4..12c62676107e6118043c2d1c11a187204d8e96a1 100644 (file)
@@ -33,13 +33,13 @@ void ui_end_new(UiObject *obj) {
     if(!obj->container_end) {
         return;
     }
-    UiContainerX *rm = obj->container_end;
+    UiContainer *rm = obj->container_end;
     uic_object_pop_container(obj);
     ui_free(obj->ctx, rm);
 }
 
 void ui_newline(UiObject *obj) {
-    UiContainerX *container = obj->container_end;
+    UiContainer *container = obj->container_end;
     if(container) {
         container->newline = TRUE;
     }
index 150cd43cd1008792cf4cd39246b0e7bcbad63cce..4cbd4d9797b06585c900ed11b3ad98810495ceae 100644 (file)
@@ -119,7 +119,7 @@ UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget) {
     return newobj;
 }
 
-void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer) {
+void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer) {
     newcontainer->prev = toplevel->container_end;
     if(toplevel->container_end) {
         toplevel->container_end->next = newcontainer;
@@ -148,8 +148,8 @@ void uic_object_pop_container(UiObject *toplevel) {
  */
 void uic_object_remove_second_last_container(UiObject *toplevel) {
     if(toplevel->container_end && toplevel->container_end->prev) {
-        UiContainerX *end = toplevel->container_end;
-        UiContainerX *rm = toplevel->container_end->prev;
+        UiContainer *end = toplevel->container_end;
+        UiContainer *rm = toplevel->container_end->prev;
         
         end->prev = rm->prev;
         if(rm->prev) {
index 43278752ef904f4cef2741721d3b639f66ff6832..c809c822d1583b658dc7853c5faf3fb0919dc213 100644 (file)
@@ -55,7 +55,7 @@ UiObject* uic_object_new_toplevel(void);
 UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget);
 UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget);
 
-void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer);
+void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer);
 void uic_object_pop_container(UiObject *toplevel);
 void uic_object_remove_second_last_container(UiObject *toplevel);
 
index e72f7a7badfd8e10abaf5aaaa7057d4e484d81b5..b8c08676977f96e4c665bae427933c7f1a6c392e 100644 (file)
@@ -153,6 +153,47 @@ void ui_button_set_icon(UIWIDGET button, const char *icon) {
     ui_button_set_icon_name(button, icon);
 }
 
+void ui_button_set_tooltip(UIWIDGET button, const char *tooltip) {
+    gtk_widget_set_tooltip_text(GTK_WIDGET(button), tooltip);
+}
+
+void ui_togglebutton_set_label(UIWIDGET button, const char *label) {
+    ui_button_set_label(button, label);
+}
+
+void ui_togglebutton_set_icon(UIWIDGET button, const char *icon) {
+    ui_button_set_icon(button, icon);
+}
+
+void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip) {
+    ui_button_set_tooltip(button, tooltip);
+}
+
+void ui_checkbox_set_label(UIWIDGET button, const char *label) {
+    ui_button_set_label(button, label);
+}
+
+void ui_checkbox_set_icon(UIWIDGET button, const char *icon) {
+    ui_button_set_icon(button, icon);
+}
+
+void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip) {
+    ui_button_set_tooltip(button, tooltip);
+}
+
+void ui_radiobutton_set_label(UIWIDGET button, const char *label) {
+    ui_button_set_label(button, label);
+}
+
+void ui_radiobutton_set_icon(UIWIDGET button, const char *icon) {
+    ui_button_set_icon(button, icon);
+}
+
+void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip) {
+    ui_button_set_tooltip(button, tooltip);
+}
+
+
 int64_t ui_toggle_button_get(UiInteger *integer) {
     GtkToggleButton *button = integer->obj;
     integer->value = (int)gtk_toggle_button_get_active(button);
@@ -880,16 +921,7 @@ static void linkbutton_callback(GtkWidget *widget, UiLinkButton *data) {
 static void linkbutton_clicked(GtkWidget *widget, UiLinkButton *data) {
     linkbutton_callback(widget, data);
     if(data->link) {   
-#if GTK_CHECK_VERSION(4, 0, 0)
-        GtkUriLauncher *launcher = gtk_uri_launcher_new (data->link);
-        gtk_uri_launcher_launch (launcher, NULL, NULL, NULL, NULL);
-        g_object_unref (launcher);
-#elif GTK_CHECK_VERSION(3, 22, 0)
-        GError *error = NULL;
-        gtk_show_uri_on_window(NULL, data->link, GDK_CURRENT_TIME, &error);
-#elif
-        // TODO: call xdg-open
-#endif
+        ui_open_uri(data->link);
     }
 }
 
index 5489ecbdc232f26da8d95e670ded6299332c3248..30960ffb5f0490793f954b5b1e800a0d7d58f29b 100644 (file)
 
 
 void ui_container_begin_close(UiObject *obj) {
-    UiContainerX *ct = obj->container_end;
+    UiContainer *ct = obj->container_end;
     ct->close = 1;
 }
 
 int ui_container_finish(UiObject *obj) {
-    UiContainerX *ct = obj->container_end;
+    UiContainer *ct = obj->container_end;
     if(ct->close) {
         ui_end_new(obj);
         return 0;
@@ -82,7 +82,7 @@ GtkWidget* ui_subcontainer_create(
 {
     GtkWidget *sub = NULL;
     GtkWidget *add = NULL;
-    UiContainerX *container = NULL;
+    UiContainer *container = NULL;
     switch(type) {
         default: {
             sub = ui_gtk_vbox_new(spacing);
@@ -125,11 +125,11 @@ void ui_custom_container_create(UiObject *obj, UIWIDGET widget, ui_addwidget_fun
     container->container.widget = widget;
     container->add = add_child;
     container->userdata = userdata;
-    uic_object_push_container(obj, (UiContainerX*)container);
+    uic_object_push_container(obj, (UiContainer*)container);
 }
 
 /* -------------------- Box Container -------------------- */
-UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) {
+UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) {
     UiBoxContainer *ct = cxCalloc(
             obj->ctx->allocator,
             1,
@@ -137,7 +137,7 @@ UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType
     ct->container.widget = box;
     ct->container.add = ui_box_container_add;
     ct->type = type;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -172,7 +172,7 @@ void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *l
 #endif
 }
 
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
         UiObject *obj,
         GtkWidget *grid,
         UiBool def_hexpand,
@@ -192,7 +192,7 @@ UiContainerX* ui_grid_container(
     ct->container.add = ui_grid_container_add;
     UI_GTK_V2(ct->width = 0);
     UI_GTK_V2(ct->height = 1);
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 
@@ -271,14 +271,14 @@ void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget) {
 }
 #endif
 
-UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame) {
+UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) {
     UiContainerPrivate *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiContainerPrivate));
     ct->widget = frame;
     ct->add = ui_frame_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -286,14 +286,14 @@ void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout
     FRAME_SET_CHILD(ct->widget, widget);
 }
 
-UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander) {
+UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander) {
     UiContainerPrivate *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiContainerPrivate));
     ct->widget = expander;
     ct->add = ui_expander_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -307,24 +307,24 @@ void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget,
     SCROLLEDWINDOW_SET_CHILD(ct->widget, widget);
 }
 
-UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) {
+UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) {
     UiContainerPrivate *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiContainerPrivate));
     ct->widget = scrolledwindow;
     ct->add = ui_scrolledwindow_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
-UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview) {
+UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview) {
     UiTabViewContainer *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiTabViewContainer));
     ct->container.widget = tabview;
     ct->container.add = ui_tabview_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -390,7 +390,7 @@ UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType
     ui_set_name_and_style(box, args->name, args->style_class);
     ct->add(ct, box, &layout);
     
-    UiContainerX *container = ui_box_container(obj, box, type);
+    UiContainer *container = ui_box_container(obj, box, type);
     uic_object_push_container(obj, container);
     
     uic_widget_set_visibility_states(obj->ctx, box, args->visibility_states);
@@ -428,7 +428,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
     ui_set_name_and_style(grid, args->name, args->style_class);
     ct->add(ct, grid, &layout);
     
-    UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
+    UiContainer *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
     uic_object_push_container(obj, container);
     
     uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states);
@@ -476,7 +476,7 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) {
     if(sub) {
         FRAME_SET_CHILD(frame, sub);
     } else {
-        UiContainerX *container = ui_frame_container(obj, frame);
+        UiContainer *container = ui_frame_container(obj, frame);
         uic_object_push_container(obj, container);
     }
     
@@ -502,7 +502,7 @@ UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) {
     if(sub) {
         EXPANDER_SET_CHILD(expander, sub);
     } else {
-        UiContainerX *container = ui_expander_container(obj, expander);
+        UiContainer *container = ui_expander_container(obj, expander);
         uic_object_push_container(obj, container);
     }
     
@@ -529,7 +529,7 @@ UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) {
     if(sub) {
         SCROLLEDWINDOW_SET_CHILD(sw, sub);
     } else {
-        UiContainerX *container = ui_scrolledwindow_container(obj, sw);
+        UiContainer *container = ui_scrolledwindow_container(obj, sw);
         uic_object_push_container(obj, container);
     }
     
@@ -821,7 +821,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
     UiLayout layout = UI_ARGS2LAYOUT(args);
     ct->add(ct, widget, &layout);
     
-    UiContainerX *container = ui_tabview_container(obj, widget);
+    UiContainer *container = ui_tabview_container(obj, widget);
     uic_object_push_container(obj, container);
     
     uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
@@ -830,7 +830,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
 }
 
 static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) {
-    UiContainerX *container;
+    UiContainer *container;
     GtkWidget *sub;
     switch(tabview->subcontainer) {
         default: {
@@ -916,7 +916,7 @@ static void hb_set_part(UiObject *obj, int part) {
             sizeof(UiHeaderbarContainer));
     memcpy(hb, ct, sizeof(UiHeaderbarContainer));
     hb->part = part;
-    uic_object_push_container(obj, (UiContainerX*)hb);
+    uic_object_push_container(obj, (UiContainer*)hb);
 }
 
 void ui_headerbar_start_create(UiObject *obj) {
@@ -939,7 +939,7 @@ UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) {
     ui_set_name_and_style(box, args->name, args->style_class);
     ct->add(ct, box, &layout);
     
-    UiContainerX *container = ui_headerbar_fallback_container(obj, box);
+    UiContainer *container = ui_headerbar_fallback_container(obj, box);
     uic_object_push_container(obj, container);
     
     return box;
@@ -949,21 +949,21 @@ static void hb_fallback_set_part(UiObject *obj, int part) {
      UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
     GtkWidget *headerbar = ct->widget;
     
-    UiContainerX *container = ui_headerbar_container(obj, headerbar);
+    UiContainer *container = ui_headerbar_container(obj, headerbar);
     uic_object_push_container(obj, container);
     
     UiHeaderbarContainer *hb = (UiHeaderbarContainer*)container;
     hb->part = part;
 }
 
-UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) {
+UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) {
     UiHeaderbarContainer *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiHeaderbarContainer));
     ct->container.widget = headerbar;
     ct->container.add = ui_headerbar_fallback_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -979,20 +979,20 @@ UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) {
         return ui_headerbar_fallback_create(obj, args);
     }
     
-    UiContainerX *container = ui_headerbar_container(obj, headerbar);
+    UiContainer *container = ui_headerbar_container(obj, headerbar);
     uic_object_push_container(obj, container);
     
     return headerbar;    
 }
 
-UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) {
+UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) {
     UiHeaderbarContainer *ct = cxCalloc(
             obj->ctx->allocator,
             1,
             sizeof(UiHeaderbarContainer));
     ct->container.widget = headerbar;
     ct->container.add = ui_headerbar_container_add;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
@@ -1035,7 +1035,7 @@ UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) {
     ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
     adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box);
     
-    UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+    UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
     
     return box;
@@ -1048,7 +1048,7 @@ UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) {
     ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
     BOX_ADD_EXPAND(sidebar_vbox, box);
     
-    UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+    UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
     
     return box;
@@ -1068,7 +1068,7 @@ static UIWIDGET splitwindow_panel(UiObject *obj, GtkWidget *pbox, UiSidebarArgs
     ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
     BOX_ADD_EXPAND(pbox, box);
     
-    UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+    UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
     
     return box;
@@ -1135,7 +1135,7 @@ static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSpl
     }
     
     UiSplitPane *splitpane = ui_create_splitpane_data(pane0, orientation, max, args->initial_position);
-    UiContainerX *container = ui_splitpane_container(obj, pane0, splitpane);
+    UiContainer *container = ui_splitpane_container(obj, pane0, splitpane);
     uic_object_push_container(obj, container);
     
     g_object_set_data(G_OBJECT(pane0), "ui_splitpane", splitpane);
@@ -1172,12 +1172,12 @@ UiSplitPane* ui_create_splitpane_data(GtkWidget *pane, UiOrientation orientation
     return ct;
 }
 
-UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) {
+UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) {
     UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer));
     ct->container.widget = pane;
     ct->container.add = ui_splitpane_container_add;
     ct->splitpane = data;
-    return (UiContainerX*)ct;
+    return (UiContainer*)ct;
 }
 
 void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
index a5e46b2febf605ee407484900fb7342def5f0bfb..352b50ea01cf6f729eea6aeb96a2f87b8dfe07e2 100644 (file)
@@ -50,7 +50,7 @@ typedef struct UiDocumentView UiDocumentView;
 
 typedef struct UiContainerPrivate UiContainerPrivate;
 struct UiContainerPrivate {
-    UiContainerX container;
+    UiContainer container;
     GtkWidget *widget;
     UIMENU menu;
     
@@ -160,11 +160,11 @@ GtkWidget* ui_subcontainer_create(
 GtkWidget* ui_gtk_set_margin(GtkWidget *widget, int margin, int margin_left, int margin_right, int margin_top, int margin_bottom);
 UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type);
 
-UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type);
+UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type);
 void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
 GtkWidget* ui_create_grid_widget(int colspacing, int rowspacing);
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
         UiObject *obj,
         GtkWidget *grid,
         UiBool def_hexpand,
@@ -173,20 +173,20 @@ UiContainerX* ui_grid_container(
         UiBool def_vfill);
 void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
-UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame);
+UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame);
 void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
-UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander);
+UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander);
 void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
-UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow);
+UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow);
 void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
-UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview);
+UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview);
 void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
 UiSplitPane* ui_create_splitpane_data(GtkWidget *pane, UiOrientation orientation, int max, int init);
-UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data);
+UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data);
 void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
 int64_t ui_splitpane_get(UiInteger *i);
@@ -197,11 +197,11 @@ UiGtkTabView* ui_widget_get_tabview_data(UIWIDGET tabview);
 void ui_gtk_notebook_select_tab(GtkWidget *widget, int tab);
 
 #if GTK_CHECK_VERSION(3, 10, 0)
-UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar);
+UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar);
 void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 #endif
 
-UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar);
+UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar);
 void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
 
 #ifdef __cplusplus
index 0ad0fe83b503e02210c246296a6350ab700fb9e0..6ab00a3ea312cc0a2b9546e0f79c73400e06d8b5 100644 (file)
@@ -572,3 +572,16 @@ void ui_set_widget_nvisibility_states(UiContext *ctx, GtkWidget *widget, const i
         ui_set_visible(widget, FALSE);
     }
 }
+
+void ui_open_uri(const char *uri) {
+#if GTK_CHECK_VERSION(4, 0, 0)
+    GtkUriLauncher *launcher = gtk_uri_launcher_new(uri);
+    gtk_uri_launcher_launch(launcher, NULL, NULL, NULL, NULL);
+    g_object_unref(launcher);
+#elif GTK_CHECK_VERSION(3, 22, 0)
+    GError *error = NULL;
+    gtk_show_uri_on_window(NULL, uri, GDK_CURRENT_TIME, &error);
+#elif
+    // TODO: call xdg-open
+#endif
+}
index 0ef809357db028e13a38df748ae524d46920360a..7952570a712b67456cf28da31c5fd29b76e5252f 100644 (file)
@@ -398,7 +398,7 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
     gtk_container_add(GTK_CONTAINER(frame), content_box);
     obj->container = ui_box_container(obj, content_box);
     */
-    UiContainerX *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX);
+    UiContainer *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
     
     nwindows++;
@@ -503,6 +503,8 @@ static void dialog_response(AdwAlertDialog *self, gchar *response, UiEventData *
     if(data->callback) {
         data->callback(&evt, data->userdata);
     }
+    
+    ui_app_unref();
 }
 
 void ui_dialog_create(UiObject *parent, UiDialogArgs *args) {
@@ -547,7 +549,8 @@ void ui_dialog_create(UiObject *parent, UiDialogArgs *args) {
                 event);
     
     g_signal_connect(dialog, "response", G_CALLBACK(dialog_response), event);
-    adw_dialog_present(dialog, parent->widget);
+    ui_app_ref();
+    adw_dialog_present(dialog, parent ? parent->widget : NULL);
     
     if(entry) {
         gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
@@ -559,8 +562,14 @@ static void ui_dialog_response (GtkDialog* self, gint response_id, gpointer user
     UiEventData *data = user_data;
     UiEvent evt;
     evt.obj = data->obj;
-    evt.document = evt.obj->ctx->document;
-    evt.window = evt.obj->window;
+    if(evt.obj) {
+        evt.document = evt.obj->ctx->document;
+        evt.window = evt.obj->window;
+    } else {
+        evt.document = NULL;
+        evt.window = NULL;
+    }
+    
     evt.eventdata = NULL;
     evt.intval = 0;
     
@@ -975,7 +984,7 @@ UiObject* ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs *args) {
 #endif
     
     GtkWidget *content_vbox = ui_gtk_vbox_new(0);
-    UiContainerX *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX);
+    UiContainer *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
     if(args->lbutton1 || args->lbutton2 || args->rbutton3 || args->rbutton4) {
 #if GTK_CHECK_VERSION(3, 10, 0)
index 73c919808bfb27ae8c11d01683022daa3bf5c67e..d99581adb857ef391dfaebf91106ea74c0d327d2 100644 (file)
@@ -87,7 +87,7 @@ static UIWIDGET box_create(UiObject *obj, UiContainerArgs *args, UiBoxOrientatio
     Widget grid = XtCreateManagedWidget(args->name ? args->name : "boxcontainer", gridClass, parent, xargs, n);
     ctn->add(ctn, grid);
     
-    UiContainerX *container = ui_box_container(obj, grid, orientation);
+    UiContainer *container = ui_box_container(obj, grid, orientation);
     uic_object_push_container(obj, container);
     
     uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states);
@@ -105,14 +105,14 @@ UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) {
     return box_create(obj, args, UI_BOX_HORIZONTAL);
 }
 
-UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation) {
+UiContainer* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation) {
     UiBoxContainer *ctn = ui_malloc(obj->ctx, sizeof(UiBoxContainer));
     memset(ctn, 0, sizeof(UiBoxContainer));
     ctn->container.prepare = orientation == UI_BOX_VERTICAL ? ui_vbox_prepare : ui_hbox_prepare;
     ctn->container.add = ui_box_container_add;
     ctn->container.widget = grid;
     ctn->n = 0;
-    return (UiContainerX*)ctn;
+    return (UiContainer*)ctn;
 }
 
 static Widget ui_box_container_prepare(UiBoxContainer *box, UiLayout *layout, Arg *args, int *n) {
@@ -170,7 +170,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
     Widget grid = XtCreateManagedWidget(args->name ? args->name : "gridcontainer", gridClass, parent, xargs, n);
     ui_container_add(ctn, grid);
     
-    UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
+    UiContainer *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
     uic_object_push_container(obj, container);
     
     uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states);
@@ -178,7 +178,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
     return grid;
 }
 
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
         UiObject *obj,
         Widget grid,
         UiBool def_hexpand,
@@ -197,7 +197,7 @@ UiContainerX* ui_grid_container(
     ctn->def_vexpand = def_vexpand;
     ctn->def_hfill = def_hfill;
     ctn->def_vfill = def_vfill;
-    return (UiContainerX*)ctn;
+    return (UiContainer*)ctn;
 }
 
 Widget ui_grid_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n) {
@@ -275,7 +275,7 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) {
         XmStringFree(s);
     }
     
-    UiContainerX *container = ui_frame_container(obj, frame);
+    UiContainer *container = ui_frame_container(obj, frame);
     uic_object_push_container(obj, container);
     
     UiContainerArgs sub_args = {
@@ -308,13 +308,13 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) {
     return frame;
 }
 
-UiContainerX* ui_frame_container(UiObject *obj, Widget frame) {
+UiContainer* ui_frame_container(UiObject *obj, Widget frame) {
     UiContainerPrivate *ctn = ui_malloc(obj->ctx, sizeof(UiContainerPrivate));
     memset(ctn, 0, sizeof(UiContainerPrivate));
     ctn->prepare = ui_frame_container_prepare;
     ctn->add = ui_frame_container_add;
     ctn->widget = frame;
-    return (UiContainerX*)ctn;
+    return (UiContainer*)ctn;
 }
 
 Widget ui_frame_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n) {
@@ -472,7 +472,7 @@ UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs *args) {
         i->set = ui_tabview_set;
     }
     
-    uic_object_push_container(obj, (UiContainerX*)ct);
+    uic_object_push_container(obj, (UiContainer*)ct);
     
     uic_widget_set_visibility_states(obj->ctx, form, args->visibility_states);
     
@@ -556,7 +556,7 @@ UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index) {
         UiObject *newobj = ui_calloc(tabviewdata->obj->ctx, 1, sizeof(UiObject));
         newobj->ctx = tabviewdata->obj->ctx;
         newobj->widget = grid;
-        UiContainerX *container = ui_box_container(newobj, grid, UI_BOX_VERTICAL);
+        UiContainer *container = ui_box_container(newobj, grid, UI_BOX_VERTICAL);
         newobj->container_begin = container;
         newobj->container_end = container;
         return newobj;
@@ -693,13 +693,13 @@ void ui_scrolledwindow_add(UiContainerPrivate *ctn, Widget widget) {
     
 }
 
-static UiContainerX* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) {
+static UiContainer* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) {
     UiContainerPrivate *ctn = ui_malloc(obj->ctx, sizeof(UiContainerPrivate));
     memset(ctn, 0, sizeof(UiContainerPrivate));
     ctn->prepare = ui_scrolledwindow_prepare;
     ctn->add = ui_scrolledwindow_add;
     ctn->widget = scrolledwindow;
-    return (UiContainerX*)ctn;
+    return (UiContainer*)ctn;
 }
 
 UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) {
@@ -721,7 +721,7 @@ UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) {
     Widget scrolledwindow = XmCreateScrolledWindow(parent, "scrolledwindow", xargs, n);
     ui_container_add(ctn, scrolledwindow);
     
-    UiContainerX *container = ui_scrolledwindow_container(obj, scrolledwindow);
+    UiContainer *container = ui_scrolledwindow_container(obj, scrolledwindow);
     uic_object_push_container(obj, container);
     
     return scrolledwindow;
index 30262e5dee5c23298d62411a39d71f748fef4b9d..afd2c034033ed49890a05167ca90ea7bf12b6802 100644 (file)
@@ -72,7 +72,7 @@ typedef struct UiContainerPrivate UiContainerPrivate;
 
 
 struct UiContainerPrivate {
-    UiContainerX    container;
+    UiContainer    container;
     Widget          (*prepare)(UiContainerPrivate*, UiLayout *layout, Arg *, int*);
     void            (*add)(UiContainerPrivate*, Widget);
     Widget          widget;
@@ -144,13 +144,13 @@ void ui_tabview_set(UiInteger *i, int64_t value);
 Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n);
 void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget);
 
-UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation);
+UiContainer* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation);
 Widget ui_vbox_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n);
 Widget ui_hbox_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n);
 void ui_box_container_add(UiContainerPrivate *ctn, Widget widget);
 
 
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
         UiObject *obj,
         Widget grid,
         UiBool def_hexpand,
@@ -160,7 +160,7 @@ UiContainerX* ui_grid_container(
 Widget ui_grid_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n);
 void ui_grid_container_add(UiContainerPrivate *ctn, Widget widget);
 
-UiContainerX* ui_frame_container(UiObject *obj, Widget frame);
+UiContainer* ui_frame_container(UiObject *obj, Widget frame);
 Widget ui_frame_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n);
 void ui_frame_container_add(UiContainerPrivate *ctn, Widget widget);
 
index c8d5b1d4fa2d579895a3cfcb329dc8bdacbf9706..dd1c9ba6f62443ad9c26acee2e35caf6a79f713d 100644 (file)
@@ -142,7 +142,7 @@ static UiObject* create_window(const char *title, Boolean simple) {
     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
     Widget vbox = XtCreateManagedWidget("window_vbox", gridClass, form, args, n);
-    UiContainerX *container = ui_box_container(obj, vbox, UI_BOX_VERTICAL);
+    UiContainer *container = ui_box_container(obj, vbox, UI_BOX_VERTICAL);
     uic_object_push_container(obj, container);
     
     obj->widget = toplevel;
index 36e5b46080552e655295c062783952d2b8a5c358..fcc622874114bc0df5fef34f2edc38fb06713c55 100644 (file)
@@ -43,7 +43,7 @@ static void delete_container(UiContainerPrivate *ct) {
 }
 
 void ui_obj_add_container(UiObject *obj, UiContainerPrivate *ct) {
-    UiContainerX *container = (UiContainerX*)ui_malloc(obj->ctx, sizeof(UiContainerX));
+    UiContainer *container = (UiContainer*)ui_malloc(obj->ctx, sizeof(UiContainer));
     container->close = 0;
     container->container = ct;
     container->prev = NULL;
index 0adf78aac6a4e2d1efae642121bcc1169fae6041..d9ba67a0692e1d97470a7ae4d595da41f8be993f 100644 (file)
 #include <QSplitter>
 #include <QGroupBox>
 
-#define ui_obj_container(obj) (UiContainerPrivate*)((UiContainerX*)obj->container_end)->container
+#define ui_obj_container(obj) (UiContainerPrivate*)((UiContainer*)obj->container_end)->container
 
 struct UiContainerPrivate {
     UIWIDGET current;
-    UiContainerX *container;
+    UiContainer *container;
 
     virtual void add(QWidget *widget, UiLayout& layout) = 0;
     virtual void end() {}
index 2aeab479607c5d977f46945a8f7e8c182ade04a5..bdac8ceaadba65fdce126411b82045fc64b9c17b 100644 (file)
@@ -96,6 +96,10 @@ UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) {
     return textarea;
 }
 
+UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
+    return textarea;
+}
+
 void ui_textarea_save(UiText *text) {
     // NOOP
 }
@@ -189,10 +193,7 @@ void ui_textarea_selection(UiText *text, int *begin, int *end) {
 
 void ui_textarea_setselection(UiText *text, int begin, int end) {
     QTextEdit *textview = (QTextEdit*)text->obj;
-    QTextCursor cursor = textview->textCursor();
-    cursor.setPosition(begin, QTextCursor::MoveAnchor);
-    cursor.setPosition(end, QTextCursor::KeepAnchor);
-    textview->setTextCursor(cursor); 
+    ui_textarea_set_selection(textview, begin, end);
 }
 
 int ui_textarea_length(UiText *text) {
@@ -208,6 +209,56 @@ void ui_textarea_remove(UiText *text, int begin, int end) {
     cursor.removeSelectedText();
 }
 
+
+void ui_textarea_focus(UIWIDGET textarea) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    edit->setFocus();
+}
+
+void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    QTextCursor cursor = edit->textCursor();
+    cursor.setPosition(begin, QTextCursor::MoveAnchor);
+    cursor.setPosition(end, QTextCursor::KeepAnchor);
+    edit->setTextCursor(cursor); 
+}
+
+void ui_textarea_select_all(UIWIDGET textarea) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    edit->selectAll();
+}
+
+void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    edit->setReadOnly(!editable);
+}
+
+UiBool ui_textarea_is_editable(UIWIDGET textarea) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    return !edit->isReadOnly();
+}
+
+void ui_textarea_set_position(UIWIDGET textarea, int pos) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    QTextCursor cursor = edit->textCursor();
+    cursor.setPosition(pos);
+    edit->setTextCursor(cursor); 
+}
+
+int ui_textarea_get_position(UIWIDGET textarea) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    QTextCursor cursor = edit->textCursor();
+    return cursor.position();
+}
+
+void ui_textarea_scroll_to(UIWIDGET textarea, int pos) {
+    QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+    QTextCursor cursor = edit->textCursor();
+    cursor.setPosition(pos);
+    edit->setTextCursor(cursor);
+    edit->ensureCursorVisible();
+}
+
 /* ------------------------------ TextField ------------------------------ */
 
 static UIWIDGET create_textfield(UiObject *obj, UiTextFieldArgs *args, bool password, bool frameless) {
index 17a64d4e6ebc0bf93128c90840de08d5f9a57e30..1196feb119bba52bf7a290d13dae2cabb427caa3 100644 (file)
 #include "args.h"
 
 void ui_container_begin_close(UiObject *obj) {
-    UiContainerX *ct = obj->container_end;
+    UiContainer *ct = obj->container_end;
     ct->close = 1;
 }
 
 int ui_container_finish(UiObject *obj) {
-    UiContainerX *ct = obj->container_end;
+    UiContainer *ct = obj->container_end;
     if(ct->close) {
         ui_end_new(obj);
         return 0;
@@ -47,8 +47,8 @@ int ui_container_finish(UiObject *obj) {
     return 1;
 }
 
-UiContainerX* ui_widget_container(UiWidget *w) {
-    UiContainerX *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainerX));
+UiContainer* ui_widget_container(UiWidget *w) {
+    UiContainer *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainer));
     container->container = w;
     return container;
 }
index dc7f3e9057129c827692485269e44eb83302e06c..4ddd08a03999ff2f1b1a7b6b5e6a3c8f27981321 100644 (file)
@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-UiContainerX* ui_widget_container(UiWidget *w);
+UiContainer* ui_widget_container(UiWidget *w);
 
 cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args);
 
index b9c56c4e8465e91999383444e1fcdda780f5a869..83d6fd0f04213f2209d306c259466653f4072cc4 100644 (file)
@@ -149,6 +149,19 @@ UIEXPORT UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args);
 
 UIEXPORT void ui_button_set_label(UIWIDGET button, const char *label);
 UIEXPORT void ui_button_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_button_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_togglebutton_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_togglebutton_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_checkbox_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_checkbox_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_radiobutton_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_radiobutton_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip);
 
 UIEXPORT void ui_linkbutton_value_set(UiString *str, const char *label, const char *uri);
 UIEXPORT void ui_linkbutton_value_set_label(UiString *str, const char *label);
index 49bc6316858115033d9ace3082ae7203f5b589f6..187f22107f624271f6a8773fd35762c6880cc568 100644 (file)
@@ -285,12 +285,12 @@ struct UiLayout {
     int          rowspan;
 };
 
-struct UiContainerX {
+struct UiContainer {
     void *container;
     UiBool close;
     UiBool newline;
-    UiContainerX *prev;
-    UiContainerX *next;
+    UiContainer *prev;
+    UiContainer *next;
 };
 
 
@@ -381,10 +381,6 @@ UIEXPORT void ui_newline(UiObject *obj);
 typedef void(*ui_addwidget_func)(UiObject *obj, UIWIDGET parent, UIWIDGET child, void *userdata);
 UIEXPORT void ui_custom_container_create(UiObject *obj, UIWIDGET widget, ui_addwidget_func add_child, void *userdata);
 
-// TODO
-UIEXPORT UiTabbedPane* ui_tabbed_document_view(UiObject *obj);
-UIEXPORT UiObject* ui_document_tab(UiTabbedPane *view);
-
 
 
 /* used for macro */
index 995c8c29c4f61e748660433f41f5cec5b57421ce..9cc79aff571ae2163472413fc8ff70ef8e64cb5b 100644 (file)
@@ -183,7 +183,6 @@ typedef bool UiBool;
 #endif
 
 typedef struct UiObject     UiObject;
-typedef struct UiContainerX UiContainerX;
 typedef struct UiEvent      UiEvent;
 typedef struct UiMouseEvent UiMouseEvent;
 typedef struct UiObserver   UiObserver;
@@ -218,8 +217,6 @@ typedef struct UiDnD         UiDnD;
 typedef struct UiThreadpool  UiThreadpool;
 /* end opaque types */
 
-typedef struct UiTabbedPane UiTabbedPane;
-
 typedef enum UiTri {
     UI_DEFAULT = 0,
     UI_ON,
@@ -294,8 +291,8 @@ struct UiObject {
      * container list
      * TODO: remove old UiContainer and rename UiContainerX to UiContainer
      */
-    UiContainerX *container_begin;
-    UiContainerX *container_end;
+    UiContainer *container_begin;
+    UiContainer *container_end;
     
     /*
      * next container object
@@ -313,23 +310,6 @@ struct UiObject {
     unsigned int ref;
 };
 
-struct UiTabbedPane {
-    /*
-     * native widget
-     */
-    UIWIDGET  widget;
-    
-    /*
-     * current document
-     */
-    void      *document;
-    
-    /*
-     * parent context
-     */
-    UiContext *ctx;
-};
-
 struct UiEvent {
     UiObject *obj;
     void     *document;
@@ -407,7 +387,6 @@ struct UiText {
     int   datatype;
     void  *data1;
     void  *data2;
-    // TODO: replacefunc, ...
     UiObserver *observers;
 };
 
@@ -574,8 +553,6 @@ UIEXPORT void  ui_document_ref(void *doc);
 UIEXPORT void  ui_document_unref(void *doc);
 UIEXPORT void  ui_document_destroy(void *doc);
 
-UIEXPORT void* ui_get_subdocument(void *document);               // deprecated
-
 UIEXPORT UiContext* ui_document_context(void *doc);
 UIEXPORT void* ui_context_document(UiContext *ctx);
 UIEXPORT UiObject* ui_context_obj(UiContext *ctx);
@@ -766,6 +743,8 @@ UIEXPORT void* ui_object_get(UiObject *obj, const char *key);
 UIEXPORT void ui_app_ref(void);
 UIEXPORT void ui_app_unref(void);
 
+UIEXPORT void ui_open_uri(const char *uri);
+
 #ifdef __cplusplus
 }
 #endif