gobjectification: b6473078: Fixed group adding
aluink at soc.pidgin.im
aluink at soc.pidgin.im
Wed Jul 15 20:55:30 EDT 2009
-----------------------------------------------------------------
Revision: b64730787353d3c8678ee066953f1ab16e58cc35
Ancestor: 2ef380ad3a75f214245ca5e1a34e7fc3d4e23914
Author: aluink at soc.pidgin.im
Date: 2009-07-13T01:47:51
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/b64730787353d3c8678ee066953f1ab16e58cc35
Modified files:
libpurple/blist-node.c libpurple/blist-node.h
libpurple/blist.c libpurple/blist.h libpurple/contact.c
libpurple/contact.h libpurple/group.c libpurple/group.h
ChangeLog:
Fixed group adding
-------------- next part --------------
============================================================
--- libpurple/blist-node.c 284f162c202c47dce41901211e5a7148ea6382bc
+++ libpurple/blist-node.c da7c3d2a7189adb0e489558fff95cd99ee5c86ed
@@ -430,18 +430,50 @@ purple_blist_node_get_extended_menu(Purp
return menu;
}
-static void
-purple_blist_node_add_node(PurpleBlistNode *parent, PurpleBlistNode *child)
+gboolean
+purple_blist_node_contains(PurpleBlistNode *parent, PurpleBlistNode *node)
{
+ return node->parent == parent;
}
-static void
-purple_blist_node_remove_node(PurpleBlistNode *group, PurpleBlistNode *child)
+void
+purple_blist_node_add_child(PurpleBlistNode *parent, PurpleBlistNode *child)
{
- PurpleBlistNodeClass *gklass = PURPLE_GET_BLIST_NODE_CLASS(group);
- PurpleBlistNode *contact = purple_blist_node_get_parent(child);
- PurpleBlistNodeClass *cklass = PURPLE_GET_BLIST_NODE_CLASS(contact);
+ if (parent->child)
+ parent->child->prev = child;
+ child->prev = NULL;
+ child->next = parent->child;
+ parent->child = child;
+ child->parent = parent;
+}
+void
+purple_blist_node_add_sibling_before(PurpleBlistNode *child, PurpleBlistNode *location)
+{
+ g_return_if_fail(location);
+ g_return_if_fail(child);
+ child->next = location;
+ child->prev = location->prev;
+ location->prev->next = child;
+ location->prev = child;
+}
+
+void
+purple_blist_node_add_sibling_after(PurpleBlistNode *child, PurpleBlistNode *location)
+{
+ g_return_if_fail(child);
+ g_return_if_fail(location);
+ if (location->next)
+ location->next->prev = child;
+ child->next = location->next;
+ child->prev = location;
+ child->parent = location->parent;
+ location->next = child;
+}
+
+void
+purple_blist_node_remove(PurpleBlistNode *child)
+{
/* Remove the node from its parent */
if (child->prev)
child->prev->next = child->next;
@@ -451,10 +483,16 @@ purple_blist_node_remove_node(PurpleBlis
if ((child->parent != NULL) && (child->parent->child == child))
child->parent->child = child->next;
- cklass->remove_node(contact, child);
- gklass->remove_node(group, contact);
+ purple_blist_node_strip(child);
}
+void
+purple_blist_node_strip(PurpleBlistNode *node)
+{
+ g_return_if_fail(node);
+ node->parent = node->child = node->next = node->prev = NULL;
+}
+
/******************/
/* GObject Code */
/******************/
@@ -500,6 +538,13 @@ purple_blist_node_finalize(GObject *obje
parent_class->finalize(object);
}
+static void *
+purple_blist_node_handle()
+{
+ static int handle;
+ return &handle;
+}
+
static void
purple_blist_node_class_init(PurpleBlistNodeClass *klass)
{
@@ -510,8 +555,17 @@ purple_blist_node_class_init(PurpleBlist
g_type_class_add_private(klass, sizeof(PurpleBlistNodePrivate));
- klass->add_node = purple_blist_node_add_node;
- klass->remove_node = purple_blist_node_remove_node;
+ klass->add_node = purple_blist_node_add_child;
+ klass->remove_node = purple_blist_node_remove;
+
+ purple_signal_register( purple_blist_node_handle(),
+ "node-updated",
+ purple_marshal_VOID__POINTER,
+ NULL,
+ 1,
+ purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_BLIST_NODE));
+
+
}
static void
============================================================
--- libpurple/blist-node.h 328c1b48a8d24bc2b1bc00afad46944896b6f4d6
+++ libpurple/blist-node.h c68193160082d8caf7c874498fb0b599a61a577d
@@ -76,8 +76,8 @@ struct _PurpleBlistNodeClass {
struct _PurpleBlistNodeClass {
PurpleObjectClass parent;
- void (*add_node)(PurpleBlistNode *parent, PurpleBlistNode *child);
- void (*remove_node)(PurpleBlistNode *parent, PurpleBlistNode *child);
+ void (*add_node)(PurpleBlistNode *parent, PurpleBlistNode *child, PurpleBlistNode *location);
+ void (*remove_node)(PurpleBlistNode *child);
void (*purple_reserved1)(void);
void (*purple_reserved2)(void);
@@ -152,6 +152,53 @@ PurpleBlistNode *purple_blist_node_get_s
PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node);
/**
+ * Check whether a node is contained in a parent node. Simply checks if the node's parent is the other node.
+ *
+ * @param parent The containing node
+ * @param node The node to check with.
+ * @return Returns TRUE if node's parent is parent.
+ */
+gboolean purple_blist_node_contains(PurpleBlistNode *parent, PurpleBlistNode *node);
+
+/**
+ * Add a node as the first child of a given node.
+ *
+ * @param parent The parent node
+ * @param child The child node to add to parent
+ */
+void purple_blist_node_add_child(PurpleBlistNode *parent, PurpleBlistNode *child);
+
+/**
+ * Add a node before a given node.
+ *
+ * @param node The node to add
+ * @param location The node to insert before, not NULL
+ */
+void purple_blist_node_add_sibling_before(PurpleBlistNode *node, PurpleBlistNode *location);
+
+/**
+ * Add a node after a given node.
+ *
+ * @param node The node to add
+ * @param location The node to insert after, not NULL
+ */
+void purple_blist_node_add_sibling_after(PurpleBlistNode *node, PurpleBlistNode *location);
+
+/**
+ * Remove a node from its parent
+ *
+ * @param node The node to remove
+ */
+void purple_blist_node_remove(PurpleBlistNode *node);
+
+/**
+ * Isolate a node by making all its references NULL.
+ *
+ * @param node The node to isolate
+ */
+void purple_blist_node_strip(PurpleBlistNode *node);
+
+/**
* Returns the UI data of a given node.
*
* @param node The node.
============================================================
--- libpurple/blist.c 35079d994842b0aad4a1e6a418ab888ffd3f6dd1
+++ libpurple/blist.c d0d36f1e2aa8bde6b01ee6f7aac8a908914bf4f1
@@ -416,6 +416,134 @@ purple_strings_are_different(const char
}
/*
+ * TODO: If merging, prompt the user if they want to merge.
+ */
+void purple_blist_rename_group(PurpleGroup *source, const char *name)
+{
+ PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+ PurpleGroup *dest;
+ gchar *old_name;
+ gchar *new_name;
+ GList *moved_buddies = NULL;
+ GSList *accts;
+
+ g_return_if_fail(source != NULL);
+ g_return_if_fail(name != NULL);
+
+ new_name = purple_utf8_strip_unprintables(name);
+
+ if (*new_name == '\0' || purple_strequal(new_name, source->name)) {
+ g_free(new_name);
+ return;
+ }
+
+ dest = purple_find_group(new_name);
+ if (dest != NULL && purple_utf8_strcasecmp(source->name, dest->name) != 0) {
+ /* We're merging two groups */
+ PurpleBlistNode *prev, *child, *next;
+
+ prev = purple_blist_get_last_child((PurpleBlistNode*)dest);
+ child = ((PurpleBlistNode*)source)->child;
+
+ /*
+ * TODO: This seems like a dumb way to do this... why not just
+ * append all children from the old group to the end of the new
+ * one? PRPLs might be expecting to receive an add_buddy() for
+ * each moved buddy...
+ */
+ while (child) {
+ next = child->next;
+ if (PURPLE_IS_CONTACT(child)) {
+ PurpleBlistNode *bnode;
+ purple_blist_add_contact((PurpleContact *)child, dest, prev);
+ for (bnode = child->child; bnode != NULL; bnode = bnode->next) {
+ purple_blist_add_buddy((PurpleBuddy *)bnode, (PurpleContact *)child,
+ NULL, bnode->prev);
+ moved_buddies = g_list_append(moved_buddies, bnode);
+ }
+ prev = child;
+ } else if (PURPLE_IS_CHAT(child)) {
+ purple_blist_add_chat((PurpleChat *)child, dest, prev);
+ prev = child;
+ } else {
+ purple_debug(PURPLE_DEBUG_ERROR, "blist",
+ "Unknown child type in group %s\n", source->name);
+ }
+ child = next;
+ }
+
+ /* Make a copy of the old group name and then delete the old group */
+ old_name = g_strdup(source->name);
+ purple_blist_remove_group(source);
+ source = dest;
+ g_free(new_name);
+ } else {
+ /* A simple rename */
+ moved_buddies = purple_group_get_buddies(source);
+
+ old_name = source->name;
+ source->name = new_name;
+ }
+
+ /* Save our changes */
+ purple_blist_schedule_save();
+
+ /* Update the UI */
+ if (ops && ops->update)
+ ops->update(purplebuddylist, (PurpleBlistNode*)source);
+
+ /* Notify all PRPLs */
+ /* TODO: Is this condition needed? Seems like it would always be TRUE */
+ if(old_name && !purple_strequal(source->name, old_name)) {
+ for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) {
+ PurpleAccount *account = accts->data;
+ PurpleConnection *gc = NULL;
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ GList *l = NULL, *buddies = NULL;
+
+ gc = purple_account_get_connection(account);
+
+ if(gc)
+ prpl = purple_connection_get_prpl(gc);
+
+ if(gc && prpl)
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if(!prpl_info)
+ continue;
+
+ for(l = moved_buddies; l; l = l->next) {
+ PurpleBuddy *buddy = (PurpleBuddy *)l->data;
+
+ if(buddy && purple_buddy_get_account(buddy)== account)
+ buddies = g_list_append(buddies, (PurpleBlistNode *)buddy);
+ }
+
+ if(prpl_info->rename_group) {
+ prpl_info->rename_group(gc, old_name, source, buddies);
+ } else {
+ GList *cur, *groups = NULL;
+
+ /* Make a list of what the groups each buddy is in */
+ for(cur = buddies; cur; cur = cur->next) {
+ PurpleBlistNode *node = (PurpleBlistNode *)cur->data;
+ groups = g_list_prepend(groups, node->parent->parent);
+ }
+
+ purple_account_remove_buddies(account, buddies, groups);
+ g_list_free(groups);
+ purple_account_add_buddies(account, buddies);
+ }
+
+ g_list_free(buddies);
+ }
+ }
+ g_list_free(moved_buddies);
+ g_free(old_name);
+}
+
+/*
* TODO: Maybe remove the call to this from server.c and call it
* from oscar.c and toc.c instead?
*/
@@ -484,21 +612,20 @@ void purple_blist_add_contact(PurpleCont
gnode = (PurpleBlistNode*)g;
cnode = (PurpleBlistNode*)contact;
+ /* If node is already in the list somewhere */
if (cnode->parent) {
- if (cnode->parent->child == cnode)
- cnode->parent->child = cnode->next;
- if (cnode->prev)
- cnode->prev->next = cnode->next;
- if (cnode->next)
- cnode->next->prev = cnode->prev;
-
- if (cnode->parent != gnode) {
+ purple_blist_node_remove(cnode);
+ /* If node is in the group already */
+ if (purple_blist_node_contains(gnode, cnode)) {
bnode = cnode->child;
+ /* Iterate the buddies of the contact */
while (bnode) {
PurpleBlistNode *next_bnode = bnode->next;
PurpleBuddy *b = (PurpleBuddy*)bnode;
GHashTable *account_buddies;
+
+ /* Remove the buddy from the buddies and buddies_cache HTs */
struct _purple_hbuddy *hb, *hb2;
hb = g_new(struct _purple_hbuddy, 1);
@@ -511,6 +638,7 @@ void purple_blist_add_contact(PurpleCont
account_buddies = g_hash_table_lookup(purplebuddylist->buddies_cache, purple_buddy_get_account(b));
g_hash_table_remove(account_buddies, hb);
+ /* If buddy isn't in the group, then add it to the caches with the new group */
if (!purple_find_buddy_in_group(purple_buddy_get_account(b), purple_buddy_get_name(b), g)) {
hb->group = gnode;
g_hash_table_replace(purplebuddylist->buddies, hb, b);
@@ -525,6 +653,8 @@ void purple_blist_add_contact(PurpleCont
if (purple_account_get_connection(purple_buddy_get_account(b)))
serv_move_buddy(b, (PurpleGroup *)cnode->parent, g);
} else {
+ /* If it's already in the group, then we don't move it there,
+ * we just remove it from the contact.*/
gboolean empty_contact = FALSE;
/* this buddy already exists in the group, so we're
@@ -534,6 +664,7 @@ void purple_blist_add_contact(PurpleCont
if (purple_account_get_connection(purple_buddy_get_account(b)))
purple_account_remove_buddy(purple_buddy_get_account(b), b, (PurpleGroup *)cnode->parent);
+ /* Since we removed it from the contact, the cnode might be empty */
if (!cnode->child->next)
empty_contact = TRUE;
purple_blist_remove_buddy(b);
@@ -541,6 +672,7 @@ void purple_blist_add_contact(PurpleCont
/** in purple_blist_remove_buddy(), if the last buddy in a
* contact is removed, the contact is cleaned up and
* g_free'd, so we mustn't try to reference bnode->next */
+ /* If the contact is empty, it's deleted, and thus there's nothing to move */
if (empty_contact)
return;
}
@@ -548,11 +680,8 @@ void purple_blist_add_contact(PurpleCont
}
}
- if (purple_contact_get_online(contact) > 0)
- ((PurpleGroup*)cnode->parent)->online--;
- if (purple_contact_get_currentsize(contact) > 0)
- ((PurpleGroup*)cnode->parent)->currentsize--;
- ((PurpleGroup*)cnode->parent)->totalsize--;
+ /*purple_group_remove_contact_count(PURPLE_GROUP(cnode->parent), contact);*/
+ PURPLE_GROUP(cnode->parent)->totalsize--;
if (ops && ops->remove)
ops->remove(purplebuddylist, cnode);
@@ -560,30 +689,10 @@ void purple_blist_add_contact(PurpleCont
purple_blist_schedule_save();
}
- if (node && (PURPLE_IS_CONTACT(node) ||
- PURPLE_IS_CHAT(node))) {
- if (node->next)
- node->next->prev = cnode;
- cnode->next = node->next;
- cnode->prev = node;
- cnode->parent = node->parent;
- node->next = cnode;
- } else {
- if (gnode->child)
- gnode->child->prev = cnode;
- cnode->prev = NULL;
- cnode->next = gnode->child;
- gnode->child = cnode;
- cnode->parent = gnode;
- }
+ /*purple_group_add_contact(g,contact,node);*/
- if (purple_contact_get_online(contact) > 0)
- g->online++;
- if (purple_contact_get_currentsize(contact) > 0)
- g->currentsize++;
- g->totalsize++;
+ purple_blist_schedule_save();
- purple_blist_schedule_save();
if (ops && ops->update)
{
@@ -595,6 +704,24 @@ void purple_blist_add_contact(PurpleCont
}
}
+/**
+ * Return the group this node is contained in, or the node itself if the node is a group.
+ *
+ * @param node The node to search
+ * @return The group containing the node, or the node itself if the node is a group
+ */
+static PurpleGroup *
+purple_blist_get_containing_group(PurpleBlistNode *node)
+{
+ g_return_val_if_fail(node, NULL);
+ do {
+ if(PURPLE_IS_GROUP(node))
+ return PURPLE_GROUP(node);
+ node = node->parent;
+ } while(node);
+ return NULL;
+}
+
void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node)
{
PurpleBlistUiOps *ops;
@@ -622,24 +749,20 @@ void purple_blist_add_group(PurpleGroup
if (gnode == purplebuddylist->root)
purplebuddylist->root = gnode->next;
- if (gnode->prev)
- gnode->prev->next = gnode->next;
- if (gnode->next)
- gnode->next->prev = gnode->prev;
+ purple_blist_node_remove(gnode);
}
- if (node && PURPLE_IS_GROUP(node)) {
- gnode->next = node->next;
- gnode->prev = node;
- if (node->next)
- node->next->prev = gnode;
- node->next = gnode;
+ if (node) {
+ node = PURPLE_BLIST_NODE(purple_blist_get_containing_group(node));
+ purple_blist_node_add_sibling_after(gnode, node);
} else {
- if (purplebuddylist->root)
- purplebuddylist->root->prev = gnode;
- gnode->next = purplebuddylist->root;
- gnode->prev = NULL;
- purplebuddylist->root = gnode;
+ if (purplebuddylist->root) {
+ purple_blist_node_add_sibling_before(gnode, purplebuddylist->root);
+ }
+ else {
+ purple_blist_node_strip(gnode);
+ purplebuddylist->root = gnode;
+ }
}
purple_blist_schedule_save();
@@ -681,12 +804,7 @@ void purple_blist_remove_contact(PurpleC
purple_blist_remove_buddy((PurpleBuddy*)node->child);
} else {
/* Remove the node from its parent */
- if (gnode->child == node)
- gnode->child = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
+ purple_blist_node_remove(node);
purple_blist_schedule_save();
@@ -715,7 +833,8 @@ void purple_blist_remove_buddy(PurpleBud
cnode = purple_blist_node_get_parent(node);
gnode = purple_blist_node_get_parent(cnode);
- PURPLE_GET_BLIST_NODE_CLASS(node)->remove_node(gnode, node);
+ purple_blist_node_remove(node);
+
purple_blist_schedule_save();
/* Remove this buddy from the buddies hash table */
@@ -757,12 +876,7 @@ void purple_blist_remove_chat(PurpleChat
if (gnode != NULL)
{
/* Remove the node from its parent */
- if (gnode->child == node)
- gnode->child = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
+ purple_blist_node_remove(node);
/* Adjust size counts */
if (purple_account_is_connected(chat->account)) {
@@ -800,12 +914,7 @@ void purple_blist_remove_group(PurpleGro
return;
/* Remove the node from its parent */
- if (purplebuddylist->root == node)
- purplebuddylist->root = node->next;
- if (node->prev)
- node->prev->next = node->next;
- if (node->next)
- node->next->prev = node->prev;
+ purple_blist_node_remove(node);
purple_blist_schedule_save();
============================================================
--- libpurple/blist.h 0dbe462ed24bf7230be59224963bf52e04029987
+++ libpurple/blist.h 4f36e6d84f8d69e8528c9e9be006c74e7c59670a
@@ -291,7 +291,7 @@ void purple_blist_add_buddy(PurpleBuddy
/**
* Adds a new group to the buddy list.
*
- * The new group will be inserted after insert or prepended to the list if
+ * The new group will be inserted after node or prepended to the list if
* node is NULL.
*
* @param group The group
============================================================
--- libpurple/contact.c f225b58c37533bfdee32ee10d4ce4b8f00dd6a66
+++ libpurple/contact.c 0fce70049c47b2f7ccf898f4ee8834b3ebbbb8cb
@@ -280,6 +280,24 @@ gboolean purple_contact_on_account(Purpl
return FALSE;
}
+GList *purple_contact_get_buddies(PurpleContact *contact)
+{
+ GList *buddies = NULL;
+ PurpleBlistNode *cnode;
+ PurpleBlistNode *itr;
+
+ g_return_val_if_fail(contact, NULL);
+ cnode = PURPLE_BLIST_NODE(contact);
+
+ for(itr = cnode->child;itr;itr = itr->next){
+ if(PURPLE_IS_BUDDY(itr)){
+ buddies = g_list_append(buddies,itr);
+ }
+ }
+
+ return buddies;
+}
+
void purple_contact_invalidate_priority_buddy(PurpleContact *contact)
{
g_return_if_fail(contact != NULL);
@@ -298,18 +316,19 @@ static void
}
static void
-purple_contact_add_buddy(PurpleBlistNode *parent, PurpleBlistNode *child)
+purple_contact_add_buddy(PurpleBlistNode *parent, PurpleBlistNode *child, PurpleBlistNode *location)
{
}
static void
-purple_contact_remove_buddy(PurpleBlistNode *parent, PurpleBlistNode *child)
+purple_contact_remove_buddy(PurpleBlistNode *child)
{
- PurpleContact *contact = PURPLE_CONTACT(parent);
+ PurpleContact *contact;
PurpleBuddy *buddy = PURPLE_BUDDY(child);
PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- g_return_if_fail(contact);
+ g_return_if_fail(purple_blist_node_get_parent(child));
+ contact = PURPLE_CONTACT(purple_blist_node_get_parent(child));
if (PURPLE_BUDDY_IS_ONLINE(buddy))
contact->online--;
@@ -317,14 +336,15 @@ purple_contact_remove_buddy(PurpleBlistN
contact->currentsize--;
contact->totalsize--;
-#warning The ui calls haven't been thought out yet, as to where they ought to go.
+ /* emit a node-updated signal here */
+
+#warning The ui calls havent been thought out yet, as to where they ought to go.
/* Re-sort the contact */
if (purple_blist_node_get_first_child(PURPLE_BLIST_NODE(contact)) && contact->priority == buddy) {
purple_contact_invalidate_priority_buddy(contact);
if (ops && ops->update)
ops->update(purplebuddylist, PURPLE_BLIST_NODE(contact));
}
-
}
/****************/
============================================================
--- libpurple/contact.h 72b439d3cc6745409bbf88509d8bae1a028ca382
+++ libpurple/contact.h 5d8bd3aa66ac07cddb3fb79ba83df13c8884e72e
@@ -128,6 +128,14 @@ const char *purple_contact_get_alias(Pur
const char *purple_contact_get_alias(PurpleContact *contact);
/**
+ * Get a list of buddies for this contact
+ *
+ * @param contact The contact
+ * @return the list of buddies
+ */
+GList *purple_contact_get_buddies(PurpleContact *contact);
+
+/**
* Returns a buddy's contact.
*
* @param buddy The buddy.
============================================================
--- libpurple/group.c 1d155a7e3af1302b0948d34bc83e5727a7baf620
+++ libpurple/group.c d6f3080aedb46426fa288810e3f3ef43d4db6b56
@@ -66,142 +66,6 @@ group_to_xmlnode(PurpleBlistNode *gnode)
return node;
}
-/*
- * TODO: If merging, prompt the user if they want to merge.
- */
-void purple_blist_rename_group(PurpleGroup *source, const char *name)
-{
- PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
- PurpleGroup *dest;
- gchar *old_name;
- gchar *new_name;
- GList *moved_buddies = NULL;
- GSList *accts;
-
- g_return_if_fail(source != NULL);
- g_return_if_fail(name != NULL);
-
- new_name = purple_utf8_strip_unprintables(name);
-
- if (*new_name == '\0' || purple_strequal(new_name, source->name)) {
- g_free(new_name);
- return;
- }
-
- dest = purple_find_group(new_name);
- if (dest != NULL && purple_utf8_strcasecmp(source->name, dest->name) != 0) {
- /* We're merging two groups */
- PurpleBlistNode *prev, *child, *next;
-
- prev = purple_blist_get_last_child((PurpleBlistNode*)dest);
- child = ((PurpleBlistNode*)source)->child;
-
- /*
- * TODO: This seems like a dumb way to do this... why not just
- * append all children from the old group to the end of the new
- * one? PRPLs might be expecting to receive an add_buddy() for
- * each moved buddy...
- */
- while (child)
- {
- next = child->next;
- if (PURPLE_IS_CONTACT(child)) {
- PurpleBlistNode *bnode;
- purple_blist_add_contact((PurpleContact *)child, dest, prev);
- for (bnode = child->child; bnode != NULL; bnode = bnode->next) {
- purple_blist_add_buddy((PurpleBuddy *)bnode, (PurpleContact *)child,
- NULL, bnode->prev);
- moved_buddies = g_list_append(moved_buddies, bnode);
- }
- prev = child;
- } else if (PURPLE_IS_CHAT(child)) {
- purple_blist_add_chat((PurpleChat *)child, dest, prev);
- prev = child;
- } else {
- purple_debug(PURPLE_DEBUG_ERROR, "blist",
- "Unknown child type in group %s\n", source->name);
- }
- child = next;
- }
-
- /* Make a copy of the old group name and then delete the old group */
- old_name = g_strdup(source->name);
- purple_blist_remove_group(source);
- source = dest;
- g_free(new_name);
- } else {
- /* A simple rename */
- PurpleBlistNode *cnode, *bnode;
-
- /* Build a GList of all buddies in this group */
- for (cnode = ((PurpleBlistNode *)source)->child; cnode != NULL; cnode = cnode->next) {
- if (PURPLE_IS_CONTACT(cnode))
- for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
- moved_buddies = g_list_append(moved_buddies, bnode);
- }
-
- old_name = source->name;
- source->name = new_name;
- }
-
- /* Save our changes */
- purple_blist_schedule_save();
-
- /* Update the UI */
- if (ops && ops->update)
- ops->update(purplebuddylist, (PurpleBlistNode*)source);
-
- /* Notify all PRPLs */
- /* TODO: Is this condition needed? Seems like it would always be TRUE */
- if(old_name && !purple_strequal(source->name, old_name)) {
- for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) {
- PurpleAccount *account = accts->data;
- PurpleConnection *gc = NULL;
- PurplePlugin *prpl = NULL;
- PurplePluginProtocolInfo *prpl_info = NULL;
- GList *l = NULL, *buddies = NULL;
-
- gc = purple_account_get_connection(account);
-
- if(gc)
- prpl = purple_connection_get_prpl(gc);
-
- if(gc && prpl)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if(!prpl_info)
- continue;
-
- for(l = moved_buddies; l; l = l->next) {
- PurpleBuddy *buddy = (PurpleBuddy *)l->data;
-
- if(buddy && purple_buddy_get_account(buddy)== account)
- buddies = g_list_append(buddies, (PurpleBlistNode *)buddy);
- }
-
- if(prpl_info->rename_group) {
- prpl_info->rename_group(gc, old_name, source, buddies);
- } else {
- GList *cur, *groups = NULL;
-
- /* Make a list of what the groups each buddy is in */
- for(cur = buddies; cur; cur = cur->next) {
- PurpleBlistNode *node = (PurpleBlistNode *)cur->data;
- groups = g_list_prepend(groups, node->parent->parent);
- }
-
- purple_account_remove_buddies(account, buddies, groups);
- g_list_free(groups);
- purple_account_add_buddies(account, buddies);
- }
-
- g_list_free(buddies);
- }
- }
- g_list_free(moved_buddies);
- g_free(old_name);
-}
-
GSList *purple_group_get_accounts(PurpleGroup *group)
{
GSList *l = NULL;
@@ -227,12 +91,17 @@ static void
}
static void
-purple_group_remove_node(PurpleBlistNode *parent, PurpleBlistNode *child)
+purple_group_remove_node(PurpleBlistNode *child)
{
- PurpleGroup *group = PURPLE_GROUP(parent);
- PurpleContact *contact = PURPLE_CONTACT(child);
+ PurpleGroup *group;
+ PurpleContact *contact;
PurpleBlistNode *itr;
+ g_return_if_fail(child);
+ g_return_if_fail(purple_blist_node_get_parent(child));
+ group = PURPLE_GROUP(child->parent);
+ contact = PURPLE_CONTACT(child);
+
#warning Consider optimizing this.
group->totalsize = 0;
group->currentsize = 0;
@@ -293,7 +162,58 @@ int purple_blist_get_group_online_count(
return group->online;
}
+GList *purple_group_get_buddies(PurpleGroup *group)
+{
+ GList *buddies = NULL;
+ PurpleBlistNode *gnode;
+ PurpleBlistNode *itr;
+
+ g_return_val_if_fail(group,NULL);
+
+ gnode = PURPLE_BLIST_NODE(group);
+ for(itr = gnode->child;itr;itr = itr->next){
+ if(PURPLE_IS_CONTACT(itr)){
+ buddies = g_list_concat(buddies, purple_contact_get_buddies(PURPLE_CONTACT(itr)));
+ }
+ }
+
+ return buddies;
+}
+
+void
+purple_group_contact_updated(PurpleGroup *group, PurpleContact *contact)
+{
+ g_return_if_fail(group);
+ g_return_if_fail(contact);
+
+ if (purple_contact_get_online(contact) > 0)
+ group->online++;
+ else
+ group->online--;
+
+ if (purple_contact_get_currentsize(contact) > 0)
+ group->currentsize++;
+ else
+ group->currentsize--;
+}
+
static void
+purple_group_add_contact(PurpleGroup *group, PurpleContact *contact, PurpleBlistNode *node)
+{
+ g_return_if_fail(group);
+ g_return_if_fail(contact);
+
+ if (node && (PURPLE_IS_CONTACT(node) ||
+ PURPLE_IS_CHAT(node))) {
+ purple_blist_node_add_sibling_after(PURPLE_BLIST_NODE(contact), node);
+ } else {
+ purple_blist_node_add_child(PURPLE_BLIST_NODE(group), PURPLE_BLIST_NODE(contact));
+ }
+ purple_group_contact_updated(group, contact);
+ group->totalsize++;
+}
+
+static void
purple_group_set_name(PurpleGroup *group, const char *name)
{
g_return_if_fail(group != NULL);
============================================================
--- libpurple/group.h fe615f7839c9eb8cc6b642e5ea5330f01923249d
+++ libpurple/group.h e76a4c2517b9f0f267cbeb33ea9aa17aafc6390a
@@ -143,6 +143,22 @@ int purple_blist_get_group_online_count(
int purple_blist_get_group_online_count(PurpleGroup *group);
/**
+ * Update the counts based on a changed online/offline status of a contact
+ *
+ * @param group The group to alter
+ * @param contact The contact that's changed
+ */
+void purple_group_contact_updated(PurpleGroup *group, PurpleContact *contact);
+
+/**
+ * Get a list of all the buddies in this group
+ *
+ * @param group The group
+ * @return a list of buddies
+ */
+GList *purple_group_get_buddies(PurpleGroup *group);
+
+/**
* Get the GType for PurpleGroup
*/
GType purple_group_get_type(void);
More information about the Commits
mailing list