diff options
Diffstat (limited to 'gtk/gtkitemfactory.c')
-rw-r--r-- | gtk/gtkitemfactory.c | 581 |
1 files changed, 35 insertions, 546 deletions
diff --git a/gtk/gtkitemfactory.c b/gtk/gtkitemfactory.c index 6ab691fbad..02fa3df2e6 100644 --- a/gtk/gtkitemfactory.c +++ b/gtk/gtkitemfactory.c @@ -39,6 +39,7 @@ #include "gtk/gtkcheckmenuitem.h" #include "gtk/gtkimagemenuitem.h" #include "gtk/gtktearoffmenuitem.h" +#include "gtk/gtkaccelmap.h" #include "gtk/gtkaccellabel.h" #include "gdk/gdkkeysyms.h" #include "gtk/gtkimage.h" @@ -75,13 +76,6 @@ struct _GtkIFCBData gpointer func_data; guint callback_action; }; -struct _GtkIFDumpData -{ - GtkPrintFunc print_func; - gpointer func_data; - guint modified_only : 1; - GPatternSpec *pspec; -}; /* --- prototypes --- */ @@ -114,47 +108,6 @@ static GQuark quark_type_tearoff_item = 0; static GQuark quark_type_separator_item = 0; static GQuark quark_type_branch = 0; static GQuark quark_type_last_branch = 0; -static GScannerConfig ifactory_scanner_config = -{ - ( - " \t\n" - ) /* cset_skip_characters */, - ( - G_CSET_a_2_z - "_" - G_CSET_A_2_Z - ) /* cset_identifier_first */, - ( - G_CSET_a_2_z - "-+_0123456789" - G_CSET_A_2_Z - G_CSET_LATINS - G_CSET_LATINC - ) /* cset_identifier_nth */, - ( ";\n" ) /* cpair_comment_single */, - - FALSE /* case_sensitive */, - - TRUE /* skip_comment_multi */, - TRUE /* skip_comment_single */, - FALSE /* scan_comment_multi */, - TRUE /* scan_identifier */, - FALSE /* scan_identifier_1char */, - FALSE /* scan_identifier_NULL */, - TRUE /* scan_symbols */, - TRUE /* scan_binary */, - TRUE /* scan_octal */, - TRUE /* scan_float */, - TRUE /* scan_hex */, - FALSE /* scan_hex_dollar */, - TRUE /* scan_string_sq */, - TRUE /* scan_string_dq */, - TRUE /* numbers_2_int */, - FALSE /* int_2_float */, - FALSE /* identifier_2_string */, - TRUE /* char_2_token */, - FALSE /* symbol_2_token */, -}; /* --- functions --- */ @@ -187,22 +140,16 @@ static void gtk_item_factory_class_init (GtkItemFactoryClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GtkObjectClass *object_class; + GtkObjectClass *object_class = GTK_OBJECT_CLASS (class); gtk_item_factory_class = class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class = (GtkObjectClass*) class; + parent_class = g_type_class_peek_parent (class); gobject_class->finalize = gtk_item_factory_finalize; object_class->destroy = gtk_item_factory_destroy; - class->cpair_comment_single = g_strdup (";\n"); - class->item_ht = g_hash_table_new (g_str_hash, g_str_equal); - class->dummy = NULL; ifactory_item_chunks = g_mem_chunk_new ("GtkItemFactoryItem", sizeof (GtkItemFactoryItem), @@ -285,125 +232,6 @@ gtk_item_factory_callback_marshal (GtkWidget *widget, } static void -gtk_item_factory_propagate_accelerator (GtkItemFactoryItem *item, - GtkWidget *exclude) -{ - GSList *widget_list; - GSList *slist; - - if (item->in_propagation) - return; - - item->in_propagation = TRUE; - - widget_list = NULL; - for (slist = item->widgets; slist; slist = slist->next) - { - GtkWidget *widget; - - widget = slist->data; - - if (widget != exclude) - { - gtk_widget_ref (widget); - widget_list = g_slist_prepend (widget_list, widget); - } - } - - for (slist = widget_list; slist; slist = slist->next) - { - GtkWidget *widget; - GtkAccelGroup *accel_group; - guint signal_id; - - widget = slist->data; - - accel_group = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_accel_group); - - signal_id = gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget)); - if (signal_id && accel_group) - { - if (item->accelerator_key) - gtk_widget_add_accelerator (widget, - "activate", - accel_group, - item->accelerator_key, - item->accelerator_mods, - GTK_ACCEL_VISIBLE); - else - { - GSList *work; - - work = gtk_accel_group_entries_from_object (G_OBJECT (widget)); - while (work) - { - GtkAccelEntry *ac_entry; - - ac_entry = work->data; - work = work->next; - if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE && - ac_entry->accel_group == accel_group && - ac_entry->signal_id == signal_id) - gtk_widget_remove_accelerator (GTK_WIDGET (widget), - ac_entry->accel_group, - ac_entry->accelerator_key, - ac_entry->accelerator_mods); - } - } - } - - gtk_widget_unref (widget); - } - - g_slist_free (widget_list); - - item->in_propagation = FALSE; -} - -static gint -gtk_item_factory_item_add_accelerator (GtkWidget *widget, - guint accel_signal_id, - GtkAccelGroup *accel_group, - guint accel_key, - guint accel_mods, - GtkAccelFlags accel_flags, - GtkItemFactoryItem *item) -{ - if (!item->in_propagation && - g_slist_find (item->widgets, widget) && - accel_signal_id == gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget))) - { - item->accelerator_key = accel_key; - item->accelerator_mods = accel_mods; - item->modified = TRUE; - - gtk_item_factory_propagate_accelerator (item, widget); - } - - return TRUE; -} - -static void -gtk_item_factory_item_remove_accelerator (GtkWidget *widget, - GtkAccelGroup *accel_group, - guint accel_key, - guint accel_mods, - GtkItemFactoryItem *item) -{ - if (!item->in_propagation && - g_slist_find (item->widgets, widget) && - item->accelerator_key == accel_key && - item->accelerator_mods == accel_mods) - { - item->accelerator_key = 0; - item->accelerator_mods = 0; - item->modified = TRUE; - - gtk_item_factory_propagate_accelerator (item, widget); - } -} - -static void gtk_item_factory_item_remove_widget (GtkWidget *widget, GtkItemFactoryItem *item) { @@ -416,8 +244,8 @@ void gtk_item_factory_add_foreign (GtkWidget *accel_widget, const gchar *full_path, GtkAccelGroup *accel_group, - guint keyval, - GdkModifierType modifiers) + guint accel_key, + GdkModifierType accel_mods) { GtkItemFactoryClass *class; GtkItemFactoryItem *item; @@ -427,7 +255,7 @@ gtk_item_factory_add_foreign (GtkWidget *accel_widget, class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); - keyval = keyval != GDK_VoidSymbol ? keyval : 0; + accel_key = accel_key != GDK_VoidSymbol ? accel_key : 0; item = g_hash_table_lookup (class->item_ht, full_path); if (!item) @@ -435,11 +263,6 @@ gtk_item_factory_add_foreign (GtkWidget *accel_widget, item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); item->path = g_strdup (full_path); - item->accelerator_key = keyval; - item->accelerator_mods = modifiers; - item->modified = FALSE; - item->in_propagation = FALSE; - item->dummy = NULL; item->widgets = NULL; g_hash_table_insert (class->item_ht, item->path, item); @@ -470,29 +293,12 @@ gtk_item_factory_add_foreign (GtkWidget *accel_widget, */ if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (accel_widget))) { - if (item->accelerator_key && accel_group) - gtk_widget_add_accelerator (accel_widget, - "activate", - accel_group, - item->accelerator_key, - item->accelerator_mods, - GTK_ACCEL_VISIBLE); - else - gtk_widget_remove_accelerators (accel_widget, - "activate", - TRUE); + if (accel_key && accel_group) + { + gtk_accel_map_add_entry (full_path, accel_key, accel_mods); + _gtk_widget_set_accel_path (accel_widget, full_path, accel_group); + } } - - /* keep track of accelerator changes - */ - gtk_signal_connect_after (GTK_OBJECT (accel_widget), - "add-accelerator", - GTK_SIGNAL_FUNC (gtk_item_factory_item_add_accelerator), - item); - gtk_signal_connect_after (GTK_OBJECT (accel_widget), - "remove-accelerator", - GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_accelerator), - item); } static void @@ -725,136 +531,6 @@ gtk_item_factory_path_from_widget (GtkWidget *widget) return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_path); } -static gchar * -item_factory_escape_path (const gchar *path) -{ - GString *str = g_string_new (NULL); - - while (*path) - { - gchar c = *path; - - switch (c) - { - case '\n': - g_string_append (str, "\\n"); - break; - case '\r': - g_string_append (str, "\\r"); - break; - case '"': - case '\\': - g_string_append_c (str, '\\'); - /* Fall through */ - default: - g_string_append_c (str, c); - } - - path++; - } - - return g_string_free (str, FALSE); -} - -static void -gtk_item_factory_foreach (gpointer hash_key, - gpointer value, - gpointer user_data) -{ - GtkItemFactoryItem *item; - GtkIFDumpData *data; - gchar *string; - gchar *path; - gchar *name; - gchar comment_prefix[2] = "\000\000"; - - item = value; - data = user_data; - - if (data->pspec && !g_pattern_match_string (data->pspec, item->path)) - return; - - comment_prefix[0] = gtk_item_factory_class->cpair_comment_single[0]; - - path = item_factory_escape_path (hash_key); - name = gtk_accelerator_name (item->accelerator_key, item->accelerator_mods); - string = g_strconcat (item->modified ? "" : comment_prefix, - "(menu-path \"", - path, - "\" \"", - name, - "\")", - NULL); - g_free (path); - g_free (name); - - data->print_func (data->func_data, string); - - g_free (string); -} - -void -gtk_item_factory_dump_items (GPatternSpec *path_pspec, - gboolean modified_only, - GtkPrintFunc print_func, - gpointer func_data) -{ - GtkIFDumpData data; - - g_return_if_fail (print_func != NULL); - - if (!gtk_item_factory_class) - gtk_type_class (GTK_TYPE_ITEM_FACTORY); - - data.print_func = print_func; - data.func_data = func_data; - data.modified_only = (modified_only != FALSE); - data.pspec = path_pspec; - - g_hash_table_foreach (gtk_item_factory_class->item_ht, gtk_item_factory_foreach, &data); -} - -void -gtk_item_factory_print_func (gpointer FILE_pointer, - const gchar *string) -{ - FILE *f_out = FILE_pointer; - - g_return_if_fail (FILE_pointer != NULL); - g_return_if_fail (string != NULL); - - fputs (string, f_out); - fputc ('\n', f_out); -} - -void -gtk_item_factory_dump_rc (const gchar *file_name, - GPatternSpec *path_pspec, - gboolean modified_only) -{ - FILE *f_out; - - g_return_if_fail (file_name != NULL); - - f_out = fopen (file_name, "w"); - if (!f_out) - return; - - fputs ("; ", f_out); - if (g_get_prgname ()) - fputs (g_get_prgname (), f_out); - fputs (" GtkItemFactory rc-file -*- scheme -*-\n", f_out); - fputs ("; this file is an automated menu-path dump\n", f_out); - fputs (";\n", f_out); - - gtk_item_factory_dump_items (path_pspec, - modified_only, - gtk_item_factory_print_func, - f_out); - - fclose (f_out); -} - void gtk_item_factory_create_items (GtkItemFactory *ifactory, guint n_entries, @@ -1193,25 +869,32 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, parent = gtk_item_factory_get_widget (ifactory, parent_path); g_return_if_fail (parent != NULL); } - g_free (parent_path); if (GTK_IS_OPTION_MENU (parent)) { option_menu = GTK_OPTION_MENU (parent); if (!option_menu->menu) - gtk_option_menu_set_menu (option_menu, gtk_widget_new (GTK_TYPE_MENU, NULL)); + { + GtkWidget *menu = g_object_new (GTK_TYPE_MENU, NULL); + gchar *p = g_strconcat (ifactory->path, parent_path, NULL); + + gtk_menu_set_accel_path (GTK_MENU (menu), p); + g_free (p); + gtk_option_menu_set_menu (option_menu, menu); + } parent = option_menu->menu; } + g_free (parent_path); g_return_if_fail (GTK_IS_CONTAINER (parent)); accelerator = entry->accelerator; widget = gtk_widget_new (type, - "GtkWidget::visible", TRUE, - "GtkWidget::sensitive", (type_id != quark_type_separator_item && - type_id != quark_type_title), - "GtkWidget::parent", parent, + "visible", TRUE, + "sensitive", (type_id != quark_type_separator_item && + type_id != quark_type_title), + "parent", parent, NULL); if (option_menu && !option_menu->menu_item) gtk_option_menu_set_history (option_menu, 0); @@ -1223,32 +906,26 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, if (type_id == quark_type_image_item) { GdkPixbuf *pixbuf = NULL; - image = NULL; + image = NULL; pixbuf = gdk_pixbuf_new_from_inline (-1, entry->extra_data, FALSE, NULL); - if (pixbuf) image = gtk_image_new_from_pixbuf (pixbuf); - if (image) { gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image); - gtk_widget_show (image); } - if (pixbuf) g_object_unref (G_OBJECT (pixbuf)); } if (type_id == quark_type_stock_item) { image = gtk_image_new_from_stock (entry->extra_data, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image); - gtk_widget_show (image); if (gtk_stock_lookup (entry->extra_data, &stock_item)) @@ -1257,8 +934,6 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, accelerator = gtk_accelerator_name (stock_item.keyval, stock_item.modifier); } } - - /* install underline accelerators for this item */ @@ -1269,12 +944,11 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, GtkWidget *label; label = gtk_widget_new (GTK_TYPE_ACCEL_LABEL, - "GtkWidget::visible", TRUE, - "GtkWidget::parent", widget, - "GtkAccelLabel::accel_object", widget, - "GtkMisc::xalign", 0.0, + "visible", TRUE, + "parent", widget, + "accel_widget", widget, + "xalign", 0.0, NULL); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), name); } @@ -1283,16 +957,19 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, if (type_id == quark_type_branch || type_id == quark_type_last_branch) { + gchar *p; + if (entry->callback) g_warning ("gtk_item_factory_create_item(): Can't specify a callback on a branch: \"%s\"", entry->path); - if (type_id == quark_type_last_branch) gtk_menu_item_set_right_justified (GTK_MENU_ITEM (widget), TRUE); parent = widget; - widget = gtk_widget_new (GTK_TYPE_MENU, - NULL); + widget = gtk_widget_new (GTK_TYPE_MENU, NULL); + p = g_strconcat (ifactory->path, path, NULL); + gtk_menu_set_accel_path (GTK_MENU (widget), p); + g_free (p); gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent), widget); } @@ -1306,10 +983,8 @@ gtk_item_factory_create_item (GtkItemFactory *ifactory, callback_type, item_type_path, widget); - if (accelerator != entry->accelerator) g_free (accelerator); - g_free (path); } @@ -1595,192 +1270,6 @@ gtk_item_factory_popup_with_data (GtkItemFactory *ifactory, mouse_button, time); } -static guint -gtk_item_factory_parse_menu_path (GScanner *scanner, - GtkItemFactoryClass *class) -{ - GtkItemFactoryItem *item; - - g_scanner_get_next_token (scanner); - if (scanner->token != G_TOKEN_STRING) - return G_TOKEN_STRING; - - g_scanner_peek_next_token (scanner); - if (scanner->next_token != G_TOKEN_STRING) - { - g_scanner_get_next_token (scanner); - return G_TOKEN_STRING; - } - - item = g_hash_table_lookup (class->item_ht, scanner->value.v_string); - if (!item) - { - item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); - - item->path = g_strdup (scanner->value.v_string); - item->accelerator_key = 0; - item->accelerator_mods = 0; - item->modified = TRUE; - item->in_propagation = FALSE; - item->dummy = NULL; - item->widgets = NULL; - - g_hash_table_insert (class->item_ht, item->path, item); - } - g_scanner_get_next_token (scanner); - - if (!item->in_propagation) - { - guint old_keyval; - guint old_mods; - - old_keyval = item->accelerator_key; - old_mods = item->accelerator_mods; - gtk_accelerator_parse (scanner->value.v_string, - &item->accelerator_key, - &item->accelerator_mods); - if (old_keyval != item->accelerator_key || - old_mods != item->accelerator_mods) - { - item->modified = TRUE; - gtk_item_factory_propagate_accelerator (item, NULL); - } - } - - g_scanner_get_next_token (scanner); - if (scanner->token != ')') - return ')'; - else - return G_TOKEN_NONE; -} - -static void -gtk_item_factory_parse_statement (GScanner *scanner, - GtkItemFactoryClass *class) -{ - guint expected_token; - - g_scanner_get_next_token (scanner); - - if (scanner->token == G_TOKEN_SYMBOL) - { - guint (*parser_func) (GScanner*, GtkItemFactoryClass*); - - parser_func = scanner->value.v_symbol; - - /* check whether this is a GtkItemFactory symbol. - */ - if (parser_func == gtk_item_factory_parse_menu_path) - expected_token = parser_func (scanner, class); - else - expected_token = G_TOKEN_SYMBOL; - } - else - expected_token = G_TOKEN_SYMBOL; - - /* skip rest of statement on errrors - */ - if (expected_token != G_TOKEN_NONE) - { - register guint level; - - level = 1; - if (scanner->token == ')') - level--; - if (scanner->token == '(') - level++; - - while (!g_scanner_eof (scanner) && level > 0) - { - g_scanner_get_next_token (scanner); - - if (scanner->token == '(') - level++; - else if (scanner->token == ')') - level--; - } - } -} - -void -gtk_item_factory_parse_rc_string (const gchar *rc_string) -{ - GScanner *scanner; - - g_return_if_fail (rc_string != NULL); - - if (!gtk_item_factory_class) - gtk_type_class (GTK_TYPE_ITEM_FACTORY); - - ifactory_scanner_config.cpair_comment_single = gtk_item_factory_class->cpair_comment_single; - scanner = g_scanner_new (&ifactory_scanner_config); - - g_scanner_input_text (scanner, rc_string, strlen (rc_string)); - - gtk_item_factory_parse_rc_scanner (scanner); - - g_scanner_destroy (scanner); -} - -void -gtk_item_factory_parse_rc_scanner (GScanner *scanner) -{ - gpointer saved_symbol; - - g_return_if_fail (scanner != NULL); - - if (!gtk_item_factory_class) - gtk_type_class (GTK_TYPE_ITEM_FACTORY); - - saved_symbol = g_scanner_lookup_symbol (scanner, "menu-path"); - g_scanner_scope_remove_symbol (scanner, 0, "menu-path"); - g_scanner_scope_add_symbol (scanner, 0, "menu-path", gtk_item_factory_parse_menu_path); - - g_scanner_peek_next_token (scanner); - - while (scanner->next_token == '(') - { - g_scanner_get_next_token (scanner); - - gtk_item_factory_parse_statement (scanner, gtk_item_factory_class); - - g_scanner_peek_next_token (scanner); - } - - g_scanner_scope_remove_symbol (scanner, 0, "menu-path"); - g_scanner_scope_add_symbol (scanner, 0, "menu-path", saved_symbol); -} - -void -gtk_item_factory_parse_rc (const gchar *file_name) -{ - gint fd; - GScanner *scanner; - - g_return_if_fail (file_name != NULL); - - if (!g_file_test (file_name, G_FILE_TEST_IS_REGULAR)) - return; - - fd = open (file_name, O_RDONLY); - if (fd < 0) - return; - - if (!gtk_item_factory_class) - gtk_type_class (GTK_TYPE_ITEM_FACTORY); - - ifactory_scanner_config.cpair_comment_single = gtk_item_factory_class->cpair_comment_single; - scanner = g_scanner_new (&ifactory_scanner_config); - - g_scanner_input_file (scanner, fd); - - gtk_item_factory_parse_rc_scanner (scanner); - - g_scanner_destroy (scanner); - - close (fd); -} - void gtk_item_factory_set_translate_func (GtkItemFactory *ifactory, GtkTranslateFunc func, |