From e8456beadc9c065b52291ebdc552564d0a1d9069 Mon Sep 17 00:00:00 2001 From: TingPing Date: Sun, 4 Aug 2013 04:36:10 -0400 Subject: [PATCH] Add reload command for plugins and add to gui --- plugins/perl/perl.c | 9 +++++--- plugins/python/python.c | 5 +---- src/common/outbound.c | 35 +++++++++++++++++++++++++++++- src/common/plugin.c | 38 +++++++++++++++++++++++++++++++++ src/common/plugin.h | 1 + src/fe-gtk/plugingui.c | 47 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 8 deletions(-) diff --git a/plugins/perl/perl.c b/plugins/perl/perl.c index 732fd65c..abb66c5a 100644 --- a/plugins/perl/perl.c +++ b/plugins/perl/perl.c @@ -1520,7 +1520,7 @@ perl_command_unload (char *word[], char *word_eol[], void *userdata) } static int -perl_command_reload (char *word[], char *word_eol[], void *userdata) +perl_command_reload (char *word[], char *word_eol[], void *eat) { char *file = get_filename (word, word_eol); @@ -1529,7 +1529,10 @@ perl_command_reload (char *word[], char *word_eol[], void *userdata) return HEXCHAT_EAT_HEXCHAT; } - return HEXCHAT_EAT_HEXCHAT; + if (eat) + return HEXCHAT_EAT_HEXCHAT; + else + return HEXCHAT_EAT_NONE; } void @@ -1570,7 +1573,7 @@ hexchat_plugin_init (hexchat_plugin * plugin_handle, char **plugin_name, hexchat_hook_command (ph, "reload", HEXCHAT_PRI_NORM, perl_command_reload, 0, 0); hexchat_hook_command (ph, "pl_reload", HEXCHAT_PRI_NORM, perl_command_reload, 0, - 0); + (int*)1); hexchat_hook_command (ph, "unloadall", HEXCHAT_PRI_NORM, perl_command_unloadall, 0, 0); hexchat_hook_command (ph, "reloadall", HEXCHAT_PRI_NORM, diff --git a/plugins/python/python.c b/plugins/python/python.c index ade5de95..7bedcad9 100644 --- a/plugins/python/python.c +++ b/plugins/python/python.c @@ -382,9 +382,6 @@ Usage: /PY LOAD \n\ ABOUT\n\ \n"; -/* Remove if/when HexChat supports this command for plugins */ -static const char reload[] = "Usage: RELOAD , reloads a python script"; - static const char about[] = "HexChat Python " PY_VERSION " Interface Version " VERSION "\n"; /* ===================================================================== */ @@ -2855,7 +2852,7 @@ hexchat_plugin_init(hexchat_plugin *plugin_handle, hexchat_hook_command(ph, "PY", HEXCHAT_PRI_NORM, Command_Py, usage, 0); hexchat_hook_command(ph, "LOAD", HEXCHAT_PRI_NORM, Command_Load, 0, 0); hexchat_hook_command(ph, "UNLOAD", HEXCHAT_PRI_NORM, Command_Unload, 0, 0); - hexchat_hook_command(ph, "RELOAD", HEXCHAT_PRI_NORM, Command_Reload, reload, 0); + hexchat_hook_command(ph, "RELOAD", HEXCHAT_PRI_NORM, Command_Reload, 0, 0); #ifdef WITH_THREAD thread_timer = hexchat_hook_timer(ph, 300, Callback_ThreadTimer, NULL); #endif diff --git a/src/common/outbound.c b/src/common/outbound.c index 91188a8a..21af2940 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -3498,6 +3498,39 @@ cmd_unload (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return FALSE; } +static int +cmd_reload (struct session *sess, char *tbuf, char *word[], char *word_eol[]) +{ +#ifdef USE_PLUGIN + int len, by_file = FALSE; + + len = strlen (word[2]); +#ifdef WIN32 + if (len > 4 && g_ascii_strcasecmp (word[2] + len - 4, ".dll") == 0) +#else +#if defined(__hpux) + if (len > 3 && g_ascii_strcasecmp (word[2] + len - 3, ".sl") == 0) +#else + if (len > 3 && g_ascii_strcasecmp (word[2] + len - 3, ".so") == 0) +#endif +#endif + by_file = TRUE; + + switch (plugin_reload (sess, word[2], by_file)) + { + case 0: /* error */ + PrintText (sess, _("No such plugin found.\n")); + break; + case 1: /* success */ + return TRUE; + case 2: /* fake plugin, we know it exists but scripts should handle it. */ + return TRUE; + } +#endif + + return FALSE; +} + static server * find_server_from_hostname (char *hostname) { @@ -3918,7 +3951,7 @@ const struct commands xc_cmds[] = { N_("RECONNECT [] [] [], Can be called just as /RECONNECT to reconnect to the current server or with /RECONNECT ALL to reconnect to all the open servers")}, #endif {"RECV", cmd_recv, 1, 0, 1, N_("RECV , send raw data to HexChat, as if it was received from the IRC server")}, - + {"RELOAD", cmd_reload, 0, 0, 1, N_("RELOAD , reloads a plugin or script")}, {"SAY", cmd_say, 0, 0, 1, N_("SAY , sends the text to the object in the current window")}, {"SEND", cmd_send, 0, 0, 1, N_("SEND []")}, diff --git a/src/common/plugin.c b/src/common/plugin.c index 50157ea1..9ce387c8 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -512,6 +512,44 @@ plugin_auto_load (session *sess) g_free (sub_dir); } +int +plugin_reload (session *sess, char *name, int by_filename) +{ + GSList *list; + char *filename; + char *ret; + hexchat_plugin *pl; + + list = plugin_list; + while (list) + { + pl = list->data; + /* static-plugins (plugin-timer.c) have a NULL filename */ + if ((by_filename && pl->filename && g_ascii_strcasecmp (name, pl->filename) == 0) || + (by_filename && pl->filename && g_ascii_strcasecmp (name, file_part (pl->filename)) == 0) || + (!by_filename && g_ascii_strcasecmp (name, pl->name) == 0)) + { + /* statically linked plugins have a NULL filename */ + if (pl->filename != NULL && !pl->fake) + { + filename = g_strdup (pl->filename); + plugin_free (pl, TRUE, FALSE); + ret = plugin_load (sess, filename, NULL); + g_free (filename); + if (ret == NULL) + return 1; + else + return 0; + } + else + return 2; + } + list = list->next; + } + + return 0; +} + #endif static GSList * diff --git a/src/common/plugin.h b/src/common/plugin.h index f75639e9..ee9da8c1 100644 --- a/src/common/plugin.h +++ b/src/common/plugin.h @@ -164,6 +164,7 @@ struct _hexchat_plugin #endif char *plugin_load (session *sess, char *filename, char *arg); +int plugin_reload (session *sess, char *name, int by_filename); void plugin_add (session *sess, char *filename, void *handle, void *init_func, void *deinit_func, char *arg, int fake); int plugin_kill (char *name, int by_filename); void plugin_kill_all (void); diff --git a/src/fe-gtk/plugingui.c b/src/fe-gtk/plugingui.c index c7193837..ed093404 100644 --- a/src/fe-gtk/plugingui.c +++ b/src/fe-gtk/plugingui.c @@ -72,6 +72,31 @@ plugingui_treeview_new (GtkWidget *box) return view; } +static char * +plugingui_getfilename (GtkTreeView *view) +{ + GtkTreeModel *model; + GtkTreeSelection *sel; + GtkTreeIter iter; + GValue file; + char *str; + + memset (&file, 0, sizeof (file)); + + sel = gtk_tree_view_get_selection (view); + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + gtk_tree_model_get_value (model, &iter, FILE_COLUMN, &file); + + str = g_value_dup_string (&file); + g_value_unset (&file); + + return str; + } + + return NULL; +} + static void plugingui_close (GtkWidget * wid, gpointer a) { @@ -193,6 +218,25 @@ plugingui_unload (GtkWidget * wid, gpointer unused) g_free (file); } +static void +plugingui_reloadbutton_cb (GtkWidget *wid, GtkTreeView *view) +{ + char *file = plugingui_getfilename(view); + + if (file) + { + char *buf = malloc (strlen (file) + 9); + + if (strchr (file, ' ')) + sprintf (buf, "RELOAD \"%s\"", file); + else + sprintf (buf, "RELOAD %s", file); + handle_command (current_sess, buf, FALSE); + free (buf); + g_free (file); + } +} + void plugingui_open (void) { @@ -225,6 +269,9 @@ plugingui_open (void) gtkutil_button (hbox, GTK_STOCK_DELETE, NULL, plugingui_unload, NULL, _("_UnLoad")); + gtkutil_button (hbox, NULL, NULL, + plugingui_reloadbutton_cb, view, _("_Reload...")); + fe_pluginlist_update (); gtk_widget_show_all (plugin_window);