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

Reply via email to