New objects psppire-window and psppire-syntax-window.
[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
38 GType
39 psppire_window_get_type (void)
40 {
41   static GType psppire_window_type = 0;
42
43   if (!psppire_window_type)
44     {
45       static const GTypeInfo psppire_window_info =
46       {
47         sizeof (PsppireWindowClass),
48         (GBaseInitFunc) psppire_window_base_init,
49         (GBaseFinalizeFunc) psppire_window_base_finalize,
50         (GClassInitFunc)psppire_window_class_init,
51         (GClassFinalizeFunc) NULL,
52         NULL,
53         sizeof (PsppireWindow),
54         0,
55         (GInstanceInitFunc) psppire_window_init,
56       };
57
58       psppire_window_type =
59         g_type_register_static (GTK_TYPE_WINDOW, "PsppireWindow",
60                                 &psppire_window_info, 0);
61     }
62
63   return psppire_window_type;
64 }
65
66
67 /* Properties */
68 enum
69 {
70   PROP_0,
71   PROP_FILENAME
72 };
73
74
75 gchar *
76 uniquify (const gchar *str, int *x)
77 {
78   return g_strdup_printf ("%s%d", str, (*x)++);
79 }
80
81 static void
82 psppire_window_set_property (GObject         *object,
83                              guint            prop_id,
84                              const GValue    *value,
85                              GParamSpec      *pspec)
86 {
87   PsppireWindow *window = PSPPIRE_WINDOW (object);
88
89   PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object));
90   
91   switch (prop_id)
92     {
93     case PROP_FILENAME:
94       {
95         gchar mdash[6] = {0,0,0,0,0,0};
96         gchar *basename, *title;
97         const gchar *name = g_value_get_string (value);
98         gchar *candidate_name = strdup (name);
99         int x = 0;
100
101         while ( g_hash_table_lookup (class->name_table, candidate_name))
102           {
103             free (candidate_name);
104             candidate_name = uniquify (name, &x);
105           }
106
107         basename = g_path_get_basename (candidate_name);
108         g_unichar_to_utf8 (0x2014, mdash);
109
110         title = g_strdup_printf ( _("%s %s PSPPIRE Syntax Editor"), basename, mdash);
111
112         gtk_window_set_title (GTK_WINDOW (window), title);
113
114         free (window->name);
115         window->name = candidate_name;
116
117
118         g_hash_table_insert (class->name_table, window->name, window);
119
120         free (basename);
121         free (title);
122       }
123       break;
124     default:
125       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126       break;
127     };
128 }
129
130
131 static void
132 psppire_window_get_property (GObject         *object,
133                              guint            prop_id,
134                              GValue          *value,
135                              GParamSpec      *pspec)
136 {
137   PsppireWindow *window = PSPPIRE_WINDOW (object);
138
139   switch (prop_id)
140     {
141     case PROP_FILENAME:
142       g_value_set_string (value, window->name);
143       break;
144     default:
145       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
146       break;
147     };
148 }
149
150
151
152 static void
153 psppire_window_finalize (GObject *object)
154 {
155   PsppireWindow *window = PSPPIRE_WINDOW (object);
156   PsppireWindowClass *class = PSPPIRE_WINDOW_CLASS (G_OBJECT_GET_CLASS (object));
157
158   GtkWindowClass *parent_class = g_type_class_peek_parent (class);
159
160   if ( window->finalized )
161     return;
162
163   window->finalized = TRUE;
164
165   g_debug ("%s %p", __FUNCTION__, object);
166
167   g_hash_table_remove (class->name_table, window->name);
168   free (window->name);
169
170   if (G_OBJECT_CLASS (parent_class)->finalize)
171      (*G_OBJECT_CLASS (parent_class)->finalize) (object);
172 }
173
174
175 static void
176 psppire_window_class_init (PsppireWindowClass *class)
177 {
178  GObjectClass *object_class = G_OBJECT_CLASS (class);
179  
180   GParamSpec *filename_spec =
181     g_param_spec_string ("filename",
182                        "File name",
183                        "The name of the file associated with this window, if any",
184                          "Untitled",
185                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT
186                          );
187
188
189   object_class->set_property = psppire_window_set_property;
190   object_class->get_property = psppire_window_get_property;
191
192   g_object_class_install_property (object_class,
193                                    PROP_FILENAME,
194                                    filename_spec);
195
196
197
198   class->name_table = g_hash_table_new (g_str_hash, g_str_equal);
199
200   g_hash_table_insert (class->name_table, "Untitled", NULL);
201 }
202
203
204 static void
205 psppire_window_base_init (PsppireWindowClass *class)
206 {
207   GObjectClass *object_class = G_OBJECT_CLASS (class);
208
209   object_class->finalize = psppire_window_finalize;
210   
211 }
212
213
214
215 static void
216 psppire_window_base_finalize (PsppireWindowClass *class,
217                                 gpointer class_data)
218 {
219   g_hash_table_destroy (class->name_table);
220 }
221
222
223
224 static void
225 psppire_window_init (PsppireWindow *window)
226 {
227   window->name = NULL;
228   window->finalized = FALSE;
229 }
230
231
232 GtkWidget*
233 psppire_window_new (void)
234 {
235   return GTK_WIDGET (g_object_new (psppire_window_get_type (), "type", GTK_WINDOW_TOPLEVEL, NULL));
236 }
237
238
239 const gchar *
240 psppire_window_get_filename (PsppireWindow *w)
241 {
242   const gchar *name = NULL;
243   g_object_get (w, "filename", name, NULL);
244   return name;
245 }
246
247
248 void
249 psppire_window_set_filename (PsppireWindow *w, const gchar *filename)
250 {
251   g_object_set (w, "filename", filename, NULL);
252 }
253