diff --git a/ChangeLog b/ChangeLog index 3ff92137f6..5565034098 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-01-03 Matthias Clasen + + * gtk/gtkaction.c: Avoid connecting to notify on our own + properties. + 2006-01-02 Matthias Clasen * gtk/gtkentry.c (gtk_entry_delete_from_cursor): When deleting diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 3ff92137f6..5565034098 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,8 @@ +2006-01-03 Matthias Clasen + + * gtk/gtkaction.c: Avoid connecting to notify on our own + properties. + 2006-01-02 Matthias Clasen * gtk/gtkentry.c (gtk_entry_delete_from_cursor): When deleting diff --git a/gtk/gtkaction.c b/gtk/gtkaction.c index ab2c22bac5..2e1abe2436 100644 --- a/gtk/gtkaction.c +++ b/gtk/gtkaction.c @@ -147,8 +147,24 @@ static void gtk_action_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void gtk_action_set_action_group (GtkAction *action, +static void gtk_action_set_action_group (GtkAction *action, GtkActionGroup *action_group); +static void gtk_action_set_is_important (GtkAction *action, + gboolean is_important); +static void gtk_action_set_label (GtkAction *action, + const gchar *label); +static void gtk_action_set_short_label (GtkAction *action, + const gchar *label); +static void gtk_action_set_visible_horizontal (GtkAction *action, + gboolean visible_horizontal); +static void gtk_action_set_visible_vertical (GtkAction *action, + gboolean visible_vertical); +static void gtk_action_set_tooltip (GtkAction *action, + const gchar *tooltip); +static void gtk_action_set_stock_id (GtkAction *action, + const gchar *stock_id); +static void gtk_action_sync_tooltip (GtkAction *action, + GtkWidget *proxy); static GtkWidget *create_menu_item (GtkAction *action); static GtkWidget *create_tool_item (GtkAction *action); @@ -429,87 +445,37 @@ gtk_action_set_property (GObject *object, g_free (tmp); break; case PROP_LABEL: - tmp = action->private_data->label; - action->private_data->label = g_value_dup_string (value); - g_free (tmp); - action->private_data->label_set = (action->private_data->label != NULL); - /* if label is unset, then use the label from the stock item */ - if (!action->private_data->label_set && action->private_data->stock_id) - { - GtkStockItem stock_item; - - if (gtk_stock_lookup (action->private_data->stock_id, &stock_item)) - action->private_data->label = g_strdup (stock_item.label); - } - /* if short_label is unset, set short_label=label */ - if (!action->private_data->short_label_set) - { - tmp = action->private_data->short_label; - action->private_data->short_label = g_strdup (action->private_data->label); - g_free (tmp); - g_object_notify (object, "short-label"); - } + gtk_action_set_label (action, g_value_get_string (value)); break; case PROP_SHORT_LABEL: - tmp = action->private_data->short_label; - action->private_data->short_label = g_value_dup_string (value); - g_free (tmp); - action->private_data->short_label_set = (action->private_data->short_label != NULL); - /* if short_label is unset, then use the value of label */ - if (!action->private_data->short_label_set) - { - action->private_data->short_label = g_strdup (action->private_data->label); - } + gtk_action_set_short_label (action, g_value_get_string (value)); break; case PROP_TOOLTIP: - tmp = action->private_data->tooltip; - action->private_data->tooltip = g_value_dup_string (value); - g_free (tmp); + gtk_action_set_tooltip (action, g_value_get_string (value)); break; case PROP_STOCK_ID: - tmp = action->private_data->stock_id; - action->private_data->stock_id = g_value_dup_string (value); - g_free (tmp); - /* update label and short_label if appropriate */ - if (!action->private_data->label_set) - { - GtkStockItem stock_item; - - g_free (action->private_data->label); - if (gtk_stock_lookup (action->private_data->stock_id, &stock_item)) - action->private_data->label = g_strdup (stock_item.label); - else - action->private_data->label = NULL; - g_object_notify (object, "label"); - } - if (!action->private_data->short_label_set) - { - tmp = action->private_data->short_label; - action->private_data->short_label = g_strdup (action->private_data->label); - g_free (tmp); - g_object_notify (object, "short-label"); - } + gtk_action_set_stock_id (action, g_value_get_string (value)); break; case PROP_VISIBLE_HORIZONTAL: - action->private_data->visible_horizontal = g_value_get_boolean (value); + gtk_action_set_visible_horizontal (action, g_value_get_boolean (value)); break; case PROP_VISIBLE_VERTICAL: - action->private_data->visible_vertical = g_value_get_boolean (value); + gtk_action_set_visible_vertical (action, g_value_get_boolean (value)); break; case PROP_VISIBLE_OVERFLOWN: action->private_data->visible_overflown = g_value_get_boolean (value); break; case PROP_IS_IMPORTANT: - action->private_data->is_important = g_value_get_boolean (value); + gtk_action_set_is_important (action, g_value_get_boolean (value)); break; case PROP_HIDE_IF_EMPTY: action->private_data->hide_if_empty = g_value_get_boolean (value); break; case PROP_SENSITIVE: - action->private_data->sensitive = g_value_get_boolean (value); + gtk_action_set_sensitive (action, g_value_get_boolean (value)); break; case PROP_VISIBLE: - action->private_data->visible = g_value_get_boolean (value); + gtk_action_set_visible (action, g_value_get_boolean (value)); break; case PROP_ACTION_GROUP: gtk_action_set_action_group (action, g_value_get_object (value)); @@ -607,14 +573,6 @@ 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, @@ -674,54 +632,6 @@ _gtk_action_sync_menu_visible (GtkAction *action, gboolean _gtk_menu_is_empty (GtkWidget *menu); -static void -gtk_action_sync_visible (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - if (GTK_IS_MENU_ITEM (proxy)) - { - GtkWidget *menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)); - - _gtk_action_sync_menu_visible (action, proxy, _gtk_menu_is_empty (menu)); - } - else - { - if (gtk_action_is_visible (action)) - gtk_widget_show (proxy); - else - gtk_widget_hide (proxy); - } -} - -static void -gtk_action_sync_label (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - GtkWidget *label = NULL; - - g_return_if_fail (GTK_IS_MENU_ITEM (proxy)); - label = GTK_BIN (proxy)->child; - - if (GTK_IS_LABEL (label)) - gtk_label_set_label (GTK_LABEL (label), action->private_data->label); -} - -static void -gtk_action_sync_short_label (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - GValue value = { 0, }; - - g_value_init (&value, G_TYPE_STRING); - g_object_get_property (G_OBJECT (action), "short-label", &value); - - g_object_set_property (G_OBJECT (proxy), "label", &value); - g_value_unset (&value); -} - static void gtk_action_sync_stock_id (GtkAction *action, GParamSpec *pspec, @@ -739,35 +649,6 @@ gtk_action_sync_stock_id (GtkAction *action, } } -static void -gtk_action_sync_button_stock_id (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - g_object_set (G_OBJECT (proxy), - "label", - action->private_data->stock_id, - NULL); -} - -static void -gtk_action_sync_tooltip (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - g_return_if_fail (GTK_IS_TOOL_ITEM (proxy)); - - if (GTK_IS_TOOLBAR (gtk_widget_get_parent (proxy))) - { - GtkToolbar *toolbar = GTK_TOOLBAR (gtk_widget_get_parent (proxy)); - - gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (proxy), - toolbar->tooltips, - action->private_data->tooltip, - NULL); - } -} - static gboolean gtk_action_create_menu_proxy (GtkToolItem *tool_item, GtkAction *action) @@ -791,52 +672,6 @@ gtk_action_create_menu_proxy (GtkToolItem *tool_item, return TRUE; } -static void -gtk_action_handle_notify (GtkAction *action, - GParamSpec *pspec, - GtkWidget *proxy) -{ - if (pspec->name == I_("sensitive")) - gtk_action_sync_sensitivity (action, pspec, proxy); - else if (pspec->name == I_("visible")) - gtk_action_sync_visible (action, pspec, proxy); - else if (GTK_IS_MENU_ITEM (proxy) && pspec->name == I_("label")) - gtk_action_sync_label (action, pspec, proxy); - else if (GTK_IS_IMAGE_MENU_ITEM (proxy) && pspec->name == I_("stock-id")) - gtk_action_sync_stock_id (action, pspec, proxy); - else if (GTK_IS_TOOL_ITEM (proxy)) - { - if (pspec->name == I_("visible-horizontal") || - pspec->name == I_("visible-vertical") || - pspec->name == I_("is-important")) - gtk_action_sync_property (action, pspec, proxy); - else if (pspec->name == I_("tooltip")) - gtk_action_sync_tooltip (action, pspec, proxy); - - if (GTK_IS_TOOL_BUTTON (proxy)) - { - if (pspec->name == I_("short-label")) - gtk_action_sync_short_label (action, pspec, proxy); - if (pspec->name == I_("stock-id")) - gtk_action_sync_property (action, pspec, proxy); - } - } - else if (GTK_IS_BUTTON (proxy)) - { - if (gtk_button_get_use_stock (GTK_BUTTON (proxy))) - { - if (pspec->name == I_("stock-id")) - gtk_action_sync_button_stock_id (action, pspec, proxy); - } - else if (GTK_BIN (proxy)->child == NULL || - GTK_IS_LABEL (GTK_BIN (proxy)->child)) - { - if (pspec->name == I_("short-label")) - gtk_action_sync_short_label (action, pspec, proxy); - } - } -} - static void connect_proxy (GtkAction *action, GtkWidget *proxy) @@ -850,9 +685,6 @@ connect_proxy (GtkAction *action, g_signal_connect (proxy, "destroy", G_CALLBACK (remove_proxy), action); - g_signal_connect_object (action, "notify", - G_CALLBACK (gtk_action_handle_notify), proxy, 0); - gtk_widget_set_sensitive (proxy, gtk_action_is_sensitive (action)); if (gtk_action_is_visible (action)) gtk_widget_show (proxy); @@ -926,19 +758,15 @@ connect_proxy (GtkAction *action, } else if (GTK_IS_TOOL_ITEM (proxy)) { - GParamSpec *pspec; - /* toolbar item specific synchronisers ... */ g_object_set (proxy, "visible_horizontal", action->private_data->visible_horizontal, - "visible_vertical", action->private_data->visible_vertical, + "visible_vertical", action->private_data->visible_vertical, "is_important", action->private_data->is_important, NULL); - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (action), - "tooltip"); - gtk_action_sync_tooltip (action, pspec, proxy); + gtk_action_sync_tooltip (action, proxy); g_signal_connect_object (proxy, "create_menu_proxy", G_CALLBACK (gtk_action_create_menu_proxy), @@ -1008,12 +836,6 @@ disconnect_proxy (GtkAction *action, action); /* disconnect handlers for notify::* signals */ - g_signal_handlers_disconnect_by_func (action, - G_CALLBACK (gtk_action_sync_sensitivity), - proxy); - g_signal_handlers_disconnect_by_func (action, - G_CALLBACK (gtk_action_sync_visible), - proxy); g_signal_handlers_disconnect_by_func (action, G_CALLBACK (gtk_action_sync_property), proxy); @@ -1021,16 +843,7 @@ disconnect_proxy (GtkAction *action, g_signal_handlers_disconnect_by_func (action, G_CALLBACK (gtk_action_sync_stock_id), proxy); - /* menu item specific synchronisers ... */ - g_signal_handlers_disconnect_by_func (action, - G_CALLBACK (gtk_action_sync_label), - proxy); - /* toolbar button specific synchronisers ... */ - g_signal_handlers_disconnect_by_func (action, - G_CALLBACK (gtk_action_sync_short_label), - proxy); - g_signal_handlers_disconnect_by_func (proxy, G_CALLBACK (gtk_action_create_menu_proxy), action); @@ -1303,6 +1116,9 @@ void gtk_action_set_sensitive (GtkAction *action, gboolean sensitive) { + GSList *p; + GtkWidget *proxy; + g_return_if_fail (GTK_IS_ACTION (action)); sensitive = sensitive != FALSE; @@ -1311,6 +1127,12 @@ gtk_action_set_sensitive (GtkAction *action, { action->private_data->sensitive = sensitive; + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + gtk_widget_set_sensitive (proxy, sensitive); + } + g_object_notify (G_OBJECT (action), "sensitive"); } } @@ -1374,6 +1196,9 @@ void gtk_action_set_visible (GtkAction *action, gboolean visible) { + GSList *p; + GtkWidget *proxy; + g_return_if_fail (GTK_IS_ACTION (action)); visible = visible != FALSE; @@ -1382,10 +1207,280 @@ gtk_action_set_visible (GtkAction *action, { action->private_data->visible = visible; + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_MENU_ITEM (proxy)) + { + GtkWidget *menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)); + + _gtk_action_sync_menu_visible (action, proxy, _gtk_menu_is_empty (menu)); + } + else + { + if (visible) + gtk_widget_show (proxy); + else + gtk_widget_hide (proxy); + } + } + g_object_notify (G_OBJECT (action), "visible"); } } +static void +gtk_action_set_is_important (GtkAction *action, + gboolean is_important) +{ + GSList *p; + GtkWidget *proxy; + + is_important = is_important != FALSE; + + if (action->private_data->is_important != is_important) + { + action->private_data->is_important = is_important; + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_TOOL_ITEM (proxy)) + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (proxy), + is_important); + } + + g_object_notify (G_OBJECT (action), "is-important"); + } +} + +static void +gtk_action_set_label (GtkAction *action, + const gchar *label) +{ + GSList *p; + GtkWidget *proxy, *child; + gchar *tmp; + + tmp = action->private_data->label; + action->private_data->label = g_strdup (label); + g_free (tmp); + action->private_data->label_set = (action->private_data->label != NULL); + /* if label is unset, then use the label from the stock item */ + if (!action->private_data->label_set && action->private_data->stock_id) + { + GtkStockItem stock_item; + + if (gtk_stock_lookup (action->private_data->stock_id, &stock_item)) + action->private_data->label = g_strdup (stock_item.label); + } + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_MENU_ITEM (proxy)) + { + child = GTK_BIN (proxy)->child; + + if (GTK_IS_LABEL (child)) + gtk_label_set_label (GTK_LABEL (child), + action->private_data->label); + } + } + + g_object_notify (G_OBJECT (action), "label"); + + /* if short_label is unset, set short_label=label */ + if (!action->private_data->short_label_set) + { + gtk_action_set_short_label (action, action->private_data->label); + action->private_data->short_label_set = FALSE; + } +} + +static void +gtk_action_set_short_label (GtkAction *action, + const gchar *label) +{ + GSList *p; + GtkWidget *proxy, *child; + gchar *tmp; + + tmp = action->private_data->short_label; + action->private_data->short_label = g_strdup (label); + g_free (tmp); + action->private_data->short_label_set = (action->private_data->short_label != NULL); + /* if short_label is unset, then use the value of label */ + if (!action->private_data->short_label_set) + action->private_data->short_label = g_strdup (action->private_data->label); + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_TOOL_BUTTON (proxy)) + gtk_tool_button_set_label (GTK_TOOL_BUTTON (proxy), + action->private_data->label); + else if (GTK_IS_BUTTON (proxy) && + !gtk_button_get_use_stock (GTK_BUTTON (proxy))) + { + child = GTK_BIN (proxy)->child; + + if (child == NULL || GTK_IS_LABEL (child)) + gtk_button_set_label (GTK_BUTTON (proxy), + action->private_data->label); + } + } + + g_object_notify (G_OBJECT (action), "short-label"); +} + +static void +gtk_action_set_visible_horizontal (GtkAction *action, + gboolean visible_horizontal) +{ + GSList *p; + GtkWidget *proxy; + + visible_horizontal = visible_horizontal != FALSE; + + if (action->private_data->visible_horizontal != visible_horizontal) + { + action->private_data->visible_horizontal = visible_horizontal; + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_TOOL_ITEM (proxy)) + gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (proxy), + visible_horizontal); + } + + g_object_notify (G_OBJECT (action), "visible-horizontal"); + } +} + +static void +gtk_action_set_visible_vertical (GtkAction *action, + gboolean visible_vertical) +{ + GSList *p; + GtkWidget *proxy; + + visible_vertical = visible_vertical != FALSE; + + if (action->private_data->visible_vertical != visible_vertical) + { + action->private_data->visible_vertical = visible_vertical; + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_TOOL_ITEM (proxy)) + gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (proxy), + visible_vertical); + } + + g_object_notify (G_OBJECT (action), "visible-vertical"); + } +} + +static void +gtk_action_sync_tooltip (GtkAction *action, + GtkWidget *proxy) +{ + GtkWidget *parent; + + parent = gtk_widget_get_parent (proxy); + + if (GTK_IS_TOOL_ITEM (proxy) && GTK_IS_TOOLBAR (parent)) + gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (proxy), + GTK_TOOLBAR (parent)->tooltips, + action->private_data->tooltip, + NULL); +} + +static void +gtk_action_set_tooltip (GtkAction *action, + const gchar *tooltip) +{ + GSList *p; + GtkWidget *proxy; + gchar *tmp; + + tmp = action->private_data->tooltip; + action->private_data->tooltip = g_strdup (tooltip); + g_free (tmp); + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + gtk_action_sync_tooltip (action, proxy); + } + + g_object_notify (G_OBJECT (action), "tooltip"); +} + +static void +gtk_action_set_stock_id (GtkAction *action, + const gchar *stock_id) +{ + GSList *p; + GtkWidget *proxy, *image; + gchar *tmp; + + tmp = action->private_data->stock_id; + action->private_data->stock_id = g_strdup (stock_id); + g_free (tmp); + + for (p = action->private_data->proxies; p; p = p->next) + { + proxy = (GtkWidget *)p->data; + + if (GTK_IS_IMAGE_MENU_ITEM (proxy)) + { + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy)); + + if (GTK_IS_IMAGE (image)) + gtk_image_set_from_stock (GTK_IMAGE (image), + action->private_data->stock_id, GTK_ICON_SIZE_MENU); + } + else if (GTK_IS_TOOL_BUTTON (proxy)) + { + gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (proxy), + action->private_data->stock_id); + } + else if (GTK_IS_BUTTON (proxy) && + gtk_button_get_use_stock (GTK_BUTTON (proxy))) + { + gtk_button_set_label (GTK_BUTTON (proxy), + action->private_data->stock_id); + } + } + + g_object_notify (G_OBJECT (action), "stock-id"); + + /* update label and short_label if appropriate */ + if (!action->private_data->label_set) + { + GtkStockItem stock_item; + + if (gtk_stock_lookup (action->private_data->stock_id, &stock_item)) + gtk_action_set_label (action, stock_item.label); + else + gtk_action_set_label (action, NULL); + + action->private_data->label_set = FALSE; + } +} + + /** * gtk_action_block_activate_from: * @action: the action object