40 #include "swig-runtime.h"
42 #include "guile-util.h"
48 #include "gnc-menu-extensions.h"
50 static GObjectClass *parent_class = NULL;
54 static void gnc_plugin_menu_additions_finalize (GObject *
object);
56 static void gnc_plugin_menu_additions_add_to_window (
GncPlugin *plugin,
GncMainWindow *window, GQuark type);
57 static void gnc_plugin_menu_additions_remove_from_window (
GncPlugin *plugin,
GncMainWindow *window, GQuark type);
64 #define PLUGIN_ACTIONS_NAME "gnc-plugin-menu-additions-actions"
72 #define GNC_PLUGIN_MENU_ADDITIONS_GET_PRIVATE(o) \
73 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_MENU_ADDITIONS, GncPluginMenuAdditionsPrivate))
84 GtkUIManager *ui_manager;
85 GtkActionGroup *group;
96 static GType gnc_plugin_menu_additions_type = 0;
98 if (gnc_plugin_menu_additions_type == 0)
100 static const GTypeInfo our_info =
105 (GClassInitFunc) gnc_plugin_menu_additions_class_init,
110 (GInstanceInitFunc) gnc_plugin_menu_additions_init
113 gnc_plugin_menu_additions_type = g_type_register_static (GNC_TYPE_PLUGIN,
114 "GncPluginMenuAdditions",
118 return gnc_plugin_menu_additions_type;
124 GObjectClass *object_class = G_OBJECT_CLASS (klass);
127 parent_class = g_type_class_peek_parent (klass);
129 object_class->finalize = gnc_plugin_menu_additions_finalize;
132 plugin_class->
plugin_name = GNC_PLUGIN_MENU_ADDITIONS_NAME;
135 plugin_class->
add_to_window = gnc_plugin_menu_additions_add_to_window;
144 ENTER(
"plugin %p", plugin);
149 gnc_plugin_menu_additions_finalize (GObject *
object)
151 g_return_if_fail (GNC_IS_PLUGIN_MENU_ADDITIONS (
object));
153 ENTER(
"plugin %p",
object);
154 G_OBJECT_CLASS (parent_class)->finalize (
object);
170 plugin_page = GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_MENU_ADDITIONS, NULL));
171 LEAVE(
"plugin %p", plugin_page);
182 static swig_type_info * main_window_type = NULL;
187 if (!main_window_type)
188 main_window_type = SWIG_TypeQuery(
"_p_GncMainWindow");
190 return SWIG_NewPointerObj(window, main_window_type, 0);
206 gnc_plugin_menu_additions_action_cb (GtkAction *action,
210 g_return_if_fail(GTK_IS_ACTION(action));
211 g_return_if_fail(data != NULL);
213 gnc_extension_invoke_cb(data->data, gnc_main_window_to_scm(data->window));
231 if (a->type == b->type)
232 return strcmp(a->sort_key, b->sort_key);
233 else if (a->type == GTK_UI_MANAGER_MENU)
235 else if (b->type == GTK_UI_MANAGER_MENU)
248 gnc_menu_additions_init_accel_table (gpointer unused)
250 return g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
267 gchar *map, *new_map, *accel_key;
270 ENTER(
"Checking %s/%s [%s]", info->path, info->ae.label, info->ae.name);
271 if (info->accel_assigned)
273 LEAVE(
"Already processed");
277 if (!g_utf8_validate(info->ae.label, -1, NULL))
279 g_warning(
"Extension menu label '%s' is not valid utf8.", info->ae.label);
280 info->accel_assigned = TRUE;
281 LEAVE(
"Label is invalid utf8");
286 ptr = g_utf8_strchr(info->ae.label, -1,
'_');
289 LEAVE(
"not preassigned");
293 accel_key = g_utf8_strdown(g_utf8_next_char(ptr), 1);
294 DEBUG(
"Accelerator preassigned: '%s'", accel_key);
297 map = g_hash_table_lookup(table, info->path);
300 new_map = g_strconcat(map, accel_key, (gchar *)NULL);
301 DEBUG(
"path '%s', map '%s' -> '%s'", info->path, map, new_map);
302 g_hash_table_replace(table, info->path, new_map);
304 info->accel_assigned = TRUE;
306 LEAVE(
"preassigned");
322 gnc_menu_additions_assign_accel (
ExtensionInfo *info, GHashTable *table)
324 gchar *map, *new_map, *new_label, *start, buf[16];
329 ENTER(
"Checking %s/%s [%s]", info->path, info->ae.label, info->ae.name);
330 if (info->accel_assigned)
332 LEAVE(
"Already processed");
337 map = g_hash_table_lookup(table, info->path);
340 DEBUG(
"map '%s', path %s", map, info->path);
342 for (ptr = info->ae.label; *ptr; ptr = g_utf8_next_char(ptr))
344 uni = g_utf8_get_char(ptr);
345 if (!g_unichar_isalpha(uni))
347 uni = g_unichar_tolower(uni);
348 len = g_unichar_to_utf8(uni, buf);
350 DEBUG(
"Testing character '%s'", buf);
351 if (!g_utf8_strchr(map, -1, uni))
358 info->accel_assigned = TRUE;
359 LEAVE(
"All characters already assigned");
364 start = g_strndup(info->ae.label, ptr - info->ae.label);
365 DEBUG(
"start %p, len %ld, text '%s'", start, g_utf8_strlen(start, -1), start);
366 new_label = g_strconcat(start,
"_", ptr, (gchar *)NULL);
368 DEBUG(
"label '%s' -> '%s'", info->ae.label, new_label);
369 g_free((gchar *)info->ae.label);
370 info->ae.label = new_label;
373 new_map = g_strconcat(map, buf, (gchar *)NULL);
374 DEBUG(
"map '%s' -> '%s'", map, new_map);
375 g_hash_table_replace(table, info->path, new_map);
377 info->accel_assigned = TRUE;
397 DEBUG(
"Adding %s/%s [%s] as [%s]", ext_info->path, ext_info->ae.label,
398 ext_info->ae.name, ext_info->typeStr );
401 cb_data->window = per_window->
window;
402 cb_data->data = ext_info->extension;
404 if (ext_info->type == GTK_UI_MANAGER_MENUITEM)
405 ext_info->ae.callback = (GCallback)gnc_plugin_menu_additions_action_cb;
407 gtk_action_group_add_actions_full(per_window->group, &ext_info->ae, 1,
409 gtk_ui_manager_add_ui(per_window->ui_manager, per_window->merge_id,
410 ext_info->path, ext_info->ae.label, ext_info->ae.name,
411 ext_info->type, FALSE);
412 gtk_ui_manager_ensure_update(per_window->ui_manager);
429 gnc_plugin_menu_additions_add_to_window (
GncPlugin *plugin,
434 static GOnce accel_table_init = G_ONCE_INIT;
435 static GHashTable *table;
440 per_window.
window = window;
441 per_window.ui_manager = window->
ui_merge;
442 per_window.group = gtk_action_group_new (
"MenuAdditions" );
444 per_window.merge_id = gtk_ui_manager_new_merge_id(window->
ui_merge);
445 gtk_ui_manager_insert_action_group(window->
ui_merge, per_window.group, 0);
447 menu_list = g_slist_sort(gnc_extensions_get_menu_list(),
448 (GCompareFunc)gnc_menu_additions_sort);
451 table = g_once(&accel_table_init, gnc_menu_additions_init_accel_table, NULL);
452 g_slist_foreach(menu_list,
453 (GFunc)gnc_menu_additions_do_preassigned_accel, table);
454 g_slist_foreach(menu_list, (GFunc)gnc_menu_additions_assign_accel, table);
457 g_slist_foreach(menu_list, (GFunc)gnc_menu_additions_menu_setup_one,
463 per_window.group, per_window.merge_id);
465 g_slist_free(menu_list);
482 gnc_plugin_menu_additions_remove_from_window (
GncPlugin *plugin,
486 GtkActionGroup *group;
494 gtk_ui_manager_remove_action_group(window->
ui_merge, group);
#define DEBUG(format, args...)
Functions that are supported by all types of windows.
#define ENTER(format, args...)
Functions for adding content to a window.
void(* remove_from_window)(GncPlugin *plugin, GncMainWindow *window, GQuark type)
All type declarations for the whole Gnucash engine.
GtkActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
const gchar * plugin_name
void gnc_main_window_manual_merge_actions(GncMainWindow *window, const gchar *group_name, GtkActionGroup *group, guint merge_id)
#define PLUGIN_ACTIONS_NAME
#define LEAVE(format, args...)
void(* add_to_window)(GncPlugin *plugin, GncMainWindow *window, GQuark type)
void gnc_gtk_action_group_set_translation_domain(GtkActionGroup *action_group, const gchar *domain)
const gchar * QofLogModule