Merge branch 'master' of ssh://jmd@git.sv.gnu.org/srv/git/pspp
[pspp] / src / ui / gui / psppire-conf.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2009  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    This module provides an interface for simple user preference config
19    parameters.
20 */
21
22 #include <config.h>
23 #include <stdio.h>
24
25 #include "psppire-conf.h"
26
27 static void psppire_conf_init            (PsppireConf      *conf);
28 static void psppire_conf_class_init      (PsppireConfClass *class);
29
30 static void psppire_conf_finalize        (GObject   *object);
31 static void psppire_conf_dispose        (GObject   *object);
32
33 static GObjectClass *parent_class = NULL;
34
35
36 GType
37 psppire_conf_get_type (void)
38 {
39   static GType conf_type = 0;
40
41   if (!conf_type)
42     {
43       static const GTypeInfo conf_info =
44       {
45         sizeof (PsppireConfClass),
46         NULL,           /* base_init */
47         NULL,           /* base_finalize */
48         (GClassInitFunc) psppire_conf_class_init,
49         NULL,           /* class_finalize */
50         NULL,           /* class_data */
51         sizeof (PsppireConf),
52         0,
53         (GInstanceInitFunc) psppire_conf_init,
54       };
55
56       conf_type = g_type_register_static (G_TYPE_OBJECT,
57                                                 "PsppireConf",
58                                                 &conf_info, 0);
59     }
60
61   return conf_type;
62 }
63
64
65 static void
66 conf_read (PsppireConf *conf)
67 {
68   g_key_file_load_from_file (conf->keyfile,
69                              conf->filename,
70                              G_KEY_FILE_KEEP_COMMENTS,
71                              NULL);
72 }
73
74 static void
75 conf_write (PsppireConf *conf)
76 {
77   gsize length = 0;
78
79   gchar *kf = g_key_file_to_data  (conf->keyfile, &length, NULL);
80
81   if ( ! g_file_set_contents (conf->filename, kf, length, NULL) )
82     {
83       g_warning ("Cannot open %s for writing", conf->filename);
84     }
85
86   g_free (kf);
87 }
88
89 static void
90 psppire_conf_dispose  (GObject *object)
91 {
92 }
93
94 static void
95 psppire_conf_finalize (GObject *object)
96 {
97   PsppireConf *conf = PSPPIRE_CONF (object);
98   g_key_file_free (conf->keyfile);
99   g_free (conf->filename);
100 }
101
102
103 static PsppireConf *the_instance = NULL;
104
105 static GObject*
106 psppire_conf_construct   (GType                  type,
107                                      guint                  n_construct_params,
108                                      GObjectConstructParam *construct_params)
109 {
110   GObject *object;
111
112   if (!the_instance)
113     {
114       object = G_OBJECT_CLASS (parent_class)->constructor (type,
115                                                            n_construct_params,
116                                                            construct_params);
117       the_instance = PSPPIRE_CONF (object);
118     }
119   else
120     object = g_object_ref (G_OBJECT (the_instance));
121
122   return object;
123 }
124
125 static void
126 psppire_conf_class_init (PsppireConfClass *class)
127 {
128   GObjectClass *object_class;
129
130   parent_class = g_type_class_peek_parent (class);
131   object_class = (GObjectClass*) class;
132
133   object_class->finalize = psppire_conf_finalize;
134   object_class->dispose = psppire_conf_dispose;
135   object_class->constructor = psppire_conf_construct;
136
137 }
138
139
140 static void
141 psppire_conf_init (PsppireConf *conf)
142 {
143   const gchar *dirname = g_get_user_config_dir ();
144
145   conf->filename = g_strdup_printf ("%s/%s", dirname, "psppirerc");
146
147   conf->keyfile = g_key_file_new ();
148
149   conf->dispose_has_run = FALSE;
150 }
151
152
153 PsppireConf *
154 psppire_conf_new (void)
155 {
156   return g_object_new (psppire_conf_get_type (), NULL);
157 }
158
159
160
161 gboolean
162 psppire_conf_get_int (PsppireConf *conf, const gchar *base,
163                       const gchar *name, gint *value)
164 {
165   gboolean ok;
166   GError *err = NULL;
167   conf_read (conf);
168   *value = g_key_file_get_integer (conf->keyfile,
169                                    base,
170                                    name, &err);
171
172   ok = (err == NULL);
173   if ( err != NULL )
174     g_error_free (err);
175
176   return ok;
177 }
178
179 gboolean
180 psppire_conf_get_boolean (PsppireConf *conf, const gchar *base,
181                           const gchar *name, gboolean *value)
182 {
183   gboolean ok;
184   GError *err = NULL;
185   conf_read (conf);
186   *value = g_key_file_get_boolean (conf->keyfile,
187                                    base,
188                                    name, &err);
189
190   ok = (err == NULL);
191   if ( err != NULL )
192     g_error_free (err);
193
194   return ok;
195 }
196
197
198 void
199 psppire_conf_set_int (PsppireConf *conf,
200                       const gchar *base, const gchar *name,
201                       gint value)
202 {
203   g_key_file_set_integer (conf->keyfile, base, name, value);
204   conf_write (conf);
205 }
206
207 void
208 psppire_conf_set_boolean (PsppireConf *conf,
209                           const gchar *base, const gchar *name,
210                           gboolean value)
211 {
212   g_key_file_set_boolean (conf->keyfile, base, name, value);
213   conf_write (conf);
214 }
215
216 /*
217   A convenience function to set the geometry of a
218   window from from a saved config
219 */
220 void
221 psppire_conf_set_window_geometry (PsppireConf *conf,
222                                   const gchar *base,
223                                   GtkWindow *window)
224 {
225   gint height, width;
226   gint x, y;
227   gboolean maximize;
228
229   if (psppire_conf_get_int (conf, base, "height", &height)
230       &&
231       psppire_conf_get_int (conf, base, "width", &width) )
232     {
233       gtk_window_set_default_size (window, width, height);
234     }
235
236   if ( psppire_conf_get_int (conf, base, "x", &x)
237        &&
238        psppire_conf_get_int (conf, base, "y", &y) )
239     {
240       gtk_window_move (window, x, y);
241     }
242
243   if ( psppire_conf_get_boolean (conf, base, "maximize", &maximize))
244     {
245       if (maximize)
246         gtk_window_maximize (window);
247       else
248         gtk_window_unmaximize (window);
249     }
250 }
251
252
253 /*
254    A convenience function to save the window geometry.
255    This should typically be called from a window's
256    "configure-event" and "window-state-event" signal handlers
257  */
258 void
259 psppire_conf_save_window_geometry (PsppireConf *conf,
260                                    const gchar *base,
261                                    GdkEvent *e)
262 {
263   switch (e->type)
264     {
265     case GDK_CONFIGURE:
266       {
267         GdkEventConfigure *event = &e->configure;
268
269         if ( gdk_window_get_state (event->window) &
270              GDK_WINDOW_STATE_MAXIMIZED )
271           return;
272
273         if ( event->send_event )
274           return;
275
276         psppire_conf_set_int (conf, base, "height", event->height);
277         psppire_conf_set_int (conf, base, "width", event->width);
278
279         psppire_conf_set_int (conf, base, "x", event->x);
280         psppire_conf_set_int (conf, base, "y", event->y);
281       }
282       break;
283     case GDK_WINDOW_STATE:
284       {
285         GdkEventWindowState *event = &e->window_state;
286
287         psppire_conf_set_boolean (conf, base, "maximize",
288                                   event->new_window_state &
289                                   GDK_WINDOW_STATE_MAXIMIZED );
290       }
291       break;
292     default:
293       break;
294     };
295 }