📄 gtkitemfactory.c
字号:
guint len; g_return_if_fail (ifactory != NULL); g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); g_return_if_fail (ifactory->accel_group == NULL); g_return_if_fail (path != NULL); if (!gtk_type_is_a (container_type, GTK_TYPE_OPTION_MENU)) g_return_if_fail (gtk_type_is_a (container_type, GTK_TYPE_MENU_SHELL)); len = strlen (path); if (path[0] != '<' && path[len - 1] != '>') { g_warning ("GtkItemFactory: invalid factory path `%s'", path); return; } if (accel_group) { ifactory->accel_group = accel_group; gtk_accel_group_ref (ifactory->accel_group); } else ifactory->accel_group = gtk_accel_group_new (); ifactory->path = g_strdup (path); ifactory->widget = gtk_widget_new (container_type, "GtkObject::signal::destroy", gtk_widget_destroyed, &ifactory->widget, NULL); gtk_object_ref (GTK_OBJECT (ifactory)); gtk_object_sink (GTK_OBJECT (ifactory)); gtk_item_factory_add_item (ifactory, "", NULL, NULL, 0, NULL, 0, ITEM_FACTORY_STRING, ifactory->widget);}GtkItemFactory*gtk_item_factory_from_path (const gchar *path){ GtkItemFactoryClass *class; GtkItemFactoryItem *item; gchar *fname; guint i; g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (path[0] == '<', NULL); class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); i = 0; while (path[i] && path[i] != '>') i++; if (path[i] != '>') { g_warning ("gtk_item_factory_from_path(): invalid factory path \"%s\"", path); return NULL; } fname = g_new (gchar, i + 2); g_memmove (fname, path, i + 1); fname[i + 1] = 0; item = g_hash_table_lookup (class->item_ht, fname); g_free (fname); if (item && item->widgets) return gtk_item_factory_from_widget (item->widgets->data); return NULL;}static voidgtk_item_factory_destroy (GtkObject *object){ GtkItemFactory *ifactory; GSList *slist; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); ifactory = (GtkItemFactory*) object; if (ifactory->widget) { GtkObject *dobj; dobj = GTK_OBJECT (ifactory->widget); gtk_object_ref (dobj); gtk_object_sink (dobj); gtk_object_destroy (dobj); gtk_object_unref (dobj); ifactory->widget = NULL; } for (slist = ifactory->items; slist; slist = slist->next) { GtkItemFactoryItem *item = slist->data; GSList *link; for (link = item->widgets; link; link = link->next) if (gtk_object_get_data_by_id (link->data, quark_item_factory) == ifactory) gtk_object_remove_data_by_id (link->data, quark_item_factory); } g_slist_free (ifactory->items); ifactory->items = NULL; parent_class->destroy (object);}static voidgtk_item_factory_finalize (GtkObject *object){ GtkItemFactory *ifactory; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); ifactory = GTK_ITEM_FACTORY (object); gtk_accel_group_unref (ifactory->accel_group); g_free (ifactory->path); g_assert (ifactory->widget == NULL); if (ifactory->translate_notify) ifactory->translate_notify (ifactory->translate_data); parent_class->finalize (object);}GtkItemFactory*gtk_item_factory_from_widget (GtkWidget *widget){ g_return_val_if_fail (widget != NULL, NULL); g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_factory);}gchar*gtk_item_factory_path_from_widget (GtkWidget *widget){ g_return_val_if_fail (widget != NULL, NULL); g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_path);}static voidgtk_item_factory_foreach (gpointer hash_key, gpointer value, gpointer user_data){ GtkItemFactoryItem *item; GtkIFDumpData *data; gchar *string; gchar *name; gchar comment_prefix[2] = "\000\000"; item = value; data = user_data; if (data->pspec && !gtk_pattern_match_string (data->pspec, item->path)) return; comment_prefix[0] = gtk_item_factory_class->cpair_comment_single[0]; name = gtk_accelerator_name (item->accelerator_key, item->accelerator_mods); string = g_strconcat (item->modified ? "" : comment_prefix, "(menu-path \"", hash_key, "\" \"", name, "\")", NULL); g_free (name); data->print_func (data->func_data, string); g_free (string);}voidgtk_item_factory_dump_items (GtkPatternSpec *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);}voidgtk_item_factory_print_func (gpointer FILE_pointer, 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);}voidgtk_item_factory_dump_rc (const gchar *file_name, GtkPatternSpec *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);}voidgtk_item_factory_create_items (GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data){ gtk_item_factory_create_items_ac (ifactory, n_entries, entries, callback_data, 1);}voidgtk_item_factory_create_items_ac (GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data, guint callback_type){ guint i; g_return_if_fail (ifactory != NULL); g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); g_return_if_fail (callback_type >= 1 && callback_type <= 2); if (n_entries == 0) return; g_return_if_fail (entries != NULL); for (i = 0; i < n_entries; i++) gtk_item_factory_create_item (ifactory, entries + i, callback_data, callback_type);}GtkWidget*gtk_item_factory_get_widget (GtkItemFactory *ifactory, const gchar *path){ GtkItemFactoryClass *class; GtkItemFactoryItem *item; g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); g_return_val_if_fail (path != NULL, NULL); class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); if (path[0] == '<') item = g_hash_table_lookup (class->item_ht, (gpointer) path); else { gchar *fpath; fpath = g_strconcat (ifactory->path, path, NULL); item = g_hash_table_lookup (class->item_ht, fpath); g_free (fpath); } if (item) { GSList *slist; for (slist = item->widgets; slist; slist = slist->next) { if (gtk_item_factory_from_widget (slist->data) == ifactory) return slist->data; } } return NULL;}GtkWidget*gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory, guint action){ GSList *slist; g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); for (slist = ifactory->items; slist; slist = slist->next) { GtkItemFactoryItem *item = slist->data; GSList *link; for (link = item->widgets; link; link = link->next) if (gtk_object_get_data_by_id (link->data, quark_item_factory) == ifactory && gtk_object_get_data_by_id (link->data, quark_action) == GUINT_TO_POINTER (action)) return link->data; } return NULL;}GtkWidget*gtk_item_factory_get_item (GtkItemFactory *ifactory, const gchar *path){ GtkWidget *widget; g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); g_return_val_if_fail (path != NULL, NULL); widget = gtk_item_factory_get_widget (ifactory, path); if (GTK_IS_MENU (widget)) widget = gtk_menu_get_attach_widget (GTK_MENU (widget)); return GTK_IS_ITEM (widget) ? widget : NULL;}GtkWidget*gtk_item_factory_get_item_by_action (GtkItemFactory *ifactory, guint action){ GtkWidget *widget; g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); widget = gtk_item_factory_get_widget_by_action (ifactory, action); if (GTK_IS_MENU (widget)) widget = gtk_menu_get_attach_widget (GTK_MENU (widget)); return GTK_IS_ITEM (widget) ? widget : NULL;}static gbooleangtk_item_factory_parse_path (GtkItemFactory *ifactory, gchar *str, gchar **path, gchar **parent_path, gchar **item){ gchar *translation; gchar *p, *q; *path = g_strdup (str); p = q = *path; while (*p) { if (*p != '_') { *q++ = *p; } p++; } *q = 0; *parent_path = g_strdup (*path); p = strrchr (*parent_path, '/'); if (!p) { g_warning ("GtkItemFactory: invalid entry path `%s'", str); return FALSE; } *p = 0; if (ifactory->translate_func) translation = ifactory->translate_func (str, ifactory->translate_data); else translation = str; p = strrchr (translation, '/'); p++; *item = g_strdup (p); return TRUE;}voidgtk_item_factory_create_item (GtkItemFactory *ifactory, GtkItemFactoryEntry *entry, gpointer callback_data, guint callback_type){ GtkOptionMenu *option_menu = NULL; GtkWidget *parent; GtkWidget *widget; GSList *radio_group; gchar *name; gchar *parent_path; gchar *path; guint accel_key; guint type_id; GtkType type; gchar *item_type_path; g_return_if_fail (ifactory != NULL); g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); g_return_if_fail (entry != NULL); g_return_if_fail (entry->path != NULL); g_return_if_fail (entry->path[0] == '/'); g_return_if_fail (callback_type >= 1 && callback_type <= 2); if (!entry->item_type || entry->item_type[0] == 0) { item_type_path = "<Item>"; type_id = quark_type_item; } else { item_type_path = entry->item_type; type_id = gtk_object_data_try_key (item_type_path); } radio_group = NULL; if (type_id == quark_type_item) type = GTK_TYPE_MENU_ITEM; else if (type_id == quark_type_title) type = GTK_TYPE_MENU_ITEM; else if (type_id == quark_type_radio_item) type = GTK_TYPE_RADIO_MENU_ITEM; else if (type_id == quark_type_check_item) type = GTK_TYPE_CHECK_MENU_ITEM; else if (type_id == quark_type_tearoff_item) type = GTK_TYPE_TEAROFF_MENU_ITEM; else if (type_id == quark_type_toggle_item) type = GTK_TYPE_CHECK_MENU_ITEM; else if (type_id == quark_type_separator_item) type = GTK_TYPE_MENU_ITEM; else if (type_id == quark_type_branch) type = GTK_TYPE_MENU_ITEM; else if (type_id == quark_type_last_branch) type = GTK_TYPE_MENU_ITEM; else { GtkWidget *radio_link; radio_link = gtk_item_factory_get_widget (ifactory, item_type_path); if (radio_link && GTK_IS_RADIO_MENU_ITEM (radio_link)) { type = GTK_TYPE_RADIO_MENU_ITEM; radio_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (radio_link)); } else { g_warning ("GtkItemFactory: entry path `%s' has invalid type `%s'", entry->path, item_type_path); return; } } if (!gtk_item_factory_parse_path (ifactory, entry->path, &path, &parent_path, &name)) return; parent = gtk_item_factory_get_widget (ifactory, parent_path); if (!parent) { GtkItemFactoryEntry pentry; gchar *ppath, *p; ppath = g_strdup (entry->path); p = strrchr (ppath, '/'); g_return_if_fail (p != NULL); *p = 0; pentry.path = ppath; pentry.accelerator = NULL; pentry.callback = NULL; pentry.callback_action = 0; pentry.item_type = "<Branch>"; gtk_item_factory_create_item (ifactory, &pentry, NULL, 1); g_free (ppath); 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)); parent = option_menu->menu; } g_return_if_fail (GTK_IS_CONTAINER (parent)); widget = gtk_widget_new (type, "GtkWidget::visible", TRUE, "GtkWidget::sensitive", (type_id != quark_type_separator_item && type_id != quark_type_title), "GtkWidget::parent", parent, NULL); if (option_menu && !option_menu->menu_item) gtk_option_menu_set_history (option_menu, 0); if (type == GTK_TYPE_RADIO_MENU_ITEM) gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget), radio_group); if (GTK_IS_CHECK_MENU_ITEM (widget)) gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (widget), TRUE); /* install underline accelerators for this item */ if (type_id != quark_type_separator_item && type_id != quark_type_tearoff_item && *name) { GtkWidget *label; label = gtk_widget_new (GTK_TYPE_ACCEL_LABEL, "GtkWidget::visible", TRUE, "GtkWidget::parent", widget, "GtkAccelLabel::accel_widget", widget, "GtkMisc::xalign", 0.0, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -