pidgin/pidginaccountmanager.c

changeset 42028
f3090252de57
parent 41962
f802660eaef2
child 42151
41b9c5be8965
--- a/pidgin/pidginaccountmanager.c	Tue Jan 17 02:27:41 2023 -0600
+++ b/pidgin/pidginaccountmanager.c	Tue Jan 17 02:29:19 2023 -0600
@@ -29,167 +29,33 @@
 #include "gtkaccount.h"
 #include "pidgincore.h"
 #include "pidginaccounteditor.h"
+#include "pidginaccountrow.h"
 
 struct _PidginAccountManager {
 	GtkDialog parent;
 
-	GtkListStore *model;
-	GtkTreeSelection *selection;
-
-	GtkWidget *modify_button;
-	GtkWidget *remove_button;
+	GtkListBox *list_box;
+	GtkWidget *add;
 };
 
 enum {
 	RESPONSE_ADD,
-	RESPONSE_MODIFY,
-	RESPONSE_REMOVE,
-};
-
-enum {
-	COLUMN_ENABLED,
-	COLUMN_AVATAR,
-	COLUMN_USERNAME,
-	COLUMN_PROTOCOL_ICON,
-	COLUMN_PROTOCOL_NAME,
-	COLUMN_ACCOUNT
 };
 
 G_DEFINE_TYPE(PidginAccountManager, pidgin_account_manager, GTK_TYPE_DIALOG)
 
-static void pidgin_account_manager_account_notify_cb(GObject *obj, GParamSpec *pspec, gpointer data);
-
 /******************************************************************************
  * Helpers
  *****************************************************************************/
-static gboolean
-pidgin_account_manager_find_account(PidginAccountManager *manager,
-                                    PurpleAccount *account, GtkTreeIter *iter)
+static GtkWidget *
+pidgin_account_manager_create_widget(gpointer item,
+                                     G_GNUC_UNUSED gpointer data)
 {
-	GtkTreeModel *model = GTK_TREE_MODEL(manager->model);
-
-	if(!gtk_tree_model_get_iter_first(model, iter)) {
-		return FALSE;
-	}
-
-	do {
-		PurpleAccount *current = NULL;
-
-		gtk_tree_model_get(model, iter,
-		                   COLUMN_ACCOUNT, &current,
-		                   -1);
-
-		if(current == account) {
-			g_clear_object(&current);
-
-			return TRUE;
-		}
-
-		g_clear_object(&current);
-	} while(gtk_tree_model_iter_next(model, iter));
-
-	return FALSE;
-}
-
-static PurpleAccount *
-pidgin_account_manager_get_selected_account(PidginAccountManager *manager) {
-	PurpleAccount *account = NULL;
-	GtkTreeIter iter;
-
-	if(gtk_tree_selection_count_selected_rows(manager->selection) == 0) {
+	if(!PURPLE_IS_ACCOUNT(item)) {
 		return NULL;
 	}
 
-	gtk_tree_selection_get_selected(manager->selection, NULL, &iter);
-
-	gtk_tree_model_get(GTK_TREE_MODEL(manager->model), &iter,
-	                   COLUMN_ACCOUNT, &account,
-	                   -1);
-
-	return account;
-}
-
-static void
-pidgin_account_manager_refresh_account(PidginAccountManager *manager,
-                                       PurpleAccount *account,
-                                       GtkTreeIter *iter)
-{
-	PurpleContactInfo *info = NULL;
-	PurpleImage *image = NULL;
-	PurpleProtocol *protocol = NULL;
-	GdkPixbuf *avatar = NULL;
-	const gchar *protocol_icon = NULL, *protocol_name = NULL;
-
-	/* Try to find the avatar for the account. */
-	image = purple_buddy_icons_find_account_icon(account);
-	if(image != NULL) {
-		GdkPixbuf *raw = NULL;
-
-		raw = purple_gdk_pixbuf_from_image(image);
-		g_object_unref(image);
-
-		avatar = gdk_pixbuf_scale_simple(raw, 22, 22, GDK_INTERP_HYPER);
-		g_clear_object(&raw);
-	}
-
-	/* Get the protocol fields. */
-	protocol = purple_account_get_protocol(account);
-	if(PURPLE_IS_PROTOCOL(protocol)) {
-		protocol_name = purple_protocol_get_name(protocol);
-		protocol_icon = purple_protocol_get_icon_name(protocol);
-	} else {
-		protocol_name = _("Unknown");
-	}
-
-	info = PURPLE_CONTACT_INFO(account);
-	gtk_list_store_set(manager->model, iter,
-	                   COLUMN_ENABLED, purple_account_get_enabled(account),
-	                   COLUMN_AVATAR, avatar,
-	                   COLUMN_USERNAME, purple_contact_info_get_username(info),
-	                   COLUMN_PROTOCOL_ICON, protocol_icon,
-	                   COLUMN_PROTOCOL_NAME, protocol_name,
-	                   COLUMN_ACCOUNT, account,
-	                   -1);
-
-	g_clear_object(&avatar);
-}
-
-static void
-pidgin_account_manager_update_account(PidginAccountManager *manager,
-                                      PurpleAccount *account)
-{
-	GtkTreeIter iter;
-
-	if(pidgin_account_manager_find_account(manager, account, &iter)) {
-		pidgin_account_manager_refresh_account(manager, account, &iter);
-	}
-}
-
-static void
-pidgin_account_manager_add_account(PidginAccountManager *manager,
-                                   PurpleAccount *account)
-{
-	GtkTreeIter iter;
-
-	gtk_list_store_append(manager->model, &iter);
-
-	pidgin_account_manager_refresh_account(manager, account, &iter);
-
-	g_signal_connect_object(account, "notify",
-	                        G_CALLBACK(pidgin_account_manager_account_notify_cb),
-	                        manager, 0);
-}
-
-static void
-pidgin_account_manager_populate_helper(PurpleAccount *account, gpointer data) {
-	pidgin_account_manager_add_account(PIDGIN_ACCOUNT_MANAGER(data), account);
-}
-
-static void
-pidgin_account_manager_populate(PidginAccountManager *manager) {
-	purple_account_manager_foreach(purple_account_manager_get_default(),
-	                               pidgin_account_manager_populate_helper,
-	                               manager);
+	return pidgin_account_row_new(PURPLE_ACCOUNT(item));
 }
 
 static void
@@ -200,51 +66,22 @@
 	gtk_window_present_with_time(GTK_WINDOW(editor), GDK_CURRENT_TIME);
 }
 
-static void
-pidgin_account_manager_edit_selected_account(PidginAccountManager *manager) {
-	PurpleAccount *account = NULL;
-	GtkWidget *editor = NULL;
-
-	account = pidgin_account_manager_get_selected_account(manager);
-
-	editor = pidgin_account_editor_new(account);
-	gtk_window_set_transient_for(GTK_WINDOW(editor),
-	                             GTK_WINDOW(manager));
-	gtk_window_present_with_time(GTK_WINDOW(editor), GDK_CURRENT_TIME);
-
-	g_clear_object(&account);
-}
-
-static void
-pidgin_account_manager_remove_selected_account(PidginAccountManager *manager) {
-	PurpleAccount *account = NULL;
-	PurpleNotificationManager *notification_manager = NULL;
-
-	account = pidgin_account_manager_get_selected_account(manager);
-
-	/* Remove all notifications including connection errors for the account. */
-	notification_manager = purple_notification_manager_get_default();
-	purple_notification_manager_remove_with_account(notification_manager,
-	                                                account, TRUE);
-
-	/* Delete the account. */
-	purple_accounts_delete(account);
-
-	g_clear_object(&account);
-}
-
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
+
 static void
-pidgin_account_manager_account_notify_cb(GObject *obj,
-                                         G_GNUC_UNUSED GParamSpec *pspec,
-                                         gpointer data)
+pidgin_account_manager_refresh_add_cb(GListModel *list,
+                                      G_GNUC_UNUSED guint position,
+                                      G_GNUC_UNUSED guint removed,
+                                      G_GNUC_UNUSED guint added,
+                                      gpointer data)
 {
-	PidginAccountManager *manager = PIDGIN_ACCOUNT_MANAGER(data);
-	PurpleAccount *account = PURPLE_ACCOUNT(obj);
+	PidginAccountManager *manager = data;
 
-	pidgin_account_manager_update_account(manager, account);
+	/* If there are no accounts, the placeholder is shown, which includes an
+	 * Add button. So hide the one in the button box if that's the case. */
+	gtk_widget_set_visible(manager->add, g_list_model_get_n_items(list) != 0);
 }
 
 static void
@@ -257,12 +94,6 @@
 		case RESPONSE_ADD:
 			pidgin_account_manager_create_account(manager);
 			break;
-		case RESPONSE_MODIFY:
-			pidgin_account_manager_edit_selected_account(manager);
-			break;
-		case RESPONSE_REMOVE:
-			pidgin_account_manager_remove_selected_account(manager);
-			break;
 		case GTK_RESPONSE_CLOSE:
 		case GTK_RESPONSE_DELETE_EVENT:
 			gtk_window_destroy(GTK_WINDOW(dialog));
@@ -273,100 +104,16 @@
 }
 
 static void
-pidgin_account_manager_selection_changed_cb(GtkTreeSelection *selection,
-                                            gpointer data)
-{
-	PidginAccountManager *manager = data;
-	gboolean sensitive = TRUE;
-
-	if(gtk_tree_selection_count_selected_rows(selection) == 0) {
-		sensitive = FALSE;
-	}
-
-	gtk_widget_set_sensitive(manager->modify_button, sensitive);
-	gtk_widget_set_sensitive(manager->remove_button, sensitive);
-}
-
-static void
-pidgin_account_manager_row_activated_cb(G_GNUC_UNUSED GtkTreeView *tree_view,
-                                        GtkTreePath *path,
-                                        G_GNUC_UNUSED GtkTreeViewColumn *column,
-                                        gpointer data)
+pidgin_account_manager_row_activated_cb(G_GNUC_UNUSED GtkListBox *box,
+                                        GtkListBoxRow *row,
+                                        G_GNUC_UNUSED gpointer data)
 {
-	PidginAccountManager *manager = data;
-	GtkTreeIter iter;
-
-	if(gtk_tree_model_get_iter(GTK_TREE_MODEL(manager->model), &iter, path)) {
-		GtkWidget *editor = NULL;
-		PurpleAccount *account = NULL;
-
-		gtk_tree_model_get(GTK_TREE_MODEL(manager->model), &iter,
-		                   COLUMN_ACCOUNT, &account,
-		                   -1);
-
-		editor = pidgin_account_editor_new(account);
-		gtk_widget_show(editor);
-
-		g_clear_object(&account);
-	}
-}
-
-static void
-pidgin_account_manager_enable_toggled_cb(G_GNUC_UNUSED GtkCellRendererToggle *renderer,
-                                         gchar *path, gpointer data)
-{
-	PidginAccountManager *manager = data;
-	GtkTreeModel *model = GTK_TREE_MODEL(manager->model);
-	GtkTreeIter iter;
+	GtkWidget *editor = NULL;
+	PurpleAccount *account = NULL;
 
-	if(gtk_tree_model_get_iter_from_string(model, &iter, path)) {
-		PurpleAccount *account = NULL;
-		gboolean enabled = FALSE;
-
-		/* The value of enabled in the model is the old value, so if enabled
-		 * is currently set to TRUE, we are disabling the account and vice
-		 * versa.
-		 */
-		gtk_tree_model_get(model, &iter,
-		                   COLUMN_ENABLED, &enabled,
-		                   COLUMN_ACCOUNT, &account,
-		                   -1);
-
-		/* The account was just enabled, so set its status. */
-		if(!enabled) {
-			PurpleSavedStatus *status = purple_savedstatus_get_current();
-			purple_savedstatus_activate_for_account(status, account);
-		}
-
-		purple_account_set_enabled(account, !enabled);
-
-		/* We don't update the model here, as it's updated via the notify
-		 * signal.
-		 */
-	}
-}
-
-static void
-pidgin_account_manager_account_added_cb(G_GNUC_UNUSED PurpleAccountManager *purple_manager,
-                                        PurpleAccount *account,
-                                        gpointer data)
-{
-	PidginAccountManager *manager = data;
-
-	pidgin_account_manager_add_account(manager, account);
-}
-
-static void
-pidgin_account_manager_account_removed_cb(G_GNUC_UNUSED PurpleAccountManager *purple_manager,
-                                          PurpleAccount *account,
-                                          gpointer data)
-{
-	PidginAccountManager *manager = data;
-	GtkTreeIter iter;
-
-	if(pidgin_account_manager_find_account(manager, account, &iter)) {
-		gtk_list_store_remove(manager->model, &iter);
-	}
+	account = pidgin_account_row_get_account(PIDGIN_ACCOUNT_ROW(row));
+	editor = pidgin_account_editor_new(account);
+	gtk_widget_show(editor);
 }
 
 /******************************************************************************
@@ -374,19 +121,17 @@
  *****************************************************************************/
 static void
 pidgin_account_manager_init(PidginAccountManager *manager) {
-	PurpleAccountManager *purple_manager = NULL;
+	GListModel *purple_manager = NULL;
 
 	gtk_widget_init_template(GTK_WIDGET(manager));
 
-	pidgin_account_manager_populate(manager);
-
-	purple_manager = purple_account_manager_get_default();
-	g_signal_connect_object(purple_manager, "added",
-	                        G_CALLBACK(pidgin_account_manager_account_added_cb),
+	purple_manager = purple_account_manager_get_default_as_model();
+	gtk_list_box_bind_model(manager->list_box, purple_manager,
+	                        pidgin_account_manager_create_widget, NULL, NULL);
+	g_signal_connect_object(purple_manager, "items-changed",
+	                        G_CALLBACK(pidgin_account_manager_refresh_add_cb),
 	                        manager, 0);
-	g_signal_connect_object(purple_manager, "removed",
-	                        G_CALLBACK(pidgin_account_manager_account_removed_cb),
-	                        manager, 0);
+	pidgin_account_manager_refresh_add_cb(purple_manager, 0, 0, 0, manager);
 }
 
 static void
@@ -399,23 +144,16 @@
 	);
 
 	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
-	                                     model);
-	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
-	                                     selection);
-
+	                                     list_box);
 	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
-	                                     modify_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
-	                                     remove_button);
+	                                     add);
 
 	gtk_widget_class_bind_template_callback(widget_class,
-	                                        pidgin_account_manager_enable_toggled_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_account_manager_response_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_account_manager_row_activated_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
-	                                        pidgin_account_manager_selection_changed_cb);
+	                                        pidgin_account_manager_create_account);
 }
 
 /******************************************************************************

mercurial