/soc/2013/bhaskar/plugins-window: 7f2290906b5a: Added functional...

Bhaskar Kandiyal bkandiyal at gmail.com
Thu Jun 20 09:51:12 EDT 2013


Changeset: 7f2290906b5ae5cd7707a891457297fe6680c6a1
Author:	 Bhaskar Kandiyal <bkandiyal at gmail.com>
Date:	 2013-06-20 19:16 +0530
Branch:	 soc.2013.plugins_window
URL: https://hg.pidgin.im/soc/2013/bhaskar/plugins-window/rev/7f2290906b5a

Description:

Added functionality to remove plugins in libpurple and the plugins window

diffstat:

 libpurple/plugin.c            |  53 +++++++++++++++++++++++++++++++++++++++++++
 libpurple/plugin.h            |  22 +++++++++++++++++
 pidgin/gtkplugin.c            |  52 ++++++++++++++++++++++++++++++++++++++----
 pidgin/ui/plugin_details.html |   4 +++
 4 files changed, 126 insertions(+), 5 deletions(-)

diffs (243 lines):

diff --git a/libpurple/plugin.c b/libpurple/plugin.c
--- a/libpurple/plugin.c
+++ b/libpurple/plugin.c
@@ -36,6 +36,8 @@
 #include "valgrind.h"
 #include "version.h"
 
+#include <gio/gio.h>
+
 typedef struct
 {
 	GHashTable *commands;
@@ -199,6 +201,8 @@ purple_plugin_probe(const char *filename
 	gpointer unpunned;
 	gchar *basename = NULL;
 	gboolean (*purple_init_plugin)(PurplePlugin *);
+	GFile *gfile;
+	GFileInfo *gfile_info;
 
 	purple_debug_misc("plugins", "probing %s\n", filename);
 	g_return_val_if_fail(filename != NULL, NULL);
@@ -477,6 +481,21 @@ purple_plugin_probe(const char *filename
 		}
 	}
 
+	gfile = g_file_new_for_path(filename);
+	gfile_info = g_file_query_info(gfile, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+	if (gfile_info != NULL)
+	{
+		plugin->removeable = g_file_info_get_attribute_boolean(gfile_info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE);
+		g_object_unref(gfile_info);
+		purple_debug_info("plugins", "Removeable: %s\n", (plugin->removeable)?"TRUE":"FALSE");
+	}
+	else {
+		plugin->removeable = FALSE;
+		purple_debug_info("plugins", "Cannot read file info of %s", filename);
+	}
+
+	g_object_unref(gfile);
 	return plugin;
 #else
 	return NULL;
@@ -884,6 +903,32 @@ purple_plugin_destroy(PurplePlugin *plug
 }
 
 gboolean
+purple_plugin_remove(PurplePlugin *plugin)
+{
+#ifdef PURPLE_PLUGINS
+	gboolean ret;
+	GFile *file;
+
+	g_return_val_if_fail(plugin != NULL, FALSE);
+
+	if (!plugin->removeable)
+		return FALSE;
+
+	file = g_file_new_for_path(plugin->path);
+
+	purple_plugin_destroy(plugin);
+
+	ret = g_file_delete(file, NULL, NULL);
+
+	g_object_unref(file);
+
+	return ret;
+#else
+	return TRUE;
+#endif /* PURPLE_PLUGINS */
+}
+
+gboolean
 purple_plugin_is_loaded(const PurplePlugin *plugin)
 {
 	g_return_val_if_fail(plugin != NULL, FALSE);
@@ -899,6 +944,14 @@ purple_plugin_is_unloadable(const Purple
 	return plugin->unloadable;
 }
 
+gboolean
+purple_plugin_is_removeable(const PurplePlugin *plugin)
+{
+	g_return_val_if_fail(plugin != NULL, FALSE);
+	
+	return plugin->removeable;
+}
+
 const gchar *
 purple_plugin_get_id(const PurplePlugin *plugin) {
 	g_return_val_if_fail(plugin, NULL);
diff --git a/libpurple/plugin.h b/libpurple/plugin.h
--- a/libpurple/plugin.h
+++ b/libpurple/plugin.h
@@ -159,6 +159,7 @@ struct _PurplePlugin
 	void *ipc_data;                        /**< IPC data.                 */
 	void *extra;                           /**< Plugin-specific data.     */
 	gboolean unloadable;                   /**< Unloadable                */
+	gboolean removeable;				   /**< Removeable				  */	
 	GList *dependent_plugins;              /**< Plugins depending on this */
 
 	void (*_purple_reserved1)(void);
@@ -338,6 +339,13 @@ gboolean purple_plugin_reload(PurplePlug
 void purple_plugin_destroy(PurplePlugin *plugin);
 
 /**
+ * Completely removes the plugin file from the filesystem.
+ *
+ * @param plugin The plugin hangle
+ */
+gboolean purple_plugin_remove(PurplePlugin *plugin);
+
+/**
  * Returns whether or not a plugin is currently loaded.
  *
  * @param plugin The plugin.
@@ -361,6 +369,20 @@ gboolean purple_plugin_is_loaded(const P
 gboolean purple_plugin_is_unloadable(const PurplePlugin *plugin);
 
 /**
+ * Returns whether or not a plugin is removeable.
+ * 
+ * If this returns @c TRUE, the plugin can be removed that is,
+ * it's file can be deleted. If the plugin file is writeable then
+ * the plugin can be removed.
+ * 
+ * @param plugin The plugin.
+ * 
+ * @return @c TRUE if the plugin can be removed
+ * 			@c FALSE otherwise
+ */
+ gboolean purple_plugin_is_removeable(const PurplePlugin *plugin);
+ 
+/**
  * Returns a plugin's id.
  *
  * @param plugin The plugin.
diff --git a/pidgin/gtkplugin.c b/pidgin/gtkplugin.c
--- a/pidgin/gtkplugin.c
+++ b/pidgin/gtkplugin.c
@@ -480,11 +480,11 @@ static void prefs_plugin_sel (GtkTreeSel
 	gtk_webview_safe_execute_script(GTK_WEBVIEW(plugin_details), buf);
 	g_free(buf);
 
-	buf = g_strdup_printf("enableConfigure(%d)", purple_plugin_is_loaded(plug)
+	buf = g_strdup_printf("enableConfigure(%d);enableRemove(%d)", purple_plugin_is_loaded(plug)
 		&& ((PIDGIN_IS_PIDGIN_PLUGIN(plug) && plug->info->ui_info
 			&& PIDGIN_PLUGIN_UI_INFO(plug)->get_config_frame)
 		 || (plug->info->prefs_info
-			&& plug->info->prefs_info->get_plugin_pref_frame)));
+			&& plug->info->prefs_info->get_plugin_pref_frame)), plug->removeable);
 
 	gtk_webview_safe_execute_script(GTK_WEBVIEW(plugin_details), buf);
 
@@ -669,10 +669,15 @@ plugin_details_button_click_cb(WebKitDOM
 	PurplePlugin *plugin;
 	GtkTreeModel *model;
 	gchar *id;
+	GtkWidget *dialog;
+	gint result;
+	GtkListStore *ls;
+	gboolean ret;
 
 	g_object_get(element, "id", &id, NULL);
 
-	if (g_str_equal(id, "configure")) {
+	if (g_str_equal(id, "configure"))
+	{
 
 		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(event_view));
 
@@ -687,10 +692,47 @@ plugin_details_button_click_cb(WebKitDOM
 		/* Now show the pref-dialog for the plugin */
 		plugin_show_configure_dialog(sel);
 	}
+	else if(g_str_equal(id, "remove"))
+	{
+		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(event_view));
+
+		if (!gtk_tree_selection_get_selected(sel, &model, &iter))
+			return;
+
+		gtk_tree_model_get(model, &iter, 2, &plugin, -1);
+
+		dialog = gtk_message_dialog_new(GTK_WINDOW(plugin_dialog), GTK_DIALOG_MODAL,
+				GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Are you sure you wish to delete the plugin \'%s\'?", plugin->info->name);
+		result = gtk_dialog_run(GTK_DIALOG(dialog));
+		gtk_widget_destroy(dialog);
+
+		switch (result) {
+		case GTK_RESPONSE_YES:
+			ret = purple_plugin_remove(plugin);
+			if (ret) {
+				ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(event_view)));
+				g_object_ref(G_OBJECT(ls));
+
+				gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), NULL);
+				update_plugin_list(ls);
+				gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), GTK_TREE_MODEL(ls));
+
+				g_object_unref(G_OBJECT(ls));
+			}
+			else {
+				dialog = gtk_message_dialog_new(GTK_WINDOW(plugin_dialog), GTK_DIALOG_MODAL,
+						GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error removing plugin");
+				gtk_dialog_run(GTK_DIALOG(dialog));
+				gtk_widget_destroy(dialog);
+			}
+
+		break;
+		}
+	}
 }
 
 static void
-setup_input_event_handlers(WebKitWebView *webview) {
+setup_webview_input_event_handlers(WebKitWebView *webview) {
 	WebKitDOMDocument *document;
 	WebKitDOMNodeList *elements;
 	gulong element_count;
@@ -717,7 +759,7 @@ plugin_details_view_load_status_cb(WebKi
 	purple_debug_info("plugins", "Load status called\n");
 	switch (status) {
 	case WEBKIT_LOAD_FINISHED:
-		setup_input_event_handlers(webview);
+		setup_webview_input_event_handlers(webview);
 		break;
 	default:
 		break;
diff --git a/pidgin/ui/plugin_details.html b/pidgin/ui/plugin_details.html
--- a/pidgin/ui/plugin_details.html
+++ b/pidgin/ui/plugin_details.html
@@ -90,6 +90,10 @@
 			document.getElementById('configure').disabled = !enable;
 		}
 		
+		function enableRemove(enable) {
+			document.getElementById('remove').disabled = !enable;
+		}
+		
 		function extractAuthors(author) {
 			var regexp = /(.*)<(.*)>.*/;
 			var ret = Array();



More information about the Commits mailing list