Commit 4e8105c1 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Correctly translated & sorted plug-in actions & menu entries:

2004-04-27  Michael Natterer  <mitch@gimp.org>

	Correctly translated & sorted plug-in actions & menu entries:

	* app/widgets/gimpuimanager.[ch]: added a "gchar *name" property
	and a hash table which keeps all created UI managers (similar to
	GimpActionGroup's hash table). Added function
	gimp_ui_managers_from_name() which returns a list of all managers
	with the given name.

	* app/widgets/gimpmenufactory.c: register a name per UI manager
	and pass the name to gimp_ui_manager_new().

	* app/actions/plug-in-actions.c: added code which correctly
	translates the created plug-in actions and also creates translated
	menu actions for the plug-in's menu_path elements.

	* app/gui/plug-in-menus.[ch]: sort the plug-ins' menu entries
	using a GTree. For each entry, recursivlely create submenus
	from the dynamic menu actions created above before creating
	the plug-in's menu entry itself.

	* app/gui/image-menu.c (image_menu_setup2)
	* app/gui/toolbox-menu.c (toolbox_menu_setup2): call
	plug_in_menus_create2().

	* app/gui/gui-vtable.c (gui_menus_create_entry)
	(gui_menus_delete_entry): added some uglyness which maps old <Prefix>
	menu identifiers to new-style UI manager plus ui_path tuples and
	call plug_in_menus_add,remove_proc() accordingly.

	* menus/image-menu.xml
	* menus/toolbox-menu.xml: added name="Foo" attributes to all menus
	so plug-in entries find their place.
parent 11309f8e
2004-04-27 Michael Natterer <mitch@gimp.org>
Correctly translated & sorted plug-in actions & menu entries:
* app/widgets/gimpuimanager.[ch]: added a "gchar *name" property
and a hash table which keeps all created UI managers (similar to
GimpActionGroup's hash table). Added function
gimp_ui_managers_from_name() which returns a list of all managers
with the given name.
* app/widgets/gimpmenufactory.c: register a name per UI manager
and pass the name to gimp_ui_manager_new().
* app/actions/plug-in-actions.c: added code which correctly
translates the created plug-in actions and also creates translated
menu actions for the plug-in's menu_path elements.
* app/gui/plug-in-menus.[ch]: sort the plug-ins' menu entries
using a GTree. For each entry, recursivlely create submenus
from the dynamic menu actions created above before creating
the plug-in's menu entry itself.
* app/gui/image-menu.c (image_menu_setup2)
* app/gui/toolbox-menu.c (toolbox_menu_setup2): call
plug_in_menus_create2().
* app/gui/gui-vtable.c (gui_menus_create_entry)
(gui_menus_delete_entry): added some uglyness which maps old <Prefix>
menu identifiers to new-style UI manager plus ui_path tuples and
call plug_in_menus_add,remove_proc() accordingly.
* menus/image-menu.xml
* menus/toolbox-menu.xml: added name="Foo" attributes to all menus
so plug-in entries find their place.
2004-04-27 Michael Natterer <mitch@gimp.org>
* app/gui/gui.c (gui_restore_callback): call actions_init()
......
......@@ -50,6 +50,15 @@
#include "gimp-intl.h"
/* local function prototypes */
static void plug_in_actions_build_path (GimpActionGroup *group,
const gchar *path_original,
const gchar *path_translated);
/* private variables */
static GimpActionEntry plug_in_actions[] =
{
{ "plug-in-menu", NULL, N_("Filte_rs") },
......@@ -131,7 +140,7 @@ plug_in_actions_update (GimpActionGroup *group,
{
GimpImage *gimage = NULL;
GimpImageType type = -1;
GList *list;
GSList *list;
if (GIMP_IS_ITEM_TREE_VIEW (data))
gimage = GIMP_ITEM_TREE_VIEW (data)->gimage;
......@@ -254,12 +263,13 @@ void
plug_in_actions_add_proc (GimpActionGroup *group,
PlugInProcDef *proc_def)
{
GimpActionEntry entry;
const gchar *progname;
const gchar *locale_domain;
const gchar *help_domain;
gchar *label;
gchar *help_id;
const gchar *progname;
const gchar *locale_domain;
const gchar *help_domain;
gchar *path_original;
gchar *path_translated;
gchar *help_id;
gchar *p1, *p2;
g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
g_return_if_fail (proc_def != NULL);
......@@ -271,27 +281,44 @@ plug_in_actions_add_proc (GimpActionGroup *group,
help_id = plug_in_proc_def_get_help_id (proc_def, help_domain);
label = g_strdup (strrchr (proc_def->menu_path, '/') + 1);
path_original = g_strdup (proc_def->menu_path);
path_translated = g_strdup (dgettext (locale_domain, path_original));
p1 = strrchr (path_original, '/');
p2 = strrchr (path_translated, '/');
if (p1 && p2)
{
gchar *label;
GtkAction *action;
label = p2 + 1;
g_print ("adding plug-in action '%s' (%s)\n",
proc_def->db_info.name, label);
entry.name = proc_def->db_info.name;
entry.stock_id = NULL;
entry.label = label;
entry.accelerator = proc_def->accelerator;
entry.tooltip = NULL;
entry.callback = G_CALLBACK (plug_in_run_cmd_callback);
entry.help_id = help_id;
action = gtk_action_new (proc_def->db_info.name, label, NULL, NULL);
g_print ("adding plug-in action '%s' (%s)\n",
entry.name, label);
g_signal_connect (action, "activate",
G_CALLBACK (plug_in_run_cmd_callback),
&proc_def->db_info);
g_object_set (group, "translation-domain", locale_domain, NULL);
gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
action,
proc_def->accelerator);
gimp_action_group_add_actions (group, &entry, 1, &proc_def->db_info);
g_object_unref (action);
g_object_set (group, "translation-domain", NULL, NULL);
g_free (help_id);
g_free (label);
g_free (help_id);
*p1 = '\0';
*p2 = '\0';
plug_in_actions_build_path (group, path_original, path_translated);
g_free (path_original);
g_free (path_translated);
}
}
void
......@@ -314,3 +341,60 @@ plug_in_actions_remove_proc (GimpActionGroup *group,
gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action);
}
}
/* private functions */
static void
plug_in_actions_build_path (GimpActionGroup *group,
const gchar *path_original,
const gchar *path_translated)
{
GHashTable *path_table;
gchar *p1, *p2;
path_table = g_object_get_data (G_OBJECT (group), "plug-in-path-table");
if (! path_table)
{
path_table = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
g_object_set_data_full (G_OBJECT (group), "plug-in-path-table",
path_table,
(GDestroyNotify) g_hash_table_destroy);
}
p1 = strrchr (path_original, '/');
p2 = strrchr (path_translated, '/');
if (p1 && p2 && ! g_hash_table_lookup (path_table, path_original))
{
gchar *copy_original = g_strdup (path_original);
gchar *copy_translated = g_strdup (path_translated);
gchar *label;
GtkAction *action;
label = p2 + 1;
g_print ("adding plug-in submenu '%s' (%s)\n",
path_original, label);
action = gtk_action_new (path_original, label, NULL, NULL);
gtk_action_group_add_action (GTK_ACTION_GROUP (group), action);
g_object_unref (action);
g_hash_table_insert (path_table, g_strdup (path_original), action);
p1 = strrchr (copy_original, '/');
p2 = strrchr (copy_translated, '/');
*p1 = '\0';
*p2 = '\0';
plug_in_actions_build_path (group, copy_original, copy_translated);
g_free (copy_original);
g_free (copy_translated);
}
}
......@@ -18,6 +18,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
......@@ -236,6 +238,21 @@ gui_menus_create_entry (Gimp *gimp,
plug_in_actions_add_proc (list->data, proc_def);
}
for (list = gimp_ui_managers_from_name ("<Image>");
list;
list = g_list_next (list))
{
if (! strncmp (proc_def->menu_path, "<Toolbox>", 9))
{
plug_in_menus_add_proc (list->data, "/toolbox-menubar", proc_def);
}
else if (! strncmp (proc_def->menu_path, "<Image>", 7))
{
plug_in_menus_add_proc (list->data, "/image-menubar", proc_def);
plug_in_menus_add_proc (list->data, "/image-popup", proc_def);
}
}
progname = plug_in_proc_def_get_progname (proc_def);
locale_domain = plug_ins_locale_domain (gimp, progname, NULL);
......@@ -252,6 +269,13 @@ gui_menus_delete_entry (Gimp *gimp,
plug_in_menus_delete_entry (proc_def);
for (list = gimp_ui_managers_from_name ("<Image>");
list;
list = g_list_next (list))
{
plug_in_menus_remove_proc (list->data, proc_def);
}
for (list = gimp_action_groups_from_name ("plug-in");
list;
list = g_list_next (list))
......
......@@ -1140,6 +1140,7 @@ image_menu_setup2 (GimpUIManager *manager,
const gchar *ui_path)
{
menus_open_recent_add (manager, ui_path);
plug_in_menus_create2 (manager, ui_path);
}
void
......
......@@ -34,6 +34,7 @@
#include "plug-in/plug-in-run.h"
#include "widgets/gimpitemfactory.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
#include "actions/plug-in-commands.h"
......@@ -59,6 +60,14 @@ static gboolean plug_in_menu_tree_traverse_func (gpointer foo,
PlugInMenuEntry *menu_entry,
GimpItemFactory *item_factory);
static gboolean plug_in_menus_tree_traverse (gpointer foo,
PlugInProcDef *proc_def,
GimpUIManager *manager);
static void plug_in_menus_build_path (GimpUIManager *manager,
const gchar *ui_path,
guint merge_id,
const gchar *path);
/* public functions */
......@@ -113,6 +122,117 @@ plug_in_menus_init (Gimp *gimp,
g_slist_free (domains);
}
void
plug_in_menus_create2 (GimpUIManager *manager,
const gchar *ui_path)
{
GTree *menu_entries;
GSList *list;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
menu_entries = g_tree_new_full ((GCompareDataFunc) g_utf8_collate, NULL,
g_free, NULL);
for (list = manager->gimp->plug_in_proc_defs;
list;
list = g_slist_next (list))
{
PlugInProcDef *proc_def = list->data;
if (proc_def->prog &&
proc_def->menu_path &&
! proc_def->extensions &&
! proc_def->prefixes &&
! proc_def->magics)
{
if ((! strncmp (proc_def->menu_path, "<Toolbox>", 9) &&
! strcmp (ui_path, "/toolbox-menubar")) ||
(! strncmp (proc_def->menu_path, "<Image>", 7) &&
(! strcmp (ui_path, "/image-menubar") ||
! strcmp (ui_path, "/image-popup"))))
{
const gchar *progname;
const gchar *locale_domain;
gchar *key;
progname = plug_in_proc_def_get_progname (proc_def);
locale_domain = plug_ins_locale_domain (manager->gimp,
progname, NULL);
key = gimp_strip_uline (dgettext (locale_domain,
proc_def->menu_path));
g_tree_insert (menu_entries, key, proc_def);
}
}
}
g_object_set_data (G_OBJECT (manager), "ui-path", (gpointer) ui_path);
g_tree_foreach (menu_entries,
(GTraverseFunc) plug_in_menus_tree_traverse,
manager);
g_object_set_data (G_OBJECT (manager), "ui-path", NULL);
g_tree_destroy (menu_entries);
}
void
plug_in_menus_add_proc (GimpUIManager *manager,
const gchar *ui_path,
PlugInProcDef *proc_def)
{
gchar *path;
gchar *p;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
g_return_if_fail (proc_def != NULL);
path = g_strdup (proc_def->menu_path);
p = strrchr (path, '/');
if (p)
{
gchar *action_path;
guint merge_id;
*p = '\0';
merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
plug_in_menus_build_path (manager, ui_path, merge_id, path);
action_path = g_strdup_printf ("%s%s", ui_path, strchr (path, '/'));
g_print ("adding UI for '%s' (@ %s)\n",
proc_def->db_info.name, action_path);
gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
action_path,
proc_def->db_info.name,
proc_def->db_info.name,
GTK_UI_MANAGER_MENUITEM,
FALSE);
g_free (action_path);
}
g_free (path);
}
void
plug_in_menus_remove_proc (GimpUIManager *manager,
PlugInProcDef *proc_def)
{
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (proc_def != NULL);
}
void
plug_in_menus_create (GimpItemFactory *item_factory,
GSList *proc_defs)
......@@ -396,3 +516,60 @@ plug_in_menu_tree_traverse_func (gpointer foo,
return FALSE;
}
static gboolean
plug_in_menus_tree_traverse (gpointer foo,
PlugInProcDef *proc_def,
GimpUIManager *manager)
{
const gchar *ui_path = g_object_get_data (G_OBJECT (manager), "ui-path");
plug_in_menus_add_proc (manager, ui_path, proc_def);
return FALSE;
}
static void
plug_in_menus_build_path (GimpUIManager *manager,
const gchar *ui_path,
guint merge_id,
const gchar *path)
{
gchar *action_path;
action_path = g_strdup_printf ("%s%s", ui_path, strchr (path, '/'));
if (! gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), action_path))
{
gchar *base_path = g_strdup (path);
gchar *p;
p = strrchr (base_path, '/');
if (p)
{
gchar *name;
*p = '\0';
plug_in_menus_build_path (manager, ui_path, merge_id, base_path);
p = strrchr (action_path, '/');
*p = '\0';
g_print ("adding UI for '%s' (@ %s)\n",
path, action_path);
name = strrchr (path, '/') + 1;
gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
action_path, name, path,
GTK_UI_MANAGER_MENU,
FALSE);
}
g_free (base_path);
}
g_free (action_path);
}
......@@ -24,6 +24,14 @@ void plug_in_menus_init (Gimp *gimp,
GSList *plug_in_defs,
const gchar *std_plugins_domain);
void plug_in_menus_create2 (GimpUIManager *manager,
const gchar *ui_path);
void plug_in_menus_add_proc (GimpUIManager *manager,
const gchar *ui_path,
PlugInProcDef *proc_def);
void plug_in_menus_remove_proc (GimpUIManager *manager,
PlugInProcDef *proc_def);
void plug_in_menus_create (GimpItemFactory *item_factory,
GSList *proc_defs);
void plug_in_menus_create_entry (GimpItemFactory *item_factory,
......
......@@ -290,6 +290,7 @@ toolbox_menu_setup2 (GimpUIManager *manager,
const gchar *ui_path)
{
menus_open_recent_add (manager, ui_path);
plug_in_menus_create2 (manager, ui_path);
}
void
......
......@@ -1140,6 +1140,7 @@ image_menu_setup2 (GimpUIManager *manager,
const gchar *ui_path)
{
menus_open_recent_add (manager, ui_path);
plug_in_menus_create2 (manager, ui_path);
}
void
......
......@@ -34,6 +34,7 @@
#include "plug-in/plug-in-run.h"
#include "widgets/gimpitemfactory.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
#include "actions/plug-in-commands.h"
......@@ -59,6 +60,14 @@ static gboolean plug_in_menu_tree_traverse_func (gpointer foo,
PlugInMenuEntry *menu_entry,
GimpItemFactory *item_factory);
static gboolean plug_in_menus_tree_traverse (gpointer foo,
PlugInProcDef *proc_def,
GimpUIManager *manager);
static void plug_in_menus_build_path (GimpUIManager *manager,
const gchar *ui_path,
guint merge_id,
const gchar *path);
/* public functions */
......@@ -113,6 +122,117 @@ plug_in_menus_init (Gimp *gimp,
g_slist_free (domains);
}
void
plug_in_menus_create2 (GimpUIManager *manager,
const gchar *ui_path)
{
GTree *menu_entries;
GSList *list;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
menu_entries = g_tree_new_full ((GCompareDataFunc) g_utf8_collate, NULL,
g_free, NULL);
for (list = manager->gimp->plug_in_proc_defs;
list;
list = g_slist_next (list))
{
PlugInProcDef *proc_def = list->data;
if (proc_def->prog &&
proc_def->menu_path &&
! proc_def->extensions &&
! proc_def->prefixes &&
! proc_def->magics)
{
if ((! strncmp (proc_def->menu_path, "<Toolbox>", 9) &&
! strcmp (ui_path, "/toolbox-menubar")) ||
(! strncmp (proc_def->menu_path, "<Image>", 7) &&
(! strcmp (ui_path, "/image-menubar") ||
! strcmp (ui_path, "/image-popup"))))
{
const gchar *progname;
const gchar *locale_domain;
gchar *key;
progname = plug_in_proc_def_get_progname (proc_def);
locale_domain = plug_ins_locale_domain (manager->gimp,
progname, NULL);
key = gimp_strip_uline (dgettext (locale_domain,
proc_def->menu_path));
g_tree_insert (menu_entries, key, proc_def);
}
}
}
g_object_set_data (G_OBJECT (manager), "ui-path", (gpointer) ui_path);
g_tree_foreach (menu_entries,
(GTraverseFunc) plug_in_menus_tree_traverse,
manager);
g_object_set_data (G_OBJECT (manager), "ui-path", NULL);
g_tree_destroy (menu_entries);
}
void
plug_in_menus_add_proc (GimpUIManager *manager,
const gchar *ui_path,
PlugInProcDef *proc_def)
{
gchar *path;
gchar *p;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
g_return_if_fail (proc_def != NULL);
path = g_strdup (proc_def->menu_path);
p = strrchr (path, '/');
if (p)
{
gchar *action_path;
guint merge_id;
*p = '\0';
merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
plug_in_menus_build_path (manager, ui_path, merge_id, path);
action_path = g_strdup_printf ("%s%s", ui_path, strchr (path, '/'));
g_print ("adding UI for '%s' (@ %s)\n",
proc_def->db_info.name, action_path);
gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
action_path,
proc_def->db_info.name,
proc_def->db_info.name,
GTK_UI_MANAGER_MENUITEM,
FALSE);
g_free (action_path);
}
g_free (path);
}
void
plug_in_menus_remove_proc (GimpUIManager *manager,
PlugInProcDef *proc_def)
{
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (proc_def != NULL);
}
void
plug_in_menus_create (GimpItemFactory *item_factory,
GSList *proc_defs)
......@@ -396,3 +516,60 @@ plug_in_menu_tree_traverse_func (gpointer foo,
return FALSE;
}
static gboolean
plug_in_menus_tree_traverse (gpointer foo,
PlugInProcDef *proc_def,
GimpUIManager *manager)
{
const gchar *ui_path = g_object_get_data (G_OBJECT (manager), "ui-path");
plug_in_menus_add_proc (manager, ui_path, proc_def);
return FALSE;
}
static void
plug_in_menus_build_path (GimpUIManager *manager,
const gchar *ui_path,
guint merge_id,
const gchar *path)
{
gchar *action_path;
action_path = g_strdup_printf ("%s%s", ui_path, strchr (path, '/'));
if (! gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), action_path))
{
gchar *base_path = g_strdup (path);
gchar *p;
p = strrchr (base_path, '/');
if (p)
{
gchar *name;
*p = '\0';
plug_in_menus_build_path (manager, ui_path, merge_id, base_path);
p = strrchr (action_path, '/');
*p = '\0';
g_print ("adding UI for '%s' (@ %s)\n",
path, action_path);
name = strrchr (path, '/') + 1;
gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
action_path, name, path,
GTK_UI_MANAGER_MENU,
FALSE);
}
g_free (base_path);
}
g_free (action_path);
}
......@@ -24,6 +24,14 @@ void plug_in_menus_init (Gimp *gimp,
GSList *plug_in_defs,
const gchar *std_plugins_domain);
void plug_in_menus_create2 (GimpUIManager *manager,
const gchar *ui_path);
void plug_in_menus_add_proc (GimpUIManager *manager,
const gchar *ui_path,
PlugInProcDef *proc_def);
void plug_in_menus_remove_proc (GimpUIManager *manager,
PlugInProcDef *proc_def);
void plug_in_menus_create (GimpItemFactory *item_factory,
GSList *proc_defs);
void plug_in_menus_create_entry (GimpItemFactory *item_factory,
......
......@@ -290,6 +290,7 @@ toolbox_menu_setup2 (GimpUIManager *manager,
const gchar *ui_path)
{
menus_open_recent_add (manager, ui_path);
plug_in_menus_create2 (manager, ui_path);
}
void
......
......@@ -318,7 +318,7 @@ gimp_menu_factory_manager_new (GimpMenuFactory *factory,
GimpUIManager *manager;
GList *list;
manager = gimp_ui_manager_new (factory->gimp);
manager = gimp_ui_manager_new (factory->gimp, entry->identifier);
gtk_ui_manager_set_add_tearoffs (GTK_UI_MANAGER (manager),
create_tearoff);
......
......@@ -38,22 +38,27 @@
enum
{
PROP_0,
PROP_NAME,
PROP_GIMP
};
static void gimp_ui_manager_init (GimpUIManager *manager);
static void gimp_ui_manager_class_init (GimpUIManagerClass *klass);
static void gimp_ui_manager_init (GimpUIManager *manager);
static void gimp_ui_manager_class_init (GimpUIManagerClass *klass);