changeset 5142:94f11800cac5

[gaim-migrate @ 5506] gave groups the same neat setting stuff that buddies have, and put it to use by having groups remember if they're collapsed. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Wed, 16 Apr 2003 21:49:02 +0000
parents 5736055629cb
children e5661daa66ea
files src/buddy.c src/list.c src/list.h
diffstat 3 files changed, 143 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/buddy.c	Wed Apr 16 17:33:25 2003 +0000
+++ b/src/buddy.c	Wed Apr 16 21:49:02 2003 +0000
@@ -215,6 +215,34 @@
 	gtk_menu_popup(GTK_MENU(awaymenu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
 }
 
+static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) {
+	GaimBlistNode *node;
+	GValue val = {0,};
+
+	gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val);
+
+	node = g_value_get_pointer(&val);
+
+	if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		gaim_group_set_setting((struct group *)node, "collapsed", NULL);
+		gaim_blist_save();
+	}
+}
+
+static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) {
+	GaimBlistNode *node;
+	GValue val = {0,};
+
+	gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val);
+
+	node = g_value_get_pointer(&val);
+
+	if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		gaim_group_set_setting((struct group *)node, "collapsed", "true");
+		gaim_blist_save();
+	}
+}
+
 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) {
 	GaimBlistNode *node;
 	GtkTreeIter iter;
@@ -1232,6 +1260,8 @@
 	gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column);
 
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL);
+	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL);
+	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL);
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL);
 
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0);
@@ -1483,6 +1513,7 @@
 				GtkTreeIter groupiter;
 				GaimBlistNode *oldersibling;
 				GtkTreeIter oldersiblingiter;
+				char *collapsed = gaim_group_get_setting((struct group *)node->parent, "collapsed");
 
 				if(node->parent &&
 						!get_iter_from_node(node->parent, &groupiter)) {
@@ -1490,8 +1521,10 @@
 					 * We do that here */
 					make_a_group(node->parent, &groupiter);
 				}
-				if(!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter))
+				if(!collapsed)
 					expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter);
+				else
+					g_free(collapsed);
 
 				oldersibling = node->prev;
 				while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) {
--- a/src/list.c	Wed Apr 16 17:33:25 2003 +0000
+++ b/src/list.c	Wed Apr 16 21:49:02 2003 +0000
@@ -300,6 +300,8 @@
 		struct gaim_blist_ui_ops *ops;
 		g= g_new0(struct group, 1);
 		g->name = g_strdup(name);
+		g->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
+				g_free, g_free);
 		((GaimBlistNode*)g)->type = GAIM_BLIST_GROUP_NODE;
 
 		ops = gaim_get_blist_ui_ops();
@@ -901,8 +903,10 @@
 static char *blist_parser_setting_name = NULL;
 static char *blist_parser_setting_value = NULL;
 static GHashTable *blist_parser_buddy_settings = NULL;
+static GHashTable *blist_parser_group_settings = NULL;
 static int blist_parser_privacy_mode = 0;
-static enum {
+static GList *tag_stack = NULL;
+enum {
 	BLIST_TAG_GAIM,
 	BLIST_TAG_BLIST,
 	BLIST_TAG_GROUP,
@@ -916,7 +920,7 @@
 	BLIST_TAG_PERMIT,
 	BLIST_TAG_BLOCK,
 	BLIST_TAG_IGNORE
-} blist_parser_current_tag;
+};
 static gboolean blist_parser_error_occurred = FALSE;
 
 static void blist_start_element_handler (GMarkupParseContext *context,
@@ -928,11 +932,11 @@
 	int i;
 
 	if(!strcmp(element_name, "gaim")) {
-		blist_parser_current_tag = BLIST_TAG_GAIM;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_GAIM));
 	} else if(!strcmp(element_name, "blist")) {
-		blist_parser_current_tag = BLIST_TAG_BLIST;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_BLIST));
 	} else if(!strcmp(element_name, "group")) {
-		blist_parser_current_tag = BLIST_TAG_GROUP;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_GROUP));
 		for(i=0; attribute_names[i]; i++) {
 			if(!strcmp(attribute_names[i], "name")) {
 				g_free(blist_parser_group_name);
@@ -944,7 +948,7 @@
 			gaim_blist_add_group(g,NULL);
 		}
 	} else if(!strcmp(element_name, "person")) {
-		blist_parser_current_tag = BLIST_TAG_PERSON;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PERSON));
 		for(i=0; attribute_names[i]; i++) {
 			if(!strcmp(attribute_names[i], "name")) {
 				g_free(blist_parser_person_name);
@@ -952,7 +956,7 @@
 			}
 		}
 	} else if(!strcmp(element_name, "buddy")) {
-		blist_parser_current_tag = BLIST_TAG_BUDDY;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_BUDDY));
 		for(i=0; attribute_names[i]; i++) {
 			if(!strcmp(attribute_names[i], "account")) {
 				g_free(blist_parser_account_name);
@@ -962,11 +966,11 @@
 			}
 		}
 	} else if(!strcmp(element_name, "name")) {
-		blist_parser_current_tag = BLIST_TAG_NAME;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_NAME));
 	} else if(!strcmp(element_name, "alias")) {
-		blist_parser_current_tag = BLIST_TAG_ALIAS;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_ALIAS));
 	} else if(!strcmp(element_name, "setting")) {
-		blist_parser_current_tag = BLIST_TAG_SETTING;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_SETTING));
 		for(i=0; attribute_names[i]; i++) {
 			if(!strcmp(attribute_names[i], "name")) {
 				g_free(blist_parser_setting_name);
@@ -974,9 +978,9 @@
 			}
 		}
 	} else if(!strcmp(element_name, "privacy")) {
-		blist_parser_current_tag = BLIST_TAG_PRIVACY;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PRIVACY));
 	} else if(!strcmp(element_name, "account")) {
-		blist_parser_current_tag = BLIST_TAG_ACCOUNT;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_ACCOUNT));
 		for(i=0; attribute_names[i]; i++) {
 			if(!strcmp(attribute_names[i], "protocol"))
 				blist_parser_account_protocol = atoi(attribute_values[i]);
@@ -988,25 +992,32 @@
 			}
 		}
 	} else if(!strcmp(element_name, "permit")) {
-		blist_parser_current_tag = BLIST_TAG_PERMIT;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PERMIT));
 	} else if(!strcmp(element_name, "block")) {
-		blist_parser_current_tag = BLIST_TAG_BLOCK;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_BLOCK));
 	} else if(!strcmp(element_name, "ignore")) {
-		blist_parser_current_tag = BLIST_TAG_IGNORE;
+		tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_IGNORE));
 	}
 }
 
 static void blist_end_element_handler(GMarkupParseContext *context,
 		const gchar *element_name, gpointer user_data, GError **error) {
 	if(!strcmp(element_name, "gaim")) {
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "blist")) {
-		blist_parser_current_tag = BLIST_TAG_GAIM;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "group")) {
-		blist_parser_current_tag = BLIST_TAG_BLIST;
+		if(blist_parser_group_settings) {
+			struct group *g = gaim_find_group(blist_parser_group_name);
+			g_hash_table_destroy(g->settings);
+			g->settings = blist_parser_group_settings;
+		}
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
+		blist_parser_group_settings = NULL;
 	} else if(!strcmp(element_name, "person")) {
-		blist_parser_current_tag = BLIST_TAG_GROUP;
 		g_free(blist_parser_person_name);
 		blist_parser_person_name = NULL;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "buddy")) {
 		struct gaim_account *account = gaim_account_find(blist_parser_account_name,
 				blist_parser_account_protocol);
@@ -1019,7 +1030,6 @@
 				b->settings = blist_parser_buddy_settings;
 			}
 		}
-		blist_parser_current_tag = BLIST_TAG_PERSON;
 		g_free(blist_parser_buddy_name);
 		blist_parser_buddy_name = NULL;
 		g_free(blist_parser_buddy_alias);
@@ -1027,62 +1037,74 @@
 		g_free(blist_parser_account_name);
 		blist_parser_account_name = NULL;
 		blist_parser_buddy_settings = NULL;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "name")) {
-		blist_parser_current_tag = BLIST_TAG_BUDDY;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "alias")) {
-		blist_parser_current_tag = BLIST_TAG_BUDDY;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "setting")) {
-		if(!blist_parser_buddy_settings)
-			blist_parser_buddy_settings = g_hash_table_new_full(g_str_hash,
-					g_str_equal, g_free, g_free);
-		if(blist_parser_setting_name && blist_parser_setting_value) {
-			g_hash_table_replace(blist_parser_buddy_settings,
-					g_strdup(blist_parser_setting_name),
-					g_strdup(blist_parser_setting_value));
+		if(GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_BUDDY) {
+			if(!blist_parser_buddy_settings)
+				blist_parser_buddy_settings = g_hash_table_new_full(g_str_hash,
+						g_str_equal, g_free, g_free);
+			if(blist_parser_setting_name && blist_parser_setting_value) {
+				g_hash_table_replace(blist_parser_buddy_settings,
+						g_strdup(blist_parser_setting_name),
+						g_strdup(blist_parser_setting_value));
+			}
+		} else if(GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_GROUP) {
+			if(!blist_parser_group_settings)
+				blist_parser_group_settings = g_hash_table_new_full(g_str_hash,
+						g_str_equal, g_free, g_free);
+			if(blist_parser_setting_name && blist_parser_setting_value) {
+				g_hash_table_replace(blist_parser_group_settings,
+						g_strdup(blist_parser_setting_name),
+						g_strdup(blist_parser_setting_value));
+			}
 		}
 		g_free(blist_parser_setting_name);
 		g_free(blist_parser_setting_value);
 		blist_parser_setting_name = NULL;
 		blist_parser_setting_value = NULL;
-		blist_parser_current_tag = BLIST_TAG_BUDDY;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "privacy")) {
-		blist_parser_current_tag = BLIST_TAG_GAIM;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "account")) {
 		struct gaim_account *account = gaim_account_find(blist_parser_account_name,
 				blist_parser_account_protocol);
 		if(account) {
 			account->permdeny = blist_parser_privacy_mode;
 		}
-		blist_parser_current_tag = BLIST_TAG_PRIVACY;
 		g_free(blist_parser_account_name);
 		blist_parser_account_name = NULL;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "permit")) {
 		struct gaim_account *account = gaim_account_find(blist_parser_account_name,
 				blist_parser_account_protocol);
 		if(account) {
 			gaim_privacy_permit_add(account, blist_parser_buddy_name);
 		}
-		blist_parser_current_tag = BLIST_TAG_ACCOUNT;
 		g_free(blist_parser_buddy_name);
 		blist_parser_buddy_name = NULL;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "block")) {
 		struct gaim_account *account = gaim_account_find(blist_parser_account_name,
 				blist_parser_account_protocol);
 		if(account) {
 			gaim_privacy_deny_add(account, blist_parser_buddy_name);
 		}
-		blist_parser_current_tag = BLIST_TAG_ACCOUNT;
 		g_free(blist_parser_buddy_name);
 		blist_parser_buddy_name = NULL;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	} else if(!strcmp(element_name, "ignore")) {
 		/* we'll apparently do something with this later */
-		blist_parser_current_tag = BLIST_TAG_ACCOUNT;
+		tag_stack = g_list_delete_link(tag_stack, tag_stack);
 	}
 }
 
 static void blist_text_handler(GMarkupParseContext *context, const gchar *text,
 		gsize text_len, gpointer user_data, GError **error) {
-	switch(blist_parser_current_tag) {
+	switch(GPOINTER_TO_INT(tag_stack->data)) {
 		case BLIST_TAG_NAME:
 			blist_parser_buddy_name = g_strndup(text, text_len);
 			break;
@@ -1198,6 +1220,24 @@
 	g_free(filename);
 }
 
+static void blist_print_group_settings(gpointer key, gpointer data,
+		gpointer user_data) {
+	char *key_val;
+	char *data_val;
+	FILE *file = user_data;
+
+	if(!key || !data)
+		return;
+
+	key_val = g_markup_escape_text(key, -1);
+	data_val = g_markup_escape_text(data, -1);
+
+	fprintf(file, "\t\t\t<setting name=\"%s\">%s</setting>\n", key_val,
+			data_val);
+	g_free(key_val);
+	g_free(data_val);
+}
+
 static void blist_print_buddy_settings(gpointer key, gpointer data,
 		gpointer user_data) {
 	char *key_val;
@@ -1232,6 +1272,7 @@
 		if(!exp_acct || gaim_group_on_account(group, exp_acct)) {
 			char *group_name = g_markup_escape_text(group->name, -1);
 			fprintf(file, "\t\t<group name=\"%s\">\n", group_name);
+			g_hash_table_foreach(group->settings, blist_print_group_settings, file);
 			for(bnode = gnode->child; bnode; bnode = bnode->next) {
 				if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
 					continue;
@@ -1401,6 +1442,19 @@
 	return FALSE;
 }
 
+void gaim_group_set_setting(struct group *g, const char *key,
+		const char *value) {
+	if(!g)
+		return;
+	g_hash_table_replace(g->settings, g_strdup(key), g_strdup(value));
+}
+
+char *gaim_group_get_setting(struct group *g, const char *key) {
+	if(!g)
+		return NULL;
+	return g_strdup(g_hash_table_lookup(g->settings, key));
+}
+
 void gaim_buddy_set_setting(struct buddy *b, const char *key,
 		const char *value) {
 	if(!b)
--- a/src/list.h	Wed Apr 16 17:33:25 2003 +0000
+++ b/src/list.h	Wed Apr 16 21:49:02 2003 +0000
@@ -94,6 +94,7 @@
 struct group {
 	GaimBlistNode node;                    /**< The node that this group inherits from */
 	char *name;                            /**< The name of this group. */
+	GHashTable *settings;                  /**< per-group settings from the XML buddy list, set by plugins and the likes. */
 };
 
 
@@ -416,6 +417,25 @@
 void gaim_blist_load();
 
 /**
+ * Associates some data with the group in the xml buddy list
+ *
+ * @param g      The group the data is associated with
+ * @param key    The key used to retrieve the data
+ * @param value  The data to set
+ */
+void gaim_group_set_setting(struct group *g, const char *key, const char *value);
+
+/**
+ * Retrieves data from the XML buddy list set by gaim_group_set_setting())
+ *
+ * @param g      The group to retrieve data from
+ * @param key    The key to retrieve the data with
+ * @return       The associated data or NULL if no data is associated
+ */
+char *gaim_group_get_setting(struct group *g, const char *key);
+
+
+/**
  * Associates some data with the buddy in the xml buddy list
  *
  * @param b      The buddy the data is associated with