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)