/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