Set type hints for older gtk versions
[pspp] / src / ui / gui / psppire-dialog.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2007  Free Software Foundation
3
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.
8
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.
13
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/>. */
16
17
18 #include <config.h>
19
20 #include <gtk/gtk.h>
21 #include <gtk/gtksignal.h>
22 #include "psppire-dialog.h"
23
24 static void psppire_dialog_class_init          (PsppireDialogClass *);
25 static void psppire_dialog_init                (PsppireDialog      *);
26
27
28 enum  {DIALOG_REFRESH,
29        n_SIGNALS};
30
31 static guint signals [n_SIGNALS];
32
33
34 GType
35 psppire_dialog_get_type (void)
36 {
37   static GType dialog_type = 0;
38
39   if (!dialog_type)
40     {
41       static const GTypeInfo dialog_info =
42       {
43         sizeof (PsppireDialogClass),
44         NULL, /* base_init */
45         NULL, /* base_finalize */
46         (GClassInitFunc) psppire_dialog_class_init,
47         NULL, /* class_finalize */
48         NULL, /* class_data */
49         sizeof (PsppireDialog),
50         0,
51         (GInstanceInitFunc) psppire_dialog_init,
52       };
53
54       dialog_type = g_type_register_static (GTK_TYPE_WINDOW,
55                                             "PsppireDialog", &dialog_info, 0);
56     }
57
58   return dialog_type;
59 }
60
61
62
63 static GObjectClass     *parent_class = NULL;
64
65
66 static void
67 psppire_dialog_finalize (GObject *object)
68 {
69   PsppireDialog *dialog ;
70
71   g_return_if_fail (object != NULL);
72   g_return_if_fail (PSPPIRE_IS_DIALOG (object));
73
74   dialog = PSPPIRE_DIALOG (object);
75
76   if (G_OBJECT_CLASS (parent_class)->finalize)
77     G_OBJECT_CLASS (parent_class)->finalize (object);
78 }
79
80
81
82 /* Properties */
83 enum
84 {
85   PROP_0,
86   PROP_ORIENTATION
87 };
88
89
90 static void
91 psppire_dialog_get_property (GObject         *object,
92                              guint            prop_id,
93                              GValue          *value,
94                              GParamSpec      *pspec)
95 {
96   PsppireDialog *dialog = PSPPIRE_DIALOG (object);
97
98   switch (prop_id)
99     {
100     case PROP_ORIENTATION:
101       {
102         if ( GTK_IS_VBOX (dialog->box) )
103           g_value_set_enum (value, PSPPIRE_VERTICAL);
104         else if ( GTK_IS_HBOX (dialog->box))
105           g_value_set_enum (value, PSPPIRE_HORIZONTAL);
106       }
107       break;
108     default:
109       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
110       break;
111     };
112 }
113
114
115 static void
116 dialog_set_orientation (PsppireDialog *dialog, const GValue *orval)
117 {
118   PsppireOrientation orientation = g_value_get_enum (orval);
119
120   if ( dialog->box != NULL)
121     {
122       gtk_container_remove (GTK_CONTAINER (dialog), dialog->box);
123     }
124
125   if ( orientation == PSPPIRE_HORIZONTAL)
126     {
127       dialog->box = gtk_hbox_new (FALSE, 5);
128     }
129   else
130     {
131       dialog->box = gtk_vbox_new (FALSE, 5);
132     }
133
134   gtk_container_add (GTK_CONTAINER (dialog), dialog->box);
135 }
136
137
138 static void
139 psppire_dialog_set_property (GObject         *object,
140                              guint            prop_id,
141                              const GValue    *value,
142                              GParamSpec      *pspec)
143
144 {
145   PsppireDialog *dialog = PSPPIRE_DIALOG (object);
146
147   switch (prop_id)
148     {
149     case PROP_ORIENTATION:
150       dialog_set_orientation (dialog, value);
151       break;
152     default:
153       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
154       break;
155     };
156 }
157
158
159 static GParamSpec *orientation_spec ;
160
161 static void
162 psppire_dialog_class_init (PsppireDialogClass *class)
163 {
164   GObjectClass *object_class = (GObjectClass *) class;
165
166
167   orientation_spec =
168     g_param_spec_enum ("orientation",
169                        "Orientation",
170                        "Which way widgets are packed",
171                        G_TYPE_PSPPIRE_ORIENTATION,
172                        PSPPIRE_HORIZONTAL /* default value */,
173                        G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE);
174
175
176   object_class->set_property = psppire_dialog_set_property;
177   object_class->get_property = psppire_dialog_get_property;
178
179   g_object_class_install_property (object_class,
180                                    PROP_ORIENTATION,
181                                    orientation_spec);
182
183
184
185   signals [DIALOG_REFRESH] =
186     g_signal_new ("refresh",
187                   G_TYPE_FROM_CLASS (class),
188                   G_SIGNAL_RUN_FIRST,
189                   0,
190                   NULL, NULL,
191                   g_cclosure_marshal_VOID__VOID,
192                   G_TYPE_NONE,
193                   0);
194
195
196   object_class->finalize = psppire_dialog_finalize;
197 }
198
199
200
201
202 static void
203 close_dialog (GtkWidget *w, gpointer data)
204 {
205   PsppireDialog *dialog = data;
206
207   psppire_dialog_close (dialog);
208 }
209
210 void
211 psppire_dialog_close (PsppireDialog *dialog)
212 {
213   g_main_loop_quit (dialog->loop);
214   gtk_widget_hide (GTK_WIDGET (dialog));
215 }
216
217
218 static void
219 delete_event_callback (GtkWidget *w, GdkEvent *e, gpointer data)
220 {
221   close_dialog (w, data);
222 }
223
224
225 static void
226 psppire_dialog_init (PsppireDialog *dialog)
227 {
228   GValue value = {0};
229   dialog->box = NULL;
230
231   g_value_init (&value, orientation_spec->value_type);
232   g_param_value_set_default (orientation_spec, &value);
233
234   gtk_window_set_type_hint (GTK_WINDOW (dialog),
235         GDK_WINDOW_TYPE_HINT_DIALOG);
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 }