/* 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_plugin.h" #include "sg.h" #include "sg_menus.h" #include "python/python_int.h" static GtkWidget *find_submenu (GtkWidget *widget, gchar *label); static void menu_activate (GtkWidget *widget, gpointer data); static GList *plugins; void sg_plugins_init() { plugins = NULL; } void sg_plugins_free() { GList *list; list = plugins; while(list){ SGplugin *plugin; plugin = (SGplugin *)list->data; plugins = g_list_remove_link(plugins, list); g_list_free_1(list); list = plugins; } } void sg_plugin_group_new(gchar *group) { GtkWidget *menu = NULL; gchar *real_group; gint i, n, nc; gchar *subgroup = NULL; gchar *groups[100]; /* parse group */ n = nc = 0; subgroup = (gchar *)g_malloc(sizeof(gchar)); for(i = 0; i < strlen(group); i++){ if(group[i] == ':'){ groups[n] = g_strdup(subgroup); g_free(subgroup); subgroup = (gchar *)g_malloc(sizeof(gchar)); n++; nc = 0; }else{ nc++; subgroup = (gchar *)g_realloc(subgroup, (nc + 1) * sizeof(gchar)); subgroup[nc - 1] = group[i]; subgroup[nc] = '\0'; } } if(subgroup) g_free(subgroup); if(strcmp(groups[0], "Worksheet") == 0){ menu = worksheet_menu; }else if(strcmp(groups[0], "Plot") == 0){ menu = plot_menu; }else if(strcmp(groups[0], "Matrix") == 0){ menu = matrix_menu; } /* menu = find_submenu(menu, "Plugins"); if(!menu) return; */ for(i = 1; i < n; i++){ GtkWidget *sub_menu = NULL; sub_menu = find_submenu(menu, groups[i]); if(!sub_menu){ GtkWidget *item; sub_menu = gtk_menu_new(); item=gtk_menu_item_new_with_label(groups[i]); gtk_widget_show(item); gtk_menu_append(GTK_MENU(menu),item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub_menu); } menu = sub_menu; } } SGplugin * sg_plugin_new_python(gchar *name, gchar *group, PyObject *callable) { SGplugin *plugin = NULL; if(!name || !callable || !group) return NULL; plugin = g_new0(SGplugin, 1); plugin->name = g_strdup(name); plugin->type = SG_PYTHON_PLUGIN; plugin->func = (SGPluginFunc)callable; sg_plugin_set_group(plugin, group); return plugin; } SGplugin * sg_plugin_new_c(gchar *name, gchar *group, SGPluginFunc func) { SGplugin *plugin = NULL; if(!name || !func || !group) return NULL; plugin = g_new0(SGplugin, 1); plugin->name = g_strdup(name); plugin->type = SG_C_PLUGIN; plugin->func = func; sg_plugin_set_group(plugin, group); return plugin; } void sg_plugin_destroy(SGplugin *plugin) { if(!plugin) return; if(plugin->name) g_free(plugin->name); if(plugin->group) g_free(plugin->group); g_free(plugin); } void sg_plugin_set_name(SGplugin *plugin, gchar *name) { if(!plugin || !name) return; if(plugin->name) g_free(plugin->name); plugin->name = g_strdup(name); } void sg_plugin_set_group(SGplugin *plugin, gchar *group) { GtkWidget *menu = NULL; gchar *groups[100]; gchar *subgroup = NULL; gint n, nc; gint i; if(!plugin || !group) return; if(plugin->group) g_free(plugin->group); plugin->group = g_strdup(group); /* parse group */ n = nc = 0; subgroup = (gchar *)g_malloc(sizeof(gchar)); for(i = 0; i < strlen(group); i++){ if(group[i] == ':'){ groups[n] = g_strdup(subgroup); g_free(subgroup); subgroup = (gchar *)g_malloc(sizeof(gchar)); n++; nc = 0; }else{ nc++; subgroup = (gchar *)g_realloc(subgroup, (nc + 1) * sizeof(gchar)); subgroup[nc - 1] = group[i]; subgroup[nc] = '\0'; } } if(subgroup) g_free(subgroup); if(strcmp(groups[0], "Worksheet") == 0){ menu = worksheet_menu; }else if(strcmp(groups[0], "Plot") == 0){ menu = plot_menu; }else if(strcmp(groups[0], "Matrix") == 0){ menu = matrix_menu; } /* menu = find_submenu(menu, "Plugins"); if(!menu) return; */ for(i = 1; i < n; i++){ GtkWidget *sub_menu = NULL; sub_menu = find_submenu(menu, groups[i]); if(!sub_menu) return; menu = sub_menu; } if(menu){ GtkWidget *item, *sub_item; item=gtk_menu_item_new_with_label(plugin->name); gtk_widget_show(item); gtk_menu_append(GTK_MENU(menu),item); gtk_signal_connect(GTK_OBJECT(item),"activate", GTK_SIGNAL_FUNC(menu_activate), plugin); } for(i = 0; i < n; i++) if(groups[i]) g_free(groups[i]); } static GtkWidget * find_submenu(GtkWidget *widget, gchar *label) { GList *list; list = GTK_MENU_SHELL(widget)->children; while(list){ GtkWidget *sub_item; gchar *item_label; sub_item = GTK_WIDGET(list->data); item_label = GTK_LABEL(GTK_BIN(sub_item)->child)->label; if(strcmp(item_label, label) == 0) return GTK_MENU_ITEM(sub_item)->submenu; list = list->next; } return NULL; } static void menu_activate(GtkWidget *widget, gpointer data) { SGplugin *plugin; plugin = (SGplugin *)data; sg_plugin_exec(plugin); } void sg_plugin_exec(SGplugin *plugin){ PyObject *object; GtkSignalFunc func; switch (plugin->type){ case SG_PYTHON_PLUGIN: object=PyObject_CallObject((PyObject*)plugin->func,NULL); python_error_report(object); break; case SG_C_PLUGIN: plugin->func(plugin); break; } }