ms-dlx: parse SearchAbRequest response
[siplcs.git] / src / purple / purple-buddy.c
blob54a9bd4b98d0db78e4f1c94b3ba37394957588fd
1 /**
2 * @file purple-buddy.c
4 * pidgin-sipe
6 * Copyright (C) 2010-11 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <glib.h>
29 #include "purple-private.h"
31 #include "blist.h"
32 #include "notify.h"
33 #include "privacy.h"
34 #include "request.h"
35 #include "version.h"
37 #include "sipe-common.h"
38 #include "sipe-backend.h"
39 #include "sipe-core.h"
40 #include "sipe-nls.h"
42 static GHashTable *info_to_property_table = NULL;
44 /** Property names to store in blist.xml */
45 #define ALIAS_PROP "alias"
46 #define EMAIL_PROP "email"
47 #define PHONE_PROP "phone"
48 #define PHONE_DISPLAY_PROP "phone-display"
49 #define PHONE_MOBILE_PROP "phone-mobile"
50 #define PHONE_MOBILE_DISPLAY_PROP "phone-mobile-display"
51 #define PHONE_HOME_PROP "phone-home"
52 #define PHONE_HOME_DISPLAY_PROP "phone-home-display"
53 #define PHONE_OTHER_PROP "phone-other"
54 #define PHONE_OTHER_DISPLAY_PROP "phone-other-display"
55 #define PHONE_CUSTOM1_PROP "phone-custom1"
56 #define PHONE_CUSTOM1_DISPLAY_PROP "phone-custom1-display"
57 #define SITE_PROP "site"
58 #define COMPANY_PROP "company"
59 #define DEPARTMENT_PROP "department"
60 #define TITLE_PROP "title"
61 #define OFFICE_PROP "office"
62 /** implies work address */
63 #define ADDRESS_STREET_PROP "address-street"
64 #define ADDRESS_CITY_PROP "address-city"
65 #define ADDRESS_STATE_PROP "address-state"
66 #define ADDRESS_ZIPCODE_PROP "address-zipcode"
67 #define ADDRESS_COUNTRYCODE_PROP "address-country-code"
69 #define ADD_PROP(key,value) g_hash_table_insert(info_to_property_table, (gpointer)key, value)
71 static void
72 init_property_hash(void)
74 info_to_property_table = g_hash_table_new(NULL, NULL);
76 ADD_PROP(SIPE_BUDDY_INFO_DISPLAY_NAME , ALIAS_PROP);
77 ADD_PROP(SIPE_BUDDY_INFO_EMAIL , EMAIL_PROP);
78 ADD_PROP(SIPE_BUDDY_INFO_WORK_PHONE , PHONE_PROP);
79 ADD_PROP(SIPE_BUDDY_INFO_WORK_PHONE_DISPLAY , PHONE_DISPLAY_PROP);
80 ADD_PROP(SIPE_BUDDY_INFO_SITE , SITE_PROP);
81 ADD_PROP(SIPE_BUDDY_INFO_COMPANY , COMPANY_PROP);
82 ADD_PROP(SIPE_BUDDY_INFO_DEPARTMENT , DEPARTMENT_PROP);
83 ADD_PROP(SIPE_BUDDY_INFO_JOB_TITLE , TITLE_PROP);
84 ADD_PROP(SIPE_BUDDY_INFO_OFFICE , OFFICE_PROP);
85 ADD_PROP(SIPE_BUDDY_INFO_STREET , ADDRESS_STREET_PROP);
86 ADD_PROP(SIPE_BUDDY_INFO_CITY , ADDRESS_CITY_PROP);
87 ADD_PROP(SIPE_BUDDY_INFO_STATE , ADDRESS_STATE_PROP);
88 ADD_PROP(SIPE_BUDDY_INFO_ZIPCODE , ADDRESS_ZIPCODE_PROP);
89 ADD_PROP(SIPE_BUDDY_INFO_COUNTRY , ADDRESS_COUNTRYCODE_PROP);
90 ADD_PROP(SIPE_BUDDY_INFO_MOBILE_PHONE , PHONE_MOBILE_PROP);
91 ADD_PROP(SIPE_BUDDY_INFO_MOBILE_PHONE_DISPLAY , PHONE_MOBILE_DISPLAY_PROP);
92 ADD_PROP(SIPE_BUDDY_INFO_HOME_PHONE , PHONE_HOME_PROP);
93 ADD_PROP(SIPE_BUDDY_INFO_HOME_PHONE_DISPLAY , PHONE_HOME_DISPLAY_PROP);
94 ADD_PROP(SIPE_BUDDY_INFO_OTHER_PHONE , PHONE_OTHER_PROP);
95 ADD_PROP(SIPE_BUDDY_INFO_OTHER_PHONE_DISPLAY , PHONE_OTHER_DISPLAY_PROP);
96 ADD_PROP(SIPE_BUDDY_INFO_CUSTOM1_PHONE , PHONE_CUSTOM1_PROP);
97 ADD_PROP(SIPE_BUDDY_INFO_CUSTOM1_PHONE_DISPLAY, PHONE_CUSTOM1_DISPLAY_PROP);
100 static gchar *
101 sipe_buddy_info_to_purple_property(sipe_buddy_info_fields info)
103 if (!info_to_property_table)
104 init_property_hash();
105 return g_hash_table_lookup(info_to_property_table, (gpointer)info);
108 sipe_backend_buddy sipe_backend_buddy_find(struct sipe_core_public *sipe_public,
109 const gchar *buddy_name,
110 const gchar *group_name)
112 struct sipe_backend_private *purple_private = sipe_public->backend_private;
113 PurpleGroup *purple_group;
115 if (group_name)
117 purple_group = purple_find_group(group_name);
118 if (!purple_group)
119 return NULL;
121 return purple_find_buddy_in_group(purple_private->account,
122 buddy_name,
123 purple_group);
124 } else {
125 return purple_find_buddy(purple_private->account,
126 buddy_name);
130 GSList* sipe_backend_buddy_find_all(struct sipe_core_public *sipe_public,
131 const gchar *buddy_name,
132 const gchar *group_name)
134 struct sipe_backend_private *purple_private = sipe_public->backend_private;
136 if (group_name)
138 SIPE_DEBUG_ERROR_NOFORMAT("Finding all buddies in a group not supported on purple");
139 return NULL;
142 return purple_find_buddies(purple_private->account, buddy_name);
145 gchar* sipe_backend_buddy_get_name(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
146 const sipe_backend_buddy who)
148 return g_strdup(((PurpleBuddy*)who)->name);
151 gchar* sipe_backend_buddy_get_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
152 const sipe_backend_buddy who)
154 return g_strdup(purple_buddy_get_alias(who));
157 gchar* sipe_backend_buddy_get_server_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
158 const sipe_backend_buddy who)
160 return g_strdup(purple_buddy_get_server_alias(who));
163 gchar *sipe_backend_buddy_get_local_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
164 const sipe_backend_buddy who)
166 return g_strdup(purple_buddy_get_local_alias(who));
169 gchar* sipe_backend_buddy_get_group_name(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
170 const sipe_backend_buddy who)
172 return g_strdup(purple_buddy_get_group((PurpleBuddy*)who)->name);
175 const gchar *sipe_backend_buddy_get_status(struct sipe_core_public *sipe_public,
176 const gchar *uri)
178 struct sipe_backend_private *purple_private = sipe_public->backend_private;
179 PurpleBuddy *pbuddy = purple_find_buddy(purple_private->account, uri);
180 const PurplePresence *presence = purple_buddy_get_presence(pbuddy);
181 const PurpleStatus *pstatus = purple_presence_get_active_status(presence);
182 return(purple_status_get_id(pstatus));
185 void sipe_backend_buddy_set_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
186 const sipe_backend_buddy who,
187 const gchar *alias)
189 purple_blist_alias_buddy(who, alias);
192 void sipe_backend_buddy_set_server_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
193 const sipe_backend_buddy who,
194 const gchar *alias)
196 purple_blist_server_alias_buddy(who, alias);
199 gchar* sipe_backend_buddy_get_string(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
200 sipe_backend_buddy buddy,
201 const sipe_buddy_info_fields key)
203 PurpleBuddy *b = (PurpleBuddy*) buddy;
204 return g_strdup(purple_blist_node_get_string(&b->node, sipe_buddy_info_to_purple_property(key)));
207 void sipe_backend_buddy_set_string(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
208 sipe_backend_buddy buddy,
209 const sipe_buddy_info_fields key,
210 const gchar *val)
212 PurpleBuddy *b = (PurpleBuddy*) buddy;
213 purple_blist_node_set_string(&b->node, sipe_buddy_info_to_purple_property(key), val);
216 sipe_backend_buddy sipe_backend_buddy_add(struct sipe_core_public *sipe_public,
217 const gchar *name,
218 const gchar *alias,
219 const gchar *groupname)
221 struct sipe_backend_private *purple_private = sipe_public->backend_private;
222 PurpleBuddy *b;
223 PurpleGroup *purple_group = purple_find_group(groupname);
225 if (!purple_group)
226 return NULL;
228 b = purple_buddy_new(purple_private->account, name, alias);
229 purple_blist_add_buddy(b, NULL, purple_group, NULL);
230 return b;
233 void sipe_backend_buddy_remove(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
234 const sipe_backend_buddy who)
236 purple_blist_remove_buddy(who);
239 void sipe_backend_buddy_request_authorization(struct sipe_core_public *sipe_public,
240 const gchar *who,
241 const gchar *alias,
242 gboolean on_list,
243 sipe_backend_buddy_request_authorization_cb auth_cb,
244 sipe_backend_buddy_request_authorization_cb deny_cb,
245 gpointer data)
247 struct sipe_backend_private *purple_private = sipe_public->backend_private;
249 purple_account_request_authorization(
250 purple_private->account,
251 who,
252 _("you"), /* id */
253 alias,
254 NULL, /* message */
255 on_list,
256 auth_cb,
257 deny_cb,
258 data);
262 void sipe_backend_buddy_request_add(struct sipe_core_public *sipe_public,
263 const gchar *who,
264 const gchar *alias)
266 struct sipe_backend_private *purple_private = sipe_public->backend_private;
268 purple_account_request_add(purple_private->account,
269 who,
270 _("you"),
271 alias,
272 NULL);
276 gboolean sipe_backend_buddy_is_blocked(struct sipe_core_public *sipe_public,
277 const gchar *who)
279 struct sipe_backend_private *purple_private = sipe_public->backend_private;
281 return !purple_privacy_check(purple_private->account, who);
284 void sipe_backend_buddy_set_blocked_status(struct sipe_core_public *sipe_public,
285 const gchar *who,
286 gboolean blocked)
288 struct sipe_backend_private *purple_private = sipe_public->backend_private;
290 if (blocked) {
291 purple_privacy_deny_add(purple_private->account, who, TRUE);
292 } else {
293 purple_privacy_deny_remove(purple_private->account, who, TRUE);
296 /* stupid workaround to make pidgin re-render screen to reflect our changes */
297 SIPE_DEBUG_INFO_NOFORMAT("sipe_backend_buddy_set_blocked_status: forcefully refreshing screen.");
298 sipe_core_buddy_got_status(sipe_public,
299 who,
300 sipe_backend_buddy_get_status(sipe_public,
301 who));
304 void sipe_backend_buddy_set_status(struct sipe_core_public *sipe_public,
305 const gchar *who,
306 const gchar *status_id)
308 struct sipe_backend_private *purple_private = sipe_public->backend_private;
310 purple_prpl_got_user_status(purple_private->account, who, status_id, NULL);
313 gboolean sipe_backend_buddy_group_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
314 const gchar *group_name)
316 PurpleGroup * purple_group = purple_find_group(group_name);
317 if (!purple_group) {
318 purple_group = purple_group_new(group_name);
319 purple_blist_add_group(purple_group, NULL);
322 return (purple_group != NULL);
325 struct sipe_backend_buddy_info *sipe_backend_buddy_info_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public)
327 return((struct sipe_backend_buddy_info *)purple_notify_user_info_new());
330 void sipe_backend_buddy_info_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
331 struct sipe_backend_buddy_info *info,
332 const gchar *description,
333 const gchar *value)
335 if (info) {
336 #if PURPLE_VERSION_CHECK(3,0,0)
337 purple_notify_user_info_add_pair_html
338 #else
339 purple_notify_user_info_add_pair
340 #endif
341 ((PurpleNotifyUserInfo *) info, description, value);
345 void sipe_backend_buddy_info_break(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
346 struct sipe_backend_buddy_info *info)
348 purple_notify_user_info_add_section_break((PurpleNotifyUserInfo *) info);
351 void sipe_backend_buddy_info_finalize(struct sipe_core_public *sipe_public,
352 struct sipe_backend_buddy_info *info,
353 const gchar *uri)
355 struct sipe_backend_private *purple_private = sipe_public->backend_private;
357 /* show a buddy's user info in a nice dialog box */
358 purple_notify_userinfo(purple_private->gc,
359 uri, /* buddy's URI */
360 (PurpleNotifyUserInfo *) info,
361 NULL, /* callback called when dialog closed */
362 NULL); /* userdata for callback */
365 void sipe_backend_buddy_tooltip_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
366 struct sipe_backend_buddy_tooltip *tooltip,
367 const gchar *description,
368 const gchar *value)
370 #if PURPLE_VERSION_CHECK(3,0,0)
371 purple_notify_user_info_add_pair_html
372 #else
373 purple_notify_user_info_add_pair
374 #endif
375 ((PurpleNotifyUserInfo *) tooltip, description, value);
378 void sipe_purple_add_buddy(PurpleConnection *gc,
379 PurpleBuddy *buddy,
380 PurpleGroup *group)
382 SIPE_DEBUG_INFO("sipe_purple_add_buddy[CB]: buddy:%s group:%s",
383 buddy ? buddy->name : "",
384 group ? group->name : "");
386 /* libpurple can call us with undefined buddy or group */
387 if (buddy && group) {
389 * Buddy name must be lower case as we use
390 * purple_normalize_nocase() to compare
392 gchar *buddy_name = g_ascii_strdown(buddy->name, -1);
393 gchar *uri = sip_uri(buddy_name);
394 g_free(buddy_name);
395 purple_blist_rename_buddy(buddy, uri);
396 g_free(uri);
398 sipe_core_buddy_add(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
399 buddy->name,
400 group->name);
404 void sipe_purple_remove_buddy(PurpleConnection *gc,
405 PurpleBuddy *buddy,
406 PurpleGroup *group)
408 SIPE_DEBUG_INFO("sipe_purple_remove_buddy[CB]: buddy:%s group:%s", buddy ? buddy->name : "", group ? group->name : "");
409 if (!buddy) return;
411 sipe_core_buddy_remove(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
412 buddy->name,
413 group ? group->name : NULL);
416 void sipe_purple_group_buddy(PurpleConnection *gc,
417 const char *who,
418 const char *old_group_name,
419 const char *new_group_name)
421 sipe_core_buddy_group(PURPLE_GC_TO_SIPE_CORE_PUBLIC, who, old_group_name, new_group_name);
424 /* Buddy Menu Handling */
426 static void sipe_purple_buddy_make_chat_leader_cb(PurpleBuddy *buddy,
427 gpointer parameter)
429 SIPE_DEBUG_INFO("sipe_purple_buddy_make_chat_leader_cb: buddy->name=%s",
430 buddy->name);
431 sipe_core_conf_make_leader(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
432 parameter,
433 buddy->name);
436 static void sipe_purple_buddy_remove_from_chat_cb(PurpleBuddy *buddy,
437 gpointer parameter)
439 SIPE_DEBUG_INFO("sipe_purple_buddy_remove_from_chat_cb: buddy->name=%s",
440 buddy->name);
441 sipe_core_conf_remove_from(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
442 parameter,
443 buddy->name);
446 static void sipe_purple_buddy_invite_to_chat_cb(PurpleBuddy *buddy,
447 gpointer parameter)
449 SIPE_DEBUG_INFO("sipe_purple_buddy_invite_to_chat_cb: buddy->name=%s",
450 buddy->name);
451 sipe_core_chat_invite(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
452 parameter,
453 buddy->name);
456 static void sipe_purple_buddy_new_chat_cb(PurpleBuddy *buddy,
457 SIPE_UNUSED_PARAMETER gpointer parameter)
459 SIPE_DEBUG_INFO("sipe_purple_buddy_new_chat_cb: buddy->name=%s",
460 buddy->name);
461 sipe_core_buddy_new_chat(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
462 buddy->name);
465 static void sipe_purple_buddy_make_call_cb(PurpleBuddy *buddy,
466 gpointer parameter)
468 SIPE_DEBUG_INFO("sipe_purple_buddy_make_call_cb: buddy->name=%s", buddy->name);
469 sipe_core_buddy_make_call(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
470 parameter);
473 static void sipe_purple_buddy_send_email_cb(PurpleBuddy *buddy,
474 SIPE_UNUSED_PARAMETER gpointer parameter)
476 SIPE_DEBUG_INFO("sipe_purple_buddy_send_email_cb: buddy->name=%s",
477 buddy->name);
478 sipe_core_buddy_send_email(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
479 buddy->name);
482 static void sipe_purple_buddy_access_level_help_cb(PurpleBuddy *buddy,
483 SIPE_UNUSED_PARAMETER gpointer parameter)
486 * Translators: replace with URL to localized page
487 * If it doesn't exist copy the original URL
489 purple_notify_uri(buddy->account->gc,
490 _("https://sourceforge.net/apps/mediawiki/sipe/index.php?title=Access_Levels"));
493 static void sipe_purple_buddy_change_access_level_cb(PurpleBuddy *buddy,
494 gpointer parameter)
496 sipe_core_change_access_level_from_container(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
497 parameter);
500 static void sipe_purple_ask_access_domain_cb(PurpleConnection *gc,
501 PurpleRequestFields *fields)
503 const gchar *domain = purple_request_fields_get_string(fields, "access_domain");
504 guint index = purple_request_fields_get_choice(fields, "container_id");
505 sipe_core_change_access_level_for_domain(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
506 domain,
507 index);
510 static void sipe_purple_buddy_add_new_domain_cb(PurpleBuddy *buddy,
511 SIPE_UNUSED_PARAMETER gpointer parameter)
513 PurpleConnection *gc = purple_account_get_connection(buddy->account);
514 PurpleRequestFields *fields;
515 PurpleRequestFieldGroup *g;
516 PurpleRequestField *f;
518 fields = purple_request_fields_new();
520 g = purple_request_field_group_new(NULL);
521 f = purple_request_field_string_new("access_domain",
522 _("Domain"),
523 "partner-company.com",
524 FALSE);
525 purple_request_field_set_required(f, TRUE);
526 purple_request_field_group_add_field(g, f);
528 f = purple_request_field_choice_new("container_id",
529 _("Access level"),
531 purple_request_field_choice_add(f, _("Personal")); /* index 0 */
532 purple_request_field_choice_add(f, _("Team"));
533 purple_request_field_choice_add(f, _("Company"));
534 purple_request_field_choice_add(f, _("Public"));
535 purple_request_field_choice_add(f, _("Blocked")); /* index 4 */
536 purple_request_field_choice_set_default_value(f, 3); /* index */
537 purple_request_field_set_required(f, TRUE);
538 purple_request_field_group_add_field(g, f);
540 purple_request_fields_add_group(fields, g);
542 purple_request_fields(gc, _("Add new domain"),
543 _("Add new domain"), NULL, fields,
544 _("Add"), G_CALLBACK(sipe_purple_ask_access_domain_cb),
545 _("Cancel"), NULL,
546 buddy->account, NULL, NULL, gc);
549 typedef void (*buddy_menu_callback)(PurpleBuddy *buddy,
550 gpointer parameter);
551 static const buddy_menu_callback callback_map[SIPE_BUDDY_MENU_TYPES] = {
552 /* SIPE_BUDDY_MENU_MAKE_CHAT_LEADER */ sipe_purple_buddy_make_chat_leader_cb,
553 /* SIPE_BUDDY_MENU_REMOVE_FROM_CHAT */ sipe_purple_buddy_remove_from_chat_cb,
554 /* SIPE_BUDDY_MENU_INVITE_TO_CHAT */ sipe_purple_buddy_invite_to_chat_cb,
555 /* SIPE_BUDDY_MENU_NEW_CHAT */ sipe_purple_buddy_new_chat_cb,
556 /* SIPE_BUDDY_MENU_MAKE_CALL */ sipe_purple_buddy_make_call_cb,
557 /* SIPE_BUDDY_MENU_SEND_EMAIL */ sipe_purple_buddy_send_email_cb,
558 /* SIPE_BUDDY_MENU_ACCESS_LEVEL_HELP */ sipe_purple_buddy_access_level_help_cb,
559 /* SIPE_BUDDY_MENU_CHANGE_ACCESS_LEVEL */ sipe_purple_buddy_change_access_level_cb,
560 /* SIPE_BUDDY_MENU_ADD_NEW_DOMAIN */ sipe_purple_buddy_add_new_domain_cb,
563 struct sipe_backend_buddy_menu *sipe_backend_buddy_menu_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public)
565 return(NULL);
568 struct sipe_backend_buddy_menu *sipe_backend_buddy_menu_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
569 struct sipe_backend_buddy_menu *menu,
570 const gchar *label,
571 enum sipe_buddy_menu_type type,
572 gpointer parameter)
574 return((struct sipe_backend_buddy_menu *)
575 g_list_prepend((GList *) menu,
576 purple_menu_action_new(label,
577 PURPLE_CALLBACK(callback_map[type]),
578 parameter, NULL)));
581 struct sipe_backend_buddy_menu *sipe_backend_buddy_menu_separator(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
582 struct sipe_backend_buddy_menu *menu,
583 const gchar *label)
585 return((struct sipe_backend_buddy_menu *)
586 g_list_prepend((GList *) menu,
587 purple_menu_action_new(label, NULL, NULL, NULL)));
590 struct sipe_backend_buddy_menu *sipe_backend_buddy_sub_menu_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
591 struct sipe_backend_buddy_menu *menu,
592 const gchar *label,
593 struct sipe_backend_buddy_menu *sub)
595 return((struct sipe_backend_buddy_menu *)
596 g_list_prepend((GList *) menu,
597 purple_menu_action_new(label,
598 NULL,
599 NULL,
600 g_list_reverse((GList *) sub))));
603 static void sipe_purple_buddy_copy_to_cb(PurpleBlistNode *node,
604 const gchar *group_name)
606 struct sipe_core_public *sipe_public;
607 PurpleBuddy *buddy = (PurpleBuddy *)node;
608 PurpleGroup *group;
609 PurpleBuddy *clone;
611 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
613 sipe_public = PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC;
614 group = purple_find_group(group_name);
616 SIPE_DEBUG_INFO("sipe_purple_buddy_copy_to_cb: copying %s to %s",
617 buddy->name, group_name);
619 clone = purple_find_buddy_in_group(buddy->account, buddy->name, group);
620 if (!clone) {
621 clone = sipe_backend_buddy_add(sipe_public,
622 buddy->name,
623 buddy->alias,
624 group->name);
625 if (clone) {
626 const gchar *tmp;
627 const gchar *key;
628 const PurpleStatus *status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
630 tmp = purple_buddy_get_server_alias(buddy);
631 if (tmp) purple_blist_server_alias_buddy(clone, tmp);
633 key = sipe_buddy_info_to_purple_property(SIPE_BUDDY_INFO_EMAIL);
634 tmp = purple_blist_node_get_string(&buddy->node, key);
635 if (tmp) purple_blist_node_set_string(&clone->node,
636 key,
637 tmp);
639 tmp = purple_status_get_id(status);
640 purple_presence_set_status_active(purple_buddy_get_presence(clone),
641 tmp,
642 TRUE);
644 /* update UI */
645 purple_prpl_got_user_status(clone->account,
646 clone->name,
647 tmp,
648 NULL);
652 if (clone && group)
653 sipe_core_buddy_add(sipe_public,
654 clone->name,
655 group->name);
658 static GList *sipe_purple_copy_to_menu(GList *menu,
659 PurpleBuddy *buddy)
661 GList *menu_groups = NULL;
662 PurpleGroup *gr_parent = purple_buddy_get_group(buddy);
663 PurpleBlistNode *g_node;
665 for (g_node = purple_blist_get_root(); g_node; g_node = g_node->next) {
666 PurpleGroup *group = (PurpleGroup *)g_node;
667 PurpleMenuAction *act;
669 if ((g_node->type != PURPLE_BLIST_GROUP_NODE) ||
670 (group == gr_parent) ||
671 purple_find_buddy_in_group(buddy->account,
672 buddy->name,
673 group))
674 continue;
676 act = purple_menu_action_new(purple_group_get_name(group),
677 PURPLE_CALLBACK(sipe_purple_buddy_copy_to_cb),
678 group->name, NULL);
679 menu_groups = g_list_prepend(menu_groups, act);
682 if (menu_groups)
683 menu = g_list_prepend(menu,
684 purple_menu_action_new(_("Copy to"),
685 NULL,
686 NULL,
687 g_list_reverse(menu_groups)));
689 return(menu);
692 GList *sipe_purple_buddy_menu(PurpleBuddy *buddy)
694 struct sipe_core_public *sipe_public = PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC;
695 GList *menu = (GList *) sipe_core_buddy_create_menu(sipe_public,
696 buddy->name,
697 NULL);
698 menu = sipe_purple_copy_to_menu(menu, buddy);
699 return(g_list_reverse(menu));
704 Local Variables:
705 mode: c
706 c-file-style: "bsd"
707 indent-tabs-mode: t
708 tab-width: 8
709 End: