pidgin: 9de96edc: Add blist ui-ops to overload the saving ...

darkrain42 at pidgin.im darkrain42 at pidgin.im
Mon Jul 27 02:16:50 EDT 2009


-----------------------------------------------------------------
Revision: 9de96edcea00fc0b41b3668bdd9072738cbf149d
Ancestor: 5e1dede17ba70958e2a909057d864197e0e4ceaf
Author: hanzz at soc.pidgin.im
Date: 2009-07-27T05:20:52
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/9de96edcea00fc0b41b3668bdd9072738cbf149d

Modified files:
        ChangeLog.API libpurple/account.c libpurple/blist.c
        libpurple/blist.h libpurple/privacy.c

ChangeLog: 

Add blist ui-ops to overload the saving of data to blist.xml. Closes #9630.

Patch from Jan "HanzZ" Kaluza with some changes by me so that it's
easier to merge with Sulabh and Eric's SoC projects (mostly so grim
wouldn't yell at me).  Anyway, any bugs introduced by me (darkrain42).

-------------- next part --------------
============================================================
--- ChangeLog.API	57e08d2fc212efd8446f2a1e13bf18091cbaffe1
+++ ChangeLog.API	a84a7848f57afcb793880cc4ae04c719e919dd37
@@ -15,6 +15,9 @@ version 2.6.0 (??/??/2009):
 			* account-destroying
 		* blist-node-added and blist-node-removed signals (see
 		  blist-signals.dox)
+		* Three Blist UI ops used to overload libpurple's built-in saving
+		  of the buddy list to blist.xml. If a UI implements these, it probably
+		  wants to add the buddies itself and not call purple_blist_load.
 		* Jabber plugin signals (see jabber-signals.dox)
 		* purple_account_remove_setting
 		* purple_buddy_destroy
============================================================
--- libpurple/account.c	2715e52a80d216af9cc215046353cc8e244e8ace
+++ libpurple/account.c	ed1447e356c599eaf779b947205a136748e80eb4
@@ -1534,6 +1534,8 @@ purple_account_set_username(PurpleAccoun
 void
 purple_account_set_username(PurpleAccount *account, const char *username)
 {
+	PurpleBlistUiOps *blist_ops;
+
 	g_return_if_fail(account != NULL);
 
 	g_free(account->username);
@@ -1543,7 +1545,9 @@ purple_account_set_username(PurpleAccoun
 
 	/* if the name changes, we should re-write the buddy list
 	 * to disk with the new name */
-	purple_blist_schedule_save();
+	blist_ops = purple_blist_get_ui_ops();
+	if (blist_ops != NULL && blist_ops->save_account != NULL)
+		blist_ops->save_account(account);
 }
 
 void
============================================================
--- libpurple/blist.c	07eedaf4bad461df42b05857d9d3dcea0fc38be1
+++ libpurple/blist.c	2908d2996da394f24d703b0529cbc4b6867cfe9b
@@ -393,14 +393,43 @@ save_cb(gpointer data)
 	return FALSE;
 }
 
-void
-purple_blist_schedule_save()
+static void
+_purple_blist_schedule_save()
 {
 	if (save_timer == 0)
 		save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
 }
 
+static void
+purple_blist_save_account(PurpleAccount *account)
+{
+#if 1
+	_purple_blist_schedule_save();
+#else
+	if (account != NULL) {
+		/* Save the buddies and privacy data for this account */
+	} else {
+		/* Save all buddies and privacy data */
+	}
+#endif
+}
 
+static void
+purple_blist_save_node(PurpleBlistNode *node)
+{
+	_purple_blist_schedule_save();
+}
+
+void purple_blist_schedule_save()
+{
+	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+	/* Save everything */
+	if (ops && ops->save_account)
+		ops->save_account(NULL);
+}
+
+
 /*********************************************************************
  * Reading from disk                                                 *
  *********************************************************************/
@@ -971,7 +1000,8 @@ void purple_blist_rename_buddy(PurpleBud
 	g_free(buddy->name);
 	buddy->name = g_strdup(name);
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode *) buddy);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
@@ -1011,7 +1041,8 @@ void purple_blist_alias_contact(PurpleCo
 		g_free(new_alias); /* could be "\0" */
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) contact);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)contact);
@@ -1056,7 +1087,8 @@ void purple_blist_alias_chat(PurpleChat 
 		g_free(new_alias); /* could be "\0" */
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) chat);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)chat);
@@ -1092,7 +1124,8 @@ void purple_blist_alias_buddy(PurpleBudd
 		g_free(new_alias); /* could be "\0" */
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) buddy);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
@@ -1133,7 +1166,8 @@ void purple_blist_server_alias_buddy(Pur
 		g_free(new_alias); /* could be "\0"; */
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) buddy);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)buddy);
@@ -1235,7 +1269,8 @@ void purple_blist_rename_group(PurpleGro
 	}
 
 	/* Save our changes */
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) source);
 
 	/* Update the UI */
 	if (ops && ops->update)
@@ -1493,8 +1528,6 @@ void purple_blist_add_chat(PurpleChat *c
 		 * reinitialize it */
 		if (ops && ops->new_node)
 			ops->new_node(cnode);
-
-		purple_blist_schedule_save();
 	}
 
 	if (node != NULL) {
@@ -1523,7 +1556,8 @@ void purple_blist_add_chat(PurpleChat *c
 		}
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node(cnode);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode *)cnode);
@@ -1601,8 +1635,6 @@ void purple_blist_add_buddy(PurpleBuddy 
 		if (ops && ops->remove)
 			ops->remove(purplebuddylist, bnode);
 
-		purple_blist_schedule_save();
-
 		if (bnode->parent->parent != (PurpleBlistNode*)g) {
 			struct _purple_hbuddy hb;
 			hb.name = (gchar *)purple_normalize(buddy->account, buddy->name);
@@ -1667,7 +1699,8 @@ void purple_blist_add_buddy(PurpleBuddy 
 
 	purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+		ops->save_node((PurpleBlistNode*) buddy);
 
 	if (ops && ops->update)
 		ops->update(purplebuddylist, (PurpleBlistNode*)buddy);
@@ -1886,7 +1919,8 @@ void purple_blist_add_contact(PurpleCont
 		if (ops && ops->remove)
 			ops->remove(purplebuddylist, cnode);
 
-		purple_blist_schedule_save();
+		if (ops && ops->remove_node)
+			ops->remove_node(cnode);
 	}
 
 	if (node && (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
@@ -1912,7 +1946,13 @@ void purple_blist_add_contact(PurpleCont
 		g->currentsize++;
 	g->totalsize++;
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node)
+	{
+		if (cnode->child)
+			ops->save_node(cnode);
+		for (bnode = cnode->child; bnode; bnode = bnode->next)
+			ops->save_node(bnode);
+	}
 
 	if (ops && ops->update)
 	{
@@ -2012,7 +2052,11 @@ void purple_blist_add_group(PurpleGroup 
 		purplebuddylist->root = gnode;
 	}
 
-	purple_blist_schedule_save();
+	if (ops && ops->save_node) {
+		ops->save_node(gnode);
+		for (node = gnode->child; node; node = node->next)
+			ops->save_node(node);
+	}
 
 	if (ops && ops->update) {
 		ops->update(purplebuddylist, gnode);
@@ -2058,12 +2102,13 @@ void purple_blist_remove_contact(PurpleC
 		if (node->next)
 			node->next->prev = node->prev;
 
-		purple_blist_schedule_save();
-
 		/* Update the UI */
 		if (ops && ops->remove)
 			ops->remove(purplebuddylist, node);
 
+		if (ops && ops->remove_node)
+			ops->remove_node(node);
+
 		purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
 				PURPLE_BLIST_NODE(contact));
 
@@ -2119,8 +2164,6 @@ void purple_blist_remove_buddy(PurpleBud
 		}
 	}
 
-	purple_blist_schedule_save();
-
 	/* Remove this buddy from the buddies hash table */
 	hb.name = (gchar *)purple_normalize(buddy->account, buddy->name);
 	hb.account = buddy->account;
@@ -2134,6 +2177,9 @@ void purple_blist_remove_buddy(PurpleBud
 	if (ops && ops->remove)
 		ops->remove(purplebuddylist, node);
 
+	if (ops && ops->remove_node)
+		ops->remove_node(node);
+
 	/* Signal that the buddy has been removed before freeing the memory for it */
 	purple_signal_emit(purple_blist_get_handle(), "buddy-removed", buddy);
 
@@ -2176,13 +2222,15 @@ void purple_blist_remove_chat(PurpleChat
 		}
 		group->totalsize--;
 
-		purple_blist_schedule_save();
 	}
 
 	/* Update the UI */
 	if (ops && ops->remove)
 		ops->remove(purplebuddylist, node);
 
+	if (ops && ops->remove_node)
+		ops->remove_node(node);
+
 	purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
 			PURPLE_BLIST_NODE(chat));
 
@@ -2217,12 +2265,13 @@ void purple_blist_remove_group(PurpleGro
 	g_hash_table_remove(groups_cache, key);
 	g_free(key);
 
-	purple_blist_schedule_save();
-
 	/* Update the UI */
 	if (ops && ops->remove)
 		ops->remove(purplebuddylist, node);
 
+	if (ops && ops->remove_node)
+		ops->remove_node(node);
+
 	purple_signal_emit(purple_blist_get_handle(), "blist-node-removed",
 			PURPLE_BLIST_NODE(group));
 
@@ -2827,13 +2876,16 @@ void purple_blist_node_remove_setting(Pu
 
 void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key)
 {
+	PurpleBlistUiOps *ops;
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(node->settings != NULL);
 	g_return_if_fail(key != NULL);
 
 	g_hash_table_remove(node->settings, key);
 
-	purple_blist_schedule_save();
+	ops = purple_blist_get_ui_ops();
+	if (ops && ops->save_node)
+		ops->save_node(node);
 }
 
 void
@@ -2863,6 +2915,7 @@ purple_blist_node_set_bool(PurpleBlistNo
 purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data)
 {
 	PurpleValue *value;
+	PurpleBlistUiOps *ops;
 
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(node->settings != NULL);
@@ -2873,7 +2926,9 @@ purple_blist_node_set_bool(PurpleBlistNo
 
 	g_hash_table_replace(node->settings, g_strdup(key), value);
 
-	purple_blist_schedule_save();
+	ops = purple_blist_get_ui_ops();
+	if (ops && ops->save_node)
+		ops->save_node(node);
 }
 
 gboolean
@@ -2899,6 +2954,7 @@ purple_blist_node_set_int(PurpleBlistNod
 purple_blist_node_set_int(PurpleBlistNode* node, const char *key, int data)
 {
 	PurpleValue *value;
+	PurpleBlistUiOps *ops;
 
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(node->settings != NULL);
@@ -2909,7 +2965,9 @@ purple_blist_node_set_int(PurpleBlistNod
 
 	g_hash_table_replace(node->settings, g_strdup(key), value);
 
-	purple_blist_schedule_save();
+	ops = purple_blist_get_ui_ops();
+	if (ops && ops->save_node)
+		ops->save_node(node);
 }
 
 int
@@ -2935,6 +2993,7 @@ purple_blist_node_set_string(PurpleBlist
 purple_blist_node_set_string(PurpleBlistNode* node, const char *key, const char *data)
 {
 	PurpleValue *value;
+	PurpleBlistUiOps *ops;
 
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(node->settings != NULL);
@@ -2945,7 +3004,9 @@ purple_blist_node_set_string(PurpleBlist
 
 	g_hash_table_replace(node->settings, g_strdup(key), value);
 
-	purple_blist_schedule_save();
+	ops = purple_blist_get_ui_ops();
+	if (ops && ops->save_node)
+		ops->save_node(node);
 }
 
 const char *
@@ -2999,7 +3060,31 @@ purple_blist_set_ui_ops(PurpleBlistUiOps
 void
 purple_blist_set_ui_ops(PurpleBlistUiOps *ops)
 {
+	gboolean overrode = FALSE;
 	blist_ui_ops = ops;
+
+	if (!ops)
+		return;
+
+	if (!ops->save_node) {
+		ops->save_node = purple_blist_save_node;
+		overrode = TRUE;
+	}
+	if (!ops->remove_node) {
+		ops->remove_node = purple_blist_save_node;
+		overrode = TRUE;
+	}
+	if (!ops->save_account) {
+		ops->save_account = purple_blist_save_account;
+		overrode = TRUE;
+	}
+
+	if (overrode && (ops->save_node    != purple_blist_save_node ||
+	                 ops->remove_node  != purple_blist_save_node ||
+	                 ops->save_account != purple_blist_save_account)) {
+		purple_debug_warning("blist", "Only some of the blist saving UI ops "
+				"were overridden. This probably is not what you want!\n");
+	}
 }
 
 PurpleBlistUiOps *
============================================================
--- libpurple/blist.h	15ec6aaf213a433927c2461893586c0c579e1112
+++ libpurple/blist.h	c3102fc0dd9d5ef293c42dcf1d6818d77491c1f9
@@ -216,10 +216,49 @@ struct _PurpleBlistUiOps
 							 const char *alias, const char *name);
 	void (*request_add_group)(void);
 
+	/**
+	 * This is called when a node has been modified and should be saved.
+	 *
+	 * Implementation of this UI op is OPTIONAL. If not implemented, it will
+	 * be set to a fallback function that saves data to blist.xml like in
+	 * previous libpurple versions.
+	 *
+	 * @attrib node    The node which has been modified.
+	 *
+	 * @since 2.6.0.
+	 */
+	void (*save_node)(PurpleBlistNode *node);
+
+	/**
+	 * Called when a node is about to be removed from the buddy list.
+	 * The UI op should update the relevant data structures to remove this
+	 * node (for example, removing a buddy from the group this node is in).
+	 *
+	 * Implementation of this UI op is OPTIONAL. If not implemented, it will
+	 * be set to a fallback function that saves data to blist.xml like in
+	 * previous libpurple versions.
+	 *
+	 * @attrib node  The node which has been modified.
+	 * @since 2.6.0.
+	 */
+	void (*remove_node)(PurpleBlistNode *node);
+
+	/**
+	 * Called to save all the data for an account. If the UI sets this,
+	 * the callback must save the privacy and buddy list data for an account.
+	 * If the account is NULL, save the data for all accounts.
+	 *
+	 * Implementation of this UI op is OPTIONAL. If not implemented, it will
+	 * be set to a fallback function that saves data to blist.xml like in
+	 * previous libpurple versions.
+	 *
+	 * @attrib account  The account whose data to save. If NULL, save all data
+	 *                  for all accounts.
+	 * @since 2.6.0.
+	 */
+	void (*save_account)(PurpleAccount *account);
+
 	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
-	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
 };
 
 #ifdef __cplusplus
============================================================
--- libpurple/privacy.c	5e9715a02d5433f53c7de47f703619bc84be82f5
+++ libpurple/privacy.c	d0ea5addf9ad746869966e8b5334c7e3faa54f4b
@@ -35,6 +35,7 @@ purple_privacy_permit_add(PurpleAccount 
 	GSList *l;
 	char *name;
 	PurpleBuddy *buddy;
+	PurpleBlistUiOps *blist_ops;
 
 	g_return_val_if_fail(account != NULL, FALSE);
 	g_return_val_if_fail(who     != NULL, FALSE);
@@ -62,7 +63,9 @@ purple_privacy_permit_add(PurpleAccount 
 	if (privacy_ops != NULL && privacy_ops->permit_added != NULL)
 		privacy_ops->permit_added(account, who);
 
-	purple_blist_schedule_save();
+	blist_ops = purple_blist_get_ui_ops();
+	if (blist_ops != NULL && blist_ops->save_account != NULL)
+		blist_ops->save_account(account);
 
 	/* This lets the UI know a buddy has had its privacy setting changed */
 	buddy = purple_find_buddy(account, name);
@@ -81,6 +84,7 @@ purple_privacy_permit_remove(PurpleAccou
 	const char *name;
 	PurpleBuddy *buddy;
 	char *del;
+	PurpleBlistUiOps *blist_ops;
 
 	g_return_val_if_fail(account != NULL, FALSE);
 	g_return_val_if_fail(who     != NULL, FALSE);
@@ -109,7 +113,9 @@ purple_privacy_permit_remove(PurpleAccou
 	if (privacy_ops != NULL && privacy_ops->permit_removed != NULL)
 		privacy_ops->permit_removed(account, who);
 
-	purple_blist_schedule_save();
+	blist_ops = purple_blist_get_ui_ops();
+	if (blist_ops != NULL && blist_ops->save_account != NULL)
+		blist_ops->save_account(account);
 
 	buddy = purple_find_buddy(account, name);
 	if (buddy != NULL) {
@@ -127,6 +133,7 @@ purple_privacy_deny_add(PurpleAccount *a
 	GSList *l;
 	char *name;
 	PurpleBuddy *buddy;
+	PurpleBlistUiOps *blist_ops;
 
 	g_return_val_if_fail(account != NULL, FALSE);
 	g_return_val_if_fail(who     != NULL, FALSE);
@@ -154,7 +161,9 @@ purple_privacy_deny_add(PurpleAccount *a
 	if (privacy_ops != NULL && privacy_ops->deny_added != NULL)
 		privacy_ops->deny_added(account, who);
 
-	purple_blist_schedule_save();
+	blist_ops = purple_blist_get_ui_ops();
+	if (blist_ops != NULL && blist_ops->save_account != NULL)
+		blist_ops->save_account(account);
 
 	buddy = purple_find_buddy(account, name);
 	if (buddy != NULL) {
@@ -172,6 +181,7 @@ purple_privacy_deny_remove(PurpleAccount
 	const char *normalized;
 	char *name;
 	PurpleBuddy *buddy;
+	PurpleBlistUiOps *blist_ops;
 
 	g_return_val_if_fail(account != NULL, FALSE);
 	g_return_val_if_fail(who     != NULL, FALSE);
@@ -205,8 +215,11 @@ purple_privacy_deny_remove(PurpleAccount
 	}
 
 	g_free(name);
-	purple_blist_schedule_save();
 
+	blist_ops = purple_blist_get_ui_ops();
+	if (blist_ops != NULL && blist_ops->save_account != NULL)
+		blist_ops->save_account(account);
+
 	return TRUE;
 }
 


More information about the Commits mailing list