Hi Tristan, thank you for your help. Now I have got on the fly switch locale hack for menu items too. Below example code how it was done.
#include <stdlib.h> #include <glib.h> #include <gtk/gtk.h> #include <glib/gi18n.h> #define RU_PACKAGE (gchar*) "messages" #define EN_PACKAGE (gchar*) "en_messages" #define LOCALEDIR (gchar*) "locale" // ----------------------------------------------------------------------------- void use_ru() { putenv("LANG=RU"); bindtextdomain (RU_PACKAGE, LOCALEDIR); bind_textdomain_codeset (RU_PACKAGE, "UTF-8"); textdomain (RU_PACKAGE); } // ----------------------------------------------------------------------------- void use_en() { putenv("LANG=EN"); bindtextdomain (EN_PACKAGE, LOCALEDIR); bind_textdomain_codeset (EN_PACKAGE, "UTF-8"); textdomain (EN_PACKAGE); } const gchar* msg_id="msg_id"; // ----------------------------------------------------------------------------- void translate_item(GtkWidget* w) { if (!w) return; GObject *o = G_OBJECT(w); if (!G_IS_OBJECT(o)) return; guint type_id = G_OBJECT_TYPE(o); const gchar* label="label"; GParamSpec* ps = g_object_class_find_property(G_OBJECT_GET_CLASS(o), label); if (!ps) return; gchar *id; id =(gchar*) g_object_get_data(o, msg_id); if (!id) { gchar *c; // Get copy of property. g_object_get(o, label, &c, NULL); // Create data field containing msg_id value. g_object_set_data_full(G_OBJECT(w), msg_id, c, g_free); id =(gchar*) g_object_get_data(o, msg_id); } gint len = strlen(id); if(len > 0) { // Get and set translated value. const gchar* txt = gettext(id); if(txt) { g_object_set(o, label, txt, NULL); } } } // ----------------------------------------------------------------------------- void translate_widget(GtkWidget *w, gpointer dummy) { if(GTK_IS_MENU_ITEM(w)) { GtkWidget *submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(w)); if (submenu) gtk_container_foreach(GTK_CONTAINER(submenu), translate_widget, 0); } if (GTK_IS_CONTAINER(w)) { gtk_container_foreach(GTK_CONTAINER(w), translate_widget, 0); return; } if (w) { translate_item(w); } } // ----------------------------------------------------------------------------- GtkBuilder* read_ui(char *file) // load user interface from file { GError *error = NULL; gchar *nm; int ok=0; nm = g_filename_from_utf8( file, -1,NULL,NULL,NULL); GtkBuilder* ui = gtk_builder_new (); const gchar* a = gtk_builder_get_translation_domain(ui); ok = gtk_builder_add_from_file( ui, nm , &error); return ui; } // ----------------------------------------------------------------------------- void on_window_destroy (GtkWidget *widget, gpointer user_data) { gtk_main_quit (); /* quit main loop when windows closes */ } // ----------------------------------------------------------------------------- void swap_translation(void) { char *c = getenv("LANG"); if (c) { if (strcmp(c, "EN")==0) use_ru(); else use_en(); } else { use_ru(); } } // ----------------------------------------------------------------------------- void translate_button_label (GtkWidget *w, gpointer user_data) { GtkWidget *widget = GTK_WIDGET(user_data); /* get button widget */ swap_translation(); translate_item(widget); } // ----------------------------------------------------------------------------- void translate_frame (GtkWidget *w, gpointer user_data) { GtkWidget *widget = GTK_WIDGET(user_data); /* get_frame_widget */ swap_translation(); translate_widget(widget, NULL); } // ----------------------------------------------------------------------------- void translate_menu (GtkWidget *w, gpointer user_data) { GtkWidget *widget = GTK_WIDGET(user_data); /* get menu widget*/ swap_translation(); translate_widget(widget, NULL); } // ----------------------------------------------------------------------------- int main (int argc, char *argv[]) { GtkWidget *window, *translate_button, *translate_frame_button, *translate_menu_button; gtk_init (&argc,&argv); /* initialize GTK+ */ GtkBuilder* ui = read_ui( "ui/translation_check_ui.glade"); GtkWidget* device = GTK_WIDGET (gtk_builder_get_object( ui, "device_apd_hbox")); GtkButton* apply_button = GTK_BUTTON (gtk_builder_get_object( ui, "apply_button" )); GtkFrame* frame = GTK_FRAME(gtk_builder_get_object( ui, "device_apd_frame" )); ui = read_ui((gchar*) "ui/menu_bar_ui.glade"); GtkWidget* menu = GTK_WIDGET (gtk_builder_get_object( ui, "menubar1")); g_assert(menu); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* create the main window */ GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7); /*Create container for all staff*/ //Create button1 translate_button = gtk_button_new(); gtk_button_set_label(GTK_BUTTON(translate_button), "Translate <Apply button>"); //Create button2 translate_frame_button = gtk_button_new(); gtk_button_set_label(GTK_BUTTON(translate_frame_button), "Translate <Frame>"); //Create button3 translate_menu_button = gtk_button_new(); gtk_button_set_label(GTK_BUTTON(translate_menu_button ), "Translate <menu>"); gtk_box_pack_start(GTK_BOX(box), menu,true,true,5); gtk_box_pack_start(GTK_BOX(box), device,true,true,5); gtk_box_pack_start(GTK_BOX(box), translate_button,true,true,5); gtk_box_pack_start(GTK_BOX(box), translate_frame_button,true,true,5); gtk_box_pack_start(GTK_BOX(box), translate_menu_button,true,true,5); gtk_container_add (GTK_CONTAINER (window), box); /*add children*/ translate_widget(window, NULL); gtk_widget_show_all (window); /* display window and children */ g_signal_connect (window, "destroy", G_CALLBACK(on_window_destroy), NULL); /* connect the window closing event with the "on_window_destroy" function */ g_signal_connect (translate_button, "clicked", G_CALLBACK(translate_button_label), apply_button); /* connect the button event with the "translate" function */ g_signal_connect (translate_frame_button, "clicked", G_CALLBACK(translate_frame), frame); /* connect the button event with the "translate" function */ g_signal_connect (translate_menu_button, "clicked", G_CALLBACK(translate_menu), menu); /* connect the button event with the "translate" function */ gtk_main (); /* MAIN LOOP */ return 0; } Best regards, Igor 2017-07-17 14:35 GMT+03:00 Tristan Van Berkom < tristan.vanber...@codethink.co.uk>: > On Mon, 2017-07-17 at 12:32 +0300, Igor Chetverovod wrote: > > Hi all, I have a need to switch locale on the fly (without an > > application > > UI reload). > > I have a function which are using gkt_container_forall() for > > marking of > > all widgets are having GObject property "label" , all of them get > > aditional GObject field "msg_id" with original english text of > > property > > "label"). When user press the button "Change locale" function > > iterates > > through all children of the main window and reads thier marks > > "msg_id" > > added before and uses them as a parameter for get_text() to > > get translated > > version of the label. And it sets localized text of every label by > > function g_object_set(). Function works good for all widgets in my > > application. But there is exclusion - GtkMenuItems widgets. Function > > gkt_container_forall() iterates trough them only once - at the > > "marking" > > phase. In "change locale" phase it does not iterate them. It > > translates > > only top level of GtkMenuBar, but does not GtkMenuItems and > > GtkCheckMenuItems. > > > > Fuction gtk_container_foreach () givese the same results. > > > > Is there method to solve this issue by gtk-functions? > > > > I am using gtk3.22.1 for Windows7. > > Hi Igor, > > Translating the UI on the fly is something I have wanted for many > years, and would be awesome to have real support for :) > > That said, using your current 'hack' (which seems a bit dangerous as it > makes assumptions about "label" properties on widgets and their > meaning), you are just missing some special cases to traverse through > the UI. > > For this case, you can probably get away with somthing like the > following inserted into your recursive widget crawling loop: > > if (GTK_IS_MENU_ITEM(widget)) > child = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)) > > https://developer.gnome.org/gtk3/stable/GtkMenuItem.html# > gtk-menu-item-get-submenu > > > Cheers, > -Tristan > > <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> Без вирусов. www.avast.ru <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list