Zbigniew Chyla
Thu, 07 Dec 2000 06:03:46 -0800
On Wed, 2000-12-06 at 15:24:58, Zbigniew Chyla wrote:
> (...)
> Thanks tor this! It should be no problem for translators - I have another
> patch, that doesn't _require_ modified translations. If you replace
> _("File") with Q_("!menu!File") in your code, old translations (containing
> only "File") will still work. I'll send improved patch tomorrow.
Attached patch implements new version of the Q_() macro. As I said before,
adding new prefixes to strings doesn't break existing translations.
This time I don't include whole po/Makefile.in.in but only small patch
adding "--keyword=Q_" to the list of xgettext options. Patch is being
applied by autogen.sh after running gettextize. Many GNOME apps
(eg. gnumeric) modify po/Makefile.in.in this way.
Zbigniew
diff -ruN /home/cyba/gcvs/gimp/ChangeLog gimp/ChangeLog
--- /home/cyba/gcvs/gimp/ChangeLog Sun Dec 3 20:16:03 2000
+++ gimp/ChangeLog Wed Dec 6 19:32:58 2000
@@ -1,3 +1,33 @@
+2000-12-06 Zbigniew Chyla <[EMAIL PROTECTED]>
+
+ I18n improvement - added support for Q_() macro (replacement for _()
+ allowing to add a prefix of the form "!some_prefix!" to the
+ string and thus making it possible to translate it differently in
+ different contexts).
+
+ * libgimp/gimpintl.h, libgimp/libgimp-intl.h: included "gimputils.h",
+ defined Q_() macro.
+
+ * libgimp/gimputils.h: added functions declarations:
+ gimp_i18n_qualifier_prefix_gettext(),
+ gimp_i18n_qualifier_prefix_dgettext(),
+ gimp_i18n_qualifier_prefix_noop().
+
+ * libgimp/gimputils.c: included "gimpintl.h", added functions:
+ gimp_i18n_qualifier_prefix_gettext(),
+ gimp_i18n_qualifier_prefix_dgettext(),
+ gimp_i18n_qualifier_prefix_noop().
+
+ * autogen.sh: patching po/Makefile.in.in (with
+ po/Makefile.in.in.i18npatch) after running gettextize.
+
+ * po/Makefile.in.in.i18n: new file - patch for po/Makefile.in.in (file
+ provided by gettextize), adds "--keyword=Q_" to the list of xgettext
+ options.
+
+ * po-libgimp/Makefile.in.in, po-plug-ins/Makefile.in.in: added
+ "--keyword=Q_" to the list of xgettext options.
+
2000-11-30 Andy Thomas <[EMAIL PROTECTED]>
* app/curves.c
diff -ruN /home/cyba/gcvs/gimp/libgimp/gimputils.h gimp/libgimp/gimputils.h
--- /home/cyba/gcvs/gimp/libgimp/gimputils.h Thu Nov 23 12:38:50 2000
+++ gimp/libgimp/gimputils.h Wed Dec 6 19:32:58 2000
@@ -45,13 +45,12 @@
const gchar *exceptions);
gchar * gimp_strcompress (const gchar *source);
#endif /* GLIB <= 1.3 */
-
+gchar *gimp_i18n_qualifier_prefix_gettext (const gchar *string);
+gchar *gimp_i18n_qualifier_prefix_dgettext (const gchar *domain, const gchar *string);
+gchar *gimp_i18n_qualifier_prefix_noop (const gchar *string);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMPUTILS_H__ */
-
-
-
diff -ruN /home/cyba/gcvs/gimp/libgimp/libgimp-intl.h gimp/libgimp/libgimp-intl.h
--- /home/cyba/gcvs/gimp/libgimp/libgimp-intl.h Thu Nov 23 12:38:50 2000
+++ gimp/libgimp/libgimp-intl.h Wed Dec 6 19:32:58 2000
@@ -22,10 +22,12 @@
#ifndef __LIBGIMP_INTL_H__
#define __LIBGIMP_INTL_H__
+#include "gimputils.h"
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(String) dgettext ("gimp-libgimp", String)
+# define Q_(String) gimp_i18n_qualifier_prefix_dgettext ("gimp-libgimp", String)
# undef gettext
# define gettext(String) dgettext ("gimp-libgimp", String)
# ifdef gettext_noop
@@ -37,6 +39,7 @@
/* Stubs that do something close enough. */
# define gettext(String) (String)
# define _(String) (String)
+# define Q_(String) gimp_i18n_qualifier_prefix_noop (String)
# define N_(String) (String)
#endif
diff -ruN /home/cyba/gcvs/gimp/libgimp/gimpintl.h gimp/libgimp/gimpintl.h
--- /home/cyba/gcvs/gimp/libgimp/gimpintl.h Thu Nov 23 12:38:48 2000
+++ gimp/libgimp/gimpintl.h Wed Dec 6 19:32:58 2000
@@ -25,6 +25,8 @@
#include <glib.h>
#include <locale.h>
+#include "gimputils.h"
+
/* Copied from gnome-i18n.h by Tom Tromey <[EMAIL PROTECTED]>
* Heavily modified by Daniel Egger <[EMAIL PROTECTED]>
* So be sure to hit me instead of him if something is wrong here
@@ -40,6 +42,7 @@
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(String) gettext (String)
+# define Q_(String) gimp_i18n_qualifier_prefix_gettext (String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
@@ -53,6 +56,7 @@
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
+# define Q_(String) gimp_i18n_qualifier_prefix_noop (String)
# define N_(String) (String)
#endif
diff -ruN /home/cyba/gcvs/gimp/libgimp/gimputils.c gimp/libgimp/gimputils.c
--- /home/cyba/gcvs/gimp/libgimp/gimputils.c Thu Nov 23 12:38:50 2000
+++ gimp/libgimp/gimputils.c Wed Dec 6 19:32:58 2000
@@ -23,8 +23,12 @@
#include <string.h>
#include <glib.h>
+#include "gimpintl.h"
#include "gimputils.h"
+#define Q_PREFIX_START '!'
+#define Q_PREFIX_END '!'
+
/**
* gimp_strescape:
* @source: A string to escape special characters in.
@@ -197,3 +201,113 @@
return dest;
}
#endif /* GLIB <= 1.3 */
+
+/***
+ * gimp_i18n_qualifier_prefix_gettext
+ *
+ **/
+gchar *
+gimp_i18n_qualifier_prefix_gettext (const gchar *string)
+{
+ g_assert (string != NULL);
+
+ if (*string != Q_PREFIX_START) {
+ return gettext (string);
+ } else {
+ gchar *translation;
+
+ translation = gettext (string);
+ if (translation != string) {
+ if (*translation != Q_PREFIX_START) {
+ return translation;
+ } else {
+ gchar *real_translation;
+
+ real_translation = strchr (translation + 1,
+Q_PREFIX_END);
+ if (real_translation != NULL) {
+ return real_translation + 1;
+ } else {
+ g_warning ("Ivalid Q_() translation: \"%s\"",
+translation);
+ return translation;
+ }
+ }
+ } else {
+ gchar *real_string;
+
+ real_string = strchr (string + 1, Q_PREFIX_END);
+ if (real_string != NULL) {
+ return gettext (real_string + 1);
+ } else {
+ g_warning ("Ivalid Q_() string: \"%s\"", string);
+ return (gchar *) string;
+ }
+ }
+ }
+}
+
+/***
+ * gimp_i18n_qualifier_prefix_dgettext
+ *
+ **/
+gchar *
+gimp_i18n_qualifier_prefix_dgettext (const gchar *domain, const gchar *string)
+{
+ g_assert (string != NULL);
+
+ if (*string != Q_PREFIX_START) {
+ return dgettext (domain, string);
+ } else {
+ gchar *translation;
+
+ translation = dgettext (domain, string);
+ if (translation != string) {
+ if (*translation != Q_PREFIX_START) {
+ return translation;
+ } else {
+ gchar *real_translation;
+
+ real_translation = strchr (translation + 1,
+Q_PREFIX_END);
+ if (real_translation != NULL) {
+ return real_translation + 1;
+ } else {
+ g_warning ("Ivalid Q_() translation: \"%s\"",
+translation);
+ return translation;
+ }
+ }
+ } else {
+ gchar *real_string;
+
+ real_string = strchr (string + 1, Q_PREFIX_END);
+ if (real_string != NULL) {
+ return dgettext (domain, real_string + 1);
+ } else {
+ g_warning ("Ivalid Q_() string: \"%s\"", string);
+ return (gchar *) string;
+ }
+ }
+ }
+}
+
+/***
+ * gimp_i18n_qualifier_prefix_noop
+ *
+ **/
+gchar *
+gimp_i18n_qualifier_prefix_noop (const gchar *string)
+{
+ g_assert (string != NULL);
+
+ if (*string != Q_PREFIX_START) {
+ return (gchar *) string;
+ } else {
+ gchar *real_string;
+
+ real_string = strchr (string + 1, Q_PREFIX_END);
+ if (real_string != NULL) {
+ return real_string + 1;
+ } else {
+ g_warning ("Ivalid Q_() string: \"%s\"", string);
+ return (gchar *) string;
+ }
+ }
+}
diff -ruN /home/cyba/gcvs/gimp/autogen.sh gimp/autogen.sh
--- /home/cyba/gcvs/gimp/autogen.sh Sun Dec 3 20:18:06 2000
+++ gimp/autogen.sh Wed Dec 6 19:42:30 2000
@@ -105,6 +105,14 @@
# while making dist.
echo "no" | gettextize --copy --force
+if [ -r po/Makefile.in.in.i18npatch ]; then
+ if grep 'keyword=Q_' po/Makefile.in.in >/dev/null; then
+ echo "no need for patching file \"Makefile.in.in\""
+ else
+ patch po/Makefile.in.in < po/Makefile.in.in.i18npatch
+ fi
+fi
+
autogen_dirs="."
#if test -z "$NO_GCG"; then
# autogen_dirs="$autogen_dirs tools/gcg"
diff -ruN /home/cyba/gcvs/gimp/po/Makefile.in.in.i18npatch
gimp/po/Makefile.in.in.i18npatch
--- /home/cyba/gcvs/gimp/po/Makefile.in.in.i18npatch Thu Jan 1 01:00:00 1970
+++ gimp/po/Makefile.in.in.i18npatch Wed Dec 6 19:35:34 2000
@@ -0,0 +1,9 @@
+--- Makefile.in.in.clean Wed Dec 6 19:33:55 2000
++++ Makefile.in.in Wed Dec 6 19:32:58 2000
+@@ -87,5 +87,5 @@
+ $(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+- --add-comments --keyword=_ --keyword=N_ \
++ --add-comments --keyword=_ --keyword=N_ --keyword=Q_ \
+ --files-from=$(srcdir)/POTFILES.in \
+ && test ! -f $(PACKAGE).po \
diff -ruN /home/cyba/gcvs/gimp/po-libgimp/Makefile.in.in gimp/po-libgimp/Makefile.in.in
--- /home/cyba/gcvs/gimp/po-libgimp/Makefile.in.in Thu Nov 23 12:39:17 2000
+++ gimp/po-libgimp/Makefile.in.in Wed Dec 6 19:32:58 2000
@@ -84,7 +84,7 @@
$(srcdir)/$(PACKAGE).pot: $(POTFILES)
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
- --add-comments --keyword=_ --keyword=N_ \
+ --add-comments --keyword=_ --keyword=N_ --keyword=Q_ \
--files-from=$(srcdir)/POTFILES.in \
&& test ! -f $(PACKAGE).po \
|| ( rm -f $(srcdir)/$(PACKAGE).pot \
diff -ruN /home/cyba/gcvs/gimp/po-plug-ins/Makefile.in.in
gimp/po-plug-ins/Makefile.in.in
--- /home/cyba/gcvs/gimp/po-plug-ins/Makefile.in.in Thu Nov 23 12:39:17 2000
+++ gimp/po-plug-ins/Makefile.in.in Wed Dec 6 19:32:58 2000
@@ -84,7 +84,7 @@
$(srcdir)/$(PACKAGE).pot: $(POTFILES)
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
- --add-comments --keyword=_ --keyword=N_ \
+ --add-comments --keyword=_ --keyword=N_ --keyword=Q_ \
--files-from=$(srcdir)/POTFILES.in \
&& test ! -f $(PACKAGE).po \
|| ( rm -f $(srcdir)/$(PACKAGE).pot \
diff -ru /home/cyba/gcvs/gimp/app/blend.c gimp/app/blend.c
--- /home/cyba/gcvs/gimp/app/blend.c Sun Dec 3 20:16:03 2000
+++ gimp/app/blend.c Wed Dec 6 21:39:01 2000
@@ -317,7 +317,7 @@
(FALSE, gradient_type_callback,
&options->gradient_type, (gpointer) options->gradient_type_d,
- _("Linear"), (gpointer) LINEAR, NULL,
+ Q_("!gradient_type!Linear"), (gpointer) LINEAR, NULL,
_("Bi-Linear"), (gpointer) BILINEAR, NULL,
_("Radial"), (gpointer) RADIAL, NULL,
_("Square"), (gpointer) SQUARE, NULL,
diff -ru /home/cyba/gcvs/gimp/app/brush_select.c gimp/app/brush_select.c
--- /home/cyba/gcvs/gimp/app/brush_select.c Sun Dec 3 20:16:03 2000
+++ gimp/app/brush_select.c Wed Dec 6 21:39:01 2000
@@ -464,7 +464,7 @@
util_box = gtk_hbox_new (FALSE, 0);
gtk_box_pack_end (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 4);
- button = gtk_button_new_with_label (_("New"));
+ button = gtk_button_new_with_label (Q_("!brush-button!New"));
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (brush_select_new_brush_callback),
bsp);
diff -ru /home/cyba/gcvs/gimp/app/gradient.c gimp/app/gradient.c
--- /home/cyba/gcvs/gimp/app/gradient.c Sun Dec 3 20:16:19 2000
+++ gimp/app/gradient.c Wed Dec 6 22:46:31 2000
@@ -529,7 +529,7 @@
static const gchar *blending_types[] =
{
- N_("Linear"),
+ N_("!blending_type!Linear"),
N_("Curved"),
N_("Sinusoidal"),
N_("Spherical (increasing)"),
@@ -906,7 +906,7 @@
gtk_box_pack_start (GTK_BOX (gvbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
- button = ed_create_button (_("Save as POV-Ray"),
+ button = ed_create_button (Q_("!gradient-button!Save as POV-Ray"),
"dialogs/gradient_editor/save_as_pov_ray.html",
GTK_SIGNAL_FUNC (ed_save_pov_callback),
NULL);
@@ -1845,7 +1845,7 @@
if (curr_gradient == NULL)
return;
- window = gtk_file_selection_new (_("Save as POV-Ray"));
+ window = gtk_file_selection_new (Q_("!gradient-dialog_title!Save as POV-Ray"));
gtk_window_set_wmclass (GTK_WINDOW (window), "save_gradient", "Gimp");
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
@@ -4617,7 +4617,7 @@
else
menuitem =
gtk_radio_menu_item_new_with_label (group,
- gettext (blending_types[i]));
+ Q_(blending_types[i]));
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
diff -ru /home/cyba/gcvs/gimp/app/palette.c gimp/app/palette.c
--- /home/cyba/gcvs/gimp/app/palette.c Sun Dec 3 20:16:54 2000
+++ gimp/app/palette.c Wed Dec 6 21:39:01 2000
@@ -1161,7 +1161,7 @@
palette->popup_menu = menu = gtk_menu_new ();
- menu_item = gtk_menu_item_new_with_label (_("New"));
+ menu_item = gtk_menu_item_new_with_label (Q_("!palette_color-menuitem!New"));
gtk_menu_append (GTK_MENU (menu), menu_item);
gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
GTK_SIGNAL_FUNC (palette_dialog_new_entry_callback),
@@ -2176,7 +2176,7 @@
gtk_notebook_append_page (GTK_NOTEBOOK (hbox), vbox,
gtk_label_new (_("Palette")));
gtk_notebook_append_page (GTK_NOTEBOOK (hbox), scrolledwindow,
- gtk_label_new (_("Select")));
+ gtk_label_new (Q_("!palette-notebook_tab!Select")));
}
else
{
@@ -2216,7 +2216,7 @@
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
- button = gtk_button_new_with_label (_("New"));
+ button = gtk_button_new_with_label (Q_("!palette-button!New"));
GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
@@ -2238,7 +2238,7 @@
"dialogs/palette_editor/delete_palette.html");
gtk_widget_show (button);
- button = gtk_button_new_with_label (_("Import"));
+ button = gtk_button_new_with_label (Q_("!palette-button!Import"));
GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
@@ -3093,7 +3093,7 @@
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
- _("Import"), palette_import_import_callback,
+ Q_("!palette_import_dialog-button!Import"),
+palette_import_import_callback,
palette, NULL, NULL, FALSE, FALSE,
_("Close"), palette_import_close_callback,
palette, NULL, NULL, TRUE, TRUE,
@@ -3107,7 +3107,7 @@
gtk_widget_show (hbox);
/* The "Import" frame */
- frame = gtk_frame_new (_("Import"));
+ frame = gtk_frame_new (Q_("!palette_import_dialog-frame!Import"));
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
@@ -3230,7 +3230,7 @@
gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
gtk_widget_show (image);
- button = import_dialog->select = gtk_button_new_with_label (_("Select"));
+ button = import_dialog->select = gtk_button_new_with_label
+(Q_("!palette_import-button!Select"));
GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (palette_import_select_grad_callback),
diff -ru /home/cyba/gcvs/gimp/app/preferences_dialog.c gimp/app/preferences_dialog.c
--- /home/cyba/gcvs/gimp/app/preferences_dialog.c Sun Dec 3 20:16:59 2000
+++ gimp/app/preferences_dialog.c Wed Dec 6 21:39:01 2000
@@ -2109,9 +2109,9 @@
/* Interface / Tool Options */
vbox = prefs_notebook_append_page (GTK_NOTEBOOK (notebook),
- _("Tool Options"),
+ Q_("!preferences_interface!Tool Options"),
GTK_CTREE (ctree),
- _("Tool Options"),
+ Q_("!preferences_interface!Tool Options"),
"dialogs/preferences/interface.html#tool_options",
top_insert,
&child_insert,
@@ -2246,7 +2246,7 @@
_("Nearest Neighbor (Fast)"),
(gpointer) NEAREST_NEIGHBOR_INTERPOLATION, NULL,
- _("Linear"),
+ Q_("!interpolation_type!Linear"),
(gpointer) LINEAR_INTERPOLATION, NULL,
_("Cubic (Slow)"),
(gpointer) CUBIC_INTERPOLATION, NULL,
diff -ru /home/cyba/gcvs/gimp/app/tools.c gimp/app/tools.c
--- /home/cyba/gcvs/gimp/app/tools.c Sun Dec 3 20:17:06 2000
+++ gimp/app/tools.c Wed Dec 6 21:39:01 2000
@@ -1534,7 +1534,7 @@
/* The shell and main vbox */
options_shell =
- gimp_dialog_new (_("Tool Options"), "tool_options",
+ gimp_dialog_new (Q_("!dialog_title!Tool Options"), "tool_options",
tools_help_func,
"dialogs/tool_options.html",
GTK_WIN_POS_NONE,
diff -ru /home/cyba/gcvs/gimp/modules/colorsel_water.c gimp/modules/colorsel_water.c
--- /home/cyba/gcvs/gimp/modules/colorsel_water.c Thu Nov 23 12:38:51 2000
+++ gimp/modules/colorsel_water.c Wed Dec 6 21:39:01 2000
@@ -626,7 +626,7 @@
bbox = gtk_vbutton_box_new ();
gtk_box_pack_end (GTK_BOX (hbox2), bbox, FALSE, FALSE, 0);
- button = gtk_button_new_with_label (_("New"));
+ button = gtk_button_new_with_label (Q_("!color-button!New"));
gtk_container_add (GTK_CONTAINER (bbox), button);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) new_color_callback,