Added "comments" dialog.
[pspp-builds.git] / src / ui / gui / psppire-dialog.c
1 /*
2     PSPPIRE --- A Graphical User Interface for PSPP
3     Copyright (C) 2007  Free Software Foundation
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18     02110-1301, USA. */
19
20
21 #include <config.h>
22
23 #include <gtk/gtk.h>
24 #include <gtk/gtksignal.h>
25 #include "psppire-dialog.h"
26
27 static void psppire_dialog_class_init          (PsppireDialogClass *);
28 static void psppire_dialog_init                (PsppireDialog      *);
29
30
31 enum  {DIALOG_REFRESH,
32        n_SIGNALS};
33
34 static guint signals [n_SIGNALS];
35
36
37 GType
38 psppire_dialog_get_type (void)
39 {
40   static GType dialog_type = 0;
41
42   if (!dialog_type)
43     {
44       static const GTypeInfo dialog_info =
45       {
46         sizeof (PsppireDialogClass),
47         NULL, /* base_init */
48         NULL, /* base_finalize */
49         (GClassInitFunc) psppire_dialog_class_init,
50         NULL, /* class_finalize */
51         NULL, /* class_data */
52         sizeof (PsppireDialog),
53         0,
54         (GInstanceInitFunc) psppire_dialog_init,
55       };
56
57       dialog_type = g_type_register_static (GTK_TYPE_WINDOW,
58                                             "PsppireDialog", &dialog_info, 0);
59     }
60
61   return dialog_type;
62 }
63
64
65
66 static GObjectClass     *parent_class = NULL;
67
68
69 static void
70 psppire_dialog_finalize (GObject *object)
71 {
72   PsppireDialog *dialog ;
73
74   g_return_if_fail (object != NULL);
75   g_return_if_fail (PSPPIRE_IS_DIALOG (object));
76
77   dialog = PSPPIRE_DIALOG (object);
78
79   if (G_OBJECT_CLASS (parent_class)->finalize)
80     G_OBJECT_CLASS (parent_class)->finalize (object);
81 }
82
83
84
85 /* Properties */
86 enum
87 {
88   PROP_0,
89   PROP_ORIENTATION
90 };
91
92
93 static void
94 psppire_dialog_get_property (GObject         *object,
95                              guint            prop_id,
96                              GValue          *value,
97                              GParamSpec      *pspec)
98 {
99   PsppireDialog *dialog = PSPPIRE_DIALOG (object);
100
101   switch (prop_id)
102     {
103     case PROP_ORIENTATION:
104       {
105         if ( GTK_IS_VBOX (dialog->box) )
106           g_value_set_enum (value, PSPPIRE_VERTICAL);
107         else if ( GTK_IS_HBOX (dialog->box))
108           g_value_set_enum (value, PSPPIRE_HORIZONTAL);
109       }
110       break;
111     default:
112       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
113       break;
114     };
115 }
116
117
118 static void
119 dialog_set_orientation (PsppireDialog *dialog, const GValue *orval)
120 {
121   PsppireOrientation orientation = g_value_get_enum (orval);
122
123   if ( dialog->box != NULL)
124     {
125       gtk_container_remove (GTK_CONTAINER (dialog), dialog->box);
126     }
127
128   if ( orientation == PSPPIRE_HORIZONTAL)
129     {
130       dialog->box = gtk_hbox_new (FALSE, 5);
131     }
132   else
133     {
134       dialog->box = gtk_vbox_new (FALSE, 5);
135     }
136
137   gtk_container_add (GTK_CONTAINER (dialog), dialog->box);
138 }
139
140
141 static void
142 psppire_dialog_set_property (GObject         *object,
143                              guint            prop_id,
144                              const GValue    *value,
145                              GParamSpec      *pspec)
146
147 {
148   PsppireDialog *dialog = PSPPIRE_DIALOG (object);
149
150   switch (prop_id)
151     {
152     case PROP_ORIENTATION:
153       dialog_set_orientation (dialog, value);
154       break;
155     default:
156       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
157       break;
158     };
159 }
160
161
162 static GParamSpec *orientation_spec ;
163
164 static void
165 psppire_dialog_class_init (PsppireDialogClass *class)
166 {
167   GObjectClass *object_class = (GObjectClass *) class;
168
169
170   orientation_spec =
171     g_param_spec_enum ("orientation",
172                        "Orientation",
173                        "Which way widgets are packed",
174                        G_TYPE_PSPPIRE_ORIENTATION,
175                        PSPPIRE_HORIZONTAL /* default value */,
176                        G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE);
177
178
179   object_class->set_property = psppire_dialog_set_property;
180   object_class->get_property = psppire_dialog_get_property;
181
182   g_object_class_install_property (object_class,
183                                    PROP_ORIENTATION,
184                                    orientation_spec);
185
186
187
188   signals [DIALOG_REFRESH] =
189     g_signal_new ("refresh",
190                   G_TYPE_FROM_CLASS (class),
191                   G_SIGNAL_RUN_FIRST,
192                   0,
193                   NULL, NULL,
194                   g_cclosure_marshal_VOID__VOID,
195                   G_TYPE_NONE,
196                   0);
197
198
199   object_class->finalize = psppire_dialog_finalize;
200 }
201
202
203
204
205 static void
206 close_dialog (GtkWidget *w, gpointer data)
207 {
208   PsppireDialog *dialog = data;
209
210   psppire_dialog_close (dialog);
211 }
212
213 void
214 psppire_dialog_close (PsppireDialog *dialog)
215 {
216   g_main_loop_quit (dialog->loop);
217   gtk_widget_hide (GTK_WIDGET (dialog));
218 }
219
220
221 static void
222 delete_event_callback (GtkWidget *w, GdkEvent *e, gpointer data)
223 {
224   close_dialog (w, data);
225 }
226
227
228 static void
229 psppire_dialog_init (PsppireDialog *dialog)
230 {
231   GValue value = {0};
232   dialog->box = NULL;
233
234   g_value_init (&value, orientation_spec->value_type);
235   g_param_value_set_default (orientation_spec, &value);
236
237   dialog_set_orientation (dialog, &value);
238
239   g_value_unset (&value);
240
241   g_signal_connect (G_OBJECT (dialog), "delete-event",
242                     G_CALLBACK (delete_event_callback),
243                     dialog);
244
245   gtk_widget_show_all (dialog->box);
246 }
247
248
249 GtkWidget*
250 psppire_dialog_new (void)
251 {
252   PsppireDialog *dialog ;
253
254   dialog = g_object_new (psppire_dialog_get_type (), NULL);
255
256   return GTK_WIDGET (dialog) ;
257 }
258
259 gint
260 psppire_dialog_run (PsppireDialog *dialog)
261 {
262   dialog->loop = g_main_loop_new (NULL, FALSE);
263
264   gtk_widget_show (GTK_WIDGET (dialog));
265
266   g_signal_emit (dialog, signals [DIALOG_REFRESH], 0);
267
268   g_main_loop_run (dialog->loop);
269
270   return dialog->response;
271 }
272
273
274 void
275 psppire_dialog_reload (PsppireDialog *dialog)
276 {
277   g_signal_emit (dialog, signals [DIALOG_REFRESH], 0);
278 }
279
280
281
282
283 GType
284 psppire_orientation_get_type (void)
285 {
286   static GType etype = 0;
287   if (etype == 0)
288     {
289       static const GEnumValue values[] =
290         {
291           { PSPPIRE_HORIZONTAL, "PSPPIRE_HORIZONTAL", "Horizontal" },
292           { PSPPIRE_VERTICAL,   "PSPPIRE_VERTICAL",   "Vertical" },
293           { 0, NULL, NULL }
294         };
295
296       etype = g_enum_register_static
297         (g_intern_static_string ("PsppireOrientation"), values);
298
299     }
300   return etype;
301 }