aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-05-09 19:05:55 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-05-09 19:05:55 +0100
commit7aadd714313ba3e966720e7565f72118b97bd551 (patch)
treee9ae885742564d381504b0c05f5f8a702b53ac56
parent9ac3ed11de72046c318398481603c6680af37cf2 (diff)
Keep track of contact groups in a slightly more efficient way.
-rw-r--r--protocols/bee.c2
-rw-r--r--protocols/bee.h11
-rw-r--r--protocols/bee_user.c48
-rw-r--r--protocols/nogaim.c2
4 files changed, 61 insertions, 2 deletions
diff --git a/protocols/bee.c b/protocols/bee.c
index 8c38d550..471ce02a 100644
--- a/protocols/bee.c
+++ b/protocols/bee.c
@@ -71,6 +71,8 @@ void bee_free( bee_t *b )
while( b->set )
set_del( &b->set, b->set->key );
+ bee_group_free( b );
+
g_free( b->user );
g_free( b );
}
diff --git a/protocols/bee.h b/protocols/bee.h
index b8fee2ae..100593f9 100644
--- a/protocols/bee.h
+++ b/protocols/bee.h
@@ -34,6 +34,7 @@ typedef struct bee
struct set *set;
GSList *users;
+ GSList *groups;
struct account *accounts; /* TODO(wilmer): Use GSList here too? */
/* Symbolic, to refer to the local user (who has no real bee_user
@@ -59,7 +60,7 @@ typedef struct bee_user
struct im_connection *ic;
char *handle;
char *fullname;
- char *group;
+ struct bee_group *group;
bee_user_flags_t flags;
char *status;
@@ -69,6 +70,12 @@ typedef struct bee_user
void *ui_data;
} bee_user_t;
+typedef struct bee_group
+{
+ char *key;
+ char *name;
+} bee_group_t;
+
typedef struct bee_ui_funcs
{
gboolean (*user_new)( bee_t *bee, struct bee_user *bu );
@@ -103,6 +110,8 @@ bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *hand
int bee_user_free( bee_t *bee, bee_user_t *bu );
bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle );
int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags );
+bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat );
+void bee_group_free( bee_t *bee );
/* Callbacks from IM modules to core: */
/* Buddy activity */
diff --git a/protocols/bee_user.c b/protocols/bee_user.c
index 0dd40cab..fdf84934 100644
--- a/protocols/bee_user.c
+++ b/protocols/bee_user.c
@@ -102,6 +102,54 @@ int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags )
}
+/* Groups */
+static bee_group_t *bee_group_new( bee_t *bee, const char *name )
+{
+ bee_group_t *bg = g_new0( bee_group_t, 1 );
+
+ bg->name = g_strdup( name );
+ bg->key = g_utf8_casefold( name, -1 );
+ bee->groups = g_slist_prepend( bee->groups, bg );
+
+ return bg;
+}
+
+bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat )
+{
+ GSList *l;
+ char *key;
+
+ if( name == NULL )
+ return NULL;
+
+ key = g_utf8_casefold( name, -1 );
+ for( l = bee->groups; l; l = l->next )
+ {
+ bee_group_t *bg = l->data;
+ if( strcmp( bg->key, key ) == 0 )
+ break;
+ }
+ g_free( key );
+
+ if( !l )
+ return creat ? bee_group_new( bee, name ) : NULL;
+ else
+ return l->data;
+}
+
+void bee_group_free( bee_t *bee )
+{
+ while( bee->groups )
+ {
+ bee_group_t *bg = bee->groups->data;
+ g_free( bg->name );
+ g_free( bg->key );
+ g_free( bg );
+ bee->groups = g_slist_remove( bee->groups, bee->groups->data );
+ }
+}
+
+
/* IM->UI callbacks */
void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message )
{
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 149e64f1..5696a01e 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -388,7 +388,7 @@ void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *g
}
bu = bee_user_new( bee, ic, handle );
- bu->group = g_strdup( group );
+ bu->group = bee_group_by_name( bee, group, TRUE );
}
void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname )