767e10541d679ee028cbbee3dae14327699855fb
[pspp-builds.git] / src / ui / gui / psppire-window.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2008  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 #include <config.h>
18
19 #include <gtk/gtksignal.h>
20 #include <gtk/gtkwindow.h>
21
22 #include <stdlib.h>
23
24 #include <gettext.h>
25 #define _(msgid) gettext (msgid)
26 #define N_(msgid) msgid
27
28 #include "psppire-window.h"
29
30
31 static void psppire_window_base_finalize (PsppireWindowClass *, gpointer);
32 static void psppire_window_base_init     (PsppireWindowClass *class);
33 static void psppire_window_class_init    (PsppireWindowClass *class);
34 static void psppire_window_init          (PsppireWindow      *window);
35
36
37 static PsppireWindowClass *the_class;
38 static GObjectClass *parent_class;
39
40 GType
41 psppire_window_get_type (void)
42 {
43   static GType psppire_window_type = 0;
44
45   if (!psppire_window_type)
46     {
47       static const GTypeInfo psppire_window_info =
48       {
49         sizeof (PsppireWindowClass),
50         (GBaseInitFunc) psppire_window_base_init,
51         (GBaseFinalizeFunc) psppire_window_base_finalize,
52         (GClassInitFunc)psppire_window_class_init,
53         (GClassFinalizeFunc) NULL,
54         NULL,
55         sizeof (PsppireWindow),
56         0,
57         (GInstanceInitFunc) psppire_window_init,
58       };
59
60       psppire_window_type =
61         g_type_register_static (GTK_TYPE_WINDOW, "PsppireWindow",
62                                 &psppire_window_info, 0);
63     }
64
65   return psppire_window_type;
66 }
67
68
69 /* Properties */
70 enum
71 {
72   PROP_0,
73   PROP_FILENAME,
74   PROP_USAGE
75 };
76
77
78 gchar *
79 uniquify (const gchar *str, int *x)
80 {
81   return g_strdup_printf ("%s%d", str, (*x)++);
82 }
83
84
85
86 static void
87 psppire_window_set_property (GObject         *object,
88                              guint            prop_id,
89                              const GValue    *value,
90                              GParamSpec      *pspec)
91 {
92   PsppireWindow *window = PSPPIRE_WINDOW (object);
93
94   PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object));
95   switch (prop_id)
96     {
97     case PROP_USAGE:
98       window->usage = g_value_get_enum (value);
99       break;
100     case PROP_FILENAME:
101       {
102         gchar mdash[6] = {0,0,0,0,0,0};
103         gchar *basename, *title;
104         const gchar *name = g_value_get_string (value);
105         gchar *candidate_name = strdup (name);
106         int x = 0;
107
108         while ( g_hash_table_lookup (class->name_table, candidate_name))
109           {
110             free (candidate_name);
111             candidate_name = uniquify (name, &x);
112           }
113
114         basename = g_path_get_basename (candidate_name);
115         g_unichar_to_utf8 (0x2014, mdash);
116
117         switch (window->usage)
118           {
119           case PSPPIRE_WINDOW_USAGE_SYNTAX:
120             title = g_strdup_printf ( _("%s %s PSPPIRE Syntax Editor"),
121                                       basename, mdash);
122             break;
123           case PSPPIRE_WINDOW_USAGE_OUTPUT:
124             title = g_strdup_printf ( _("%s %s PSPPIRE Output"),
125                                       basename, mdash);
126           case PSPPIRE_WINDOW_USAGE_DATA:
127             title = g_strdup_printf ( _("%s %s PSPPIRE Data Editor"),
128                                       basename, mdash);
129             break;
130           default:
131             g_assert_not_reached ();
132             break;
133           }
134
135         gtk_window_set_title (GTK_WINDOW (window), title);
136
137         free (window->name);
138         window->name = candidate_name;
139
140
141         g_hash_table_insert (class->name_table, window->name, window);
142
143         free (basename);
144         free (title);
145       }
146       break;
147     default:
148       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
149       break;
150     };
151 }
152
153
154 static void
155 psppire_window_get_property (GObject         *object,
156                              guint            prop_id,
157                              GValue          *value,
158                              GParamSpec      *pspec)
159 {
160   PsppireWindow *window = PSPPIRE_WINDOW (object);
161
162   switch (prop_id)
163     {
164     case PROP_USAGE:
165       g_value_set_enum (value, window->usage);
166       break;
167     case PROP_FILENAME:
168       g_value_set_string (value, window->name);
169       break;
170     default:
171       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
172       break;
173     };
174 }
175
176
177
178 static void
179 psppire_window_finalize (GObject *object)
180 {
181   PsppireWindow *window = PSPPIRE_WINDOW (object);
182   PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object));
183
184   g_hash_table_remove (class->name_table, window->name);
185   free (window->name);
186
187   if (G_OBJECT_CLASS (parent_class)->finalize)
188     G_OBJECT_CLASS (parent_class)->finalize (object);
189 }
190
191
192 static void
193 psppire_window_class_init (PsppireWindowClass *class)
194 {
195   GObjectClass *object_class = G_OBJECT_CLASS (class);
196
197
198
199   GParamSpec *use_class_spec =
200     g_param_spec_enum ("usage",
201                        "Usage",
202                        "What the window is used for",
203                        G_TYPE_PSPPIRE_WINDOW_USAGE,
204                        PSPPIRE_WINDOW_USAGE_SYNTAX /* default value */,
205                        G_PARAM_CONSTRUCT_ONLY |G_PARAM_READABLE | G_PARAM_WRITABLE);
206
207
208   GParamSpec *filename_spec =
209     g_param_spec_string ("filename",
210                        "File name",
211                        "The name of the file associated with this window, if any",
212                          "Untitled",
213                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT
214                          );
215
216
217   object_class->set_property = psppire_window_set_property;
218   object_class->get_property = psppire_window_get_property;
219
220   g_object_class_install_property (object_class,
221                                    PROP_FILENAME,
222                                    filename_spec);
223
224   g_object_class_install_property (object_class,
225                                    PROP_USAGE,
226                                    use_class_spec);
227
228
229   class->name_table = g_hash_table_new (g_str_hash, g_str_equal);
230
231   g_hash_table_insert (class->name_table, "Untitled", NULL);
232
233   the_class = class;
234   parent_class = g_type_class_peek_parent (class);
235 }
236
237
238 static void
239 psppire_window_base_init (PsppireWindowClass *class)
240 {
241   GObjectClass *object_class = G_OBJECT_CLASS (class);
242
243   object_class->finalize = psppire_window_finalize;
244 }
245
246
247
248 static void
249 psppire_window_base_finalize (PsppireWindowClass *class,
250                                 gpointer class_data)
251 {
252   g_hash_table_destroy (class->name_table);
253 }
254
255
256
257 static void
258 psppire_window_init (PsppireWindow *window)
259 {
260   window->name = NULL;
261   window->finalized = FALSE;
262 }
263
264
265 GtkWidget*
266 psppire_window_new (PsppireWindowUsage usage)
267 {
268   return GTK_WIDGET (g_object_new (psppire_window_get_type (),
269                                    "type", GTK_WINDOW_TOPLEVEL,
270                                    "usage", usage,
271                                    NULL));
272 }
273
274
275 const gchar *
276 psppire_window_get_filename (PsppireWindow *w)
277 {
278   const gchar *name = NULL;
279   g_object_get (w, "filename", name, NULL);
280   return name;
281 }
282
283
284 void
285 psppire_window_set_filename (PsppireWindow *w, const gchar *filename)
286 {
287   g_object_set (w, "filename", filename, NULL);
288 }
289
290
291 static void
292 minimise_all  (gpointer key,
293                gpointer value,
294                gpointer user_data)
295 {
296   PsppireWindow *w = PSPPIRE_WINDOW (value);
297
298   gtk_window_iconify (GTK_WINDOW (w));
299 }
300
301
302
303 void
304 psppire_window_minimise_all (void)
305 {
306   g_hash_table_foreach (the_class->name_table, minimise_all, NULL);
307 }
308
309
310
311 \f
312
313 GType
314 psppire_window_usage_get_type (void)
315 {
316   static GType etype = 0;
317   if (etype == 0)
318     {
319       static const GEnumValue values[] = {
320         { PSPPIRE_WINDOW_USAGE_SYNTAX, "PSPPIRE_WINDOW_USAGE_SYNTAX",
321           "Syntax" },
322
323         { PSPPIRE_WINDOW_USAGE_OUTPUT, "PSPPIRE_WINDOW_USAGE_OUTPUT",
324           "Output" },
325
326         { PSPPIRE_WINDOW_USAGE_DATA,   "PSPPIRE_WINDOW_USAGE_DATA",
327           "Data" },
328
329         { 0, NULL, NULL }
330       };
331
332       etype = g_enum_register_static
333         (g_intern_static_string ("PsppireWindowUsage"), values);
334     }
335
336   return etype;
337 }