summaryrefslogtreecommitdiff
path: root/gtk/gtkmenuitem.c
diff options
context:
space:
mode:
authorTim Janik <timj@gtk.org>2001-11-13 00:53:47 +0000
committerTim Janik <timj@src.gnome.org>2001-11-13 00:53:47 +0000
commitd07573c090f8ca8c3fdb8f4d3f63b32be96ea7d6 (patch)
treeea660dfa3bec08f14714db1b2e9699bf5f126394 /gtk/gtkmenuitem.c
parentaebe24f2bba1a41b23ab62b7adfc867e28adb3fc (diff)
downloadgtk+-d07573c090f8ca8c3fdb8f4d3f63b32be96ea7d6.tar.gz
added gtkaccelmap.sgml. other updates.
Mon Nov 12 23:06:38 2001 Tim Janik <timj@gtk.org> * added gtkaccelmap.sgml. other updates. Mon Nov 12 23:08:37 2001 Tim Janik <timj@gtk.org> * gtk/maketypes.awk: fix type utils generation on unix. * gtk/gtkaccelmap.[hc]: new files, implementing a global accelerator registry. * gtk/gtkaccelgroup.[hc]: major API/implementation revamp: removed GTK_ACCEL_SIGNAL_VISIBLE, gtk_accel_group_get_default, gtk_accel_group_get_entry, gtk_accel_group_(un)lock_entry, gtk_accel_group_add/remove, gtk_accel_group_handle_add/remove, gtk_accel_group_create_add/remove, gtk_accel_group_entries_from_object. introduced ::accel_changed signal for change notification, and gtk_accel_group_connect/disconnect to connect closures to accel groups. made gtk_accel_group_attach/detach and gtk_accel_group_activate private functions. deprecated gtk_accel_group_ref/unref. * gtk/gtkaccellabel.[hc]: changes to make accellabels pay attention to accel group changed notification and basically operate on closures. removed gtk_accel_label_get_accel_object and gtk_accel_label_set_accel_object. introduced gtk_accel_label_set_accel_closure, and for convenience, gtk_accel_label_set_accel_widget. * gtk/gtkitemfactory.[hc]: removed accelerator propagation code which mostly moved into gtkaccelmap.[hc]. removed gtk_item_factory_parse_rc*, gtk_item_factory_dump_* and gtk_item_factory_print_func. * gtk/gtkmain.c: call _gtk_accel_map_init(). * gtk/gtkmenuitem.[hc]: introduced gtk_menu_item_set_accel_path(), that associates an accelerator path with menu items, through which persistent accelerator settings on menu items are enabled. * gtk/gtkmenu.[hc]: added gtk_menu_set_accel_path() so accelerator paths of menu item can be default constructed to allow installation of accelerators on menu items that don't come with an accelerator binding by default. * gtk/gtksettings.c: fix STRING type rc settings by special casing them appropriately in the parser. * gtk/gtksignal.[hc]: allow a class function offset of 0 for gtk_signal_newv(). * gtk/gtkwidget.[hc]: accelerator API revamp. removed ::accelerator_add/remove signals, gtk_widget_accelerator_signal, gtk_widget_accelerators_locked, gtk_widget_remove_accelerators and gtk_widget_(un)lock_accelerators. accelerators maintained through gtk_widget_add/remove_accelerator() are not runtime changable now, the correct sequence to setup a widget for runtime changable accelerators is now: gtk_accel_map_add_entry(accel_path, key, mods); _gtk_widget_set_accel_path(widget, accel_path, accel_group); * gtk/gtkwindow.[hc]: accelerator changes, proxy and coalesce accel group changes (as well as mnemonic changes) through the new signal ::accels_changed. Sat Nov 10 12:08:56 2001 Tim Janik <timj@gtk.org> * gtk/gtksettings.c (_gtk_settings_parse_convert): properly handle GString->string conversions.
Diffstat (limited to 'gtk/gtkmenuitem.c')
-rw-r--r--gtk/gtkmenuitem.c138
1 files changed, 123 insertions, 15 deletions
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index edc7f4f3f4..e269a790f0 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -51,6 +51,7 @@ enum {
static void gtk_menu_item_class_init (GtkMenuItemClass *klass);
static void gtk_menu_item_init (GtkMenuItem *menu_item);
static void gtk_menu_item_destroy (GtkObject *object);
+static void gtk_menu_item_finalize (GObject *object);
static void gtk_menu_item_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_menu_item_size_allocate (GtkWidget *widget,
@@ -60,6 +61,7 @@ static void gtk_menu_item_paint (GtkWidget *widget,
static gint gtk_menu_item_expose (GtkWidget *widget,
GdkEventExpose *event);
+
static void gtk_real_menu_item_select (GtkItem *item);
static void gtk_real_menu_item_deselect (GtkItem *item);
static void gtk_real_menu_item_activate_item (GtkMenuItem *item);
@@ -120,18 +122,15 @@ gtk_menu_item_get_type (void)
static void
gtk_menu_item_class_init (GtkMenuItemClass *klass)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- GtkContainerClass *container_class;
- GtkItemClass *item_class;
-
- object_class = (GtkObjectClass*) klass;
- widget_class = (GtkWidgetClass*) klass;
- container_class = (GtkContainerClass*) klass;
- item_class = (GtkItemClass*) klass;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+ GtkItemClass *item_class = GTK_ITEM_CLASS (klass);
- parent_class = gtk_type_class (gtk_item_get_type ());
+ parent_class = g_type_class_peek_parent (klass);
+ gobject_class->finalize = gtk_menu_item_finalize;
object_class->destroy = gtk_menu_item_destroy;
@@ -141,7 +140,7 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
widget_class->show_all = gtk_menu_item_show_all;
widget_class->hide_all = gtk_menu_item_hide_all;
widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
-
+
container_class->forall = gtk_menu_item_forall;
item_class->select = gtk_real_menu_item_select;
@@ -194,7 +193,6 @@ static void
gtk_menu_item_init (GtkMenuItem *menu_item)
{
menu_item->submenu = NULL;
- menu_item->accelerator_signal = menu_item_signals[ACTIVATE];
menu_item->toggle_size = 0;
menu_item->accelerator_width = 0;
menu_item->show_submenu_indicator = FALSE;
@@ -269,8 +267,17 @@ gtk_menu_item_destroy (GtkObject *object)
if (menu_item->submenu)
gtk_widget_destroy (menu_item->submenu);
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static void
+gtk_menu_item_finalize (GObject *object)
+{
+ GtkMenuItem *menu_item = GTK_MENU_ITEM (object);
+
+ g_free (menu_item->accel_path);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
@@ -898,6 +905,107 @@ gtk_menu_item_hide_all (GtkWidget *widget)
}
static void
+gtk_menu_item_accel_name_foreach (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar **path_p = data;
+
+ if (!*path_p)
+ {
+ if (GTK_IS_LABEL (widget))
+ {
+ *path_p = gtk_label_get_text (GTK_LABEL (widget));
+ if (*path_p && (*path_p)[0] == 0)
+ *path_p = NULL;
+ }
+ else if (GTK_IS_CONTAINER (widget))
+ gtk_container_foreach (GTK_CONTAINER (widget),
+ gtk_menu_item_accel_name_foreach,
+ data);
+ }
+}
+
+void
+_gtk_menu_item_refresh_accel_path (GtkMenuItem *menu_item,
+ const gchar *prefix,
+ GtkAccelGroup *accel_group,
+ gboolean group_changed)
+{
+ const gchar *path;
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+
+ widget = GTK_WIDGET (menu_item);
+
+ path = _gtk_widget_get_accel_path (widget);
+ if (!path) /* no active accel_path yet */
+ {
+ path = menu_item->accel_path;
+ if (!path && prefix)
+ {
+ gchar *postfix = NULL;
+
+ /* try to construct one from label text */
+ gtk_container_foreach (GTK_CONTAINER (menu_item),
+ gtk_menu_item_accel_name_foreach,
+ &postfix);
+ menu_item->accel_path = postfix ? g_strconcat (prefix, "/", postfix, NULL) : NULL;
+ path = menu_item->accel_path;
+ }
+ if (path)
+ _gtk_widget_set_accel_path (widget, path, accel_group);
+ }
+ else if (group_changed) /* reinstall accelerators */
+ _gtk_widget_set_accel_path (widget, path, accel_group);
+}
+
+/**
+ * gtk_menu_item_set_accel_path
+ * @menu_item: a valid #GtkMenuItem
+ * @accel_path: accelerator path, corresponding to this menu item's funcitonality
+ *
+ * Set the accelerator path on @menu_item, through which runtime changes of the
+ * menu item's accelerator caused by the user can be identified and saved to
+ * persistant storage (see gtk_accel_map_save() on this).
+ * To setup a default accelerator for this menu item, call
+ * gtk_accel_map_add_entry() with the same @accel_path.
+ * See also gtk_accel_map_add_entry() on the specifics of accelerator paths,
+ * and gtk_menu_set_accel_path() for a more convenient variant of this function.
+ */
+void
+gtk_menu_item_set_accel_path (GtkMenuItem *menu_item,
+ const gchar *accel_path)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+ g_return_if_fail (accel_path && accel_path[0] == '<' && strchr (accel_path, '/'));
+
+ widget = GTK_WIDGET (menu_item);
+
+ /* store new path */
+ g_free (menu_item->accel_path);
+ menu_item->accel_path = g_strdup (accel_path);
+
+ /* forget accelerators associated with old path */
+ _gtk_widget_set_accel_path (widget, NULL, NULL);
+
+ /* install accelerators associated with new path */
+ if (widget->parent)
+ {
+ GtkMenu *menu = GTK_MENU (widget->parent);
+
+ if (menu->accel_group)
+ _gtk_menu_item_refresh_accel_path (GTK_MENU_ITEM (widget),
+ NULL,
+ menu->accel_group,
+ FALSE);
+ }
+}
+
+static void
gtk_menu_item_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
@@ -913,5 +1021,5 @@ gtk_menu_item_forall (GtkContainer *container,
menu_item = GTK_MENU_ITEM (container);
if (bin->child)
- (* callback) (bin->child, callback_data);
+ callback (bin->child, callback_data);
}