Mercurial > hg
comparison mcabber/src/roster.c @ 78:d001d8fb876d
[/trunk] Changeset 92 by mikael
* Improve roster. Next step is to switch to it, from "buddies".
author | mikael |
---|---|
date | Sat, 16 Apr 2005 20:34:00 +0000 |
parents | 9b7f0d313e33 |
children | 7fb661f19a77 |
comparison
equal
deleted
inserted
replaced
77:32f54ad6d729 | 78:d001d8fb876d |
---|---|
25 | 25 |
26 | 26 |
27 /* This is a private structure type for the roster */ | 27 /* This is a private structure type for the roster */ |
28 | 28 |
29 typedef struct { | 29 typedef struct { |
30 char *name; | 30 const char *name; |
31 char *jid; | 31 const char *jid; |
32 guint type; | 32 guint type; |
33 enum imstatus status; | 33 enum imstatus status; |
34 guint flags; | 34 guint flags; |
35 // list: user -> points to his group; group -> points to its users list | 35 // list: user -> points to his group; group -> points to its users list |
36 GSList *list; | 36 GSList *list; |
40 /* ### Variables ### */ | 40 /* ### Variables ### */ |
41 | 41 |
42 static int hide_offline_buddies; | 42 static int hide_offline_buddies; |
43 static GSList *groups; | 43 static GSList *groups; |
44 GList *buddylist; | 44 GList *buddylist; |
45 GList *current_buddy; | |
45 | 46 |
46 #ifdef MCABBER_TESTUNIT | 47 #ifdef MCABBER_TESTUNIT |
47 // Export groups for testing routines | 48 // Export groups for testing routines |
48 GSList **pgroups = &groups; | 49 GSList **pgroups = &groups; |
49 #endif | 50 #endif |
63 return strcasecmp(a->name, b->name); | 64 return strcasecmp(a->name, b->name); |
64 } | 65 } |
65 | 66 |
66 // Finds a roster element (user, group, agent...), by jid or name | 67 // Finds a roster element (user, group, agent...), by jid or name |
67 // Returns the roster GSList element, or NULL if jid/name not found | 68 // Returns the roster GSList element, or NULL if jid/name not found |
68 GSList *roster_find(char *jidname, enum findwhat type, guint roster_type) | 69 GSList *roster_find(const char *jidname, enum findwhat type, guint roster_type) |
69 { | 70 { |
70 GSList *sl_roster_elt = groups; | 71 GSList *sl_roster_elt = groups; |
71 GSList *res; | 72 GSList *res; |
72 roster sample; | 73 roster sample; |
73 GCompareFunc comp; | 74 GCompareFunc comp; |
99 } | 100 } |
100 return NULL; | 101 return NULL; |
101 } | 102 } |
102 | 103 |
103 // Returns pointer to new group, or existing group with that name | 104 // Returns pointer to new group, or existing group with that name |
104 GSList *roster_add_group(char *name) | 105 GSList *roster_add_group(const char *name) |
105 { | 106 { |
106 roster *roster_grp; | 107 roster *roster_grp; |
107 // #1 Check name doesn't already exist | 108 // #1 Check name doesn't already exist |
108 if (!roster_find(name, namesearch, ROSTER_TYPE_GROUP)) { | 109 if (!roster_find(name, namesearch, ROSTER_TYPE_GROUP)) { |
109 // #2 Create the group node | 110 // #2 Create the group node |
116 } | 117 } |
117 return roster_find(name, namesearch, ROSTER_TYPE_GROUP); | 118 return roster_find(name, namesearch, ROSTER_TYPE_GROUP); |
118 } | 119 } |
119 | 120 |
120 // Returns a pointer to the new user, or existing user with that name | 121 // Returns a pointer to the new user, or existing user with that name |
121 GSList *roster_add_user(char *jid, char *name, char *group, guint type) | 122 GSList *roster_add_user(const char *jid, const char *name, const char *group, |
123 guint type) | |
122 { | 124 { |
123 roster *roster_usr; | 125 roster *roster_usr; |
124 roster *my_group; | 126 roster *my_group; |
125 GSList *slist; | 127 GSList *slist; |
126 | 128 |
127 if ((type != ROSTER_TYPE_USER) && (type != ROSTER_TYPE_AGENT)) { | 129 if ((type != ROSTER_TYPE_USER) && (type != ROSTER_TYPE_AGENT)) { |
128 // XXX Error message? | 130 // XXX Error message? |
129 return NULL; | 131 return NULL; |
130 } | 132 } |
133 | |
134 // Let's be arbitrary: default group has an empty name (""). | |
135 if (!group) group = ""; | |
131 | 136 |
132 // #1 Check this user doesn't already exist | 137 // #1 Check this user doesn't already exist |
133 if ((slist = roster_find(jid, jidsearch, type)) != NULL) | 138 if ((slist = roster_find(jid, jidsearch, type)) != NULL) |
134 return slist; | 139 return slist; |
135 // #2 add group if necessary | 140 // #2 add group if necessary |
137 if (!slist) return NULL; | 142 if (!slist) return NULL; |
138 my_group = (roster*)slist->data; | 143 my_group = (roster*)slist->data; |
139 // #3 Create user node | 144 // #3 Create user node |
140 roster_usr = g_new0(roster, 1); | 145 roster_usr = g_new0(roster, 1); |
141 roster_usr->jid = g_strdup(jid); | 146 roster_usr->jid = g_strdup(jid); |
142 roster_usr->name = g_strdup(name); | 147 if (name) { |
148 roster_usr->name = g_strdup(name); | |
149 } else { | |
150 gchar *p, *str = g_strdup(jid); | |
151 p = g_strstr(str, "/"); | |
152 if (p) *p = '\0'; | |
153 roster_usr->name = g_strdup(str); | |
154 g_free(str); | |
155 } | |
143 roster_usr->type = type; //ROSTER_TYPE_USER; | 156 roster_usr->type = type; //ROSTER_TYPE_USER; |
144 roster_usr->list = slist; // (my_group SList element) | 157 roster_usr->list = slist; // (my_group SList element) |
145 // #4 Insert node (sorted) | 158 // #4 Insert node (sorted) |
146 my_group->list = g_slist_insert_sorted(my_group->list, roster_usr, | 159 my_group->list = g_slist_insert_sorted(my_group->list, roster_usr, |
147 (GCompareFunc)&roster_compare_name); | 160 (GCompareFunc)&roster_compare_name); |
148 return roster_find(jid, jidsearch, type); | 161 return roster_find(jid, jidsearch, type); |
149 } | 162 } |
150 | 163 |
151 // Removes user (jid) from roster, frees allocated memory | 164 // Removes user (jid) from roster, frees allocated memory |
152 void roster_del_user(char *jid) | 165 void roster_del_user(const char *jid) |
153 { | 166 { |
154 GSList *sl_user, *sl_group; | 167 GSList *sl_user, *sl_group; |
155 GSList **sl_group_listptr; | 168 GSList **sl_group_listptr; |
156 roster *roster_usr; | 169 roster *roster_usr; |
157 | 170 |
158 if ((sl_user = roster_find(jid, jidsearch, ROSTER_TYPE_USER)) == NULL) | 171 if ((sl_user = roster_find(jid, jidsearch, ROSTER_TYPE_USER)) == NULL) |
159 return; | 172 return; |
160 // Let's free memory (jid, name) | 173 // Let's free memory (jid, name) |
161 roster_usr = (roster*)sl_user->data; | 174 roster_usr = (roster*)sl_user->data; |
162 if (roster_usr->jid) | 175 if (roster_usr->jid) |
163 g_free(roster_usr->jid); | 176 g_free((gchar*)roster_usr->jid); |
164 if (roster_usr->name) | 177 if (roster_usr->name) |
165 g_free(roster_usr->name); | 178 g_free((gchar*)roster_usr->name); |
166 | 179 |
167 // That's a little complex, we need to dereference twice | 180 // That's a little complex, we need to dereference twice |
168 sl_group = ((roster*)sl_user->data)->list; | 181 sl_group = ((roster*)sl_user->data)->list; |
169 sl_group_listptr = &((roster*)(sl_group->data))->list; | 182 sl_group_listptr = &((roster*)(sl_group->data))->list; |
170 *sl_group_listptr = g_slist_delete_link(*sl_group_listptr, sl_user); | 183 *sl_group_listptr = g_slist_delete_link(*sl_group_listptr, sl_user); |
171 } | 184 |
172 | 185 // We need to rebuild the list |
173 void roster_setstatus(char *jid, enum imstatus bstat) | 186 if (current_buddy) |
187 buddylist_build(); | |
188 // TODO What we should do, too, is to check if the deleted node is | |
189 // current_buddy, in which case we could move current_buddy to the | |
190 // previous (or next) node. | |
191 } | |
192 | |
193 void roster_setstatus(const char *jid, enum imstatus bstat) | |
174 { | 194 { |
175 GSList *sl_user; | 195 GSList *sl_user; |
176 roster *roster_usr; | 196 roster *roster_usr; |
177 | 197 |
178 if ((sl_user = roster_find(jid, jidsearch, ROSTER_TYPE_USER)) == NULL) | 198 if ((sl_user = roster_find(jid, jidsearch, ROSTER_TYPE_USER)) == NULL) |
180 | 200 |
181 roster_usr = (roster*)sl_user->data; | 201 roster_usr = (roster*)sl_user->data; |
182 roster_usr->status = bstat; | 202 roster_usr->status = bstat; |
183 } | 203 } |
184 | 204 |
205 // roster_setflags() | |
206 // Set one or several flags to value (TRUE/FALSE) | |
207 void roster_setflags(char *jid, guint flags, guint value) | |
208 { | |
209 GSList *sl_user; | |
210 roster *roster_usr; | |
211 | |
212 if ((sl_user = roster_find(jid, jidsearch, ROSTER_TYPE_USER)) == NULL) | |
213 return; | |
214 | |
215 roster_usr = (roster*)sl_user->data; | |
216 if (value) | |
217 roster_usr->flags |= flags; | |
218 else | |
219 roster_usr->flags &= ~flags; | |
220 } | |
221 | |
185 // char *roster_getgroup(...) / Or *GSList? Which use?? | 222 // char *roster_getgroup(...) / Or *GSList? Which use?? |
186 // ... setgroup(char*) ?? | 223 // ... setgroup(char*) ?? |
187 // guint roster_gettype(...) / settype | 224 // guint roster_gettype(...) / settype |
188 // guchar roster_getflags(...) / setflags | 225 // guchar roster_getflags(...) |
189 // guchar roster_getname(...) / setname ?? | 226 // guchar roster_getname(...) / setname ?? |
190 // roster_del_group? | 227 // roster_del_group? |
191 | 228 |
192 | 229 |
193 /* ### BuddyList functions ### */ | 230 /* ### BuddyList functions ### */ |
256 | 293 |
257 sl_roster_usrelt = g_slist_next(sl_roster_usrelt); | 294 sl_roster_usrelt = g_slist_next(sl_roster_usrelt); |
258 } | 295 } |
259 sl_roster_elt = g_slist_next(sl_roster_elt); | 296 sl_roster_elt = g_slist_next(sl_roster_elt); |
260 } | 297 } |
298 | |
299 // current_buddy initialization | |
300 if (!current_buddy || (g_list_position(buddylist, current_buddy) == -1)) | |
301 current_buddy = buddylist; | |
261 } | 302 } |
262 | 303 |
263 // buddy_hide_group(roster, hide) | 304 // buddy_hide_group(roster, hide) |
264 // "hide" values: 1=hide 0=show_all -1=invert | 305 // "hide" values: 1=hide 0=show_all -1=invert |
265 void buddy_hide_group(gpointer rosterdata, int hide) | 306 void buddy_hide_group(gpointer rosterdata, int hide) |