# HG changeset patch # User Ankit Vani # Date 1382639204 -19800 # Node ID eed15b8d51a11de5923fe6eb79a21601a282bb79 # Parent ae920fa3414351d186e08f01d347fa1147975d4e# Parent 01aafc96f36eedfd186ef4e58177400fa3895fd8 Merged soc.2013.gobjectification branch diff -r ae920fa34143 -r eed15b8d51a1 ChangeLog.API --- a/ChangeLog.API Thu Oct 24 18:21:35 2013 +0530 +++ b/ChangeLog.API Thu Oct 24 23:56:44 2013 +0530 @@ -86,6 +86,7 @@ * purple_plugin_info_get_license_text * purple_plugin_info_get_license_url * purple_plugin_info_get_pref_frame_callback + * purple_plugin_info_get_pref_request_callback * purple_plugin_info_get_ui_data * purple_plugin_info_set_ui_data * purple_plugin_register_type diff -r ae920fa34143 -r eed15b8d51a1 finch/gntplugin.c --- a/finch/gntplugin.c Thu Oct 24 18:21:35 2013 +0530 +++ b/finch/gntplugin.c Thu Oct 24 23:56:44 2013 +0530 @@ -65,7 +65,20 @@ GntWidget *conf; } plugins; -static GHashTable *confwins; +typedef struct +{ + enum + { + FINCH_PLUGIN_UI_DATA_TYPE_WINDOW, + FINCH_PLUGIN_UI_DATA_TYPE_REQUEST + } type; + + union + { + GntWidget *window; + gpointer request_handle; + } u; +} FinchPluginUiData; static GntWidget *process_pref_frame(PurplePluginPrefFrame *frame); @@ -167,26 +180,66 @@ g_list_free(list); } +static gboolean +has_prefs(PurplePlugin *plugin) +{ + PurplePluginInfo *info = purple_plugin_get_info(plugin); + FinchPluginInfoPrivate *priv = NULL; + gboolean ret; + + g_return_val_if_fail(plugin != NULL, FALSE); + + if (!purple_plugin_is_loaded(plugin)) + return FALSE; + + if (FINCH_IS_PLUGIN_INFO(info)) + priv = FINCH_PLUGIN_INFO_GET_PRIVATE(info); + + ret = ((priv && priv->get_pref_frame) || + purple_plugin_info_get_pref_frame_callback(info) || + purple_plugin_info_get_pref_request_callback(info)); + + return ret; +} + static void decide_conf_button(PurplePlugin *plugin) { - gboolean visible = FALSE; - PurplePluginInfo *info = purple_plugin_get_info(plugin); + if (has_prefs(plugin)) + gnt_widget_set_visible(plugins.conf, TRUE); + else + gnt_widget_set_visible(plugins.conf, FALSE); + + gnt_box_readjust(GNT_BOX(plugins.window)); + gnt_widget_draw(plugins.window); +} - if (purple_plugin_is_loaded(plugin)) { - FinchPluginInfoPrivate *priv = NULL; - if (FINCH_IS_PLUGIN_INFO(info)) - priv = FINCH_PLUGIN_INFO_GET_PRIVATE(info); +static void +finch_plugin_pref_close(PurplePlugin *plugin) +{ + PurplePluginInfo *info; + FinchPluginUiData *ui_data; + + g_return_if_fail(plugin != NULL); - if ((priv && priv->get_pref_frame) || - (purple_plugin_info_get_pref_frame_callback(info))) { - visible = TRUE; - } + info = purple_plugin_get_info(plugin); + ui_data = purple_plugin_info_get_ui_data(info); + + if (!ui_data) + return; + + if (ui_data->type == FINCH_PLUGIN_UI_DATA_TYPE_REQUEST) { + purple_request_close(PURPLE_REQUEST_FIELDS, + ui_data->u.request_handle); + return; } - gnt_widget_set_visible(plugins.conf, visible); - gnt_box_readjust(GNT_BOX(plugins.window)); - gnt_widget_draw(plugins.window); + g_return_if_fail(ui_data->type == FINCH_PLUGIN_UI_DATA_TYPE_WINDOW); + + gnt_widget_destroy(ui_data->u.window); + + g_free(ui_data); + purple_plugin_info_set_ui_data(info, NULL); } static void @@ -204,8 +257,6 @@ } else { - GntWidget *win; - if (!purple_plugin_unload(plugin, &error)) { purple_notify_error(NULL, _("ERROR"), _("unloading plugin failed"), error->message, NULL); purple_plugin_disable(plugin); @@ -213,10 +264,7 @@ g_error_free(error); } - if (confwins && (win = g_hash_table_lookup(confwins, plugin)) != NULL) - { - gnt_widget_destroy(win); - } + finch_plugin_pref_close(plugin); } decide_conf_button(plugin); finch_plugins_save_loaded(); @@ -309,15 +357,13 @@ } static void -confwin_init(void) +remove_confwin(GntWidget *window, gpointer _plugin) { - confwins = g_hash_table_new(g_direct_hash, g_direct_equal); -} + PurplePlugin *plugin = _plugin; + PurplePluginInfo *info = purple_plugin_get_info(plugin); -static void -remove_confwin(GntWidget *window, gpointer plugin) -{ - g_hash_table_remove(confwins, plugin); + g_free(info->ui_data); + purple_plugin_info_set_ui_data(info, NULL); } static void @@ -326,6 +372,7 @@ PurplePlugin *plugin; PurplePluginInfo *info; FinchPluginInfoPrivate *priv = NULL; + FinchPluginUiData *ui_data; g_return_if_fail(plugins.tree != NULL); @@ -337,10 +384,13 @@ return; } - if (confwins && g_hash_table_lookup(confwins, plugin)) + info = purple_plugin_get_info(plugin); + + if (purple_plugin_info_get_ui_data(info)) return; + ui_data = g_new0(FinchPluginUiData, 1); + purple_plugin_info_set_ui_data(info, ui_data); - info = purple_plugin_get_info(plugin); if (FINCH_IS_PLUGIN_INFO(info)) priv = FINCH_PLUGIN_INFO_GET_PRIVATE(info); @@ -368,23 +418,35 @@ gnt_widget_show(window); - if (confwins == NULL) - confwin_init(); - g_hash_table_insert(confwins, plugin, window); + ui_data->type = FINCH_PLUGIN_UI_DATA_TYPE_WINDOW; + ui_data->u.window = window; + } + else if (purple_plugin_info_get_pref_request_callback(info)) + { + PurplePluginPrefRequestCallback get_pref_request = purple_plugin_info_get_pref_request_callback(info); + gpointer handle; + + ui_data->type = FINCH_PLUGIN_UI_DATA_TYPE_REQUEST; + ui_data->u.request_handle = handle = get_pref_request(plugin); + purple_request_add_close_notify(handle, + purple_callback_set_zero, &info->ui_data); + purple_request_add_close_notify(handle, g_free, ui_data); } else if (purple_plugin_info_get_pref_frame_callback(info)) { PurplePluginPrefFrameCallback get_pref_frame = purple_plugin_info_get_pref_frame_callback(info); GntWidget *win = process_pref_frame(get_pref_frame(plugin)); - if (confwins == NULL) - confwin_init(); g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(remove_confwin), plugin); - g_hash_table_insert(confwins, plugin, win); + + ui_data->type = FINCH_PLUGIN_UI_DATA_TYPE_WINDOW; + ui_data->u.window = win; } else { - purple_notify_info(plugin, _("Error"), - _("No configuration options for this plugin."), NULL, NULL); + purple_notify_info(plugin, _("Error"), _("No configuration " + "options for this plugin."), NULL, NULL); + g_free(ui_data); + purple_plugin_info_set_ui_data(info, NULL); } } diff -r ae920fa34143 -r eed15b8d51a1 finch/plugins/gnttinyurl.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins.c --- a/libpurple/plugins.c Thu Oct 24 18:21:35 2013 +0530 +++ b/libpurple/plugins.c Thu Oct 24 23:56:44 2013 +0530 @@ -48,6 +48,9 @@ /** Callback that returns a preferences frame for a plugin */ PurplePluginPrefFrameCallback get_pref_frame; + /** Callback that returns a preferences request handle for a plugin */ + PurplePluginPrefRequestCallback get_pref_request; + /** TRUE if a plugin has been unloaded at least once. Auto-load * plugins that have been unloaded once will not be auto-loaded again. */ gboolean unloaded; @@ -59,6 +62,7 @@ PROP_UI_REQUIREMENT, PROP_GET_ACTIONS, PROP_PREFERENCES_FRAME, + PROP_PREFERENCES_REQUEST, PROP_FLAGS, PROP_LAST }; @@ -377,6 +381,9 @@ case PROP_PREFERENCES_FRAME: priv->get_pref_frame = g_value_get_pointer(value); break; + case PROP_PREFERENCES_REQUEST: + priv->get_pref_request = g_value_get_pointer(value); + break; case PROP_FLAGS: priv->flags = g_value_get_flags(value); break; @@ -402,6 +409,10 @@ g_value_set_pointer(value, purple_plugin_info_get_pref_frame_callback(info)); break; + case PROP_PREFERENCES_REQUEST: + g_value_set_pointer(value, + purple_plugin_info_get_pref_request_callback(info)); + break; case PROP_FLAGS: g_value_set_flags(value, purple_plugin_info_get_flags(info)); break; @@ -496,6 +507,12 @@ _("The callback that returns the preferences frame"), G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(obj_class, PROP_PREFERENCES_REQUEST, + g_param_spec_pointer("preferences-request", + _("Preferences request callback"), + _("Callback that returns preferences request handle"), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(obj_class, PROP_FLAGS, g_param_spec_flags("flags", _("Plugin flags"), @@ -752,6 +769,16 @@ return priv->get_pref_frame; } +PurplePluginPrefRequestCallback +purple_plugin_info_get_pref_request_callback(const PurplePluginInfo *info) +{ + PurplePluginInfoPrivate *priv = PURPLE_PLUGIN_INFO_GET_PRIVATE(info); + + g_return_val_if_fail(priv != NULL, NULL); + + return priv->get_pref_request; +} + PurplePluginInfoFlags purple_plugin_info_get_flags(const PurplePluginInfo *info) { diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins.h --- a/libpurple/plugins.h Thu Oct 24 18:21:35 2013 +0530 +++ b/libpurple/plugins.h Thu Oct 24 23:56:44 2013 +0530 @@ -98,6 +98,7 @@ typedef void (*PurplePluginActionCallback)(PurplePluginAction *); typedef GList *(*PurplePluginGetActionsCallback)(PurplePlugin *); typedef PurplePluginPrefFrame *(*PurplePluginPrefFrameCallback)(PurplePlugin *); +typedef gpointer (*PurplePluginPrefRequestCallback)(PurplePlugin *); /** * Flags that can be used to treat plugins differently. @@ -500,35 +501,37 @@ * * All properties except "id" and "purple-abi" are optional. * - * Valid property names are: \n - * "id" (string) The ID of the plugin. \n - * "name" (string) The translated name of the plugin. \n - * "version" (string) Version of the plugin. \n - * "category" (string) Primary category of the plugin. \n - * "summary" (string) Brief summary of the plugin. \n - * "description" (string) Full description of the plugin. \n - * "authors" (const gchar * const *) A NULL-terminated list of - * plugin authors. - * format: First Last \n - * "website" (string) Website of the plugin. \n - * "icon" (string) Path to a plugin's icon. \n - * "license-id" (string) Short name of the plugin's license. This + * Valid property names are: \n + * "id" (string) The ID of the plugin. \n + * "name" (string) The translated name of the plugin. \n + * "version" (string) Version of the plugin. \n + * "category" (string) Primary category of the plugin. \n + * "summary" (string) Brief summary of the plugin. \n + * "description" (string) Full description of the plugin. \n + * "authors" (const gchar * const *) A NULL-terminated list of + * plugin authors. + * format: First Last \n + * "website" (string) Website of the plugin. \n + * "icon" (string) Path to a plugin's icon. \n + * "license-id" (string) Short name of the plugin's license. This * should either be an identifier of the license from * http://dep.debian.net/deps/dep5/#license-specification - * or "Other" for custom licenses. \n - * "license-text" (string) The text of the plugin's license, if - * unlisted on DEP5. \n - * "license-url" (string) The plugin's license URL, if unlisted on - * DEP5. \n - * "dependencies" (const gchar * const *) A NULL-terminated list of - * plugin IDs required by the plugin. \n - * "abi-version" (guint32) The ABI version required by the plugin. \n - * "get-actions" (PurplePluginGetActionsCallback) Callback that - * returns a list of actions the plugin can - * perform. \n - * "preferences-frame" (PurplePluginPrefFrameCallback) Callback that returns - * a preferences frame for the plugin. - * "flags" (PurplePluginInfoFlags) The flags for a plugin. \n + * or "Other" for custom licenses. \n + * "license-text" (string) The text of the plugin's license, if + * unlisted on DEP5. \n + * "license-url" (string) The plugin's license URL, if unlisted on + * DEP5. \n + * "dependencies" (const gchar * const *) A NULL-terminated list of + * plugin IDs required by the plugin. \n + * "abi-version" (guint32) The ABI version required by the plugin. \n + * "get-actions" (PurplePluginGetActionsCallback) Callback that + * returns a list of actions the plugin can + * perform. \n + * "preferences-frame" (PurplePluginPrefFrameCallback) Callback that returns + * a preferences frame for the plugin. + * "preferences-request" (PurplePluginPrefRequestCallback) Callback that returns + * a preferences request handle for the plugin. + * "flags" (PurplePluginInfoFlags) The flags for a plugin. \n * * @param first_property The first property name * @param ... The value of the first property, followed optionally by more @@ -693,6 +696,17 @@ purple_plugin_info_get_pref_frame_callback(const PurplePluginInfo *info); /** + * Returns the callback that retrieves the preferences request handle for a + * plugin. + * + * @param info The plugin info to get the callback from. + * + * @return The callback that returns the preferences request handle. + */ +PurplePluginPrefRequestCallback +purple_plugin_info_get_pref_request_callback(const PurplePluginInfo *info); + +/** * Returns the plugin's flags. * * @param info The plugin's info instance. diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/autoaccept.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/joinpart.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/log_reader.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/newline.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/offlinemsg.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/perl/perl.c --- a/libpurple/plugins/perl/perl.c Thu Oct 24 18:21:35 2013 +0530 +++ b/libpurple/plugins/perl/perl.c Thu Oct 24 23:56:44 2013 +0530 @@ -117,6 +117,8 @@ static PurplePluginUiInfo ui_info = { purple_perl_get_plugin_frame, + NULL, + /* Padding */ NULL, NULL, diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/pluginpref_example.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/psychic.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/plugins/statenotify.c diff -r ae920fa34143 -r eed15b8d51a1 libpurple/util.c --- a/libpurple/util.c Thu Oct 24 18:21:35 2013 +0530 +++ b/libpurple/util.c Thu Oct 24 23:56:44 2013 +0530 @@ -4743,6 +4743,15 @@ (tmp >> 16) & 0xFFFF, g_random_int()); } +void purple_callback_set_zero(gpointer data) +{ + gpointer *ptr = data; + + g_return_if_fail(ptr != NULL); + + *ptr = NULL; +} + GValue * purple_value_new(GType type) { diff -r ae920fa34143 -r eed15b8d51a1 libpurple/util.h --- a/libpurple/util.h Thu Oct 24 18:21:35 2013 +0530 +++ b/libpurple/util.h Thu Oct 24 23:56:44 2013 +0530 @@ -1432,6 +1432,15 @@ gchar *purple_uuid_random(void); /** + * Sets given pointer to NULL. + * + * Function designed to be used as a GDestroyNotify callback. + * + * @param data A pointer to variable, which should be set to NULL. + */ +void purple_callback_set_zero(gpointer data); + +/** * Creates a new GValue of the specified type. * * @param type The type of data to be held by the GValue diff -r ae920fa34143 -r eed15b8d51a1 pidgin/gtkplugin.c --- a/pidgin/gtkplugin.c Thu Oct 24 18:21:35 2013 +0530 +++ b/pidgin/gtkplugin.c Thu Oct 24 23:56:44 2013 +0530 @@ -54,6 +54,26 @@ PROP_LAST }; +typedef struct +{ + enum + { + PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME, + PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST + } type; + + union + { + struct + { + GtkWidget *dialog; + PurplePluginPrefFrame *pref_frame; + } frame; + + gpointer request_handle; + } u; +} PidginPluginUiData; + static void plugin_toggled_stage_two(PurplePlugin *plug, GtkTreeModel *model, GtkTreeIter *iter, GError *error, gboolean unload); @@ -69,7 +89,6 @@ static GtkLabel *plugin_filename = NULL; static GtkWidget *pref_button = NULL; -static GHashTable *plugin_pref_dialogs = NULL; /* Set method for GObject properties */ static void @@ -162,8 +181,31 @@ return PIDGIN_PLUGIN_INFO(info); } -GtkWidget * -pidgin_plugin_get_config_frame(PurplePlugin *plugin) +static gboolean +pidgin_plugin_has_prefs(PurplePlugin *plugin) +{ + PurplePluginInfo *info = purple_plugin_get_info(plugin); + PidginPluginInfoPrivate *priv = NULL; + gboolean ret; + + g_return_val_if_fail(plugin != NULL, FALSE); + + if (!purple_plugin_is_loaded(plugin)) + return FALSE; + + if (PIDGIN_IS_PLUGIN_INFO(info)) + priv = PIDGIN_PLUGIN_INFO_GET_PRIVATE(info); + + ret = ((priv && priv->get_config_frame) || + purple_plugin_info_get_pref_frame_callback(info) || + purple_plugin_info_get_pref_request_callback(info)); + + return ret; +} + +static GtkWidget * +pidgin_plugin_get_config_frame(PurplePlugin *plugin, + PurplePluginPrefFrame **purple_pref_frame) { GtkWidget *config = NULL; PurplePluginInfo *info; @@ -175,20 +217,10 @@ if (PIDGIN_IS_PLUGIN_INFO(info)) priv = PIDGIN_PLUGIN_INFO_GET_PRIVATE(info); - if (priv && priv->get_config_frame) - { + if (priv) config = priv->get_config_frame(plugin); - if (purple_plugin_info_get_pref_frame_callback(info)) - { - purple_debug_warning("gtkplugin", - "Plugin %s contains both, ui_info and " - "prefs_info preferences; prefs_info will be " - "ignored.", - purple_plugin_info_get_name(info)); - } - } - else if (purple_plugin_info_get_pref_frame_callback(info)) + if (!config && purple_plugin_info_get_pref_frame_callback(info)) { PurplePluginPrefFrame *frame; PurplePluginPrefFrameCallback get_pref_frame = @@ -198,28 +230,143 @@ config = pidgin_plugin_pref_create_frame(frame); - purple_plugin_info_set_ui_data(info, frame); + *purple_pref_frame = frame; } return config; } -static gboolean -pidgin_plugin_has_config_frame(PurplePlugin *plugin) +static void +pref_dialog_close(PurplePlugin *plugin) { - PurplePluginInfo *info = purple_plugin_get_info(plugin); + PurplePluginInfo *info; + PidginPluginUiData *ui_data; + + g_return_if_fail(plugin != NULL); + + info = purple_plugin_get_info(plugin); + + ui_data = purple_plugin_info_get_ui_data(info); + if (ui_data == NULL) + return; + + if (ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST) { + purple_request_close(PURPLE_REQUEST_FIELDS, + ui_data->u.request_handle); + return; + } + + g_return_if_fail(ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME); + + gtk_widget_destroy(ui_data->u.frame.dialog); + + if (ui_data->u.frame.pref_frame) + purple_plugin_pref_frame_destroy(ui_data->u.frame.pref_frame); + + g_free(ui_data); + purple_plugin_info_set_ui_data(info, NULL); +} + + +static void +pref_dialog_response_cb(GtkWidget *dialog, int response, PurplePlugin *plugin) +{ + if (response == GTK_RESPONSE_CLOSE || + response == GTK_RESPONSE_DELETE_EVENT) + { + pref_dialog_close(plugin); + } +} + +static void +pidgin_plugin_open_config(PurplePlugin *plugin, GtkWindow *parent) +{ + PurplePluginInfo *info; PidginPluginInfoPrivate *priv = NULL; - gboolean ret; + PidginPluginUiData *ui_data; + PurplePluginPrefFrameCallback get_pref_frame; + PurplePluginPrefRequestCallback get_pref_request; + PidginPluginConfigFrame get_pidgin_frame = NULL; + gint prefs_count; + + g_return_if_fail(plugin != NULL); - g_return_val_if_fail(plugin != NULL, FALSE); + info = purple_plugin_get_info(plugin); + + if (!pidgin_plugin_has_prefs(plugin)) { + purple_debug_warning("gtkplugin", "Plugin has no prefs"); + return; + } + + if (purple_plugin_info_get_ui_data(info)) + return; if (PIDGIN_IS_PLUGIN_INFO(info)) priv = PIDGIN_PLUGIN_INFO_GET_PRIVATE(info); - ret = ((priv && priv->get_config_frame) || - purple_plugin_info_get_pref_frame_callback(info)); + get_pref_frame = purple_plugin_info_get_pref_frame_callback(info); + get_pref_request = purple_plugin_info_get_pref_request_callback(info); + + if (priv) + get_pidgin_frame = priv->get_config_frame; + + prefs_count = 0; + if (get_pref_frame) + prefs_count++; + if (get_pref_request) + prefs_count++; + if (get_pidgin_frame) + prefs_count++; + + if (prefs_count > 1) { + purple_debug_warning("gtkplugin", "Plugin %s contains more than" + " one prefs callback, some will be ignored.", + purple_plugin_info_get_name(info)); + } + g_return_if_fail(prefs_count > 0); + + ui_data = g_new0(PidginPluginUiData, 1); + purple_plugin_info_set_ui_data(info, ui_data); - return ret; + /* Priority: pidgin frame > purple request > purple frame + * Purple frame could be replaced with purple request some day. + */ + if (get_pref_request && !get_pidgin_frame) { + ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST; + ui_data->u.request_handle = get_pref_request(plugin); + purple_request_add_close_notify(ui_data->u.request_handle, + purple_callback_set_zero, &info->ui_data); + purple_request_add_close_notify(ui_data->u.request_handle, + g_free, ui_data); + } else { + GtkWidget *box, *dialog; + + ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME; + + box = pidgin_plugin_get_config_frame(plugin, + &ui_data->u.frame.pref_frame); + if (box == NULL) { + purple_debug_error("gtkplugin", + "Failed to display prefs frame"); + g_free(ui_data); + purple_plugin_info_set_ui_data(info, NULL); + return; + } + + ui_data->u.frame.dialog = dialog = gtk_dialog_new_with_buttons( + PIDGIN_ALERT_TITLE, parent, + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, NULL); + + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(pref_dialog_response_cb), plugin); + gtk_container_add(GTK_CONTAINER( + gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box); + gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config"); + gtk_window_set_title(GTK_WINDOW(dialog), + _(purple_plugin_info_get_name(info))); + gtk_widget_show_all(dialog); + } } void @@ -328,7 +475,7 @@ if (plug == plugin) { gtk_widget_set_sensitive(pref_button, - loaded && pidgin_plugin_has_config_frame(plug)); + pidgin_plugin_has_prefs(plug)); } } @@ -349,29 +496,6 @@ plugin_loading_common(plugin, view, FALSE); } -static void pref_dialog_response_cb(GtkWidget *d, int response, PurplePlugin *plug) -{ - PurplePluginInfo *info = purple_plugin_get_info(plug); - - switch (response) { - case GTK_RESPONSE_CLOSE: - case GTK_RESPONSE_DELETE_EVENT: - g_hash_table_remove(plugin_pref_dialogs, plug); - if (g_hash_table_size(plugin_pref_dialogs) == 0) { - g_hash_table_destroy(plugin_pref_dialogs); - plugin_pref_dialogs = NULL; - } - gtk_widget_destroy(d); - - if (purple_plugin_info_get_pref_frame_callback(info) && info->ui_data) { - purple_plugin_pref_frame_destroy(info->ui_data); - purple_plugin_info_set_ui_data(info, NULL); - } - - break; - } -} - static void plugin_unload_confirm_cb(gpointer *data) { PurplePlugin *plugin = (PurplePlugin *)data[0]; @@ -390,7 +514,6 @@ GtkTreePath *path = gtk_tree_path_new_from_string(pth); PurplePlugin *plug; GError *error = NULL; - GtkWidget *dialog = NULL; gtk_tree_model_get_iter(model, iter, path); gtk_tree_path_free(path); @@ -407,9 +530,7 @@ } else { - if (plugin_pref_dialogs != NULL && - (dialog = g_hash_table_lookup(plugin_pref_dialogs, plug))) - pref_dialog_response_cb(dialog, GTK_RESPONSE_DELETE_EVENT, plug); + pref_dialog_close(plug); if (purple_plugin_get_dependent_plugins(plug) != NULL) { @@ -474,8 +595,7 @@ purple_notify_warning(NULL, NULL, _("Could not load plugin"), error->message, NULL); } - gtk_widget_set_sensitive(pref_button, - purple_plugin_is_loaded(plug) && pidgin_plugin_has_config_frame(plug)); + gtk_widget_set_sensitive(pref_button, pidgin_plugin_has_prefs(plug)); if (error != NULL) { @@ -616,8 +736,7 @@ g_free(tmp); } - gtk_widget_set_sensitive(pref_button, - purple_plugin_is_loaded(plug) && pidgin_plugin_has_config_frame(plug)); + gtk_widget_set_sensitive(pref_button, pidgin_plugin_has_prefs(plug)); /* Make sure the selected plugin is still visible */ g_idle_add(ensure_plugin_visible, sel); @@ -627,22 +746,22 @@ static void plugin_dialog_response_cb(GtkWidget *d, int response, GtkTreeSelection *sel) { - PurplePlugin *plug; - GtkWidget *dialog, *box; + PurplePlugin *plugin; GtkTreeModel *model; GValue val; GtkTreeIter iter; + GList *list, *it; switch (response) { case GTK_RESPONSE_CLOSE: case GTK_RESPONSE_DELETE_EVENT: purple_request_close_with_handle(plugin_dialog); purple_signals_disconnect_by_handle(plugin_dialog); + list = purple_plugins_find_all(); + for (it = list; it; it = g_list_next(it)) + pref_dialog_close(it->data); + g_list_free(list); gtk_widget_destroy(d); - if (plugin_pref_dialogs != NULL) { - g_hash_table_destroy(plugin_pref_dialogs); - plugin_pref_dialogs = NULL; - } plugin_dialog = NULL; break; case PIDGIN_RESPONSE_CONFIGURE: @@ -650,32 +769,12 @@ return; val.g_type = 0; gtk_tree_model_get_value(model, &iter, 2, &val); - plug = g_value_get_pointer(&val); - if (plug == NULL) - break; - if (plugin_pref_dialogs != NULL && - g_hash_table_lookup(plugin_pref_dialogs, plug)) - break; - box = pidgin_plugin_get_config_frame(plug); - if (box == NULL) + plugin = g_value_get_pointer(&val); + g_value_unset(&val); + if (plugin == NULL) break; - dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, GTK_WINDOW(d), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - if (plugin_pref_dialogs == NULL) - plugin_pref_dialogs = g_hash_table_new(NULL, NULL); - - g_hash_table_insert(plugin_pref_dialogs, plug, dialog); - - g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(pref_dialog_response_cb), plug); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box); - gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config"); - gtk_window_set_title(GTK_WINDOW(dialog), - _(purple_plugin_info_get_name(purple_plugin_get_info(plug)))); - gtk_widget_show_all(dialog); - g_value_unset(&val); + pidgin_plugin_open_config(plugin, GTK_WINDOW(d)); break; } diff -r ae920fa34143 -r eed15b8d51a1 pidgin/gtkplugin.h --- a/pidgin/gtkplugin.h Thu Oct 24 18:21:35 2013 +0530 +++ b/pidgin/gtkplugin.h Thu Oct 24 23:56:44 2013 +0530 @@ -94,17 +94,6 @@ G_GNUC_NULL_TERMINATED; /** - * Returns the configuration frame widget for a GTK+ plugin, if one - * exists. - * - * @param plugin The plugin. - * - * @return The frame, if the plugin is a GTK+ plugin and provides a - * configuration frame. - */ -GtkWidget *pidgin_plugin_get_config_frame(PurplePlugin *plugin); - -/** * Saves all loaded plugins. */ void pidgin_plugins_save(void); diff -r ae920fa34143 -r eed15b8d51a1 pidgin/plugins/extplacement.c diff -r ae920fa34143 -r eed15b8d51a1 pidgin/plugins/markerline.c