diff --git a/lib/sp-empty-state-view.c b/lib/sp-empty-state-view.c index 9dc064ad..9174b80c 100644 --- a/lib/sp-empty-state-view.c +++ b/lib/sp-empty-state-view.c @@ -16,6 +16,10 @@ * along with this program. If not, see . */ +#define G_LOG_DOMAIN "sp-empty-state-view" + +#include + #include "sp-empty-state-view.h" typedef struct @@ -41,6 +45,98 @@ sp_empty_state_view_new (void) return g_object_new (SP_TYPE_EMPTY_STATE_VIEW, NULL); } +static gboolean +sp_empty_state_view_action (GtkWidget *widget, + const gchar *prefix, + const gchar *action_name, + GVariant *parameter) +{ + GtkWidget *toplevel; + GApplication *app; + GActionGroup *group = NULL; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + g_return_val_if_fail (prefix, FALSE); + g_return_val_if_fail (action_name, FALSE); + + app = g_application_get_default (); + toplevel = gtk_widget_get_toplevel (widget); + + while ((group == NULL) && (widget != NULL)) + { + group = gtk_widget_get_action_group (widget, prefix); + widget = gtk_widget_get_parent (widget); + } + + if (!group && g_str_equal (prefix, "win") && G_IS_ACTION_GROUP (toplevel)) + group = G_ACTION_GROUP (toplevel); + + if (!group && g_str_equal (prefix, "app") && G_IS_ACTION_GROUP (app)) + group = G_ACTION_GROUP (app); + + if (group && g_action_group_has_action (group, action_name)) + { + g_action_group_activate_action (group, action_name, parameter); + return TRUE; + } + + if (parameter && g_variant_is_floating (parameter)) + { + parameter = g_variant_ref_sink (parameter); + g_variant_unref (parameter); + } + + g_warning ("Failed to locate action %s.%s", prefix, action_name); + + return FALSE; +} + +static gboolean +sp_empty_state_view_activate_link (SpEmptyStateView *self, + const gchar *uri, + GtkLabel *label) +{ + g_assert (SP_IS_EMPTY_STATE_VIEW (self)); + g_assert (uri != NULL); + g_assert (GTK_IS_LABEL (label)); + + if (g_str_has_prefix (uri, "action://")) + { + g_autofree gchar *full_name = NULL; + g_autofree gchar *action_name = NULL; + g_autofree gchar *group_name = NULL; + g_autoptr(GVariant) param = NULL; + g_autoptr(GError) error = NULL; + + uri += strlen ("action://"); + + if (g_action_parse_detailed_name (uri, &full_name, ¶m, &error)) + { + const gchar *dot = strchr (full_name, '.'); + + if (param != NULL && g_variant_is_floating (param)) + param = g_variant_ref_sink (param); + + if (dot == NULL) + return FALSE; + + group_name = g_strndup (full_name, dot - full_name); + action_name = g_strdup (++dot); + + sp_empty_state_view_action (GTK_WIDGET (self), + group_name, + action_name, + param); + + return TRUE; + } + else + g_warning ("%s", error->message); + } + + return FALSE; +} + static void sp_empty_state_view_set_property (GObject *object, guint prop_id, @@ -97,5 +193,13 @@ sp_empty_state_view_class_init (SpEmptyStateViewClass *klass) static void sp_empty_state_view_init (SpEmptyStateView *self) { + SpEmptyStateViewPrivate *priv = sp_empty_state_view_get_instance_private (self); + gtk_widget_init_template (GTK_WIDGET (self)); + + g_signal_connect_object (priv->subtitle, + "activate-link", + G_CALLBACK (sp_empty_state_view_activate_link), + self, + G_CONNECT_SWAPPED); }