Dear James, the attached patch implements the disambiguating msgids for libglade, which can optionally be enabled if a newly introduced attribute use_translation_disambiguation of the XML file element <glade-interface> is set to 'yes'.
I already submitted such a patch some weeks ago, but at that time I didn't know how to implement such an optional attribute into the XML file. Now I know how to do this and implemented it already. This means that for old existing glade XML files, libglade will show an unchanged behaviour. Whereas for new glade files, the abovementioned attribute can activate the usage of the new disambiguating translation msgids. I have tested this against example glade files. It seems to work quite well while maintaining full backward compatibility. Since I have a cvs.gnome.org account, I could simply go ahead and commit this patches myself. If nobody objects, I would commit these into CVS some time during next week. Thanks a lot in advance, Christian Stimming Full discussion of problem in previous message on November 29th, 2003: Dear James, I've brought up this issue before: I would like to see support for disambiguated msgids of gettext() inside libglade. The problem (ambiguous short GUI msgids) is explained in my earlier email quoted below. The gettext manual proposes a solution for that http://www.gnu.org/manual/gettext/html_node/gettext_151.html#SEC151 by introducing msgids with a disambiguating prefix. And just recently (Nov 5th) the necessary function for stripping this disambiguating prefix has been added to glib. It is called g_strip_context() in glib/gstrfuncs.h, and the macro Q_() for using this is in glib/gi18n.h or glib/gi18n-lib.h. Mark McLoughlin said I should simply prepare a patch and send it to you. I've assembled the necessary code changes and prepared a patch (attached). (I don't use Q_() directly because it is defined in gi18n-lib.h for a fixed domain name of dgettext. Therefore I rather use g_strip_context and the fully written function call.) However, this is incomplete (i.e. the new code is still disabled), as you can easily see by the FIXME markers. I thought it would be a good idea to enable these disambiguated msgids only if the creator of the glade XML file explicitly requested support for these. This would avoid any problems with backward compatibility since every old existing glade file would be processed exactly the way it used to be. But this means there needs to be some sort of file-wide property or attribute or something similar in the top-level GtkWindow widget that can be queried at those points marked with FIXME. Unfortunately I don't have any idea which of these possibilities would work best, and how and where a new GtkWindow property would have to be added. Any thoughts? Nevertheless I find it rather important to include this feature in libglade as fast as possible, even before glade itself can offer a GUI and/or support for this (which I could add later as well). This feature won't be usable for actual applications until it really propagates into the stable releases and into the distributions. In other words, even after the next stable release (by the way, is there a schedule for 2.4?) it will still take another 6-9 months until applications really can start to use this feature. I mean, that's fine with me, because that's the way it is, but nevertheless this feature needs to be brought on its way right now. Thanks, Christian On Montag, 17. November 2003 14:43, Mark McLoughlin wrote: > Hi Christian, > James Henstridge is the maintainer of libglade. > > You seem to have a good handle on this issue - you should probably just > go ahead and write the patch and send it to James. > > Thanks, > Mark. > > On Sun, 2003-11-16 at 13:07, Christian Stimming wrote: > > > > Sorry if I'm bothering you directly -- I didn't find any libglade > > development mailing list. If there is one, please forward this to there. > > > > A long known issue in the internationalization and translation of GUI > > application is the problem with ambiguous message string. If GUIs contain > > very short strings (e.g. a button label "File") in different places with > > different meanings (detailed explanation [1]), then all these labels are > > forced to have one common translation. This frequently leads to totally > > wrong translations, and translation teams all over the place are longing > > for a solution for this problem. > > > > The gettext manual knows about this as well > > http://www.gnu.org/manual/gettext/html_node/gettext_151.html#SEC151 but > > it defers the solution into the application domain. It proposes to > > introduce a new "qualified_gettext()" function and "disambiguating > > comments" into the msgid, so that the msgid then reads "noun|File" > > instead of just "File". Every occurrence of the call to gettext() (or _() > > ) in the program code should then be replaced by a call to the newly > > introduced qualified_gettext() (or Q_() ) function or however it's > > called. > > > > Fortunately, just recently exactly these extra functions have been > > introduced into glib: On November 5th, Matthias Clausen introduced > > glib/gi18n.h into glib CVS, and they define such a Q_() function (using > > g_strip_context() from gstrfuncs.h). > > > > I'm writing to you because in order to make use of this extra > > functionality, the code place where gettext() is called has to be changed > > in order to call the qualified_gettext() or Q_(). For message strings > > that have been defined in a Glade XML file this would be in > > libglade/glade/glade-parser.c in glade_parser_end_element(). Maybe one > > could even introduce a xml-file-wide option that either stays with the > > conventional gettext() or turns on the new qualified gettext() calls. > > That way, nothing would change for old projects, but those projects who > > want to make use of glib's functionality here can consciously turn on > > this new feature. > > > > It is important that this is done in libglade (as opposed to the > > application's code), because the message strings in question usually only > > show up inside the glade XML file. In the project I'm involved > > (www.gnucash.org) we don't define the button labels inside (our) C code > > (where we could switch from _() to Q_() on our own) but only inside the > > Glade XML files. Therefore we can only make use of the qualified gettext > > functions if libglade uses these, and we cannot make this transition in > > our application code alone. > > > > What do you think about such a change? If you are interested, I could > > also prepare some patches to implement this. > > > > Christian Stimming > > > > > > [1] From an earlier posting to [EMAIL PROTECTED]: > > Think of any english word that can both be a noun and a verb (e.g. "a > > file" and "to file"). Think of the fact that almost always in at least > > some languages the translation of the verb is [very] different from the > > translation of the noun (e.g. in German the noun is "Datei" and the verb > > is "ablegen"). Now think of a GUI button that is labelled with this word. > > Now think of a case where this button has the meaning of the verb, and > > another case where this button has the meaning of the noun (e.g. "File" > > meaning "to file something somewhere" as opposed to "File" meaning "do > > something with a file"). There you are -- the msgid in both cases is > > identical, but the msgstr should be different. Therefore we need a > > disambiguating addition in the msgids. In the example this can be as > > simple as (in gettext manual's format) "noun|File" and "verb|File", but > > you could also use the real meaning: "to file something somewhere|File" > > and so on.
? examples/simple-disambiguation.glade Index: ChangeLog =================================================================== RCS file: /cvs/gnome/libglade/ChangeLog,v retrieving revision 1.299 diff -u -r1.299 ChangeLog --- ChangeLog 14 Nov 2003 13:11:13 -0000 1.299 +++ ChangeLog 20 Dec 2003 11:57:55 -0000 @@ -1,3 +1,15 @@ +2003-12-20 Christian Stimming <[EMAIL PROTECTED]> + + * glade-2.0.dtd: Add attribute use_translation_disambiguation to + top-level element glade-interface which can optionally enable the + usage of disambiguated msgids in translatable strings. + + * glade/glade-parser.c: Add proposed code for using disambiguated + msgids in gettext() by utilizing the newly introduced + g_strip_context function from glib-2.3.1. This code will only be + enabled when the optional attribute use_translation_disambiguation + was set to 'yes'. + 2003-11-14 Mark McLoughlin <[EMAIL PROTECTED]> * configure.in: Version 2.3.1. Index: glade-2.0.dtd =================================================================== RCS file: /cvs/gnome/libglade/glade-2.0.dtd,v retrieving revision 1.11 diff -u -r1.11 glade-2.0.dtd --- glade-2.0.dtd 21 Feb 2002 14:24:17 -0000 1.11 +++ glade-2.0.dtd 20 Dec 2003 11:57:55 -0000 @@ -2,7 +2,8 @@ <!ELEMENT glade-interface (requires*, widget*) > <!ATTLIST glade-interface - xmlns CDATA #FIXED 'http://glade.gnome.org/glade-2.0.dtd' > + xmlns CDATA #FIXED 'http://glade.gnome.org/glade-2.0.dtd' + use_translation_disambiguation (yes|no) 'no' > <!ELEMENT requires EMPTY > <!ATTLIST requires Index: glade/glade-parser.c =================================================================== RCS file: /cvs/gnome/libglade/glade/glade-parser.c,v retrieving revision 1.27 diff -u -r1.27 glade-parser.c --- glade/glade-parser.c 12 May 2002 11:26:14 -0000 1.27 +++ glade/glade-parser.c 20 Dec 2003 11:57:56 -0000 @@ -26,6 +26,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <glib/gstrfuncs.h> #ifdef ENABLE_NLS # include <libintl.h> @@ -111,6 +112,7 @@ enum {PROP_NONE, PROP_WIDGET, PROP_ATK, PROP_CHILD } prop_type; gchar *prop_name; gboolean translate_prop; + gboolean translation_disambiguation; GArray *props; GArray *signals; @@ -476,6 +478,7 @@ state->prop_type = PROP_NONE; state->prop_name = NULL; state->translate_prop = FALSE; + state->translation_disambiguation = FALSE; state->props = NULL; state->signals = NULL; @@ -506,17 +509,22 @@ case PARSER_START: if (!strcmp(name, "glade-interface")) { state->state = PARSER_GLADE_INTERFACE; +/* #if 0 */ + for (i = 0; attrs && attrs[i] != NULL; i += 2) { + /* check whether to use translation disambiguation prefix */ + if (!strcmp(attrs[i], "use_translation_disambiguation")) { + state->translation_disambiguation = !strcmp(attrs[i+1], "yes"); #if 0 /* check for correct XML namespace */ - for (i = 0; attrs && attrs[i] != NULL; i += 2) { - if (!strcmp(attrs[i], "xmlns") && + } else if (!strcmp(attrs[i], "xmlns") && !strcmp(attrs[i+1], "...")) { g_warning("bad XML namespace `%s'.", attrs[i+1]); +#endif } else g_warning("unknown attribute `%s' for <glade-interface>", attrs[i]); } -#endif +/* #endif */ } else { g_warning("Expected <glade-interface>. Got <%s>.", name); state->prev_state = state->state; @@ -900,7 +908,14 @@ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty)); prop.name = state->prop_name; if (state->translate_prop && state->content->str[0] != '\0') { - prop.value = alloc_string(state->interface, + if (state->translation_disambiguation) + prop.value = + alloc_string(state->interface, + g_strip_context(state->content->str, + dgettext(state->domain, + state->content->str))); + else + prop.value = alloc_string(state->interface, dgettext(state->domain, state->content->str)); } else { prop.value = alloc_string(state->interface, state->content->str); @@ -922,7 +937,14 @@ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty)); prop.name = state->prop_name; if (state->translate_prop && state->content->str[0] != '\0') { - prop.value = alloc_string(state->interface, + if (state->translation_disambiguation) + prop.value = + alloc_string(state->interface, + g_strip_context(state->content->str, + dgettext(state->domain, + state->content->str))); + else + prop.value = alloc_string(state->interface, dgettext(state->domain, state->content->str)); } else { prop.value = alloc_string(state->interface, state->content->str); @@ -984,7 +1006,14 @@ state->props = g_array_new(FALSE, FALSE, sizeof(GladeProperty)); prop.name = state->prop_name; if (state->translate_prop && state->content->str[0] != '\0') { - prop.value = alloc_string(state->interface, + if (state->translation_disambiguation) + prop.value = + alloc_string(state->interface, + g_strip_context(state->content->str, + dgettext(state->domain, + state->content->str))); + else + prop.value = alloc_string(state->interface, dgettext(state->domain, state->content->str)); } else { prop.value = alloc_string(state->interface, state->content->str); @@ -1402,7 +1431,7 @@ main(int argc, char **argv) { gtk_init(&argc, &argv); if (argc > 1) { - GladeInterface *interface = glade_parser_parse_file(argv[1]); + GladeInterface *interface = glade_parser_parse_file(argv[1], ""); g_message("output: %p", interface); if (interface) { glade_interface_dump(interface, "/dev/stdout");
_______________________________________________ gnucash-devel mailing list [EMAIL PROTECTED] http://www.gnucash.org/cgi-bin/mailman/listinfo/gnucash-devel