Merge commit 'origin/stable'
[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   gboolean b;
185   GError *err = NULL;
186   conf_read (conf);
187   b = g_key_file_get_boolean (conf->keyfile,
188                               base,
189                               name, &err);
190
191   ok = (err == NULL);
192   if ( err != NULL )
193     g_error_free (err);
194
195   if (ok)
196     *value = b;
197
198   return ok;
199 }
200
201
202 void
203 psppire_conf_set_int (PsppireConf *conf,
204                       const gchar *base, const gchar *name,
205                       gint value)
206 {
207   g_key_file_set_integer (conf->keyfile, base, name, value);
208   conf_write (conf);
209 }
210
211 void
212 psppire_conf_set_boolean (PsppireConf *conf,
213                           const gchar *base, const gchar *name,
214                           gboolean value)
215 {
216   g_key_file_set_boolean (conf->keyfile, base, name, value);
217   conf_write (conf);
218 }
219
220 /*
221   A convenience function to set the geometry of a
222   window from from a saved config
223 */
224 void
225 psppire_conf_set_window_geometry (PsppireConf *conf,
226                                   const gchar *base,
227                                   GtkWindow *window)
228 {
229   gint height, width;
230   gint x, y;
231   gboolean maximize;
232
233   if (psppire_conf_get_int (conf, base, "height", &height)
234       &&
235       psppire_conf_get_int (conf, base, "width", &width) )
236     {
237       gtk_window_set_default_size (window, width, height);
238     }
239
240   if ( psppire_conf_get_int (conf, base, "x", &x)
241        &&
242        psppire_conf_get_int (conf, base, "y", &y) )
243     {
244       gtk_window_move (window, x, y);
245     }
246
247   if ( psppire_conf_get_boolean (conf, base, "maximize", &maximize))
248     {
249       if (maximize)
250         gtk_window_maximize (window);
251       else
252         gtk_window_unmaximize (window);
253     }
254 }
255
256
257 /*
258    A convenience function to save the window geometry.
259    This should typically be called from a window's
260    "configure-event" and "window-state-event" signal handlers
261  */
262 void
263 psppire_conf_save_window_geometry (PsppireConf *conf,
264                                    const gchar *base,
265                                    GdkEvent *e)
266 {
267   switch (e->type)
268     {
269     case GDK_CONFIGURE:
270       {
271         GdkEventConfigure *event = &e->configure;
272
273         if ( gdk_window_get_state (event->window) &
274              GDK_WINDOW_STATE_MAXIMIZED )
275           return;
276
277         psppire_conf_set_int (conf, base, "height", event->height);
278         psppire_conf_set_int (conf, base, "width", event->width);
279
280         psppire_conf_set_int (conf, base, "x", event->x);
281         psppire_conf_set_int (conf, base, "y", event->y);
282       }
283       break;
284     case GDK_WINDOW_STATE:
285       {
286         GdkEventWindowState *event = &e->window_state;
287
288         psppire_conf_set_boolean (conf, base, "maximize",
289                                   event->new_window_state &
290                                   GDK_WINDOW_STATE_MAXIMIZED );
291       }
292       break;
293     default:
294       break;
295     };
296
297 }