/* Hack. We iterate over the accel map instead of the actions, * in order to pull the parameters out of accel map entries */ static void add_accel_closure (gpointer data, const gchar *accel_path, guint accel_key, GdkModifierType accel_mods, gboolean changed) { GtkApplicationWindow *window = data; GActionGroup *actions; const gchar *path; const gchar *p; gchar *action_name; GVariant *parameter; AccelClosure *closure; if (accel_key == 0) return; if (!g_str_has_prefix (accel_path, "<GAction>/")) return; path = accel_path + strlen ("<GAction>/"); p = strchr (path, '/'); if (p) { action_name = g_strndup (path, p - path); parameter = g_variant_parse (NULL, p + 1, NULL, NULL, NULL); if (!parameter) g_warning ("Failed to parse parameter from '%s'\n", accel_path); } else { action_name = g_strdup (path); parameter = NULL; } actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (GTK_WIDGET (window))); if (g_action_group_has_action (actions, action_name)) { closure = (AccelClosure*) g_closure_new_object (sizeof (AccelClosure), g_object_ref (actions)); g_closure_set_marshal (&closure->closure, accel_activate); closure->action_name = g_strdup (action_name); closure->parameter = parameter ? g_variant_ref_sink (parameter) : NULL; window->priv->accel_closures = g_slist_prepend (window->priv->accel_closures, g_closure_ref (&closure->closure)); g_closure_sink (&closure->closure); gtk_accel_group_connect_by_path (window->priv->accels, accel_path, &closure->closure); } else if (parameter) { g_variant_unref (parameter); } g_free (action_name); }
static void gtk_action_init (GtkAction *action) { action->private_data = G_TYPE_INSTANCE_GET_PRIVATE (action, GTK_TYPE_ACTION, GtkActionPrivate); action->private_data->name = NULL; action->private_data->label = NULL; action->private_data->short_label = NULL; action->private_data->tooltip = NULL; action->private_data->stock_id = NULL; action->private_data->icon_name = NULL; action->private_data->visible_horizontal = TRUE; action->private_data->visible_vertical = TRUE; action->private_data->visible_overflown = TRUE; action->private_data->is_important = FALSE; action->private_data->hide_if_empty = TRUE; action->private_data->always_show_image = FALSE; action->private_data->activate_blocked = FALSE; action->private_data->sensitive = TRUE; action->private_data->visible = TRUE; action->private_data->label_set = FALSE; action->private_data->short_label_set = FALSE; action->private_data->accel_count = 0; action->private_data->accel_group = NULL; action->private_data->accel_quark = 0; action->private_data->accel_closure = g_closure_new_object (sizeof (GClosure), G_OBJECT (action)); g_closure_set_marshal (action->private_data->accel_closure, closure_accel_activate); g_closure_ref (action->private_data->accel_closure); g_closure_sink (action->private_data->accel_closure); action->private_data->action_group = NULL; action->private_data->proxies = NULL; action->private_data->gicon = NULL; }
static void gimp_display_shell_close_dialog (GimpDisplayShell *shell, GimpImage *image) { GtkWidget *dialog; GimpMessageBox *box; GtkWidget *label; GtkAccelGroup *accel_group; GClosure *closure; GSource *source; guint accel_key; GdkModifierType accel_mods; gchar *title; gchar *accel_string; gchar *hint; gchar *markup; GFile *file; if (shell->close_dialog) { gtk_window_present (GTK_WINDOW (shell->close_dialog)); return; } file = gimp_image_get_file (image); title = g_strdup_printf (_("Close %s"), gimp_image_get_display_name (image)); shell->close_dialog = dialog = gimp_message_dialog_new (title, "document-save", GTK_WIDGET (shell), GTK_DIALOG_DESTROY_WITH_PARENT, gimp_standard_help_func, NULL, NULL); g_free (title); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Discard Changes"), GTK_RESPONSE_CLOSE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, (file ? GTK_STOCK_SAVE : GTK_STOCK_SAVE_AS), RESPONSE_SAVE, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), RESPONSE_SAVE, GTK_RESPONSE_CLOSE, GTK_RESPONSE_CANCEL, -1); g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &shell->close_dialog); g_signal_connect (dialog, "response", G_CALLBACK (gimp_display_shell_close_response), shell); /* connect <Primary>D to the quit/close button */ accel_group = gtk_accel_group_new (); gtk_window_add_accel_group (GTK_WINDOW (shell->close_dialog), accel_group); g_object_unref (accel_group); closure = g_closure_new_object (sizeof (GClosure), G_OBJECT (shell->close_dialog)); g_closure_set_marshal (closure, gimp_display_shell_close_accel_marshal); gtk_accelerator_parse ("<Primary>D", &accel_key, &accel_mods); gtk_accel_group_connect (accel_group, accel_key, accel_mods, 0, closure); box = GIMP_MESSAGE_DIALOG (dialog)->box; accel_string = gtk_accelerator_get_label (accel_key, accel_mods); hint = g_strdup_printf (_("Press %s to discard all changes and close the image."), accel_string); markup = g_strdup_printf ("<i><small>%s</small></i>", hint); label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_markup (GTK_LABEL (label), markup); gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); gtk_widget_show (label); g_free (markup); g_free (hint); g_free (accel_string); g_signal_connect_object (image, "name-changed", G_CALLBACK (gimp_display_shell_close_name_changed), box, 0); g_signal_connect_object (image, "exported", G_CALLBACK (gimp_display_shell_close_exported), box, 0); gimp_display_shell_close_name_changed (image, box); closure = g_cclosure_new_object (G_CALLBACK (gimp_display_shell_close_time_changed), G_OBJECT (box)); /* update every 10 seconds */ source = g_timeout_source_new_seconds (10); g_source_set_closure (source, closure); g_source_attach (source, NULL); g_source_unref (source); /* The dialog is destroyed with the shell, so it should be safe * to hold an image pointer for the lifetime of the dialog. */ g_object_set_data (G_OBJECT (box), "gimp-image", image); gimp_display_shell_close_time_changed (box); gtk_widget_show (dialog); }