From: Jody Goldberg Date: Mon, 12 Jan 2004 22:45:45 +0000 (+0000) Subject: Adjust to the new connect_proxy signals. X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=c73ab06ef57f2f6d1b73f852efa8c08e040cf557;p=~andy%2Fgtk Adjust to the new connect_proxy signals. Mon Jan 12 23:40:34 2004 Matthias Clasen * tests/testmerge.c: Adjust to the new connect_proxy signals. * gtk/gtkuimanager.c * gtk/gtkactiongroup.c * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This removes the confusion between the disconnect_/connect_proxy signals and the (unrelated) virtual functions of the same name and aligns the setup with the pre_/post_activate signals. 2004-01-12 Jody Goldberg * gtk/gtkaction.c (connect_proxy) : only connect activate for menus with no submenus otherwise it looks like we activate every time a submenu opens. 2004-01-10 Jody Goldberg * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. s/merge_signals/ui_manager_signals/ for readability. (gtk_ui_manager_class_init) : add pre_activate and post_activate signals. (cb_proxy_pre_activate) : new. (cb_proxy_post_activate) : new. (gtk_ui_manager_insert_action_group) : connect the proxies for GtkActionGroup::pre/post_activate (gtk_ui_manager_remove_action_group) : disconnect them. * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add 'sensitive', and 'visible' properties. Also add pre_activate and post_activate signals to help deal with activations at a higher level (eg GtkUIManager) (gtk_action_group_init) : init sensitive and visible (gtk_action_group_set_property) : add sensitive and visible (gtk_action_group_get_property) : add sensitive and visible (gtk_action_group_get_sensitive) : new. (gtk_action_group_get_visible) : new. (cb_set_action_sensitivity) : new with minor optimization that only signals sensitivity changes if the action could possibly change. (cb_set_action_visiblility) : ditto. (gtk_action_group_set_sensitive) : new. walk the actions directly rather than using notify::sensitive because that is simpler, easier to read, and more efficient. (gtk_action_group_set_visible) : ditto. (gtk_action_group_add_action) : Each action can only be in 1 group, set GtkAction::action_group. (gtk_action_group_remove_action) : clear it. (gtk_action_group_add_toggle_actions_full) : warning suppression. (gtk_action_group_add_radio_actions_full) : warning suppression. (_gtk_action_group_emit_pre_activate) : new protected routine for use by GtkAction. (_gtk_action_group_emit_post_activate) : ditto. * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. (gtk_action_init) : initialize it. (gtk_action_get_property) : get. (gtk_action_set_property) : set it via (gtk_action_set_action_group) : new function. (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity with the logical sensitivity (action & group) rather than the simple action::sensitivity. (gtk_action_sync_visible) : use gtk_action_is_visible to handle logical visibility (action & group) rather than the simple action::visible. Use widget show/hide directly. (connect_proxy) : handle the custom sensitivity handler. Make the TOOL_BUTTON signals more general and support TOOL_ITEM directly, with special cases for TOOL_BUTTON. Still not especially good it might be useful to handle label/use_underline by parmspec lookup. Those are likely to be implemented by custom types, and are assumed to exist in GtkToolItem. (disconnect_proxy) : disconnect the new sensitivity handler. (_gtk_action_emit_activate) : add pre/post signals. (gtk_action_activate) : use logical sensitivity. (gtk_action_is_sensitive) : logical sensitivity. (gtk_action_get_sensitive) : actual sensitivity. (closure_accel_activate) : use logical sensitivity. --- diff --git a/ChangeLog b/ChangeLog index d1de5fb3d..9a0730566 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,22 @@ -Mon Jan 12 00:10:20 2004 Matthias Clasen +Mon Jan 12 23:40:34 2004 Matthias Clasen + + * tests/testmerge.c: Adjust to the new connect_proxy signals. + + * gtk/gtkuimanager.c + * gtk/gtkactiongroup.c + * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals + from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This + removes the confusion between the disconnect_/connect_proxy signals + and the (unrelated) virtual functions of the same name and aligns + the setup with the pre_/post_activate signals. + +2004-01-12 Jody Goldberg + + * gtk/gtkaction.c (connect_proxy) : only connect activate for menus + with no submenus otherwise it looks like we activate every time a + submenu opens. + +2004-01-12 Jody Goldberg * gtk/gtkuimanager.c: Remove accidentially committed debug spew. @@ -10,6 +28,67 @@ Sun Jan 11 01:55:07 2004 Matthias Clasen entry is silently created during lock_path(), and treated as an error during unlock_path(). These changes have been requested by Tim Janik. +2004-01-10 Jody Goldberg + + * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. + s/merge_signals/ui_manager_signals/ for readability. + (gtk_ui_manager_class_init) : add pre_activate and post_activate + signals. + (cb_proxy_pre_activate) : new. + (cb_proxy_post_activate) : new. + (gtk_ui_manager_insert_action_group) : connect the proxies for + GtkActionGroup::pre/post_activate + (gtk_ui_manager_remove_action_group) : disconnect them. + + * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add + 'sensitive', and 'visible' properties. Also add pre_activate and + post_activate signals to help deal with activations at a higher + level (eg GtkUIManager) + (gtk_action_group_init) : init sensitive and visible + (gtk_action_group_set_property) : add sensitive and visible + (gtk_action_group_get_property) : add sensitive and visible + (gtk_action_group_get_sensitive) : new. + (gtk_action_group_get_visible) : new. + (cb_set_action_sensitivity) : new with minor optimization that only + signals sensitivity changes if the action could possibly change. + (cb_set_action_visiblility) : ditto. + (gtk_action_group_set_sensitive) : new. walk the actions directly + rather than using notify::sensitive because that is simpler, easier + to read, and more efficient. + (gtk_action_group_set_visible) : ditto. + (gtk_action_group_add_action) : Each action can only be in 1 group, + set GtkAction::action_group. + (gtk_action_group_remove_action) : clear it. + (gtk_action_group_add_toggle_actions_full) : warning suppression. + (gtk_action_group_add_radio_actions_full) : warning suppression. + (_gtk_action_group_emit_pre_activate) : new protected routine for use + by GtkAction. + (_gtk_action_group_emit_post_activate) : ditto. + + * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. + (gtk_action_init) : initialize it. + (gtk_action_get_property) : get. + (gtk_action_set_property) : set it via + (gtk_action_set_action_group) : new function. + (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity + with the logical sensitivity (action & group) rather than the simple + action::sensitivity. + (gtk_action_sync_visible) : use gtk_action_is_visible to handle + logical visibility (action & group) rather than the simple + action::visible. Use widget show/hide directly. + (connect_proxy) : handle the custom sensitivity handler. + Make the TOOL_BUTTON signals more general and support TOOL_ITEM + directly, with special cases for TOOL_BUTTON. Still not especially + good it might be useful to handle label/use_underline by parmspec + lookup. Those are likely to be implemented by custom types, and are + assumed to exist in GtkToolItem. + (disconnect_proxy) : disconnect the new sensitivity handler. + (_gtk_action_emit_activate) : add pre/post signals. + (gtk_action_activate) : use logical sensitivity. + (gtk_action_is_sensitive) : logical sensitivity. + (gtk_action_get_sensitive) : actual sensitivity. + (closure_accel_activate) : use logical sensitivity. + Fri Jan 9 22:23:45 2004 Matthias Clasen * gtk/gtkuimanager.c: Introduce a new parser state for diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d1de5fb3d..9a0730566 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,4 +1,22 @@ -Mon Jan 12 00:10:20 2004 Matthias Clasen +Mon Jan 12 23:40:34 2004 Matthias Clasen + + * tests/testmerge.c: Adjust to the new connect_proxy signals. + + * gtk/gtkuimanager.c + * gtk/gtkactiongroup.c + * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals + from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This + removes the confusion between the disconnect_/connect_proxy signals + and the (unrelated) virtual functions of the same name and aligns + the setup with the pre_/post_activate signals. + +2004-01-12 Jody Goldberg + + * gtk/gtkaction.c (connect_proxy) : only connect activate for menus + with no submenus otherwise it looks like we activate every time a + submenu opens. + +2004-01-12 Jody Goldberg * gtk/gtkuimanager.c: Remove accidentially committed debug spew. @@ -10,6 +28,67 @@ Sun Jan 11 01:55:07 2004 Matthias Clasen entry is silently created during lock_path(), and treated as an error during unlock_path(). These changes have been requested by Tim Janik. +2004-01-10 Jody Goldberg + + * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. + s/merge_signals/ui_manager_signals/ for readability. + (gtk_ui_manager_class_init) : add pre_activate and post_activate + signals. + (cb_proxy_pre_activate) : new. + (cb_proxy_post_activate) : new. + (gtk_ui_manager_insert_action_group) : connect the proxies for + GtkActionGroup::pre/post_activate + (gtk_ui_manager_remove_action_group) : disconnect them. + + * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add + 'sensitive', and 'visible' properties. Also add pre_activate and + post_activate signals to help deal with activations at a higher + level (eg GtkUIManager) + (gtk_action_group_init) : init sensitive and visible + (gtk_action_group_set_property) : add sensitive and visible + (gtk_action_group_get_property) : add sensitive and visible + (gtk_action_group_get_sensitive) : new. + (gtk_action_group_get_visible) : new. + (cb_set_action_sensitivity) : new with minor optimization that only + signals sensitivity changes if the action could possibly change. + (cb_set_action_visiblility) : ditto. + (gtk_action_group_set_sensitive) : new. walk the actions directly + rather than using notify::sensitive because that is simpler, easier + to read, and more efficient. + (gtk_action_group_set_visible) : ditto. + (gtk_action_group_add_action) : Each action can only be in 1 group, + set GtkAction::action_group. + (gtk_action_group_remove_action) : clear it. + (gtk_action_group_add_toggle_actions_full) : warning suppression. + (gtk_action_group_add_radio_actions_full) : warning suppression. + (_gtk_action_group_emit_pre_activate) : new protected routine for use + by GtkAction. + (_gtk_action_group_emit_post_activate) : ditto. + + * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. + (gtk_action_init) : initialize it. + (gtk_action_get_property) : get. + (gtk_action_set_property) : set it via + (gtk_action_set_action_group) : new function. + (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity + with the logical sensitivity (action & group) rather than the simple + action::sensitivity. + (gtk_action_sync_visible) : use gtk_action_is_visible to handle + logical visibility (action & group) rather than the simple + action::visible. Use widget show/hide directly. + (connect_proxy) : handle the custom sensitivity handler. + Make the TOOL_BUTTON signals more general and support TOOL_ITEM + directly, with special cases for TOOL_BUTTON. Still not especially + good it might be useful to handle label/use_underline by parmspec + lookup. Those are likely to be implemented by custom types, and are + assumed to exist in GtkToolItem. + (disconnect_proxy) : disconnect the new sensitivity handler. + (_gtk_action_emit_activate) : add pre/post signals. + (gtk_action_activate) : use logical sensitivity. + (gtk_action_is_sensitive) : logical sensitivity. + (gtk_action_get_sensitive) : actual sensitivity. + (closure_accel_activate) : use logical sensitivity. + Fri Jan 9 22:23:45 2004 Matthias Clasen * gtk/gtkuimanager.c: Introduce a new parser state for diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d1de5fb3d..9a0730566 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,4 +1,22 @@ -Mon Jan 12 00:10:20 2004 Matthias Clasen +Mon Jan 12 23:40:34 2004 Matthias Clasen + + * tests/testmerge.c: Adjust to the new connect_proxy signals. + + * gtk/gtkuimanager.c + * gtk/gtkactiongroup.c + * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals + from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This + removes the confusion between the disconnect_/connect_proxy signals + and the (unrelated) virtual functions of the same name and aligns + the setup with the pre_/post_activate signals. + +2004-01-12 Jody Goldberg + + * gtk/gtkaction.c (connect_proxy) : only connect activate for menus + with no submenus otherwise it looks like we activate every time a + submenu opens. + +2004-01-12 Jody Goldberg * gtk/gtkuimanager.c: Remove accidentially committed debug spew. @@ -10,6 +28,67 @@ Sun Jan 11 01:55:07 2004 Matthias Clasen entry is silently created during lock_path(), and treated as an error during unlock_path(). These changes have been requested by Tim Janik. +2004-01-10 Jody Goldberg + + * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. + s/merge_signals/ui_manager_signals/ for readability. + (gtk_ui_manager_class_init) : add pre_activate and post_activate + signals. + (cb_proxy_pre_activate) : new. + (cb_proxy_post_activate) : new. + (gtk_ui_manager_insert_action_group) : connect the proxies for + GtkActionGroup::pre/post_activate + (gtk_ui_manager_remove_action_group) : disconnect them. + + * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add + 'sensitive', and 'visible' properties. Also add pre_activate and + post_activate signals to help deal with activations at a higher + level (eg GtkUIManager) + (gtk_action_group_init) : init sensitive and visible + (gtk_action_group_set_property) : add sensitive and visible + (gtk_action_group_get_property) : add sensitive and visible + (gtk_action_group_get_sensitive) : new. + (gtk_action_group_get_visible) : new. + (cb_set_action_sensitivity) : new with minor optimization that only + signals sensitivity changes if the action could possibly change. + (cb_set_action_visiblility) : ditto. + (gtk_action_group_set_sensitive) : new. walk the actions directly + rather than using notify::sensitive because that is simpler, easier + to read, and more efficient. + (gtk_action_group_set_visible) : ditto. + (gtk_action_group_add_action) : Each action can only be in 1 group, + set GtkAction::action_group. + (gtk_action_group_remove_action) : clear it. + (gtk_action_group_add_toggle_actions_full) : warning suppression. + (gtk_action_group_add_radio_actions_full) : warning suppression. + (_gtk_action_group_emit_pre_activate) : new protected routine for use + by GtkAction. + (_gtk_action_group_emit_post_activate) : ditto. + + * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. + (gtk_action_init) : initialize it. + (gtk_action_get_property) : get. + (gtk_action_set_property) : set it via + (gtk_action_set_action_group) : new function. + (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity + with the logical sensitivity (action & group) rather than the simple + action::sensitivity. + (gtk_action_sync_visible) : use gtk_action_is_visible to handle + logical visibility (action & group) rather than the simple + action::visible. Use widget show/hide directly. + (connect_proxy) : handle the custom sensitivity handler. + Make the TOOL_BUTTON signals more general and support TOOL_ITEM + directly, with special cases for TOOL_BUTTON. Still not especially + good it might be useful to handle label/use_underline by parmspec + lookup. Those are likely to be implemented by custom types, and are + assumed to exist in GtkToolItem. + (disconnect_proxy) : disconnect the new sensitivity handler. + (_gtk_action_emit_activate) : add pre/post signals. + (gtk_action_activate) : use logical sensitivity. + (gtk_action_is_sensitive) : logical sensitivity. + (gtk_action_get_sensitive) : actual sensitivity. + (closure_accel_activate) : use logical sensitivity. + Fri Jan 9 22:23:45 2004 Matthias Clasen * gtk/gtkuimanager.c: Introduce a new parser state for diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d1de5fb3d..9a0730566 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,4 +1,22 @@ -Mon Jan 12 00:10:20 2004 Matthias Clasen +Mon Jan 12 23:40:34 2004 Matthias Clasen + + * tests/testmerge.c: Adjust to the new connect_proxy signals. + + * gtk/gtkuimanager.c + * gtk/gtkactiongroup.c + * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals + from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This + removes the confusion between the disconnect_/connect_proxy signals + and the (unrelated) virtual functions of the same name and aligns + the setup with the pre_/post_activate signals. + +2004-01-12 Jody Goldberg + + * gtk/gtkaction.c (connect_proxy) : only connect activate for menus + with no submenus otherwise it looks like we activate every time a + submenu opens. + +2004-01-12 Jody Goldberg * gtk/gtkuimanager.c: Remove accidentially committed debug spew. @@ -10,6 +28,67 @@ Sun Jan 11 01:55:07 2004 Matthias Clasen entry is silently created during lock_path(), and treated as an error during unlock_path(). These changes have been requested by Tim Janik. +2004-01-10 Jody Goldberg + + * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. + s/merge_signals/ui_manager_signals/ for readability. + (gtk_ui_manager_class_init) : add pre_activate and post_activate + signals. + (cb_proxy_pre_activate) : new. + (cb_proxy_post_activate) : new. + (gtk_ui_manager_insert_action_group) : connect the proxies for + GtkActionGroup::pre/post_activate + (gtk_ui_manager_remove_action_group) : disconnect them. + + * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add + 'sensitive', and 'visible' properties. Also add pre_activate and + post_activate signals to help deal with activations at a higher + level (eg GtkUIManager) + (gtk_action_group_init) : init sensitive and visible + (gtk_action_group_set_property) : add sensitive and visible + (gtk_action_group_get_property) : add sensitive and visible + (gtk_action_group_get_sensitive) : new. + (gtk_action_group_get_visible) : new. + (cb_set_action_sensitivity) : new with minor optimization that only + signals sensitivity changes if the action could possibly change. + (cb_set_action_visiblility) : ditto. + (gtk_action_group_set_sensitive) : new. walk the actions directly + rather than using notify::sensitive because that is simpler, easier + to read, and more efficient. + (gtk_action_group_set_visible) : ditto. + (gtk_action_group_add_action) : Each action can only be in 1 group, + set GtkAction::action_group. + (gtk_action_group_remove_action) : clear it. + (gtk_action_group_add_toggle_actions_full) : warning suppression. + (gtk_action_group_add_radio_actions_full) : warning suppression. + (_gtk_action_group_emit_pre_activate) : new protected routine for use + by GtkAction. + (_gtk_action_group_emit_post_activate) : ditto. + + * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. + (gtk_action_init) : initialize it. + (gtk_action_get_property) : get. + (gtk_action_set_property) : set it via + (gtk_action_set_action_group) : new function. + (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity + with the logical sensitivity (action & group) rather than the simple + action::sensitivity. + (gtk_action_sync_visible) : use gtk_action_is_visible to handle + logical visibility (action & group) rather than the simple + action::visible. Use widget show/hide directly. + (connect_proxy) : handle the custom sensitivity handler. + Make the TOOL_BUTTON signals more general and support TOOL_ITEM + directly, with special cases for TOOL_BUTTON. Still not especially + good it might be useful to handle label/use_underline by parmspec + lookup. Those are likely to be implemented by custom types, and are + assumed to exist in GtkToolItem. + (disconnect_proxy) : disconnect the new sensitivity handler. + (_gtk_action_emit_activate) : add pre/post signals. + (gtk_action_activate) : use logical sensitivity. + (gtk_action_is_sensitive) : logical sensitivity. + (gtk_action_get_sensitive) : actual sensitivity. + (closure_accel_activate) : use logical sensitivity. + Fri Jan 9 22:23:45 2004 Matthias Clasen * gtk/gtkuimanager.c: Introduce a new parser state for diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d1de5fb3d..9a0730566 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,4 +1,22 @@ -Mon Jan 12 00:10:20 2004 Matthias Clasen +Mon Jan 12 23:40:34 2004 Matthias Clasen + + * tests/testmerge.c: Adjust to the new connect_proxy signals. + + * gtk/gtkuimanager.c + * gtk/gtkactiongroup.c + * gtk/gtkaction.c: Move the connect_proxy and disconnect_proxy signals + from GtkAction to GtkActionGroup and proxy it on GtkUIManager. This + removes the confusion between the disconnect_/connect_proxy signals + and the (unrelated) virtual functions of the same name and aligns + the setup with the pre_/post_activate signals. + +2004-01-12 Jody Goldberg + + * gtk/gtkaction.c (connect_proxy) : only connect activate for menus + with no submenus otherwise it looks like we activate every time a + submenu opens. + +2004-01-12 Jody Goldberg * gtk/gtkuimanager.c: Remove accidentially committed debug spew. @@ -10,6 +28,67 @@ Sun Jan 11 01:55:07 2004 Matthias Clasen entry is silently created during lock_path(), and treated as an error during unlock_path(). These changes have been requested by Tim Janik. +2004-01-10 Jody Goldberg + + * gtk/gtkuimanager.c (d) : Add a debug macro to quiet the spew. + s/merge_signals/ui_manager_signals/ for readability. + (gtk_ui_manager_class_init) : add pre_activate and post_activate + signals. + (cb_proxy_pre_activate) : new. + (cb_proxy_post_activate) : new. + (gtk_ui_manager_insert_action_group) : connect the proxies for + GtkActionGroup::pre/post_activate + (gtk_ui_manager_remove_action_group) : disconnect them. + + * gtk/gtkactiongroup.c (gtk_action_group_class_init) : add + 'sensitive', and 'visible' properties. Also add pre_activate and + post_activate signals to help deal with activations at a higher + level (eg GtkUIManager) + (gtk_action_group_init) : init sensitive and visible + (gtk_action_group_set_property) : add sensitive and visible + (gtk_action_group_get_property) : add sensitive and visible + (gtk_action_group_get_sensitive) : new. + (gtk_action_group_get_visible) : new. + (cb_set_action_sensitivity) : new with minor optimization that only + signals sensitivity changes if the action could possibly change. + (cb_set_action_visiblility) : ditto. + (gtk_action_group_set_sensitive) : new. walk the actions directly + rather than using notify::sensitive because that is simpler, easier + to read, and more efficient. + (gtk_action_group_set_visible) : ditto. + (gtk_action_group_add_action) : Each action can only be in 1 group, + set GtkAction::action_group. + (gtk_action_group_remove_action) : clear it. + (gtk_action_group_add_toggle_actions_full) : warning suppression. + (gtk_action_group_add_radio_actions_full) : warning suppression. + (_gtk_action_group_emit_pre_activate) : new protected routine for use + by GtkAction. + (_gtk_action_group_emit_post_activate) : ditto. + + * gtk/gtkaction.c (gtk_action_class_init) : add 'action_group' property. + (gtk_action_init) : initialize it. + (gtk_action_get_property) : get. + (gtk_action_set_property) : set it via + (gtk_action_set_action_group) : new function. + (gtk_action_sync_sensitivity) : new routine to sync proxy sensitivity + with the logical sensitivity (action & group) rather than the simple + action::sensitivity. + (gtk_action_sync_visible) : use gtk_action_is_visible to handle + logical visibility (action & group) rather than the simple + action::visible. Use widget show/hide directly. + (connect_proxy) : handle the custom sensitivity handler. + Make the TOOL_BUTTON signals more general and support TOOL_ITEM + directly, with special cases for TOOL_BUTTON. Still not especially + good it might be useful to handle label/use_underline by parmspec + lookup. Those are likely to be implemented by custom types, and are + assumed to exist in GtkToolItem. + (disconnect_proxy) : disconnect the new sensitivity handler. + (_gtk_action_emit_activate) : add pre/post signals. + (gtk_action_activate) : use logical sensitivity. + (gtk_action_is_sensitive) : logical sensitivity. + (gtk_action_get_sensitive) : actual sensitivity. + (closure_accel_activate) : use logical sensitivity. + Fri Jan 9 22:23:45 2004 Matthias Clasen * gtk/gtkuimanager.c: Introduce a new parser state for diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 9747ab463..145e72a83 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -104,6 +104,10 @@ gtk_accessible_get_type GtkAction gtk_action_new gtk_action_get_name +gtk_action_is_sensitive +gtk_action_get_sensitive +gtk_action_is_visible +gtk_action_get_visible gtk_action_activate gtk_action_create_icon gtk_action_create_menu_item @@ -136,6 +140,10 @@ GtkActionPrivate GtkActionGroup gtk_action_group_new gtk_action_group_get_name +gtk_action_group_get_sensitive +gtk_action_group_set_sensitive +gtk_action_group_get_visible +gtk_action_group_set_visible gtk_action_group_get_action gtk_action_group_list_actions gtk_action_group_add_action diff --git a/gtk/gtkaction.c b/gtk/gtkaction.c index 20c2dbe1f..bb94df689 100644 --- a/gtk/gtkaction.c +++ b/gtk/gtkaction.c @@ -31,6 +31,7 @@ #include #include "gtkaction.h" +#include "gtkactiongroup.h" #include "gtkaccellabel.h" #include "gtkbutton.h" #include "gtkimage.h" @@ -70,14 +71,14 @@ struct _GtkActionPrivate GClosure *accel_closure; GQuark accel_quark; + GtkActionGroup *action_group; + /* list of proxy widgets */ GSList *proxies; }; enum { - CONNECT_PROXY, - DISCONNECT_PROXY, ACTIVATE, LAST_SIGNAL }; @@ -95,7 +96,8 @@ enum PROP_IS_IMPORTANT, PROP_HIDE_IF_EMPTY, PROP_SENSITIVE, - PROP_VISIBLE + PROP_VISIBLE, + PROP_ACTION_GROUP }; static void gtk_action_init (GtkAction *action); @@ -141,6 +143,8 @@ static void gtk_action_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gtk_action_set_action_group (GtkAction *action, + GtkActionGroup *action_group); static GtkWidget *create_menu_item (GtkAction *action); static GtkWidget *create_tool_item (GtkAction *action); @@ -261,6 +265,13 @@ gtk_action_class_init (GtkActionClass *klass) _("Whether the action is visible."), TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_ACTION_GROUP, + g_param_spec_object ("action_group", + _("Action Group"), + _("The GtkActionGroup this GtkAction is associated with, or NULL (for internal use)."), + GTK_TYPE_ACTION_GROUP, + G_PARAM_READWRITE)); /** * GtkAction::activate: @@ -278,47 +289,6 @@ gtk_action_class_init (GtkActionClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - /** - * GtkAction::connect-proxy: - * @action: the action - * @proxy: the proxy - * - * The connect_proxy signal is emitted after connecting a proxy to - * an action. Note that the proxy may have been connected to a different - * action before. - * - * This is intended for simple customizations for which a custom action - * class would be too clumsy, e.g. showing tooltips for menuitems in the - * statusbar. - * - * Since: 2.4 - */ - action_signals[CONNECT_PROXY] = - g_signal_new ("connect_proxy", - G_OBJECT_CLASS_TYPE (klass), - 0, 0, NULL, NULL, - _gtk_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); - - /** - * GtkAction::disconnect-proxy: - * @action: the action - * @proxy: the proxy - * - * The disconnect_proxy signal is emitted after disconnecting a proxy - * from an action. - * - * Since: 2.4 - */ - action_signals[DISCONNECT_PROXY] = - g_signal_new ("disconnect_proxy", - G_OBJECT_CLASS_TYPE (klass), - 0, 0, NULL, NULL, - _gtk_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); - g_type_class_add_private (gobject_class, sizeof (GtkActionPrivate)); } @@ -356,6 +326,8 @@ gtk_action_init (GtkAction *action) action->private_data->accel_count = 0; action->private_data->accel_group = NULL; + action->private_data->action_group = NULL; + action->private_data->proxies = NULL; } @@ -507,6 +479,9 @@ gtk_action_set_property (GObject *object, case PROP_VISIBLE: action->private_data->visible = g_value_get_boolean (value); break; + case PROP_ACTION_GROUP: + gtk_action_set_action_group (action, g_value_get_object (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -558,6 +533,9 @@ gtk_action_get_property (GObject *object, case PROP_VISIBLE: g_value_set_boolean (value, action->private_data->visible); break; + case PROP_ACTION_GROUP: + g_value_set_object (value, action->private_data->action_group); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -594,6 +572,14 @@ remove_proxy (GtkWidget *proxy, action->private_data->proxies = g_slist_remove (action->private_data->proxies, proxy); } +static void +gtk_action_sync_sensitivity (GtkAction *action, + GParamSpec *pspec, + GtkWidget *proxy) +{ + gtk_widget_set_sensitive (proxy, gtk_action_is_sensitive (action)); +} + static void gtk_action_sync_property (GtkAction *action, GParamSpec *pspec, @@ -642,7 +628,7 @@ _gtk_action_sync_menu_visible (GtkAction *action, if (action == NULL) action = g_object_get_data (G_OBJECT (proxy), "gtk-action"); - visible = action->private_data->visible; + visible = gtk_action_is_visible (action); hide_if_empty = action->private_data->hide_if_empty; g_object_set (G_OBJECT (proxy), @@ -664,7 +650,12 @@ gtk_action_sync_visible (GtkAction *action, _gtk_action_sync_menu_visible (action, proxy, _gtk_menu_is_empty (menu)); } else - gtk_action_sync_property (action, pspec, proxy); + { + if (gtk_action_is_visible (action)) + gtk_widget_show (proxy); + else + gtk_widget_hide (proxy); + } } static void @@ -750,6 +741,8 @@ static void connect_proxy (GtkAction *action, GtkWidget *proxy) { + GtkActionGroup *group = action->private_data->action_group; + g_object_ref (action); g_object_set_data_full (G_OBJECT (proxy), "gtk-action", action, g_object_unref); @@ -760,12 +753,12 @@ connect_proxy (GtkAction *action, G_CALLBACK (remove_proxy), action); g_signal_connect_object (action, "notify::sensitive", - G_CALLBACK (gtk_action_sync_property), proxy, 0); - gtk_widget_set_sensitive (proxy, action->private_data->sensitive); + G_CALLBACK (gtk_action_sync_sensitivity), proxy, 0); + gtk_widget_set_sensitive (proxy, gtk_action_is_sensitive (action)); g_signal_connect_object (action, "notify::visible", G_CALLBACK (gtk_action_sync_visible), proxy, 0); - if (action->private_data->visible) + if (gtk_action_is_visible (action)) gtk_widget_show (proxy); else gtk_widget_hide (proxy); @@ -834,19 +827,17 @@ connect_proxy (GtkAction *action, proxy, 0); } + if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)) == NULL) g_signal_connect_object (proxy, "activate", G_CALLBACK (gtk_action_activate), action, G_CONNECT_SWAPPED); } - else if (GTK_IS_TOOL_BUTTON (proxy)) + else if (GTK_IS_TOOL_ITEM (proxy)) { - /* toolbar button specific synchronisers ... */ + /* toolbar item specific synchronisers ... */ g_object_set (G_OBJECT (proxy), - "label", action->private_data->short_label, - "use_underline", TRUE, - "stock_id", action->private_data->stock_id, "visible_horizontal", action->private_data->visible_horizontal, "visible_vertical", action->private_data->visible_vertical, "is_important", action->private_data->is_important, @@ -854,12 +845,6 @@ connect_proxy (GtkAction *action, /* FIXME: we should set the tooltip here, but the current api * doesn't allow it before the item is added to a toolbar. */ - g_signal_connect_object (action, "notify::short_label", - G_CALLBACK (gtk_action_sync_short_label), - proxy, 0); - g_signal_connect_object (action, "notify::stock_id", - G_CALLBACK (gtk_action_sync_property), - proxy, 0); g_signal_connect_object (action, "notify::visible_horizontal", G_CALLBACK (gtk_action_sync_property), proxy, 0); @@ -877,10 +862,28 @@ connect_proxy (GtkAction *action, G_CALLBACK (gtk_action_create_menu_proxy), action, 0); + /* toolbar button specific synchronisers ... */ + if (GTK_IS_TOOL_BUTTON (proxy)) + { + g_object_set (G_OBJECT (proxy), + "label", action->private_data->short_label, + "use_underline", TRUE, + "stock_id", action->private_data->stock_id, + NULL); + /* FIXME: we should set the tooltip here, but the current api + * doesn't allow it before the item is added to a toolbar. + */ + g_signal_connect_object (action, "notify::short_label", + G_CALLBACK (gtk_action_sync_short_label), + proxy, 0); + g_signal_connect_object (action, "notify::stock_id", + G_CALLBACK (gtk_action_sync_property), + proxy, 0); g_signal_connect_object (proxy, "clicked", G_CALLBACK (gtk_action_activate), action, G_CONNECT_SWAPPED); } + } else if (GTK_IS_BUTTON (proxy)) { /* button specific synchronisers ... */ @@ -899,13 +902,15 @@ connect_proxy (GtkAction *action, G_CONNECT_SWAPPED); } - g_signal_emit (action, action_signals[CONNECT_PROXY], 0, proxy); + _gtk_action_group_emit_connect_proxy (group, action, proxy); } static void disconnect_proxy (GtkAction *action, GtkWidget *proxy) { + GtkActionGroup *group = action->private_data->action_group; + g_object_set_data (G_OBJECT (proxy), "gtk-action", NULL); /* remove proxy from list of proxies */ @@ -920,6 +925,9 @@ disconnect_proxy (GtkAction *action, action); /* disconnect handlers for notify::* signals */ + g_signal_handlers_disconnect_by_func (proxy, + G_CALLBACK (gtk_action_sync_sensitivity), + action); g_signal_handlers_disconnect_by_func (proxy, G_CALLBACK (gtk_action_sync_property), action); @@ -941,13 +949,21 @@ disconnect_proxy (GtkAction *action, G_CALLBACK (gtk_action_create_menu_proxy), action); - g_signal_emit (action, action_signals[DISCONNECT_PROXY], 0, proxy); + _gtk_action_group_emit_disconnect_proxy (group, action, proxy); } void _gtk_action_emit_activate (GtkAction *action) { + GtkActionGroup *group = action->private_data->action_group; + + if (group != NULL) + _gtk_action_group_emit_pre_activate (group, action); + g_signal_emit (action, action_signals[ACTIVATE], 0); + + if (group != NULL) + _gtk_action_group_emit_post_activate (group, action); } /** @@ -967,7 +983,7 @@ gtk_action_activate (GtkAction *action) { g_return_if_fail (GTK_IS_ACTION (action)); - if (action->private_data->sensitive) + if (gtk_action_is_sensitive (action)) _gtk_action_emit_activate (action); } @@ -1135,6 +1151,92 @@ gtk_action_get_name (GtkAction *action) return action->private_data->name; } +/** + * gtk_action_is_sensitive: + * @action: the action object + * + * Returns whether the action is effectively sensitive. + * + * Return value: %TRUE if the action and its associated action group + * are both sensitive. + * + * Since: 2.4 + **/ +gboolean +gtk_action_is_sensitive (GtkAction *action) +{ + GtkActionPrivate *priv; + g_return_val_if_fail (GTK_IS_ACTION (action), FALSE); + + priv = action->private_data; + return priv->sensitive && + (priv->action_group == NULL || + gtk_action_group_get_sensitive (priv->action_group)); +} + +/** + * gtk_action_get_sensitive: + * @action: the action object + * + * Returns whether the action itself is sensitive. Note that this doesn't + * necessarily mean effective sensitivity. See gtk_action_is_sensitive() + * for that. + * + * Return value: %TRUE if the action itself is sensitive. + * + * Since: 2.4 + **/ +gboolean +gtk_action_get_sensitive (GtkAction *action) +{ + g_return_val_if_fail (GTK_IS_ACTION (action), FALSE); + + return action->private_data->sensitive; +} + +/** + * gtk_action_is_visible: + * @action: the action object + * + * Returns whether the action is effectively visible. + * + * Return value: %TRUE if the action and its associated action group + * are both visible. + * + * Since: 2.4 + **/ +gboolean +gtk_action_is_visible (GtkAction *action) +{ + GtkActionPrivate *priv; + g_return_val_if_fail (GTK_IS_ACTION (action), FALSE); + + priv = action->private_data; + return priv->visible && + (priv->action_group == NULL || + gtk_action_group_get_visible (priv->action_group)); +} + +/** + * gtk_action_get_visible: + * @action: the action object + * + * Returns whether the action itself is visible. Note that this doesn't + * necessarily mean effective visibility. See gtk_action_is_sensitive() + * for that. + * + * Return value: %TRUE if the action itself is visible. + * + * Since: 2.4 + **/ +gboolean +gtk_action_get_visible (GtkAction *action) +{ + g_return_val_if_fail (GTK_IS_ACTION (action), FALSE); + + return action->private_data->visible; +} + /** * gtk_action_block_activate_from: * @action: the action object @@ -1189,13 +1291,27 @@ closure_accel_activate (GClosure *closure, gpointer invocation_hint, gpointer marshal_data) { - if (GTK_ACTION (closure->data)->private_data->sensitive) + if (gtk_action_is_sensitive (GTK_ACTION (closure->data))) g_signal_emit (closure->data, action_signals[ACTIVATE], 0); /* we handled the accelerator */ g_value_set_boolean (return_value, TRUE); } +static void +gtk_action_set_action_group (GtkAction *action, + GtkActionGroup *action_group) +{ + g_return_if_fail (GTK_IS_ACTION (action)); + + if (action->private_data->action_group == NULL) + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + else + g_return_if_fail (action_group == NULL); + + action->private_data->action_group = action_group; +} + /** * gtk_action_set_accel_path: * @action: the action object diff --git a/gtk/gtkaction.h b/gtk/gtkaction.h index 34cec2cda..53209baa1 100644 --- a/gtk/gtkaction.h +++ b/gtk/gtkaction.h @@ -86,6 +86,10 @@ GtkAction *gtk_action_new (const gchar *name, const gchar *tooltip, const gchar *stock_id); const gchar* gtk_action_get_name (GtkAction *action); +gboolean gtk_action_is_sensitive (GtkAction *action); +gboolean gtk_action_get_sensitive (GtkAction *action); +gboolean gtk_action_is_visible (GtkAction *action); +gboolean gtk_action_get_visible (GtkAction *action); void gtk_action_activate (GtkAction *action); GtkWidget* gtk_action_create_icon (GtkAction *action, GtkIconSize icon_size); diff --git a/gtk/gtkactiongroup.c b/gtk/gtkactiongroup.c index 348ce4551..4c3ef728e 100644 --- a/gtk/gtkactiongroup.c +++ b/gtk/gtkactiongroup.c @@ -35,6 +35,7 @@ #include "gtktoggleaction.h" #include "gtkradioaction.h" #include "gtkaccelmap.h" +#include "gtkmarshalers.h" #include "gtkintl.h" #define GTK_ACTION_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ACTION_GROUP, GtkActionGroupPrivate)) @@ -42,6 +43,8 @@ struct _GtkActionGroupPrivate { gchar *name; + gboolean sensitive; + gboolean visible; GHashTable *actions; GtkTranslateFunc translate_func; @@ -49,10 +52,21 @@ struct _GtkActionGroupPrivate GtkDestroyNotify translate_notify; }; +enum +{ + CONNECT_PROXY, + DISCONNECT_PROXY, + PRE_ACTIVATE, + POST_ACTIVATE, + LAST_SIGNAL +}; + enum { PROP_0, - PROP_NAME + PROP_NAME, + PROP_SENSITIVE, + PROP_VISIBLE }; static void gtk_action_group_init (GtkActionGroup *self); @@ -98,6 +112,7 @@ gtk_action_group_get_type (void) } static GObjectClass *parent_class = NULL; +static guint action_group_signals[LAST_SIGNAL] = { 0 }; static void gtk_action_group_class_init (GtkActionGroupClass *klass) @@ -120,6 +135,114 @@ gtk_action_group_class_init (GtkActionGroupClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_SENSITIVE, + g_param_spec_boolean ("sensitive", + _("Sensitive"), + _("Whether the action group is enabled."), + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_VISIBLE, + g_param_spec_boolean ("visible", + _("Visible"), + _("Whether the action group is visible."), + TRUE, + G_PARAM_READWRITE)); + + /** + * GtkGroupAction::connect-proxy: + * @action_group: the group + * @action: the action + * @proxy: the proxy + * + * The connect_proxy signal is emitted after connecting a proxy to + * an action in the group. Note that the proxy may have been connected + * to a different action before. + * + * This is intended for simple customizations for which a custom action + * class would be too clumsy, e.g. showing tooltips for menuitems in the + * statusbar. + * + * #GtkUIManager proxies the signal and provides global notification + * just before any action is connected to a proxy, which is probably more + * convenient to use. + * + * Since: 2.4 + */ + action_group_signals[CONNECT_PROXY] = + g_signal_new ("connect_proxy", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ACTION, GTK_TYPE_WIDGET); + + /** + * GtkAction::disconnect-proxy: + * @action_group: the group + * @action: the action + * @proxy: the proxy + * + * The disconnect_proxy signal is emitted after disconnecting a proxy + * from an action in the group. + * + * #GtkUIManager proxies the signal and provides global notification + * just before any action is connected to a proxy, which is probably more + * convenient to use. + * + * Since: 2.4 + */ + action_group_signals[DISCONNECT_PROXY] = + g_signal_new ("disconnect_proxy", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ACTION, GTK_TYPE_WIDGET); + + /** + * GtkActionGroup::pre_activate: + * @action_group: the group + * @action: the action + * + * The pre_activate signal is emitted just before the @action in the + * @action_group is activated + * + * This is intended for #GtkUIManager to proxy the signal and provide global + * notification just before any action is activated. + * + * Since: 2.4 + */ + action_group_signals[PRE_ACTIVATE] = + g_signal_new ("pre_activate", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_ACTION); + + /** + * GtkActionGroup::post_activate: + * @action_group: the group + * @action: the action + * + * The post_activate signal is emitted just after the @action in the + * @action_group is activated + * + * This is intended for #GtkUIManager to proxy the signal and provide global + * notification just after any action is activated. + * + * Since: 2.4 + */ + action_group_signals[POST_ACTIVATE] = + g_signal_new ("post_activate", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_ACTION); + g_type_class_add_private (gobject_class, sizeof (GtkActionGroupPrivate)); } @@ -128,6 +251,8 @@ gtk_action_group_init (GtkActionGroup *self) { self->private_data = GTK_ACTION_GROUP_GET_PRIVATE (self); self->private_data->name = NULL; + self->private_data->sensitive = TRUE; + self->private_data->visible = TRUE; self->private_data->actions = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); @@ -197,6 +322,12 @@ gtk_action_group_set_property (GObject *object, self->private_data->name = g_value_dup_string (value); g_free (tmp); break; + case PROP_SENSITIVE: + gtk_action_group_set_sensitive (self, g_value_get_boolean (value)); + break; + case PROP_VISIBLE: + gtk_action_group_set_visible (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -218,6 +349,12 @@ gtk_action_group_get_property (GObject *object, case PROP_NAME: g_value_set_string (value, self->private_data->name); break; + case PROP_SENSITIVE: + g_value_set_boolean (value, self->private_data->sensitive); + break; + case PROP_VISIBLE: + g_value_set_boolean (value, self->private_data->visible); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -249,6 +386,110 @@ gtk_action_group_get_name (GtkActionGroup *action_group) return action_group->private_data->name; } +/** + * gtk_action_group_get_sensitive: + * @action_group: the action group + * + * Returns %TRUE if the group is sensitive. The constituent actions + * can only be logically sensitive (see gtk_action_is_sensitive()) if + * they are sensitive (see gtk_action_get_sensitive()) and their group + * is sensitive. + * + * Return value: %TRUE if the group is sensitive. + * + * Since: 2.4 + */ +gboolean +gtk_action_group_get_sensitive (GtkActionGroup *action_group) +{ + g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE); + + return action_group->private_data->sensitive; +} + +static void +cb_set_action_sensitivity (const gchar *name, GtkAction *action) +{ + /* Minor optimization, the action_groups state only effects actions that are + * themselves sensitive */ + if (gtk_action_get_sensitive (action)) + g_object_notify (G_OBJECT (action), "sensitive"); +} + +/** + * gtk_action_group_set_sensitive: + * @action_group: the action group + * @sensitive: new sensitivity + * + * Changes the sensitivity of @action_group + * + * Since: 2.4 + */ +void +gtk_action_group_set_sensitive (GtkActionGroup *action_group, gboolean sensitive) +{ + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + + if (action_group->private_data->sensitive ^ sensitive) + { + action_group->private_data->sensitive = sensitive; + g_hash_table_foreach (action_group->private_data->actions, + (GHFunc) cb_set_action_sensitivity, NULL); + } +} + +/** + * gtk_action_group_get_visible: + * @action_group: the action group + * + * Returns %TRUE if the group is visible. The constituent actions + * can only be logically visible (see gtk_action_is_visible()) if + * they are visible (see gtk_action_get_visible()) and their group + * is visible. + * + * Return value: %TRUE if the group is sensitive. + * + * Since: 2.4 + */ +gboolean +gtk_action_group_get_visible (GtkActionGroup *action_group) +{ + g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE); + + return action_group->private_data->visible; +} + +static void +cb_set_action_visiblity (const gchar *name, GtkAction *action) +{ + /* Minor optimization, the action_groups state only effects actions that are + * themselves sensitive */ + if (gtk_action_get_visible (action)) + g_object_notify (G_OBJECT (action), "visible"); +} + +/** + * gtk_action_group_set_visible: + * @action_group: the action group + * @visible: new visiblity + * + * Changes the visible of @action_group. + * + * Since: 2.4 + */ +void +gtk_action_group_set_visible (GtkActionGroup *action_group, gboolean visible) +{ + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + + if (action_group->private_data->visible ^ visible) + { + action_group->private_data->visible = visible; + g_hash_table_foreach (action_group->private_data->actions, + (GHFunc) cb_set_action_visiblity, NULL); + } +} + /** * gtk_action_group_get_action: * @action_group: the action group @@ -291,6 +532,7 @@ gtk_action_group_add_action (GtkActionGroup *action_group, g_hash_table_insert (action_group->private_data->actions, g_strdup (gtk_action_get_name (action)), g_object_ref (action)); + g_object_set (G_OBJECT (action), "action_group", action_group, NULL); } /** @@ -365,6 +607,7 @@ gtk_action_group_remove_action (GtkActionGroup *action_group, /* extra protection to make sure action->name is valid */ g_object_ref (action); g_hash_table_remove (action_group->private_data->actions, gtk_action_get_name (action)); + g_object_set (G_OBJECT (action), "action_group", NULL, NULL); g_object_unref (action); } @@ -585,7 +828,7 @@ gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group, user_data, (GClosureNotify)destroy, 0); gtk_action_group_add_action_with_accel (action_group, - action, + GTK_ACTION (action), entries[i].accelerator); g_object_unref (action); } @@ -656,7 +899,7 @@ gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, GtkTranslateFunc translate_func; gpointer translate_data; GSList *group = NULL; - GtkAction *first_action = NULL; + GtkRadioAction *first_action = NULL; g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); @@ -693,10 +936,10 @@ gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, group = gtk_radio_action_get_group (action); if (value == entries[i].value) - gtk_toggle_action_set_active (action, TRUE); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); gtk_action_group_add_action_with_accel (action_group, - action, + GTK_ACTION (action), entries[i].accelerator); g_object_unref (action); } @@ -771,3 +1014,36 @@ gtk_action_group_set_translation_domain (GtkActionGroup *action_group, g_strdup (domain), g_free); } + +/* Protected for use by GtkAction */ +void +_gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy) +{ + g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0, + action, proxy); +} + +void +_gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy) +{ + g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0, + action, proxy); +} + +void +_gtk_action_group_emit_pre_activate (GtkActionGroup *action_group, + GtkAction *action) +{ + g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action); +} + +void +_gtk_action_group_emit_post_activate (GtkActionGroup *action_group, + GtkAction *action) +{ + g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action); +} diff --git a/gtk/gtkactiongroup.h b/gtk/gtkactiongroup.h index c4ef39b55..5d91dccf0 100644 --- a/gtk/gtkactiongroup.h +++ b/gtk/gtkactiongroup.h @@ -63,7 +63,7 @@ struct _GtkActionGroupClass GObjectClass parent_class; GtkAction *(* get_action) (GtkActionGroup *action_group, - const gchar *action_name); + const gchar *action_name); /* Padding for future expansion */ void (*_gtk_reserved1) (void); @@ -106,54 +106,72 @@ struct _GtkRadioActionEntry GType gtk_action_group_get_type (void); GtkActionGroup *gtk_action_group_new (const gchar *name); const gchar *gtk_action_group_get_name (GtkActionGroup *action_group); +gboolean gtk_action_group_get_sensitive (GtkActionGroup *action_group); +void gtk_action_group_set_sensitive (GtkActionGroup *action_group, + gboolean sensitive); +gboolean gtk_action_group_get_visible (GtkActionGroup *action_group); +void gtk_action_group_set_visible (GtkActionGroup *action_group, + gboolean visible); GtkAction *gtk_action_group_get_action (GtkActionGroup *action_group, - const gchar *action_name); + const gchar *action_name); GList *gtk_action_group_list_actions (GtkActionGroup *action_group); void gtk_action_group_add_action (GtkActionGroup *action_group, - GtkAction *action); -void gtk_action_group_add_action_with_accel (GtkActionGroup *action_group, - GtkAction *action, - const gchar *accelerator); + GtkAction *action); +void gtk_action_group_add_action_with_accel (GtkActionGroup *action_group, + GtkAction *action, + const gchar *accelerator); void gtk_action_group_remove_action (GtkActionGroup *action_group, - GtkAction *action); + GtkAction *action); void gtk_action_group_add_actions (GtkActionGroup *action_group, - GtkActionEntry *entries, - guint n_entries, - gpointer user_data); + GtkActionEntry *entries, + guint n_entries, + gpointer user_data); void gtk_action_group_add_toggle_actions (GtkActionGroup *action_group, - GtkToggleActionEntry *entries, - guint n_entries, - gpointer user_data); + GtkToggleActionEntry *entries, + guint n_entries, + gpointer user_data); void gtk_action_group_add_radio_actions (GtkActionGroup *action_group, - GtkRadioActionEntry *entries, - guint n_entries, - gint value, - GCallback on_change, - gpointer user_data); + GtkRadioActionEntry *entries, + guint n_entries, + gint value, + GCallback on_change, + gpointer user_data); void gtk_action_group_add_actions_full (GtkActionGroup *action_group, - GtkActionEntry *entries, - guint n_entries, - gpointer user_data, - GDestroyNotify destroy); + GtkActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy); void gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group, - GtkToggleActionEntry *entries, - guint n_entries, - gpointer user_data, - GDestroyNotify destroy); + GtkToggleActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy); void gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, - GtkRadioActionEntry *entries, - guint n_entries, - gint value, - GCallback on_change, - gpointer user_data, - GDestroyNotify destroy); + GtkRadioActionEntry *entries, + guint n_entries, + gint value, + GCallback on_change, + gpointer user_data, + GDestroyNotify destroy); void gtk_action_group_set_translate_func (GtkActionGroup *action_group, - GtkTranslateFunc func, - gpointer data, - GtkDestroyNotify notify); + GtkTranslateFunc func, + gpointer data, + GtkDestroyNotify notify); void gtk_action_group_set_translation_domain (GtkActionGroup *action_group, - const gchar *domain); + const gchar *domain); + +/* Protected for use by GtkAction */ +void _gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy); +void _gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy); +void _gtk_action_group_emit_pre_activate (GtkActionGroup *action_group, + GtkAction *action); +void _gtk_action_group_emit_post_activate (GtkActionGroup *action_group, + GtkAction *action); G_END_DECLS diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c index 1a4b390d0..9bf3fd0d3 100644 --- a/gtk/gtkuimanager.c +++ b/gtk/gtkuimanager.c @@ -139,6 +139,10 @@ enum { ADD_WIDGET, ACTIONS_CHANGED, + CONNECT_PROXY, + DISCONNECT_PROXY, + PRE_ACTIVATE, + POST_ACTIVATE, LAST_SIGNAL }; @@ -149,7 +153,7 @@ enum PROP_UI }; -static guint merge_signals[LAST_SIGNAL] = { 0 }; +static guint ui_manager_signals[LAST_SIGNAL] = { 0 }; static GMemChunk *merge_node_chunk = NULL; @@ -235,7 +239,7 @@ gtk_ui_manager_class_init (GtkUIManagerClass *klass) * * Since: 2.4 */ - merge_signals[ADD_WIDGET] = + ui_manager_signals[ADD_WIDGET] = g_signal_new ("add_widget", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, @@ -253,7 +257,7 @@ gtk_ui_manager_class_init (GtkUIManagerClass *klass) * * Since: 2.4 */ - merge_signals[ACTIONS_CHANGED] = + ui_manager_signals[ACTIONS_CHANGED] = g_signal_new ("actions_changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, @@ -262,6 +266,90 @@ gtk_ui_manager_class_init (GtkUIManagerClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /** + * GtkUIManager::connect_proxy: + * @uimanager: the ui manager + * @action: the action + * @proxy: the proxy + * + * The connect_proxy signal is emitted after connecting a proxy to + * an action in the group. + * + * This is intended for simple customizations for which a custom action + * class would be too clumsy, e.g. showing tooltips for menuitems in the + * statusbar. + * + * Since: 2.4 + */ + ui_manager_signals[CONNECT_PROXY] = + g_signal_new ("connect_proxy", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ACTION, GTK_TYPE_WIDGET); + + /** + * GtkUIManager::disconnect_proxy: + * @uimanager: the ui manager + * @action: the action + * @proxy: the proxy + * + * The disconnect_proxy signal is emitted after disconnecting a proxy + * from an action in the group. + * + * Since: 2.4 + */ + ui_manager_signals[DISCONNECT_PROXY] = + g_signal_new ("disconnect_proxy", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ACTION, GTK_TYPE_WIDGET); + + /** + * GtkUIManager::pre_activate: + * @uimanager: the ui manager + * @action: the action + * + * The pre_activate signal is emitted just before the @action + * is activated. + * + * This is intended for applications to get notification + * just before any action is activated. + * + * Since: 2.4 + */ + ui_manager_signals[PRE_ACTIVATE] = + g_signal_new ("pre_activate", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_ACTION); + + /** + * GtkUIManager::post_activate: + * @uimanager: the ui manager + * @action: the action + * + * The post_activate signal is emitted just after the @action + * is activated. + * + * This is intended for applications to get notification + * just after any action is activated. + * + * Since: 2.4 + */ + ui_manager_signals[POST_ACTIVATE] = + g_signal_new ("post_activate", + G_OBJECT_CLASS_TYPE (klass), + 0, 0, NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_ACTION); + g_type_class_add_private (gobject_class, sizeof (GtkUIManagerPrivate)); } @@ -423,6 +511,40 @@ gtk_ui_manager_set_add_tearoffs (GtkUIManager *self, } } +static void +cb_proxy_connect_proxy (GtkActionGroup *group, + GtkAction *action, + GtkWidget *proxy, + GtkUIManager *self) +{ + g_signal_emit (self, ui_manager_signals[CONNECT_PROXY], 0, action, proxy); +} + +static void +cb_proxy_disconnect_proxy (GtkActionGroup *group, + GtkAction *action, + GtkWidget *proxy, + GtkUIManager *self) +{ + g_signal_emit (self, ui_manager_signals[DISCONNECT_PROXY], 0, action, proxy); +} + +static void +cb_proxy_pre_activate (GtkActionGroup *group, + GtkAction *action, + GtkUIManager *self) +{ + g_signal_emit (self, ui_manager_signals[PRE_ACTIVATE], 0, action); +} + +static void +cb_proxy_post_activate (GtkActionGroup *group, + GtkAction *action, + GtkUIManager *self) +{ + g_signal_emit (self, ui_manager_signals[POST_ACTIVATE], 0, action); +} + /** * gtk_ui_manager_insert_action_group: * @self: a #GtkUIManager object @@ -448,11 +570,16 @@ gtk_ui_manager_insert_action_group (GtkUIManager *self, g_object_ref (action_group); self->private_data->action_groups = g_list_insert (self->private_data->action_groups, action_group, pos); + g_object_connect (action_group, + "object_signal::connect_proxy", G_CALLBACK (cb_proxy_connect_proxy), self, + "object_signal::disconnect_proxy", G_CALLBACK (cb_proxy_disconnect_proxy), self, + "object_signal::pre_activate", G_CALLBACK (cb_proxy_pre_activate), self, + "object_signal::post_activate", G_CALLBACK (cb_proxy_post_activate), self, 0); /* dirty all nodes, as action bindings may change */ dirty_all_nodes (self); - g_signal_emit (self, merge_signals[ACTIONS_CHANGED], 0); + g_signal_emit (self, ui_manager_signals[ACTIONS_CHANGED], 0); } /** @@ -476,12 +603,19 @@ gtk_ui_manager_remove_action_group (GtkUIManager *self, self->private_data->action_groups = g_list_remove (self->private_data->action_groups, action_group); + + g_object_disconnect (action_group, + "any_signal::connect_proxy", G_CALLBACK (cb_proxy_connect_proxy), self, + "any_signal::disconnect_proxy", G_CALLBACK (cb_proxy_disconnect_proxy), self, + "any_signal::pre_activate", G_CALLBACK (cb_proxy_pre_activate), self, + "any_signal::post_activate", G_CALLBACK (cb_proxy_post_activate), self, + 0); g_object_unref (action_group); /* dirty all nodes, as action bindings may change */ dirty_all_nodes (self); - g_signal_emit (self, merge_signals[ACTIONS_CHANGED], 0); + g_signal_emit (self, ui_manager_signals[ACTIONS_CHANGED], 0); } /** @@ -1952,7 +2086,7 @@ update_node (GtkUIManager *self, info->proxy = gtk_menu_bar_new (); gtk_widget_set_name (info->proxy, info->name); gtk_widget_show (info->proxy); - g_signal_emit (self, merge_signals[ADD_WIDGET], 0, info->proxy); + g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy); } break; case NODE_TYPE_POPUP: @@ -2038,7 +2172,7 @@ update_node (GtkUIManager *self, info->proxy = gtk_toolbar_new (); gtk_widget_set_name (info->proxy, info->name); gtk_widget_show (info->proxy); - g_signal_emit (self, merge_signals[ADD_WIDGET], 0, info->proxy); + g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy); } break; case NODE_TYPE_MENU_PLACEHOLDER: diff --git a/tests/testmerge.c b/tests/testmerge.c index 75d94de5a..98f508cbe 100644 --- a/tests/testmerge.c +++ b/tests/testmerge.c @@ -51,7 +51,7 @@ dump_toplevels (GtkWidget *button, GTK_UI_MANAGER_TOOLBAR | GTK_UI_MANAGER_POPUP); - g_slist_foreach (toplevels, print_toplevel, NULL); + g_slist_foreach (toplevels, (GFunc)print_toplevel, NULL); g_slist_free (toplevels); } @@ -522,7 +522,8 @@ unset_tip (GtkWidget *widget) } static void -connect_proxy (GtkAction *action, +connect_proxy (GtkUIManager *merge, + GtkAction *action, GtkWidget *proxy, GtkWidget *statusbar) { @@ -560,7 +561,6 @@ main (int argc, char **argv) { GtkActionGroup *action_group; GtkAction *action; - GList *tmp; GtkUIManager *merge; GtkWidget *window, *table, *frame, *menu_box, *vbox, *view; GtkWidget *button, *area, *statusbar; @@ -623,15 +623,9 @@ main (int argc, char **argv) button); gtk_widget_show (button); - for (tmp = gtk_action_group_list_actions (action_group); - tmp != NULL; - tmp = tmp->next) - { - action = tmp->data; - g_signal_connect (action, "connect-proxy", - G_CALLBACK (connect_proxy), statusbar); - } merge = gtk_ui_manager_new (); + + g_signal_connect (merge, "connect-proxy", G_CALLBACK (connect_proxy), statusbar); g_signal_connect (area, "button_press_event", G_CALLBACK (area_press), merge); gtk_ui_manager_insert_action_group (merge, action_group, 0);