app, libgimp: reverse internal l10n logic of plug-in labels in core app.

I hesitated a lot whether we should just drop the whole localization of
plug-ins' label and description (blurb) within the core. Actually the
commit messages I wrote a few days ago were moving towards this logic.
It really looks to me like plug-in localization can happen fully within
plug-in themselves. As far as I can see, the only advantage which the
current logic has theoretically is that if we needed, we have access to
both the original strings and their translations (e.g. it could be
useful for text search). Nevertheless I am not sure if we will ever make
use of this, and this is limited cases as all filters turned GEGL ops
don't have such ability anyway.

Nevertheless since previous contributors clearly put quite a lot of work
on this code of localizing the plug-in's label and description within
the main binary, I want to give myself a little more time to think and
study the whole thing because doing anything rash.

In the meantime, what changes is that by default now, a plug-in without
a local gettext catalog is simply not localized. In particular, the core
process doesn't try to localize it using the default catalog, a.k.a.
GETTEXT_PACKAGE"-std-plug-ins" ("gimp30-std-plug-ins"). It just doesn't
make sense and the worst which could happen would be to get unexpected
and wrong translations.
Now by default, plug-ins will try to find a catalog in their main
folder, named as this folder. If it fails to find it, a message is
printed to stderr and localization is disabled (rather than falling back
to a default catalog). It is up to plug-in developers to either install
a catalog, or implement set_i18n() to give the right catalog, folder, or
disable localization with gettext, as handled by libgimp.
This commit is contained in:
Jehan 2022-06-05 00:56:57 +02:00
parent 01e9253d7e
commit 95abf39066
12 changed files with 173 additions and 81 deletions

View File

@ -186,21 +186,25 @@ plug_in_actions_menu_branch_added (GimpPlugInManager *manager,
const gchar *menu_label,
GimpActionGroup *group)
{
const gchar *locale_domain;
const gchar *path_translated;
const gchar *label_translated;
const gchar *locale_domain = NULL;
gchar *full_translated = NULL;
gchar *full;
gchar *full_translated;
locale_domain = gimp_plug_in_manager_get_locale_domain (manager, file, NULL);
full = g_strconcat (menu_path, "/", menu_label, NULL);
path_translated = dgettext (locale_domain, menu_path);
label_translated = dgettext (locale_domain, menu_label);
if (gimp_plug_in_manager_get_i18n (manager, file, &locale_domain, NULL))
{
const gchar *path_translated;
const gchar *label_translated;
full = g_strconcat (menu_path, "/", menu_label, NULL);
full_translated = g_strconcat (path_translated, "/", label_translated, NULL);
path_translated = dgettext (locale_domain, menu_path);
label_translated = dgettext (locale_domain, menu_label);
if (plug_in_actions_check_translation (full, full_translated))
full_translated = g_strconcat (path_translated, "/", label_translated, NULL);
}
if (full_translated != NULL &&
plug_in_actions_check_translation (full, full_translated))
plug_in_actions_build_path (group, full, full_translated);
else
plug_in_actions_build_path (group, full, full);
@ -272,19 +276,19 @@ plug_in_actions_menu_path_added (GimpPlugInProcedure *plug_in_proc,
const gchar *menu_path,
GimpActionGroup *group)
{
const gchar *locale_domain;
const gchar *path_translated;
const gchar *locale_domain = NULL;
const gchar *path_translated = NULL;
#if 0
g_print ("%s: %s (%s)\n", G_STRFUNC,
gimp_object_get_name (plug_in_proc), menu_path);
#endif
locale_domain = gimp_plug_in_procedure_get_locale_domain (plug_in_proc);
if (gimp_plug_in_procedure_get_i18n (plug_in_proc, &locale_domain))
path_translated = dgettext (locale_domain, menu_path);
path_translated = dgettext (locale_domain, menu_path);
if (plug_in_actions_check_translation (menu_path, path_translated))
if (path_translated &&
plug_in_actions_check_translation (menu_path, path_translated))
plug_in_actions_build_path (group, menu_path, path_translated);
else
plug_in_actions_build_path (group, menu_path, menu_path);
@ -295,10 +299,11 @@ plug_in_actions_add_proc (GimpActionGroup *group,
GimpPlugInProcedure *proc)
{
GimpProcedureActionEntry entry;
const gchar *locale_domain;
const gchar *locale_domain = NULL;
GList *list;
gboolean localize;
locale_domain = gimp_plug_in_procedure_get_locale_domain (proc);
localize = gimp_plug_in_procedure_get_i18n (proc, &locale_domain);
entry.name = gimp_object_get_name (proc);
entry.icon_name = gimp_viewable_get_icon_name (GIMP_VIEWABLE (proc));
@ -314,9 +319,9 @@ plug_in_actions_add_proc (GimpActionGroup *group,
for (list = proc->menu_paths; list; list = g_list_next (list))
{
const gchar *original = list->data;
const gchar *translated = dgettext (locale_domain, original);
const gchar *translated = localize ? dgettext (locale_domain, original) : NULL;
if (plug_in_actions_check_translation (original, translated))
if (translated && plug_in_actions_check_translation (original, translated))
plug_in_actions_build_path (group, original, translated);
else
plug_in_actions_build_path (group, original, original);

View File

@ -738,7 +738,7 @@ gimp_pickable_get_tiles
gimp_plug_in_manager_data_free
gimp_plug_in_manager_get_help_domain
gimp_plug_in_manager_get_help_domains
gimp_plug_in_manager_get_locale_domain
gimp_plug_in_manager_get_i18n
gimp_procedure_execute_async
gimp_procedure_get_arguments
gimp_procedure_get_type
@ -774,6 +774,7 @@ gimp_plug_in_procedure_get_label
gimp_plug_in_procedure_get_type
gimp_plug_in_procedure_new
gimp_plug_in_procedure_set_file_proc
gimp_plug_in_procedure_set_i18n
gimp_plug_in_procedure_set_icon
gimp_plug_in_procedure_set_image_types
gimp_plug_in_procedure_set_mime_type
@ -833,7 +834,7 @@ gimp_message_valist
gimp_viewable_set_stock_id
gimp_plug_in_procedure_get_blurb
gimp_plug_in_procedure_get_locale_domain
gimp_plug_in_procedure_get_i18n
gimp_channel_select_round_rect
gimp_drawable_undo_get_type

View File

@ -138,12 +138,13 @@ plug_in_menus_setup (GimpUIManager *manager,
! plug_in_proc->file_proc)
{
GFile *file = gimp_plug_in_procedure_get_file (plug_in_proc);
const gchar *locale_domain;
GList *path;
const gchar *locale_domain = NULL;
gboolean localize;
locale_domain =
gimp_plug_in_manager_get_locale_domain (plug_in_manager,
file, NULL);
localize =
gimp_plug_in_manager_get_i18n (plug_in_manager,
file, &locale_domain, NULL);
for (path = plug_in_proc->menu_paths; path; path = g_list_next (path))
{
@ -155,12 +156,21 @@ plug_in_menus_setup (GimpUIManager *manager,
entry->proc = plug_in_proc;
entry->menu_path = path->data;
menu = g_strconcat (dgettext (locale_domain,
path->data),
"/",
dgettext (locale_domain,
plug_in_proc->menu_label),
NULL);
if (localize)
{
menu = g_strconcat (dgettext (locale_domain,
path->data),
"/",
dgettext (locale_domain,
plug_in_proc->menu_label),
NULL);
}
else
{
menu = g_strconcat (path->data, "/",
plug_in_proc->menu_label,
NULL);
}
plug_in_menus_tree_insert (menu_entries, menu, entry);
g_free (menu);

View File

@ -926,8 +926,9 @@ gimp_plug_in_add_temp_proc (GimpPlugIn *plug_in,
GimpTemporaryProcedure *proc)
{
GimpPlugInProcedure *overridden;
const gchar *locale_domain;
const gchar *help_domain;
const gchar *locale_domain = NULL;
gboolean localize;
g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
g_return_if_fail (GIMP_IS_TEMPORARY_PROCEDURE (proc));
@ -939,15 +940,16 @@ gimp_plug_in_add_temp_proc (GimpPlugIn *plug_in,
gimp_plug_in_remove_temp_proc (plug_in,
GIMP_TEMPORARY_PROCEDURE (overridden));
locale_domain = gimp_plug_in_manager_get_locale_domain (plug_in->manager,
plug_in->file,
NULL);
localize = gimp_plug_in_manager_get_i18n (plug_in->manager,
plug_in->file,
&locale_domain,
NULL);
help_domain = gimp_plug_in_manager_get_help_domain (plug_in->manager,
plug_in->file,
NULL);
gimp_plug_in_procedure_set_locale_domain (GIMP_PLUG_IN_PROCEDURE (proc),
locale_domain);
gimp_plug_in_procedure_set_i18n (GIMP_PLUG_IN_PROCEDURE (proc), localize,
locale_domain);
gimp_plug_in_procedure_set_help_domain (GIMP_PLUG_IN_PROCEDURE (proc),
help_domain);

View File

@ -126,8 +126,9 @@ gimp_plug_in_def_add_procedure (GimpPlugInDef *plug_in_def,
proc->mtime = plug_in_def->mtime;
gimp_plug_in_procedure_set_locale_domain (proc,
plug_in_def->locale_domain_name);
if (plug_in_def->locale_domain_name)
gimp_plug_in_procedure_set_i18n (proc, TRUE,
plug_in_def->locale_domain_name);
gimp_plug_in_procedure_set_help_domain (proc,
plug_in_def->help_domain_name);
@ -167,8 +168,8 @@ gimp_plug_in_def_set_locale_domain (GimpPlugInDef *plug_in_def,
{
GimpPlugInProcedure *procedure = list->data;
gimp_plug_in_procedure_set_locale_domain (procedure,
plug_in_def->locale_domain_name);
gimp_plug_in_procedure_set_i18n (procedure, TRUE,
plug_in_def->locale_domain_name);
}
}

View File

@ -93,22 +93,28 @@ gimp_plug_in_manager_add_locale_domain (GimpPlugInManager *manager,
#endif
}
const gchar *
gimp_plug_in_manager_get_locale_domain (GimpPlugInManager *manager,
GFile *file,
const gchar **domain_path)
gboolean
gimp_plug_in_manager_get_i18n (GimpPlugInManager *manager,
GFile *file,
const gchar **locale_domain,
const gchar **domain_path)
{
GSList *list;
g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
g_return_val_if_fail (file == NULL || G_IS_FILE (file), FALSE);
if (domain_path)
*domain_path = gimp_locale_directory ();
/* A NULL prog_name is GIMP itself, return the default domain */
if (! file)
return NULL;
{
if (locale_domain)
*locale_domain = NULL;
return TRUE;
}
for (list = manager->locale_domains; list; list = list->next)
{
@ -120,11 +126,14 @@ gimp_plug_in_manager_get_locale_domain (GimpPlugInManager *manager,
if (domain_path && domain->domain_path)
*domain_path = domain->domain_path;
return domain->domain_name;
if (locale_domain)
*locale_domain = domain->domain_name;
return TRUE;
}
}
return STD_PLUG_INS_LOCALE_DOMAIN;
return FALSE;
}
gint

View File

@ -30,8 +30,9 @@ void gimp_plug_in_manager_add_locale_domain (GimpPlugInManager *mana
const gchar *domain_path);
/* Retrieve a plug-ins locale domain */
const gchar * gimp_plug_in_manager_get_locale_domain (GimpPlugInManager *manager,
gboolean gimp_plug_in_manager_get_i18n (GimpPlugInManager *manager,
GFile *file,
const gchar **locale_domain,
const gchar **locale_path);
/* Retrieve all locale domains */

View File

@ -151,20 +151,16 @@ gimp_plug_in_manager_restore (GimpPlugInManager *manager,
/* create locale and help domain lists */
for (list = manager->plug_in_defs; list; list = list->next)
{
GimpPlugInDef *plug_in_def = list->data;
GimpPlugInDef *plug_in_def = list->data;
const gchar *locale_domain = NULL;
if (plug_in_def->locale_domain_name)
gimp_plug_in_manager_add_locale_domain (manager,
plug_in_def->file,
plug_in_def->locale_domain_name,
plug_in_def->locale_domain_path);
else
/* set the default plug-in locale domain */
gimp_plug_in_def_set_locale_domain (plug_in_def,
gimp_plug_in_manager_get_locale_domain (manager,
plug_in_def->file,
NULL),
NULL);
{
gimp_plug_in_manager_add_locale_domain (manager,
plug_in_def->file,
plug_in_def->locale_domain_name,
plug_in_def->locale_domain_path);
}
if (plug_in_def->help_domain_name)
gimp_plug_in_manager_add_help_domain (manager,

View File

@ -255,8 +255,14 @@ gimp_plug_in_procedure_get_menu_label (GimpProcedure *procedure)
GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
if (proc->menu_label)
return dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
proc->menu_label);
{
const gchar *locale_domain = NULL;
if (gimp_plug_in_procedure_get_i18n (proc, &locale_domain))
return dgettext (locale_domain, proc->menu_label);
else
return proc->menu_label;
}
return GIMP_PROCEDURE_CLASS (parent_class)->get_menu_label (procedure);
}
@ -268,8 +274,14 @@ gimp_plug_in_procedure_get_blurb (GimpProcedure *procedure)
/* do not to pass the empty string to gettext() */
if (procedure->blurb && strlen (procedure->blurb))
return dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
procedure->blurb);
{
const gchar *locale_domain = NULL;
if (gimp_plug_in_procedure_get_i18n (proc, &locale_domain))
return dgettext (locale_domain, procedure->blurb);
else
return procedure->blurb;
}
return NULL;
}
@ -560,20 +572,27 @@ gimp_plug_in_procedure_get_file (GimpPlugInProcedure *proc)
}
void
gimp_plug_in_procedure_set_locale_domain (GimpPlugInProcedure *proc,
const gchar *locale_domain)
gimp_plug_in_procedure_set_i18n (GimpPlugInProcedure *proc,
gboolean localize,
const gchar *locale_domain)
{
g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
proc->locale_domain = locale_domain ? g_quark_from_string (locale_domain) : 0;
proc->localize = localize;
proc->locale_domain = localize && locale_domain ? g_quark_from_string (locale_domain) : 0;
}
const gchar *
gimp_plug_in_procedure_get_locale_domain (GimpPlugInProcedure *proc)
gboolean
gimp_plug_in_procedure_get_i18n (GimpPlugInProcedure *proc,
const gchar **domain)
{
g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL);
g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), FALSE);
g_return_val_if_fail (domain && *domain == NULL, FALSE);
return g_quark_to_string (proc->locale_domain);
if (proc->localize)
*domain = g_quark_to_string (proc->locale_domain);
return proc->localize;
}
void

View File

@ -40,6 +40,7 @@ struct _GimpPlugInProcedure
/* common members */
GFile *file;
gboolean localize;
GQuark locale_domain;
GQuark help_domain;
gchar *menu_label;
@ -97,9 +98,11 @@ GimpPlugInProcedure * gimp_plug_in_procedure_find (GSList *lis
GFile * gimp_plug_in_procedure_get_file (GimpPlugInProcedure *proc);
void gimp_plug_in_procedure_set_locale_domain (GimpPlugInProcedure *proc,
void gimp_plug_in_procedure_set_i18n (GimpPlugInProcedure *proc,
gboolean localize,
const gchar *locale_domain);
const gchar * gimp_plug_in_procedure_get_locale_domain (GimpPlugInProcedure *proc);
gboolean gimp_plug_in_procedure_get_i18n (GimpPlugInProcedure *proc,
const gchar **domain);
void gimp_plug_in_procedure_set_help_domain (GimpPlugInProcedure *proc,
const gchar *help_domain);

View File

@ -904,10 +904,33 @@ _gimp_plug_in_set_i18n (GimpPlugIn *plug_in,
catalog_dir);
if (use_gettext)
{
if (! (*gettext_domain))
*gettext_domain = g_strdup (plug_in->priv->translation_domain_name);
gboolean reserved = FALSE;
if (*catalog_dir)
if (! (*gettext_domain))
{
*gettext_domain = g_strdup (plug_in->priv->translation_domain_name);
}
else if (g_strcmp0 (*gettext_domain, GETTEXT_PACKAGE "-std-plug-ins") == 0 ||
g_strcmp0 (*gettext_domain, GETTEXT_PACKAGE "-script-fu") == 0 ||
g_strcmp0 (*gettext_domain, GETTEXT_PACKAGE "-python") == 0)
{
/* We special-case these 3 domains as the only ones where
* it is allowed to set an absolute system dir (actually
* set by the lib itself; devs must set NULL). See docs of
* set_i18n() method.
*/
if (*catalog_dir)
{
g_printerr ("[%s] Do not set a catalog directory with set_i18n() with reserved domain: %s\n",
procedure_name, *gettext_domain);
g_clear_pointer (catalog_dir, g_free);
}
*catalog_dir = g_strdup (gimp_locale_directory ());
reserved = TRUE;
}
if (*catalog_dir && ! reserved)
{
if (g_path_is_absolute (*catalog_dir))
{
@ -954,7 +977,7 @@ _gimp_plug_in_set_i18n (GimpPlugIn *plug_in,
g_object_unref (catalog_file);
}
}
else
else if (! *catalog_dir)
{
*catalog_dir = g_file_get_path (plug_in->priv->translation_domain_path);
}
@ -1023,11 +1046,26 @@ gimp_plug_in_register (GimpPlugIn *plug_in,
{
const gchar *name = list->data;
GimpProcedure *procedure;
gchar *gettext_domain = NULL;
gchar *catalog_dir = NULL;
procedure = _gimp_plug_in_create_procedure (plug_in, name);
if (procedure)
{
GIMP_PROCEDURE_GET_CLASS (procedure)->install (procedure);
if (_gimp_plug_in_set_i18n (plug_in, gimp_procedure_get_name (procedure),
&gettext_domain, &catalog_dir))
{
GFile *file = g_file_new_for_path (catalog_dir);
_gimp_plug_in_domain_register (gettext_domain, file);
g_free (gettext_domain);
g_free (catalog_dir);
g_object_unref (file);
}
g_object_unref (procedure);
}
else

View File

@ -163,6 +163,13 @@ struct _GimpPlugInClass
*
* Note that @localedir must be a relative path, subdirectory of the
* directory of `gimp_get_progname()`.
* The domain names "gimp30-std-plug-ins", "gimp30-script-fu" and
* "gimp30-python" are reserved and can only be used with a %NULL
* @catalog_dir. These will use the translation catalogs installed for
* core plug-ins, so you are not expected to use these for your
* plug-ins, except if you are making a core plug-in. More domain
* names may become reserved so we discourage using a gettext domain
* starting with "gimp30-".
*
* When localizing your plug-in this way, GIMP also binds
* @gettext_domain to the UTF-8 encoding.