2
GNOME Commander - A GNOME based file manager
3
Copyright (C) 2001-2006 Marcus Bjurman
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
23
#include "gnome-cmd-includes.h"
24
#include "gnome-cmd-data.h"
25
#include "plugin_manager.h"
27
#include "imageloader.h"
28
#include "gnome-cmd-main-win.h"
29
#include "gnome-cmd-about-plugin.h"
34
// The names of these functions shall never change
35
#define MODULE_INIT_FUNC "create_plugin"
36
#define MODULE_INFO_FUNC "get_plugin_info"
39
static GList *plugins = NULL;
40
static GdkPixmap *exec_pixmap = NULL;
41
static GdkBitmap *exec_mask = NULL;
42
static GdkPixmap *blank_pixmap = NULL;
43
static GdkBitmap *blank_mask = NULL;
47
load_plugin (PluginData *data)
49
GModule *module = g_module_open (data->fpath, G_MODULE_BIND_LAZY);
50
PluginInfoFunc info_func;
51
PluginConstructorFunc init_func;
52
GnomeCmdPlugin *plugin;
56
g_printerr ("ERROR: Failed to load the plugin '%s': %s\n", data->fname, g_module_error ());
60
// Try to get a reference to the "get_plugin_info" function
61
if (!g_module_symbol (module, MODULE_INFO_FUNC, (gpointer *) &info_func))
63
g_printerr ("ERROR: The plugin-file '%s' has no function named '%s'.\n", data->fname, MODULE_INFO_FUNC);
64
g_module_close (module);
68
// Try to get the plugin info
69
data->info = info_func ();
72
g_printerr ("ERROR: The plugin-file '%s' did not return valid plugin info:\n", data->fname);
73
g_printerr (" The function '%s' returned NULL\n", MODULE_INFO_FUNC);
74
g_module_close (module);
78
// Check that the plugin is compatible
79
if (data->info->plugin_system_version != GNOME_CMD_PLUGIN_SYSTEM_CURRENT_VERSION)
81
g_printerr ("ERROR: The plugin '%s' is not compatible with this version of %s:\n", data->info->name, PACKAGE);
82
g_printerr (" Plugin system supported by the plugin is %d, it should be %d\n", data->info->plugin_system_version,
83
GNOME_CMD_PLUGIN_SYSTEM_CURRENT_VERSION);
87
// Try to get a reference to the "create_plugin" function
88
if (!g_module_symbol (module, MODULE_INIT_FUNC, (gpointer *) &init_func))
90
g_printerr ("ERROR: The plugin '%s' has no '%s' function\n", data->info->name, MODULE_INIT_FUNC);
91
g_module_close (module);
95
// Try to initialize the plugin
96
plugin = init_func ();
99
g_printerr ("ERROR: The plugin '%s' could not be initialized:\n", data->info->name);
100
g_printerr (" The '%s' function returned NULL\n", MODULE_INIT_FUNC);
101
g_module_close (module);
105
// All is OK, everyone is happy
106
data->plugin = plugin;
107
data->module = module;
113
activate_plugin (PluginData *data)
126
GnomeCmdState *state = gnome_cmd_main_win_get_state (main_win);
127
data->menu = gnome_cmd_plugin_create_main_menu (data->plugin, state);
129
gnome_cmd_main_win_add_plugin_menu (main_win, data);
134
inactivate_plugin (PluginData *data)
139
data->active = FALSE;
141
gtk_object_destroy (GTK_OBJECT (data->menu));
146
scan_plugins_in_dir (const gchar *dpath)
148
DIR *dir = opendir (dpath);
154
gchar *msg = g_strdup_printf ("Could not list files in %s: %s\n", dpath, strerror (errno));
160
getcwd (prev_dir, sizeof(prev_dir));
163
while ((ent = readdir (dir)) != NULL)
167
if (strcmp (ent->d_name+strlen(ent->d_name)-3, ".so") != 0)
170
if (stat (ent->d_name, &buf) == 0)
172
if (buf.st_mode & S_IFREG)
174
// the direntry has the .so extension and is a regular file, lets accept it
175
PluginData *data = g_new (PluginData, 1);
176
data->fname = g_strdup (ent->d_name);
177
data->fpath = g_build_path (G_DIR_SEPARATOR_S, dpath, ent->d_name, NULL);
178
data->loaded = FALSE;
179
data->active = FALSE;
181
data->autoload = FALSE;
182
activate_plugin (data);
185
g_free (data->fname);
186
g_free (data->fpath);
190
plugins = g_list_append (plugins, data);
193
printf ("%s is not a regular file\n", ent->d_name);
196
printf ("Failed to stat %s\n", ent->d_name);
206
void plugin_manager_init (void)
210
warn_print ("plugin_manager already initiated\n");
215
gchar *user_dir = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir(), ".gnome-commander/plugins", NULL);
216
create_dir_if_needed (user_dir);
217
scan_plugins_in_dir (user_dir);
220
// find system plugins
221
scan_plugins_in_dir (PLUGIN_DIR);
224
for (GList *l=gnome_cmd_data_get_auto_load_plugins (); l; l=l->next)
226
char *name = (gchar *) l->data;
228
for (GList *l2 = plugins; l2; l2 = l2->next)
230
PluginData *data = (PluginData *) l2->data;
231
if (strcmp (name, data->fname) == 0)
232
data->autoload = TRUE;
236
// inactivate plugins that shouldn't be autoloaded
237
for (GList *l=plugins; l; l=l->next)
239
PluginData *data = (PluginData *) l->data;
241
inactivate_plugin (data);
246
void plugin_manager_shutdown (void)
250
for (GList *l=plugins; l; l=l->next)
252
PluginData *data = (PluginData *) l->data;
254
out = g_list_append (out, data->fname);
257
gnome_cmd_data_set_auto_load_plugins (out);
261
GList *plugin_manager_get_all (void)
268
get_selected_plugin (GtkCList *list)
270
return (PluginData *) gtk_clist_get_row_data (list, list->focus_row);
275
update_plugin_list (GtkCList *list, GtkWidget *dialog)
277
gint old_focus = list->focus_row;
279
gboolean only_update = (list->rows > 0);
281
for (GList *tmp=plugins; tmp; tmp=tmp->next)
283
PluginData *data = (PluginData *) tmp->data;
287
text[1] = data->info->name;
288
text[2] = data->info->version;
289
text[3] = data->fname;
293
gtk_clist_set_text (list, row, 1, text[1]);
295
gtk_clist_append (list, text);
298
gtk_clist_set_pixmap (list, row, 0, exec_pixmap, exec_mask);
300
gtk_clist_set_pixmap (list, row, 0, blank_pixmap, blank_mask);
303
gtk_clist_set_row_data (list, row, data);
308
gtk_clist_select_row (list, old_focus, 0);
313
do_toggle (GtkWidget *dialog)
315
GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
316
PluginData *data = get_selected_plugin (list);
321
inactivate_plugin (data);
323
activate_plugin (data);
325
update_plugin_list (list, dialog);
330
on_plugin_selected (GtkCList *list, gint row, gint column,
331
GdkEventButton *event, GtkWidget *dialog)
333
GtkWidget *toggle_button = lookup_widget (dialog, "toggle_button");
334
GtkWidget *conf_button = lookup_widget (dialog, "conf_button");
335
GtkWidget *about_button = lookup_widget (dialog, "about_button");
337
PluginData *data = get_selected_plugin (list);
338
g_return_if_fail (data != NULL);
340
if (event && event->type == GDK_2BUTTON_PRESS && event->button == 1)
346
gtk_widget_set_sensitive (about_button, TRUE);
347
gtk_button_set_label (GTK_BUTTON (toggle_button), data->active ? _("Disable") : _("Enable"));
348
gtk_widget_set_sensitive (toggle_button, TRUE);
349
gtk_widget_set_sensitive (conf_button, data->active);
354
on_plugin_unselected (GtkCList *list, gint row, gint column,
355
GdkEventButton *event, GtkWidget *dialog)
357
GtkWidget *toggle_button = lookup_widget (dialog, "toggle_button");
358
GtkWidget *conf_button = lookup_widget (dialog, "conf_button");
359
GtkWidget *about_button = lookup_widget (dialog, "about_button");
361
gtk_widget_set_sensitive (toggle_button, FALSE);
362
gtk_widget_set_sensitive (about_button, FALSE);
363
gtk_widget_set_sensitive (conf_button, FALSE);
368
on_toggle (GtkButton *button, GtkWidget *dialog)
375
on_configure (GtkButton *button, GtkWidget *dialog)
377
GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
378
PluginData *data = get_selected_plugin (list);
380
g_return_if_fail (data != NULL);
381
g_return_if_fail (data->active);
383
gnome_cmd_plugin_configure (data->plugin);
388
on_about (GtkButton *button, GtkWidget *dialog)
390
GtkCList *list = GTK_CLIST (lookup_widget (dialog, "avail_list"));
391
PluginData *data = get_selected_plugin (list);
392
GtkWidget *about = gnome_cmd_about_plugin_new (data->info);
394
g_return_if_fail (data != NULL);
396
gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (main_win));
397
gtk_widget_ref (about);
398
gtk_widget_show (about);
403
on_close (GtkButton *button, GtkWidget *dialog)
405
gtk_widget_destroy (dialog);
409
void plugin_manager_show (void)
411
GtkWidget *dialog, *hbox, *bbox, *button;
412
GtkWidget *avail_list;
414
dialog = gnome_cmd_dialog_new (_("Available plugins"));
415
gtk_widget_ref (dialog);
417
hbox = create_vbox (dialog, FALSE, 6);
418
avail_list = create_clist (dialog, "avail_list", 4, 20, GTK_SIGNAL_FUNC (on_plugin_selected), NULL);
419
create_clist_column (avail_list, 0, 20, "");
420
create_clist_column (avail_list, 1, 200, _("Name"));
421
create_clist_column (avail_list, 2, 50, _("Version"));
422
create_clist_column (avail_list, 3, 50, _("File"));
424
bbox = create_hbuttonbox (dialog);
425
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
427
button = create_button (GTK_WIDGET (dialog), _("_Enable"), GTK_SIGNAL_FUNC (on_toggle));
428
gtk_object_set_data (GTK_OBJECT (dialog), "toggle_button", button);
429
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, FALSE, 0);
431
button = create_button (GTK_WIDGET (dialog), _("_Configure"), GTK_SIGNAL_FUNC (on_configure));
432
gtk_object_set_data (GTK_OBJECT (dialog), "conf_button", button);
433
gtk_widget_set_sensitive (button, FALSE);
434
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, FALSE, 0);
436
button = create_button (GTK_WIDGET (dialog), _("_About"), GTK_SIGNAL_FUNC (on_about));
437
gtk_object_set_data (GTK_OBJECT (dialog), "about_button", button);
438
gtk_widget_set_sensitive (button, FALSE);
439
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, FALSE, 0);
441
gtk_box_pack_start (GTK_BOX (hbox), avail_list, TRUE, TRUE, 0);
442
gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 0);
444
gnome_cmd_dialog_add_expanding_category (GNOME_CMD_DIALOG (dialog), hbox);
446
avail_list = lookup_widget (avail_list, "avail_list");
447
gtk_signal_connect (GTK_OBJECT (avail_list), "unselect-row", GTK_SIGNAL_FUNC (on_plugin_unselected), dialog);
451
exec_pixmap = IMAGE_get_pixmap (PIXMAP_EXEC_WHEEL);
452
exec_mask = IMAGE_get_mask (PIXMAP_EXEC_WHEEL);
457
blank_pixmap = IMAGE_get_pixmap (PIXMAP_FLIST_ARROW_BLANK);
458
blank_mask = IMAGE_get_mask (PIXMAP_FLIST_ARROW_BLANK);
461
update_plugin_list (GTK_CLIST (avail_list), dialog);
463
gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), GNOME_STOCK_BUTTON_CLOSE, GTK_SIGNAL_FUNC(on_close), dialog);
464
gnome_cmd_dialog_set_transient_for (GNOME_CMD_DIALOG (dialog), GTK_WINDOW (main_win));
466
gtk_widget_set_size_request (GTK_WIDGET (dialog), 500, 300);
467
gtk_window_set_resizable((GtkWindow *) GTK_WIDGET (dialog), TRUE);
468
gtk_widget_show_all (GTK_WIDGET (dialog));