static void plug_in_actions_build_path (GimpActionGroup *group, const gchar *path_original, const gchar *path_translated) { GHashTable *path_table; gchar *copy_original; gchar *copy_translated; 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); } copy_original = gimp_strip_uline (path_original); copy_translated = g_strdup (path_translated); p1 = strrchr (copy_original, '/'); p2 = strrchr (copy_translated, '/'); if (p1 && p2 && ! g_hash_table_lookup (path_table, copy_original)) { GtkAction *action; gchar *label; label = p2 + 1; #if 0 g_print ("adding plug-in submenu '%s' (%s)\n", copy_original, label); #endif action = gtk_action_new (copy_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 (copy_original), action); *p1 = '\0'; *p2 = '\0'; /* recursively call ourselves with the last part of the path removed */ plug_in_actions_build_path (group, copy_original, copy_translated); } g_free (copy_original); g_free (copy_translated); }
static void plug_in_menus_tree_insert (GTree *entries, const gchar *path, PlugInMenuEntry *entry) { gchar *strip = gimp_strip_uline (path); gchar *key; /* Append the procedure name to the menu path in order to get a unique * key even if two procedures are installed to the same menu entry. */ key = g_strconcat (strip, gimp_object_get_name (entry->proc), NULL); g_tree_insert (entries, g_utf8_collate_key (key, -1), entry); g_free (key); g_free (strip); }
const gchar * gimp_plug_in_procedure_get_label (GimpPlugInProcedure *proc) { const gchar *path; gchar *stripped; gchar *ellipsis; gchar *label; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); if (proc->label) return proc->label; if (proc->menu_label) path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc), proc->menu_label); else if (proc->menu_paths) path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc), proc->menu_paths->data); else return NULL; stripped = gimp_strip_uline (path); if (proc->menu_label) label = g_strdup (stripped); else label = g_path_get_basename (stripped); g_free (stripped); ellipsis = strstr (label, "..."); if (! ellipsis) ellipsis = strstr (label, "\342\200\246" /* U+2026 HORIZONTAL ELLIPSIS */); if (ellipsis && ellipsis == (label + strlen (label) - 3)) *ellipsis = '\0'; proc->label = label; return proc->label; }
void debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action, gpointer data) { GimpDisplay *display; GimpImageWindow *window; GtkUIManager *manager; GtkAccelGroup *accel_group; GList *group_it; GList *strings = NULL; return_if_no_display (display, data); window = gimp_display_shell_get_window (gimp_display_get_shell (display)); manager = GTK_UI_MANAGER (gimp_image_window_get_ui_manager (window)); accel_group = gtk_ui_manager_get_accel_group (manager); /* Gather formated strings of keyboard shortcuts */ for (group_it = gtk_ui_manager_get_action_groups (manager); group_it; group_it = g_list_next (group_it)) { GimpActionGroup *group = group_it->data; GList *actions = NULL; GList *action_it = NULL; actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group)); actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare); for (action_it = actions; action_it; action_it = g_list_next (action_it)) { GtkAction *action = action_it->data; const gchar *name = gtk_action_get_name (action); GClosure *accel_closure = NULL; if (strstr (name, "-menu") || strstr (name, "-popup") || name[0] == '<') continue; accel_closure = gtk_action_get_accel_closure (action); if (accel_closure) { GtkAccelKey *key = gtk_accel_group_find (accel_group, debug_accel_find_func, accel_closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { const gchar *label_tmp; gchar *label; gchar *key_string; label_tmp = gtk_action_get_label (action); label = gimp_strip_uline (label_tmp); key_string = gtk_accelerator_get_label (key->accel_key, key->accel_mods); strings = g_list_prepend (strings, g_strdup_printf ("%-20s %s", key_string, label)); g_free (key_string); g_free (label); } } } g_list_free (actions); } /* Sort and prints the strings */ { GList *string_it = NULL; strings = g_list_sort (strings, (GCompareFunc) strcmp); for (string_it = strings; string_it; string_it = g_list_next (string_it)) { g_print ("%s\n", (gchar *) string_it->data); g_free (string_it->data); } g_list_free (strings); } }
static void gimp_action_view_conflict_confirm (GimpActionView *view, GtkAction *action, guint accel_key, GdkModifierType accel_mask, const gchar *accel_path) { GimpActionGroup *group; gchar *label; gchar *accel_string; ConfirmData *confirm_data; GtkWidget *dialog; GimpMessageBox *box; g_object_get (action, "action-group", &group, NULL); label = gimp_strip_uline (gtk_action_get_label (action)); accel_string = gtk_accelerator_get_label (accel_key, accel_mask); confirm_data = g_slice_new (ConfirmData); confirm_data->manager = view->manager; confirm_data->accel_path = g_strdup (accel_path); confirm_data->accel_key = accel_key; confirm_data->accel_mask = accel_mask; dialog = gimp_message_dialog_new (_("Conflicting Shortcuts"), GIMP_STOCK_WARNING, gtk_widget_get_toplevel (GTK_WIDGET (view)), 0, gimp_standard_help_func, NULL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Reassign shortcut"), GTK_RESPONSE_OK, NULL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); g_signal_connect (dialog, "response", G_CALLBACK (gimp_action_view_conflict_response), confirm_data); box = GIMP_MESSAGE_DIALOG (dialog)->box; gimp_message_box_set_primary_text (box, _("Shortcut \"%s\" is already taken " "by \"%s\" from the \"%s\" group."), accel_string, label, group->label); gimp_message_box_set_text (box, _("Reassigning the shortcut will cause it " "to be removed from \"%s\"."), label); g_free (label); g_free (accel_string); g_object_unref (group); gtk_widget_show (dialog); }
GtkWidget * gimp_action_view_new (GimpUIManager *manager, const gchar *select_action, gboolean show_shortcuts) { GtkTreeView *view; GtkTreeViewColumn *column; GtkCellRenderer *cell; GtkTreeStore *store; GtkTreeModel *filter; GtkAccelGroup *accel_group; GList *list; GtkTreePath *select_path = NULL; g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL); store = gtk_tree_store_new (GIMP_ACTION_VIEW_N_COLUMNS, G_TYPE_BOOLEAN, /* COLUMN_VISIBLE */ GTK_TYPE_ACTION, /* COLUMN_ACTION */ G_TYPE_STRING, /* COLUMN_STOCK_ID */ G_TYPE_STRING, /* COLUMN_LABEL */ G_TYPE_STRING, /* COLUMN_LABEL_CASEFOLD */ G_TYPE_STRING, /* COLUMN_NAME */ G_TYPE_UINT, /* COLUMN_ACCEL_KEY */ GDK_TYPE_MODIFIER_TYPE, /* COLUMN_ACCEL_MASK */ G_TYPE_CLOSURE); /* COLUMN_ACCEL_CLOSURE */ accel_group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager)); for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager)); list; list = g_list_next (list)) { GimpActionGroup *group = list->data; GList *actions; GList *list2; GtkTreeIter group_iter; gtk_tree_store_append (store, &group_iter, NULL); gtk_tree_store_set (store, &group_iter, GIMP_ACTION_VIEW_COLUMN_STOCK_ID, group->stock_id, GIMP_ACTION_VIEW_COLUMN_LABEL, group->label, -1); actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group)); actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare); for (list2 = actions; list2; list2 = g_list_next (list2)) { GtkAction *action = list2->data; const gchar *name = gtk_action_get_name (action); const gchar *stock_id = gtk_action_get_stock_id (action); gchar *label; gchar *label_casefold; guint accel_key = 0; GdkModifierType accel_mask = 0; GClosure *accel_closure = NULL; GtkTreeIter action_iter; if (strstr (name, "-menu") || strstr (name, "-popup") || name[0] == '<') continue; label = gimp_strip_uline (gtk_action_get_label (action)); if (! (label && strlen (label))) { g_free (label); label = g_strdup (name); } label_casefold = g_utf8_casefold (label, -1); if (show_shortcuts) { accel_closure = gtk_action_get_accel_closure (action); if (accel_closure) { GtkAccelKey *key; key = gtk_accel_group_find (accel_group, gimp_action_view_accel_find_func, accel_closure); if (key && key->accel_key && key->accel_flags & GTK_ACCEL_VISIBLE) { accel_key = key->accel_key; accel_mask = key->accel_mods; } } } gtk_tree_store_append (store, &action_iter, &group_iter); gtk_tree_store_set (store, &action_iter, GIMP_ACTION_VIEW_COLUMN_VISIBLE, TRUE, GIMP_ACTION_VIEW_COLUMN_ACTION, action, GIMP_ACTION_VIEW_COLUMN_STOCK_ID, stock_id, GIMP_ACTION_VIEW_COLUMN_LABEL, label, GIMP_ACTION_VIEW_COLUMN_LABEL_CASEFOLD, label_casefold, GIMP_ACTION_VIEW_COLUMN_NAME, name, GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY, accel_key, GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK, accel_mask, GIMP_ACTION_VIEW_COLUMN_ACCEL_CLOSURE, accel_closure, -1); g_free (label); g_free (label_casefold); if (select_action && ! strcmp (select_action, name)) { select_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &action_iter); } } g_list_free (actions); } filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); g_object_unref (store); view = g_object_new (GIMP_TYPE_ACTION_VIEW, "model", filter, "rules-hint", TRUE, NULL); g_object_unref (filter); gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), GIMP_ACTION_VIEW_COLUMN_VISIBLE); GIMP_ACTION_VIEW (view)->manager = g_object_ref (manager); GIMP_ACTION_VIEW (view)->show_shortcuts = show_shortcuts; gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), GIMP_ACTION_VIEW_COLUMN_LABEL); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Action")); cell = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); gtk_tree_view_column_set_attributes (column, cell, "stock-id", GIMP_ACTION_VIEW_COLUMN_STOCK_ID, NULL); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "text", GIMP_ACTION_VIEW_COLUMN_LABEL, NULL); gtk_tree_view_append_column (view, column); if (show_shortcuts) { g_signal_connect (view, "button-press-event", G_CALLBACK (gimp_action_view_button_press), NULL); g_signal_connect (accel_group, "accel-changed", G_CALLBACK (gimp_action_view_accel_changed), view); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Shortcut")); cell = gtk_cell_renderer_accel_new (); g_object_set (cell, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, "editable", TRUE, NULL); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "accel-key", GIMP_ACTION_VIEW_COLUMN_ACCEL_KEY, "accel-mods", GIMP_ACTION_VIEW_COLUMN_ACCEL_MASK, NULL); g_signal_connect (cell, "accel-edited", G_CALLBACK (gimp_action_view_accel_edited), view); g_signal_connect (cell, "accel-cleared", G_CALLBACK (gimp_action_view_accel_cleared), view); gtk_tree_view_append_column (view, column); } column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Name")); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "text", GIMP_ACTION_VIEW_COLUMN_NAME, NULL); gtk_tree_view_append_column (view, column); if (select_path) { gimp_action_view_select_path (GIMP_ACTION_VIEW (view), select_path); gtk_tree_path_free (select_path); } return GTK_WIDGET (view); }
static void plug_in_menus_add_proc (GimpUIManager *manager, const gchar *ui_path, GimpPlugInProcedure *proc, const gchar *menu_path) { gchar *path; gchar *merge_key; gchar *stripped_path; gchar *action_path; guint merge_id; guint menu_merge_id; g_return_if_fail (GIMP_IS_UI_MANAGER (manager)); g_return_if_fail (ui_path != NULL); g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); path = g_strdup (menu_path); if (! proc->menu_label) { gchar *p; if (! path) return; p = strrchr (path, '/'); if (! p) { g_free (path); return; } *p = '\0'; } merge_key = g_strdup_printf ("%s-merge-id", gimp_object_get_name (proc)); merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (manager), merge_key)); if (! merge_id) { merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager)); g_object_set_data (G_OBJECT (manager), merge_key, GUINT_TO_POINTER (merge_id)); } g_free (merge_key); menu_merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (manager), "plug-in-menu-merge-id")); if (! menu_merge_id) { menu_merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager)); g_object_set_data (G_OBJECT (manager), "plug-in-menu-merge-id", GUINT_TO_POINTER (menu_merge_id)); } stripped_path = gimp_strip_uline (path); action_path = plug_in_menus_build_path (manager, ui_path, menu_merge_id, stripped_path, FALSE); g_free (stripped_path); if (! action_path) { g_free (path); return; } GIMP_LOG (MENUS, "adding menu item for '%s' (@ %s)", gimp_object_get_name (proc), action_path); gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id, action_path, gimp_object_get_name (proc), gimp_object_get_name (proc), GTK_UI_MANAGER_MENUITEM, FALSE); g_free (action_path); g_free (path); }
gchar * plug_in_menu_path_map (const gchar *menu_path, const gchar *menu_label) { const MenuPathMapping *mapping; gchar *stripped_label = NULL; g_return_val_if_fail (menu_path != NULL, NULL); if (menu_label) stripped_label = gimp_strip_uline (menu_label); for (mapping = menu_path_mappings; mapping->orig_path; mapping++) { if (g_str_has_prefix (menu_path, mapping->orig_path)) { gint orig_len = strlen (mapping->orig_path); gchar *mapped_path; /* if the mapping has a label, only map if the passed label * is identical and the paths' lengths match exactly. */ if (mapping->label && (! stripped_label || strlen (menu_path) != orig_len || strcmp (mapping->label, stripped_label))) { continue; } if (strlen (menu_path) > orig_len) mapped_path = g_strconcat (mapping->mapped_path, menu_path + orig_len, NULL); else mapped_path = g_strdup (mapping->mapped_path); #if GIMP_UNSTABLE { gchar *orig; gchar *mapped; if (menu_label) { orig = g_strdup_printf ("%s/%s", menu_path, stripped_label); mapped = g_strdup_printf ("%s/%s", mapped_path, stripped_label); } else { orig = g_strdup (menu_path); mapped = g_strdup (mapped_path); } g_printerr (" mapped '%s' to '%s'\n", orig, mapped); g_free (orig); g_free (mapped); } #endif g_free (stripped_label); return mapped_path; } } g_free (stripped_label); return g_strdup (menu_path); }
gint gimp_plug_in_manager_query (GimpPlugInManager *manager, const gchar *search_str, gchar ***menu_strs, gchar ***accel_strs, gchar ***prog_strs, gchar ***types_strs, gchar ***realname_strs, gint32 **time_ints) { gint32 num_plugins = 0; GSList *list; GSList *matched = NULL; gint i = 0; GRegex *sregex = NULL; g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), 0); g_return_val_if_fail (menu_strs != NULL, 0); g_return_val_if_fail (accel_strs != NULL, 0); g_return_val_if_fail (prog_strs != NULL, 0); g_return_val_if_fail (types_strs != NULL, 0); g_return_val_if_fail (realname_strs != NULL, 0); g_return_val_if_fail (time_ints != NULL, 0); *menu_strs = NULL; *accel_strs = NULL; *prog_strs = NULL; *types_strs = NULL; *realname_strs = NULL; *time_ints = NULL; if (search_str && ! strlen (search_str)) search_str = NULL; if (search_str) { sregex = g_regex_new (search_str, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, NULL); if (! sregex) return 0; } /* count number of plugin entries, then allocate arrays of correct size * where we can store the strings. */ for (list = manager->plug_in_procedures; list; list = g_slist_next (list)) { GimpPlugInProcedure *proc = list->data; if (proc->file && proc->menu_paths) { gchar *name; if (proc->menu_label) { name = proc->menu_label; } else { name = strrchr (proc->menu_paths->data, '/'); if (name) name = name + 1; else name = proc->menu_paths->data; } name = gimp_strip_uline (name); if (! search_str || match_string (sregex, name)) { num_plugins++; matched = g_slist_prepend (matched, proc); } g_free (name); } } *menu_strs = g_new (gchar *, num_plugins); *accel_strs = g_new (gchar *, num_plugins); *prog_strs = g_new (gchar *, num_plugins); *types_strs = g_new (gchar *, num_plugins); *realname_strs = g_new (gchar *, num_plugins); *time_ints = g_new (gint, num_plugins); matched = g_slist_reverse (matched); for (list = matched; list; list = g_slist_next (list)) { GimpPlugInProcedure *proc = list->data; gchar *name; if (proc->menu_label) name = g_strdup_printf ("%s/%s", (gchar *) proc->menu_paths->data, proc->menu_label); else name = g_strdup (proc->menu_paths->data); (*menu_strs)[i] = gimp_strip_uline (name); (*accel_strs)[i] = NULL; (*prog_strs)[i] = g_file_get_path (proc->file); (*types_strs)[i] = g_strdup (proc->image_types); (*realname_strs)[i] = g_strdup (gimp_object_get_name (proc)); (*time_ints)[i] = proc->mtime; g_free (name); i++; } g_slist_free (matched); if (sregex) g_regex_unref (sregex); return num_plugins; }