Enabled the minimise_all menu, and set the title bar to reflect the usage of the...
[pspp] / 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
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   GtkWindowClass *parent_class = g_type_class_peek_parent (class);
185
186   if ( window->finalized )
187     return;
188
189   window->finalized = TRUE;
190
191   g_debug ("%s %p", __FUNCTION__, object);
192
193   g_hash_table_remove (class->name_table, window->name);
194   free (window->name);
195
196   if (G_OBJECT_CLASS (parent_class)->finalize)
197      (*G_OBJECT_CLASS (parent_class)->finalize) (object);
198 }
199
200
201 static void
202 psppire_window_class_init (PsppireWindowClass *class)
203 {
204   GObjectClass *object_class = G_OBJECT_CLASS (class);
205
206   GParamSpec *use_class_spec =
207     g_param_spec_enum ("usage",
208                        "Usage",
209                        "What the window is used for",
210                        G_TYPE_PSPPIRE_WINDOW_USAGE,
211                        PSPPIRE_WINDOW_USAGE_SYNTAX /* default value */,
212                        G_PARAM_CONSTRUCT_ONLY |G_PARAM_READABLE | G_PARAM_WRITABLE);
213
214
215   GParamSpec *filename_spec =
216     g_param_spec_string ("filename",
217                        "File name",
218                        "The name of the file associated with this window, if any",
219                          "Untitled",
220                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT
221                          );
222
223
224   object_class->set_property = psppire_window_set_property;
225   object_class->get_property = psppire_window_get_property;
226
227   g_object_class_install_property (object_class,
228                                    PROP_FILENAME,
229                                    filename_spec);
230
231   g_object_class_install_property (object_class,
232                                    PROP_USAGE,
233                                    use_class_spec);
234
235
236   class->name_table = g_hash_table_new (g_str_hash, g_str_equal);
237
238   g_hash_table_insert (class->name_table, "Untitled", NULL);
239
240   the_class = class;
241 }
242
243
244 static void
245 psppire_window_base_init (PsppireWindowClass *class)
246 {
247   GObjectClass *object_class = G_OBJECT_CLASS (class);
248
249   object_class->finalize = psppire_window_finalize;
250 }
251
252
253
254 static void
255 psppire_window_base_finalize (PsppireWindowClass *class,
256                                 gpointer class_data)
257 {
258   g_hash_table_destroy (class->name_table);
259 }
260
261
262
263 static void
264 psppire_window_init (PsppireWindow *window)
265 {
266   window->name = NULL;
267   window->finalized = FALSE;
268 }
269
270
271 GtkWidget*
272 psppire_window_new (PsppireWindowUsage usage)
273 {
274   return GTK_WIDGET (g_object_new (psppire_window_get_type (),
275                                    "type", GTK_WINDOW_TOPLEVEL,
276                                    "usage", usage,
277                                    NULL));
278 }
279
280
281 const gchar *
282 psppire_window_get_filename (PsppireWindow *w)
283 {
284   const gchar *name = NULL;
285   g_object_get (w, "filename", name, NULL);
286   return name;
287 }
288
289
290 void
291 psppire_window_set_filename (PsppireWindow *w, const gchar *filename)
292 {
293   g_object_set (w, "filename", filename, NULL);
294 }
295
296
297 static void
298 minimise_all  (gpointer key,
299                gpointer value,
300                gpointer user_data)
301 {
302   PsppireWindow *w = PSPPIRE_WINDOW (value);
303
304   gtk_window_iconify (w);
305 }
306
307
308
309 void
310 psppire_window_minimise_all (void)
311 {
312   g_hash_table_foreach (the_class->name_table, minimise_all, NULL);
313 }
314
315
316
317 \f
318
319 GType
320 psppire_window_usage_get_type (void)
321 {
322   static GType etype = 0;
323   if (etype == 0)
324     {
325       static const GEnumValue values[] = {
326         { PSPPIRE_WINDOW_USAGE_SYNTAX, "PSPPIRE_WINDOW_USAGE_SYNTAX",
327           "Syntax" },
328
329         { PSPPIRE_WINDOW_USAGE_OUTPUT, "PSPPIRE_WINDOW_USAGE_OUTPUT",
330           "Output" },
331
332         { PSPPIRE_WINDOW_USAGE_DATA,   "PSPPIRE_WINDOW_USAGE_DATA",
333           "Data" },
334
335         { 0, NULL, NULL }
336       };
337
338       etype = g_enum_register_static
339         (g_intern_static_string ("PsppireWindowUsage"), values);
340     }
341
342   return etype;
343 }