--- a/ChangeLog.API Tue May 17 01:58:55 2022 -0500
+++ b/ChangeLog.API Thu May 19 20:32:23 2022 -0500
@@ -804,6 +804,8 @@
+ * pidgin_accounts_window_hide + * pidgin_accounts_window_show, use pidgin_account_manager_new instead. * pidgin_blist_draw_tooltip
* pidgin_blist_layout_get_type
--- a/pidgin/gtkaccount.c Tue May 17 01:58:55 2022 -0500
+++ b/pidgin/gtkaccount.c Thu May 19 20:32:23 2022 -0500
@@ -38,21 +38,8 @@
#include "pidginprotocolchooser.h"
#include "pidginproxyoptions.h"
@@ -66,20 +53,6 @@
- GtkWidget *modify_button;
- GtkWidget *delete_button;
- GtkTreeViewColumn *username_col;
@@ -138,13 +111,6 @@
PidginAccountDialogType type;
} PidginAccountDialogShowData;
-static AccountsWindow *accounts_window = NULL;
-static GHashTable *account_pref_wins;
-static void add_account_to_liststore(PurpleAccount *account, gpointer user_data);
-static void set_account(GtkListStore *store, GtkTreeIter *iter,
- PurpleAccount *account, GdkPixbuf *global_buddyicon);
/**************************************************************************
* Add/Modify Account dialog
**************************************************************************/
@@ -948,8 +914,6 @@
account_win_destroy_cb(GtkWidget *w, GdkEvent *event,
AccountPrefsDialog *dialog)
- g_hash_table_remove(account_pref_wins, dialog->account);
gtk_widget_destroy(dialog->window);
g_list_free(dialog->user_split_entries);
@@ -1221,24 +1185,12 @@
- if (accounts_window != NULL && account != NULL &&
- (dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL)
- gtk_window_present(GTK_WINDOW(dialog->window));
dialog = g_new0(AccountPrefsDialog, 1);
if(PURPLE_IS_ACCOUNT(account)) {
dialog->protocol_id = g_strdup(purple_account_get_protocol_id(account));
- if (accounts_window != NULL && account != NULL)
- g_hash_table_insert(account_pref_wins, account, dialog);
dialog->account = account;
dialog->password = g_strdup(password);
@@ -1373,586 +1325,6 @@
/**************************************************************************
**************************************************************************/
-signed_on_off_cb(PurpleConnection *gc, gpointer user_data)
- PurpleAccount *account;
- PurpleAccountManager *manager = NULL;
- GList *accounts = NULL;
- /* Don't need to do anything if the accounts window is not visible */
- if(accounts_window == NULL) {
- manager = purple_account_manager_get_default();
- accounts = purple_account_manager_get_all(manager);
- account = purple_connection_get_account(gc);
- model = GTK_TREE_MODEL(accounts_window->model);
- index = g_list_index(accounts, account);
- if(gtk_tree_model_iter_nth_child(model, &iter, NULL, index)) {
- pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_MEDIUM);
- if((pixbuf != NULL) && purple_account_is_disconnected(account)) {
- gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
- gtk_list_store_set(accounts_window->model, &iter,
- g_object_unref(G_OBJECT(pixbuf));
- * Get the GtkTreeIter of the specified account in the
-accounts_window_find_account_in_treemodel(GtkTreeIter *iter, PurpleAccount *account)
- g_return_val_if_fail(account != NULL, FALSE);
- g_return_val_if_fail(accounts_window != NULL, FALSE);
- model = GTK_TREE_MODEL(accounts_window->model);
- if (!gtk_tree_model_get_iter_first(model, iter))
- gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1);
- while (gtk_tree_model_iter_next(model, iter))
- gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1);
-account_removed_cb(PurpleAccount *account, gpointer user_data)
- AccountPrefsDialog *dialog;
- /* If the account was being modified, close the edit window */
- if((dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL) {
- account_win_destroy_cb(NULL, NULL, dialog);
- if(accounts_window == NULL) {
- /* Remove the account from the GtkListStore */
- if(accounts_window_find_account_in_treemodel(&iter, account)) {
- gtk_list_store_remove(accounts_window->model, &iter);
-account_abled_cb(PurpleAccount *account, gpointer user_data)
- if (accounts_window == NULL)
- /* update the account in the GtkListStore */
- if (accounts_window_find_account_in_treemodel(&iter, account))
- gtk_list_store_set(accounts_window->model, &iter,
- COLUMN_ENABLED, GPOINTER_TO_INT(user_data),
-accedit_win_destroy_cb(GtkWidget *w, GdkEvent *event, AccountsWindow *dialog)
- pidgin_accounts_window_hide();
-modify_account_sel(GtkTreeModel *model, GtkTreePath *path,
- GtkTreeIter *iter, gpointer data)
- PurpleAccount *account;
- gtk_tree_model_get(model, iter, COLUMN_DATA, &account, -1);
- pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account);
-modify_account(AccountsWindow *dialog)
- GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
- gtk_tree_selection_selected_foreach(selection, modify_account_sel, dialog);
-delete_account_cb(PurpleAccount *account)
- purple_accounts_delete(account);
-ask_delete_account_sel(GtkTreeModel *model, GtkTreePath *path,
- GtkTreeIter *iter, gpointer data)
- PurpleAccount *account;
- gtk_tree_model_get(model, iter, COLUMN_DATA, &account, -1);
- buf = g_strdup_printf(_("Are you sure you want to delete %s?"),
- purple_account_get_username(account));
- purple_request_close_with_handle(account);
- purple_request_action(account, NULL, buf, NULL,
- PURPLE_DEFAULT_ACTION_NONE,
- purple_request_cpar_from_account(account), account, 2,
- _("Delete"), delete_account_cb, _("Cancel"), NULL);
-ask_delete_account(AccountsWindow *dialog)
- GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
- gtk_tree_selection_selected_foreach(selection, ask_delete_account_sel,
-accedit_win_response_cb(GtkDialog *dialog, guint response, gpointer data) {
- AccountsWindow *window = data;
- pidgin_account_dialog_show(PIDGIN_ADD_ACCOUNT_DIALOG, NULL);
- modify_account(window);
- ask_delete_account(window);
- pidgin_accounts_window_hide();
-enabled_cb(GtkCellRendererToggle *renderer, gchar *path_str,
- AccountsWindow *dialog = (AccountsWindow *)data;
- PurpleAccount *account;
- GtkTreeModel *model = GTK_TREE_MODEL(dialog->model);
- const PurpleSavedStatus *saved_status;
- gtk_tree_model_get_iter_from_string(model, &iter, path_str);
- gtk_tree_model_get(model, &iter,
- COLUMN_ENABLED, &enabled,
- * If we just enabled the account, then set the statuses
- * to the current status.
- saved_status = purple_savedstatus_get_current();
- purple_savedstatus_activate_for_account(saved_status, account);
- purple_account_set_enabled(account, PIDGIN_UI, !enabled);
-add_columns(GtkWidget *treeview, AccountsWindow *dialog)
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- renderer = gtk_cell_renderer_toggle_new();
- g_signal_connect(G_OBJECT(renderer), "toggled",
- G_CALLBACK(enabled_cb), dialog);
- column = gtk_tree_view_column_new_with_attributes(_("Enabled"),
- renderer, "active", COLUMN_ENABLED, NULL);
- gtk_tree_view_column_set_resizable(column, FALSE);
- gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- column = gtk_tree_view_column_new();
- gtk_tree_view_column_set_title(column, _("Username"));
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- renderer = gtk_cell_renderer_pixbuf_new();
- gtk_tree_view_column_pack_start(column, renderer, FALSE);
- gtk_tree_view_column_add_attribute(column, renderer,
- "pixbuf", COLUMN_BUDDYICON);
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, renderer, TRUE);
- gtk_tree_view_column_add_attribute(column, renderer,
- "text", COLUMN_USERNAME);
- dialog->username_col = column;
- column = gtk_tree_view_column_new();
- gtk_tree_view_column_set_title(column, _("Protocol"));
- gtk_tree_view_column_set_resizable(column, FALSE);
- gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- renderer = gtk_cell_renderer_pixbuf_new();
- gtk_tree_view_column_pack_start(column, renderer, FALSE);
- gtk_tree_view_column_add_attribute(column, renderer,
- "pixbuf", COLUMN_ICON);
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, renderer, TRUE);
- gtk_tree_view_column_add_attribute(column, renderer,
- "text", COLUMN_PROTOCOL);
-set_account(GtkListStore *store, GtkTreeIter *iter, PurpleAccount *account, GdkPixbuf *global_buddyicon)
- GdkPixbuf *pixbuf, *buddyicon = NULL;
- PurpleImage *img = NULL;
- PurpleProtocol *protocol = NULL;
- PurpleBuddyIconSpec *icon_spec = NULL;
- pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_MEDIUM);
- if ((pixbuf != NULL) && purple_account_is_disconnected(account))
- gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
- protocol = purple_account_get_protocol(account);
- icon_spec = purple_protocol_get_icon_spec(protocol);
- if (icon_spec != NULL && icon_spec->format != NULL) {
- if (purple_account_get_bool(account, "use-global-buddyicon", TRUE)) {
- if (global_buddyicon != NULL)
- buddyicon = GDK_PIXBUF(g_object_ref(G_OBJECT(global_buddyicon)));
- /* This is for when set_account() is called for a single account */
- path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon");
- if ((path != NULL) && (*path != '\0')) {
- img = purple_image_new_from_file(path, NULL);
- img = purple_buddy_icons_find_account_icon(account);
- purple_buddy_icon_spec_free(icon_spec);
- GdkPixbuf *buddyicon_pixbuf;
- buddyicon_pixbuf = purple_gdk_pixbuf_from_image(img);
- if (buddyicon_pixbuf != NULL) {
- buddyicon = gdk_pixbuf_scale_simple(buddyicon_pixbuf, 22, 22, GDK_INTERP_HYPER);
- g_object_unref(G_OBJECT(buddyicon_pixbuf));
- gtk_list_store_set(store, iter,
- COLUMN_BUDDYICON, buddyicon,
- COLUMN_USERNAME, purple_account_get_username(account),
- COLUMN_ENABLED, purple_account_get_enabled(account, PIDGIN_UI),
- COLUMN_PROTOCOL, purple_account_get_protocol_name(account),
- g_object_unref(G_OBJECT(pixbuf));
- g_object_unref(G_OBJECT(buddyicon));
-add_account_to_liststore(PurpleAccount *account, gpointer user_data) {
- GdkPixbuf *global_buddyicon = user_data;
- if(accounts_window == NULL) {
- gtk_list_store_append(accounts_window->model, &iter);
- set_account(accounts_window->model, &iter, account, global_buddyicon);
-populate_accounts_list(AccountsWindow *dialog) {
- PurpleAccountManager *manager = NULL;
- GdkPixbuf *global_buddyicon = NULL;
- gtk_list_store_clear(dialog->model);
- path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon");
- if(path != NULL && *path != '\0') {
- GdkPixbuf *pixbuf = purple_gdk_pixbuf_new_from_file(path);
- global_buddyicon = gdk_pixbuf_scale_simple(pixbuf, 22, 22,
- g_object_unref(G_OBJECT(pixbuf));
- manager = purple_account_manager_get_default();
- purple_account_manager_foreach(manager, add_account_to_liststore,
- if(global_buddyicon != NULL) {
- g_object_unref(G_OBJECT(global_buddyicon));
-account_selected_cb(GtkTreeSelection *sel, AccountsWindow *dialog)
- gboolean selected = FALSE;
- selected = (gtk_tree_selection_count_selected_rows(sel) > 0);
- gtk_widget_set_sensitive(dialog->modify_button, selected);
- gtk_widget_set_sensitive(dialog->delete_button, selected);
-account_treeview_double_click_cb(GtkTreeView *treeview, GdkEventButton *event, gpointer user_data)
- AccountsWindow *dialog;
- GtkTreeViewColumn *column;
- PurpleAccount *account;
- dialog = (AccountsWindow *)user_data;
- if (event->window != gtk_tree_view_get_bin_window(treeview))
- /* Figure out which node was clicked */
- if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(dialog->treeview), event->x, event->y, &path, &column, NULL, NULL))
- if (column == gtk_tree_view_get_column(treeview, 0)) {
- gtk_tree_path_free(path);
- gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path);
- gtk_tree_path_free(path);
- gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, COLUMN_DATA, &account, -1);
- if ((account != NULL) && (event->button == GDK_BUTTON_PRIMARY) &&
- (event->type == GDK_2BUTTON_PRESS))
- pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account);
-create_accounts_list(AccountsWindow *dialog)
- frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
- /* Create the list model. */
- dialog->model = gtk_list_store_new(NUM_COLUMNS,
- GDK_TYPE_PIXBUF, /* COLUMN_ICON */
- GDK_TYPE_PIXBUF, /* COLUMN_BUDDYICON */
- G_TYPE_STRING, /* COLUMN_USERNAME */
- G_TYPE_BOOLEAN, /* COLUMN_ENABLED */
- G_TYPE_STRING, /* COLUMN_PROTOCOL */
- G_TYPE_POINTER /* COLUMN_DATA */
- /* And now the actual treeview */
- treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
- dialog->treeview = treeview;
- g_object_unref(G_OBJECT(dialog->model));
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
- gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
- g_signal_connect(G_OBJECT(sel), "changed",
- G_CALLBACK(account_selected_cb), dialog);
- /* Handle double-clicking */
- g_signal_connect(G_OBJECT(treeview), "button_press_event",
- G_CALLBACK(account_treeview_double_click_cb), dialog);
- gtk_container_add(GTK_CONTAINER(frame),
- pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1));
- add_columns(treeview, dialog);
- gtk_tree_view_columns_autosize(GTK_TREE_VIEW(treeview));
- populate_accounts_list(dialog);
- gtk_widget_show_all(frame);
-account_modified_cb(PurpleAccount *account, gpointer data) {
- AccountsWindow *window = (AccountsWindow *)data;
- if (!accounts_window_find_account_in_treemodel(&iter, account))
- set_account(window->model, &iter, account, NULL);
-global_buddyicon_changed(const gchar *name, PurplePrefType type,
- gconstpointer value, gpointer window)
- PurpleAccountManager *manager = NULL;
- manager = purple_account_manager_get_default();
- purple_account_manager_foreach(manager, account_modified_cb, window);
-pidgin_accounts_window_show(void)
- AccountsWindow *dialog;
- if (accounts_window != NULL) {
- gtk_window_present(GTK_WINDOW(accounts_window->window));
- accounts_window = dialog = g_new0(AccountsWindow, 1);
- width = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/width");
- height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/height");
- dialog->window = win = pidgin_dialog_new(_("Accounts"), 0, "accounts", TRUE);
- gtk_window_set_default_size(GTK_WINDOW(win), width, height);
- g_signal_connect(win, "delete_event", G_CALLBACK(accedit_win_destroy_cb),
- g_signal_connect(win, "response", G_CALLBACK(accedit_win_response_cb),
- vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
- gtk_box_set_spacing(GTK_BOX(vbox), 12);
- /* Setup the scrolled window that will contain the list of accounts. */
- sw = create_accounts_list(dialog);
- gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
- gtk_dialog_add_button(GTK_DIALOG(win), _("_Add..."), RESPONSE_ADD);
- dialog->modify_button = gtk_dialog_add_button(GTK_DIALOG(win),
- gtk_widget_set_sensitive(dialog->modify_button, FALSE);
- dialog->delete_button = gtk_dialog_add_button(GTK_DIALOG(win),
- gtk_widget_set_sensitive(dialog->delete_button, FALSE);
- gtk_dialog_add_button(GTK_DIALOG(win), _("_Close"), RESPONSE_CLOSE);
- purple_signal_connect(pidgin_accounts_get_handle(), "account-modified",
- G_CALLBACK(account_modified_cb), accounts_window);
- purple_prefs_connect_callback(accounts_window,
- PIDGIN_PREFS_ROOT "/accounts/buddyicon",
- global_buddyicon_changed, accounts_window);
-pidgin_accounts_window_hide(void)
- if (accounts_window == NULL)
- if (accounts_window->window != NULL)
- gtk_widget_destroy(accounts_window->window);
- purple_signals_disconnect_by_handle(accounts_window);
- purple_prefs_disconnect_by_handle(accounts_window);
- g_free(accounts_window);
- accounts_window = NULL;
free_add_user_data(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
@@ -2296,41 +1668,11 @@
purple_signal_register(pidgin_accounts_get_handle(), "account-modified",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
- /* Setup some purple signal handlers. */
- purple_signal_connect(purple_connections_get_handle(), "signed-on",
- pidgin_accounts_get_handle(),
- G_CALLBACK(signed_on_off_cb), NULL);
- purple_signal_connect(purple_connections_get_handle(), "signed-off",
- pidgin_accounts_get_handle(),
- G_CALLBACK(signed_on_off_cb), NULL);
- purple_signal_connect(purple_accounts_get_handle(), "account-added",
- pidgin_accounts_get_handle(),
- G_CALLBACK(add_account_to_liststore), NULL);
- purple_signal_connect(purple_accounts_get_handle(), "account-removed",
- pidgin_accounts_get_handle(),
- G_CALLBACK(account_removed_cb), NULL);
- purple_signal_connect(purple_accounts_get_handle(), "account-disabled",
- pidgin_accounts_get_handle(),
- G_CALLBACK(account_abled_cb), GINT_TO_POINTER(FALSE));
- purple_signal_connect(purple_accounts_get_handle(), "account-enabled",
- pidgin_accounts_get_handle(),
- G_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE));
- g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
pidgin_accounts_uninit(void)
- * TODO: Need to free all the dialogs in here. Could probably create
- * a callback function to use for the free-some-data-function
- * parameter of g_hash_table_new_full, above.
- g_hash_table_destroy(account_pref_wins);
purple_signals_disconnect_by_handle(pidgin_accounts_get_handle());
purple_signals_unregister_by_instance(pidgin_accounts_get_handle());
--- a/pidgin/gtkaccount.h Tue May 17 01:58:55 2022 -0500
+++ b/pidgin/gtkaccount.h Thu May 19 20:32:23 2022 -0500
@@ -39,20 +39,6 @@
- * pidgin_accounts_window_show:
- * Shows the accounts window.
-void pidgin_accounts_window_show(void);
- * pidgin_accounts_window_hide:
- * Hides the accounts window.
-void pidgin_accounts_window_hide(void);
* pidgin_account_dialog_show:
* @type: The type of dialog.
* @account: The associated account, or %NULL for an Add dialog.