From 01a4feb7846f006f9169ab8a5550639ee080bf5d Mon Sep 17 00:00:00 2001 From: Jehan Date: Mon, 20 Feb 2023 18:05:21 +0100 Subject: [PATCH] app, libgimpwidgets: GimpAction proxy widgets will display the proper tooltip. The tooltip contains the reason for action inactivity, if relevant. And in case of a GtkMenuItem in particular, it will also contain the "Press F1 for more help" text at the bottom. --- app/widgets/gimpaction.c | 142 +++++++++++++++++---------------- app/widgets/gimpaction.h | 3 - app/widgets/gimpactionimpl.c | 2 - app/widgets/gimpmenu.c | 19 ----- app/widgets/gimpradioaction.c | 15 ---- app/widgets/gimptoggleaction.c | 15 ---- libgimpwidgets/gimphelpui.c | 13 ++- 7 files changed, 77 insertions(+), 132 deletions(-) diff --git a/app/widgets/gimpaction.c b/app/widgets/gimpaction.c index ac3aa839c3..21b7098aee 100644 --- a/app/widgets/gimpaction.c +++ b/app/widgets/gimpaction.c @@ -72,18 +72,18 @@ struct _GimpActionPrivate static GimpActionPrivate * - gimp_action_get_private (GimpAction *action); -static void gimp_action_private_finalize (GimpActionPrivate *priv); + gimp_action_get_private (GimpAction *action); +static void gimp_action_private_finalize (GimpActionPrivate *priv); -static void gimp_action_label_notify (GimpAction *action, - const GParamSpec *pspec, - gpointer data); -static void gimp_action_tooltip_notify (GimpAction *action, - const GParamSpec *pspec, - gpointer data); +static void gimp_action_label_notify (GimpAction *action, + const GParamSpec *pspec, + gpointer data); -static void gimp_action_proxy_destroy (GtkWidget *proxy, - GimpAction *action); +static void gimp_action_proxy_destroy (GtkWidget *proxy, + GimpAction *action); + +static void gimp_action_update_proxy_tooltip (GimpAction *action, + GtkWidget *proxy); G_DEFINE_INTERFACE (GimpAction, gimp_action, GTK_TYPE_ACTION) @@ -133,7 +133,8 @@ gimp_action_default_init (GimpActionInterface *iface) g_param_spec_boolean ("sensitive", NULL, NULL, TRUE, - GIMP_PARAM_READWRITE)); + GIMP_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY)); gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); g_object_interface_install_property (iface, @@ -178,9 +179,6 @@ gimp_action_init (GimpAction *action) g_signal_connect (action, "notify::label", G_CALLBACK (gimp_action_label_notify), NULL); - g_signal_connect (action, "notify::tooltip", - G_CALLBACK (gimp_action_tooltip_notify), - NULL); } @@ -216,40 +214,6 @@ gimp_action_emit_change_state (GimpAction *action, g_variant_unref (value); } -void -gimp_action_set_proxy_tooltip (GimpAction *action, - GtkWidget *proxy) -{ - const gchar *tooltip; - const gchar *reason = NULL; - gchar *escaped_reason = NULL; - gchar *markup; - - g_return_if_fail (GIMP_IS_ACTION (action)); - g_return_if_fail (GTK_IS_WIDGET (proxy)); - - tooltip = gimp_action_get_tooltip (action); - - gimp_action_get_sensitive (action, &reason); - if (reason) - escaped_reason = g_markup_escape_text (reason, -1); - - markup = g_strdup_printf ("%s%s" /* Action tooltip */ - "%s", /* Inactive reason */ - tooltip, - escaped_reason && tooltip ? "\n" : "", - escaped_reason ? escaped_reason : ""); - - if (tooltip || escaped_reason) - gimp_help_set_help_data_with_markup (proxy, markup, - g_object_get_qdata (G_OBJECT (proxy), - GIMP_HELP_ID)); - - g_free (escaped_reason); - g_free (markup); -} - - const gchar * gimp_action_get_name (GimpAction *action) { @@ -274,6 +238,8 @@ gimp_action_set_tooltip (GimpAction *action, const gchar *tooltip) { gtk_action_set_tooltip ((GtkAction *) action, tooltip); + + gimp_action_update_proxy_tooltip (action, NULL); } const gchar * @@ -317,6 +283,7 @@ gimp_action_set_help_id (GimpAction *action, g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID, g_strdup (help_id), (GDestroyNotify) g_free); + gimp_action_update_proxy_tooltip (action, NULL); } const gchar * @@ -353,13 +320,18 @@ gimp_action_set_sensitive (GimpAction *action, { GimpActionPrivate *priv = GET_PRIVATE (action); - g_object_set (action, - "sensitive", sensitive, - NULL); + if (priv->sensitive != sensitive || (! sensitive && reason)) + { + priv->sensitive = sensitive; - g_clear_pointer (&priv->disable_reason, g_free); - if (reason && ! sensitive) - priv->disable_reason = g_strdup (reason); + g_clear_pointer (&priv->disable_reason, g_free); + if (reason && ! sensitive) + priv->disable_reason = g_strdup (reason); + + g_object_notify (G_OBJECT (action), "sensitive"); + + gimp_action_update_proxy_tooltip (action, NULL); + } } gboolean @@ -711,7 +683,9 @@ gimp_action_set_property (GObject *object, g_set_object (&priv->context, g_value_get_object (value)); break; case GIMP_ACTION_PROP_SENSITIVE: - priv->sensitive = g_value_get_boolean (value); + gimp_action_set_sensitive (GIMP_ACTION (object), + g_value_get_boolean (value), + NULL); break; case GIMP_ACTION_PROP_COLOR: g_clear_pointer (&priv->color, g_free); @@ -857,6 +831,8 @@ gimp_action_set_proxy (GimpAction *action, g_signal_connect (proxy, "destroy", gimp_action_proxy_destroy, action); + + gimp_action_update_proxy_tooltip (action, proxy); } } @@ -954,21 +930,6 @@ gimp_action_label_notify (GimpAction *action, } } -static void -gimp_action_tooltip_notify (GimpAction *action, - const GParamSpec *pspec, - gpointer data) -{ - GSList *list; - - for (list = gimp_action_get_proxies (action); - list; - list = g_slist_next (list)) - { - gimp_action_set_proxy_tooltip (action, list->data); - } -} - static void gimp_action_proxy_destroy (GtkWidget *proxy, GimpAction *action) @@ -977,3 +938,44 @@ gimp_action_proxy_destroy (GtkWidget *proxy, priv->proxies = g_list_remove (priv->proxies, proxy); } + +static void +gimp_action_update_proxy_tooltip (GimpAction *action, + GtkWidget *proxy) +{ + GimpActionPrivate *priv; + const gchar *tooltip; + const gchar *help_id; + const gchar *reason = NULL; + gchar *escaped_reason = NULL; + gchar *markup; + + g_return_if_fail (GIMP_IS_ACTION (action)); + + priv = GET_PRIVATE (action); + tooltip = gimp_action_get_tooltip (action); + help_id = gimp_action_get_help_id (action); + + gimp_action_get_sensitive (action, &reason); + if (reason) + escaped_reason = g_markup_escape_text (reason, -1); + + markup = g_strdup_printf ("%s%s" /* Action tooltip */ + "%s", /* Inactive reason */ + tooltip, + escaped_reason && tooltip ? "\n" : "", + escaped_reason ? escaped_reason : ""); + + if (proxy != NULL) + { + gimp_help_set_help_data_with_markup (proxy, markup, help_id); + } + else + { + for (GList *list = priv->proxies; list; list = list->next) + gimp_help_set_help_data_with_markup (list->data, markup, help_id); + } + + g_free (escaped_reason); + g_free (markup); +} diff --git a/app/widgets/gimpaction.h b/app/widgets/gimpaction.h index 928a9b6ed8..5f4eecdce1 100644 --- a/app/widgets/gimpaction.h +++ b/app/widgets/gimpaction.h @@ -67,9 +67,6 @@ void gimp_action_emit_activate (GimpAction *action, void gimp_action_emit_change_state (GimpAction *action, GVariant *value); -void gimp_action_set_proxy_tooltip (GimpAction *action, - GtkWidget *proxy); - const gchar * gimp_action_get_name (GimpAction *action); void gimp_action_set_label (GimpAction *action, diff --git a/app/widgets/gimpactionimpl.c b/app/widgets/gimpactionimpl.c index 1df13a0f34..24e5043455 100644 --- a/app/widgets/gimpactionimpl.c +++ b/app/widgets/gimpactionimpl.c @@ -372,8 +372,6 @@ gimp_action_impl_connect_proxy (GtkAction *action, GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy); gimp_action_set_proxy (GIMP_ACTION (action), proxy); - - gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy); } diff --git a/app/widgets/gimpmenu.c b/app/widgets/gimpmenu.c index 07e3ffdd24..849ca6790a 100644 --- a/app/widgets/gimpmenu.c +++ b/app/widgets/gimpmenu.c @@ -110,9 +110,6 @@ static void gimp_menu_action_notify_visible (GimpAction *action, static void gimp_menu_action_notify_label (GimpAction *action, const GParamSpec *pspec, GtkMenuItem *item); -static void gimp_menu_action_notify_tooltip (GimpAction *action, - const GParamSpec *pspec, - GtkWidget *item); static GtkContainer * gimp_menu_add_submenu (GimpMenu *menu, const gchar *label, @@ -541,15 +538,6 @@ gimp_menu_action_notify_label (GimpAction *action, gtk_menu_item_set_label (item, gimp_action_get_label (action)); } -static void -gimp_menu_action_notify_tooltip (GimpAction *action, - const GParamSpec *pspec, - GtkWidget *item) -{ - gtk_widget_set_tooltip_text (item, - gimp_action_get_tooltip (GIMP_ACTION (action))); -} - static GtkContainer * gimp_menu_add_submenu (GimpMenu *menu, const gchar *label, @@ -676,13 +664,6 @@ gimp_menu_add_action (GimpMenu *menu, G_CALLBACK (gimp_menu_action_notify_sensitive), item, 0); - if (gimp_action_get_tooltip (GIMP_ACTION (action))) - gtk_widget_set_tooltip_text (item, - gimp_action_get_tooltip (GIMP_ACTION (action))); - g_signal_connect_object (action, "notify::tooltip", - G_CALLBACK (gimp_menu_action_notify_tooltip), - item, 0); - if (placeholder) { gchar *key = g_strconcat (container_key, "/", placeholder, NULL); diff --git a/app/widgets/gimpradioaction.c b/app/widgets/gimpradioaction.c index ed1f63a82c..5f724cd446 100644 --- a/app/widgets/gimpradioaction.c +++ b/app/widgets/gimpradioaction.c @@ -80,9 +80,6 @@ static void gimp_radio_action_set_state (GimpAction *gimp_acti static void gimp_radio_action_g_activate (GAction *action, GVariant *parameter); -static void gimp_radio_action_connect_proxy (GtkAction *action, - GtkWidget *proxy); - static void gimp_radio_action_changed (GtkRadioAction *action, GtkRadioAction *current); @@ -100,14 +97,11 @@ static void gimp_radio_action_class_init (GimpRadioActionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkActionClass *action_class = GTK_ACTION_CLASS (klass); GtkRadioActionClass *radio_class = GTK_RADIO_ACTION_CLASS (klass); object_class->get_property = gimp_radio_action_get_property; object_class->set_property = gimp_radio_action_set_property; - action_class->connect_proxy = gimp_radio_action_connect_proxy; - radio_class->changed = gimp_radio_action_changed; gimp_action_install_properties (object_class); @@ -352,15 +346,6 @@ gimp_radio_action_g_activate (GAction *action, gimp_action_history_action_activated (GIMP_ACTION (action)); } -static void -gimp_radio_action_connect_proxy (GtkAction *action, - GtkWidget *proxy) -{ - GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy); - - gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy); -} - static void gimp_radio_action_changed (GtkRadioAction *action, GtkRadioAction *current) diff --git a/app/widgets/gimptoggleaction.c b/app/widgets/gimptoggleaction.c index 52d1c19b0e..26d8ae1372 100644 --- a/app/widgets/gimptoggleaction.c +++ b/app/widgets/gimptoggleaction.c @@ -75,9 +75,6 @@ static GVariant * static void gimp_toggle_action_set_state (GimpAction *gimp_action, GVariant *value); -static void gimp_toggle_action_connect_proxy (GtkAction *action, - GtkWidget *proxy); - static void gimp_toggle_action_toggled (GtkToggleAction *action); static void gimp_toggle_action_g_activate (GAction *action, @@ -97,14 +94,11 @@ static void gimp_toggle_action_class_init (GimpToggleActionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkActionClass *action_class = GTK_ACTION_CLASS (klass); GtkToggleActionClass *toggle_class = GTK_TOGGLE_ACTION_CLASS (klass); object_class->get_property = gimp_toggle_action_get_property; object_class->set_property = gimp_toggle_action_set_property; - action_class->connect_proxy = gimp_toggle_action_connect_proxy; - toggle_class->toggled = gimp_toggle_action_toggled; gimp_action_install_properties (object_class); @@ -332,15 +326,6 @@ gimp_toggle_action_set_state (GimpAction *gimp_action, g_variant_unref (value); } -static void -gimp_toggle_action_connect_proxy (GtkAction *action, - GtkWidget *proxy) -{ - GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy); - - gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy); -} - static void gimp_toggle_action_toggled (GtkToggleAction *action) { diff --git a/libgimpwidgets/gimphelpui.c b/libgimpwidgets/gimphelpui.c index e42195b547..4f523d4c19 100644 --- a/libgimpwidgets/gimphelpui.c +++ b/libgimpwidgets/gimphelpui.c @@ -329,6 +329,11 @@ gimp_help_menu_item_set_tooltip (GtkWidget *widget, { g_return_if_fail (GTK_IS_MENU_ITEM (widget)); + g_object_set (widget, "has-tooltip", FALSE, NULL); + + g_signal_handlers_disconnect_by_func (widget, + gimp_help_menu_item_query_tooltip, + NULL); if (tooltip && help_id) { g_object_set (widget, "has-tooltip", TRUE, NULL); @@ -337,14 +342,6 @@ gimp_help_menu_item_set_tooltip (GtkWidget *widget, G_CALLBACK (gimp_help_menu_item_query_tooltip), NULL); } - else if (! tooltip) - { - g_object_set (widget, "has-tooltip", FALSE, NULL); - - g_signal_handlers_disconnect_by_func (widget, - gimp_help_menu_item_query_tooltip, - NULL); - } } static gboolean