X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-dialog-action.c;h=32cfcc702d57b54257290b1a220788dffda26a47;hb=30cea3a93e0c674cfd581b9ae9e4f3cb5847e639;hp=e2b15e03eba76085b90d9c5756ba8f6a493bf6b4;hpb=7466f9c7baaf5a5d4cc7b670be290395ccb20b65;p=pspp diff --git a/src/ui/gui/psppire-dialog-action.c b/src/ui/gui/psppire-dialog-action.c index e2b15e03eb..32cfcc702d 100644 --- a/src/ui/gui/psppire-dialog-action.c +++ b/src/ui/gui/psppire-dialog-action.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2012 Free Software Foundation + Copyright (C) 2012, 2016 Free Software Foundation This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -84,31 +84,83 @@ psppire_dialog_action_get_property (GObject *object, static void -psppire_dialog_action_activate (PsppireDialogAction *act) +set_toplevel (PsppireDialogAction *act) { - gint response; - - PsppireVarStore *vs; - PsppireDialogActionClass *class = PSPPIRE_DIALOG_ACTION_GET_CLASS (act); + if (act->toplevel) + return; GSList *sl = gtk_ui_manager_get_toplevels (act->uim, GTK_UI_MANAGER_MENUBAR | GTK_UI_MANAGER_TOOLBAR); g_return_if_fail (sl); - + act->toplevel = gtk_widget_get_toplevel (GTK_WIDGET (sl->data)); g_slist_free (sl); +} - vs = PSPPIRE_DATA_WINDOW(act->toplevel)->var_store; - - g_object_get (vs, "dictionary", &act->dict, NULL); +static void +on_destroy_dataset (GObject *w) +{ + GHashTable *t = g_object_get_data (w, "thing-table"); + GSList *dl = g_object_get_data (w, "widget-list"); - g_object_set (act->source, "model", act->dict, NULL); + g_slist_free_full (dl, (GDestroyNotify) gtk_widget_destroy); + g_hash_table_unref (t); +} + +/* Each toplevel widget - that is the data window, which generally has a 1-1 association + with a dataset - has an associated GHashTable. + + This GHashTable is keyed by the address of a PsppireDialogAction, and its values + are user determined pointers (typically a GtkBuilder*). + + This is useful for storing the state of dialogs so they can persist between invocations. +*/ +GHashTable * +psppire_dialog_action_get_hash_table (PsppireDialogAction *act) +{ + set_toplevel (act); - gtk_window_set_transient_for (GTK_WINDOW (act->dialog), GTK_WINDOW (act->toplevel)); + GHashTable *t = g_object_get_data (G_OBJECT (act->toplevel), "thing-table"); + if (t == NULL) + { + t = g_hash_table_new_full (g_direct_hash, g_direct_equal, 0, g_object_unref); + g_object_set_data (G_OBJECT (act->toplevel), "thing-table", t); + g_object_set_data (G_OBJECT (act->toplevel), "widget-list", NULL); + g_signal_connect (act->toplevel, "destroy", G_CALLBACK (on_destroy_dataset), NULL); + } + return t; +} + +static void +psppire_dialog_action_activate (PsppireDialogAction *act) +{ + gint response; + + PsppireDialogActionClass *class = PSPPIRE_DIALOG_ACTION_GET_CLASS (act); + + gboolean first_time = ! act->toplevel; + + set_toplevel (act); + + act->dict = PSPPIRE_DATA_WINDOW(act->toplevel)->dict; + if (act->source) + g_object_set (act->source, "model", act->dict, NULL); + + GSList *wl = g_object_get_data (G_OBJECT (act->toplevel), "widget-list"); + wl = g_slist_prepend (wl, act->dialog); + g_object_set_data (G_OBJECT (act->toplevel), "widget-list", wl); + + gtk_window_set_transient_for (GTK_WINDOW (act->dialog), GTK_WINDOW (act->toplevel)); if (GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate) GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate ( GTK_ACTION (act)); + if (act->source) + gtk_widget_grab_focus (act->source); + + if (first_time) + psppire_dialog_reload (PSPPIRE_DIALOG (act->dialog)); + response = psppire_dialog_run (PSPPIRE_DIALOG (act->dialog)); if ( class->generate_syntax ) @@ -138,7 +190,7 @@ psppire_dialog_action_class_init (PsppireDialogActionClass *class) "Manager", "The GtkUIManager which created this object", GTK_TYPE_UI_MANAGER, - G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE); + G_PARAM_READWRITE); GParamSpec *toplevel_spec = g_param_spec_object ("top-level", @@ -187,3 +239,10 @@ psppire_dialog_action_set_refresh (PsppireDialogAction *pda, g_signal_connect_swapped (pda->dialog, "refresh", G_CALLBACK (refresh), pda); } + +void +psppire_dialog_action_set_activation (gpointer class, activation activate) +{ + GTK_ACTION_CLASS (class)->activate = (void (*)(GtkAction *)) activate; +} +