Commit 7c5682a8 authored by Arturo Espinosa's avatar Arturo Espinosa

Plugin architecture for Gnumeric by Tom Dyas 1998-09-10 Tom Dyas <tdyas@romulus.rutgers.edu>

	* src/func.c: Made install_symbols public.

	* src/main.c: initialize the plugins.

	* src/workbook.c (plugins_cmd): Add a menu option for plugin
	loading.

	* plugin-manager.c: New file.  Implements the GUI part of the
	plugin manager.

	* plugin.c, plugin.h: New file. Support for the dynamically loaded
	Gnumeric plugin components.
parent 361bb50b
1998-09-10 Tom Dyas <tdyas@romulus.rutgers.edu>
* src/func.c: Made install_symbols public.
* src/main.c: initialize the plugins.
* src/workbook.c (plugins_cmd): Add a menu option for plugin
loading.
* plugin-manager.c: New file. Implements the GUI part of the
plugin manager.
* plugin.c, plugin.h: New file. Support for the dynamically loaded
Gnumeric plugin components.
1998-09-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (dialog_cell_format): save and restore
......
1998-09-10 Tom Dyas <tdyas@romulus.rutgers.edu>
* src/func.c: Made install_symbols public.
* src/main.c: initialize the plugins.
* src/workbook.c (plugins_cmd): Add a menu option for plugin
loading.
* plugin-manager.c: New file. Implements the GUI part of the
plugin manager.
* plugin.c, plugin.h: New file. Support for the dynamically loaded
Gnumeric plugin components.
1998-09-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (dialog_cell_format): save and restore
......
SUBDIRS = intl po macros src
\ No newline at end of file
SUBDIRS = intl po macros src
1998-09-10 Tom Dyas <tdyas@romulus.rutgers.edu>
* src/func.c: Made install_symbols public.
* src/main.c: initialize the plugins.
* src/workbook.c (plugins_cmd): Add a menu option for plugin
loading.
* plugin-manager.c: New file. Implements the GUI part of the
plugin manager.
* plugin.c, plugin.h: New file. Support for the dynamically loaded
Gnumeric plugin components.
1998-09-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (dialog_cell_format): save and restore
......
1998-09-10 Tom Dyas <tdyas@romulus.rutgers.edu>
* src/func.c: Made install_symbols public.
* src/main.c: initialize the plugins.
* src/workbook.c (plugins_cmd): Add a menu option for plugin
loading.
* plugin-manager.c: New file. Implements the GUI part of the
plugin manager.
* plugin.c, plugin.h: New file. Support for the dynamically loaded
Gnumeric plugin components.
1998-09-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (dialog_cell_format): save and restore
......
......@@ -54,6 +54,9 @@ GNUMERIC_BASE_SOURCES = \
parser.y \
pattern-selector.c \
pattern-selector.h \
plugin.c \
plugin.h \
plugin-manager.c \
sheet.c \
sheet.h \
sheet-object.c \
......
......@@ -134,7 +134,7 @@ function_iterate_argument_values (Sheet *sheet,
return result;
}
static void
void
install_symbols (FunctionDefinition *functions)
{
int i;
......
......@@ -37,5 +37,7 @@ function_iterate_argument_values (Sheet *sheet,
char **error_string);
void install_symbols (FunctionDefinition *functions);
#endif /* GNUMERIC_FUNC_H */
......@@ -2,6 +2,7 @@
#include <gnome.h>
#include "gnumeric.h"
#include "xml-io.h"
#include "plugin.h"
/* If set, the file to load at startup time */
static char *startup_file;
......@@ -42,6 +43,7 @@ main (int argc, char *argv [])
symbol_init ();
constants_init ();
functions_init ();
plugins_init ();
if (startup_file)
current_workbook = gnumericReadXmlWorkbook (startup_file);
......
......@@ -2,6 +2,7 @@
#include <gnome.h>
#include "gnumeric.h"
#include "xml-io.h"
#include "plugin.h"
/* If set, the file to load at startup time */
static char *startup_file;
......@@ -42,6 +43,7 @@ main (int argc, char *argv [])
symbol_init ();
constants_init ();
functions_init ();
plugins_init ();
if (startup_file)
current_workbook = gnumericReadXmlWorkbook (startup_file);
......
/*
* plugin-manager.c: Dialog used to load plugins into the Gnumeric
* spreadsheet
*
* Author:
* Tom Dyas (tdyas@romulus.rutgers.edu)
*/
#include <glib.h>
#include <gnome.h>
#include "gnumeric.h"
#include "dialogs.h"
#include "plugin.h"
typedef struct
{
GtkWidget *dialog;
GtkWidget *hbox;
GtkWidget *vbbox;
GtkWidget *clist;
GtkWidget *button_add;
GtkWidget *button_remove;
GtkWidget *button_close;
} PluginManager;
static void
add_to_clist (PluginData *pd, GtkWidget *clist)
{
gchar *data[2];
gint row;
data [0] = pd->title;
data [1] = g_module_name (pd->handle);
row = gtk_clist_append (GTK_CLIST (clist), data);
gtk_clist_set_row_data (GTK_CLIST (clist), row, pd);
}
static void
populate_clist (GtkWidget *clist)
{
gtk_clist_freeze (GTK_CLIST (clist));
gtk_clist_clear (GTK_CLIST (clist));
g_list_foreach (plugin_list, (GFunc) add_to_clist, clist);
gtk_clist_thaw (GTK_CLIST (clist));
}
static void
close_cb (GtkWidget *button, PluginManager *pm)
{
gtk_widget_destroy (pm->dialog);
}
static void
add_cb (GtkWidget *button, PluginManager *pm)
{
char *modfile = dialog_query_load_file ();
PluginData *pd;
if (!modfile)
return;
pd = plugin_load (modfile);
populate_clist (pm->clist);
}
static void
remove_cb (GtkWidget *button, PluginManager *pm)
{
GList *selection = GTK_CLIST (pm->clist)->selection;
gint row = (gint) g_list_nth_data (selection, 0);
PluginData *pd = gtk_clist_get_row_data (GTK_CLIST (pm->clist), row);
g_print("remove_cb: activated\n");
plugin_unload (pd);
populate_clist (pm->clist);
}
static void
select_row_cb (GtkWidget * clist, gint row, gint col,
GdkEvent *event, PluginManager *pm)
{
gtk_widget_set_sensitive (pm->button_remove, 1);
}
static void
unselect_row_cb (GtkWidget * clist, gint row, gint col,
GdkEvent *event, PluginManager *pm)
{
gtk_widget_set_sensitive (pm->button_remove, 0);
}
GtkWidget *
plugin_manager_new (void)
{
PluginManager *pm;
gchar *titles[2] = { "Name", "File" };
pm = g_new0 (PluginManager, 1);
if (!pm)
return NULL;
pm->dialog = gtk_window_new (GTK_WINDOW_DIALOG);
pm->hbox = gtk_hbox_new (0, 0);
gtk_container_add (GTK_CONTAINER (pm->dialog), pm->hbox);
pm->clist = gtk_clist_new_with_titles (2, titles);
gtk_box_pack_start (GTK_BOX (pm->hbox), pm->clist, 1, 1, 5);
pm->vbbox = gtk_vbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (pm->vbbox), GTK_BUTTONBOX_START);
gtk_box_pack_start (GTK_BOX (pm->hbox), pm->vbbox, 0, 0, 5);
pm->button_close = gtk_button_new_with_label ("Close");
gtk_container_add (GTK_CONTAINER(pm->vbbox), pm->button_close);
pm->button_add = gtk_button_new_with_label ("Add...");
gtk_container_add (GTK_CONTAINER (pm->vbbox), pm->button_add);
pm->button_remove = gtk_button_new_with_label ("Remove");
gtk_container_add (GTK_CONTAINER (pm->vbbox), pm->button_remove);
gtk_widget_realize (pm->clist);
populate_clist (pm->clist);
gtk_signal_connect (GTK_OBJECT (pm->button_close), "clicked",
GTK_SIGNAL_FUNC (close_cb), pm);
gtk_signal_connect(GTK_OBJECT (pm->button_add), "clicked",
GTK_SIGNAL_FUNC (add_cb), pm);
gtk_signal_connect (GTK_OBJECT (pm->button_remove), "clicked",
GTK_SIGNAL_FUNC (remove_cb), pm);
gtk_signal_connect(GTK_OBJECT (pm->clist), "select_row",
GTK_SIGNAL_FUNC (select_row_cb), pm);
gtk_signal_connect(GTK_OBJECT (pm->clist), "unselect_row",
GTK_SIGNAL_FUNC (unselect_row_cb), pm);
gtk_widget_show_all (pm->hbox);
return pm->dialog;
}
/*
* Support for dynamically-loaded Gnumeric plugin components.
*
* Author:
* Tom Dyas (tdyas@romulus.rutgers.edu)
*/
#include <unistd.h>
#include <dirent.h>
#include <glib.h>
#include <gmodule.h>
#include <gnome.h>
#include <string.h>
#include "gnumeric.h"
#include "plugin.h"
GList *plugin_list = NULL;
PluginData *
plugin_load (gchar *modfile)
{
PluginData *data;
g_return_val_if_fail (modfile != NULL, NULL);
g_print("Loading plugin '%s'.\n", modfile);
data = g_new0 (PluginData, 1);
if (!data){
g_print ("allocation error");
return NULL;
}
data->handle = g_module_open (modfile, 0);
if (!data->handle) {
g_print ("unable to open module file: %s\n", g_module_error());
g_free(data);
return NULL;
}
if (!g_module_symbol (data->handle, "init_plugin", (gpointer *) &data->init_plugin)){
g_print ("module must contain init_plugin function");
goto error;
}
if (!g_module_symbol (data->handle, "cleanup_plugin", (gpointer *) &data->cleanup_plugin)){
g_print("module must contain cleanup_plugin funciton");
goto error;
}
if (data->init_plugin (data) < 0){
g_print ("init_plugin returned error");
goto error;
}
plugin_list = g_list_append (plugin_list, data);
return data;
error:
g_module_close (data->handle);
g_free (data);
return NULL;
}
void
plugin_unload (struct PluginData *pd)
{
g_return_if_fail (pd != NULL);
g_print ("unloading plugin %s\n", g_module_name (pd->handle));
if (pd->refcount > 0) {
g_print ("unload_plugin: refcount is positve, cannot unload\n");
return;
}
if (pd->cleanup_plugin)
pd->cleanup_plugin (pd);
plugin_list = g_list_remove (plugin_list, pd);
g_module_close (pd->handle);
g_free (pd);
g_print ("unload_plugin: plugin is unloaded\n");
}
static void
plugin_load_plugins_in_dir (char *directory)
{
DIR *d;
struct dirent *e;
if ((d = opendir (directory)) == NULL)
return;
while ((e = readdir (d)) != NULL){
if (strncmp (e->d_name + strlen (e->d_name) - 3, ".so", 3) == 0){
char *plugin_name;
plugin_name = g_copy_strings (directory, e->d_name, NULL);
plugin_load (plugin_name);
g_free (plugin_name);
}
}
closedir (d);
}
void
plugins_init(void)
{
char *plugin_dir;
char *home_dir = getenv ("HOME");
if (!g_module_supported())
return;
g_print ("plugins_init()\n");
/* Load the user plugins */
plugin_dir = g_copy_strings (home_dir ? home_dir : "", "/.gnumeric/plugins", NULL);
plugin_load_plugins_in_dir (plugin_dir);
g_free (plugin_dir);
/* Load the system plugins */
plugin_dir = gnome_unconditional_libdir_file ("gnumeric/plugins");
plugin_load_plugins_in_dir (plugin_dir);
g_free (plugin_dir);
}
#ifndef _PLUGIN_H
#define _PLUGIN_H
#include <gmodule.h>
struct PluginData
{
GModule *handle;
int (*init_plugin) (struct PluginData *);
void (*cleanup_plugin) (struct PluginData *);
int refcount;
gchar *title;
/* filled in by plugin */
void *private;
};
typedef struct PluginData PluginData;
extern GList *plugin_list;
void plugins_init (void);
PluginData *plugin_load (gchar *filename);
void plugin_unload (PluginData *pd);
GtkWidget *plugin_manager_new (void);
#endif
......@@ -13,6 +13,7 @@
#include "gnumeric-sheet.h"
#include "dialogs.h"
#include "xml-io.h"
#include "plugin.h"
#include "pixmaps.h"
/* The locations within the main table in the workbook */
......@@ -58,6 +59,13 @@ save_as_cmd (GtkWidget *widget, Workbook *wb)
workbook_save_as (wb);
}
static void
plugins_cmd (GtkWidget *widget, Workbook *wb)
{
GtkWidget *pm = plugin_manager_new();
gtk_widget_show(pm);
}
static void
set_selection_halign (Workbook *wb, StyleHAlignFlags align)
{
......@@ -275,6 +283,7 @@ static GnomeUIInfo workbook_menu_file [] = {
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE },
{ GNOME_APP_UI_ITEM, N_("Save as..."), NULL, save_as_cmd, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE },
{ GNOME_APP_UI_ITEM, N_("Plugins..."), NULL, plugins_cmd },
{ GNOME_APP_UI_ITEM, N_("Exit"), NULL, quit_cmd, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXIT },
GNOMEUIINFO_END
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment