Translate GtkAlertDialog buttons

Hello there,

i want to construct a GtkAlertDialog where all of the dialog is translatable. I’ve got it to work except for the buttons. My code:

static GtkWindow *parent_window;
static const char *dialog_buttons[] = { "Cancel", "Yes" };

static void
custom_window_apply_cb(GtkButton *btn, gpointer user_data)
{
	GtkAlertDialog *d = gtk_alert_dialog_new(_("Service Restart"));
	gtk_alert_dialog_set_buttons(d, dialog_buttons);
	gtk_alert_dialog_set_cancel_button(d, 0);
	gtk_alert_dialog_set_default_button(d, 1);
	gtk_alert_dialog_set_detail(d, _("Do you really want to restart the service?"));
	gtk_alert_dialog_choose(d, parent_window, NULL, custom_window_alert_dialog_cb, NULL);
}

I have translations compiled as .mo files available for all four strings: Cancel, Yes, Service Restart and Do you really want to restart the service?. That’s not the issue.

If I use this syntax…

static const char *dialog_buttons[] = { _("Cancel"), _("Yes") };

the compiler complains …

In file included from src/custom_window.c:1:
/usr/include/glib-2.0/glib/gi18n-lib.h:32:20: error: initializer element is not constant
   32 | #define  _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String))
      |                    ^
src/custom_window.c:55:41: note: in expansion of macro ‘_’
   55 | static const char *dialog_buttons[] = { _("_Cancel"), _("_Yes") };
      |                                         ^
/usr/include/glib-2.0/glib/gi18n-lib.h:32:20: note: (near initialization for ‘dialog_buttons[0]’)
   32 | #define  _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String))
      |                    ^
src/custom_window.c:55:41: note: in expansion of macro ‘_’
   55 | static const char *dialog_buttons[] = { _("_Cancel"), _("_Yes") };
      |                                         ^
/usr/include/glib-2.0/glib/gi18n-lib.h:32:20: error: initializer element is not constant
   32 | #define  _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String))
      |                    ^
src/custom_window.c:55:55: note: in expansion of macro ‘_’
   55 | static const char *dialog_buttons[] = { _("_Cancel"), _("_Yes") };
      |                                                       ^
/usr/include/glib-2.0/glib/gi18n-lib.h:32:20: note: (near initialization for ‘dialog_buttons[1]’)
   32 | #define  _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String))
      |                    ^
src/custom_window.c:55:55: note: in expansion of macro ‘_’
   55 | static const char *dialog_buttons[] = { _("_Cancel"), _("_Yes") };
      |                                                       ^
make: *** [Makefile:9: debug] Error 1

How can I get a constant gettext translation?

A different strategy would be to use a .ui file for the GtkAlertDialog but that doesn’t seem intended and results in the issue that I don’t know how to declare an array of strings in a .ui file in the property buttons.

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <object class="GtkAlertDialog" id="dialog">
    <property name="buttons">
      <items>
        <item translatable="yes">Cancel</item>
        <item translatable="yes">Yes</item>
      </items>
      </object>
    </property>
    <property name="cancel-button">0</property>
    <property name="default-button">1</property>
    <property name="detail" translatable="yes">Do you really want to restart the service?</property>
    <property name="message" translatable="yes">Service Restart</property>
  </object>
</interface>

This ui definition might look ok but it doesn’t work.

Any ideas how I can get the buttons to be translated?

Many thanks in advance!

Hi,

_() is evaluated at runtime, so you cant’ use it to initialize a static variable.
Also, the buttons list shall be null-terminated.

Try something like this:

gtk_alert_dialog_set_buttons (d, (const char *[]) { _("_Cancel"), _("_Yes"), NULL });
2 Likes

It works. Thank you so much. A helpful reply in such a short time doesn’t happen every day.

2 Likes