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