im.pidgin.gobjectification: 8e2491d9c32f26d30461706427ec812d39cfcf5d

sadrul at pidgin.im sadrul at pidgin.im
Thu Feb 28 03:26:27 EST 2008


-----------------------------------------------------------------
Revision: 8e2491d9c32f26d30461706427ec812d39cfcf5d
Ancestor: f6f3d8091b777753fff033e4cafb622087632fe3
Author: sadrul at pidgin.im
Date: 2008-02-28T08:27:10
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/8e2491d9c32f26d30461706427ec812d39cfcf5d

Modified files:
        libpurple/account.c libpurple/account.h pidgin/Makefile.am
        pidgin/gtkaccount.c pidgin/gtkutils.c

ChangeLog: 

Introduce PurpleAccountManager, which manages the PurpleAccount's. It also
emits the account-added and account-removed signals.
purple_accounts_add, _remove, _reorder just redirects the calls to the
corresponding purple_account_manager_ functions. Considering the account-manager
is a singleton, keeping the short-named functions for convenience reasons
sounds good to me, for now.

Updated pidgin to work with the changed signals (account-added and -removed).

grim, seanegan: The change is miniscule, considering all the more changes that
are still needed. But is this going somewhere towards your envisioned ways, or is
this headed completely in the opposite direction, or in no direction at all?
(Feel free to correct/disapprove the mistakes, without any fear of hurting my
 feelings ;) )

-------------- next part --------------
============================================================
--- libpurple/account.c	4d59135382cc3ef5ce38072eb7f30c26c1e349c2
+++ libpurple/account.c	56425f88bec9c12cbf0c0301bbcf3155a2723230
@@ -28,6 +28,7 @@
 #include "core.h"
 #include "dbus-maybe.h"
 #include "debug.h"
+#include "marshallers.h"
 #include "network.h"
 #include "notify.h"
 #include "pounce.h"
@@ -41,10 +42,10 @@
 #include "util.h"
 #include "xmlnode.h"
 
-typedef struct
+struct _PurpleAccountPrivate
 {
 	PurpleConnectionErrorInfo *current_error;
-} PurpleAccountPrivate;
+};
 
 #define PURPLE_ACCOUNT_GET_PRIVATE(account) \
 	((PurpleAccountPrivate *) (account->priv))
@@ -79,7 +80,6 @@ static PurpleAccountUiOps *account_ui_op
 
 static PurpleAccountUiOps *account_ui_ops = NULL;
 
-static GList   *accounts = NULL;
 static guint    save_timer = 0;
 static gboolean accounts_loaded = FALSE;
 
@@ -915,6 +915,46 @@ delete_setting(void *data)
 	g_free(setting);
 }
 
+/****************
+ * Purple Account
+ ****************/
+static void purple_account_class_init(PurpleAccountClass *klass)
+{
+#warning TODO: create signals and properties
+}
+
+static void purple_account_init(PurpleAccount *account)
+{
+#warning TODO: Move the initializations from _account_new to here
+}
+
+static GType purple_account_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(PurpleAccountClass),
+			NULL,
+			NULL,
+			(GClassInitFunc)purple_account_class_init,
+			NULL,
+			NULL,
+			sizeof(PurpleAccount),
+			0,
+			(GInstanceInitFunc)purple_account_init,
+			NULL,
+		};
+
+		type = g_type_register_static(G_TYPE_OBJECT,
+				"PurpleAccount",
+				&info, 0);
+	}
+
+	return type;
+}
+
+
 PurpleAccount *
 purple_account_new(const char *username, const char *protocol_id)
 {
@@ -2420,14 +2460,9 @@ purple_accounts_add(PurpleAccount *accou
 {
 	g_return_if_fail(account != NULL);
 
-	if (g_list_find(accounts, account) != NULL)
-		return;
+	purple_account_manager_add_account(purple_account_manager_get(), account);
 
-	accounts = g_list_append(accounts, account);
-
 	schedule_accounts_save();
-
-	purple_signal_emit(purple_accounts_get_handle(), "account-added", account);
 }
 
 void
@@ -2435,16 +2470,16 @@ purple_accounts_remove(PurpleAccount *ac
 {
 	g_return_if_fail(account != NULL);
 
-	accounts = g_list_remove(accounts, account);
+	purple_account_manager_remove_account(purple_account_manager_get(), account);
 
 	schedule_accounts_save();
 
+#warning TODO: This should be moved to the account destructor
 	/* Clearing the error ensures that account-error-changed is emitted,
 	 * which is the end of the guarantee that the the error's pointer is
 	 * valid.
 	 */
 	purple_account_clear_current_error(account);
-	purple_signal_emit(purple_accounts_get_handle(), "account-removed", account);
 }
 
 void
@@ -2520,39 +2555,14 @@ purple_accounts_reorder(PurpleAccount *a
 void
 purple_accounts_reorder(PurpleAccount *account, gint new_index)
 {
-	gint index;
-	GList *l;
-
-	g_return_if_fail(account != NULL);
-	g_return_if_fail(new_index <= g_list_length(accounts));
-
-	index = g_list_index(accounts, account);
-
-	if (index == -1) {
-		purple_debug_error("account",
-				   "Unregistered account (%s) discovered during reorder!\n",
-				   purple_account_get_username(account));
-		return;
-	}
-
-	l = g_list_nth(accounts, index);
-
-	if (new_index > index)
-		new_index--;
-
-	/* Remove the old one. */
-	accounts = g_list_delete_link(accounts, l);
-
-	/* Insert it where it should go. */
-	accounts = g_list_insert(accounts, account, new_index);
-
-	schedule_accounts_save();
+	purple_account_manager_reorder_account(purple_account_manager_get(),
+			account, new_index);
 }
 
 GList *
 purple_accounts_get_all(void)
 {
-	return accounts;
+	return purple_account_manager_get_all_accounts(purple_account_manager_get());
 }
 
 GList *
@@ -2675,14 +2685,6 @@ purple_accounts_init(void)
 										PURPLE_SUBTYPE_ACCOUNT),
 						 purple_value_new(PURPLE_TYPE_STRING));
 
-	purple_signal_register(handle, "account-added",
-						 purple_marshal_VOID__POINTER, NULL, 1,
-						 purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
-	purple_signal_register(handle, "account-removed",
-						 purple_marshal_VOID__POINTER, NULL, 1,
-						 purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT));
-
 	purple_signal_register(handle, "account-status-changed",
 						 purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
 						 purple_value_new(PURPLE_TYPE_SUBTYPE,
@@ -2748,3 +2750,145 @@ purple_accounts_uninit(void)
 	purple_signals_disconnect_by_handle(handle);
 	purple_signals_unregister_by_instance(handle);
 }
+
+/******************************************************************************
+ * PurpleAccountManager API
+ *****************************************************************************/
+enum
+{
+	ACCOUNT_ADDED,
+	ACCOUNT_REMOVED,
+	ACCOUNT_MANAGER_LAST_SIGNAL
+};
+static int account_manager_signals[ACCOUNT_MANAGER_LAST_SIGNAL];
+
+struct _PurpleAccountManagerPrivate
+{
+	GList *accounts;
+};
+
+#define PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerPrivate))
+
+static void
+purple_account_manager_class_init(PurpleAccountManagerClass *klass)
+{
+	account_manager_signals[ACCOUNT_ADDED] =
+		g_signal_new("account-added",
+				G_OBJECT_CLASS_TYPE(klass),
+				G_SIGNAL_RUN_LAST,
+				0, NULL, NULL,
+#warning FIXME: Change this to __OBJECT when PurpleAccount is a GObject
+				purple_smarshal_VOID__POINTER,
+				G_TYPE_NONE,
+				1, G_TYPE_POINTER);//PURPLE_TYPE_ACCOUNT);
+
+	account_manager_signals[ACCOUNT_REMOVED] =
+		g_signal_new("account-removed",
+				G_OBJECT_CLASS_TYPE(klass),
+				G_SIGNAL_RUN_LAST,
+				0, NULL, NULL,
+#warning FIXME: Change this to __OBJECT when PurpleAccount is a GObject
+				purple_smarshal_VOID__POINTER,
+				G_TYPE_NONE,
+				1, G_TYPE_POINTER);//PURPLE_TYPE_ACCOUNT);
+
+	g_type_class_add_private(klass, sizeof(PurpleAccountManagerPrivate));
+}
+
+static void
+purple_account_manager_init(PurpleAccountManager *manager)
+{
+	manager->priv = PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(manager);
+	manager->priv->accounts = NULL;
+}
+
+GType purple_account_manager_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(PurpleAccountManagerClass),
+			NULL,
+			NULL,
+			(GClassInitFunc)purple_account_manager_class_init,
+			NULL,
+			NULL,
+			sizeof(PurpleAccountManager),
+			0,
+			(GInstanceInitFunc)purple_account_manager_init,
+			NULL,
+		};
+
+		type = g_type_register_static(G_TYPE_OBJECT,
+				"PurpleAccountManager",
+				&info, 0);
+	}
+
+	return type;
+}
+
+PurpleAccountManager *purple_account_manager_get(void)
+{
+	static PurpleAccountManager *manager = NULL;
+	if (manager == NULL)
+		manager = g_object_new(PURPLE_TYPE_ACCOUNT_MANAGER, NULL);
+	return manager;
+}
+
+void purple_account_manager_add_account(PurpleAccountManager *manager, PurpleAccount *account)
+{
+	if (g_list_find(manager->priv->accounts, account))
+		return;
+
+	manager->priv->accounts = g_list_append(manager->priv->accounts, account);
+	g_signal_emit(manager, account_manager_signals[ACCOUNT_ADDED], 0, account);
+}
+
+void purple_account_manager_remove_account(PurpleAccountManager *manager, PurpleAccount *account)
+{
+	if (!g_list_find(manager->priv->accounts, account))
+		return;
+
+	manager->priv->accounts = g_list_remove(manager->priv->accounts, account);
+	g_signal_emit(manager, account_manager_signals[ACCOUNT_REMOVED], 0, account);
+}
+
+void purple_account_manager_reorder_account(PurpleAccountManager *manager, PurpleAccount *account, int new_index)
+{
+	gint index;
+	GList *l;
+	GList *accounts = manager->priv->accounts;
+
+	g_return_if_fail(account != NULL);
+	g_return_if_fail(new_index <= g_list_length(accounts));
+
+	index = g_list_index(accounts, account);
+
+	if (index == -1) {
+		purple_debug_error("account",
+				   "Unregistered account (%s) discovered during reorder!\n",
+				   purple_account_get_username(account));
+		return;
+	}
+
+	l = g_list_nth(accounts, index);
+
+	if (new_index > index)
+		new_index--;
+
+	/* Remove the old one. */
+	accounts = g_list_delete_link(accounts, l);
+
+	/* Insert it where it should go. */
+	accounts = g_list_insert(accounts, account, new_index);
+	manager->priv->accounts = accounts;
+
+	schedule_accounts_save();
+}
+
+GList *purple_account_manager_get_all_accounts(PurpleAccountManager *manager)
+{
+	return manager->priv->accounts;
+}
+
============================================================
--- libpurple/account.h	ecb127afd83b617baea333eabe7ae5c0c7787a2d
+++ libpurple/account.h	c88f0da9d8663714a5a5aa5f4d41320667dbf607
@@ -27,12 +27,21 @@
 #ifndef _PURPLE_ACCOUNT_H_
 #define _PURPLE_ACCOUNT_H_
 
-#include <glib-object.h>
 #include <glib.h>
 #include <glib-object.h>
 
+#define PURPLE_TYPE_ACCOUNT				(purple_account_get_gtype())
+#define PURPLE_ACCOUNT(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_ACCOUNT, PurpleAccount))
+#define PURPLE_ACCOUNT_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_ACCOUNT, PurpleAccountClass))
+#define PURPLE_IS_ACCOUNT(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_ACCOUNT))
+#define PURPLE_IS_ACCOUNT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_ACCOUNT))
+#define PURPLE_ACCOUNT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_ACCOUNT, PurpleAccountClass))
+
+typedef struct _PurpleAccount			PurpleAccount;
+typedef struct _PurpleAccountPrivate		PurpleAccountPrivate;
+typedef struct _PurpleAccountClass		PurpleAccountClass;
+
 typedef struct _PurpleAccountUiOps PurpleAccountUiOps;
-typedef struct _PurpleAccount      PurpleAccount;
 
 typedef gboolean (*PurpleFilterAccountFunc)(PurpleAccount *account);
 typedef void (*PurpleAccountRequestAuthorizationCb)(void *);
@@ -144,6 +153,12 @@ struct _PurpleAccount
 	gpointer priv;              /**< Pointer to opaque private data. */
 };
 
+struct _PurpleAccountClass
+{
+	GObjectClass parent;
+	void (*_purple_reserved[4])(void);
+};
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -1036,6 +1051,46 @@ void purple_accounts_uninit(void);
 
 /*@}*/
 
+/**************************************************************************/
+/** @name Account Manager */
+/**************************************************************************/
+/*@{*/
+
+#define PURPLE_TYPE_ACCOUNT_MANAGER				(purple_account_manager_get_gtype())
+#define PURPLE_ACCOUNT_MANAGER(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManager))
+#define PURPLE_ACCOUNT_MANAGER_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerClass))
+#define PURPLE_IS_ACCOUNT_MANAGER(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_ACCOUNT_MANAGER))
+#define PURPLE_IS_ACCOUNT_MANAGER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_ACCOUNT_MANAGER))
+#define PURPLE_ACCOUNT_MANAGER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerClass))
+
+typedef struct _PurpleAccountManager          PurpleAccountManager;
+typedef struct _PurpleAccountManagerPrivate   PurpleAccountManagerPrivate;
+typedef struct _PurpleAccountManagerClass     PurpleAccountManagerClass;
+
+struct _PurpleAccountManager
+{
+	GObject gparent;
+
+	PurpleAccountManagerPrivate *priv;
+
+	void (*_purple_reserved[4])(void);
+};
+
+struct _PurpleAccountManagerClass
+{
+	GObjectClass gparent;
+	void (*_purple_reserved[4])(void);
+};
+
+GType purple_account_manager_get_gtype(void);
+PurpleAccountManager *purple_account_manager_get(void);
+
+void purple_account_manager_add_account(PurpleAccountManager *manager, PurpleAccount *account);
+void purple_account_manager_remove_account(PurpleAccountManager *manager, PurpleAccount *account);
+void purple_account_manager_reorder_account(PurpleAccountManager *manager, PurpleAccount *account, int new_index);
+GList *purple_account_manager_get_all_accounts(PurpleAccountManager *manager);
+/*@}*/
+
 #ifdef __cplusplus
 }
 #endif
============================================================
--- pidgin/Makefile.am	510e3537b50a6f6f3da3cb4cc110d44d3e183beb
+++ pidgin/Makefile.am	90edc84675d8fceadfc7ddaef8292c1a36b5d068
@@ -68,7 +68,7 @@ pkgconfig_DATA = pidgin.pc
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = pidgin.pc
 
-SUBDIRS = pixmaps plugins
+SUBDIRS = plugins
 
 bin_PROGRAMS = pidgin
 
============================================================
--- pidgin/gtkaccount.c	eab593e665e6425c44421c59170ecfbc811cdcfb
+++ pidgin/gtkaccount.c	6c6792c8a538737448ed8c357aa90a7605dd9793
@@ -141,7 +141,7 @@ static GHashTable *account_pref_wins;
 static AccountsWindow *accounts_window = NULL;
 static GHashTable *account_pref_wins;
 
-static void add_account_to_liststore(PurpleAccount *account, gpointer user_data);
+static void add_account_to_liststore(PurpleAccountManager *manager, PurpleAccount *account, gpointer user_data);
 static void set_account(GtkListStore *store, GtkTreeIter *iter,
 						  PurpleAccount *account, GdkPixbuf *global_buddyicon);
 
@@ -1581,7 +1581,7 @@ static void
 }
 
 static void
-account_removed_cb(PurpleAccount *account, gpointer user_data)
+account_removed_cb(PurpleAccountManager *manager, PurpleAccount *account, gpointer user_data)
 {
 	AccountPrefsDialog *dialog;
 	GtkTreeIter iter;
@@ -2008,7 +2008,7 @@ static void
 }
 
 static void
-add_account_to_liststore(PurpleAccount *account, gpointer user_data)
+add_account_to_liststore(PurpleAccountManager *manager, PurpleAccount *account, gpointer user_data)
 {
 	GtkTreeIter iter;
 	GdkPixbuf *global_buddyicon = user_data;
@@ -2042,7 +2042,7 @@ populate_accounts_list(AccountsWindow *d
 
 	for (l = purple_accounts_get_all(); l != NULL; l = l->next) {
 		ret = TRUE;
-		add_account_to_liststore((PurpleAccount *)l->data, global_buddyicon);
+		add_account_to_liststore(NULL, (PurpleAccount *)l->data, global_buddyicon);
 	}
 
 	if (global_buddyicon != NULL)
@@ -2569,12 +2569,20 @@ pidgin_account_init(void)
 	purple_signal_connect(purple_connections_get_handle(), "signed-off",
 						pidgin_account_get_handle(),
 						PURPLE_CALLBACK(signed_on_off_cb), NULL);
+#if 0
 	purple_signal_connect(purple_accounts_get_handle(), "account-added",
 						pidgin_account_get_handle(),
 						PURPLE_CALLBACK(add_account_to_liststore), NULL);
 	purple_signal_connect(purple_accounts_get_handle(), "account-removed",
 						pidgin_account_get_handle(),
 						PURPLE_CALLBACK(account_removed_cb), NULL);
+#else
+	g_signal_connect(purple_account_manager_get(), "account-added",
+			G_CALLBACK(add_account_to_liststore), NULL);
+	g_signal_connect(purple_account_manager_get(), "account-removed",
+			G_CALLBACK(account_removed_cb), NULL);
+#endif
+
 	purple_signal_connect(purple_accounts_get_handle(), "account-disabled",
 						pidgin_account_get_handle(),
 						PURPLE_CALLBACK(account_abled_cb), GINT_TO_POINTER(FALSE));
============================================================
--- pidgin/gtkutils.c	f97856e347a3079e0e816589d6bd3e1827caeb82
+++ pidgin/gtkutils.c	a94ee2e5911c1b7477191533988f780a1ad6c32b
@@ -841,7 +841,7 @@ static void
 }
 
 static void
-account_menu_added_removed_cb(PurpleAccount *account, GtkWidget *optmenu)
+account_menu_added_removed_cb(PurpleAccountManager *manager, PurpleAccount *account, GtkWidget *optmenu)
 {
 	regenerate_account_menu(optmenu);
 }
@@ -882,18 +882,32 @@ pidgin_account_option_menu_new(PurpleAcc
 	purple_signal_connect(purple_connections_get_handle(), "signed-off",
 						optmenu, PURPLE_CALLBACK(account_menu_sign_on_off_cb),
 						optmenu);
+#if 0
 	purple_signal_connect(purple_accounts_get_handle(), "account-added",
 						optmenu, PURPLE_CALLBACK(account_menu_added_removed_cb),
 						optmenu);
 	purple_signal_connect(purple_accounts_get_handle(), "account-removed",
 						optmenu, PURPLE_CALLBACK(account_menu_added_removed_cb),
 						optmenu);
+#else
+	g_signal_connect(purple_account_manager_get(), "account-added",
+			G_CALLBACK(account_menu_added_removed_cb), optmenu);
+	g_signal_connect(purple_account_manager_get(), "account-removed",
+			G_CALLBACK(account_menu_added_removed_cb), optmenu);
+#endif
 
 	/* Set some data. */
 	g_object_set_data(G_OBJECT(optmenu), "user_data", user_data);
 	g_object_set_data(G_OBJECT(optmenu), "show_all", GINT_TO_POINTER(show_all));
 	g_object_set_data(G_OBJECT(optmenu), "filter_func", filter_func);
 
+	void disconnect(gpointer optmenu)
+	{
+		g_signal_handlers_disconnect_matched(purple_account_manager_get(),
+				G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, optmenu);
+	}
+	g_signal_connect(G_OBJECT(optmenu), "destroy", G_CALLBACK(disconnect), NULL);
+
 	return optmenu;
 }
 
@@ -2141,10 +2155,12 @@ screenname_autocomplete_destroyed_cb(Gtk
 {
 	g_free(data);
 	purple_signals_disconnect_by_handle(widget);
+	g_signal_handlers_disconnect_matched(purple_account_manager_get(),
+			G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data);
 }
 
 static void
-repopulate_autocomplete(gpointer something, gpointer data)
+repopulate_autocomplete(PurpleAccountManager *manager, gpointer something, gpointer data)
 {
 	add_completion_list(data);
 }
@@ -2223,6 +2239,7 @@ pidgin_setup_screenname_autocomplete_wit
 
 #endif /* !NEW_STYLE_COMPLETION */
 
+#if 0
 	purple_signal_connect(purple_connections_get_handle(), "signed-on", entry,
 						PURPLE_CALLBACK(repopulate_autocomplete), data);
 	purple_signal_connect(purple_connections_get_handle(), "signed-off", entry,
@@ -2232,6 +2249,13 @@ pidgin_setup_screenname_autocomplete_wit
 						PURPLE_CALLBACK(repopulate_autocomplete), data);
 	purple_signal_connect(purple_accounts_get_handle(), "account-removed", entry,
 						PURPLE_CALLBACK(repopulate_autocomplete), data);
+#else
+#warning TODO: The autocomplete needs to be repopulated on sign-on/off too.
+	g_signal_connect(purple_account_manager_get(), "account-added",
+			G_CALLBACK(repopulate_autocomplete), data);
+	g_signal_connect(purple_account_manager_get(), "account-removed",
+			G_CALLBACK(repopulate_autocomplete), data);
+#endif
 
 	g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(screenname_autocomplete_destroyed_cb), data);
 }


More information about the Commits mailing list