From b4b7591371add6dac8c191a522be4a43ef25b7eb Mon Sep 17 00:00:00 2001
From: John Darrington <john@darrington.wattle.id.au>
Date: Tue, 3 Mar 2009 20:47:40 +0900
Subject: [PATCH] Added a simple singleton object for user preference storage.

---
 src/ui/gui/automake.mk      |   2 +
 src/ui/gui/psppire-conf.c   | 187 ++++++++++++++++++++++++++++++++++++
 src/ui/gui/psppire-conf.h   |  86 +++++++++++++++++
 src/ui/gui/psppire-window.c |  50 ++++++++++
 4 files changed, 325 insertions(+)
 create mode 100644 src/ui/gui/psppire-conf.c
 create mode 100644 src/ui/gui/psppire-conf.h

diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk
index 748a12df..838a773a 100644
--- a/src/ui/gui/automake.mk
+++ b/src/ui/gui/automake.mk
@@ -137,6 +137,8 @@ src_ui_gui_psppire_SOURCES = \
 	src/ui/gui/psppire.h \
 	src/ui/gui/psppire-acr.h \
 	src/ui/gui/psppire-buttonbox.h \
+	src/ui/gui/psppire-conf.c \
+	src/ui/gui/psppire-conf.h \
 	src/ui/gui/psppire-data-editor.c \
 	src/ui/gui/psppire-data-editor.h \
 	src/ui/gui/psppire-data-store.c \
diff --git a/src/ui/gui/psppire-conf.c b/src/ui/gui/psppire-conf.c
new file mode 100644
index 00000000..c7d7cbe3
--- /dev/null
+++ b/src/ui/gui/psppire-conf.c
@@ -0,0 +1,187 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2009  Free Software Foundation
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+   This module provides an interface for simple user preference config
+   parameters.
+*/
+
+#include <config.h>
+#include <stdio.h>
+
+#include "psppire-conf.h"
+
+static void psppire_conf_init            (PsppireConf      *conf);
+static void psppire_conf_class_init      (PsppireConfClass *class);
+
+static void psppire_conf_finalize        (GObject   *object);
+static void psppire_conf_dispose        (GObject   *object);
+
+static GObjectClass *parent_class = NULL;
+
+
+GType
+psppire_conf_get_type (void)
+{
+  static GType conf_type = 0;
+
+  if (!conf_type)
+    {
+      static const GTypeInfo conf_info =
+      {
+	sizeof (PsppireConfClass),
+	NULL,		/* base_init */
+	NULL,		/* base_finalize */
+        (GClassInitFunc) psppire_conf_class_init,
+	NULL,		/* class_finalize */
+	NULL,		/* class_data */
+        sizeof (PsppireConf),
+	0,
+        (GInstanceInitFunc) psppire_conf_init,
+      };
+
+      conf_type = g_type_register_static (G_TYPE_OBJECT,
+						"PsppireConf",
+						&conf_info, 0);
+    }
+
+  return conf_type;
+}
+
+
+static void
+conf_read (PsppireConf *conf)
+{
+  g_key_file_load_from_file (conf->keyfile,
+			     conf->filename,
+			     G_KEY_FILE_KEEP_COMMENTS,
+			     NULL);
+}
+
+static void
+conf_write (PsppireConf *conf)
+{
+  gsize length = 0;
+
+  gchar *kf = g_key_file_to_data  (conf->keyfile, &length, NULL);
+
+  if ( ! g_file_set_contents (conf->filename, kf, length, NULL) )
+    {
+      g_warning ("Cannot open %s for writing", conf->filename);
+    }
+
+  g_free (kf);
+}
+
+static void
+psppire_conf_dispose  (GObject *object)
+{
+}
+
+static void
+psppire_conf_finalize (GObject *object)
+{
+  PsppireConf *conf = PSPPIRE_CONF (object);
+  g_key_file_free (conf->keyfile);
+  g_free (conf->filename);
+}
+
+
+static PsppireConf *the_instance = NULL;
+
+static GObject*
+psppire_conf_construct   (GType                  type,
+				     guint                  n_construct_params,
+				     GObjectConstructParam *construct_params)
+{
+  GObject *object;
+
+  if (!the_instance)
+    {
+      object = G_OBJECT_CLASS (parent_class)->constructor (type,
+                                                           n_construct_params,
+                                                           construct_params);
+      the_instance = PSPPIRE_CONF (object);
+    }
+  else
+    object = g_object_ref (G_OBJECT (the_instance));
+
+  return object;
+}
+
+static void
+psppire_conf_class_init (PsppireConfClass *class)
+{
+  GObjectClass *object_class;
+
+  parent_class = g_type_class_peek_parent (class);
+  object_class = (GObjectClass*) class;
+
+  object_class->finalize = psppire_conf_finalize;
+  object_class->dispose = psppire_conf_dispose;
+  object_class->constructor = psppire_conf_construct;
+
+}
+
+
+static void
+psppire_conf_init (PsppireConf *conf)
+{
+  const gchar *dirname = g_get_user_config_dir ();
+
+  conf->filename = g_strdup_printf ("%s/%s", dirname, "psppirerc");
+
+  conf->keyfile = g_key_file_new ();
+
+  conf->dispose_has_run = FALSE;
+}
+
+
+PsppireConf *
+psppire_conf_new (void)
+{
+  return g_object_new (psppire_conf_get_type (), NULL);
+}
+
+
+
+gboolean
+psppire_conf_get_int (PsppireConf *conf, const gchar *base,
+		      const gchar *name, gint *value)
+{
+  gboolean ok;
+  GError *err = NULL;
+  conf_read (conf);
+  *value = g_key_file_get_integer (conf->keyfile,
+				   base,
+				   name, &err);
+
+  ok = (err == NULL);
+  if ( err != NULL )
+    g_error_free (err);
+
+  return ok;
+}
+
+void
+psppire_conf_set_int (PsppireConf *conf,
+		      const gchar *base, const gchar *name,
+		      gint value)
+{
+  g_key_file_set_integer (conf->keyfile, base, name, value);
+  conf_write (conf);
+}
+
diff --git a/src/ui/gui/psppire-conf.h b/src/ui/gui/psppire-conf.h
new file mode 100644
index 00000000..f98c25a0
--- /dev/null
+++ b/src/ui/gui/psppire-conf.h
@@ -0,0 +1,86 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2009  Free Software Foundation
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#ifndef __PSPPIRE_CONF_H__
+#define __PSPPIRE_CONF_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_CONF (psppire_conf_get_type ())
+
+#define PSPPIRE_CONF(obj)	\
+                     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+		    PSPPIRE_TYPE_CONF, PsppireConf))
+
+#define PSPPIRE_CONF_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_CAST ((klass), \
+				 PSPPIRE_TYPE_CONF, \
+                                 PsppireConfClass))
+
+
+#define PSPPIRE_IS_CONF(obj) \
+	             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_CONF))
+
+#define PSPPIRE_IS_CONF_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_CONF))
+
+
+#define PSPPIRE_CONF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+				   PSPPIRE_TYPE_CONF, \
+				   PsppireConfClass))
+
+typedef struct _PsppireConf       PsppireConf;
+typedef struct _PsppireConfClass  PsppireConfClass;
+
+
+struct _PsppireConf
+{
+  GObject parent;
+
+  /*< private >*/
+  gboolean dispose_has_run ;
+
+  GKeyFile *keyfile;
+  gchar *filename;
+};
+
+
+struct _PsppireConfClass
+{
+  GObjectClass parent_class;
+};
+
+
+GType psppire_conf_get_type (void) G_GNUC_CONST;
+
+PsppireConf * psppire_conf_new (void);
+
+gboolean psppire_conf_get_int (PsppireConf *,
+			       const gchar *, const gchar *, int *);
+
+void psppire_conf_set_int (PsppireConf *conf,
+			   const gchar *base, const gchar *name,
+			   gint value);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_CONF_H__ */
diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c
index 407ba973..5de6afd8 100644
--- a/src/ui/gui/psppire-window.c
+++ b/src/ui/gui/psppire-window.c
@@ -31,6 +31,7 @@
 
 #include "psppire-window.h"
 #include "psppire-window-register.h"
+#include "psppire-conf.h"
 
 static void psppire_window_base_finalize (PsppireWindowClass *, gpointer);
 static void psppire_window_base_init     (PsppireWindowClass *class);
@@ -190,6 +191,49 @@ psppire_window_get_property (GObject         *object,
 }
 
 
+static void
+on_realize (GtkWindow *window, gpointer data)
+{
+  gint height, width;
+  gint x, y;
+
+  PsppireConf *conf = psppire_conf_new ();
+
+  const gchar *base = G_OBJECT_TYPE_NAME (window);
+
+  if (psppire_conf_get_int (conf, base, "height", &height)
+      &&
+      psppire_conf_get_int (conf, base, "width", &width) )
+    {
+      gtk_window_set_default_size (window, width, height);
+    }
+
+
+  if ( psppire_conf_get_int (conf, base, "x", &x)
+       &&
+       psppire_conf_get_int (conf, base, "x", &y) )
+    {
+      gtk_window_move (window, x, y);
+    }
+
+}
+
+
+static gboolean
+on_configure (GtkWidget *w, GdkEventConfigure *event, gpointer data)
+{
+  const gchar *base = G_OBJECT_TYPE_NAME (w);
+
+  PsppireConf *conf = psppire_conf_new ();
+
+  psppire_conf_set_int (conf, base, "height", event->height);
+  psppire_conf_set_int (conf, base, "width", event->width);
+  psppire_conf_set_int (conf, base, "x", event->x);
+  psppire_conf_set_int (conf, base, "y", event->y);
+
+  return FALSE;
+}
+
 
 static void
 psppire_window_finalize (GObject *object)
@@ -402,6 +446,12 @@ psppire_window_init (PsppireWindow *window)
 
   g_object_set (window, "icon-name", "psppicon", NULL);
 
+  g_signal_connect (window, "configure-event",
+		    G_CALLBACK (on_configure), window);
+
+  g_signal_connect (window, "realize",
+		    G_CALLBACK (on_realize), window);
+
 }
 
 
-- 
2.30.2