[PATCH] Improve function internationalization system



I sat down and investigated different possibilites for improving the
function internationalization system. The problem with the current
system is that we'll most likely split out the function strings to
another gettext domain since these strings are very special compared to
other gnumeric strings, but the current internationalization system
doesn't allow this in a reasonable way.

What I changed to realize this/how it works/should work:
- Added <gettext-domain> node to <service type="function_group"> node in
plugin.xml.in files (gnumeric-xml.diff). This node sets the gettext
domain that should be used for the whole function groups' functions.
Note that this doesn't affect the category name since this is extracted
from the XML file itself while function description strings are fetched
from source files.
- Added possibility to set custom translation functions and translation
domains for GnmFuncGroups. It is taken from GTK+ HEAD and slightly
modified to fit our needs (gnumeric-src.diff). Those can be called from
external plugins that don't ship with Gnumeric.
- Read <gettext-domain> node from plugin XML files and set translation
domains accordingly. If none is specified, we use "gnumeric-functions",
which will most probably be a new gettext domain containing function
description strings.

What remains to do:
- Change N_ to another macro (e.g. F_) for function description strings,
take a look at GTK+'s P_ implementation to get an impression of how this
works
- Add po-function subdir and required Makefiles, add files containing F_
macros to po-function/POTFILES.in, the rest to po-function/POTFILES.
skip, add GTK+/GIMP multi-domain hacks to configure.in

Any further ideas? Comments? Suggestions? Criticism?

regs,
 Chris
Index: src/func.c
===================================================================
RCS file: /cvs/gnome/gnumeric/src/func.c,v
retrieving revision 1.210
diff -u -r1.210 func.c
--- src/func.c  14 Jan 2004 06:20:57 -0000      1.210
+++ src/func.c  2 Mar 2004 19:23:42 -0000
@@ -118,7 +118,8 @@
                GnmFunc const *fd = g_ptr_array_index (ordered, i);
                if (as_def) {
                        fprintf (output_file, "@CATEGORY=%s\n%s\n\n",
-                                _(fd->fn_group->display_name->str), _(fd->help));
+                                fd->fn_group->translate_func (fd->fn_group->display_name->str, 
fd->fn_group->translate_data),
+                                fd->fn_group->translate_func (fd->help, fd->fn_group->translate_data));
                } else {
                        static struct {
                                char const *name;
@@ -176,6 +177,9 @@
        g_return_if_fail (fn_group != NULL);
        g_return_if_fail (fn_group->functions == NULL);
 
+       if (fn_group->translate_notify)
+         fn_group->translate_notify (fn_group->translate_data);
+      
        gnm_string_unref (fn_group->internal_name);
        gnm_string_unref (fn_group->display_name);
        g_free (fn_group);
@@ -191,6 +195,62 @@
                               cat_b->display_name->str);
 }
 
+/**
+ * gnm_func_group_set_translate_func:
+ * @fn_group: a #GnmFuncGroup
+ * @func: a #GtkTranslateFunc
+ * @data: data to be passed to @func and @notify
+ * @notify: a #GtkDestroyNotify function to be called when @fn_group is 
+ *   destroyed and when the translation function is changed again
+ * 
+ * Sets a function to be used for translating the display labels of 
+ * functions inside the GnmFuncGroup<!-- -->
+ *
+ * If you're using gettext(), it is enough to set the translation domain
+ * with gnm_func_group_set_translation_domain().
+ **/
+void
+gnm_func_group_set_translate_func (GnmFuncGroup *fn_group,
+                                  GtkTranslateFunc func,
+                                  gpointer data,
+                                  GtkDestroyNotify notify)
+{
+       if (fn_group->translate_notify)
+               fn_group->translate_notify (fn_group->translate_data);
+      
+       fn_group->translate_func = func;
+       fn_group->translate_data = data;
+       fn_group->translate_notify = notify;
+}
+
+static gchar *
+dgettext_swapped (const gchar *msgid, 
+                 const gchar *domainname)
+{
+       return dgettext (domainname, msgid);
+}
+
+/**
+ * gnm_func_group_set_translation_domain:
+ * @fn_group: a #GnmFuncGroup
+ * @domain: the translation domain to use for dgettext() calls
+ * 
+ * Sets the translation domain and uses dgettext() the display labels
+ * of functions inside the GnmFuncGroup<!-- -->
+ *
+ * If you're not using gettext() for localization, see 
+ * gnm_fn_group_set_translate_func().
+ **/
+void 
+gnm_func_group_set_translation_domain (GnmFuncGroup *fn_group,
+                                      const gchar *domain)
+{
+       gnm_func_group_set_translate_func (fn_group, 
+                                          (GtkTranslateFunc)dgettext_swapped,
+                                          g_strdup (domain),
+                                          g_free);
+} 
+
 GnmFuncGroup *
 gnm_func_group_fetch (char const *name)
 {
@@ -216,6 +276,9 @@
        if (l == NULL) {
                cat = g_new (GnmFuncGroup, 1);
                cat->internal_name = gnm_string_get (name);
+               cat->translate_func = NULL;
+               cat->translate_data = NULL;
+               cat->translate_notify = NULL;
                if (translation != NULL) {
                        cat->display_name = gnm_string_get (translation);
                        cat->has_translation = TRUE;
@@ -1238,7 +1301,7 @@
                gboolean seek_at = TRUE;
                gboolean last_newline = TRUE;
 
-               ptr = _(func->help);
+               ptr = func->fn_group->translate_func (func->help, func->fn_group->translate_data);
                tok->help_is_localized = ptr != func->help;
                tok->help_copy = g_strdup (ptr);
                tok->sections = g_ptr_array_new ();
Index: src/func.h
===================================================================
RCS file: /cvs/gnome/gnumeric/src/func.h,v
retrieving revision 1.100
diff -u -r1.100 func.h
--- src/func.h  25 Nov 2003 06:04:12 -0000      1.100
+++ src/func.h  2 Mar 2004 19:23:42 -0000
@@ -4,6 +4,8 @@
 #include "gnumeric.h"
 #include "dependent.h"
 
+#include <gtk/gtkitemfactory.h> /* for GtkTranslateFunc */
+
 /* Setup of the symbol table */
 void functions_init     (void);
 void functions_shutdown (void);
@@ -18,6 +20,10 @@
        GnmString *internal_name, *display_name;
        gboolean has_translation;
        GSList *functions;
+
+       GtkTranslateFunc translate_func;
+       gpointer translate_data;
+       GtkDestroyNotify translate_notify;
 } GnmFuncGroup;
 
 GnmFuncGroup *gnm_func_group_get_nth (gint n);
@@ -197,6 +203,12 @@
 GnmExpr const *gnm_func_placeholder_factory (const char *name,
                                             GnmExprList *args,
                                             GnmExprConventions *convs);
+void       gnm_func_group_set_translate_func (GnmFuncGroup *fn_group,
+                                              GtkTranslateFunc func,
+                                              gpointer data,
+                                              GtkDestroyNotify notify);
+void       gnm_func_group_set_translation_domain (GnmFuncGroup *fn_group,
+                                                  const gchar *domain);
 
 
 /* TODO */
Index: src/plugin-service.c
===================================================================
RCS file: /cvs/gnome/gnumeric/src/plugin-service.c,v
retrieving revision 1.83
diff -u -r1.83 plugin-service.c
--- src/plugin-service.c        21 Feb 2004 17:16:44 -0000      1.83
+++ src/plugin-service.c        2 Mar 2004 19:23:43 -0000
@@ -923,7 +923,7 @@
 struct _PluginServiceFunctionGroup {
        GnmPluginService plugin_service;
 
-       gchar *category_name, *translated_category_name;
+       gchar *category_name, *translated_category_name, *gettext_domain_name;
        GSList *function_name_list;
 
        GnmFuncGroup    *func_group;
@@ -939,6 +939,7 @@
        GNM_PLUGIN_SERVICE (obj)->cbs_ptr = &service_function_group->cbs;
        service_function_group->category_name = NULL;
        service_function_group->translated_category_name = NULL;
+       service_function_group->gettext_domain_name = NULL;
        service_function_group->function_name_list = NULL;
        service_function_group->func_group = NULL;
 }
@@ -953,6 +954,8 @@
        service_function_group->category_name = NULL;
        g_free (service_function_group->translated_category_name);
        service_function_group->translated_category_name = NULL;
+       g_free (service_function_group->gettext_domain_name);
+       service_function_group->gettext_domain_name = NULL;
        g_slist_free_custom (service_function_group->function_name_list, g_free);
        service_function_group->function_name_list = NULL;
 
@@ -963,8 +966,8 @@
 static void
 plugin_service_function_group_read_xml (GnmPluginService *service, xmlNode *tree, ErrorInfo **ret_error)
 {
-       xmlNode *category_node, *translated_category_node, *functions_node;
-       gchar *category_name, *translated_category_name;
+       xmlNode *category_node, *translated_category_node, *functions_node, *gettext_domain_node;
+       gchar *category_name, *translated_category_name, *gettext_domain_name;
        GSList *function_name_list = NULL;
 
        GNM_INIT_RET_ERROR_INFO (ret_error);
@@ -996,6 +999,16 @@
        } else {
                translated_category_name = NULL;
        }
+       gettext_domain_node = e_xml_get_child_by_name_by_lang (tree, (xmlChar *)"gettext-domain");
+       if (gettext_domain_node != NULL) {
+               xmlChar *val;
+
+               val = xmlNodeGetContent (gettext_domain_node);
+               gettext_domain_name = g_strdup ((gchar *)val);
+               xmlFree (val);
+       } else {
+               gettext_domain_name = NULL;
+       }
        functions_node = e_xml_get_child_by_name (tree, (xmlChar *)"functions");
        if (functions_node != NULL) {
                xmlNode *node;
@@ -1016,6 +1029,7 @@
 
                service_function_group->category_name = category_name;
                service_function_group->translated_category_name = translated_category_name;
+               service_function_group->gettext_domain_name = gettext_domain_name;
                service_function_group->function_name_list = function_name_list;
        } else {
                GSList *error_list = NULL;
@@ -1033,6 +1047,7 @@
 
                g_free (category_name);
                g_free (translated_category_name);
+               g_free (gettext_domain_name);
                g_slist_free_custom (function_name_list, g_free);
        }
 }
@@ -1082,6 +1097,13 @@
        service_function_group->func_group = gnm_func_group_fetch_with_translation (
                service_function_group->category_name,
                service_function_group->translated_category_name);
+       if (service_function_group->gettext_domain_name != NULL)
+               gnm_func_group_set_translation_domain (service_function_group->func_group,
+                                                      service_function_group->gettext_domain_name);
+       else
+               gnm_func_group_set_translation_domain (service_function_group->func_group,
+                                                      "gnumeric-functions");
+
        GNM_SLIST_FOREACH (service_function_group->function_name_list, char, fname,
                GnmFunc *fn_def;
 
Index: plugins/derivatives/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/derivatives/plugin.xml.in,v
retrieving revision 1.10
diff -u -r1.10 plugin.xml.in
--- plugins/derivatives/plugin.xml.in   23 Aug 2003 01:24:17 -0000      1.10
+++ plugins/derivatives/plugin.xml.in   2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="derivatives">
                        <_category>Finance</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="cum_biv_norm_dist"/>
                                <function name="opt_bs"/>
Index: plugins/fn-complex/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-complex/plugin.xml.in,v
retrieving revision 1.5
diff -u -r1.5 plugin.xml.in
--- plugins/fn-complex/plugin.xml.in    23 Aug 2003 01:24:23 -0000      1.5
+++ plugins/fn-complex/plugin.xml.in    2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="complex">
                        <_category>Complex</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                 <function name="complex"/>
                                 <function name="imabs"/>
Index: plugins/fn-database/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-database/plugin.xml.in,v
retrieving revision 1.4
diff -u -r1.4 plugin.xml.in
--- plugins/fn-database/plugin.xml.in   23 Aug 2003 01:24:24 -0000      1.4
+++ plugins/fn-database/plugin.xml.in   2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="database">
                        <_category>Database</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="daverage"/>
                                <function name="dcount"/>
Index: plugins/fn-date/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-date/plugin.xml.in,v
retrieving revision 1.5
diff -u -r1.5 plugin.xml.in
--- plugins/fn-date/plugin.xml.in       23 Aug 2003 01:24:26 -0000      1.5
+++ plugins/fn-date/plugin.xml.in       2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="datetime">
                        <_category>Date/Time</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="date"/>
                                <function name="unix2date"/>
Index: plugins/fn-eng/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-eng/plugin.xml.in,v
retrieving revision 1.4
diff -u -r1.4 plugin.xml.in
--- plugins/fn-eng/plugin.xml.in        23 Aug 2003 01:24:28 -0000      1.4
+++ plugins/fn-eng/plugin.xml.in        2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="engineering">
                        <_category>Engineering</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="besseli"/>
                                <function name="besselk"/>
Index: plugins/fn-financial/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-financial/plugin.xml.in,v
retrieving revision 1.6
diff -u -r1.6 plugin.xml.in
--- plugins/fn-financial/plugin.xml.in  23 Aug 2003 01:24:31 -0000      1.6
+++ plugins/fn-financial/plugin.xml.in  2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="financial">
                        <_category>Finance</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="accrint"/>
                                <function name="accrintm"/>
Index: plugins/fn-info/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-info/plugin.xml.in,v
retrieving revision 1.3
diff -u -r1.3 plugin.xml.in
--- plugins/fn-info/plugin.xml.in       23 Aug 2003 01:24:32 -0000      1.3
+++ plugins/fn-info/plugin.xml.in       2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="info">
                        <_category>Information</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="cell"/>
                                <function name="countblank"/>
Index: plugins/fn-logical/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-logical/plugin.xml.in,v
retrieving revision 1.4
diff -u -r1.4 plugin.xml.in
--- plugins/fn-logical/plugin.xml.in    23 Aug 2003 01:24:34 -0000      1.4
+++ plugins/fn-logical/plugin.xml.in    2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="logical">
                        <_category>Logic</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="and"/>
                                <function name="or"/>
Index: plugins/fn-lookup/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-lookup/plugin.xml.in,v
retrieving revision 1.5
diff -u -r1.5 plugin.xml.in
--- plugins/fn-lookup/plugin.xml.in     23 Aug 2003 01:24:35 -0000      1.5
+++ plugins/fn-lookup/plugin.xml.in     2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="lookup">
                        <_category>Lookup</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="address"/>
                                <function name="areas"/>
Index: plugins/fn-math/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-math/plugin.xml.in,v
retrieving revision 1.7
diff -u -r1.7 plugin.xml.in
--- plugins/fn-math/plugin.xml.in       23 Aug 2003 01:24:37 -0000      1.7
+++ plugins/fn-math/plugin.xml.in       2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="math">
                        <_category>Mathematics</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="abs"/>
                                <function name="acos"/>
Index: plugins/fn-random/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-random/plugin.xml.in,v
retrieving revision 1.24
diff -u -r1.24 plugin.xml.in
--- plugins/fn-random/plugin.xml.in     23 Aug 2003 01:24:38 -0000      1.24
+++ plugins/fn-random/plugin.xml.in     2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="random">
                        <_category>Random Numbers</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="rand"/>
                                <function name="randbernoulli"/>
Index: plugins/fn-stat/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-stat/plugin.xml.in,v
retrieving revision 1.10
diff -u -r1.10 plugin.xml.in
--- plugins/fn-stat/plugin.xml.in       23 Aug 2003 01:34:11 -0000      1.10
+++ plugins/fn-stat/plugin.xml.in       2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="stat">
                        <_category>Statistics</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="avedev"/>
                                <function name="average"/>
Index: plugins/fn-string/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/fn-string/plugin.xml.in,v
retrieving revision 1.6
diff -u -r1.6 plugin.xml.in
--- plugins/fn-string/plugin.xml.in     25 Nov 2003 06:04:09 -0000      1.6
+++ plugins/fn-string/plugin.xml.in     2 Mar 2004 17:29:09 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="string">
                        <_category>String</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="char"/>
                                <function name="clean"/>
Index: plugins/gda/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/gda/plugin.xml.in,v
retrieving revision 1.7
diff -u -r1.7 plugin.xml.in
--- plugins/gda/plugin.xml.in   23 Aug 2003 01:34:14 -0000      1.7
+++ plugins/gda/plugin.xml.in   2 Mar 2004 17:29:10 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="gdaif">
                        <_category>Database</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="execSQL"/>
                                <function name="readDBTable"/>
Index: plugins/numtheory/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/numtheory/plugin.xml.in,v
retrieving revision 1.6
diff -u -r1.6 plugin.xml.in
--- plugins/numtheory/plugin.xml.in     23 Aug 2003 01:34:25 -0000      1.6
+++ plugins/numtheory/plugin.xml.in     2 Mar 2004 17:29:10 -0000
@@ -10,6 +10,7 @@
        <services>
                <service type="function_group" id="num_theory">
                        <_category>Number Theory</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="ithprime"/>
                                <function name="nt_phi"/>
Index: plugins/py-func/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/py-func/plugin.xml.in,v
retrieving revision 1.5
diff -u -r1.5 plugin.xml.in
--- plugins/py-func/plugin.xml.in       23 Aug 2003 01:35:34 -0000      1.5
+++ plugins/py-func/plugin.xml.in       2 Mar 2004 17:29:10 -0000
@@ -11,6 +11,7 @@
        <services>
                <service type="function_group" id="test">
                        <_category>Python</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="py_printf"/>
                                <function name="py_capwords"/>
Index: plugins/sample_datasource/plugin.xml.in
===================================================================
RCS file: /cvs/gnome/gnumeric/plugins/sample_datasource/plugin.xml.in,v
retrieving revision 1.5
diff -u -r1.5 plugin.xml.in
--- plugins/sample_datasource/plugin.xml.in     23 Aug 2003 01:35:37 -0000      1.5
+++ plugins/sample_datasource/plugin.xml.in     2 Mar 2004 17:29:10 -0000
@@ -11,6 +11,7 @@
        <services>
                <service type="function_group" id="ATL">
                        <_category>Finance</_category>
+                       <gettext-domain>gnumeric-functions</gettext-domain>
                        <functions>
                                <function name="atl_last"/>
                        </functions>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]