# HG changeset patch # User Nathan Walp # Date 1050529742 0 # Node ID 94f11800cac5abd7a01ace566b0f196af43871c2 # Parent 5736055629cbd02f5c5b03b2089f24602e9f1456 [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 diff -r 5736055629cb -r 94f11800cac5 src/buddy.c --- 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)) { diff -r 5736055629cb -r 94f11800cac5 src/list.c --- 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%s\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\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) diff -r 5736055629cb -r 94f11800cac5 src/list.h --- 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