6 * Copyright (C) 2010-2013 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
35 #include "sipe-common.h"
36 #include "sipe-backend.h"
37 #include "sipe-core.h"
40 #include "purple-private.h"
43 const gchar
*property
; /* property name to store in blist.xml */
44 const gchar
*description
; /* label for "Get Info" dialog */
45 } buddy_info_map
[] = {
46 /* SIPE_BUDDY_INFO_DISPLAY_NAME */ { "alias", N_("Display name") },
47 /* SIPE_BUDDY_INFO_JOB_TITLE */ { "title", N_("Job title") },
48 /* SIPE_BUDDY_INFO_CITY */ { "address-city", N_("City") },
49 /* SIPE_BUDDY_INFO_STATE */ { "address-state", N_("State") },
50 /* SIPE_BUDDY_INFO_OFFICE */ { "office", N_("Office") },
51 /* SIPE_BUDDY_INFO_DEPARTMENT */ { "department", NULL
},
52 /* SIPE_BUDDY_INFO_COUNTRY */ { "address-country-code", N_("Country") },
53 /* SIPE_BUDDY_INFO_WORK_PHONE */ { "phone", N_("Business phone") },
54 /* SIPE_BUDDY_INFO_WORK_PHONE_DISPLAY */ { "phone-display", NULL
},
55 /* SIPE_BUDDY_INFO_COMPANY */ { "company", N_("Company") },
56 /* SIPE_BUDDY_INFO_EMAIL */ { "email", N_("Email address") },
57 /* SIPE_BUDDY_INFO_SITE */ { "site", N_("Site") },
58 /* SIPE_BUDDY_INFO_ZIPCODE */ { "address-zipcode", NULL
},
59 /* SIPE_BUDDY_INFO_STREET */ { "address-street", NULL
},
60 /* SIPE_BUDDY_INFO_MOBILE_PHONE */ { "phone-mobile", NULL
},
61 /* SIPE_BUDDY_INFO_MOBILE_PHONE_DISPLAY */ { "phone-mobile-display", NULL
},
62 /* SIPE_BUDDY_INFO_HOME_PHONE */ { "phone-home", NULL
},
63 /* SIPE_BUDDY_INFO_HOME_PHONE_DISPLAY */ { "phone-home-display", NULL
},
64 /* SIPE_BUDDY_INFO_OTHER_PHONE */ { "phone-other", NULL
},
65 /* SIPE_BUDDY_INFO_OTHER_PHONE_DISPLAY */ { "phone-other-display", NULL
},
66 /* SIPE_BUDDY_INFO_CUSTOM1_PHONE */ { "phone-custom1", NULL
},
67 /* SIPE_BUDDY_INFO_CUSTOM1_PHONE_DISPLAY */ { "phone-custom1-display", NULL
},
68 /* SIPE_BUDDY_INFO_ALIAS */ { NULL
, N_("Alias") },
69 /* SIPE_BUDDY_INFO_DEVICE */ { NULL
, N_("Device") },
72 #define buddy_info_property(i) buddy_info_map[i].property
73 #define buddy_info_description(i) gettext(buddy_info_map[i].description)
75 sipe_backend_buddy
sipe_backend_buddy_find(struct sipe_core_public
*sipe_public
,
76 const gchar
*buddy_name
,
77 const gchar
*group_name
)
79 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
80 PurpleGroup
*purple_group
;
84 purple_group
= purple_find_group(group_name
);
88 return purple_find_buddy_in_group(purple_private
->account
,
92 return purple_find_buddy(purple_private
->account
,
97 GSList
* sipe_backend_buddy_find_all(struct sipe_core_public
*sipe_public
,
98 const gchar
*buddy_name
,
99 const gchar
*group_name
)
101 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
105 SIPE_DEBUG_ERROR_NOFORMAT("Finding all buddies in a group not supported on purple");
109 return purple_find_buddies(purple_private
->account
, buddy_name
);
112 gchar
* sipe_backend_buddy_get_name(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
113 const sipe_backend_buddy who
)
115 return g_strdup(((PurpleBuddy
*)who
)->name
);
118 gchar
* sipe_backend_buddy_get_alias(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
119 const sipe_backend_buddy who
)
121 return g_strdup(purple_buddy_get_alias(who
));
124 gchar
* sipe_backend_buddy_get_server_alias(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
125 const sipe_backend_buddy who
)
127 return g_strdup(purple_buddy_get_server_alias(who
));
130 gchar
*sipe_backend_buddy_get_local_alias(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
131 const sipe_backend_buddy who
)
134 #if PURPLE_VERSION_CHECK(2,6,0) || PURPLE_VERSION_CHECK(3,0,0)
135 purple_buddy_get_local_buddy_alias
137 purple_buddy_get_local_alias
142 gchar
* sipe_backend_buddy_get_group_name(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
143 const sipe_backend_buddy who
)
145 return g_strdup(purple_buddy_get_group((PurpleBuddy
*)who
)->name
);
148 guint
sipe_backend_buddy_get_status(struct sipe_core_public
*sipe_public
,
151 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
152 PurpleBuddy
*pbuddy
= purple_find_buddy(purple_private
->account
, uri
);
153 const PurplePresence
*presence
= purple_buddy_get_presence(pbuddy
);
154 const PurpleStatus
*pstatus
= purple_presence_get_active_status(presence
);
155 return(sipe_purple_token_to_activity(purple_status_get_id(pstatus
)));
158 void sipe_backend_buddy_set_alias(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
159 const sipe_backend_buddy who
,
162 purple_blist_alias_buddy(who
, alias
);
165 void sipe_backend_buddy_set_server_alias(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
166 const sipe_backend_buddy who
,
169 purple_blist_server_alias_buddy(who
, alias
);
172 gchar
* sipe_backend_buddy_get_string(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
173 sipe_backend_buddy buddy
,
174 const sipe_buddy_info_fields key
)
176 PurpleBuddy
*b
= (PurpleBuddy
*) buddy
;
177 return g_strdup(purple_blist_node_get_string(&b
->node
, buddy_info_property(key
)));
180 void sipe_backend_buddy_set_string(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
181 sipe_backend_buddy buddy
,
182 const sipe_buddy_info_fields key
,
185 PurpleBuddy
*b
= (PurpleBuddy
*) buddy
;
186 purple_blist_node_set_string(&b
->node
, buddy_info_property(key
), val
);
189 void sipe_backend_buddy_refresh_properties(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
190 SIPE_UNUSED_PARAMETER
const gchar
*uri
)
192 /* nothing to do here: already taken care of by libpurple */
195 void sipe_backend_buddy_list_processing_start(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
)
199 void sipe_backend_buddy_list_processing_finish(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
)
203 sipe_backend_buddy
sipe_backend_buddy_add(struct sipe_core_public
*sipe_public
,
206 const gchar
*groupname
)
208 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
210 PurpleGroup
*purple_group
= purple_find_group(groupname
);
215 b
= purple_buddy_new(purple_private
->account
, name
, alias
);
216 purple_blist_add_buddy(b
, NULL
, purple_group
, NULL
);
220 void sipe_backend_buddy_remove(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
221 const sipe_backend_buddy who
)
223 purple_blist_remove_buddy(who
);
226 void sipe_backend_buddy_request_authorization(struct sipe_core_public
*sipe_public
,
230 sipe_backend_buddy_request_authorization_cb auth_cb
,
231 sipe_backend_buddy_request_authorization_cb deny_cb
,
234 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
236 purple_account_request_authorization(
237 purple_private
->account
,
243 (PurpleAccountRequestAuthorizationCb
) auth_cb
,
244 (PurpleAccountRequestAuthorizationCb
) deny_cb
,
249 void sipe_backend_buddy_request_add(struct sipe_core_public
*sipe_public
,
253 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
255 purple_account_request_add(purple_private
->account
,
263 gboolean
sipe_backend_buddy_is_blocked(struct sipe_core_public
*sipe_public
,
266 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
268 return !purple_privacy_check(purple_private
->account
, who
);
271 void sipe_backend_buddy_set_blocked_status(struct sipe_core_public
*sipe_public
,
275 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
278 purple_privacy_deny_add(purple_private
->account
, who
, TRUE
);
280 purple_privacy_deny_remove(purple_private
->account
, who
, TRUE
);
283 /* stupid workaround to make pidgin re-render screen to reflect our changes */
284 SIPE_DEBUG_INFO_NOFORMAT("sipe_backend_buddy_set_blocked_status: forcefully refreshing screen.");
285 sipe_core_buddy_got_status(sipe_public
,
287 sipe_backend_buddy_get_status(sipe_public
,
291 void sipe_backend_buddy_set_status(struct sipe_core_public
*sipe_public
,
295 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
297 purple_prpl_got_user_status(purple_private
->account
, who
,
298 sipe_purple_activity_to_token(activity
),
302 gboolean
sipe_backend_uses_photo(void)
307 void sipe_backend_buddy_set_photo(struct sipe_core_public
*sipe_public
,
311 const gchar
*photo_hash
)
313 PurpleAccount
*account
= sipe_public
->backend_private
->account
;
315 purple_buddy_icons_set_for_user(account
, who
, photo_data
,
316 data_len
, photo_hash
);
319 const gchar
*sipe_backend_buddy_get_photo_hash(struct sipe_core_public
*sipe_public
,
322 PurpleAccount
*account
= sipe_public
->backend_private
->account
;
323 const gchar
*result
= NULL
;
325 PurpleBuddyIcon
*icon
= purple_buddy_icons_find(account
, who
);
327 result
= purple_buddy_icon_get_checksum(icon
);
328 purple_buddy_icon_unref(icon
);
334 gboolean
sipe_backend_buddy_group_add(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
335 const gchar
*group_name
)
337 PurpleGroup
* purple_group
= purple_find_group(group_name
);
339 purple_group
= purple_group_new(group_name
);
340 purple_blist_add_group(purple_group
, NULL
);
343 return (purple_group
!= NULL
);
346 gboolean
sipe_backend_buddy_group_rename(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
347 const gchar
*old_name
,
348 const gchar
*new_name
)
350 PurpleGroup
*purple_group
= purple_find_group(old_name
);
352 purple_blist_rename_group(purple_group
, new_name
);
353 return(purple_group
!= NULL
);
356 void sipe_backend_buddy_group_remove(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
357 const gchar
*group_name
)
359 PurpleGroup
*purple_group
= purple_find_group(group_name
);
361 purple_blist_remove_group(purple_group
);
364 struct sipe_backend_buddy_info
*sipe_backend_buddy_info_start(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
)
366 return((struct sipe_backend_buddy_info
*)purple_notify_user_info_new());
369 void sipe_backend_buddy_info_add(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
370 struct sipe_backend_buddy_info
*info
,
371 sipe_buddy_info_fields key
,
375 #if PURPLE_VERSION_CHECK(3,0,0)
376 purple_notify_user_info_add_pair_html
378 purple_notify_user_info_add_pair
380 ((PurpleNotifyUserInfo
*) info
,
381 buddy_info_description(key
),
386 void sipe_backend_buddy_info_break(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
387 struct sipe_backend_buddy_info
*info
)
389 purple_notify_user_info_add_section_break((PurpleNotifyUserInfo
*) info
);
392 void sipe_backend_buddy_info_finalize(struct sipe_core_public
*sipe_public
,
393 struct sipe_backend_buddy_info
*info
,
396 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
398 /* show a buddy's user info in a nice dialog box */
399 purple_notify_userinfo(purple_private
->gc
,
400 uri
, /* buddy's URI */
401 (PurpleNotifyUserInfo
*) info
,
402 NULL
, /* callback called when dialog closed */
403 NULL
); /* userdata for callback */
406 void sipe_backend_buddy_tooltip_add(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
407 struct sipe_backend_buddy_tooltip
*tooltip
,
408 const gchar
*description
,
411 #if PURPLE_VERSION_CHECK(3,0,0)
412 purple_notify_user_info_add_pair_html
414 purple_notify_user_info_add_pair
416 ((PurpleNotifyUserInfo
*) tooltip
, description
, value
);
419 void sipe_purple_add_buddy(PurpleConnection
*gc
,
422 #if PURPLE_VERSION_CHECK(3,0,0)
423 , SIPE_UNUSED_PARAMETER
const gchar
*message
427 SIPE_DEBUG_INFO("sipe_purple_add_buddy[CB]: buddy:%s group:%s",
428 buddy
? buddy
->name
: "",
429 group
? group
->name
: "");
431 /* libpurple can call us with undefined buddy or group */
432 if (buddy
&& group
) {
434 * Buddy name must be lower case as we use
435 * purple_normalize_nocase() to compare
437 gchar
*buddy_name
= g_ascii_strdown(buddy
->name
, -1);
438 gchar
*uri
= sip_uri_if_valid(buddy_name
);
442 purple_blist_rename_buddy(buddy
, uri
);
445 sipe_core_buddy_add(PURPLE_GC_TO_SIPE_CORE_PUBLIC
,
449 SIPE_DEBUG_ERROR_NOFORMAT("sipe_purple_add_buddy[CB]: buddy name is invalid for URI");
450 purple_blist_remove_buddy(buddy
);
451 purple_notify_error(gc
, NULL
,
452 _("User name should be a valid SIP URI\nExample: user@company.com"),
458 void sipe_purple_remove_buddy(PurpleConnection
*gc
,
462 SIPE_DEBUG_INFO("sipe_purple_remove_buddy[CB]: buddy:%s group:%s", buddy
? buddy
->name
: "", group
? group
->name
: "");
465 sipe_core_buddy_remove(PURPLE_GC_TO_SIPE_CORE_PUBLIC
,
467 group
? group
->name
: NULL
);
470 void sipe_purple_group_buddy(PurpleConnection
*gc
,
472 const char *old_group_name
,
473 const char *new_group_name
)
475 sipe_core_buddy_group(PURPLE_GC_TO_SIPE_CORE_PUBLIC
, who
, old_group_name
, new_group_name
);
478 /* Buddy Menu Handling */
480 static void sipe_purple_buddy_make_chat_leader_cb(PurpleBuddy
*buddy
,
483 SIPE_DEBUG_INFO("sipe_purple_buddy_make_chat_leader_cb: buddy->name=%s",
485 sipe_core_conf_make_leader(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
490 static void sipe_purple_buddy_remove_from_chat_cb(PurpleBuddy
*buddy
,
493 SIPE_DEBUG_INFO("sipe_purple_buddy_remove_from_chat_cb: buddy->name=%s",
495 sipe_core_conf_remove_from(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
500 static void sipe_purple_buddy_invite_to_chat_cb(PurpleBuddy
*buddy
,
503 SIPE_DEBUG_INFO("sipe_purple_buddy_invite_to_chat_cb: buddy->name=%s",
505 sipe_core_chat_invite(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
510 static void sipe_purple_buddy_new_chat_cb(PurpleBuddy
*buddy
,
511 SIPE_UNUSED_PARAMETER gpointer parameter
)
513 SIPE_DEBUG_INFO("sipe_purple_buddy_new_chat_cb: buddy->name=%s",
515 sipe_core_buddy_new_chat(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
519 static void sipe_purple_buddy_make_call_cb(PurpleBuddy
*buddy
,
522 SIPE_DEBUG_INFO("sipe_purple_buddy_make_call_cb: buddy->name=%s", buddy
->name
);
523 sipe_core_buddy_make_call(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
527 static void sipe_purple_buddy_send_email_cb(PurpleBuddy
*buddy
,
528 SIPE_UNUSED_PARAMETER gpointer parameter
)
530 SIPE_DEBUG_INFO("sipe_purple_buddy_send_email_cb: buddy->name=%s",
532 sipe_core_buddy_send_email(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
536 static void sipe_purple_buddy_access_level_help_cb(PurpleBuddy
*buddy
,
537 SIPE_UNUSED_PARAMETER gpointer parameter
)
540 * Translators: replace with URL to localized page
541 * If it doesn't exist copy the original URL
543 purple_notify_uri(buddy
->account
->gc
,
544 _("https://sourceforge.net/apps/mediawiki/sipe/index.php?title=Access_Levels"));
547 static void sipe_purple_buddy_change_access_level_cb(PurpleBuddy
*buddy
,
550 sipe_core_change_access_level_from_container(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
554 static void sipe_purple_ask_access_domain_cb(PurpleConnection
*gc
,
555 PurpleRequestFields
*fields
)
557 const gchar
*domain
= purple_request_fields_get_string(fields
, "access_domain");
558 guint index
= purple_request_fields_get_choice(fields
, "container_id");
559 sipe_core_change_access_level_for_domain(PURPLE_GC_TO_SIPE_CORE_PUBLIC
,
564 static void sipe_purple_buddy_add_new_domain_cb(PurpleBuddy
*buddy
,
565 SIPE_UNUSED_PARAMETER gpointer parameter
)
567 PurpleConnection
*gc
= purple_account_get_connection(buddy
->account
);
568 PurpleRequestFields
*fields
;
569 PurpleRequestFieldGroup
*g
;
570 PurpleRequestField
*f
;
572 fields
= purple_request_fields_new();
574 g
= purple_request_field_group_new(NULL
);
575 f
= purple_request_field_string_new("access_domain",
577 "partner-company.com",
579 purple_request_field_set_required(f
, TRUE
);
580 purple_request_field_group_add_field(g
, f
);
582 f
= purple_request_field_choice_new("container_id",
585 purple_request_field_choice_add(f
, _("Personal")); /* index 0 */
586 purple_request_field_choice_add(f
, _("Team"));
587 purple_request_field_choice_add(f
, _("Company"));
588 purple_request_field_choice_add(f
, _("Public"));
589 purple_request_field_choice_add(f
, _("Blocked")); /* index 4 */
590 purple_request_field_choice_set_default_value(f
, 3); /* index */
591 purple_request_field_set_required(f
, TRUE
);
592 purple_request_field_group_add_field(g
, f
);
594 purple_request_fields_add_group(fields
, g
);
596 purple_request_fields(gc
, _("Add new domain"),
597 _("Add new domain"), NULL
, fields
,
598 _("Add"), G_CALLBACK(sipe_purple_ask_access_domain_cb
),
600 buddy
->account
, NULL
, NULL
, gc
);
603 typedef void (*buddy_menu_callback
)(PurpleBuddy
*buddy
,
605 static const buddy_menu_callback callback_map
[SIPE_BUDDY_MENU_TYPES
] = {
606 /* SIPE_BUDDY_MENU_MAKE_CHAT_LEADER */ sipe_purple_buddy_make_chat_leader_cb
,
607 /* SIPE_BUDDY_MENU_REMOVE_FROM_CHAT */ sipe_purple_buddy_remove_from_chat_cb
,
608 /* SIPE_BUDDY_MENU_INVITE_TO_CHAT */ sipe_purple_buddy_invite_to_chat_cb
,
609 /* SIPE_BUDDY_MENU_NEW_CHAT */ sipe_purple_buddy_new_chat_cb
,
610 /* SIPE_BUDDY_MENU_MAKE_CALL */ sipe_purple_buddy_make_call_cb
,
611 /* SIPE_BUDDY_MENU_SEND_EMAIL */ sipe_purple_buddy_send_email_cb
,
612 /* SIPE_BUDDY_MENU_ACCESS_LEVEL_HELP */ sipe_purple_buddy_access_level_help_cb
,
613 /* SIPE_BUDDY_MENU_CHANGE_ACCESS_LEVEL */ sipe_purple_buddy_change_access_level_cb
,
614 /* SIPE_BUDDY_MENU_ADD_NEW_DOMAIN */ sipe_purple_buddy_add_new_domain_cb
,
617 struct sipe_backend_buddy_menu
*sipe_backend_buddy_menu_start(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
)
622 struct sipe_backend_buddy_menu
*sipe_backend_buddy_menu_add(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
623 struct sipe_backend_buddy_menu
*menu
,
625 enum sipe_buddy_menu_type type
,
628 return((struct sipe_backend_buddy_menu
*)
629 g_list_prepend((GList
*) menu
,
630 purple_menu_action_new(label
,
631 PURPLE_CALLBACK(callback_map
[type
]),
635 struct sipe_backend_buddy_menu
*sipe_backend_buddy_menu_separator(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
636 struct sipe_backend_buddy_menu
*menu
,
639 return((struct sipe_backend_buddy_menu
*)
640 g_list_prepend((GList
*) menu
,
641 purple_menu_action_new(label
, NULL
, NULL
, NULL
)));
644 struct sipe_backend_buddy_menu
*sipe_backend_buddy_sub_menu_add(SIPE_UNUSED_PARAMETER
struct sipe_core_public
*sipe_public
,
645 struct sipe_backend_buddy_menu
*menu
,
647 struct sipe_backend_buddy_menu
*sub
)
649 return((struct sipe_backend_buddy_menu
*)
650 g_list_prepend((GList
*) menu
,
651 purple_menu_action_new(label
,
654 g_list_reverse((GList
*) sub
))));
657 static void sipe_purple_buddy_copy_to_cb(PurpleBlistNode
*node
,
658 const gchar
*group_name
)
660 struct sipe_core_public
*sipe_public
;
661 PurpleBuddy
*buddy
= (PurpleBuddy
*)node
;
665 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node
));
667 sipe_public
= PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
;
668 group
= purple_find_group(group_name
);
670 SIPE_DEBUG_INFO("sipe_purple_buddy_copy_to_cb: copying %s to %s",
671 buddy
->name
, group_name
);
673 clone
= purple_find_buddy_in_group(buddy
->account
, buddy
->name
, group
);
675 clone
= sipe_backend_buddy_add(sipe_public
,
682 const PurpleStatus
*status
= purple_presence_get_active_status(purple_buddy_get_presence(buddy
));
684 tmp
= purple_buddy_get_server_alias(buddy
);
685 if (tmp
) purple_blist_server_alias_buddy(clone
, tmp
);
687 key
= buddy_info_property(SIPE_BUDDY_INFO_EMAIL
);
688 tmp
= purple_blist_node_get_string(&buddy
->node
, key
);
689 if (tmp
) purple_blist_node_set_string(&clone
->node
,
693 tmp
= purple_status_get_id(status
);
694 purple_presence_set_status_active(purple_buddy_get_presence(clone
),
699 purple_prpl_got_user_status(clone
->account
,
707 sipe_core_buddy_add(sipe_public
,
712 static GList
*sipe_purple_copy_to_menu(GList
*menu
,
715 GList
*menu_groups
= NULL
;
716 PurpleGroup
*gr_parent
= purple_buddy_get_group(buddy
);
717 PurpleBlistNode
*g_node
;
719 for (g_node
= purple_blist_get_root(); g_node
; g_node
= g_node
->next
) {
720 PurpleGroup
*group
= (PurpleGroup
*)g_node
;
721 PurpleMenuAction
*act
;
723 if ((g_node
->type
!= PURPLE_BLIST_GROUP_NODE
) ||
724 (group
== gr_parent
) ||
725 purple_find_buddy_in_group(buddy
->account
,
730 act
= purple_menu_action_new(purple_group_get_name(group
),
731 PURPLE_CALLBACK(sipe_purple_buddy_copy_to_cb
),
733 menu_groups
= g_list_prepend(menu_groups
, act
);
737 menu
= g_list_prepend(menu
,
738 purple_menu_action_new(_("Copy to"),
741 g_list_reverse(menu_groups
)));
746 GList
*sipe_purple_buddy_menu(PurpleBuddy
*buddy
)
748 struct sipe_core_public
*sipe_public
= PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
;
749 GList
*menu
= (GList
*) sipe_core_buddy_create_menu(sipe_public
,
752 menu
= sipe_purple_copy_to_menu(menu
, buddy
);
753 return(g_list_reverse(menu
));