summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--plugins/perl/perl.c9
-rw-r--r--plugins/python/python.c5
-rw-r--r--src/common/outbound.c35
-rw-r--r--src/common/plugin.c38
-rw-r--r--src/common/plugin.h1
-rw-r--r--src/fe-gtk/plugingui.c47
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   <filename>\n\
            ABOUT\n\
 \n";
 
-/* Remove if/when HexChat supports this command for plugins */
-static const char reload[] = "Usage: RELOAD <name>, 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 [<host>] [<port>] [<password>], 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 <text>, send raw data to HexChat, as if it was received from the IRC server")},
-
+	{"RELOAD", cmd_reload, 0, 0, 1, N_("RELOAD <name>, reloads a plugin or script")},
 	{"SAY", cmd_say, 0, 0, 1,
 	 N_("SAY <text>, sends the text to the object in the current window")},
 	{"SEND", cmd_send, 0, 0, 1, N_("SEND <nick> [<file>]")},
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);