/* SciGraphica - Scientific graphics and data manipulation * Copyright (C) 2001 Adrian E. Feiguin * * 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 2 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "sg_config.h" #include "sg_plugin.h" #include "python_main.h" PyObject *sg_config_dict; static GHashTable *config_groups; /* Create groups hashtable, and optionally the python config_dict */ void sg_config_init() { config_groups = g_hash_table_new (g_str_hash, g_str_equal); sg_config_dict=PyDict_New(); /* Make the configuration details available in python too */ sg_config_dict=PyDict_GetItemString (sg_dict, "config"); if (!sg_config_dict){ sg_config_dict=PyDict_New(); PyDict_SetItemString(sg_dict,"config",sg_config_dict); } } /* Create a new group, if it doesn't exist already, in the sg_config_dict */ static PyObject * sg_config_group_new_python(gchar *group) { PyObject *group_dict; group_dict=PyDict_GetItemString(sg_config_dict,group); if (!group_dict) { group_dict=PyDict_New(); PyDict_SetItemString(sg_config_dict,group,group_dict); } return group_dict; } /* Create a new group, if it doesn't exist already, in the config_groups */ static GHashTable * sg_config_group_new_config(gchar *group) { GHashTable *group_config; group_config=(GHashTable*)g_hash_table_lookup(config_groups,group); if (!group_config) { group_config=g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(config_groups,group,group_config); } return group_config; } /* Remove a configuration item. from the C structures only */ static void sg_config_destroy_config(SGconfig *config) { PyObject *group_dict,*config_item; if(!config) return; if(config->name) g_free(config->name); if(config->group) g_free(config->group); g_free(config); } /* Set the SGconfig structure belonging to the name and group */ static gboolean sg_config_set_config(gchar *name, gchar *group, SGconfig *config, gboolean overwrite){ GHashTable *group_config; SGconfig *oldconfig; group_config=sg_config_group_new_config(group); oldconfig=(SGconfig*)g_hash_table_lookup(group_config,name); if (oldconfig==config) return TRUE; if (oldconfig && !overwrite) return FALSE; else { g_hash_table_remove(group_config,name); sg_config_destroy_config(oldconfig); } g_hash_table_insert(group_config,name,config); return TRUE; } /* New configuration item */ static SGconfig * sg_config_new(gchar *name, gchar *group, SGPluginType type, gpointer def, gpointer commit) { SGconfig *config = NULL; if(!name || !def || !commit || !group) return NULL; config = g_new0(SGconfig, 1); config->name = g_strdup(name); config->group = g_strdup(group); config->type = (SGConfigType)type; config->def = (SGConfigFunc)def; config->commit = (SGConfigFunc)commit; config->status=SG_CONFIG_NEW; sg_config_group_new_python(group); sg_config_set_config(config->name,config->group,config,TRUE); /* always overwrite old value */ return config; } /* New configuration item, with python callbacks */ SGconfig * sg_config_new_python(gchar *name, gchar *group, PyObject *def, PyObject *commit) { SGconfig *config; config=sg_config_new(name,group,(SGPluginType)SG_PYTHON_CONFIG, (gpointer)def, (gpointer)commit); sg_config_exec_default(config); config->status=SG_CONFIG_INIT; return config; } /* New configuration item, with C callbacks */ SGconfig * sg_config_new_c(gchar *name, gchar *group, SGConfigFunc def, SGConfigFunc commit) { SGconfig *config; config= sg_config_new(name,group,(SGPluginType)SG_C_CONFIG,(gpointer)def, (gpointer)commit); sg_config_exec_default(config); config->status=SG_CONFIG_INIT; return config; } /* Remove a configuration item. from the C and python structures */ static void sg_config_destroy_full(SGconfig *config) { PyObject *group_dict,*config_item; GHashTable *group_config; if(!config) return; group_dict=PyDict_GetItemString(sg_config_dict,config->group); if(!group_dict) return; PyDict_DelItemString(group_dict,config->name); group_config=(GHashTable*)g_hash_table_lookup(config_groups,config->group); if (g_hash_table_lookup(group_config,config->name)); g_hash_table_remove(group_config,config->name); sg_config_destroy_config(config); } /* Query python value, using the name and group as keys */ PyObject *sg_config_get_value(gchar *name, gchar *group){ PyObject *group_dict; group_dict=PyDict_GetItemString(sg_config_dict,group); return PyDict_GetItemString(group_dict,name); } /* Set the python value */ gboolean sg_config_set_value(gchar *name, gchar *group, PyObject *value, gboolean overwrite){ PyObject *group_dict; group_dict=sg_config_group_new_python(group); if (sg_config_get_value(name, group) && !overwrite) return FALSE; PyDict_SetItemString(group_dict,name,value); return TRUE; } /* Return the SGconfig structure belonging to the name and group */ SGconfig * sg_config_get_config(gchar *name, gchar *group){ GHashTable *group_config; group_config=(GHashTable*)g_hash_table_lookup(config_groups,group); return (SGconfig *)g_hash_table_lookup(group_config,name); } /* This function is for use in g_hash_table_foreach_remove */ static gboolean sg_config_destroy_hash(gpointer key, gpointer value, gpointer data) { SGconfig *config; config=(SGconfig *)value; if(!config) return TRUE; sg_config_destroy_config(config); return TRUE; } void sg_config_exec_default(SGconfig *config){ PyObject *object; gint retval; if (!config) return; switch (config->type){ case SG_PYTHON_CONFIG: object=PyObject_CallObject((PyObject*)config->def,NULL); if (object) config->status=SG_CONFIG_INIT; python_error_report(object); break; case SG_C_CONFIG: retval=config->def(config); if (retval) config->status=SG_CONFIG_INIT; break; } } void sg_config_exec_commit(SGconfig *config){ PyObject *object; gint retval; if (!config) return; switch (config->type){ case SG_PYTHON_CONFIG: object=PyObject_CallObject((PyObject*)config->commit,NULL); python_error_report(object); if (object) config->status=SG_CONFIG_COMMIT; break; case SG_C_CONFIG: config->commit(config); if (retval) config->status=SG_CONFIG_COMMIT; break; } } static void commit_item(gpointer key, gpointer value, gpointer user_data) { sg_config_exec_commit((SGconfig*)value); } /* Cycle through commit functions within a group, which is a hashtable kept in the value parameter. */ static void commit_group(gpointer key, gpointer value, gpointer user_data) { g_hash_table_foreach ((GHashTable *)value,commit_item,NULL); } void sg_config_exec_commit_all(void) { g_hash_table_foreach (config_groups,commit_group,NULL); }