1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2012, 2016 Free Software Foundation
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "psppire-dialog-action.h"
21 #include "psppire-dialog.h"
24 #include "psppire-data-window.h"
26 static void psppire_dialog_action_init (PsppireDialogAction *act);
27 static void psppire_dialog_action_class_init (PsppireDialogActionClass *class);
29 G_DEFINE_ABSTRACT_TYPE (PsppireDialogAction, psppire_dialog_action, GTK_TYPE_ACTION);
40 psppire_dialog_action_set_property (GObject *object,
45 PsppireDialogAction *act = PSPPIRE_DIALOG_ACTION (object);
52 GObject *p = g_value_get_object (value);
53 act->uim = GTK_UI_MANAGER (p);
57 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
64 psppire_dialog_action_get_property (GObject *object,
69 PsppireDialogAction *dialog_action = PSPPIRE_DIALOG_ACTION (object);
74 g_value_take_object (value, dialog_action->uim);
77 g_value_take_object (value, dialog_action->toplevel);
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
87 set_toplevel (PsppireDialogAction *act)
92 GSList *sl = gtk_ui_manager_get_toplevels (act->uim, GTK_UI_MANAGER_MENUBAR | GTK_UI_MANAGER_TOOLBAR);
93 g_return_if_fail (sl);
95 act->toplevel = gtk_widget_get_toplevel (GTK_WIDGET (sl->data));
100 on_destroy_dataset (GObject *w)
102 GHashTable *t = g_object_get_data (w, "thing-table");
103 GSList *dl = g_object_get_data (w, "widget-list");
105 g_slist_free_full (dl, (GDestroyNotify) gtk_widget_destroy);
106 g_hash_table_unref (t);
109 /* Each toplevel widget - that is the data window, which generally has a 1-1 association
110 with a dataset - has an associated GHashTable.
112 This GHashTable is keyed by the address of a PsppireDialogAction, and its values
113 are user determined pointers (typically a GtkBuilder*).
115 This is useful for storing the state of dialogs so they can persist between invocations.
118 psppire_dialog_action_get_hash_table (PsppireDialogAction *act)
122 GHashTable *t = g_object_get_data (G_OBJECT (act->toplevel), "thing-table");
125 t = g_hash_table_new_full (g_direct_hash, g_direct_equal, 0, g_object_unref);
126 g_object_set_data (G_OBJECT (act->toplevel), "thing-table", t);
127 g_object_set_data (G_OBJECT (act->toplevel), "widget-list", NULL);
128 g_signal_connect (act->toplevel, "destroy", G_CALLBACK (on_destroy_dataset), NULL);
135 psppire_dialog_action_activate (PsppireDialogAction *act)
139 PsppireDialogActionClass *class = PSPPIRE_DIALOG_ACTION_GET_CLASS (act);
141 gboolean first_time = ! act->toplevel;
145 act->dict = PSPPIRE_DATA_WINDOW(act->toplevel)->dict;
147 g_object_set (act->source, "model", act->dict, NULL);
149 GSList *wl = g_object_get_data (G_OBJECT (act->toplevel), "widget-list");
150 wl = g_slist_prepend (wl, act->dialog);
151 g_object_set_data (G_OBJECT (act->toplevel), "widget-list", wl);
153 gtk_window_set_transient_for (GTK_WINDOW (act->dialog), GTK_WINDOW (act->toplevel));
155 if (GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate)
156 GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate ( GTK_ACTION (act));
159 gtk_widget_grab_focus (act->source);
162 psppire_dialog_reload (PSPPIRE_DIALOG (act->dialog));
164 response = psppire_dialog_run (PSPPIRE_DIALOG (act->dialog));
166 if ( class->generate_syntax )
170 case GTK_RESPONSE_OK:
171 g_free (execute_syntax_string (PSPPIRE_DATA_WINDOW (act->toplevel),
172 class->generate_syntax (act)));
174 case PSPPIRE_RESPONSE_PASTE:
175 g_free (paste_syntax_to_window (class->generate_syntax (act)));
184 psppire_dialog_action_class_init (PsppireDialogActionClass *class)
186 GObjectClass *object_class = G_OBJECT_CLASS (class);
188 GParamSpec *manager_spec =
189 g_param_spec_object ("manager",
191 "The GtkUIManager which created this object",
195 GParamSpec *toplevel_spec =
196 g_param_spec_object ("top-level",
198 "The top level widget to which this dialog action belongs",
202 object_class->set_property = psppire_dialog_action_set_property;
203 object_class->get_property = psppire_dialog_action_get_property;
205 class->generate_syntax = NULL;
207 class->activate = psppire_dialog_action_activate;
209 g_object_class_install_property (object_class,
213 g_object_class_install_property (object_class,
220 psppire_dialog_action_init (PsppireDialogAction *act)
222 act->toplevel = NULL;
228 psppire_dialog_action_set_valid_predicate (PsppireDialogAction *act,
229 ContentsAreValid dialog_state_valid)
231 psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (act->dialog),
232 dialog_state_valid, act);
236 psppire_dialog_action_set_refresh (PsppireDialogAction *pda,
237 PsppireDialogActionRefresh refresh)
239 g_signal_connect_swapped (pda->dialog, "refresh", G_CALLBACK (refresh), pda);
244 psppire_dialog_action_set_activation (gpointer class, activation activate)
246 GTK_ACTION_CLASS (class)->activate = (void (*)(GtkAction *)) activate;