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.
This commit is contained in:
Tim Janik 2001-11-13 00:53:47 +00:00 committed by Tim Janik
parent aebe24f2bb
commit d07573c090
56 changed files with 3419 additions and 2197 deletions

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -1,3 +1,69 @@
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.
Mon Nov 12 19:33:52 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkmessagedialog.c (gtk_message_dialog_new): Warn

View File

@ -213,8 +213,8 @@ do_appwindow (void)
*/
accel_group = gtk_accel_group_new ();
gtk_accel_group_attach (accel_group, G_OBJECT (window));
gtk_accel_group_unref (accel_group);
gtk_window_add_accel_group (window, accel_group);
g_object_unref (accel_group);
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);

View File

@ -68,7 +68,7 @@ do_item_factory (void)
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
g_object_set_data_full (G_OBJECT (window), "<main>",
item_factory, (GDestroyNotify) g_object_unref);
gtk_accel_group_attach (accel_group, G_OBJECT (window));
gtk_window_add_accel_group (window, accel_group);
gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);

View File

@ -98,7 +98,7 @@ do_menus (void)
G_CALLBACK (gtk_true), NULL);
accel_group = gtk_accel_group_new ();
gtk_accel_group_attach (accel_group, G_OBJECT (window));
gtk_window_add_accel_group (window, accel_group);
gtk_window_set_title (GTK_WINDOW (window), "menus");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
@ -150,7 +150,7 @@ do_menus (void)
accel_group,
GDK_F1,
0,
GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
GTK_ACCEL_VISIBLE);
menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
gtk_widget_show (menuitem);
@ -175,7 +175,6 @@ do_menus (void)
GDK_F3,
0,
GTK_ACCEL_VISIBLE);
gtk_widget_lock_accelerators (menuitem);
optionmenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);

View File

@ -1,3 +1,7 @@
Mon Nov 12 23:06:38 2001 Tim Janik <timj@gtk.org>
* added gtkaccelmap.sgml. other updates.
2001-11-11 Matthias Clasen <matthiasc@poet.de>
* gdk-pixbuf/gdk-pixbuf-rendering.sgml,

View File

@ -126,7 +126,8 @@
<!entity gtk-Styles SYSTEM "sgml/gtkstyle.sgml">
<!entity gtk-Themes SYSTEM "sgml/gtkthemes.sgml">
<!entity gtk-Resource-Files SYSTEM "sgml/gtkrc.sgml">
<!entity gtk-Keyboard-Accelerators SYSTEM "sgml/gtkaccelgroup.sgml">
<!entity GtkAccelGroup SYSTEM "sgml/gtkaccelgroup.sgml">
<!entity gtk-accel-map SYSTEM "sgml/gtkaccelmap.sgml">
<!entity gtk-Selections SYSTEM "sgml/gtkselection.sgml">
<!entity gtk-Clipboards SYSTEM "sgml/gtkclipboard.sgml">
<!entity gtk-Drag-and-Drop SYSTEM "sgml/gtkdnd.sgml">
@ -248,7 +249,8 @@ that is, GUI components such as #GtkButton or #GtkTextView.
<title>GTK+ Core Reference</title>
&gtk-General;
&gtk-Keyboard-Accelerators;
&GtkAccelGroup;
&gtk-accel-map;
&gtk-Clipboards;
&gtk-Drag-and-Drop;
&gtk-Stock-Items;

View File

@ -1,6 +1,52 @@
<INCLUDE>gtk/gtk.h</INCLUDE>
<SECTION>
<FILE>gtkaccelgroup</FILE>
<TITLE>Keyboard Accelerators</TITLE>
GtkAccelGroup
gtk_accel_group_get_type
gtk_accel_group_new
gtk_accel_group_connect
gtk_accel_group_disconnect
gtk_accel_group_query
gtk_accel_group_activate
gtk_accel_groups_activate
gtk_accel_group_lock
gtk_accel_group_unlock
gtk_accelerator_valid
gtk_accelerator_parse
gtk_accelerator_name
gtk_accelerator_set_default_mod_mask
gtk_accelerator_get_default_mod_mask
<SUBSECTION Private>
<SUBSECTION Standard>
GtkAccelGroupClass
GTK_TYPE_ACCEL_GROUP
GTK_ACCEL_GROUP
GTK_IS_ACCEL_GROUP
GTK_ACCEL_GROUP_CLASS
GTK_IS_ACCEL_GROUP_CLASS
GTK_ACCEL_GROUP_GET_CLASS
</SECTION>
<SECTION>
<FILE>gtkaccelmap</FILE>
<TITLE>Accelerator Maps</TITLE>
GtkAccelMapNotify
GtkAccelMapForeach
gtk_accel_map_add_entry
gtk_accel_map_lookup_entry
gtk_accel_map_change_entry
gtk_accel_map_add_notifer
gtk_accel_map_remove_notifer
gtk_accel_map_load
gtk_accel_map_save
gtk_accel_map_foreach
gtk_accel_map_load_fd
gtk_accel_map_save_fd
</SECTION>
<SECTION>
<FILE>gtkaccellabel</FILE>
<TITLE>GtkAccelLabel</TITLE>
@ -1428,6 +1474,7 @@ gtk_menu_reorder_child
gtk_menu_popup
gtk_menu_set_accel_group
gtk_menu_get_accel_group
gtk_menu_set_accel_path
gtk_menu_set_title
gtk_menu_get_tearoff_state
gtk_menu_get_title
@ -1481,6 +1528,7 @@ gtk_menu_item_new_with_label
gtk_menu_item_new_with_mnemonic
gtk_menu_item_set_right_justified
gtk_menu_item_set_submenu
gtk_menu_item_set_accel_path
gtk_menu_item_remove_submenu
gtk_menu_item_select
gtk_menu_item_deselect
@ -3880,49 +3928,6 @@ gtk_rc_style_get_type
GtkRcContext
</SECTION>
<SECTION>
<FILE>gtkaccelgroup</FILE>
<TITLE>Keyboard Accelerators</TITLE>
GtkAccelGroup
gtk_accel_group_new
gtk_accel_group_get_default
gtk_accel_group_ref
gtk_accel_group_unref
gtk_accel_group_activate
gtk_accel_groups_activate
gtk_accel_group_attach
gtk_accel_group_detach
gtk_accel_group_add
gtk_accel_group_remove
gtk_accel_group_lock
gtk_accel_group_unlock
gtk_accelerator_valid
gtk_accelerator_parse
gtk_accelerator_name
gtk_accelerator_set_default_mod_mask
gtk_accelerator_get_default_mod_mask
<SUBSECTION Private>
GtkAccelEntry
gtk_accel_group_get_type
gtk_accel_group_get_entry
gtk_accel_group_lock_entry
gtk_accel_group_unlock_entry
gtk_accel_group_handle_add
gtk_accel_group_handle_remove
gtk_accel_group_create_add
gtk_accel_group_create_remove
gtk_accel_groups_from_object
gtk_accel_group_entries_from_object
<SUBSECTION Standard>
GtkAccelGroupClass
GTK_ACCEL_GROUP
GTK_TYPE_ACCEL_GROUP
GTK_ACCEL_GROUP_CLASS
GTK_ACCEL_GROUP_GET_CLASS
GTK_IS_ACCEL_GROUP
GTK_IS_ACCEL_GROUP_CLASS
</SECTION>
<SECTION>
<FILE>gtkselection</FILE>
<TITLE>Selections</TITLE>

View File

@ -495,9 +495,9 @@ This is a private struct used by GTK+ internally, don't worry about it.
@object:
@signal_id:
<!-- ##### ARG GtkAccelLabel:accel-widget ##### -->
<!-- ##### ARG GtkAccelLabel:accel-object ##### -->
<para>
The widget whose accelerators are to be shown by the #GtkAccelLabel.
</para>
@ -1186,6 +1186,29 @@ produce superscript and subscript.
@parent:
@priv:
<!-- ##### USER_FUNCTION GtkTreeViewDraggableFunc ##### -->
<para>
</para>
@tree_view:
@context:
@path:
@user_data:
@Returns:
<!-- ##### USER_FUNCTION GtkTreeViewDroppableFunc ##### -->
<para>
</para>
@tree_view:
@context:
@path:
@pos:
@user_data:
@Returns:
<!-- ##### ARG GtkVScale:adjustment ##### -->
<para>
the #GtkAdjustment which sets the range of the scale.
@ -1207,6 +1230,18 @@ the #GtkAdjustment which sets the range of the scale.
@arg1:
@Returns:
<!-- ##### SIGNAL GtkWidget::add-accelerator ##### -->
<para>
</para>
@widget: the object which received the signal.
@accel_signal_id:
@accel_group:
@accel_key:
@accel_mods:
@accel_flags:
<!-- ##### SIGNAL GtkWidget::debug-msg ##### -->
<para>
@ -1237,6 +1272,16 @@ the #GtkAdjustment which sets the range of the scale.
@widget: the object which received the signal.
<!-- ##### SIGNAL GtkWidget::remove-accelerator ##### -->
<para>
</para>
@widget: the object which received the signal.
@accel_group:
@accel_key:
@accel_mods:
<!-- ##### ARG GtkWidget:height ##### -->
<para>
@ -1273,6 +1318,37 @@ If the window shrinks automatically when widgets within it shrink.
</para>
<!-- ##### FUNCTION gtk_accel_group_activate ##### -->
<para>
</para>
@accel_group:
@accel_key:
@accel_mods:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_add ##### -->
<para>
</para>
@accel_group:
@path:
@accel_key:
@accel_mods:
@accel_flags:
@object:
@accel_signal:
<!-- ##### FUNCTION gtk_accel_group_attach ##### -->
<para>
</para>
@accel_group:
@object:
<!-- ##### FUNCTION gtk_accel_group_create_add ##### -->
<para>
@ -1293,6 +1369,14 @@ If the window shrinks automatically when widgets within it shrink.
@handler_offset:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_detach ##### -->
<para>
</para>
@accel_group:
@object:
<!-- ##### FUNCTION gtk_accel_group_entries_from_object ##### -->
<para>
@ -1301,6 +1385,13 @@ If the window shrinks automatically when widgets within it shrink.
@object:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_get_default ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION gtk_accel_group_get_entry ##### -->
<para>
@ -1342,6 +1433,24 @@ If the window shrinks automatically when widgets within it shrink.
@accel_key:
@accel_mods:
<!-- ##### MACRO gtk_accel_group_ref ##### -->
<para>
</para>
@Returns:
@accel_group:
<!-- ##### FUNCTION gtk_accel_group_remove ##### -->
<para>
</para>
@accel_group:
@accel_key:
@accel_mods:
@object:
<!-- ##### FUNCTION gtk_accel_group_unlock_entry ##### -->
<para>
@ -1351,6 +1460,13 @@ If the window shrinks automatically when widgets within it shrink.
@accel_key:
@accel_mods:
<!-- ##### MACRO gtk_accel_group_unref ##### -->
<para>
</para>
@accel_group:
<!-- ##### FUNCTION gtk_accel_groups_from_object ##### -->
<para>
@ -1359,6 +1475,22 @@ If the window shrinks automatically when widgets within it shrink.
@object:
@Returns:
<!-- ##### FUNCTION gtk_accel_label_get_accel_object ##### -->
<para>
</para>
@accel_label:
@Returns:
<!-- ##### FUNCTION gtk_accel_label_set_accel_object ##### -->
<para>
</para>
@accel_label:
@accel_object:
<!-- ##### FUNCTION gtk_arg_copy ##### -->
<para>
It will either copy data into an existing argument or allocate a new argument
@ -1905,6 +2037,54 @@ Get the type of GtkIdentifier.
@Returns:
<!-- ##### FUNCTION gtk_item_factory_dump_items ##### -->
<para>
</para>
@path_pspec:
@modified_only:
@print_func:
@func_data:
<!-- ##### FUNCTION gtk_item_factory_dump_rc ##### -->
<para>
</para>
@file_name:
@path_pspec:
@modified_only:
<!-- ##### FUNCTION gtk_item_factory_parse_rc ##### -->
<para>
</para>
@file_name:
<!-- ##### FUNCTION gtk_item_factory_parse_rc_scanner ##### -->
<para>
</para>
@scanner:
<!-- ##### FUNCTION gtk_item_factory_parse_rc_string ##### -->
<para>
</para>
@rc_string:
<!-- ##### FUNCTION gtk_item_factory_print_func ##### -->
<para>
</para>
@FILE_pointer:
@string:
<!-- ##### FUNCTION gtk_label_set_markup_with_accel ##### -->
<para>
@ -2715,6 +2895,31 @@ a gtk_object_unref().
@width:
@size:
<!-- ##### FUNCTION gtk_tree_view_set_rows_drag_dest ##### -->
<para>
</para>
@tree_view:
@targets:
@n_targets:
@actions:
@location_droppable_func:
@user_data:
<!-- ##### FUNCTION gtk_tree_view_set_rows_drag_source ##### -->
<para>
</para>
@tree_view:
@start_button_mask:
@targets:
@n_targets:
@actions:
@row_draggable_func:
@user_data:
<!-- ##### FUNCTION gtk_type_check_class_cast ##### -->
<para>
Given a GtkTypeClass pointer @klass, and a GtkType @cast_type, make
@ -2829,6 +3034,25 @@ Set the varargs type for a fundamental type @foreign_type.
fundamental type.
@varargs_type: Must be a GtkType which is either structured or flag, or NONE.
<!-- ##### FUNCTION gtk_widget_accelerator_signal ##### -->
<para>
</para>
@widget:
@accel_group:
@accel_key:
@accel_mods:
@Returns:
<!-- ##### FUNCTION gtk_widget_accelerators_locked ##### -->
<para>
</para>
@widget:
@Returns:
<!-- ##### FUNCTION gtk_widget_activate_mnemonic ##### -->
<para>
@ -2847,6 +3071,13 @@ fundamental type.
@width:
@height:
<!-- ##### FUNCTION gtk_widget_lock_accelerators ##### -->
<para>
</para>
@widget:
<!-- ##### FUNCTION gtk_widget_pop_style ##### -->
<para>
@ -2869,6 +3100,15 @@ fundamental type.
@style:
<!-- ##### FUNCTION gtk_widget_remove_accelerators ##### -->
<para>
</para>
@widget:
@accel_signal:
@visible_only:
<!-- ##### FUNCTION gtk_widget_set_default_style ##### -->
<para>
@ -2876,6 +3116,13 @@ fundamental type.
@style:
<!-- ##### FUNCTION gtk_widget_unlock_accelerators ##### -->
<para>
</para>
@widget:
<!-- ##### FUNCTION gtk_window_activate_mnemonic ##### -->
<para>

View File

@ -1,9 +1,9 @@
<!-- ##### SECTION Title ##### -->
Keyboard Accelerators
Keyboard Accelerator Groups
<!-- ##### SECTION Short_Description ##### -->
global keyboard accelerators (for an entire #GtkWindow)
Groups of global keyboard accelerators for an entire #GtkWindow
<!-- ##### SECTION Long_Description ##### -->
<para>
@ -11,14 +11,15 @@ A #GtkAccelGroup represents a group of keyboard accelerators,
typically attached to a toplevel #GtkWindow (with
gtk_window_add_accel_group()). Usually you won't need to create a
#GtkAccelGroup directly; instead, when using #GtkItemFactory, GTK+
automatically sets up the accelerators for your menus.
automatically sets up the accelerators for your menus in the item
factory's #GtkAccelGroup.
</para>
<para>
Note that <firstterm>accelerators</firstterm> are different from
<firstterm>mnemonics</firstterm>. Accelerators are shortcuts for
activating a menu item; they appear alongside the menu item they're a
shortcut for, for example "Ctrl+Q" might appear alongside the "Quit"
shortcut for. For example "Ctrl+Q" might appear alongside the "Quit"
menu item. Mnemonics are shortcuts for GUI elements such as text
entries or buttons; they appear as underlined characters. See
gtk_label_new_with_mnemonic(). Menu items can have both accelerators
@ -27,15 +28,24 @@ and mnemonics, of course.
<!-- ##### SECTION See_Also ##### -->
<para>
gtk_label_new_with_mnemonic(), gtk_window_add_accel_group()
gtk_window_add_accel_group(), gtk_accel_map_change_entry(),
gtk_item_factory_new(), gtk_label_new_with_mnemonic()
</para>
<!-- ##### STRUCT GtkAccelGroup ##### -->
<para>
On opaque data type representing a group of accelerators.
An object representing and maintaining a group of accelerators.
</para>
<!-- ##### FUNCTION gtk_accel_group_get_type ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION gtk_accel_group_new ##### -->
<para>
@ -44,72 +54,7 @@ On opaque data type representing a group of accelerators.
@Returns:
<!-- ##### FUNCTION gtk_accel_group_get_default ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION gtk_accel_group_ref ##### -->
<para>
</para>
@accel_group:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_unref ##### -->
<para>
</para>
@accel_group:
<!-- ##### FUNCTION gtk_accel_group_activate ##### -->
<para>
</para>
@accel_group:
@accel_key:
@accel_mods:
@Returns:
<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
<para>
</para>
@object:
@accel_key:
@accel_mods:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_attach ##### -->
<para>
</para>
@accel_group:
@object:
<!-- ##### FUNCTION gtk_accel_group_detach ##### -->
<para>
</para>
@accel_group:
@object:
<!-- ##### FUNCTION gtk_accel_group_add ##### -->
<!-- ##### FUNCTION gtk_accel_group_connect ##### -->
<para>
</para>
@ -118,11 +63,13 @@ On opaque data type representing a group of accelerators.
@accel_key:
@accel_mods:
@accel_flags:
@object:
@accel_signal:
@closure:
@accel_path_quark:
<!-- # Unused Parameters # -->
@path_quark:
<!-- ##### FUNCTION gtk_accel_group_remove ##### -->
<!-- ##### FUNCTION gtk_accel_group_disconnect ##### -->
<para>
</para>
@ -130,6 +77,31 @@ On opaque data type representing a group of accelerators.
@accel_group:
@accel_key:
@accel_mods:
@Returns:
<!-- ##### FUNCTION gtk_accel_group_query ##### -->
<para>
</para>
@accel_group:
@accel_key:
@accel_mods:
@n_entries:
@Returns:
<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
<para>
</para>
@acceleratable:
@accel_key:
@accel_mods:
@Returns:
<!-- # Unused Parameters # -->
@object:

View File

@ -94,7 +94,7 @@ Creates a new #GtkAccelLabel.
@Returns: a new #GtkAccelLabel.
<!-- ##### FUNCTION gtk_accel_label_get_accel_object ##### -->
<!-- ##### FUNCTION gtk_accel_label_get_accel_widget ##### -->
<para>
</para>
@ -103,24 +103,7 @@ Creates a new #GtkAccelLabel.
@Returns:
<!-- ##### FUNCTION gtk_accel_label_set_accel_object ##### -->
<para>
</para>
@accel_label:
@accel_object:
<!-- ##### MACRO gtk_accel_label_get_accel_widget ##### -->
<para>
</para>
@accel_label:
<!-- ##### MACRO gtk_accel_label_set_accel_widget ##### -->
<!-- ##### FUNCTION gtk_accel_label_set_accel_widget ##### -->
<para>
Sets the widget whose accelerators are to be shown.
</para>
@ -151,8 +134,13 @@ accelerators are added or removed from the associated widget.
@Returns: always returns %FALSE.
<!-- ##### ARG GtkAccelLabel:accel-object ##### -->
<!-- ##### ARG GtkAccelLabel:accel-closure ##### -->
<para>
</para>
<!-- ##### ARG GtkAccelLabel:accel-widget ##### -->
<para>
The widget whose accelerators are to be shown by the #GtkAccelLabel.
</para>

View File

@ -225,7 +225,7 @@ time.
</para>
@colorsel:
@colorsel:
@color:
@ -234,8 +234,8 @@ time.
</para>
@colorsel:
@color:
@colorsel:
@color:
<!-- ##### SIGNAL GtkColorSelection::color-changed ##### -->

View File

@ -178,7 +178,7 @@ worried about differences in case.
</para>
@combo: a #GtkCombo.
@val: %TRUE if the text in the list items is case sensitive.
@val: %TRUE if the text in the list items is case sensitive.
<!-- ##### FUNCTION gtk_combo_set_item_string ##### -->

View File

@ -169,7 +169,7 @@ Creates a new dialog box. Widgets should not be packed into this #GtkWindow
directly, but into the vbox and action_area, as described above.
</para>
@Returns: a new #GtkDialog.
@Returns: a new #GtkDialog.
<!-- ##### FUNCTION gtk_dialog_new_with_buttons ##### -->

View File

@ -20,7 +20,6 @@ Public enumerated types used throughout GTK+.
</para>
@GTK_ACCEL_VISIBLE:
@GTK_ACCEL_SIGNAL_VISIBLE:
@GTK_ACCEL_LOCKED:
@GTK_ACCEL_MASK:

View File

@ -84,11 +84,6 @@ GtkItemFactory
</para>
@path:
@accelerator_key:
@accelerator_mods:
@modified:
@in_propagation:
@dummy:
@widgets:
<!-- ##### FUNCTION gtk_item_factory_new ##### -->
@ -113,30 +108,6 @@ GtkItemFactory
@accel_group:
<!-- ##### FUNCTION gtk_item_factory_parse_rc ##### -->
<para>
</para>
@file_name:
<!-- ##### FUNCTION gtk_item_factory_parse_rc_string ##### -->
<para>
</para>
@rc_string:
<!-- ##### FUNCTION gtk_item_factory_parse_rc_scanner ##### -->
<para>
</para>
@scanner:
<!-- ##### FUNCTION gtk_item_factory_add_foreign ##### -->
<para>
@ -207,36 +178,6 @@ GtkItemFactory
@Returns:
<!-- ##### FUNCTION gtk_item_factory_dump_items ##### -->
<para>
</para>
@path_pspec:
@modified_only:
@print_func:
@func_data:
<!-- ##### FUNCTION gtk_item_factory_dump_rc ##### -->
<para>
</para>
@file_name:
@path_pspec:
@modified_only:
<!-- ##### FUNCTION gtk_item_factory_print_func ##### -->
<para>
</para>
@FILE_pointer:
@string:
<!-- ##### FUNCTION gtk_item_factory_create_item ##### -->
<para>

View File

@ -96,9 +96,9 @@ Creates a new #GtkMenu.
Adds a new #GtkMenuItem to the end of the menu's item list.
</para>
<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
<!-- # Unused Parameters # -->
@m:
@c:
@ -108,9 +108,9 @@ Adds a new #GtkMenuItem to the end of the menu's item list.
Adds a new #GtkMenuItem to the beginning of the menu's item list.
</para>
<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
<!-- # Unused Parameters # -->
@menu_child:
@m:
@c:
@ -122,10 +122,10 @@ Adds a new #GtkMenuItem to the menu's item list at the position
indicated by @position.
</para>
<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
@pos:
<!-- # Unused Parameters # -->
@position: The position in the item list where @child is added.
Positions are numbered from 0 to n-1.
@ -162,6 +162,9 @@ at the current pointer position.
<!-- ##### FUNCTION gtk_menu_set_accel_group ##### -->
<para>
Set the #GtkAccelGroup which holds global accelerators for the menu.
This accelerator group needs to also be added to all windows that
this menu is being used in with gtk_window_add_accel_group(), in order
for those windows to support all the accelerators contained in this group.
</para>
@menu: a #GtkMenu.
@ -178,6 +181,15 @@ See gtk_menu_set_accel_group().
@Returns: the #GtkAccelGroup associated with the menu.
<!-- ##### FUNCTION gtk_menu_set_accel_path ##### -->
<para>
</para>
@menu:
@accel_path:
<!-- ##### FUNCTION gtk_menu_set_title ##### -->
<para>
Sets the title string for the menu. The title is displayed when the menu

View File

@ -83,6 +83,15 @@ Sets the widget submenu, or changes it.
@submenu: the submenu
<!-- ##### FUNCTION gtk_menu_item_set_accel_path ##### -->
<para>
</para>
@menu_item:
@accel_path:
<!-- ##### FUNCTION gtk_menu_item_remove_submenu ##### -->
<para>
Removes the widget's submenu.

View File

@ -112,6 +112,9 @@ Old name for gtk_paned_set_handle_size()
Old name for gtk_paned_set_gutter_size()
</para>
@p:
@s:
<!-- ##### FUNCTION gtk_paned_pack1 ##### -->
<para>

View File

@ -47,8 +47,8 @@ Widgets can be visibly grouped by adding gaps between widgets using gtk_toolbar_
to a #GtkToolbar.
</para>
@GTK_TOOLBAR_CHILD_SPACE: a space in the style of the toolbar's #GtkToolbarSpaceStyle.
@GTK_TOOLBAR_CHILD_BUTTON: a #GtkButton.
@GTK_TOOLBAR_CHILD_SPACE: a space in the style of the toolbar's #GtkToolbarSpaceStyle.
@GTK_TOOLBAR_CHILD_BUTTON: a #GtkButton.
@GTK_TOOLBAR_CHILD_TOGGLEBUTTON: a #GtkToggleButton.
@GTK_TOOLBAR_CHILD_RADIOBUTTON: a #GtkRadioButton.
@GTK_TOOLBAR_CHILD_WIDGET: a standard #GtkWidget.

View File

@ -43,6 +43,7 @@ GtkTreeView drag-and-drop
</para>
@g_iface:
@row_draggable:
@drag_data_get:
@drag_data_delete:

View File

@ -49,18 +49,6 @@ GtkTreeView
@Returns:
<!-- ##### USER_FUNCTION GtkTreeViewDraggableFunc ##### -->
<para>
</para>
@tree_view:
@context:
@path:
@user_data:
@Returns:
<!-- ##### USER_FUNCTION GtkTreeViewMappingFunc ##### -->
<para>
@ -71,19 +59,6 @@ GtkTreeView
@user_data:
<!-- ##### USER_FUNCTION GtkTreeViewDroppableFunc ##### -->
<para>
</para>
@tree_view:
@context:
@path:
@pos:
@user_data:
@Returns:
<!-- ##### USER_FUNCTION GtkTreeViewSearchEqualFunc ##### -->
<para>
@ -559,33 +534,6 @@ GtkTreeView
@wy:
<!-- ##### FUNCTION gtk_tree_view_set_rows_drag_source ##### -->
<para>
</para>
@tree_view:
@start_button_mask:
@targets:
@n_targets:
@actions:
@row_draggable_func:
@user_data:
<!-- ##### FUNCTION gtk_tree_view_set_rows_drag_dest ##### -->
<para>
</para>
@tree_view:
@targets:
@n_targets:
@actions:
@location_droppable_func:
@user_data:
<!-- ##### FUNCTION gtk_tree_view_unset_rows_drag_source ##### -->
<para>

View File

@ -523,27 +523,6 @@ GtkWidget
</para>
@widget:
@accel_group:
@accel_key:
@accel_mods:
<!-- ##### FUNCTION gtk_widget_remove_accelerators ##### -->
<para>
</para>
@widget:
@accel_signal:
@visible_only:
<!-- ##### FUNCTION gtk_widget_accelerator_signal ##### -->
<para>
</para>
@widget:
@accel_group:
@accel_key:
@ -1000,14 +979,6 @@ GtkWidget
@Returns:
<!-- ##### FUNCTION gtk_widget_lock_accelerators ##### -->
<para>
</para>
@widget:
<!-- ##### FUNCTION gtk_widget_modify_style ##### -->
<para>
@ -1207,23 +1178,6 @@ GtkWidget
@Returns:
<!-- ##### FUNCTION gtk_widget_unlock_accelerators ##### -->
<para>
</para>
@widget:
<!-- ##### FUNCTION gtk_widget_accelerators_locked ##### -->
<para>
</para>
@widget:
@Returns:
<!-- ##### FUNCTION gtk_widget_mnemonic_activate ##### -->
<para>
@ -1456,17 +1410,12 @@ GtkWidget
@requisition:
<!-- ##### SIGNAL GtkWidget::add-accelerator ##### -->
<!-- ##### SIGNAL GtkWidget::accel-closures-changed ##### -->
<para>
</para>
@widget: the object which received the signal.
@accel_signal_id:
@accel_group:
@accel_key:
@accel_mods:
@accel_flags:
<!-- ##### SIGNAL GtkWidget::button-press-event ##### -->
<para>
@ -1834,16 +1783,6 @@ a widget changes from un-anchored to anchored or vice-versa.
@widget: the object which received the signal.
<!-- ##### SIGNAL GtkWidget::remove-accelerator ##### -->
<para>
</para>
@widget: the object which received the signal.
@accel_group:
@accel_key:
@accel_mods:
<!-- ##### SIGNAL GtkWidget::scroll-event ##### -->
<para>

View File

@ -694,6 +694,13 @@ it's larger
@height:
<!-- ##### SIGNAL GtkWindow::accels-changed ##### -->
<para>
</para>
@window: the object which received the signal.
<!-- ##### SIGNAL GtkWindow::activate-default ##### -->
<para>

View File

@ -86,6 +86,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtk.h \
gtkaccelgroup.h \
gtkaccellabel.h \
gtkaccelmap.h \
gtkaccessible.h \
gtkadjustment.h \
gtkalignment.h \
@ -244,6 +245,7 @@ gtk_private_h_sources = @STRIP_BEGIN@ \
# GTK+ C sources to build the library from
gtk_c_sources = @STRIP_BEGIN@ \
gtkaccelgroup.c \
gtkaccelmap.c \
gtkaccellabel.c \
gtkaccessible.c \
gtkadjustment.c \

View File

@ -31,6 +31,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkaccelgroup.h>
#include <gtk/gtkaccellabel.h>
#include <gtk/gtkaccelmap.h>
#include <gtk/gtkaccessible.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkalignment.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,5 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* GtkAccelGroup: Accelerator manager for GtkObjects.
* Copyright (C) 1998 Tim Janik
* Copyright (C) 1998, 2001 Tim Janik
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -32,13 +29,12 @@
#include <gdk/gdk.h>
#include <gtk/gtkobject.h>
#include <gtk/gtkenums.h>
G_BEGIN_DECLS
/* --- type macros --- */
#define GTK_TYPE_ACCEL_GROUP (gtk_accel_group_get_type ())
#define GTK_ACCEL_GROUP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_ACCEL_GROUP, GtkAccelGroup))
#define GTK_ACCEL_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ACCEL_GROUP, GtkAccelGroupClass))
@ -47,56 +43,85 @@ G_BEGIN_DECLS
#define GTK_ACCEL_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ACCEL_GROUP, GtkAccelGroupClass))
typedef struct _GtkAccelGroup GtkAccelGroup;
typedef struct _GtkAccelGroupClass GtkAccelGroupClass;
typedef struct _GtkAccelEntry GtkAccelEntry;
/* --- accel flags --- */
typedef enum
{
/* should the accelerator appear in
* the widget's display?
*/
GTK_ACCEL_VISIBLE = 1 << 0,
/* should the signal associated with
* this accelerator be also visible?
*/
GTK_ACCEL_SIGNAL_VISIBLE = 1 << 1,
/* may the accelerator be removed
* again?
*/
GTK_ACCEL_LOCKED = 1 << 2,
GTK_ACCEL_VISIBLE = 1 << 0, /* display in GtkAccelLabel? */
GTK_ACCEL_LOCKED = 1 << 1, /* is it removable? */
GTK_ACCEL_MASK = 0x07
} GtkAccelFlags;
/* --- typedefs & structures --- */
typedef struct _GtkAccelGroup GtkAccelGroup;
typedef struct _GtkAccelGroupClass GtkAccelGroupClass;
typedef struct _GtkAccelKey GtkAccelKey;
typedef struct _GtkAccelGroupEntry GtkAccelGroupEntry;
typedef gboolean (*GtkAccelGroupActivate) (GtkAccelGroup *accel_group,
GObject *acceleratable,
guint keyval,
GdkModifierType modifier);
struct _GtkAccelGroup
{
GObject parent;
guint lock_count;
GdkModifierType modifier_mask;
GSList *attach_objects;
GObject parent;
guint lock_count;
GdkModifierType modifier_mask;
GSList *acceleratables;
guint n_accels;
GtkAccelGroupEntry *priv_accels;
};
struct _GtkAccelGroupClass
{
GObjectClass parent_class;
};
struct _GtkAccelEntry
void (*accel_changed) (GtkAccelGroup *accel_group,
guint keyval,
GdkModifierType modifier,
GClosure *accel_closure);
};
struct _GtkAccelKey
{
/* key portion
*/
GtkAccelGroup *accel_group;
guint accelerator_key;
GdkModifierType accelerator_mods;
GtkAccelFlags accel_flags;
GObject *object;
guint signal_id;
guint accel_key;
GdkModifierType accel_mods;
guint accel_flags : 16;
};
/* Accelerators
*/
/* -- Accelerator Groups --- */
GType gtk_accel_group_get_type (void);
GtkAccelGroup* gtk_accel_group_new (void);
void gtk_accel_group_lock (GtkAccelGroup *accel_group);
void gtk_accel_group_unlock (GtkAccelGroup *accel_group);
void gtk_accel_group_connect (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GtkAccelFlags accel_flags,
GClosure *closure,
GQuark accel_path_quark);
gboolean gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
gboolean gtk_accel_groups_disconnect_closure (GClosure *closure);
/* --- GtkActivatable glue --- */
void _gtk_accel_group_attach (GtkAccelGroup *accel_group,
GObject *object);
void _gtk_accel_group_detach (GtkAccelGroup *accel_group,
GObject *object);
gboolean gtk_accel_groups_activate (GObject *acceleratable,
guint accel_key,
GdkModifierType accel_mods);
GSList* gtk_accel_groups_from_acceleratable (GObject *object);
GtkAccelKey* gtk_accel_group_find (GtkAccelGroup *accel_group,
gboolean (*find_func) (GtkAccelKey *key,
GClosure *closure,
gpointer data),
gpointer data);
GtkAccelGroup* gtk_accel_group_from_accel_closure (GClosure *closure);
/* --- Accelerators--- */
gboolean gtk_accelerator_valid (guint keyval,
GdkModifierType modifiers) G_GNUC_CONST;
void gtk_accelerator_parse (const gchar *accelerator,
@ -108,75 +133,23 @@ void gtk_accelerator_set_default_mod_mask (GdkModifierType default_mod_mask);
guint gtk_accelerator_get_default_mod_mask (void);
/* Accelerator Groups
*/
GType gtk_accel_group_get_type (void);
GtkAccelGroup* gtk_accel_group_new (void);
GtkAccelGroup* gtk_accel_group_get_default (void);
GtkAccelGroup* gtk_accel_group_ref (GtkAccelGroup *accel_group);
void gtk_accel_group_unref (GtkAccelGroup *accel_group);
void gtk_accel_group_lock (GtkAccelGroup *accel_group);
void gtk_accel_group_unlock (GtkAccelGroup *accel_group);
gboolean gtk_accel_groups_activate (GObject *object,
guint accel_key,
GdkModifierType accel_mods);
/* internal functions
*/
gboolean gtk_accel_group_activate (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
void gtk_accel_group_attach (GtkAccelGroup *accel_group,
GObject *object);
void gtk_accel_group_detach (GtkAccelGroup *accel_group,
GObject *object);
/* Accelerator Group Entries (internal)
*/
GtkAccelEntry* gtk_accel_group_get_entry (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
void gtk_accel_group_lock_entry (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
void gtk_accel_group_unlock_entry (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
void gtk_accel_group_add (GtkAccelGroup *accel_group,
/* --- internal --- */
GtkAccelGroupEntry* gtk_accel_group_query (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GtkAccelFlags accel_flags,
GObject *object,
const gchar *accel_signal);
void gtk_accel_group_remove (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GObject *object);
guint *n_entries);
struct _GtkAccelGroupEntry
{
GtkAccelKey key;
GClosure *closure;
GQuark accel_path_quark;
};
/* Accelerator Signals (internal)
*/
void gtk_accel_group_handle_add (GObject *object,
guint accel_signal_id,
GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GtkAccelFlags accel_flags);
void gtk_accel_group_handle_remove (GObject *object,
GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
guint gtk_accel_group_create_add (GType class_type,
GSignalFlags signal_flags,
guint handler_offset);
guint gtk_accel_group_create_remove (GType class_type,
GSignalFlags signal_flags,
guint handler_offset);
/* Miscellaneous (internal)
*/
GSList* gtk_accel_groups_from_object (GObject *object);
GSList* gtk_accel_group_entries_from_object (GObject *object);
#ifndef GTK_DISABLE_DEPRECATED
#define gtk_accel_group_ref g_object_ref
#define gtk_accel_group_unref g_object_unref
#endif /* GTK_DISABLE_DEPRECATED */
G_END_DECLS

View File

@ -26,17 +26,19 @@
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gtkaccellabel.h"
#include "gtkaccelmap.h"
#include "gtkmain.h"
#include "gtksignal.h"
#include "gtkintl.h"
#include <string.h>
#include <ctype.h>
#include "gtkmain.h"
#include "gtksignal.h"
#include "gtkaccellabel.h"
#include "gtkintl.h"
enum {
PROP_0,
PROP_ACCEL_OBJECT
PROP_ACCEL_CLOSURE,
PROP_ACCEL_WIDGET
};
static void gtk_accel_label_class_init (GtkAccelLabelClass *klass);
@ -90,33 +92,17 @@ static void
gtk_accel_label_class_init (GtkAccelLabelClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkMiscClass *misc_class;
GtkLabelClass *label_class;
GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
accel_label_class = class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
misc_class = (GtkMiscClass*) class;
label_class = (GtkLabelClass*) class;
parent_class = gtk_type_class (GTK_TYPE_LABEL);
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_accel_label_finalize;
gobject_class->set_property = gtk_accel_label_set_property;
gobject_class->get_property = gtk_accel_label_get_property;
object_class->destroy = gtk_accel_label_destroy;
g_object_class_install_property (G_OBJECT_CLASS(object_class),
PROP_ACCEL_OBJECT,
g_param_spec_object ("accel_object",
_("Accelerator object"),
_("The object monitored by this accelerator label"),
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_WRITABLE));
widget_class->size_request = gtk_accel_label_size_request;
widget_class->expose_event = gtk_accel_label_expose_event;
@ -129,6 +115,21 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
class->mod_separator = g_strdup ("+");
class->accel_seperator = g_strdup (" / ");
class->latin1_to_char = TRUE;
g_object_class_install_property (G_OBJECT_CLASS (object_class),
PROP_ACCEL_CLOSURE,
g_param_spec_object ("accel_closure",
_("Accelerator Closure"),
_("The closure to be monitored for accelerator changes"),
GTK_TYPE_WIDGET,
G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (G_OBJECT_CLASS (object_class),
PROP_ACCEL_WIDGET,
g_param_spec_object ("accel_widget",
_("Accelerator Widget"),
_("The widget to be monitored for accelerator changes"),
GTK_TYPE_WIDGET,
G_PARAM_READABLE | G_PARAM_WRITABLE));
}
static void
@ -143,8 +144,11 @@ gtk_accel_label_set_property (GObject *object,
switch (prop_id)
{
case PROP_ACCEL_OBJECT:
gtk_accel_label_set_accel_object (accel_label, g_value_get_object (value));
case PROP_ACCEL_CLOSURE:
gtk_accel_label_set_accel_closure (accel_label, g_value_get_boxed (value));
break;
case PROP_ACCEL_WIDGET:
gtk_accel_label_set_accel_widget (accel_label, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -152,10 +156,11 @@ gtk_accel_label_set_property (GObject *object,
}
}
static void gtk_accel_label_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
static void
gtk_accel_label_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkAccelLabel *accel_label;
@ -163,8 +168,11 @@ static void gtk_accel_label_get_property (GObject *object,
switch (prop_id)
{
case PROP_ACCEL_OBJECT:
g_value_set_object (value, accel_label->accel_object);
case PROP_ACCEL_CLOSURE:
g_value_set_boxed (value, accel_label->accel_closure);
break;
case PROP_ACCEL_WIDGET:
g_value_set_object (value, accel_label->accel_widget);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -177,7 +185,9 @@ gtk_accel_label_init (GtkAccelLabel *accel_label)
{
accel_label->queue_id = 0;
accel_label->accel_padding = 3;
accel_label->accel_object = NULL;
accel_label->accel_widget = NULL;
accel_label->accel_closure = NULL;
accel_label->accel_group = NULL;
accel_label->accel_string = NULL;
gtk_accel_label_refetch (accel_label);
@ -206,7 +216,8 @@ gtk_accel_label_destroy (GtkObject *object)
accel_label = GTK_ACCEL_LABEL (object);
gtk_accel_label_set_accel_object (accel_label, NULL);
gtk_accel_label_set_accel_widget (accel_label, NULL);
gtk_accel_label_set_accel_closure (accel_label, NULL);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
@ -214,33 +225,34 @@ gtk_accel_label_destroy (GtkObject *object)
static void
gtk_accel_label_finalize (GObject *object)
{
GtkAccelLabel *accel_label;
g_return_if_fail (GTK_IS_ACCEL_LABEL (object));
accel_label = GTK_ACCEL_LABEL (object);
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (object);
if (accel_label->queue_id)
{
gtk_idle_remove (accel_label->queue_id);
accel_label->queue_id = 0;
}
g_free (accel_label->accel_string);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* gtk_accel_label_get_accel_object:
* gtk_accel_label_get_accel_widget:
* @accel_label: a #GtkAccelLabel
*
* Fetches the widget monitored by this accelerator label. See
* gtk_accel_label_set_accel_object().
* gtk_accel_label_set_accel_widget().
*
* Return value: the object monitored by the accelerator label,
* or %NULL.
**/
GObject *
gtk_accel_label_get_accel_object (GtkAccelLabel *accel_label)
GtkWidget*
gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label)
{
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), NULL);
return accel_label->accel_object;
return accel_label->accel_widget;
}
guint
@ -336,6 +348,55 @@ gtk_accel_label_expose_event (GtkWidget *widget,
return TRUE;
}
static void
refetch_widget_accel_closure (GtkAccelLabel *accel_label)
{
GSList *slist;
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
g_return_if_fail (GTK_IS_WIDGET (accel_label->accel_widget));
for (slist = _gtk_widget_get_accel_closures (accel_label->accel_widget); slist; slist = slist->next)
if (gtk_accel_group_from_accel_closure (slist->data))
{
/* we just take the first correctly used closure */
gtk_accel_label_set_accel_closure (accel_label, slist->data);
return;
}
gtk_accel_label_set_accel_closure (accel_label, NULL);
}
void
gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
GtkWidget *accel_widget)
{
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
if (accel_widget)
g_return_if_fail (GTK_IS_WIDGET (accel_widget));
if (accel_widget != accel_label->accel_widget)
{
if (accel_label->accel_widget)
{
gtk_accel_label_set_accel_closure (accel_label, NULL);
g_signal_handlers_disconnect_by_func (accel_label->accel_widget,
G_CALLBACK (refetch_widget_accel_closure),
accel_label);
g_object_unref (accel_label->accel_widget);
}
accel_label->accel_widget = accel_widget;
if (accel_label->accel_widget)
{
g_object_ref (accel_label->accel_widget);
g_signal_connect_object (accel_label->accel_widget, "accel_closures_changed",
G_CALLBACK (refetch_widget_accel_closure),
accel_label, G_CONNECT_SWAPPED);
refetch_widget_accel_closure (accel_label);
}
g_object_notify (G_OBJECT (accel_label), "accel_widget");
}
}
static void
gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label)
{
@ -347,45 +408,46 @@ gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label)
accel_label);
}
static void
check_accel_changed (GtkAccelGroup *accel_group,
guint keyval,
GdkModifierType modifier,
GClosure *accel_closure,
GtkAccelLabel *accel_label)
{
if (accel_closure == accel_label->accel_closure)
gtk_accel_label_queue_refetch (accel_label);
}
void
gtk_accel_label_set_accel_object (GtkAccelLabel *accel_label,
GObject *accel_object)
gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
GClosure *accel_closure)
{
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
g_return_if_fail (accel_object == NULL || G_IS_OBJECT (accel_object));
if (accel_object != accel_label->accel_object)
{
if (accel_label->accel_object)
{
g_signal_handlers_disconnect_by_func (accel_label->accel_object,
G_CALLBACK (gtk_accel_label_queue_refetch),
accel_object);
g_object_unref (accel_label->accel_object);
}
if (accel_label->queue_id)
{
gtk_idle_remove (accel_label->queue_id);
accel_label->queue_id = 0;
}
accel_label->accel_object = accel_object;
if (accel_label->accel_object)
{
g_object_ref (accel_label->accel_object);
g_signal_connect_object (accel_label->accel_object,
"add-accelerator",
G_CALLBACK (gtk_accel_label_queue_refetch),
accel_label,
G_CONNECT_AFTER | G_CONNECT_SWAPPED);
g_signal_connect_object (accel_label->accel_object,
"remove-accelerator",
G_CALLBACK (gtk_accel_label_queue_refetch),
accel_label,
G_CONNECT_AFTER | G_CONNECT_SWAPPED);
}
gtk_accel_label_refetch (accel_label);
if (accel_closure)
g_return_if_fail (gtk_accel_group_from_accel_closure (accel_closure) != NULL);
g_object_notify (G_OBJECT (accel_label), "accel_object");
if (accel_closure != accel_label->accel_closure)
{
if (accel_label->accel_closure)
{
g_signal_handlers_disconnect_by_func (accel_label->accel_group,
G_CALLBACK (check_accel_changed),
accel_label);
accel_label->accel_group = NULL;
g_closure_unref (accel_label->accel_closure);
}
accel_label->accel_closure = accel_closure;
if (accel_label->accel_closure)
{
g_closure_ref (accel_label->accel_closure);
accel_label->accel_group = gtk_accel_group_from_accel_closure (accel_closure);
g_signal_connect_object (accel_label->accel_group, "accel_changed",
G_CALLBACK (check_accel_changed),
accel_label, 0);
}
gtk_accel_label_queue_refetch (accel_label);
g_object_notify (G_OBJECT (accel_label), "accel_closure");
}
}
@ -401,107 +463,106 @@ gtk_accel_label_refetch_idle (GtkAccelLabel *accel_label)
return retval;
}
static gboolean
find_accel (GtkAccelKey *key,
GClosure *closure,
gpointer data)
{
return data == (gpointer) closure;
}
gboolean
gtk_accel_label_refetch (GtkAccelLabel *accel_label)
{
GtkAccelLabelClass *class;
gchar *utf8;
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE);
class = GTK_ACCEL_LABEL_GET_CLASS (accel_label);
g_free (accel_label->accel_string);
accel_label->accel_string = NULL;
if (accel_label->accel_object)
if (accel_label->accel_closure)
{
GtkAccelEntry *entry = NULL;
GSList *slist;
slist = gtk_accel_group_entries_from_object (accel_label->accel_object);
for (; slist; slist = slist->next)
GtkAccelKey *key = gtk_accel_group_find (accel_label->accel_group, find_accel, accel_label->accel_closure);
if (key && key->accel_flags & GTK_ACCEL_VISIBLE)
{
entry = slist->data;
if (entry->accel_flags & GTK_ACCEL_VISIBLE)
GString *gstring;
gboolean seen_mod = FALSE;
gstring = g_string_new (accel_label->accel_string);
g_string_append (gstring, gstring->len ? class->accel_seperator : " ");
if (key->accel_mods & GDK_SHIFT_MASK)
{
GString *gstring;
gboolean had_mod;
gstring = g_string_new (accel_label->accel_string);
if (gstring->len)
g_string_append (gstring, class->accel_seperator);
else
g_string_append (gstring, " ");
if (entry->accel_flags & GTK_ACCEL_SIGNAL_VISIBLE)
{
g_string_append (gstring, class->signal_quote1);
g_string_append (gstring, gtk_signal_name (entry->signal_id));
g_string_append (gstring, class->signal_quote2);
}
had_mod = FALSE;
if (entry->accelerator_mods & GDK_SHIFT_MASK)
{
g_string_append (gstring, class->mod_name_shift);
had_mod = TRUE;
}
if (entry->accelerator_mods & GDK_CONTROL_MASK)
{
if (had_mod)
g_string_append (gstring, class->mod_separator);
g_string_append (gstring, class->mod_name_control);
had_mod = TRUE;
}
if (entry->accelerator_mods & GDK_MOD1_MASK)
{
if (had_mod)
g_string_append (gstring, class->mod_separator);
g_string_append (gstring, class->mod_name_alt);
had_mod = TRUE;
}
if (had_mod)
g_string_append (gstring, class->mod_separator);
if (entry->accelerator_key < 0x80 ||
(entry->accelerator_key > 0x80 &&
entry->accelerator_key <= 0xff &&
class->latin1_to_char))
{
switch (entry->accelerator_key)
{
case ' ':
g_string_append (gstring, "Space");
break;
case '\\':
g_string_append (gstring, "Backslash");
break;
default:
g_string_append_c (gstring, toupper (entry->accelerator_key));
break;
}
}
else
{
gchar *tmp;
tmp = gtk_accelerator_name (entry->accelerator_key, 0);
if (tmp[0] != 0 && tmp[1] == 0)
tmp[0] = toupper (tmp[0]);
g_string_append (gstring, tmp);
g_free (tmp);
}
g_free (accel_label->accel_string);
accel_label->accel_string = gstring->str;
g_string_free (gstring, FALSE);
g_string_append (gstring, class->mod_name_shift);
seen_mod = TRUE;
}
if (key->accel_mods & GDK_CONTROL_MASK)
{
if (seen_mod)
g_string_append (gstring, class->mod_separator);
g_string_append (gstring, class->mod_name_control);
seen_mod = TRUE;
}
if (key->accel_mods & GDK_MOD1_MASK)
{
if (seen_mod)
g_string_append (gstring, class->mod_separator);
g_string_append (gstring, class->mod_name_alt);
seen_mod = TRUE;
}
if (seen_mod)
g_string_append (gstring, class->mod_separator);
if (key->accel_key < 0x80 ||
(key->accel_key > 0x80 &&
key->accel_key <= 0xff &&
class->latin1_to_char))
{
switch (key->accel_key)
{
case ' ':
g_string_append (gstring, "Space");
break;
case '\\':
g_string_append (gstring, "Backslash");
break;
default:
g_string_append_c (gstring, toupper (key->accel_key));
break;
}
}
else
{
gchar *tmp;
tmp = gtk_accelerator_name (key->accel_key, 0);
if (tmp[0] != 0 && tmp[1] == 0)
tmp[0] = toupper (tmp[0]);
g_string_append (gstring, tmp);
g_free (tmp);
}
g_free (accel_label->accel_string);
accel_label->accel_string = gstring->str;
g_string_free (gstring, FALSE);
}
if (!accel_label->accel_string)
accel_label->accel_string = g_strdup ("-/-");
}
if (!accel_label->accel_string)
accel_label->accel_string = g_strdup ("");
utf8 = g_locale_to_utf8 (accel_label->accel_string, -1, NULL, NULL, NULL);
if (utf8)
{
g_free (accel_label->accel_string);
accel_label->accel_string = utf8;
}
if (accel_label->queue_id)
{
gtk_idle_remove (accel_label->queue_id);

View File

@ -54,11 +54,13 @@ struct _GtkAccelLabel
{
GtkLabel label;
guint queue_id;
guint accel_padding;
GObject *accel_object;
gchar *accel_string;
guint16 accel_string_width;
guint queue_id;
guint accel_padding;
GtkWidget *accel_widget;
GClosure *accel_closure;
GtkAccelGroup *accel_group;
gchar *accel_string;
guint16 accel_string_width;
};
struct _GtkAccelLabelClass
@ -80,20 +82,15 @@ struct _GtkAccelLabelClass
#endif /* GTK_DISABLE_DEPRECATED */
GtkType gtk_accel_label_get_type (void) G_GNUC_CONST;
GtkWidget *gtk_accel_label_new (const gchar *string);
GObject *gtk_accel_label_get_accel_object (GtkAccelLabel *accel_label);
GtkWidget* gtk_accel_label_new (const gchar *string);
GtkWidget* gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label);
guint gtk_accel_label_get_accel_width (GtkAccelLabel *accel_label);
void gtk_accel_label_set_accel_object (GtkAccelLabel *accel_label,
GObject *accel_object);
void gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
GtkWidget *accel_widget);
void gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
GClosure *closure);
gboolean gtk_accel_label_refetch (GtkAccelLabel *accel_label);
#ifndef GTK_DISABLE_DEPRECATED
#define gtk_accel_label_get_accel_widget(accel_label) \
GTK_WIDGET(gtk_accel_label_get_accel_object(acel_label))
#define gtk_accel_label_set_accel_widget(accel_label, accel_widget) \
gtk_accel_label_set_accel_object((accel_label), G_OBJECT(accel_widget))
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */

858
gtk/gtkaccelmap.c Normal file
View File

@ -0,0 +1,858 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1998, 2001 Tim Janik
*
* This library is free software; you can redistribute it and/or
* 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
* Lesser General Public License for more details.
*
* 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.
*/
#include "gtkaccelmap.h"
#include "gtkwindow.h" /* in lack of GtkAcceleratable */
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/* --- structures --- */
typedef struct {
const gchar *accel_path;
guint accel_key;
guint accel_mods;
guint std_accel_key;
guint std_accel_mods;
guint changed : 1;
GHookList *hooks;
} AccelEntry;
/* --- variables --- */
static GHashTable *accel_entry_ht = NULL; /* accel_path -> AccelEntry */
static GSList *accel_filters = NULL;
/* --- functions --- */
static guint
accel_entry_hash (gconstpointer key)
{
const AccelEntry *entry = key;
return g_str_hash (entry->accel_path);
}
static gboolean
accel_entry_equal (gconstpointer key1,
gconstpointer key2)
{
const AccelEntry *entry1 = key1;
const AccelEntry *entry2 = key2;
return g_str_equal (entry1->accel_path, entry2->accel_path);
}
static inline AccelEntry*
accel_path_lookup (const gchar *accel_path)
{
AccelEntry ekey;
ekey.accel_path = accel_path;
/* safety NULL check for return_if_fail()s */
return accel_path ? g_hash_table_lookup (accel_entry_ht, &ekey) : NULL;
}
void
_gtk_accel_map_init (void)
{
g_assert (accel_entry_ht == NULL);
accel_entry_ht = g_hash_table_new (accel_entry_hash, accel_entry_equal);
}
static gboolean
gtk_accel_path_is_valid (const gchar *accel_path)
{
gchar *p;
if (!accel_path || accel_path[0] != '<' ||
accel_path[1] == '<' || accel_path[1] == '>' || !accel_path[1])
return FALSE;
p = strchr (accel_path, '>');
if (!p || p[1] != '/')
return FALSE;
return TRUE;
}
/**
* gtk_accel_map_add_entry
* @accel_path: valid accelerator path
* @accel_key: the accelerator key
* @accel_mods: the accelerator modifiers
* @returns: the GQuark for the @accel_path (to ease local storage)
*
* Register a new accelerator with the global accelerator map.
* This function should only be called once per @accel_path
* with the canonical @accel_key and @accel_mods for this path.
* To change the accelerator during runtime programatically, use
* gtk_accel_map_change_entry().
* The accelerator path must consist of "<WINDOWTYPE>/Category1/Category2/.../Action",
* where WINDOWTYPE should be a unique application specifc identifier, that
* corresponds to the kind of window the accelerator is being used in, e.g. "Gimp-Image",
* "Abiword-Document" or "Gnumeric-Settings".
* The Category1/.../Action portion is most apropriately choosen by the action the
* accelerator triggers, i.e. for accelerators on menu items, choose the item's menu path,
* e.g. "File/Save As", "Image/View/Zoom" or "Edit/Select All".
* So a full valid accelerator path may look like:
* "<Gimp-Toolbox>/File/Dialogs/Tool Options...".
*/
GQuark
gtk_accel_map_add_entry (const gchar *accel_path,
guint accel_key,
guint accel_mods)
{
AccelEntry *entry;
g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
accel_mods &= gtk_accelerator_get_default_mod_mask ();
entry = accel_path_lookup (accel_path);
if (entry)
{
if (!entry->std_accel_key && !entry->std_accel_mods &&
(accel_key || accel_mods))
{
entry->std_accel_key = accel_key;
entry->std_accel_mods = accel_mods;
if (!entry->changed)
gtk_accel_map_change_entry (entry->accel_path, accel_key, accel_mods, TRUE);
}
}
else
{
entry = g_new0 (AccelEntry, 1);
entry->accel_path = g_quark_to_string (g_quark_from_string (accel_path));
entry->std_accel_key = accel_key;
entry->std_accel_mods = accel_mods;
entry->accel_key = accel_key;
entry->accel_mods = accel_mods;
entry->changed = FALSE;
g_hash_table_insert (accel_entry_ht, entry, entry);
}
return g_quark_try_string (entry->accel_path);
}
typedef struct {
GHook hook;
GtkAccelGroup *accel_group;
} AccelHook;
static void
accel_hook_finalize (GHookList *hook_list,
GHook *hook)
{
GDestroyNotify destroy = hook->destroy;
AccelHook *ahook = (AccelHook*) hook;
if (ahook->accel_group)
g_object_unref (ahook->accel_group);
if (destroy)
{
hook->destroy = NULL;
destroy (hook->data);
}
}
/**
* GtkAccelMapNotify
* @data: notifier user data
* @accel_path_quark: accelerator path (as #GQuark) which has just changed
* @accel_key: new accelerator key
* @accel_mods: new accelerator modifiers
* @accel_group: accelerator group of this notifier
* @old_accel_key: former accelerator key
* @old_accel_mods): former accelerator modifiers
*
* #GtkAccelMapNotify is the signature of user callbacks, installed via
* gtk_accel_map_add_notifier(). Once the accel path of the notifier changes,
* the notifier is invoked with this signature, where @accel_path_quark
* indicates the accel path that changed, and @data and @accel_group are
* the notifier's arguments as passed into gtk_accel_map_add_notifier().
*/
/**
* gtk_accel_map_add_notifer
* @accel_path: valid accelerator path
* @notify_data: data argument to the notifier
* @notify_func: the notifier function
* @accel_group: accelerator group used by the notifier function
*
* Install a notifier function to be called if an accelerator
* map entry changes. @accel_group has to be the accel group
* that is being affected (gets an accelerator removed or added,
* when the notifier function is executed).
*/
void
gtk_accel_map_add_notifer (const gchar *accel_path,
gpointer notify_data,
GtkAccelMapNotify notify_func,
GtkAccelGroup *accel_group)
{
AccelEntry *entry;
AccelHook *ahook;
GHook *hook;
g_return_if_fail (gtk_accel_path_is_valid (accel_path));
g_return_if_fail (notify_func != NULL);
if (accel_group)
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
entry = accel_path_lookup (accel_path);
if (!entry)
{
gtk_accel_map_add_entry (accel_path, 0, 0);
entry = accel_path_lookup (accel_path);
}
if (!entry->hooks)
{
entry->hooks = g_new (GHookList, 1);
g_hook_list_init (entry->hooks, sizeof (AccelHook));
entry->hooks->finalize_hook = accel_hook_finalize;
}
hook = g_hook_alloc (entry->hooks);
hook->data = notify_data;
hook->func = notify_func;
hook->destroy = NULL;
ahook = (AccelHook*) hook;
ahook->accel_group = accel_group ? g_object_ref (accel_group) : NULL;
g_hook_append (entry->hooks, hook);
}
/**
* gtk_accel_map_remove_notifer
* @accel_path: valid accelerator path
* @notify_data: data argument to the notifier
* @notify_func: the notifier function
*
* Remove a notifier function, previously installed through
* gtk_accel_map_add_notifer().
*/
void
gtk_accel_map_remove_notifer (const gchar *accel_path,
gpointer notify_data,
GtkAccelMapNotify notify_func)
{
AccelEntry *entry;
g_return_if_fail (gtk_accel_path_is_valid (accel_path));
g_return_if_fail (notify_func != NULL);
entry = accel_path_lookup (accel_path);
if (entry && entry->hooks)
{
GHook *hook = g_hook_find_func_data (entry->hooks, TRUE, notify_func, notify_data);
if (hook && g_hook_destroy (entry->hooks, hook->hook_id))
return; /* successfully removed */
}
g_warning (G_STRLOC ": no notifier %p(%p) installed for accel path \"%s\"",
notify_func, notify_data, accel_path);
}
/**
* gtk_accel_map_lookup_entry
* @accel_path: valid accelerator path
* @key: accelerator key to be filled in (optional)
* @returns: #GQuark for @accel_path or (0) if @accel_path is not known
*
* Lookup the accelerator entry for @accel_path and fill in @key.
* If the lookup revealed no results, (0) is returned, the entry's
* #GQuark otherwise.
*/
GQuark
gtk_accel_map_lookup_entry (const gchar *accel_path,
GtkAccelKey *key)
{
AccelEntry *entry;
g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
entry = accel_path_lookup (accel_path);
if (entry && key)
{
key->accel_key = entry->accel_key;
key->accel_mods = entry->accel_mods;
key->accel_flags = 0; // FIXME: global lock?
}
return entry ? g_quark_try_string (entry->accel_path) : 0;
}
static void
hash2slist_foreach (gpointer key,
gpointer value,
gpointer user_data)
{
GSList **slist_p = user_data;
*slist_p = g_slist_prepend (*slist_p, value);
}
static GSList*
g_hash_table_slist_values (GHashTable *hash_table)
{
GSList *slist = NULL;
g_return_val_if_fail (hash_table != NULL, NULL);
g_hash_table_foreach (hash_table, hash2slist_foreach, &slist);
return slist;
}
static gboolean
internal_change_entry (const gchar *accel_path,
guint accel_key,
GdkModifierType accel_mods,
gboolean replace,
gboolean simulate)
{
GSList *node, *slist, *win_list, *group_list, *replace_list = NULL;
GHashTable *group_hm, *win_hm;
gboolean change_accel, removable, can_change = TRUE, seen_accel = FALSE, hooks_may_recurse = TRUE;
GQuark entry_quark;
GHook *hook;
AccelEntry *entry = accel_path_lookup (accel_path);
/* not much todo if there's no entry yet */
if (!entry)
{
if (!simulate)
{
gtk_accel_map_add_entry (accel_path, 0, 0);
entry = accel_path_lookup (accel_path);
entry->accel_key = accel_key;
entry->accel_mods = accel_mods;
entry->changed = TRUE;
}
return TRUE;
}
/* if there's nothing to change, not much todo either */
if (entry->accel_key == accel_key && entry->accel_mods == accel_mods)
return FALSE;
/* nobody's interested, easy going */
if (!entry->hooks)
{
if (!simulate)
{
entry->accel_key = accel_key;
entry->accel_mods = accel_mods;
entry->changed = TRUE;
}
return TRUE;
}
/* 1) fetch all accel groups affected by this entry */
entry_quark = g_quark_try_string (entry->accel_path);
group_hm = g_hash_table_new (NULL, NULL);
win_hm = g_hash_table_new (NULL, NULL);
hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
while (hook)
{
AccelHook *ahook = (AccelHook*) hook;
if (ahook->accel_group)
g_hash_table_insert (group_hm, ahook->accel_group, ahook->accel_group);
hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
}
/* 2) collect acceleratables affected */
group_list = g_hash_table_slist_values (group_hm);
for (slist = group_list; slist; slist = slist->next)
{
GtkAccelGroup *group = slist->data;
for (node = group->acceleratables; node; node = node->next)
g_hash_table_insert (win_hm, node->data, node->data);
}
g_slist_free (group_list);
/* 3) include all accel groups used by acceleratables */
win_list = g_hash_table_slist_values (win_hm);
g_hash_table_destroy (win_hm);
for (slist = win_list; slist; slist = slist->next)
for (node = gtk_accel_groups_from_acceleratable (slist->data); node; node = node->next)
g_hash_table_insert (group_hm, node->data, node->data);
group_list = g_hash_table_slist_values (group_hm);
g_hash_table_destroy (group_hm);
/* 4) walk the acceleratables and figure whether they occupy accel_key&accel_mods */
for (slist = accel_key ? win_list : NULL; slist; slist = slist->next)
if (GTK_IS_WINDOW (slist->data)) /* bad kludge in lack of a GtkAcceleratable */
if (_gtk_window_query_nonaccels (slist->data, accel_key, accel_mods))
{
seen_accel = TRUE;
break;
}
removable = !seen_accel;
/* 5) walk all accel groups and search for locks */
for (slist = removable ? group_list : NULL; slist; slist = slist->next)
{
GtkAccelGroup *group = slist->data;
GtkAccelGroupEntry *ag_entry;
guint i, n;
n = 0;
ag_entry = entry->accel_key ? gtk_accel_group_query (group, entry->accel_key, entry->accel_mods, &n) : NULL;
for (i = 0; i < n; i++)
if (ag_entry[i].accel_path_quark == entry_quark)
{
can_change = !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
if (!can_change)
goto break_loop_step5;
}
n = 0;
ag_entry = accel_key ? gtk_accel_group_query (group, accel_key, accel_mods, &n) : NULL;
for (i = 0; i < n; i++)
{
seen_accel = TRUE;
removable = !group->lock_count && !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
if (!removable)
goto break_loop_step5;
if (ag_entry[i].accel_path_quark)
replace_list = g_slist_prepend (replace_list, GUINT_TO_POINTER (ag_entry->accel_path_quark));
}
}
break_loop_step5:
/* 6) check whether we can remove existing accelerators */
for (slist = removable ? replace_list : NULL; slist; slist = slist->next)
if (!internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, TRUE))
{
removable = FALSE;
break;
}
/* 7) check conditions and proceed if possible */
change_accel = can_change && (!seen_accel || (removable && replace));
if (change_accel && !simulate)
{
guint old_accel_key, old_accel_mods;
/* 8) remove existing accelerators */
for (slist = replace_list; slist; slist = slist->next)
internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, FALSE);
/* 9) install new accelerator */
old_accel_key = entry->accel_key;
old_accel_mods = entry->accel_mods;
entry->accel_key = accel_key;
entry->accel_mods = accel_mods;
entry->changed = TRUE;
hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
while (hook)
{
gboolean was_in_call, need_destroy = FALSE;
GtkAccelMapNotify hook_func = hook->func;
AccelHook *ahook = (AccelHook*) hook;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
/* need_destroy = */ hook_func (hook->data, g_quark_try_string (entry->accel_path),
entry->accel_key, entry->accel_mods,
ahook->accel_group,
old_accel_key, old_accel_mods);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
if (need_destroy)
g_hook_destroy_link (entry->hooks, hook);
hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
}
}
g_slist_free (replace_list);
g_slist_free (group_list);
g_slist_free (win_list);
return change_accel;
}
/**
* gtk_accel_map_change_entry
* @accel_path: valid accelerator path
* @accel_key: new accelerator key
* @accel_mods: new accelerator modifiers
* @replace: %TRUE if other accelerators may be deleted upon conflicts
* @returns: %TRUE if the accelerator could be changed, %FALSE otherwise
*
* Change the @accel_key and @accel_mods currently associated with @accel_path.
* Due to conflicts with other accelerators, a change may not alwys be possible,
* @replace indicates whether other accelerators may be deleted to resolve such
* conflicts. A change will only occour if all conflicts could be resolved (which
* might not be the case if conflicting accelerators are locked). Succesfull
* changes are indicated by a %TRUE return value.
* Changes occouring are also indicated by invocation of notifiers attached to
* @accel_path (see gtk_accel_map_add_notifer() on this) and other accelerators
* that are being deleted.
*/
gboolean
gtk_accel_map_change_entry (const gchar *accel_path,
guint accel_key,
GdkModifierType accel_mods,
gboolean replace)
{
g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), FALSE);
return internal_change_entry (accel_path, accel_key, accel_key ? accel_mods : 0, replace, FALSE);
}
static guint
accel_map_parse_accel_path (GScanner *scanner)
{
guint accel_key = 0, accel_mods = 0;
gchar *path, *accel;
/* parse accel path */
g_scanner_get_next_token (scanner);
if (scanner->token != G_TOKEN_STRING)
return G_TOKEN_STRING;
/* test if the next token is an accelerator */
g_scanner_peek_next_token (scanner);
if (scanner->next_token != G_TOKEN_STRING)
{
/* if not so, eat that token and error out */
g_scanner_get_next_token (scanner);
return G_TOKEN_STRING;
}
/* get the full accelerator specification */
path = g_strdup (scanner->value.v_string);
g_scanner_get_next_token (scanner);
accel = g_strdup (scanner->value.v_string);
/* ensure the entry is present */
gtk_accel_map_add_entry (path, 0, 0);
/* and propagate it */
gtk_accelerator_parse (accel, &accel_key, &accel_mods);
gtk_accel_map_change_entry (path, accel_key, accel_mods, TRUE);
g_free (accel);
g_free (path);
/* check correct statement end */
g_scanner_get_next_token (scanner);
if (scanner->token != ')')
return ')';
else
return G_TOKEN_NONE;
}
static void
accel_map_parse_statement (GScanner *scanner)
{
guint expected_token;
g_scanner_get_next_token (scanner);
if (scanner->token == G_TOKEN_SYMBOL)
{
guint (*parser_func) (GScanner*);
parser_func = scanner->value.v_symbol;
expected_token = parser_func (scanner);
}
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_accel_map_load_scanner (GScanner *scanner)
{
gboolean skip_comment_single;
gboolean symbol_2_token;
gchar *cpair_comment_single;
gpointer saved_symbol;
g_return_if_fail (scanner != 0);
/* configure scanner */
skip_comment_single = scanner->config->skip_comment_single;
scanner->config->skip_comment_single = TRUE;
cpair_comment_single = scanner->config->cpair_comment_single;
scanner->config->cpair_comment_single = ";\n";
symbol_2_token = scanner->config->symbol_2_token;
scanner->config->symbol_2_token = FALSE;
saved_symbol = g_scanner_lookup_symbol (scanner, "gtk_accel_path");
g_scanner_scope_add_symbol (scanner, 0, "gtk_accel_path", accel_map_parse_accel_path);
/* outer parsing loop
*/
g_scanner_peek_next_token (scanner);
while (scanner->next_token == '(')
{
g_scanner_get_next_token (scanner);
accel_map_parse_statement (scanner);
g_scanner_peek_next_token (scanner);
}
/* restore config */
scanner->config->skip_comment_single = skip_comment_single;
scanner->config->cpair_comment_single = cpair_comment_single;
scanner->config->symbol_2_token = symbol_2_token;
g_scanner_scope_remove_symbol (scanner, 0, "gtk_accel_path");
if (saved_symbol)
g_scanner_scope_add_symbol (scanner, 0, "gtk_accel_path", saved_symbol);
}
/**
* gtk_accel_map_load_fd
* @fd: valid readable file descriptor
*
* Filedescriptor variant of gtk_accel_map_load().
* Note that the file descriptor will not be closed by this function.
*/
void
gtk_accel_map_load_fd (gint fd)
{
GScanner *scanner;
g_return_if_fail (fd >= 0);
/* create and setup scanner */
scanner = g_scanner_new (NULL);
g_scanner_input_file (scanner, fd);
gtk_accel_map_load_scanner (scanner);
g_scanner_destroy (scanner);
}
/**
* gtk_accel_map_load
* @file_name: a file containing accelerator specifications
*
* Parses a file previously saved with gtk_accel_map_save() for
* accelerator specifications, and propagates them accordingly.
*/
void
gtk_accel_map_load (const gchar *file_name)
{
gint fd;
g_return_if_fail (file_name != NULL);
if (!g_file_test (file_name, G_FILE_TEST_IS_REGULAR))
return;
fd = open (file_name, O_RDONLY);
if (fd < 0)
return;
gtk_accel_map_load_fd (fd);
close (fd);
}
static void
accel_map_print (gpointer data,
const gchar *accel_path,
guint accel_key,
guint accel_mods,
gboolean changed)
{
GString *gstring = g_string_new (changed ? NULL : "; ");
gint err, fd = GPOINTER_TO_INT (data);
gchar *tmp, *name;
g_string_append (gstring, "(gtk_accel_path \"");
tmp = g_strescape (accel_path, NULL);
g_string_append (gstring, tmp);
g_free (tmp);
g_string_append (gstring, "\" \"");
name = gtk_accelerator_name (accel_key, accel_mods);
tmp = g_strescape (name, NULL);
g_free (name);
g_string_append (gstring, tmp);
g_free (tmp);
g_string_append (gstring, "\")\n");
do
err = write (fd, gstring->str, gstring->len);
while (err < 0 && errno == EINTR);
g_string_free (gstring, TRUE);
}
/**
* gtk_accel_map_save_fd
* @fd: valid writable file descriptor
*
* Filedescriptor variant of gtk_accel_map_save().
* Note that the file descriptor will not be closed by this function.
*/
void
gtk_accel_map_save_fd (gint fd)
{
GString *gstring;
gint err;
g_return_if_fail (fd >= 0);
gstring = g_string_new ("; ");
if (g_get_prgname ())
g_string_append (gstring, g_get_prgname ());
g_string_append (gstring, " GtkAccelMap rc-file -*- scheme -*-\n");
g_string_append (gstring, "; this file is an automated accelerator map dump\n");
g_string_append (gstring, ";\n");
do
err = write (fd, gstring->str, gstring->len);
while (err < 0 && errno == EINTR);
gtk_accel_map_foreach (GINT_TO_POINTER (fd), accel_map_print);
}
/**
* gtk_accel_map_save
* @file_name: the file to contain accelerator specifications
*
* Saves current accelerator specifications (accelerator path, key
* and modifiers) to @file_name.
* The file is written in a format suitable to be read back in by
* gtk_accel_map_load().
*/
void
gtk_accel_map_save (const gchar *file_name)
{
gint fd;
g_return_if_fail (file_name != NULL);
fd = open (file_name, O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (fd < 0)
return;
gtk_accel_map_save_fd (fd);
close (fd);
}
/**
* gtk_accel_map_foreach
* @data: data to be passed into @foreach_func
* @foreach_func: function to be executed for each accel map entry
*
* Loop over the entries in the accelerator map, and execute
* @foreach_func on each. The signature of @foreach_func is that of
* #GtkAccelMapForeach, the @changed parameter indicates whether
* this accelerator was changed during runtime (thus, would need
* saving during an accelerator map dump).
*/
void
gtk_accel_map_foreach (gpointer data,
GtkAccelMapForeach foreach_func)
{
GSList *entries, *slist, *node;
g_return_if_fail (foreach_func != NULL);
entries = g_hash_table_slist_values (accel_entry_ht);
for (slist = entries; slist; slist = slist->next)
{
AccelEntry *entry = slist->data;
gboolean changed = entry->accel_key != entry->std_accel_key || entry->accel_mods != entry->std_accel_mods;
for (node = accel_filters; node; node = node->next)
if (g_pattern_match_string (node->data, entry->accel_path))
goto skip_accel;
foreach_func (data, entry->accel_path, entry->accel_key, entry->accel_mods, changed);
skip_accel:
}
g_slist_free (entries);
}
void
gtk_accel_map_foreach_unfiltered (gpointer data,
GtkAccelMapForeach foreach_func)
{
GSList *entries, *slist;
g_return_if_fail (foreach_func != NULL);
entries = g_hash_table_slist_values (accel_entry_ht);
for (slist = entries; slist; slist = slist->next)
{
AccelEntry *entry = slist->data;
gboolean changed = entry->accel_key != entry->std_accel_key || entry->accel_mods != entry->std_accel_mods;
foreach_func (data, entry->accel_path, entry->accel_key, entry->accel_mods, changed);
}
g_slist_free (entries);
}
void
gtk_accel_map_add_filter (const gchar *filter_pattern)
{
GPatternSpec *pspec;
GSList *slist;
g_return_if_fail (filter_pattern != NULL);
pspec = g_pattern_spec_new (filter_pattern);
for (slist = accel_filters; slist; slist = slist->next)
if (g_pattern_spec_equal (pspec, slist->data))
{
g_pattern_spec_free (pspec);
return;
}
accel_filters = g_slist_prepend (accel_filters, pspec);
}

81
gtk/gtkaccelmap.h Normal file
View File

@ -0,0 +1,81 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1998, 2001 Tim Janik
*
* This library is free software; you can redistribute it and/or
* 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
* Lesser General Public License for more details.
*
* 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.
*/
#ifndef __GTK_ACCEL_MAP_H__
#define __GTK_ACCEL_MAP_H__
#include <gtk/gtkaccelgroup.h>
G_BEGIN_DECLS
/* --- notifier --- */
typedef void (*GtkAccelMapNotify) (gpointer data,
GQuark accel_path_quark,
guint accel_key,
guint accel_mods,
GtkAccelGroup *accel_group,
guint old_accel_key,
guint old_accel_mods);
typedef void (*GtkAccelMapForeach) (gpointer data,
const gchar *accel_path,
guint accel_key,
guint accel_mods,
gboolean changed);
/* --- public API --- */
GQuark gtk_accel_map_add_entry (const gchar *accel_path,
guint accel_key,
guint accel_mods);
void gtk_accel_map_add_notifer (const gchar *accel_path,
gpointer notify_data,
GtkAccelMapNotify notify_func,
GtkAccelGroup *accel_group);
void gtk_accel_map_remove_notifer (const gchar *accel_path,
gpointer notify_data,
GtkAccelMapNotify notify_func);
GQuark gtk_accel_map_lookup_entry (const gchar *accel_path,
GtkAccelKey *key);
gboolean gtk_accel_map_change_entry (const gchar *accel_path,
guint accel_key,
GdkModifierType accel_mods,
gboolean replace);
void gtk_accel_map_load (const gchar *file_name);
void gtk_accel_map_save (const gchar *file_name);
void gtk_accel_map_foreach (gpointer data,
GtkAccelMapForeach foreach_func);
void gtk_accel_map_load_fd (gint fd);
void gtk_accel_map_load_scanner (GScanner *scanner);
void gtk_accel_map_save_fd (gint fd);
/* --- filter functions --- */
void gtk_accel_map_add_filter (const gchar *filter_pattern);
void gtk_accel_map_foreach_unfilterd (gpointer data,
GtkAccelMapForeach foreach_func);
/* --- internal API --- */
void _gtk_accel_map_init (void);
G_END_DECLS
#endif /* __GTK_ACCEL_MAP_H__ */

View File

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

View File

@ -79,11 +79,7 @@ struct _GtkItemFactoryClass
{
GtkObjectClass object_class;
gchar *cpair_comment_single;
GHashTable *item_ht;
gpointer dummy;
};
struct _GtkItemFactoryEntry
@ -122,12 +118,6 @@ struct _GtkItemFactoryEntry
struct _GtkItemFactoryItem
{
gchar *path;
guint accelerator_key;
guint accelerator_mods;
guint modified : 1;
guint in_propagation : 1;
gchar *dummy;
GSList *widgets;
};
@ -147,9 +137,6 @@ void gtk_item_factory_construct (GtkItemFactory *ifactory,
/* These functions operate on GtkItemFactoryClass basis.
*/
void gtk_item_factory_parse_rc (const gchar *file_name);
void gtk_item_factory_parse_rc_string (const gchar *rc_string);
void gtk_item_factory_parse_rc_scanner (GScanner *scanner);
void gtk_item_factory_add_foreign (GtkWidget *accel_widget,
const gchar *full_path,
GtkAccelGroup *accel_group,
@ -168,19 +155,6 @@ GtkWidget* gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory,
GtkWidget* gtk_item_factory_get_item_by_action (GtkItemFactory *ifactory,
guint action);
/* If `path_pspec' is passed as `NULL', this function will iterate over
* all hash entries. otherwise only those entries will be dumped for which
* the pattern matches, e.g. "<Image>*...".
*/
void gtk_item_factory_dump_items (GPatternSpec *path_pspec,
gboolean modified_only,
GtkPrintFunc print_func,
gpointer func_data);
void gtk_item_factory_dump_rc (const gchar *file_name,
GPatternSpec *path_pspec,
gboolean modified_only);
void gtk_item_factory_print_func (gpointer FILE_pointer,
const gchar *string);
void gtk_item_factory_create_item (GtkItemFactory *ifactory,
GtkItemFactoryEntry *entry,
gpointer callback_data,

View File

@ -47,6 +47,7 @@
#include <pango/pango-utils.h> /* For pango_split_file_list */
#include "gtkaccelmap.h"
#include "gtkdnd.h"
#include "gtkversion.h"
#include "gtkmain.h"
@ -625,9 +626,9 @@ gtk_init_check (int *argc,
gtk_colormap = gdk_colormap_get_system ();
gtk_type_init (0);
_gtk_accel_map_init ();
_gtk_rc_init ();
/* Register an exit function to make sure we are able to cleanup.
*/
g_atexit (gtk_exit_func);

View File

@ -24,6 +24,7 @@
BOOLEAN:BOXED
BOOLEAN:BOXED,BOXED
BOOLEAN:ENUM
BOOLEAN:OBJECT,UINT,UINT
BOOLEAN:OBJECT,INT,INT,UINT
BOOLEAN:OBJECT,STRING,STRING,BOXED
BOOLEAN:OBJECT,BOXED,BOXED
@ -78,7 +79,9 @@ VOID:POINTER,UINT
VOID:STRING
VOID:STRING,STRING
VOID:STRING,INT,POINTER
VOID:UINT,UINT
VOID:UINT,UINT,BOXED
VOID:UINT,STRING
VOID:UINT,BOXED,UINT,FLAGS,FLAGS
VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
VOID:UINT,STRING
VOID:VOID

View File

@ -24,6 +24,7 @@
BOOLEAN:BOXED
BOOLEAN:BOXED,BOXED
BOOLEAN:ENUM
BOOLEAN:OBJECT,UINT,UINT
BOOLEAN:OBJECT,INT,INT,UINT
BOOLEAN:OBJECT,STRING,STRING,BOXED
BOOLEAN:OBJECT,BOXED,BOXED
@ -78,7 +79,9 @@ VOID:POINTER,UINT
VOID:STRING
VOID:STRING,STRING
VOID:STRING,INT,POINTER
VOID:UINT,UINT
VOID:UINT,UINT,BOXED
VOID:UINT,STRING
VOID:UINT,BOXED,UINT,FLAGS,FLAGS
VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
VOID:UINT,STRING
VOID:VOID

View File

@ -27,6 +27,7 @@
#include <ctype.h>
#include <string.h> /* memset */
#include "gdk/gdkkeysyms.h"
#include "gtkaccelmap.h"
#include "gtkbindings.h"
#include "gtklabel.h"
#include "gtkmain.h"
@ -76,6 +77,7 @@ static void gtk_menu_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gtk_menu_destroy (GtkObject *object);
static void gtk_menu_finalize (GObject *object);
static void gtk_menu_realize (GtkWidget *widget);
static void gtk_menu_unrealize (GtkWidget *widget);
static void gtk_menu_size_request (GtkWidget *widget,
@ -83,6 +85,7 @@ static void gtk_menu_size_request (GtkWidget *widget,
static void gtk_menu_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_menu_paint (GtkWidget *widget);
static void gtk_menu_show (GtkWidget *widget);
static gboolean gtk_menu_expose (GtkWidget *widget,
GdkEventExpose *event);
static gboolean gtk_menu_key_press (GtkWidget *widget,
@ -161,21 +164,16 @@ gtk_menu_get_type (void)
static void
gtk_menu_class_init (GtkMenuClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
GtkMenuShellClass *menu_shell_class;
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
GtkMenuShellClass *menu_shell_class = GTK_MENU_SHELL_CLASS (class);
GtkBindingSet *binding_set;
gobject_class = (GObjectClass*) class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
container_class = (GtkContainerClass*) class;
menu_shell_class = (GtkMenuShellClass*) class;
parent_class = gtk_type_class (gtk_menu_shell_get_type ());
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_menu_finalize;
gobject_class->set_property = gtk_menu_set_property;
gobject_class->get_property = gtk_menu_get_property;
@ -192,6 +190,7 @@ gtk_menu_class_init (GtkMenuClass *class)
widget_class->unrealize = gtk_menu_unrealize;
widget_class->size_request = gtk_menu_size_request;
widget_class->size_allocate = gtk_menu_size_allocate;
widget_class->show = gtk_menu_show;
widget_class->expose_event = gtk_menu_expose;
widget_class->key_press_event = gtk_menu_key_press;
widget_class->motion_notify_event = gtk_menu_motion_notify;
@ -388,8 +387,6 @@ gtk_menu_destroy (GtkObject *object)
gtk_menu_stop_navigating_submenu (menu);
gtk_menu_set_accel_group (menu, NULL);
if (menu->old_active_menu_item)
{
gtk_widget_unref (menu->old_active_menu_item);
@ -403,6 +400,12 @@ gtk_menu_destroy (GtkObject *object)
gtk_object_ref (object);
}
if (menu->accel_group)
{
g_object_unref (menu->accel_group);
menu->accel_group = NULL;
}
if (menu->toplevel)
gtk_widget_destroy (menu->toplevel);
if (menu->tearoff_window)
@ -411,6 +414,15 @@ gtk_menu_destroy (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gtk_menu_finalize (GObject *object)
{
GtkMenu *menu = GTK_MENU (object);
g_free (menu->accel_path);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
void
gtk_menu_attach_to_widget (GtkMenu *menu,
@ -828,6 +840,7 @@ gtk_menu_set_accel_group (GtkMenu *menu,
menu->accel_group = accel_group;
if (menu->accel_group)
gtk_accel_group_ref (menu->accel_group);
_gtk_menu_refresh_accel_paths (menu, TRUE);
}
}
@ -839,6 +852,76 @@ gtk_menu_get_accel_group (GtkMenu *menu)
return menu->accel_group;
}
/**
* gtk_menu_set_accel_path
* @menu: a valid #GtkMenu
* @accel_path: a valid accelerator path
*
* Sets an accelerator path for this menu from which accelerator paths
* for its immediate children, its menu items, can be constructed.
* The main purpose of this function is to spare the programmer the
* inconvenience of having to call gtk_menu_item_set_accel_path() on
* each menu item that should support runtime user changable accelerators.
* Instead, by just calling gtk_menu_set_accel_path() on their parent,
* each menu item of this menu, that contains a label describing its purpose,
* automatically gets an accel path assigned. For example, a menu containing
* menu items "New" and "Exit", will, after gtk_menu_set_accel_path (menu,
* "<Gnumeric-Sheet>/File"); has been called, assign its items the accel paths:
* "<Gnumeric-Sheet>/File/New" and "<Gnumeric-Sheet>/File/Exit".
* Assigning accel paths to menu items then enables the user to change
* their accelerators at runtime. More details about accelerator paths
* and their default setups can be found at gtk_accel_map_add_entry().
*/
void
gtk_menu_set_accel_path (GtkMenu *menu,
const gchar *accel_path)
{
g_return_if_fail (GTK_IS_MENU (menu));
if (accel_path)
g_return_if_fail (accel_path[0] == '<' && strchr (accel_path, '/')); /* simplistic check */
g_free (menu->accel_path);
menu->accel_path = g_strdup (accel_path);
if (menu->accel_path)
_gtk_menu_refresh_accel_paths (menu, FALSE);
}
typedef struct {
GtkMenu *menu;
gboolean group_changed;
} AccelPropagation;
static void
refresh_accel_paths_froeach (GtkWidget *widget,
gpointer data)
{
AccelPropagation *prop = data;
if (GTK_IS_MENU_ITEM (widget)) /* should always be true */
_gtk_menu_item_refresh_accel_path (GTK_MENU_ITEM (widget),
prop->menu->accel_path,
prop->menu->accel_group,
prop->group_changed);
}
void
_gtk_menu_refresh_accel_paths (GtkMenu *menu,
gboolean group_changed)
{
g_return_if_fail (GTK_IS_MENU (menu));
if (menu->accel_path && menu->accel_group)
{
AccelPropagation prop;
prop.menu = menu;
prop.group_changed = group_changed;
gtk_container_foreach (GTK_CONTAINER (menu),
refresh_accel_paths_froeach,
&prop);
}
}
void
gtk_menu_reposition (GtkMenu *menu)
{
@ -1480,20 +1563,33 @@ gtk_menu_expose (GtkWidget *widget,
return FALSE;
}
static void
gtk_menu_show (GtkWidget *widget)
{
GtkMenu *menu = GTK_MENU (widget);
_gtk_menu_refresh_accel_paths (menu, FALSE);
GTK_WIDGET_CLASS (parent_class)->show (widget);
}
static gboolean
gtk_menu_key_press (GtkWidget *widget,
GdkEventKey *event)
{
GtkMenuShell *menu_shell;
GtkMenu *menu;
GtkAccelGroup *accel_group;
gboolean delete = FALSE;
gchar *accel = NULL;
guint accel_key, accel_mods;
g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
menu_shell = GTK_MENU_SHELL (widget);
menu = GTK_MENU (widget);
accel_group = gtk_menu_get_accel_group (menu);
gtk_menu_stop_navigating_submenu (menu);
@ -1543,58 +1639,50 @@ gtk_menu_key_press (GtkWidget *widget,
break;
}
accel_key = event->keyval;
accel_mods = event->state & gtk_accelerator_get_default_mod_mask ();
/* Modify the accelerators */
if (menu_shell->active_menu_item &&
GTK_BIN (menu_shell->active_menu_item)->child &&
GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL &&
!gtk_widget_accelerators_locked (menu_shell->active_menu_item) &&
GTK_BIN (menu_shell->active_menu_item)->child && /* no seperators */
GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL && /* no submenus */
(delete ||
(gtk_accelerator_valid (event->keyval, event->state) &&
(event->state ||
(event->keyval >= GDK_F1 && event->keyval <= GDK_F35)))))
(accel_mods ||
(accel_key >= GDK_F1 && accel_key <= GDK_F35)))))
{
GtkMenuItem *menu_item;
GtkAccelGroup *accel_group;
menu_item = GTK_MENU_ITEM (menu_shell->active_menu_item);
if (!GTK_MENU (widget)->accel_group)
accel_group = gtk_accel_group_get_default ();
else
accel_group = GTK_MENU (widget)->accel_group;
gtk_widget_remove_accelerators (GTK_WIDGET (menu_item),
gtk_signal_name (menu_item->accelerator_signal),
TRUE);
if (!delete &&
0 == gtk_widget_accelerator_signal (GTK_WIDGET (menu_item),
accel_group,
event->keyval,
event->state))
GtkWidget *menu_item = menu_shell->active_menu_item;
gboolean replace_accels = TRUE;
const gchar *path;
path = _gtk_widget_get_accel_path (menu_item);
if (!path)
{
GSList *slist;
slist = gtk_accel_group_entries_from_object (G_OBJECT (menu_item));
while (slist)
/* can't change accelerators on menu_items without paths
* (basically, those items are accelerator-locked).
*/
/* g_print("item has no path, menu prefix: %s\n", menu->accel_path); */
gdk_beep ();
}
else
{
gboolean changed;
if (delete)
{
GtkAccelEntry *ac_entry;
ac_entry = slist->data;
if (ac_entry->signal_id == menu_item->accelerator_signal)
break;
slist = slist->next;
accel_key = 0;
accel_mods = 0;
}
changed = gtk_accel_map_change_entry (path, accel_key, accel_mods, replace_accels);
if (!changed)
{
/* we failed, probably because this key is in use and
* locked already
*/
/* g_print("failed to change\n"); */
gdk_beep ();
}
if (!slist)
gtk_widget_add_accelerator (GTK_WIDGET (menu_item),
gtk_signal_name (menu_item->accelerator_signal),
accel_group,
event->keyval,
event->state,
GTK_ACCEL_VISIBLE);
}
}

View File

@ -64,6 +64,7 @@ struct _GtkMenu
GtkWidget *old_active_menu_item;
GtkAccelGroup *accel_group;
gchar *accel_path;
GtkMenuPositionFunc position_func;
gpointer position_func_data;
@ -146,7 +147,10 @@ void gtk_menu_set_active (GtkMenu *menu,
void gtk_menu_set_accel_group (GtkMenu *menu,
GtkAccelGroup *accel_group);
GtkAccelGroup* gtk_menu_get_accel_group (GtkMenu *menu);
void gtk_menu_set_accel_path (GtkMenu *menu,
const gchar *accel_path);
void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
gboolean group_changed);
/* A reference count is kept for a widget when it is attached to
* a particular widget. This is typically a menu item; it may also

View File

@ -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;
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);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
item_class = (GtkItemClass*) 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
@ -897,6 +904,107 @@ gtk_menu_item_hide_all (GtkWidget *widget)
gtk_widget_hide_all (menu_item->submenu);
}
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,
@ -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);
}

View File

@ -54,9 +54,9 @@ struct _GtkMenuItem
GtkWidget *submenu;
guint accelerator_signal;
guint16 toggle_size;
guint16 accelerator_width;
gchar *accel_path;
guint show_submenu_indicator : 1;
guint submenu_placement : 1;
@ -106,6 +106,13 @@ void gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
void gtk_menu_item_set_right_justified (GtkMenuItem *menu_item,
gboolean right_justified);
gboolean gtk_menu_item_get_right_justified (GtkMenuItem *menu_item);
void gtk_menu_item_set_accel_path (GtkMenuItem *menu_item,
const gchar *accel_path);
void _gtk_menu_item_refresh_accel_path (GtkMenuItem *menu_item,
const gchar *prefix,
GtkAccelGroup *accel_group,
gboolean group_changed);
#ifndef GTK_DISABLE_DEPRECATED
#define gtk_menu_item_right_justify(menu_item) gtk_menu_item_set_right_justified ((menu_item), TRUE)

View File

@ -3540,7 +3540,6 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook,
gtk_widget_show (page->menu_label);
menu_item = gtk_menu_item_new ();
gtk_widget_lock_accelerators (menu_item);
gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
gtk_menu_shell_insert (GTK_MENU_SHELL (notebook->menu), menu_item,
gtk_notebook_real_page_position (notebook, list));

View File

@ -399,8 +399,17 @@ _gtk_settings_parse_convert (GtkRcPropertyParser parser,
if (free_gstring)
g_string_free (gstring, TRUE);
}
else if (!G_VALUE_HOLDS (src_value, G_TYPE_GSTRING) &&
g_value_type_transformable (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)))
else if (G_VALUE_HOLDS (src_value, G_TYPE_GSTRING))
{
if (G_VALUE_HOLDS (dest_value, G_TYPE_STRING))
{
GString *gstring = g_value_get_boxed (src_value);
g_value_set_string (dest_value, gstring ? gstring->str : NULL);
success = !g_param_value_validate (pspec, dest_value);
}
}
else if (g_value_type_transformable (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)))
success = g_param_value_convert (pspec, src_value, dest_value, TRUE);
return success;
@ -420,7 +429,7 @@ apply_queued_setting (GtkSettings *data,
g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
else
{
gchar *debug = g_strdup_value_contents (&tmp_value);
gchar *debug = g_strdup_value_contents (&qvalue->value);
g_message ("%s: failed to retrieve property `%s' of type `%s' from rc file value \"%s\" of type `%s'",
qvalue->origin,
@ -519,7 +528,7 @@ _gtk_rc_property_parser_from_type (GType type)
void
gtk_settings_install_property (GParamSpec *pspec)
{
GtkRcPropertyParser parser = NULL;
GtkRcPropertyParser parser;
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
@ -549,9 +558,9 @@ free_value (gpointer data)
}
void
gtk_settings_set_property_value (GtkSettings *settings,
const gchar *prop_name,
const GtkSettingsValue *new_value)
gtk_settings_set_property_value (GtkSettings *settings,
const gchar *prop_name,
const GtkSettingsValue *new_value)
{
GtkSettingsValue *qvalue;
GParamSpec *pspec;
@ -909,7 +918,6 @@ gtk_rc_property_parse_border (const GParamSpec *pspec,
return success;
}
void
_gtk_settings_handle_event (GdkEventSetting *event)
{

View File

@ -43,7 +43,7 @@ gtk_signal_newv (const gchar *name,
g_return_val_if_fail (n_params < SIGNAL_MAX_PARAMS, 0);
closure = g_signal_type_cclosure_new (object_type, function_offset);
closure = function_offset ? g_signal_type_cclosure_new (object_type, function_offset) : 0;
return g_signal_newv (name, object_type, signal_flags, closure, NULL, NULL, marshaller, return_val, n_params, params);
}

View File

@ -28,6 +28,7 @@
#include <string.h>
#include <locale.h>
#include "gtkcontainer.h"
#include "gtkaccelmap.h"
#include "gtkiconfactory.h"
#include "gtkintl.h"
#include "gtkmain.h"
@ -69,8 +70,6 @@ enum {
DIRECTION_CHANGED,
GRAB_NOTIFY,
CHILD_NOTIFY,
ADD_ACCELERATOR,
REMOVE_ACCELERATOR,
MNEMONIC_ACTIVATE,
GRAB_FOCUS,
FOCUS,
@ -114,6 +113,7 @@ enum {
WINDOW_STATE_EVENT,
POPUP_MENU,
SHOW_HELP,
ACCEL_CLOSURES_CHANGED,
LAST_SIGNAL
};
@ -230,6 +230,8 @@ static GParamSpecPool *style_property_spec_pool = NULL;
static GQuark quark_property_parser = 0;
static GQuark quark_aux_info = 0;
static GQuark quark_accel_path = 0;
static GQuark quark_accel_closures = 0;
static GQuark quark_event_mask = 0;
static GQuark quark_extension_event_mode = 0;
static GQuark quark_parent_window = 0;
@ -299,6 +301,8 @@ gtk_widget_class_init (GtkWidgetClass *klass)
quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
@ -341,8 +345,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->direction_changed = gtk_widget_direction_changed;
klass->grab_notify = NULL;
klass->child_notify = NULL;
klass->add_accelerator = (void*) gtk_accel_group_handle_add;
klass->remove_accelerator = (void*) gtk_accel_group_handle_remove;
klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
klass->grab_focus = gtk_widget_real_grab_focus;
klass->focus = gtk_widget_real_focus;
@ -620,12 +622,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
g_cclosure_marshal_VOID__PARAM,
G_TYPE_NONE,
1, G_TYPE_PARAM);
widget_signals[ADD_ACCELERATOR] =
gtk_accel_group_create_add (GTK_CLASS_TYPE (object_class), GTK_RUN_LAST,
GTK_SIGNAL_OFFSET (GtkWidgetClass, add_accelerator));
widget_signals[REMOVE_ACCELERATOR] =
gtk_accel_group_create_remove (GTK_CLASS_TYPE (object_class), GTK_RUN_LAST,
GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator));
widget_signals[MNEMONIC_ACTIVATE] =
g_signal_new ("mnemonic_activate",
GTK_CLASS_TYPE (object_class),
@ -1020,6 +1016,13 @@ gtk_widget_class_init (GtkWidgetClass *klass)
GTK_SIGNAL_OFFSET (GtkWidgetClass, show_help),
gtk_marshal_NONE__ENUM,
GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET_HELP_TYPE);
widget_signals[ACCEL_CLOSURES_CHANGED] =
gtk_signal_new ("accel_closures_changed",
0,
GTK_CLASS_TYPE (object_class),
0,
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
@ -1035,7 +1038,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
"show_help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
GTK_WIDGET_HELP_TOOLTIP);
gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_SHIFT_MASK,
"show_help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
@ -2497,148 +2499,305 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
}
}
static void
gtk_widget_stop_add_accelerator (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
typedef struct {
GClosure closure;
guint signal_id;
} AccelClosure;
gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[ADD_ACCELERATOR]);
static void
closure_accel_activate (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
AccelClosure *aclosure = (AccelClosure*) closure;
if (GTK_WIDGET_IS_SENSITIVE (closure->data))
g_signal_emit (closure->data, aclosure->signal_id, 0);
/* we handled the accelerator */
g_value_set_boolean (return_value, TRUE);
}
static void
gtk_widget_stop_remove_accelerator (GtkWidget *widget)
closures_destroy (gpointer data)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
GSList *slist, *closures = data;
gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR]);
}
void
gtk_widget_lock_accelerators (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!gtk_widget_accelerators_locked (widget))
for (slist = closures; slist; slist = slist->next)
{
gtk_signal_connect (GTK_OBJECT (widget),
"add_accelerator",
GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
NULL);
gtk_signal_connect (GTK_OBJECT (widget),
"remove_accelerator",
GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
NULL);
g_closure_invalidate (slist->data);
g_closure_unref (slist->data);
}
g_slist_free (closures);
}
void
gtk_widget_unlock_accelerators (GtkWidget *widget)
static GClosure*
widget_new_accel_closure (GtkWidget *widget,
guint signal_id)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (gtk_widget_accelerators_locked (widget))
AccelClosure *aclosure;
GClosure *closure = NULL;
GSList *slist, *closures;
closures = g_object_steal_qdata (G_OBJECT (widget), quark_accel_closures);
for (slist = closures; slist; slist = slist->next)
if (!gtk_accel_group_from_accel_closure (slist->data))
{
/* reuse this closure */
closure = slist->data;
break;
}
if (!closure)
{
gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
NULL);
gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
NULL);
closure = g_closure_new_object (sizeof (AccelClosure), G_OBJECT (widget));
closures = g_slist_prepend (closures, g_closure_ref (closure));
g_closure_sink (closure);
g_closure_set_marshal (closure, closure_accel_activate);
}
}
gboolean
gtk_widget_accelerators_locked (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_object_set_qdata_full (G_OBJECT (widget), quark_accel_closures, closures, closures_destroy);
return gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
widget_signals[ADD_ACCELERATOR],
TRUE,
GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
NULL) > 0;
aclosure = (AccelClosure*) closure;
g_assert (closure->data == widget);
g_assert (closure->marshal == closure_accel_activate);
aclosure->signal_id = signal_id;
return closure;
}
/**
* gtk_widget_add_accelerator
* @widget: widget to install an accelerator on
* @accel_signal: widget signal to emit on accelerator actiavtion
* @accel_group: accel group for this widget, added to its toplevel
* @accel_key: GDK keyval of the accelerator
* @accel_mods: modifier key combination of the accelerator
* @accel_flags: flag accelerators, e.g. GTK_ACCEL_VISIBLE
*
* Install an accelerator for this @widget in @accel_group, that causes
* @accel_signal to be emitted if the accelerator is actiavted.
* The @accel_group needs to be added to the widget's toplevel via
* gtk_window_add_accel_group(), and the signal must be of type %G_RUN_ACTION.
* Accelerators added through this function are not user changable during
* runtime. If you want to support accelerators that can be changed by the
* user, use gtk_accel_map_add_entry() and gtk_menu_item_set_accel_path()
* instead.
*/
void
gtk_widget_add_accelerator (GtkWidget *widget,
const gchar *accel_signal,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods,
GtkAccelFlags accel_flags)
gtk_widget_add_accelerator (GtkWidget *widget,
const gchar *accel_signal,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods,
GtkAccelFlags accel_flags)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (accel_group != NULL);
GClosure *closure;
GSignalQuery query;
gtk_accel_group_add (accel_group,
accel_key,
accel_mods,
accel_flags,
(GObject*) widget,
accel_signal);
}
void
gtk_widget_remove_accelerator (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (accel_group != NULL);
gtk_accel_group_remove (accel_group,
accel_key,
accel_mods,
(GObject*) widget);
}
void
gtk_widget_remove_accelerators (GtkWidget *widget,
const gchar *accel_signal,
gboolean visible_only)
{
GSList *slist;
guint signal_id;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (accel_signal != NULL);
signal_id = gtk_signal_lookup (accel_signal, GTK_OBJECT_TYPE (widget));
g_return_if_fail (signal_id != 0);
slist = gtk_accel_group_entries_from_object (G_OBJECT (widget));
while (slist)
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query);
if (!query.signal_id ||
!(query.signal_flags & G_SIGNAL_ACTION) ||
query.return_type != G_TYPE_NONE ||
query.n_params)
{
GtkAccelEntry *ac_entry;
ac_entry = slist->data;
slist = slist->next;
if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE &&
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);
/* hmm, should be elaborate enough */
g_warning (G_STRLOC ": widget `%s' has no activatable signal \"%s\" without arguments",
G_OBJECT_TYPE_NAME (widget), accel_signal);
return;
}
closure = widget_new_accel_closure (widget, query.signal_id);
/* install the accelerator. since we don't map this onto an accel_path,
* the accelerator will automatically be locked.
*/
gtk_accel_group_connect (accel_group,
accel_key,
accel_mods,
accel_flags | GTK_ACCEL_LOCKED,
closure,
0);
g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
}
/**
* gtk_widget_remove_accelerator
* @widget: widget to install an accelerator on
* @accel_group: accel group for this widget
* @accel_key: GDK keyval of the accelerator
* @accel_mods: modifier key combination of the accelerator
* @returns: whether an accelerator was installed and could be removed
*
* Remove an accelerator from @widget, previously installed with
* gtk_widget_add_accelerator().
*/
gboolean
gtk_widget_remove_accelerator (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods)
{
GtkAccelGroupEntry *ag_entry;
GSList *slist;
guint n, i;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
for (slist = _gtk_widget_get_accel_closures (widget); slist; slist = slist->next)
{
/* paranoid sanity checking */
for (i = 0; i < n; i++)
if (slist->data == (gpointer) ag_entry[i].closure)
{
gboolean is_removed = gtk_accel_groups_disconnect_closure (slist->data);
g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
return is_removed;
}
}
g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
accel_key, accel_mods, accel_group,
G_OBJECT_TYPE_NAME (widget), widget);
return FALSE;
}
GSList*
_gtk_widget_get_accel_closures (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
return g_object_get_qdata (G_OBJECT (widget), quark_accel_closures);
}
typedef struct {
GtkWidget *widget;
GtkAccelGroup *accel_group;
const gchar *path;
GClosure *closure;
} AccelPath;
static void
accel_path_changed (gpointer data,
GQuark accel_path_quark,
guint accel_key,
guint accel_mods,
GtkAccelGroup *accel_group,
guint old_accel_key,
guint old_accel_mods)
{
AccelPath *apath = data;
gboolean notify = FALSE;
if (apath->closure)
{
/* the closure might have been removed already (due to replacements) */
gtk_accel_groups_disconnect_closure (apath->closure);
g_closure_unref (apath->closure);
apath->closure = NULL;
notify = TRUE;
}
if (accel_key)
{
apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
g_closure_ref (apath->closure);
/* need to specify path to get an unlocked accelerator */
gtk_accel_group_connect (apath->accel_group,
accel_key,
accel_mods,
GTK_ACCEL_VISIBLE,
apath->closure,
accel_path_quark);
notify = TRUE;
}
if (notify)
g_signal_emit (apath->widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
}
static void
destroy_accel_path (gpointer data)
{
AccelPath *apath = data;
/* stop notification */
gtk_accel_map_remove_notifer (apath->path, apath, accel_path_changed);
/* if the closure is currently connected, get rid of that connection */
if (apath->closure)
{
gtk_accel_groups_disconnect_closure (apath->closure);
g_closure_unref (apath->closure);
}
g_object_unref (apath->accel_group);
g_free (apath);
}
/* accel_group: the accel group used to activate this widget
* accel_path: the accel path, associating the accelerator
* to activate this widget
* set accel path through which this widget can be actiavated.
*/
void
_gtk_widget_set_accel_path (GtkWidget *widget,
const gchar *accel_path,
GtkAccelGroup *accel_group)
{
AccelPath *apath;
GtkAccelKey key;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
if (accel_path)
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
if (accel_path)
{
GQuark quark_path = gtk_accel_map_add_entry (accel_path, 0, 0);
if (!quark_path)
return; /* pathologic anyway */
apath = g_new (AccelPath, 1);
apath->widget = widget;
apath->accel_group = g_object_ref (accel_group);
apath->path = g_quark_to_string (quark_path);
apath->closure = NULL;
}
else
apath = NULL;
/* also removes possible old settings */
g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
if (apath)
{
/* setup accel path hooks to react to changes */
gtk_accel_map_add_notifer (apath->path, apath, accel_path_changed, apath->accel_group);
/* install accelerators for this path */
if (gtk_accel_map_lookup_entry (apath->path, &key))
accel_path_changed (apath, g_quark_try_string (apath->path), key.accel_key, key.accel_mods, NULL, 0, 0);
}
}
guint
gtk_widget_accelerator_signal (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods)
const gchar*
_gtk_widget_get_accel_path (GtkWidget *widget)
{
GtkAccelEntry *ac_entry;
AccelPath *apath;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
g_return_val_if_fail (accel_group != NULL, 0);
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods);
if (ac_entry && ac_entry->object == (GObject*) widget)
return ac_entry->signal_id;
return 0;
apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
return apath ? apath->path : NULL;
}
gboolean
@ -5361,6 +5520,10 @@ gtk_widget_real_destroy (GtkObject *object)
*/
widget = GTK_WIDGET (object);
/* wipe accelerator closures (keep order) */
g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
gtk_grab_remove (widget);
gtk_selection_remove_all (widget);

View File

@ -277,18 +277,6 @@ struct _GtkWidgetClass
void (* child_notify) (GtkWidget *widget,
GParamSpec *pspec);
/* accelerators */
void (* add_accelerator) (GtkWidget *widget,
guint accel_signal_id,
GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GtkAccelFlags accel_flags);
void (* remove_accelerator) (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods);
/* Mnemonics */
gboolean (* mnemonic_activate) (GtkWidget *widget,
gboolean group_cycling);
@ -496,20 +484,15 @@ void gtk_widget_add_accelerator (GtkWidget *widget,
guint accel_key,
guint accel_mods,
GtkAccelFlags accel_flags);
void gtk_widget_remove_accelerator (GtkWidget *widget,
gboolean gtk_widget_remove_accelerator (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods);
void gtk_widget_remove_accelerators (GtkWidget *widget,
const gchar *accel_signal,
gboolean visible_only);
guint gtk_widget_accelerator_signal (GtkWidget *widget,
GtkAccelGroup *accel_group,
guint accel_key,
guint accel_mods);
void gtk_widget_lock_accelerators (GtkWidget *widget);
void gtk_widget_unlock_accelerators (GtkWidget *widget);
gboolean gtk_widget_accelerators_locked (GtkWidget *widget);
void _gtk_widget_set_accel_path (GtkWidget *widget,
const gchar *accel_path,
GtkAccelGroup *accel_group);
const gchar* _gtk_widget_get_accel_path (GtkWidget *widget);
GSList* _gtk_widget_get_accel_closures (GtkWidget *widget);
gboolean gtk_widget_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
gboolean gtk_widget_event (GtkWidget *widget,

View File

@ -45,6 +45,7 @@ enum {
ACTIVATE_FOCUS,
ACTIVATE_DEFAULT,
MOVE_FOCUS,
ACCELS_CHANGED,
LAST_SIGNAL
};
@ -220,6 +221,7 @@ static void gtk_window_set_default_size_internal (GtkWindow *window,
static void gtk_window_realize_icon (GtkWindow *window);
static void gtk_window_unrealize_icon (GtkWindow *window);
static void gtk_window_notify_accels_changed (GtkWindow *window);
static GSList *toplevel_list = NULL;
static GHashTable *mnemonic_hash_table = NULL;
@ -309,6 +311,8 @@ gtk_window_class_init (GtkWindowClass *klass)
parent_class = gtk_type_class (gtk_bin_get_type ());
mnemonic_hash_table = g_hash_table_new (mnemonic_hash, mnemonic_equal);
gobject_class->dispose = gtk_window_dispose;
gobject_class->finalize = gtk_window_finalize;
@ -345,6 +349,7 @@ gtk_window_class_init (GtkWindowClass *klass)
klass->activate_default = gtk_window_real_activate_default;
klass->activate_focus = gtk_window_real_activate_focus;
klass->move_focus = gtk_window_move_focus;
klass->accels_changed = NULL;
/* Construct */
g_object_class_install_property (gobject_class,
@ -493,10 +498,16 @@ gtk_window_class_init (GtkWindowClass *klass)
G_TYPE_NONE,
1,
GTK_TYPE_DIRECTION_TYPE);
if (!mnemonic_hash_table)
mnemonic_hash_table = g_hash_table_new (mnemonic_hash,
mnemonic_equal);
window_signals[ACCELS_CHANGED] =
g_signal_new ("accels_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
GTK_SIGNAL_OFFSET (GtkWindowClass, accels_changed),
NULL, NULL,
gtk_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/*
* Key bindings
@ -1001,6 +1012,38 @@ gtk_window_set_policy (GtkWindow *window,
gtk_widget_queue_resize (GTK_WIDGET (window));
}
static gboolean
handle_accels_changed (gpointer data)
{
GtkWindow *window = GTK_WINDOW (data);
if (window->accels_changed_handler)
{
gtk_idle_remove (window->accels_changed_handler);
window->accels_changed_handler = 0;
}
g_signal_emit (window, window_signals[ACCELS_CHANGED], 0);
return FALSE;
}
static void
gtk_window_notify_accels_changed (GtkWindow *window)
{
if (!window->accels_changed_handler)
window->accels_changed_handler = gtk_idle_add (handle_accels_changed, window);
}
/**
* gtk_window_add_accel_group:
* @window: window to attach accelerator group to
* @accel_group: a #GtkAccelGroup
*
* Associate @accel_group with @window, such that calling
* gtk_accel_groups_activate() on @window will activate accelerators
* in @accel_group.
**/
void
gtk_window_add_accel_group (GtkWindow *window,
GtkAccelGroup *accel_group)
@ -1008,9 +1051,19 @@ gtk_window_add_accel_group (GtkWindow *window,
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (accel_group != NULL);
gtk_accel_group_attach (accel_group, G_OBJECT (window));
_gtk_accel_group_attach (accel_group, G_OBJECT (window));
g_signal_connect_object (accel_group, "accel_changed",
G_CALLBACK (gtk_window_notify_accels_changed),
window, G_CONNECT_SWAPPED);
}
/**
* gtk_accel_group_detach:
* @accel_group: a #GtkAccelGroup
* @object: a #GObject
*
* Reverses the effects of gtk_window_add_accel_group().
**/
void
gtk_window_remove_accel_group (GtkWindow *window,
GtkAccelGroup *accel_group)
@ -1018,7 +1071,10 @@ gtk_window_remove_accel_group (GtkWindow *window,
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (accel_group != NULL);
gtk_accel_group_detach (accel_group, G_OBJECT (window));
g_signal_handlers_disconnect_by_func (accel_group,
G_CALLBACK (gtk_window_notify_accels_changed),
window);
_gtk_accel_group_detach (accel_group, G_OBJECT (window));
}
void
@ -1048,6 +1104,7 @@ gtk_window_add_mnemonic (GtkWindow *window,
mnemonic->targets = g_slist_prepend (NULL, target);
g_hash_table_insert (mnemonic_hash_table, mnemonic, mnemonic);
}
gtk_window_notify_accels_changed (window);
}
void
@ -1073,6 +1130,7 @@ gtk_window_remove_mnemonic (GtkWindow *window,
g_hash_table_remove (mnemonic_hash_table, mnemonic);
g_free (mnemonic);
}
gtk_window_notify_accels_changed (window);
}
gboolean
@ -1140,6 +1198,7 @@ gtk_window_set_mnemonic_modifier (GtkWindow *window,
g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
window->mnemonic_modifier = modifier;
gtk_window_notify_accels_changed (window);
}
/**
@ -2836,7 +2895,13 @@ gtk_window_finalize (GObject *object)
&window->geometry_info->widget);
g_free (window->geometry_info);
}
if (window->accels_changed_handler)
{
gtk_idle_remove (window->accels_changed_handler);
window->accels_changed_handler = 0;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -3371,6 +3436,46 @@ gtk_window_configure_event (GtkWidget *widget,
return TRUE;
}
/* the accel_key and accel_mods fields of the key have to be setup
* upon calling this function. it'll then return whether that key
* is at all used as accelerator, and if so will OR in the
* accel_flags member of the key.
*/
gboolean
_gtk_window_query_nonaccels (GtkWindow *window,
guint accel_key,
GdkModifierType accel_mods)
{
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
/* movement keys are considered locked accels */
if (!accel_mods)
{
static const guint bindings[] = {
GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
};
guint i;
for (i = 0; i < G_N_ELEMENTS (bindings); i++)
if (bindings[i] == accel_key)
return TRUE;
}
/* mnemonics are considered locked accels */
if (accel_mods == window->mnemonic_modifier)
{
GtkWindowMnemonic mkey;
mkey.window = window;
mkey.keyval = accel_key;
if (g_hash_table_lookup (mnemonic_hash_table, &mkey))
return TRUE;
}
return FALSE;
}
static gint
gtk_window_key_press_event (GtkWidget *widget,
GdkEventKey *event)
@ -3404,29 +3509,6 @@ gtk_window_key_press_event (GtkWidget *widget,
return handled;
}
static void
gtk_window_real_activate_default (GtkWindow *window)
{
gtk_window_activate_default (window);
}
static void
gtk_window_real_activate_focus (GtkWindow *window)
{
gtk_window_activate_focus (window);
}
static void
gtk_window_move_focus (GtkWindow *window,
GtkDirectionType dir)
{
gtk_widget_child_focus (GTK_WIDGET (window), dir);
if (!GTK_CONTAINER (window)->focus_child)
gtk_window_set_focus (window, NULL);
}
static gint
gtk_window_key_release_event (GtkWidget *widget,
GdkEventKey *event)
@ -3452,6 +3534,28 @@ gtk_window_key_release_event (GtkWidget *widget,
return handled;
}
static void
gtk_window_real_activate_default (GtkWindow *window)
{
gtk_window_activate_default (window);
}
static void
gtk_window_real_activate_focus (GtkWindow *window)
{
gtk_window_activate_focus (window);
}
static void
gtk_window_move_focus (GtkWindow *window,
GtkDirectionType dir)
{
gtk_widget_child_focus (GTK_WIDGET (window), dir);
if (!GTK_CONTAINER (window)->focus_child)
gtk_window_set_focus (window, NULL);
}
static gint
gtk_window_enter_notify_event (GtkWidget *widget,
GdkEventCrossing *event)

View File

@ -104,6 +104,8 @@ struct _GtkWindow
guint frame_top;
guint frame_right;
guint frame_bottom;
guint accels_changed_handler;
GdkModifierType mnemonic_modifier;
gpointer gtk_reserved1; /* For future GdkScreen * */
@ -124,6 +126,7 @@ struct _GtkWindowClass
void (* activate_default) (GtkWindow *window);
void (* move_focus) (GtkWindow *window,
GtkDirectionType direction);
void (*accels_changed) (GtkWindow *window);
};
#define GTK_TYPE_WINDOW_GROUP (gtk_window_group_get_type ())
@ -320,6 +323,11 @@ void _gtk_window_constrain_size (GtkWindow *window,
gint *new_height);
GtkWindowGroup *_gtk_window_get_group (GtkWindow *window);
/* --- internal (GtkAcceleratable) --- */
gboolean _gtk_window_query_nonaccels (GtkWindow *window,
guint accel_key,
GdkModifierType accel_mods);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -32,7 +32,11 @@ BEGIN {
printf ("# define GTKTYPEBUILTINS_VAR extern __declspec(dllimport)\n");
printf ("# endif\n");
printf ("#else\n");
printf ("# define GTKTYPEBUILTINS_VAR extern\n");
printf ("# ifdef GTK_COMPILATION\n");
printf ("# define GTKTYPEBUILTINS_VAR\n");
printf ("# else\n");
printf ("# define GTKTYPEBUILTINS_VAR extern\n");
printf ("# endif\n");
printf ("#endif\n");
printf ("\n");
}

View File

@ -3047,7 +3047,7 @@ create_menus (void)
NULL);
accel_group = gtk_accel_group_new ();
gtk_accel_group_attach (accel_group, G_OBJECT (window));
gtk_window_add_accel_group (window, accel_group);
gtk_window_set_title (GTK_WINDOW (window), "menus");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
@ -3103,7 +3103,7 @@ create_menus (void)
accel_group,
GDK_F1,
0,
GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
GTK_ACCEL_VISIBLE);
menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
gtk_widget_show (menuitem);
@ -3128,7 +3128,6 @@ create_menus (void)
GDK_F3,
0,
GTK_ACCEL_VISIBLE);
gtk_widget_lock_accelerators (menuitem);
optionmenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
@ -3287,7 +3286,7 @@ dump_accels (gpointer callback_data,
guint callback_action,
GtkWidget *widget)
{
gtk_item_factory_dump_items (NULL, FALSE, gtk_item_factory_print_func, stdout);
gtk_accel_map_save_fd (1 /* stdout */);
}
static GtkItemFactoryEntry menu_items[] =
@ -3360,7 +3359,7 @@ create_item_factory (void)
"<main>",
item_factory,
(GtkDestroyNotify) gtk_object_unref);
gtk_accel_group_attach (accel_group, G_OBJECT (window));
gtk_window_add_accel_group (window, accel_group);
gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);

View File

@ -26,6 +26,9 @@ double-click_timeout = 42
bell-duration = 39
bell_duration = 40
gtk-cursor-blink-time = 200
# gtk-menu-bar-accel = F10
style "global-style-properties"
{
# xthickness = 20