Mercurial > pidgin
annotate src/protocols/novell/nmcontact.c @ 12116:e75ef7aa913e
[gaim-migrate @ 14416]
" This patch implements a replacement for the queuing
system from 1.x. It also obsoletes a previous patch
[#1338873] I submitted to prioritize the unseen states
in gtk conversations.
The attached envelope.png is ripped from the
msgunread.png already included in gaim. It should be
dropped in the pixmaps directory (Makefile.am is
updated accordingly in this patch).
The two separate queuing preferences from 1.x, queuing
messages while away and queuing all new messages (from
docklet), are replaced with a single 3-way preference
for conversations. The new preference is "Hide new IM
conversations". This preference can be set to never,
away and always.
When a gtk conversation is created, it may be placed in
a hidden conversation window instead of being placed
normally. This decision is based upon the preference
and possibly the away state of the account the
conversation is being created for. This *will* effect
conversations the user explicitly requests to be
created, so in these cases the caller must be sure to
present the conversation to the user, using
gaim_gtkconv_present_conversation(). This is done
already in gtkdialogs.c which handles creating
conversations requested by the user from gaim proper
(menus, double-clicking on budy in blist, etc.).
The main advantage to not queuing messages is that the
conversations exist, the message is written to the
conversation (and logged if appropriate) and the unseen
state is set on the conversation. This means no
additional features are needed to track whether there
are queued messages or not, just use the unseen state
on conversations.
Since conversations may not be visible (messages
"queued"), gaim proper needs some notification that
there are messages waiting. I opted for a menutray icon
that shows up when an im conversation has an unseen
message. Clicking this icon will focus (and show if
hidden) the first conversation with an unseen message.
This is essentially the same behavior of the docklet in
cvs right now, except that the icon is only visible
when there is a conversation with an unread message.
The api that is added is flexible enough to allow
either the docklet or the new blist menutray icon to be
visible for conversations of any/all types and for
unseen messages >= any state. Currently they are set to
only IM conversations and only unseen states >= TEXT
(system messages and no log messages will not trigger
blinking the docklet or showing the blist tray icon),
but these could be made preferences relatively easily
in the future. Other plugins could probably benefit as
well: gaim_gtk_conversations_get_first_unseen().
There is probably some limit to comment size, so I'll
stop rambling now. If anyone has more
questions/comments, catch me in #gaim, here or on
gaim-devel."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 16 Nov 2005 18:17:01 +0000 |
parents | 6663ad2386d9 |
children |
rev | line source |
---|---|
8675 | 1 /* |
2 * nmcontact.c | |
3 * | |
8933 | 4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved. |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; version 2 of the License. | |
8675 | 9 * |
8933 | 10 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
14 * |
8933 | 15 * You should have received a copy of the GNU General Public License |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
8675 | 18 * |
19 */ | |
20 | |
21 #include <glib.h> | |
22 #include <string.h> | |
23 #include "nmcontact.h" | |
24 #include "nmfield.h" | |
25 #include "nmuser.h" | |
26 | |
27 struct _NMContact | |
28 { | |
29 int id; | |
30 int parent_id; | |
31 int seq; | |
32 char *dn; | |
33 char *display_name; | |
34 NMUserRecord *user_record; | |
35 gpointer data; | |
36 int ref_count; | |
37 }; | |
38 | |
39 struct _NMFolder | |
40 { | |
41 int id; | |
42 int seq; | |
43 char *name; | |
44 GSList *folders; | |
45 GSList *contacts; | |
46 int ref_count; | |
47 }; | |
48 | |
49 static int count = 0; | |
50 | |
51 static void _release_folder_contacts(NMFolder * folder); | |
52 static void _release_folder_folders(NMFolder * folder); | |
53 static void _add_contacts(NMUser * user, NMFolder * folder, NMField * fields); | |
54 static void _add_folders(NMFolder * root, NMField * fields); | |
55 | |
56 /********************************************************************* | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
57 * Contact API |
8675 | 58 *********************************************************************/ |
59 | |
60 NMContact * | |
61 nm_create_contact() | |
62 { | |
63 NMContact *contact = g_new0(NMContact, 1); | |
64 | |
65 contact->ref_count = 1; | |
66 | |
67 gaim_debug(GAIM_DEBUG_INFO, "novell", "Creating contact, total=%d\n", | |
68 count++); | |
69 | |
70 return contact; | |
71 } | |
72 | |
73 /* | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
74 * This creates a contact for the contact list. The |
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
75 * field array that is passed in should be a |
8675 | 76 * NM_A_FA_CONTACT array. |
77 * | |
78 */ | |
79 NMContact * | |
80 nm_create_contact_from_fields(NMField * fields) | |
81 { | |
82 NMContact *contact; | |
83 NMField *field; | |
84 | |
8933 | 85 if ( fields == NULL || fields->tag == NULL || fields->ptr_value == 0 || |
8675 | 86 strcmp(fields->tag, NM_A_FA_CONTACT) ) |
87 { | |
88 return NULL; | |
89 } | |
90 | |
91 contact = nm_create_contact(); | |
92 | |
8933 | 93 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) { |
8675 | 94 |
8933 | 95 if (field->ptr_value) |
96 contact->id = atoi((char *) field->ptr_value); | |
8675 | 97 |
98 } | |
99 | |
8933 | 100 if ((field = nm_locate_field(NM_A_SZ_PARENT_ID, (NMField *) fields->ptr_value))) { |
8675 | 101 |
8933 | 102 if (field->ptr_value) |
103 contact->parent_id = atoi((char *) field->ptr_value); | |
8675 | 104 |
105 } | |
106 | |
107 if ((field = | |
8933 | 108 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
109 |
8933 | 110 if (field->ptr_value) |
111 contact->seq = atoi((char *) field->ptr_value); | |
8675 | 112 |
113 } | |
114 | |
115 if ((field = | |
8933 | 116 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
117 |
8933 | 118 if (field->ptr_value) |
119 contact->display_name = g_strdup((char *) field->ptr_value); | |
8675 | 120 |
121 } | |
122 | |
8933 | 123 if ((field = nm_locate_field(NM_A_SZ_DN, (NMField *) fields->ptr_value))) { |
8675 | 124 |
8933 | 125 if (field->ptr_value) |
126 contact->dn = g_strdup((char *) field->ptr_value); | |
8675 | 127 |
128 } | |
129 | |
130 return contact; | |
131 } | |
132 | |
133 void | |
134 nm_contact_update_list_properties(NMContact * contact, NMField * fields) | |
135 { | |
136 NMField *field; | |
137 | |
8933 | 138 if (contact == NULL || fields == NULL || fields->ptr_value == 0) |
8675 | 139 return; |
140 | |
8933 | 141 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
142 |
8933 | 143 if (field->ptr_value) |
144 contact->id = atoi((char *)field->ptr_value); | |
8675 | 145 |
146 } | |
147 | |
8933 | 148 if ((field = nm_locate_field(NM_A_SZ_PARENT_ID, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
149 |
8933 | 150 if (field->ptr_value) |
151 contact->parent_id = atoi((char *) field->ptr_value); | |
8675 | 152 |
153 } | |
154 | |
155 if ((field = | |
8933 | 156 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) { |
8675 | 157 |
8933 | 158 if (field->ptr_value) |
159 contact->seq = atoi((char *) field->ptr_value); | |
8675 | 160 |
161 } | |
162 | |
163 if ((field = | |
8933 | 164 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
165 |
8933 | 166 if (field->ptr_value) { |
8675 | 167 if (contact->display_name) |
168 g_free(contact->display_name); | |
169 | |
8933 | 170 contact->display_name = g_strdup((char *) field->ptr_value); |
8675 | 171 } |
172 | |
173 } | |
174 | |
8933 | 175 if ((field = nm_locate_field(NM_A_SZ_DN, (NMField *) fields->ptr_value))) { |
8675 | 176 |
8933 | 177 if (field->ptr_value) { |
8675 | 178 if (contact->dn) |
179 g_free(contact->dn); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
180 |
8933 | 181 contact->dn = g_strdup((char *) field->ptr_value); |
8675 | 182 } |
183 | |
184 } | |
185 } | |
186 | |
187 NMField * | |
188 nm_contact_to_fields(NMContact * contact) | |
189 { | |
190 NMField *fields = NULL; | |
191 | |
192 if (contact == NULL) | |
193 return NULL; | |
194 | |
8933 | 195 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0, |
196 g_strdup_printf("%d", contact->id), NMFIELD_TYPE_UTF8); | |
8675 | 197 |
8933 | 198 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0, |
199 g_strdup_printf("%d", contact->parent_id), NMFIELD_TYPE_UTF8); | |
8675 | 200 |
8933 | 201 fields = nm_field_add_pointer(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0, |
202 g_strdup_printf("%d", contact->seq), NMFIELD_TYPE_UTF8); | |
8675 | 203 |
204 if (contact->display_name != NULL) { | |
8933 | 205 fields = nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0, |
206 g_strdup(contact->display_name), NMFIELD_TYPE_UTF8); | |
8675 | 207 } |
208 | |
209 if (contact->dn != NULL) { | |
8933 | 210 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0, |
211 g_strdup(contact->dn), NMFIELD_TYPE_UTF8); | |
8675 | 212 } |
213 | |
214 return fields; | |
215 } | |
216 | |
217 void | |
218 nm_contact_add_ref(NMContact * contact) | |
219 { | |
220 if (contact) | |
221 contact->ref_count++; | |
222 } | |
223 | |
224 void | |
225 nm_release_contact(NMContact * contact) | |
226 { | |
227 if (contact == NULL) | |
228 return; | |
229 | |
230 if (--(contact->ref_count) == 0) { | |
231 | |
232 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
233 "Releasing contact, total=%d\n", --count); | |
234 | |
235 if (contact->display_name) { | |
236 g_free(contact->display_name); | |
237 } | |
238 | |
239 if (contact->dn) { | |
240 g_free(contact->dn); | |
241 } | |
242 | |
243 if (contact->user_record) { | |
244 nm_release_user_record(contact->user_record); | |
245 } | |
246 | |
247 g_free(contact); | |
248 } | |
249 | |
250 } | |
251 | |
252 const char * | |
253 nm_contact_get_display_name(NMContact * contact) | |
254 { | |
255 if (contact == NULL) | |
256 return NULL; | |
257 | |
258 if (contact->user_record != NULL && contact->display_name == NULL) { | |
259 const char *full_name, *lname, *fname, *cn, *display_id; | |
260 | |
261 full_name = nm_user_record_get_full_name(contact->user_record); | |
262 fname = nm_user_record_get_first_name(contact->user_record); | |
263 lname = nm_user_record_get_last_name(contact->user_record); | |
264 cn = nm_user_record_get_userid(contact->user_record); | |
265 display_id = nm_user_record_get_display_id(contact->user_record); | |
266 | |
267 /* Try to build a display name. */ | |
268 if (full_name) { | |
269 | |
270 contact->display_name = g_strdup(full_name); | |
271 | |
272 } else if (fname && lname) { | |
273 | |
274 contact->display_name = g_strdup_printf("%s %s", fname, lname); | |
275 | |
276 } else { | |
277 | |
278 /* If auth attribute is set use it */ | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
279 if (nm_user_record_get_auth_attr(contact->user_record) && |
8675 | 280 display_id != NULL) { |
281 | |
282 contact->display_name = g_strdup(display_id); | |
283 | |
284 } else { | |
285 | |
286 /* Use CN or display id */ | |
287 if (cn) { | |
288 | |
289 contact->display_name = g_strdup(cn); | |
290 | |
291 } else if (display_id) { | |
292 | |
293 contact->display_name = g_strdup(display_id); | |
294 | |
295 } | |
296 | |
297 } | |
298 | |
299 } | |
300 } | |
301 | |
302 return contact->display_name; | |
303 } | |
304 | |
305 void | |
306 nm_contact_set_display_name(NMContact * contact, const char *display_name) | |
307 { | |
308 if (contact == NULL) | |
309 return; | |
310 | |
311 if (contact->display_name) { | |
312 g_free(contact->display_name); | |
313 contact->display_name = NULL; | |
314 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
315 |
8675 | 316 if (display_name) |
317 contact->display_name = g_strdup(display_name); | |
318 } | |
319 | |
320 void | |
321 nm_contact_set_dn(NMContact * contact, const char *dn) | |
322 { | |
323 if (contact == NULL) | |
324 return; | |
325 | |
326 if (contact->dn) { | |
327 g_free(contact->dn); | |
328 contact->dn = NULL; | |
329 } | |
330 | |
331 if (dn) | |
332 contact->dn = g_strdup(dn); | |
333 } | |
334 | |
335 const char * | |
336 nm_contact_get_dn(NMContact * contact) | |
337 { | |
338 if (contact == NULL) | |
339 return NULL; | |
340 | |
341 return contact->dn; | |
342 } | |
343 | |
344 gpointer | |
345 nm_contact_get_data(NMContact * contact) | |
346 { | |
347 if (contact == NULL) | |
348 return NULL; | |
349 | |
350 return contact->data; | |
351 } | |
352 | |
353 int | |
354 nm_contact_get_id(NMContact * contact) | |
355 { | |
356 if (contact == NULL) | |
357 return -1; | |
358 | |
359 return contact->id; | |
360 } | |
361 | |
362 int | |
363 nm_contact_get_parent_id(NMContact * contact) | |
364 { | |
365 if (contact == NULL) | |
366 return -1; | |
367 | |
368 return contact->parent_id; | |
369 } | |
370 | |
371 void | |
372 nm_contact_set_data(NMContact * contact, gpointer data) | |
373 { | |
374 if (contact == NULL) | |
375 return; | |
376 | |
377 contact->data = data; | |
378 } | |
379 | |
380 void | |
381 nm_contact_set_user_record(NMContact * contact, NMUserRecord * user_record) | |
382 { | |
383 if (contact == NULL) | |
384 return; | |
385 | |
386 if (contact->user_record) { | |
387 nm_release_user_record(contact->user_record); | |
388 } | |
389 | |
390 nm_user_record_add_ref(user_record); | |
391 contact->user_record = user_record; | |
392 } | |
393 | |
394 NMUserRecord * | |
395 nm_contact_get_user_record(NMContact * contact) | |
396 { | |
397 if (contact == NULL) | |
398 return NULL; | |
399 | |
400 return contact->user_record; | |
401 } | |
402 | |
403 const char * | |
404 nm_contact_get_userid(NMContact * contact) | |
405 { | |
406 NMUserRecord *user_record; | |
407 const char *userid = NULL; | |
408 | |
409 if (contact == NULL) | |
410 return NULL; | |
411 | |
412 user_record = nm_contact_get_user_record(contact); | |
413 if (user_record) { | |
414 userid = nm_user_record_get_userid(user_record); | |
415 } | |
416 | |
417 return userid; | |
418 } | |
419 | |
420 const char * | |
421 nm_contact_get_display_id(NMContact * contact) | |
422 { | |
423 NMUserRecord *user_record; | |
424 const char *id = NULL; | |
425 | |
426 if (contact == NULL) | |
427 return NULL; | |
428 | |
429 user_record = nm_contact_get_user_record(contact); | |
430 if (user_record) { | |
431 id = nm_user_record_get_display_id(user_record); | |
432 } | |
433 | |
434 return id; | |
435 } | |
436 | |
437 | |
438 /********************************************************************* | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
439 * Folder API |
8675 | 440 *********************************************************************/ |
441 | |
442 NMFolder * | |
443 nm_create_folder(const char *name) | |
444 { | |
445 NMFolder *folder = g_new0(NMFolder, 1); | |
446 | |
447 if (name) | |
448 folder->name = g_strdup(name); | |
449 | |
450 folder->ref_count = 1; | |
451 | |
452 return folder; | |
453 } | |
454 | |
455 NMFolder * | |
456 nm_create_folder_from_fields(NMField * fields) | |
457 { | |
458 NMField *field; | |
459 NMFolder *folder; | |
460 | |
8933 | 461 if (fields == NULL || fields->ptr_value == 0) |
8675 | 462 return NULL; |
463 | |
464 folder = g_new0(NMFolder, 1); | |
465 | |
8933 | 466 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
467 |
8933 | 468 if (field->ptr_value) |
469 folder->id = atoi((char *) field->ptr_value); | |
8675 | 470 } |
471 | |
472 if ((field = | |
8933 | 473 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
474 |
8933 | 475 if (field->ptr_value) |
476 folder->seq = atoi((char *) field->ptr_value); | |
8675 | 477 } |
478 | |
479 if ((field = | |
8933 | 480 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) { |
8675 | 481 |
8933 | 482 if (field->ptr_value) |
483 folder->name = g_strdup((char *) field->ptr_value); | |
8675 | 484 } |
485 | |
486 folder->ref_count = 1; | |
487 return folder; | |
488 } | |
489 | |
490 NMField * | |
491 nm_folder_to_fields(NMFolder * folder) | |
492 { | |
493 NMField *fields = NULL; | |
494 | |
495 if (folder == NULL) | |
496 return NULL; | |
497 | |
8933 | 498 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0, |
499 g_strdup_printf("%d", folder->id), NMFIELD_TYPE_UTF8); | |
8675 | 500 |
8933 | 501 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0, |
502 g_strdup("0"), NMFIELD_TYPE_UTF8); | |
8675 | 503 |
8933 | 504 fields = nm_field_add_pointer(fields, NM_A_SZ_TYPE, 0, NMFIELD_METHOD_VALID, 0, |
505 g_strdup("1"), NMFIELD_TYPE_UTF8); | |
8675 | 506 |
8933 | 507 fields = nm_field_add_pointer(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0, |
508 g_strdup_printf("%d", folder->seq), NMFIELD_TYPE_UTF8); | |
8675 | 509 |
510 if (folder->name != NULL) { | |
8933 | 511 fields = nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0, |
512 g_strdup(folder->name), NMFIELD_TYPE_UTF8); | |
8675 | 513 } |
514 | |
515 | |
516 return fields; | |
517 } | |
518 | |
519 void | |
520 nm_folder_update_list_properties(NMFolder * folder, NMField * fields) | |
521 { | |
522 NMField *field; | |
523 | |
8933 | 524 if (folder == NULL || fields == NULL || fields->ptr_value == 0) |
8675 | 525 return; |
526 | |
8933 | 527 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
528 |
8933 | 529 if (field->ptr_value) |
530 folder->id = atoi((char *) field->ptr_value); | |
8675 | 531 |
532 } | |
533 | |
534 if ((field = | |
8933 | 535 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) { |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
536 |
8933 | 537 if (field->ptr_value) |
538 folder->seq = atoi((char *) field->ptr_value); | |
8675 | 539 |
540 } | |
541 | |
542 if ((field = | |
8933 | 543 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) { |
8675 | 544 |
8933 | 545 if (field->ptr_value) { |
8675 | 546 if (folder->name) |
547 g_free(folder->name); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
548 |
8933 | 549 folder->name = g_strdup((char *) field->ptr_value); |
8675 | 550 } |
551 | |
552 } | |
553 | |
554 } | |
555 | |
556 void | |
557 nm_release_folder(NMFolder * folder) | |
558 { | |
559 if (folder == NULL) | |
560 return; | |
561 | |
562 if (--(folder->ref_count) == 0) { | |
563 if (folder->name) { | |
564 g_free(folder->name); | |
565 } | |
566 | |
567 if (folder->folders) { | |
568 _release_folder_folders(folder); | |
569 } | |
570 | |
571 if (folder->contacts) { | |
572 _release_folder_contacts(folder); | |
573 } | |
574 | |
575 g_free(folder); | |
576 } | |
577 } | |
578 | |
579 | |
580 void | |
581 nm_folder_add_ref(NMFolder * folder) | |
582 { | |
583 if (folder) | |
584 folder->ref_count++; | |
585 } | |
586 | |
587 int | |
588 nm_folder_get_subfolder_count(NMFolder * folder) | |
589 { | |
590 if (folder == NULL) | |
591 return 0; | |
592 | |
593 if (folder->folders) | |
594 return g_slist_length(folder->folders); | |
595 else | |
596 return 0; | |
597 } | |
598 | |
599 NMFolder * | |
600 nm_folder_get_subfolder(NMFolder * folder, int index) | |
601 { | |
602 if (folder == NULL) | |
603 return NULL; | |
604 | |
605 if (folder->folders) | |
606 return (NMFolder *) g_slist_nth_data(folder->folders, index); | |
607 else | |
608 return NULL; | |
609 } | |
610 | |
611 int | |
612 nm_folder_get_contact_count(NMFolder * folder) | |
613 { | |
614 if (folder == NULL) | |
615 return 0; | |
616 | |
617 if (folder->contacts != NULL) | |
618 return g_slist_length(folder->contacts); | |
619 else | |
620 return 0; | |
621 } | |
622 | |
623 NMContact * | |
624 nm_folder_get_contact(NMFolder * folder, int index) | |
625 { | |
626 if (folder == NULL) | |
627 return NULL; | |
628 | |
629 if (folder->contacts) | |
630 return (NMContact *) g_slist_nth_data(folder->contacts, index); | |
631 else | |
632 return NULL; | |
633 } | |
634 | |
635 const char * | |
636 nm_folder_get_name(NMFolder * folder) | |
637 { | |
638 if (folder == NULL) | |
639 return NULL; | |
640 | |
641 return folder->name; | |
642 } | |
643 | |
644 void | |
645 nm_folder_set_name(NMFolder * folder, const char *name) | |
646 { | |
647 if (folder == NULL || name == NULL) | |
648 return; | |
649 | |
650 if (folder->name) | |
651 g_free(folder->name); | |
652 | |
653 folder->name = g_strdup(name); | |
654 } | |
655 | |
656 int | |
657 nm_folder_get_id(NMFolder * folder) | |
658 { | |
659 if (folder == NULL) { | |
660 return -1; | |
661 } | |
662 | |
663 return folder->id; | |
664 } | |
665 | |
666 void | |
667 nm_folder_add_folder_to_list(NMFolder * root, NMFolder * folder) | |
668 { | |
669 GSList *node; | |
670 | |
671 if (root == NULL || folder == NULL) | |
672 return; | |
673 | |
674 node = root->folders; | |
675 while (node) { | |
676 if (folder->seq <= ((NMFolder *) node->data)->seq) { | |
677 nm_folder_add_ref(folder); | |
678 root->folders = g_slist_insert_before(root->folders, node, folder); | |
679 break; | |
680 } | |
681 node = g_slist_next(node); | |
682 } | |
683 if (node == NULL) { | |
684 nm_folder_add_ref(folder); | |
685 root->folders = g_slist_append(root->folders, folder); | |
686 } | |
687 } | |
688 | |
689 void | |
690 nm_folder_remove_contact(NMFolder * folder, NMContact * contact) | |
691 { | |
8770 | 692 GSList *node; |
8769
0bde91a2ea4d
[gaim-migrate @ 9530]
Christian Hammond <chipx86@chipx86.com>
parents:
8684
diff
changeset
|
693 |
8675 | 694 if (folder == NULL || contact == NULL) |
695 return; | |
696 | |
8770 | 697 node = folder->contacts; |
8675 | 698 while (node) { |
699 if (contact->id == ((NMContact *) (node->data))->id) { | |
700 folder->contacts = g_slist_remove(folder->contacts, node->data); | |
701 nm_release_contact(contact); | |
702 break; | |
703 } | |
704 node = g_slist_next(node); | |
705 } | |
706 } | |
707 | |
708 void | |
709 nm_folder_add_contact_to_list(NMFolder * root_folder, NMContact * contact) | |
710 { | |
711 GSList *node = NULL; | |
712 NMFolder *folder = root_folder; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
713 |
8675 | 714 if (folder == NULL || contact == NULL) |
715 return; | |
716 | |
717 /* Find folder to add contact to */ | |
718 if (contact->parent_id != 0) { | |
719 node = folder->folders; | |
720 while (node) { | |
721 folder = (NMFolder *) node->data; | |
722 if (contact->parent_id == folder->id) { | |
723 break; | |
724 } | |
725 folder = NULL; | |
726 node = g_slist_next(node); | |
727 } | |
728 } | |
729 | |
730 /* Add contact to list */ | |
731 if (folder) { | |
732 node = folder->contacts; | |
733 while (node) { | |
734 if (contact->seq <= ((NMContact *) (node->data))->seq) { | |
735 nm_contact_add_ref(contact); | |
736 folder->contacts = | |
737 g_slist_insert_before(folder->contacts, node, contact); | |
738 break; | |
739 } | |
740 node = g_slist_next(node); | |
741 } | |
742 | |
743 if (node == NULL) { | |
744 nm_contact_add_ref(contact); | |
745 folder->contacts = g_slist_append(folder->contacts, contact); | |
746 } | |
747 } | |
748 } | |
749 | |
750 void | |
751 nm_folder_add_contacts_and_folders(NMUser * user, NMFolder * root, | |
752 NMField * fields) | |
753 { | |
754 /* Add the contacts and folders from the field array */ | |
755 if (user && root && fields) { | |
756 _add_folders(root, fields); | |
757 _add_contacts(user, root, fields); | |
758 } | |
759 } | |
760 | |
761 gpointer | |
762 nm_folder_find_item_by_object_id(NMFolder * root_folder, int object_id) | |
763 { | |
764 int cnt, cnt2, i, j; | |
765 gpointer item = NULL; | |
766 NMFolder *folder; | |
767 NMContact *contact; | |
768 | |
769 if (root_folder == NULL) | |
770 return NULL; | |
771 | |
772 /* Check all contacts for the top level folder */ | |
773 cnt = nm_folder_get_contact_count(root_folder); | |
774 for (i = 0; i < cnt; i++) { | |
775 contact = nm_folder_get_contact(root_folder, i); | |
776 if (contact && (contact->id == object_id)) { | |
777 item = contact; | |
778 break; | |
779 } | |
780 } | |
781 | |
782 /* If we haven't found the item yet, check the subfolders */ | |
783 if (item == NULL) { | |
784 cnt = nm_folder_get_subfolder_count(root_folder); | |
785 for (i = 0; (i < cnt) && (item == NULL); i++) { | |
786 folder = nm_folder_get_subfolder(root_folder, i); | |
787 | |
788 /* Check the id of this folder */ | |
789 if (folder && (folder->id == object_id)) { | |
790 item = folder; | |
791 break; | |
792 } | |
793 | |
794 /* Check all contacts for this folder */ | |
795 cnt2 = nm_folder_get_contact_count(folder); | |
796 for (j = 0; j < cnt2; j++) { | |
797 contact = nm_folder_get_contact(folder, j); | |
798 if (contact && (contact->id == object_id)) { | |
799 item = contact; | |
800 break; | |
801 } | |
802 } | |
803 } | |
804 } | |
805 | |
806 return item; | |
807 } | |
808 | |
809 NMContact * | |
810 nm_folder_find_contact_by_userid(NMFolder * folder, const char *userid) | |
811 { | |
812 int cnt, i; | |
813 NMContact *tmp, *contact = NULL; | |
814 | |
815 if (folder == NULL || userid == NULL) | |
816 return NULL; | |
817 | |
818 cnt = nm_folder_get_contact_count(folder); | |
819 for (i = 0; i < cnt; i++) { | |
820 tmp = nm_folder_get_contact(folder, i); | |
821 if (tmp && nm_utf8_str_equal(nm_contact_get_userid(tmp), userid)) { | |
822 contact = tmp; | |
823 break; | |
824 } | |
825 } | |
826 | |
827 return contact; | |
828 } | |
829 | |
830 NMContact * | |
8933 | 831 nm_folder_find_contact_by_display_id(NMFolder * folder, const char *display_id) |
832 { | |
833 int cnt, i; | |
834 NMContact *tmp, *contact = NULL; | |
835 | |
836 if (folder == NULL || display_id == NULL) | |
837 return NULL; | |
838 | |
839 cnt = nm_folder_get_contact_count(folder); | |
840 for (i = 0; i < cnt; i++) { | |
841 tmp = nm_folder_get_contact(folder, i); | |
842 if (tmp && nm_utf8_str_equal(nm_contact_get_display_id(tmp), display_id)) { | |
843 contact = tmp; | |
844 break; | |
845 } | |
846 } | |
847 | |
848 return contact; | |
849 } | |
850 | |
851 NMContact * | |
8675 | 852 nm_folder_find_contact(NMFolder * folder, const char *dn) |
853 { | |
854 int cnt, i; | |
855 NMContact *tmp, *contact = NULL; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
856 |
8675 | 857 if (folder == NULL || dn == NULL) |
858 return NULL; | |
859 | |
860 cnt = nm_folder_get_contact_count(folder); | |
861 for (i = 0; i < cnt; i++) { | |
862 tmp = nm_folder_get_contact(folder, i); | |
863 if (tmp && nm_utf8_str_equal(nm_contact_get_dn(tmp), dn)) { | |
864 contact = tmp; | |
865 break; | |
866 } | |
867 } | |
868 | |
869 return contact; | |
870 } | |
871 | |
872 | |
873 /********************************************************************* | |
874 * Utility functions | |
875 *********************************************************************/ | |
876 | |
877 static void | |
878 _release_folder_contacts(NMFolder * folder) | |
879 { | |
880 GSList *cnode; | |
881 NMContact *contact; | |
882 | |
883 for (cnode = folder->contacts; cnode; cnode = cnode->next) { | |
884 contact = cnode->data; | |
885 cnode->data = NULL; | |
886 nm_release_contact(contact); | |
887 } | |
888 | |
889 g_slist_free(folder->contacts); | |
890 folder->contacts = NULL; | |
891 } | |
892 | |
893 static void | |
894 _release_folder_folders(NMFolder * folder) | |
895 { | |
896 GSList *fnode; | |
897 NMFolder *subfolder; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
898 |
8675 | 899 if (folder == NULL) |
900 return; | |
901 | |
902 for (fnode = folder->folders; fnode; fnode = fnode->next) { | |
903 subfolder = fnode->data; | |
904 fnode->data = NULL; | |
905 nm_release_folder(subfolder); | |
906 } | |
907 | |
908 g_slist_free(folder->folders); | |
909 folder->folders = NULL; | |
910 } | |
911 | |
912 static void | |
913 _add_folders(NMFolder * root, NMField * fields) | |
914 { | |
915 NMFolder *folder = NULL; | |
916 NMField *locate = NULL; | |
917 | |
918 locate = nm_locate_field(NM_A_FA_FOLDER, fields); | |
919 while (locate != NULL) { | |
920 | |
921 /* Create a new folder */ | |
922 folder = nm_create_folder_from_fields(locate); | |
923 | |
924 /* Add subfolder to roots folder list */ | |
925 nm_folder_add_folder_to_list(root, folder); | |
926 | |
927 /* Decrement the ref count */ | |
928 nm_release_folder(folder); | |
929 | |
930 /* Find the next folder */ | |
931 locate = nm_locate_field(NM_A_FA_FOLDER, locate+1); | |
932 | |
933 } | |
934 } | |
935 | |
936 static void | |
937 _add_contacts(NMUser * user, NMFolder * folder, NMField * fields) | |
938 { | |
939 NMContact *contact = NULL; | |
940 NMField *locate = NULL, *details; | |
941 NMUserRecord *user_record = NULL; | |
942 | |
943 locate = nm_locate_field(NM_A_FA_CONTACT, fields); | |
944 while (locate != NULL) { | |
945 | |
946 /* Create a new contact from the fields */ | |
947 contact = nm_create_contact_from_fields(locate); | |
948 | |
949 /* Add it to our contact list */ | |
950 nm_folder_add_contact_to_list(folder, contact); | |
951 | |
952 /* Update the contact cache */ | |
953 nm_user_add_contact(user, contact); | |
954 | |
955 /* Update the user record cache */ | |
956 if ((details = nm_locate_field(NM_A_FA_USER_DETAILS, | |
8933 | 957 (NMField *) locate->ptr_value))) { |
8675 | 958 user_record = nm_find_user_record(user, nm_contact_get_dn(contact)); |
959 if (user_record == NULL) { | |
960 user_record = nm_create_user_record_from_fields(details); | |
961 nm_user_record_set_dn(user_record, nm_contact_get_dn(contact)); | |
962 nm_user_add_user_record(user, user_record); | |
963 nm_release_user_record(user_record); | |
964 } | |
965 nm_contact_set_user_record(contact, user_record); | |
966 } | |
967 | |
968 nm_release_contact(contact); | |
969 | |
970 locate = nm_locate_field(NM_A_FA_CONTACT, locate+1); | |
971 } | |
972 } |