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;
+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_get (vs, "dictionary", &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);
- g_object_set (act->source, "model", act->dict, NULL);
+ 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;
- gtk_window_set_transient_for (GTK_WINDOW (act->dialog), GTK_WINDOW (act->toplevel));
+ 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));
+ 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 )
break;
}
}
-
- gtk_widget_destroy (act->dialog);
}
static void
"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",
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 = activate;
+}
+