]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkitemfactory.c
Practically everything changed.
[~andy/gtk] / gtk / gtkitemfactory.c
index 0a624f060562588bff1aa4c804e1da9b154ef19c..428784cdb6d6884153c753e262753d6ac3343ea9 100644 (file)
@@ -1,41 +1,59 @@
-/* GTK - The GIMP Toolkit
+/* GTK - The GTK+ Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * GtkItemFactory: Flexible item factory with automatic rc handling
  * Copyright (C) 1998 Tim Janik
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
+ * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include       <config.h>
+
+#undef GTK_DISABLE_DEPRECATED
 #include       "gtkitemfactory.h"
-#include       "gtk/gtksignal.h"
-#include       "gtk/gtkoptionmenu.h"
-#include       "gtk/gtkmenubar.h"
-#include       "gtk/gtkmenu.h"
-#include       "gtk/gtkmenuitem.h"
-#include       "gtk/gtkradiomenuitem.h"
-#include       "gtk/gtkcheckmenuitem.h"
-#include       "gtk/gtkaccellabel.h"
-#include       "gdk/gdkprivate.h" /* for gdk_progname */
+#include       "gtkoptionmenu.h"
+#include       "gtkmenubar.h"
+#include       "gtkmenu.h"
+#include       "gtkmenuitem.h"
+#include       "gtkradiomenuitem.h"
+#include       "gtkcheckmenuitem.h"
+#include       "gtkimagemenuitem.h"
+#include       "gtktearoffmenuitem.h"
+#include       "gtkaccelmap.h"
+#include       "gtkaccellabel.h"
+#include        "gdk/gdkkeysyms.h"
+#include       "gtkimage.h"
+#include       "gtkstock.h"
+#include       "gtkiconfactory.h"
+#include       "gtkintl.h"
 #include       <string.h>
-#include       <sys/stat.h>
 #include       <fcntl.h>
+#ifdef HAVE_UNISTD_H
 #include       <unistd.h>
+#endif
 #include       <stdio.h>
 
-
+#include "gtkalias.h"
 
 /* --- defines --- */
 #define                ITEM_FACTORY_STRING     ((gchar*) item_factory_string)
@@ -44,7 +62,6 @@
 
 /* --- structures --- */
 typedef struct _GtkIFCBData            GtkIFCBData;
-typedef struct _GtkIFActionLink        GtkIFActionLink;
 typedef struct  _GtkIFDumpData         GtkIFDumpData;
 struct _GtkIFCBData
 {
@@ -53,183 +70,97 @@ struct _GtkIFCBData
   gpointer               func_data;
   guint                          callback_action;
 };
-struct _GtkIFActionLink
-{
-  GtkWidget *widget;
-  guint callback_action;
-};
-struct _GtkIFDumpData
-{
-  GtkPrintFunc          print_func;
-  gpointer              func_data;
-  guint                         modified_only : 1;
-  GtkPatternSpec       *pspec;
-};
 
 
 /* --- prototypes --- */
-static void    gtk_item_factory_class_init             (GtkItemFactoryClass  *klass);
-static void    gtk_item_factory_init                   (GtkItemFactory       *ifactory);
 static void    gtk_item_factory_destroy                (GtkObject            *object);
-static void    gtk_item_factory_finalize               (GtkObject            *object);
+static void    gtk_item_factory_finalize               (GObject              *object);
 
 
 /* --- static variables --- */
-static GtkItemFactoryClass *gtk_item_factory_class = NULL;
-static GtkObjectClass  *parent_class = NULL;
-static const gchar     *item_factory_string = "Gtk-<ItemFactory>";
-static GMemChunk       *ifactory_item_chunks = NULL;
-static GMemChunk       *ifactory_cb_data_chunks = NULL;
-static const gchar     *key_popup_data = "GtkItemFactory-popup-data";
+static const gchar      item_factory_string[] = "Gtk-<ItemFactory>";
 static GQuark           quark_popup_data = 0;
-static const gchar     *key_if_menu_pos = "GtkItemFactory-menu-position";
 static GQuark           quark_if_menu_pos = 0;
-static const gchar     *key_item_factory = "GtkItemFactory";
 static GQuark           quark_item_factory = 0;
-static const gchar     *key_item_factory_path = "GtkItemFactory-path";
-static GQuark           quark_item_factory_path = 0;
-static const gchar     *key_type_item = "<Item>";
+static GQuark           quark_item_path = 0;
+static GQuark           quark_action = 0;
+static GQuark           quark_accel_group = 0;
 static GQuark           quark_type_item = 0;
-static const gchar     *key_type_title = "<Title>";
 static GQuark           quark_type_title = 0;
-static const gchar     *key_type_radio_item = "<RadioItem>";
 static GQuark           quark_type_radio_item = 0;
-static const gchar     *key_type_check_item = "<CheckItem>";
 static GQuark           quark_type_check_item = 0;
-static const gchar     *key_type_toggle_item = "<ToggleItem>";
 static GQuark           quark_type_toggle_item = 0;
-static const gchar     *key_type_separator_item = "<Separator>";
+static GQuark           quark_type_image_item = 0;
+static GQuark           quark_type_stock_item = 0;
+static GQuark           quark_type_tearoff_item = 0;
 static GQuark           quark_type_separator_item = 0;
-static const gchar     *key_type_branch = "<Branch>";
 static GQuark           quark_type_branch = 0;
-static const gchar     *key_type_last_branch = "<LastBranch>";
 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 */,
-};
 
+G_DEFINE_TYPE (GtkItemFactory, gtk_item_factory, GTK_TYPE_OBJECT)
 
 /* --- functions --- */
-GtkType
-gtk_item_factory_get_type (void)
-{
-  static GtkType item_factory_type = 0;
-  
-  if (!item_factory_type)
-    {
-      GtkTypeInfo item_factory_info =
-      {
-       "GtkItemFactory",
-       sizeof (GtkItemFactory),
-       sizeof (GtkItemFactoryClass),
-       (GtkClassInitFunc) gtk_item_factory_class_init,
-       (GtkObjectInitFunc) gtk_item_factory_init,
-       /* reserved_1 */ NULL,
-       /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
-      };
-      
-      item_factory_type = gtk_type_unique (GTK_TYPE_OBJECT, &item_factory_info);
-    }
-  
-  return item_factory_type;
-}
-
 static void
 gtk_item_factory_class_init (GtkItemFactoryClass  *class)
 {
-  GtkObjectClass *object_class;
-
-  gtk_item_factory_class = class;
-
-  parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
 
-  object_class = (GtkObjectClass*) class;
+  gobject_class->finalize = gtk_item_factory_finalize;
 
   object_class->destroy = gtk_item_factory_destroy;
-  object_class->finalize = gtk_item_factory_finalize;
-
-  class->cpair_comment_single = g_strdup (";\n");
 
   class->item_ht = g_hash_table_new (g_str_hash, g_str_equal);
-  ifactory_item_chunks =
-    g_mem_chunk_new ("GtkItemFactoryItem",
-                    sizeof (GtkItemFactoryItem),
-                    sizeof (GtkItemFactoryItem) * ITEM_BLOCK_SIZE,
-                    G_ALLOC_ONLY);
-  ifactory_cb_data_chunks =
-    g_mem_chunk_new ("GtkIFCBData",
-                    sizeof (GtkIFCBData),
-                    sizeof (GtkIFCBData) * ITEM_BLOCK_SIZE,
-                    G_ALLOC_AND_FREE);
-
-  quark_popup_data = g_quark_from_static_string (key_popup_data);
-  quark_if_menu_pos = g_quark_from_static_string (key_if_menu_pos);
-  quark_item_factory = g_quark_from_static_string (key_item_factory);
-  quark_item_factory_path = g_quark_from_static_string (key_item_factory_path);
-  quark_type_item = g_quark_from_static_string (key_type_item);
-  quark_type_title = g_quark_from_static_string (key_type_title);
-  quark_type_radio_item = g_quark_from_static_string (key_type_radio_item);
-  quark_type_check_item = g_quark_from_static_string (key_type_check_item);
-  quark_type_toggle_item = g_quark_from_static_string (key_type_toggle_item);
-  quark_type_separator_item = g_quark_from_static_string (key_type_separator_item);
-  quark_type_branch = g_quark_from_static_string (key_type_branch);
-  quark_type_last_branch = g_quark_from_static_string (key_type_last_branch);
+
+  quark_popup_data             = g_quark_from_static_string ("GtkItemFactory-popup-data");
+  quark_if_menu_pos            = g_quark_from_static_string ("GtkItemFactory-menu-position");
+  quark_item_factory           = g_quark_from_static_string ("GtkItemFactory");
+  quark_item_path              = g_quark_from_static_string ("GtkItemFactory-path");
+  quark_action                 = g_quark_from_static_string ("GtkItemFactory-action");
+  quark_accel_group            = g_quark_from_static_string ("GtkAccelGroup");
+  quark_type_item              = g_quark_from_static_string ("<Item>");
+  quark_type_title             = g_quark_from_static_string ("<Title>");
+  quark_type_radio_item                = g_quark_from_static_string ("<RadioItem>");
+  quark_type_check_item                = g_quark_from_static_string ("<CheckItem>");
+  quark_type_toggle_item       = g_quark_from_static_string ("<ToggleItem>");
+  quark_type_image_item         = g_quark_from_static_string ("<ImageItem>");
+  quark_type_stock_item         = g_quark_from_static_string ("<StockItem>");
+  quark_type_separator_item    = g_quark_from_static_string ("<Separator>");
+  quark_type_tearoff_item      = g_quark_from_static_string ("<Tearoff>");
+  quark_type_branch            = g_quark_from_static_string ("<Branch>");
+  quark_type_last_branch       = g_quark_from_static_string ("<LastBranch>");
 }
 
 static void
 gtk_item_factory_init (GtkItemFactory      *ifactory)
 {
-  GtkObject *object;
-
-  object = GTK_OBJECT (ifactory);
-
   ifactory->path = NULL;
   ifactory->accel_group = NULL;
   ifactory->widget = NULL;
-  ifactory->widgets_by_action = NULL;
+  ifactory->items = NULL;
+  ifactory->translate_func = NULL;
+  ifactory->translate_data = NULL;
+  ifactory->translate_notify = NULL;
 }
 
+/**
+ * gtk_item_factory_new:
+ * @container_type: the kind of menu to create; can be
+ *    #GTK_TYPE_MENU_BAR, #GTK_TYPE_MENU or #GTK_TYPE_OPTION_MENU
+ * @path: the factory path of the new item factory, a string of the form 
+ *    <literal>"&lt;name&gt;"</literal>
+ * @accel_group: a #GtkAccelGroup to which the accelerators for the
+ *    menu items will be added, or %NULL to create a new one
+ * @returns: a new #GtkItemFactory
+ * 
+ * Creates a new #GtkItemFactory.
+ *
+ * Beware that the returned object does not have a floating reference.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 GtkItemFactory*
-gtk_item_factory_new (GtkType       container_type,
+gtk_item_factory_new (GType         container_type,
                      const gchar   *path,
                      GtkAccelGroup *accel_group)
 {
@@ -237,7 +168,7 @@ gtk_item_factory_new (GtkType            container_type,
 
   g_return_val_if_fail (path != NULL, NULL);
 
-  ifactory = gtk_type_new (GTK_TYPE_ITEM_FACTORY);
+  ifactory = g_object_new (GTK_TYPE_ITEM_FACTORY, NULL);
   gtk_item_factory_construct (ifactory, container_type, path, accel_group);
 
   return ifactory;
@@ -253,150 +184,111 @@ gtk_item_factory_callback_marshal (GtkWidget *widget,
 
   if (data->callback_type == 1)
     {
-      GtkItemFactoryCallback1 func1 = data->func;
+      GtkItemFactoryCallback1 func1 = (GtkItemFactoryCallback1) data->func;
       func1 (data->func_data, data->callback_action, widget);
     }
   else if (data->callback_type == 2)
     {
-      GtkItemFactoryCallback2 func2 = data->func;
+      GtkItemFactoryCallback2 func2 = (GtkItemFactoryCallback2) data->func;
       func2 (widget, data->func_data, data->callback_action);
     }
 }
 
 static void
-gtk_item_factory_propagate_accelerator (GtkItemFactoryItem *item,
-                                       GtkWidget          *exclude)
+gtk_item_factory_item_remove_widget (GtkWidget         *widget,
+                                    GtkItemFactoryItem *item)
 {
-  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;
-      GtkItemFactory *ifactory;
-      
-      widget = slist->data;
-      
-      ifactory = gtk_item_factory_from_widget (widget);
-      
-      if (ifactory)
-       {
-         guint signal_id;
-         
-         signal_id = gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget));
-         if (signal_id)
-           {
-             if (item->accelerator_key)
-               gtk_widget_add_accelerator (widget,
-                                           "activate",
-                                           ifactory->accel_group,
-                                           item->accelerator_key,
-                                           item->accelerator_mods,
-                                           GTK_ACCEL_VISIBLE);
-             else
-               {
-                 GSList *slist;
-                 
-                 slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget));
-                 while (slist)
-                   {
-                     GtkAccelEntry *ac_entry;
-                     
-                     ac_entry = slist->data;
-                     slist = slist->next;
-                     if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE &&
-                         ac_entry->accel_group == ifactory->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;
+  item->widgets = g_slist_remove (item->widgets, widget);
+  g_object_set_qdata (G_OBJECT (widget), quark_item_factory, NULL);
+  g_object_set_qdata (G_OBJECT (widget), quark_item_path, NULL);
 }
 
-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)
+/**
+ * gtk_item_factory_add_foreign:
+ * @accel_widget:     widget to install an accelerator on 
+ * @full_path:       the full path for the @accel_widget 
+ * @accel_group:      the accelerator group to install the accelerator in
+ * @keyval:           key value of the accelerator
+ * @modifiers:        modifier combination of the accelerator
+ *
+ * Installs an accelerator for @accel_widget in @accel_group, that causes
+ * the ::activate signal to be emitted if the accelerator is activated.
+ * 
+ * This function can be used to make widgets participate in the accel
+ * saving/restoring functionality provided by gtk_accel_map_save() and
+ * gtk_accel_map_load(), even if they haven't been created by an item
+ * factory. 
+ *
+ * Deprecated: 2.4: The recommended API for this purpose are the functions 
+ * gtk_menu_item_set_accel_path() and gtk_widget_set_accel_path(); don't 
+ * use gtk_item_factory_add_foreign() in new code, since it is likely to
+ * be removed in the future.
+ */
+void
+gtk_item_factory_add_foreign (GtkWidget      *accel_widget,
+                             const gchar    *full_path,
+                             GtkAccelGroup  *accel_group,
+                             guint           keyval,
+                             GdkModifierType modifiers)
 {
-  if (!item->in_propagation &&
-      g_slist_find (item->widgets, widget) &&
-      accel_signal_id == gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget)))
+  GtkItemFactoryClass *class;
+  GtkItemFactoryItem *item;
+
+  g_return_if_fail (GTK_IS_WIDGET (accel_widget));
+  g_return_if_fail (full_path != NULL);
+
+  class = gtk_type_class (GTK_TYPE_ITEM_FACTORY);
+
+  keyval = keyval != GDK_VoidSymbol ? keyval : 0;
+
+  item = g_hash_table_lookup (class->item_ht, full_path);
+  if (!item)
     {
-      item->accelerator_key = accel_key;
-      item->accelerator_mods = accel_mods;
-      item->modified = TRUE;
+      item = g_slice_new (GtkItemFactoryItem);
+
+      item->path = g_strdup (full_path);
+      item->widgets = NULL;
       
-      gtk_item_factory_propagate_accelerator (item, widget);
+      g_hash_table_insert (class->item_ht, item->path, item);
     }
 
-  return TRUE;
-}
+  item->widgets = g_slist_prepend (item->widgets, accel_widget);
+  g_signal_connect (accel_widget,
+                   "destroy",
+                   G_CALLBACK (gtk_item_factory_item_remove_widget),
+                   item);
 
-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)
+  /* set the item path for the widget
+   */
+  g_object_set_qdata (G_OBJECT (accel_widget), quark_item_path, item->path);
+  gtk_widget_set_name (accel_widget, item->path);
+  if (accel_group)
     {
-      item->accelerator_key = 0;
-      item->accelerator_mods = 0;
-      item->modified = TRUE;
-      
-      gtk_item_factory_propagate_accelerator (item, widget);
+      g_object_ref (accel_group);
+      g_object_set_qdata_full (G_OBJECT (accel_widget),
+                              quark_accel_group,
+                              accel_group,
+                              g_object_unref);
     }
-}
+  else
+    g_object_set_qdata (G_OBJECT (accel_widget), quark_accel_group, NULL);
 
-static void
-gtk_item_factory_item_remove_widget (GtkWidget         *widget,
-                                    GtkItemFactoryItem *item)
-{
-  item->widgets = g_slist_remove (item->widgets, widget);
-  gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_item_factory);
-  gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_item_factory_path);
+  /* install defined accelerators
+   */
+  if (g_signal_lookup ("activate", G_TYPE_FROM_INSTANCE (accel_widget)))
+    {
+      if (accel_group)
+       {
+         gtk_accel_map_add_entry (full_path, keyval, modifiers);
+         gtk_widget_set_accel_path (accel_widget, full_path, accel_group);
+       }
+    }
 }
 
 static void
 ifactory_cb_data_free (gpointer mem)
 {
-  g_mem_chunk_free (ifactory_cb_data_chunks, mem);
+  g_slice_free (GtkIFCBData, mem);
 }
 
 static void
@@ -413,148 +305,90 @@ gtk_item_factory_add_item (GtkItemFactory                *ifactory,
   GtkItemFactoryClass *class;
   GtkItemFactoryItem *item;
   gchar *fpath;
+  guint keyval;
+  GdkModifierType mods;
   
   g_return_if_fail (widget != NULL);
   g_return_if_fail (item_type != NULL);
 
-  class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass);
-
-  fpath = g_strconcat (ifactory->path, path, NULL);
-  item = g_hash_table_lookup (class->item_ht, fpath);
-
-  /* link the widget into its item-entry
-   */
-  if (!item)
-    {
-      guint keyval;
-      guint mods;
-
-      if (accelerator)
-       gtk_accelerator_parse (accelerator, &keyval, &mods);
-      else
-       {
-         keyval = 0;
-         mods = 0;
-       }
-
-      item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks);
-
-      item->path = fpath;
-      fpath = NULL;
-      item->accelerator_key = keyval;
-      item->accelerator_mods = mods;
-      item->modified = FALSE;
-      item->in_propagation = FALSE;
-      item->item_type = NULL;
-      item->widgets = NULL;
-      
-      g_hash_table_insert (class->item_ht, item->path, item);
-    }
-  g_free (fpath);
-
-  if (item->item_type == NULL)
-    {
-      g_assert (item->widgets == NULL);
-      
-      if (item_type != ITEM_FACTORY_STRING)
-       item->item_type = g_strdup (item_type);
-      else
-       item->item_type = ITEM_FACTORY_STRING;
-    }
-
-  item->widgets = g_slist_prepend (item->widgets, widget);
-  gtk_signal_connect (GTK_OBJECT (widget),
-                     "destroy",
-                     GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_widget),
-                     item);
-
-  /* set back pointers for the widget
-   */
-  gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_item_factory, ifactory);
-  gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_item_factory_path, item->path);
-  gtk_widget_set_name (widget, item->path);
+  class = GTK_ITEM_FACTORY_GET_CLASS (ifactory);
 
   /* set accelerator group on menu widgets
    */
   if (GTK_IS_MENU (widget))
     gtk_menu_set_accel_group ((GtkMenu*) widget, ifactory->accel_group);
 
-  /* install defined accelerators
-   */
-  if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget)))
-    {
-      if (item->accelerator_key)
-       gtk_widget_add_accelerator (widget,
-                                   "activate",
-                                   ifactory->accel_group,
-                                   item->accelerator_key,
-                                   item->accelerator_mods,
-                                   GTK_ACCEL_VISIBLE);
-      else
-       gtk_widget_remove_accelerators (widget,
-                                       "activate",
-                                       TRUE);
-    }
-
-  /* keep track of accelerator changes
-   */
-  gtk_signal_connect_after (GTK_OBJECT (widget),
-                           "add-accelerator",
-                           GTK_SIGNAL_FUNC (gtk_item_factory_item_add_accelerator),
-                           item);
-  gtk_signal_connect_after (GTK_OBJECT (widget),
-                           "remove-accelerator",
-                           GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_accelerator),
-                           item);
-
-  /* keep a per-action list of the widgets on the factory
-   */
-  if (callback_action)
-    {
-      GtkIFActionLink *link;
-
-      link = g_new (GtkIFActionLink, 1);
-      link->widget = widget;
-      link->callback_action = callback_action;
-      ifactory->widgets_by_action = g_slist_prepend (ifactory->widgets_by_action, link);
-    }
-
-  /* connect callback if neccessary
+  /* connect callback if necessary
    */
   if (callback)
     {
       GtkIFCBData *data;
 
-      data = g_chunk_new (GtkIFCBData, ifactory_cb_data_chunks);
+      data = g_slice_new (GtkIFCBData);
       data->func = callback;
       data->callback_type = callback_type;
       data->func_data = callback_data;
       data->callback_action = callback_action;
 
-      gtk_object_weakref (GTK_OBJECT (widget),
-                         ifactory_cb_data_free,
-                         data);
-      gtk_signal_connect (GTK_OBJECT (widget),
-                         "activate",
-                         GTK_SIGNAL_FUNC (gtk_item_factory_callback_marshal),
-                         data);
+      g_object_weak_ref (G_OBJECT (widget),
+                        (GWeakNotify) ifactory_cb_data_free,
+                        data);
+      g_signal_connect (widget,
+                       "activate",
+                       G_CALLBACK (gtk_item_factory_callback_marshal),
+                       data);
+    }
+
+  /* link the widget into its item-entry
+   * and keep back pointer on both the item factory and the widget
+   */
+  g_object_set_qdata (G_OBJECT (widget), quark_action, GUINT_TO_POINTER (callback_action));
+  g_object_set_qdata (G_OBJECT (widget), quark_item_factory, ifactory);
+  if (accelerator)
+    gtk_accelerator_parse (accelerator, &keyval, &mods);
+  else
+    {
+      keyval = 0;
+      mods = 0;
     }
+  fpath = g_strconcat (ifactory->path, path, NULL);
+  gtk_item_factory_add_foreign (widget, fpath, ifactory->accel_group, keyval, mods);
+  item = g_hash_table_lookup (class->item_ht, fpath);
+  g_free (fpath);
+
+  g_return_if_fail (item != NULL);
+
+  if (!g_slist_find (ifactory->items, item))
+    ifactory->items = g_slist_prepend (ifactory->items, item);
 }
 
+/**
+ * gtk_item_factory_construct:
+ * @ifactory: a #GtkItemFactory
+ * @container_type: the kind of menu to create; can be
+ *    #GTK_TYPE_MENU_BAR, #GTK_TYPE_MENU or #GTK_TYPE_OPTION_MENU
+ * @path: the factory path of @ifactory, a string of the form 
+ *    <literal>"&lt;name&gt;"</literal>
+ * @accel_group: a #GtkAccelGroup to which the accelerators for the
+ *    menu items will be added, or %NULL to create a new one
+ * 
+ * Initializes an item factory.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */  
 void
 gtk_item_factory_construct (GtkItemFactory     *ifactory,
-                           GtkType              container_type,
+                           GType                container_type,
                            const gchar         *path,
                            GtkAccelGroup       *accel_group)
 {
   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));
+  if (!g_type_is_a (container_type, GTK_TYPE_OPTION_MENU))
+    g_return_if_fail (g_type_is_a (container_type, GTK_TYPE_MENU_SHELL));
 
   len = strlen (path);
 
@@ -567,24 +401,17 @@ gtk_item_factory_construct (GtkItemFactory        *ifactory,
   if (accel_group)
     {
       ifactory->accel_group = accel_group;
-      gtk_accel_group_ref (ifactory->accel_group);
+      g_object_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_signal_connect_object_while_alive (GTK_OBJECT (ifactory->widget),
-                                        "destroy",
-                                        GTK_SIGNAL_FUNC (gtk_object_destroy),
-                                        GTK_OBJECT (ifactory));
-  */
+  ifactory->widget = g_object_connect (g_object_new (container_type, NULL),
+                                      "signal::destroy", gtk_widget_destroyed, &ifactory->widget,
+                                      NULL);
+  g_object_ref_sink (ifactory);
+
   gtk_item_factory_add_item (ifactory,
                             "", NULL,
                             NULL, 0, NULL, 0,
@@ -592,6 +419,18 @@ gtk_item_factory_construct (GtkItemFactory *ifactory,
                             ifactory->widget);
 }
 
+/**
+ * gtk_item_factory_from_path:
+ * @path: a string starting with a factory path of the form 
+ *   <literal>"&lt;name&gt;"</literal>
+ * @returns: the #GtkItemFactory created for the given factory path, or %NULL 
+ *
+ * Finds an item factory which has been constructed using the 
+ * <literal>"&lt;name&gt;"</literal> prefix of @path as the @path argument 
+ * for gtk_item_factory_new().
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 GtkItemFactory*
 gtk_item_factory_from_path (const gchar      *path)
 {
@@ -619,6 +458,9 @@ gtk_item_factory_from_path (const gchar      *path)
   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);
 
@@ -626,188 +468,160 @@ gtk_item_factory_from_path (const gchar      *path)
 }
 
 static void
-gtk_item_factory_destroy (GtkObject             *object)
+gtk_item_factory_destroy (GtkObject *object)
 {
-  GtkItemFactory *ifactory;
+  GtkItemFactory *ifactory = (GtkItemFactory*) object;
   GSList *slist;
 
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_ITEM_FACTORY (object));
-
-  ifactory = (GtkItemFactory*) object;
-
   if (ifactory->widget)
     {
-      GtkObject *object;
+      GtkObject *dobj;
 
-      object = GTK_OBJECT (ifactory->widget);
+      dobj = GTK_OBJECT (ifactory->widget);
 
-      gtk_object_ref (object);
-      gtk_object_sink (object);
-      gtk_object_destroy (object);
-      gtk_object_unref (object);
+      g_object_ref_sink (dobj);
+      gtk_object_destroy (dobj);
+      g_object_unref (dobj);
 
       ifactory->widget = NULL;
     }
 
-  for (slist = ifactory->widgets_by_action; slist; slist = slist->next)
-    g_free (slist->data);
-  g_slist_free (ifactory->widgets_by_action);
-  ifactory->widgets_by_action = NULL;
+  for (slist = ifactory->items; slist; slist = slist->next)
+    {
+      GtkItemFactoryItem *item = slist->data;
+      GSList *link;
+      
+      for (link = item->widgets; link; link = link->next)
+       if (g_object_get_qdata (link->data, quark_item_factory) == ifactory)
+         g_object_set_qdata (link->data, quark_item_factory, NULL);
+    }
+  g_slist_free (ifactory->items);
+  ifactory->items = NULL;
 
-  parent_class->destroy (object);
+  GTK_OBJECT_CLASS (gtk_item_factory_parent_class)->destroy (object);
 }
 
 static void
-gtk_item_factory_finalize (GtkObject             *object)
+gtk_item_factory_finalize (GObject *object)
 {
-  GtkItemFactory *ifactory;
+  GtkItemFactory *ifactory = GTK_ITEM_FACTORY (object);
 
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_ITEM_FACTORY (object));
+  if (ifactory->accel_group)
+    g_object_unref (ifactory->accel_group);
 
-  ifactory = GTK_ITEM_FACTORY (object);
-
-  gtk_accel_group_unref (ifactory->accel_group);
   g_free (ifactory->path);
   g_assert (ifactory->widget == NULL);
 
-  parent_class->finalize (object);
+  if (ifactory->translate_notify)
+    ifactory->translate_notify (ifactory->translate_data);
+  
+  G_OBJECT_CLASS (gtk_item_factory_parent_class)->finalize (object);
 }
 
+/**
+ * gtk_item_factory_from_widget:
+ * @widget: a widget
+ * @returns: the item factory from which @widget was created, or %NULL
+ *
+ * Obtains the item factory from which a widget was created.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 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);
-}
+  GtkItemFactory *ifactory;
 
-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_factory_path);
-}
-
-static void
-gtk_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);
-}
-
-void
-gtk_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);
+  ifactory = g_object_get_qdata (G_OBJECT (widget), quark_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,
-                            gchar   *string)
-{
-  FILE *f_out = FILE_pointer;
+  if (ifactory == NULL && GTK_IS_MENU_ITEM (widget) &&
+      GTK_MENU_ITEM (widget)->submenu != NULL) 
+    {
+      GtkWidget *menu = GTK_MENU_ITEM (widget)->submenu;
+      ifactory = g_object_get_qdata (G_OBJECT (menu), quark_item_factory);
+    }
 
-  g_return_if_fail (FILE_pointer != NULL);
-  g_return_if_fail (string != NULL);
-  
-  fputs (string, f_out);
-  fputc ('\n', f_out);
+  return ifactory;
 }
 
-void
-gtk_item_factory_dump_rc (const gchar            *file_name,
-                         GtkPatternSpec         *path_pspec,
-                         gboolean                modified_only)
+/**
+ * gtk_item_factory_path_from_widget:
+ * @widget: a widget
+ * @returns: the full path to @widget if it has been created by an item
+ *   factory, %NULL otherwise. This value is owned by GTK+ and must not be
+ *   modified or freed.
+ * 
+ * If @widget has been created by an item factory, returns the full path
+ * to it. (The full path of a widget is the concatenation of the factory 
+ * path specified in gtk_item_factory_new() with the path specified in the 
+ * #GtkItemFactoryEntry from which the widget was created.)
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
+G_CONST_RETURN gchar*
+gtk_item_factory_path_from_widget (GtkWidget       *widget)
 {
-  FILE *f_out;
-
-  g_return_if_fail (file_name != NULL);
+  gchar* path;
 
-  f_out = fopen (file_name, "w");
-  if (!f_out)
-    return;
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
-  fputs ("; ", f_out);
-  if (gdk_progname)
-    fputs (gdk_progname, 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);
+  path = g_object_get_qdata (G_OBJECT (widget), quark_item_path);
 
-  gtk_item_factory_dump_items (path_pspec,
-                              modified_only,
-                              gtk_item_factory_print_func,
-                              f_out);
+  if (path == NULL && GTK_IS_MENU_ITEM (widget) &&
+      GTK_MENU_ITEM (widget)->submenu != NULL) 
+    {
+      GtkWidget *menu = GTK_MENU_ITEM (widget)->submenu;
+      path = g_object_get_qdata (G_OBJECT (menu), quark_item_path);
+    }
 
-  fclose (f_out);
+  return path;
 }
 
+/**
+ * gtk_item_factory_create_items:
+ * @ifactory: a #GtkItemFactory
+ * @n_entries: the length of @entries
+ * @entries: an array of #GtkItemFactoryEntry<!-- -->s whose @callback members
+ *    must by of type #GtkItemFactoryCallback1
+ * @callback_data: data passed to the callback functions of all entries
+ *
+ * Creates the menu items from the @entries.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
-gtk_item_factory_create_items (GtkItemFactory        *ifactory,
-                              guint                   n_entries,
-                              GtkItemFactoryEntry    *entries,
-                              gpointer                callback_data)
+gtk_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);
 }
 
+/**
+ * gtk_item_factory_create_items_ac:
+ * @ifactory: a #GtkItemFactory
+ * @n_entries: the length of @entries
+ * @entries: an array of #GtkItemFactoryEntry<!-- -->s 
+ * @callback_data: data passed to the callback functions of all entries
+ * @callback_type: 1 if the callback functions in @entries are of type
+ *    #GtkItemFactoryCallback1, 2 if they are of type #GtkItemFactoryCallback2 
+ *
+ * Creates the menu items from the @entries.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
-gtk_item_factory_create_items_ac (GtkItemFactory       *ifactory,
-                                 guint                 n_entries,
-                                 GtkItemFactoryEntry  *entries,
-                                 gpointer              callback_data,
-                                 guint                 callback_type)
+gtk_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);
 
@@ -820,18 +634,32 @@ gtk_item_factory_create_items_ac (GtkItemFactory       *ifactory,
     gtk_item_factory_create_item (ifactory, entries + i, callback_data, callback_type);
 }
 
+/**
+ * gtk_item_factory_get_widget:
+ * @ifactory: a #GtkItemFactory
+ * @path: the path to the widget
+ * @returns: the widget for the given path, or %NULL if @path doesn't lead
+ *   to a widget
+ *
+ * Obtains the widget which corresponds to @path. 
+ *
+ * If the widget corresponding to @path is a menu item which opens a 
+ * submenu, then the submenu is returned. If you are interested in the menu 
+ * item, use gtk_item_factory_get_item() instead.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 GtkWidget*
-gtk_item_factory_get_widget (GtkItemFactory   *ifactory,
-                            const gchar      *path)
+gtk_item_factory_get_widget (GtkItemFactory *ifactory,
+                            const gchar    *path)
 {
   GtkItemFactoryClass *class;
   GtkItemFactoryItem *item;
 
-  g_return_val_if_fail (ifactory != NULL, NULL);
   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);
+  class = GTK_ITEM_FACTORY_GET_CLASS (ifactory);
 
   if (path[0] == '<')
     item = g_hash_table_lookup (class->item_ht, (gpointer) path);
@@ -858,44 +686,248 @@ gtk_item_factory_get_widget (GtkItemFactory   *ifactory,
   return NULL;
 }
 
+/**
+ * gtk_item_factory_get_widget_by_action:
+ * @ifactory: a #GtkItemFactory
+ * @action: an action as specified in the @callback_action field
+ *   of #GtkItemFactoryEntry
+ * @returns: the widget which corresponds to the given action, or %NULL
+ *   if no widget was found
+ *
+ * Obtains the widget which was constructed from the #GtkItemFactoryEntry
+ * with the given @action.
+ *
+ * If there are multiple items with the same action, the result is 
+ * undefined.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 GtkWidget*
-gtk_item_factory_get_widget_by_action (GtkItemFactory   *ifactory,
-                                      guint             action)
+gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory,
+                                      guint           action)
 {
   GSList *slist;
 
-  g_return_val_if_fail (ifactory != NULL, NULL);
   g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL);
 
-  for (slist = ifactory->widgets_by_action; slist; slist = slist->next)
+  for (slist = ifactory->items; slist; slist = slist->next)
     {
-      GtkIFActionLink *link;
+      GtkItemFactoryItem *item = slist->data;
+      GSList *link;
 
-      link = slist->data;
-
-      if (link->callback_action == action)
-       return link->widget;
+      for (link = item->widgets; link; link = link->next)
+       if (g_object_get_qdata (link->data, quark_item_factory) == ifactory &&
+           g_object_get_qdata (link->data, quark_action) == GUINT_TO_POINTER (action))
+         return link->data;
     }
 
   return NULL;
 }
 
+/** 
+ * gtk_item_factory_get_item:
+ * @ifactory: a #GtkItemFactory
+ * @path: the path to the menu item
+ * @returns: the menu item for the given path, or %NULL if @path doesn't
+ *   lead to a menu item
+ *
+ * Obtains the menu item which corresponds to @path. 
+ *
+ * If the widget corresponding to @path is a menu item which opens a 
+ * submenu, then the item is returned. If you are interested in the submenu, 
+ * use gtk_item_factory_get_widget() instead.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
+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;
+}
+
+
+/**
+ * gtk_item_factory_get_item_by_action:
+ * @ifactory: a #GtkItemFactory
+ * @action: an action as specified in the @callback_action field
+ *   of #GtkItemFactoryEntry
+ * @returns: the menu item which corresponds to the given action, or %NULL
+ *   if no menu item was found
+ *
+ * Obtains the menu item which was constructed from the first 
+ * #GtkItemFactoryEntry with the given @action.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
+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 char *
+item_factory_find_separator_r (char *path)
+{
+  gchar *result = NULL;
+  gboolean escaped = FALSE;
+
+  while (*path)
+    {
+      if (escaped)
+       escaped = FALSE;
+      else
+       {
+         if (*path == '\\')
+           escaped = TRUE;
+         else if (*path == '/')
+           result = path;
+       }
+      
+      path++;
+    }
+
+  return result;
+}
+
+static char *
+item_factory_unescape_label (const char *label)
+{
+  char *new = g_malloc (strlen (label) + 1);
+  char *p = new;
+  gboolean escaped = FALSE;
+  
+  while (*label)
+    {
+      if (escaped)
+       {
+         *p++ = *label;
+         escaped = FALSE;
+       }
+      else
+       {
+         if (*label == '\\')
+           escaped = TRUE;
+         else
+           *p++ = *label;
+       }
+      
+      label++;
+    }
+
+  *p = '\0';
+
+  return new;
+}
+
+static gboolean
+gtk_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 == '_')
+       {
+         if (p[1] == '_')
+           {
+             p++;
+             *q++ = '_';
+           }
+       }
+      else
+       {
+         *q++ = *p;
+       }
+      p++;
+    }
+  *q = 0;
+
+  *parent_path = g_strdup (*path);
+  p = item_factory_find_separator_r (*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 = item_factory_find_separator_r (translation);
+  if (p)
+    p++;
+  else
+    p = translation;
+
+  *item = item_factory_unescape_label (p);
+
+  return TRUE;
+}
+
+/**
+ * gtk_item_factory_create_item:
+ * @ifactory: a #GtkItemFactory
+ * @entry: the #GtkItemFactoryEntry to create an item for
+ * @callback_data: data passed to the callback function of @entry
+ * @callback_type: 1 if the callback function of @entry is of type
+ *    #GtkItemFactoryCallback1, 2 if it is of type #GtkItemFactoryCallback2 
+ *
+ * Creates an item for @entry.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_create_item (GtkItemFactory        *ifactory,
                              GtkItemFactoryEntry    *entry,
                              gpointer                callback_data,
                              guint                   callback_type)
 {
+  GtkOptionMenu *option_menu = NULL;
   GtkWidget *parent;
   GtkWidget *widget;
+  GtkWidget *image;
   GSList *radio_group;
+  gchar *name;
   gchar *parent_path;
-  gchar *p;
+  gchar *path;
+  gchar *accelerator;
   guint type_id;
-  GtkType type;
+  GType type;
   gchar *item_type_path;
-
-  g_return_if_fail (ifactory != NULL);
+  GtkStockItem stock_item;
+      
   g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory));
   g_return_if_fail (entry != NULL);
   g_return_if_fail (entry->path != NULL);
@@ -905,13 +937,13 @@ gtk_item_factory_create_item (GtkItemFactory           *ifactory,
   if (!entry->item_type ||
       entry->item_type[0] == 0)
     {
-      item_type_path = (gpointer) key_type_item;
+      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);
+      type_id = g_quark_try_string (item_type_path);
     }
 
   radio_group = NULL;
@@ -923,6 +955,12 @@ gtk_item_factory_create_item (GtkItemFactory            *ifactory,
     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_image_item)
+    type = GTK_TYPE_IMAGE_MENU_ITEM;
+  else if (type_id == quark_type_stock_item)
+    type = GTK_TYPE_IMAGE_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)
@@ -939,7 +977,7 @@ gtk_item_factory_create_item (GtkItemFactory             *ifactory,
       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));
+         radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (radio_link));
        }
       else
        {
@@ -949,100 +987,177 @@ gtk_item_factory_create_item (GtkItemFactory         *ifactory,
          return;
        }
     }
-  
-  parent_path = g_strdup (entry->path);
-  p = strrchr (parent_path, '/');
-  if (!p)
-    {
-      g_warning ("GtkItemFactory: invalid entry path `%s'", entry->path);
-      return;
-    }
-  *p = 0;
+
+  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;
 
-      pentry.path = parent_path;
+      ppath = g_strdup (entry->path);
+      p = item_factory_find_separator_r (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);
+    }
+
+  if (GTK_IS_OPTION_MENU (parent))
+    {
+      option_menu = GTK_OPTION_MENU (parent);
+      if (!option_menu->menu)
+       {
+         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));
 
-  g_return_if_fail (parent != NULL);
-  
-  p = strrchr (entry->path, '/');
-  p++;
+  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,
+  widget = g_object_new (type,
+                          "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);
 
-  if (type == GTK_TYPE_RADIO_MENU_ITEM)
+  if (GTK_IS_RADIO_MENU_ITEM (widget))
     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);
-    
-  if (type_id != quark_type_separator_item && *p)
+  if (type_id == quark_type_image_item)
+    {
+      GdkPixbuf *pixbuf = NULL;
+      image = NULL;
+      if (entry->extra_data)
+       {
+         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 (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))
+       {
+         if (!accelerator)
+           accelerator = gtk_accelerator_name (stock_item.keyval, stock_item.modifier);
+       }
+    }
+
+  /* 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,
-                       "GtkLabel::label", p,
-                       "GtkWidget::visible", TRUE,
-                       "GtkWidget::parent", widget,
-                       "GtkAccelLabel::accel_widget", widget,
-                       "GtkMisc::xalign", 0.0,
-                       NULL);
+      label = g_object_new (GTK_TYPE_ACCEL_LABEL,
+                             "visible", TRUE,
+                             "parent", widget,
+                             "accel-widget", widget,
+                             "xalign", 0.0,
+                             NULL);
+      gtk_label_set_text_with_mnemonic (GTK_LABEL (label), name);
     }
+  
+  g_free (name);
+  
   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_right_justify (GTK_MENU_ITEM (widget));
-       
+       gtk_menu_item_set_right_justified (GTK_MENU_ITEM (widget), TRUE);
+      
       parent = widget;
-      widget =
-       gtk_widget_new (GTK_TYPE_MENU,
-                       NULL);
+      widget = g_object_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);
     }     
   
   gtk_item_factory_add_item (ifactory,
-                            entry->path, entry->accelerator,
-                            entry->callback, entry->callback_action, callback_data,
+                            path, accelerator,
+                            (type_id == quark_type_branch ||
+                             type_id == quark_type_last_branch) ?
+                             (GtkItemFactoryCallback) NULL : entry->callback,
+                            entry->callback_action, callback_data,
                             callback_type,
                             item_type_path,
                             widget);
+  if (accelerator != entry->accelerator)
+    g_free (accelerator);
+  g_free (path);
 }
 
+/**
+ * gtk_item_factory_create_menu_entries:
+ * @n_entries: the length of @entries
+ * @entries: an array of #GtkMenuEntry<!-- -->s 
+ *
+ * Creates the menu items from the @entries.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_create_menu_entries (guint              n_entries,
                                      GtkMenuEntry      *entries)
 {
-  static GtkPatternSpec pspec_separator = { 42, 0 };
-  static GtkPatternSpec pspec_check = { 42, 0 };
+  static GPatternSpec *pspec_separator = NULL;
+  static GPatternSpec *pspec_check = NULL;
   guint i;
 
   if (!n_entries)
     return;
   g_return_if_fail (entries != NULL);
 
-  if (pspec_separator.pattern_length == 0)
+  if (!pspec_separator)
     {
-      gtk_pattern_spec_init (&pspec_separator, "*<separator>*");
-      gtk_pattern_spec_init (&pspec_check, "*<check>*");
+      pspec_separator = g_pattern_spec_new ("*<separator>*");
+      pspec_check = g_pattern_spec_new ("*<check>*");
     }
 
   for (i = 0; i < n_entries; i++)
@@ -1071,9 +1186,9 @@ gtk_item_factory_create_menu_entries (guint              n_entries,
       entry.accelerator = entries[i].accelerator;
       entry.callback = entries[i].callback;
       entry.callback_action = 0;
-      if (gtk_pattern_match_string (&pspec_separator, path))
-       entry.item_type = (gpointer) key_type_separator_item;
-      else if (!gtk_pattern_match_string (&pspec_check, path))
+      if (g_pattern_match_string (pspec_separator, path))
+       entry.item_type = "<Separator>";
+      else if (!g_pattern_match_string (pspec_check, path))
        entry.item_type = NULL;
       else
        {
@@ -1093,7 +1208,7 @@ gtk_item_factory_create_menu_entries (guint              n_entries,
              path++;
            }
          *c = 0;
-         entry.item_type = (gpointer) key_type_toggle_item;
+         entry.item_type = "<ToggleItem>";
          entry.path = cpath;
        }
       
@@ -1103,6 +1218,16 @@ gtk_item_factory_create_menu_entries (guint              n_entries,
     }
 }
 
+/**
+ * gtk_item_factories_path_delete:
+ * @ifactory_path: a factory path to prepend to @path. May be %NULL if @path
+ *   starts with a factory path
+ * @path: a path 
+ * 
+ * Deletes all widgets constructed from the specified path.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factories_path_delete (const gchar *ifactory_path,
                                const gchar *path)
@@ -1139,7 +1264,7 @@ gtk_item_factories_path_delete (const gchar *ifactory_path,
 
          widget = slist->data;
          widget_list = g_slist_prepend (widget_list, widget);
-         gtk_widget_ref (widget);
+         g_object_ref (widget);
        }
 
       for (slist = widget_list; slist; slist = slist->next)
@@ -1148,59 +1273,87 @@ gtk_item_factories_path_delete (const gchar *ifactory_path,
 
          widget = slist->data;
          gtk_widget_destroy (widget);
-         gtk_widget_unref (widget);
+         g_object_unref (widget);
        }
       g_slist_free (widget_list);
     }
 }
 
+/**
+ * gtk_item_factory_delete_item:
+ * @ifactory: a #GtkItemFactory
+ * @path: a path
+ *
+ * Deletes the menu item which was created for @path by the given
+ * item factory.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_delete_item (GtkItemFactory         *ifactory,
                              const gchar            *path)
 {
-  GtkItemFactoryClass *class;
-  GtkItemFactoryItem *item;
-  gchar *fpath;
+  GtkWidget *widget;
 
-  g_return_if_fail (ifactory != NULL);
   g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory));
   g_return_if_fail (path != NULL);
 
-  class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass);
-
-  fpath = g_strconcat (ifactory->path, path, NULL);
-  item = g_hash_table_lookup (class->item_ht, fpath);
-  g_free (fpath);
+  widget = gtk_item_factory_get_widget (ifactory, path);
 
-  if (item)
+  if (widget)
     {
-      GtkWidget *widget = NULL;
-      GSList *slist;
-
-      for (slist = item->widgets; slist; slist = slist->next)
-       {
-         widget = slist->data;
-
-         if (gtk_item_factory_from_widget (widget) == ifactory)
-           break;
-       }
+      if (GTK_IS_MENU (widget))
+       widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
 
-      if (slist)
-       gtk_widget_destroy (widget);
+      gtk_widget_destroy (widget);
     }
 }
 
+/**
+ * gtk_item_factory_delete_entry:
+ * @ifactory: a #GtkItemFactory
+ * @entry: a #GtkItemFactoryEntry
+ *
+ * Deletes the menu item which was created from @entry by the given
+ * item factory.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_delete_entry (GtkItemFactory         *ifactory,
                               GtkItemFactoryEntry    *entry)
 {
-  g_return_if_fail (ifactory != NULL);
+  gchar *path;
+  gchar *parent_path;
+  gchar *name;
+
   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] == '/');
+
+  if (!gtk_item_factory_parse_path (ifactory, entry->path, 
+                                   &path, &parent_path, &name))
+    return;
+  
+  gtk_item_factory_delete_item (ifactory, path);
 
-  gtk_item_factory_delete_item (ifactory, entry->path);
+  g_free (path);
+  g_free (parent_path);
+  g_free (name);
 }
 
+/**
+ * gtk_item_factory_delete_entries:
+ * @ifactory: a #GtkItemFactory
+ * @n_entries: the length of @entries
+ * @entries: an array of #GtkItemFactoryEntry<!-- -->s 
+ *
+ * Deletes the menu items which were created from the @entries by the given
+ * item factory.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_delete_entries (GtkItemFactory         *ifactory,
                                 guint                   n_entries,
@@ -1208,13 +1361,12 @@ gtk_item_factory_delete_entries (GtkItemFactory         *ifactory,
 {
   guint i;
 
-  g_return_if_fail (ifactory != NULL);
   g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory));
   if (n_entries > 0)
     g_return_if_fail (entries != NULL);
 
   for (i = 0; i < n_entries; i++)
-    gtk_item_factory_delete_item (ifactory, (entries + i)->path);
+    gtk_item_factory_delete_entry (ifactory, entries + i);
 }
 
 typedef struct
@@ -1227,6 +1379,7 @@ static void
 gtk_item_factory_menu_pos (GtkMenu  *menu,
                           gint     *x,
                           gint     *y,
+                           gboolean *push_in,
                           gpointer  func_data)
 {
   MenuPos *mpos = func_data;
@@ -1235,40 +1388,86 @@ gtk_item_factory_menu_pos (GtkMenu  *menu,
   *y = mpos->y;
 }
 
+/**
+ * gtk_item_factory_popup_data_from_widget:
+ * @widget: a widget
+ * @returns: @popup_data associated with the item factory from
+ *   which @widget was created, or %NULL if @widget wasn't created
+ *   by an item factory
+ *
+ * Obtains the @popup_data which was passed to 
+ * gtk_item_factory_popup_with_data(). This data is available until the menu
+ * is popped down again.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 gpointer
-gtk_item_factory_popup_data_from_widget (GtkWidget     *widget)
+gtk_item_factory_popup_data_from_widget (GtkWidget *widget)
 {
   GtkItemFactory *ifactory;
   
-  g_return_val_if_fail (widget != NULL, NULL);
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
   ifactory = gtk_item_factory_from_widget (widget);
   if (ifactory)
-    return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), quark_popup_data);
+    return g_object_get_qdata (G_OBJECT (ifactory), quark_popup_data);
 
   return NULL;
 }
 
+/**
+ * gtk_item_factory_popup_data:
+ * @ifactory: a #GtkItemFactory
+ * @returns: @popup_data associated with @ifactory
+ *
+ * Obtains the @popup_data which was passed to 
+ * gtk_item_factory_popup_with_data(). This data is available until the menu
+ * is popped down again.
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 gpointer
 gtk_item_factory_popup_data (GtkItemFactory *ifactory)
 {
-  g_return_val_if_fail (ifactory != NULL, NULL);
   g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL);
 
-  return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), quark_popup_data);
+  return g_object_get_qdata (G_OBJECT (ifactory), quark_popup_data);
 }
 
 static void
 ifactory_delete_popup_data (GtkObject     *object,
                            GtkItemFactory *ifactory)
 {
-  gtk_signal_disconnect_by_func (object,
-                                GTK_SIGNAL_FUNC (ifactory_delete_popup_data),
-                                ifactory);
-  gtk_object_remove_data_by_id (GTK_OBJECT (ifactory), quark_popup_data);
+  g_signal_handlers_disconnect_by_func (object,
+                                       ifactory_delete_popup_data,
+                                       ifactory);
+  g_object_set_qdata (G_OBJECT (ifactory), quark_popup_data, NULL);
 }
 
+/**
+ * gtk_item_factory_popup:
+ * @ifactory: a #GtkItemFactory of type #GTK_TYPE_MENU (see gtk_item_factory_new())
+ * @x: the x position 
+ * @y: the y position
+ * @mouse_button: the mouse button which was pressed to initiate the popup
+ * @time_: the time at which the activation event occurred
+ *
+ * Pops up the menu constructed from the item factory at (@x, @y).
+ *
+ * The @mouse_button parameter should be the mouse button pressed to initiate
+ * the menu popup. If the menu popup was initiated by something other than
+ * a mouse button press, such as a mouse button release or a keypress,
+ * @mouse_button should be 0.
+ *
+ * The @time_ parameter should be the time stamp of the event that
+ * initiated the popup. If such an event is not available, use
+ * gtk_get_current_event_time() instead.
+ *
+ * The operation of the @mouse_button and the @time_ parameter is the same
+ * as the @button and @activation_time parameters for gtk_menu_popup().
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_popup (GtkItemFactory         *ifactory,
                        guint                    x,
@@ -1279,6 +1478,35 @@ gtk_item_factory_popup (GtkItemFactory           *ifactory,
   gtk_item_factory_popup_with_data (ifactory, NULL, NULL, x, y, mouse_button, time);
 }
 
+/**
+ * gtk_item_factory_popup_with_data:
+ * @ifactory: a #GtkItemFactory of type #GTK_TYPE_MENU (see gtk_item_factory_new())
+ * @popup_data: data available for callbacks while the menu is posted
+ * @destroy: a #GtkDestroyNotify function to be called on @popup_data when
+ *  the menu is unposted
+ * @x: the x position 
+ * @y: the y position
+ * @mouse_button: the mouse button which was pressed to initiate the popup
+ * @time_: the time at which the activation event occurred
+ *
+ * Pops up the menu constructed from the item factory at (@x, @y). Callbacks
+ * can access the @popup_data while the menu is posted via 
+ * gtk_item_factory_popup_data() and gtk_item_factory_popup_data_from_widget().
+ *
+ * The @mouse_button parameter should be the mouse button pressed to initiate
+ * the menu popup. If the menu popup was initiated by something other than
+ * a mouse button press, such as a mouse button release or a keypress,
+ * @mouse_button should be 0.
+ *
+ * The @time_ parameter should be the time stamp of the event that
+ * initiated the popup. If such an event is not available, use
+ * gtk_get_current_event_time() instead.
+ *
+ * The operation of the @mouse_button and the @time_ parameters is the same
+ * as the @button and @activation_time parameters for gtk_menu_popup().
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */
 void
 gtk_item_factory_popup_with_data (GtkItemFactory       *ifactory,
                                  gpointer               popup_data,
@@ -1288,223 +1516,71 @@ gtk_item_factory_popup_with_data (GtkItemFactory       *ifactory,
                                  guint                  mouse_button,
                                  guint32                time)
 {
-  g_return_if_fail (ifactory != NULL);
+  MenuPos *mpos;
+
   g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory));
   g_return_if_fail (GTK_IS_MENU (ifactory->widget));
-
-  if (!GTK_WIDGET_VISIBLE (ifactory->widget))
-    {
-      MenuPos *mpos;
-
-      mpos = gtk_object_get_data_by_id (GTK_OBJECT (ifactory->widget), quark_if_menu_pos);
-
-      if (!mpos)
-       {
-         mpos = g_new0 (MenuPos, 1);
-         gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory->widget),
-                                         quark_if_menu_pos,
-                                         mpos,
-                                         g_free);
-       }
-
-      mpos->x = x;
-      mpos->y = y;
-
-      if (popup_data != NULL)
-       {
-         gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory),
-                                         quark_popup_data,
-                                         popup_data,
-                                         destroy);
-         gtk_signal_connect (GTK_OBJECT (ifactory->widget),
-                             "selection-done",
-                             GTK_SIGNAL_FUNC (ifactory_delete_popup_data),
-                             ifactory);
-       }
-
-      gtk_menu_popup (GTK_MENU (ifactory->widget),
-                     NULL, NULL,
-                     gtk_item_factory_menu_pos, mpos,
-                     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->item_type = NULL;
-      item->widgets = NULL;
-
-      g_hash_table_insert (class->item_ht, item->path, item);
-    }
-  g_scanner_get_next_token (scanner);
+  mpos = g_object_get_qdata (G_OBJECT (ifactory->widget), quark_if_menu_pos);
   
-  if (!item->in_propagation)
+  if (!mpos)
     {
-      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);
-       }
+      mpos = g_new0 (MenuPos, 1);
+      g_object_set_qdata_full (G_OBJECT (ifactory->widget),
+                              quark_if_menu_pos,
+                              mpos,
+                              g_free);
     }
   
-  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);
+  mpos->x = x;
+  mpos->y = y;
   
-  if (scanner->token == G_TOKEN_SYMBOL)
+  if (popup_data != NULL)
     {
-      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;
+      g_object_set_qdata_full (G_OBJECT (ifactory),
+                              quark_popup_data,
+                              popup_data,
+                              destroy);
+      g_signal_connect (ifactory->widget,
+                       "selection-done",
+                       G_CALLBACK (ifactory_delete_popup_data),
+                       ifactory);
     }
-  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);
-
-  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);
+  
+  gtk_menu_popup (GTK_MENU (ifactory->widget),
+                 NULL, NULL,
+                 gtk_item_factory_menu_pos, mpos,
+                 mouse_button, time);
 }
 
+/**
+ * gtk_item_factory_set_translate_func:
+ * @ifactory: a #GtkItemFactory
+ * @func: the #GtkTranslateFunc function to be used to translate path elements 
+ * @data: data to pass to @func and @notify
+ * @notify: a #GtkDestroyNotify function to be called when @ifactory is 
+ *   destroyed and when the translation function is changed again
+ * 
+ * Sets a function to be used for translating the path elements before they
+ * are displayed. 
+ *
+ * Deprecated: 2.4: Use #GtkUIManager instead.
+ */ 
 void
-gtk_item_factory_parse_rc_scanner (GScanner *scanner)
+gtk_item_factory_set_translate_func (GtkItemFactory      *ifactory,
+                                    GtkTranslateFunc     func,
+                                    gpointer             data,
+                                    GtkDestroyNotify     notify)
 {
-  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_remove_symbol (scanner, "menu-path");
-  g_scanner_add_symbol (scanner, "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_remove_symbol (scanner, "menu-path");
-  g_scanner_add_symbol (scanner, "menu-path", saved_symbol);
+  g_return_if_fail (ifactory != NULL);
+  
+  if (ifactory->translate_notify)
+    ifactory->translate_notify (ifactory->translate_data);
+      
+  ifactory->translate_func = func;
+  ifactory->translate_data = data;
+  ifactory->translate_notify = notify;
 }
 
-void
-gtk_item_factory_parse_rc (const gchar   *file_name)
-{
-  gint fd;
-  GScanner *scanner;
-
-  g_return_if_fail (file_name != NULL);
-
-  if (!S_ISREG (g_scanner_stat_mode (file_name)))
-    return;
-
-  fd = open (file_name, O_RDONLY);
-  if (fd < 0)
-    return;
-
-  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);
-}
+#define __GTK_ITEM_FACTORY_C__
+#include "gtkaliasdef.c"