I'm attaching a patch that adds configuration of gnumeric for the plain GTK version, in the same sort of way as is currently implemented for Gnome and win32, but using a plain text .gnumericrc file.

The diff is against gnumeric-gconf.c in the 1.5.2 release.

--
Allin Cottrell
Department of Economics
Wake Forest University, NC
--- gnumeric-gconf.c.orig       2005-07-12 08:38:41.000000000 -0400
+++ gnumeric-gconf.c    2005-07-12 17:15:55.000000000 -0400
@@ -1061,88 +1061,465 @@
 
 #else
 
+#include <string.h>
+
+typedef enum {
+       RC_TYPE_BOOLEAN = 1,
+       RC_TYPE_INT,
+       RC_TYPE_DOUBLE,
+       RC_TYPE_STRING,
+       RC_TYPE_UNKNOWN
+} RCType;
+
+struct _GOConfNode {
+       gchar *key;
+       gchar *value;
+       RCType type;
+};
+
+static GOConfNode **rc_nodes;
+static int n_rc_nodes;
+
+static int get_rc_filename (char *rcfile)
+{
+       char *home = getenv("HOME");
+       int err = 0;
+
+       if (home == NULL) {
+               *rcfile = '\0';
+               err = 1;
+       } else {
+               sprintf(rcfile, "%s/.gnumericrc", home);
+       }
+
+       return err;
+}
+
+static GOConfNode *add_rc_conf_node (const char *key, const char *value, 
RCType type)
+{
+       GOConfNode **nodes = NULL;
+       GOConfNode *node = NULL;
+       int slot = -1;
+       int i, err = 0;
+
+       /* reuse a blank slot? */
+       for (i=0; i<n_rc_nodes; i++) {
+               if (rc_nodes[i] == NULL) {
+                       slot = i;
+                       break;
+               }
+       }
+
+       if (slot < 0) {
+               nodes = g_realloc (rc_nodes, (n_rc_nodes + 1) * sizeof *nodes);
+               if (nodes == NULL) {
+                       err = 1;
+               } else {
+                       rc_nodes = nodes;
+                       rc_nodes[n_rc_nodes] = NULL;
+                       slot = n_rc_nodes;
+                       n_rc_nodes++;
+               }
+       }
+
+       if (!err) {
+               node = g_malloc (sizeof *node);
+               if (node == NULL) {
+                       err = 1;
+               }
+       }
+       
+       if (!err) {
+               node->key = g_strdup (key);
+               if (value != NULL) {
+                       node->value = g_strdup (value);
+               } else {
+                       node->value = NULL;
+               }
+               node->type = type;
+               rc_nodes[slot] = node;
+       }
+
+       return node;
+}
+
+static GOConfNode *get_node_from_key (const char *key)
+{
+       GOConfNode *ret = NULL;
+       int i;
+
+       for (i=0; i<n_rc_nodes; i++) {
+               if (rc_nodes[i] != NULL && 
+                   g_str_has_suffix(rc_nodes[i]->key, key)) {
+                       ret = rc_nodes[i];
+                       break;
+               }
+       }
+
+#if 0
+       fprintf(stderr, "get_node_from_key: key='%s', %s\n", key,
+               (ret)? "matched" : "no match");
+#endif
+
+       return ret;
+}
+
+static int node_number_in_list (GOConfNode *node)
+{
+       int i, ret = -1;
+
+       for (i=0; i<n_rc_nodes; i++) {
+               if (rc_nodes[i] == node) {
+                       ret = i;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int max_line_length (FILE *fp)
+{
+    int len = 0, maxlen = 0;
+    int c;
+
+    while ((c = fgetc(fp)) != EOF) {
+        len++;
+        if (c == '\n') {
+            if (len > maxlen) {
+                maxlen = len;
+            }
+            len = 0;
+        }
+    }
+
+    return maxlen + 1;
+}
+
+static int make_nodes_from_rcfile (FILE *fp)
+{
+       char *line, *value;
+       char key[128], test[8];
+       int type, len;
+       int err = 0;
+
+       len = max_line_length(fp) + 1;
+       rewind(fp);
+
+       line = g_malloc (len);
+       if (line == NULL) {
+               err = 1;
+       } else {
+               while (fgets(line, len, fp)) {
+                       line[strlen(line) - 1] = '\0';
+                       if (sscanf(line, "%d %127s = %7s", &type, key, test) == 
3) {
+                               value = strchr(line, '=') + 2;
+                               add_rc_conf_node (key, value, type);
+                       }
+               }
+               g_free (line);
+       }
+
+       return err;
+}
+
+static void maybe_dump_node (GOConfNode *node, FILE *fp)
+{
+       if (node->value != NULL && node->value[0]) {    
+               fprintf(fp, "%d %s = %s\n", (int) node->type, node->key, 
node->value);
+       }
+}
+
+static int dump_rc_nodes_to_file (void)
+{
+       char rcfile[FILENAME_MAX];
+       FILE *fp = NULL;
+       int i, err = 0;
+
+       err = get_rc_filename (rcfile);
+
+       if (!err) {
+               fp = fopen (rcfile, "w");
+               if (fp == NULL) {
+                       err = 1;
+               }
+       }
+
+       if (!err) {
+               for (i=0; i<n_rc_nodes; i++) {
+                       if (rc_nodes[i] != NULL && rc_nodes[i]->key != NULL) {
+                               maybe_dump_node(rc_nodes[i], fp);
+                       }
+               }
+       }
+
+       if (fp != NULL) {
+               fclose(fp);
+       }
+       
+       return 1;
+}
+
+static GOConfNode *get_real_node (GOConfNode *parent, gchar const *key)
+{
+       GOConfNode *node = NULL;
+       gchar *path;
+
+       if (parent != NULL && parent->key != NULL) {
+               path = g_strdup_printf ("%s/%s", parent->key, key);
+       } else {
+               path = g_strdup(key);
+       }
+
+       node = get_node_from_key (path);
+       g_free (path);
+       return node;
+}
+
+static GOConfNode *modify_or_add_node (GOConfNode *parent, 
+                                      gchar const *key,
+                                      gchar const *value,
+                                      RCType type)
+{
+       GOConfNode *node = NULL;
+       gchar *path;
+
+       if (parent != NULL && parent->key != NULL) {
+               path = g_strdup_printf ("%s/%s", parent->key, key);
+       } else {
+               path = g_strdup(key);
+       }
+
+       node = get_node_from_key (path);
+       
+       if (node == NULL) {
+               add_rc_conf_node(path, value, type);
+       } else {
+               g_free (node->value);
+               node->value = g_strdup (value);
+       }
+
+       g_free (path);
+       return node;
+}
+
 static void
 go_conf_init (void)
 {
+       char rcfile[FILENAME_MAX];
+       FILE *fp;
+       int err;
+
+       err = get_rc_filename (rcfile);
+       if (!err) {
+               fp = fopen (rcfile, "r");
+               if (fp != NULL) {
+                       make_nodes_from_rcfile (fp);
+                       fclose (fp);
+               }
+       }
 }
 
 static void
 go_conf_shutdown (void)
 {
+       int i;
+
+       dump_rc_nodes_to_file();
+
+       for (i=0; i<n_rc_nodes; i++) {
+               go_conf_free_node(rc_nodes[i]);
+       }
+
+       free(rc_nodes);
+       rc_nodes = NULL;
+       n_rc_nodes = 0;
 }
 
 GOConfNode *
 go_conf_get_node (GOConfNode *parent, gchar const *key)
 {
-       return NULL;
+       GOConfNode *node;
+       gchar *path;
+
+       if (parent != NULL && parent->key != NULL) {
+               path = g_strdup_printf ("%s/%s", parent->key, key);
+       } else {
+               path = g_strdup(key);
+       }
+               
+       node = add_rc_conf_node (path, NULL, RC_TYPE_UNKNOWN);
+       g_free (path);
+       return node;
 }
 
 void
 go_conf_free_node (GOConfNode *node)
 {
+       if (node != NULL) {
+               int nn = node_number_in_list (node);
+
+               g_free (node->key);
+               g_free (node->value);
+               g_free (node);
+               if (nn >= 0) {
+                       rc_nodes[nn] = NULL;
+               }
+       }
 }
 
 void
 go_conf_set_bool (GOConfNode *node, gchar const *key, gboolean val)
 {
+       gchar *valstr = g_strdup_printf ("%d", (int) val);
+
+       modify_or_add_node (node, key, valstr, RC_TYPE_BOOLEAN);
+       g_free (valstr);
 }
 
 void
 go_conf_set_int (GOConfNode *node, gchar const *key, gint val)
 {
+       gchar *valstr = g_strdup_printf ("%d", (int) val);
+
+       modify_or_add_node (node, key, valstr, RC_TYPE_INT);
+       g_free (valstr);
 }
 
 void
 go_conf_set_double (GOConfNode *node, gchar const *key, gnm_float val)
 {
+       gchar *valstr = g_strdup_printf ("%g", (double) val);
+
+       modify_or_add_node (node, key, valstr, RC_TYPE_DOUBLE);
+       g_free (valstr);
 }
 
 void
 go_conf_set_string (GOConfNode *node, gchar const *key, char const *str)
 {
+       modify_or_add_node (node, key, str, RC_TYPE_STRING);
 }
 
 void
 go_conf_set_str_list (GOConfNode *node, gchar const *key, GSList *list)
 {
+       if (list != NULL) {
+               GString *str_list = g_string_new ("");
+
+               while (list) {
+                       const gchar *str = list->data;
+
+                       if (*str) {
+                               g_string_append (str_list, g_strescape (str, 
NULL));
+                               g_string_append_c (str_list, ';');
+                       }
+                       list = list->next;
+               }
+
+               modify_or_add_node (node, key, str_list->str, RC_TYPE_STRING);
+               g_string_free (str_list, TRUE);
+       }
 }
 
 gboolean
 go_conf_get_bool (GOConfNode *node, gchar const *key)
 {
-       return FALSE;
+       GOConfNode *rcnode;
+       gboolean val = FALSE;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atoi (rcnode->value);
+       }
+
+       return val;
 }
 
 gint
 go_conf_get_int        (GOConfNode *node, gchar const *key)
 {
-       return 0;
+       GOConfNode *rcnode;
+       gint val = 0;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atoi (rcnode->value);
+       }       
+
+       return val;
 }
 
 gdouble
 go_conf_get_double (GOConfNode *node, gchar const *key)
 {
-       return 0.;
+       GOConfNode *rcnode;
+       gdouble val = 0.0;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atof (rcnode->value);
+       }
+
+       return val;
 }
 
 gchar *
 go_conf_get_string (GOConfNode *node, gchar const *key)
 {
-       return g_strdup ("");
+       GOConfNode *rcnode;
+       gchar *val = NULL;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = g_strdup (node->value);
+       } else {
+               val = g_strdup ("");
+       }
+
+       return val;
 }
 
 GSList *
 go_conf_get_str_list (GOConfNode *node, gchar const *key)
 {
-       return NULL;
+       GOConfNode *rcnode;
+       GSList *list = NULL;
+       gchar *ptr;
+       gchar **str_list;
+       gint i;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && (ptr = rcnode->value) != NULL) {
+               str_list = g_strsplit ((const gchar *) ptr, ";", 0);
+               for (i = 0; str_list[i]; ++i) {
+                       if (str_list[i][0]) {
+                               /* was 'prepend' here: broke recent file list */
+                               list = g_slist_append (list, g_strcompress 
(str_list[i]));
+                       }
+               }
+               /* g_slist_reverse (list); */
+               g_strfreev (str_list);
+       }
+
+       return list;
 }
 
 gboolean
 go_conf_load_bool (GOConfNode *node, gchar const *key,
                   gboolean default_val)
 {
-       return default_val;
+       GOConfNode *rcnode;
+       gboolean val = default_val;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atoi (rcnode->value);
+       }
+
+       return val;
 }
+
 int
 go_conf_load_int (GOConfNode *node, gchar const *key,
                  gint minima, gint maxima,
@@ -1148,7 +1525,18 @@
                  gint minima, gint maxima,
                  gint default_val)
 {
-       return default_val;
+       GOConfNode *rcnode;
+       int val = default_val;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atoi (rcnode->value);
+               if (val < minima || val > maxima) {
+                       val = default_val;
+               }
+       }
+
+       return val;
 }
 
 double
@@ -1156,8 +1544,20 @@
                     gdouble minima, gdouble maxima,
                     gdouble default_val)
 {
-       return default_val;
+       GOConfNode *rcnode;
+       double val = default_val;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = atof (rcnode->value);
+               if (val < minima || val > maxima) {
+                       val = default_val;
+               }
+       }
+
+       return val;
 }
+
 char *
 go_conf_load_string (GOConfNode *node, gchar const *key)
 {
@@ -1161,8 +1561,17 @@
 char *
 go_conf_load_string (GOConfNode *node, gchar const *key)
 {
-       return NULL;
+       GOConfNode *rcnode;
+       char *val = NULL;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = g_strdup(rcnode->value);
+       }
+       
+       return val;
 }
+
 GSList *
 go_conf_load_str_list (GOConfNode *node, gchar const *key)
 {
@@ -1166,8 +1575,9 @@
 GSList *
 go_conf_load_str_list (GOConfNode *node, gchar const *key)
 {
-       return NULL;
+       return go_conf_get_str_list (node, key);
 }
+
 char *
 go_conf_get_short_desc (GOConfNode *node, gchar const *key)
 {
@@ -1183,19 +1593,64 @@
 GType
 go_conf_get_type (GOConfNode *node, gchar const *key)
 {
-       return G_TYPE_NONE;
+       GOConfNode *rcnode;
+       GType type = G_TYPE_NONE;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL) {
+               switch (rcnode->type) {
+               case RC_TYPE_BOOLEAN:
+                       type = G_TYPE_BOOLEAN;
+                       break;
+               case RC_TYPE_INT:
+                       type = G_TYPE_INT;
+                       break;
+               case RC_TYPE_DOUBLE:
+                       type = G_TYPE_DOUBLE;
+                       break;
+               case RC_TYPE_STRING:
+                       type = G_TYPE_STRING;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return type;
 }
 
 gchar *
 go_conf_get_value_as_str (GOConfNode *node, gchar const *key)
 {
-       return g_strdup ("");
+       GOConfNode *rcnode;
+       gchar *val = NULL;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode != NULL && rcnode->value != NULL) {
+               val = g_strdup (rcnode->value);
+       } else {
+               val = g_strdup ("");
+       }
+
+       return val;
 }
 
 gboolean
 go_conf_set_value_from_str (GOConfNode *node, gchar const *key, gchar const 
*val_str)
 {
-       return TRUE;
+       GOConfNode *rcnode;
+       gboolean ret = FALSE;
+
+       rcnode = get_real_node (node, key);
+       if (rcnode == NULL) {
+               add_rc_conf_node (key, val_str, RC_TYPE_UNKNOWN);
+       } else {        
+               g_free (rcnode->value);
+               rcnode->value = g_strdup (val_str);
+               ret = TRUE;
+       }
+
+       return ret;
 }
 
 void
_______________________________________________
gnumeric-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnumeric-list

Reply via email to