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
29 #include "purple-private.h"
37 #include "sipe-common.h"
38 #include "sipe-backend.h"
39 #include "sipe-core.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)
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
);
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
;
117 purple_group
= purple_find_group(group_name
);
121 return purple_find_buddy_in_group(purple_private
->account
,
125 return purple_find_buddy(purple_private
->account
,
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
;
138 SIPE_DEBUG_ERROR_NOFORMAT("Finding all buddies in a group not supported on purple");
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
,
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
,
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
,
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
,
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
,
219 const gchar
*groupname
)
221 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
223 PurpleGroup
*purple_group
= purple_find_group(groupname
);
228 b
= purple_buddy_new(purple_private
->account
, name
, alias
);
229 purple_blist_add_buddy(b
, NULL
, purple_group
, NULL
);
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
,
243 sipe_backend_buddy_request_authorization_cb auth_cb
,
244 sipe_backend_buddy_request_authorization_cb deny_cb
,
247 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
249 purple_account_request_authorization(
250 purple_private
->account
,
262 void sipe_backend_buddy_request_add(struct sipe_core_public
*sipe_public
,
266 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
268 purple_account_request_add(purple_private
->account
,
276 gboolean
sipe_backend_buddy_is_blocked(struct sipe_core_public
*sipe_public
,
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
,
288 struct sipe_backend_private
*purple_private
= sipe_public
->backend_private
;
291 purple_privacy_deny_add(purple_private
->account
, who
, TRUE
);
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
,
300 sipe_backend_buddy_get_status(sipe_public
,
304 void sipe_backend_buddy_set_status(struct sipe_core_public
*sipe_public
,
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
);
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
,
336 #if PURPLE_VERSION_CHECK(3,0,0)
337 purple_notify_user_info_add_pair_html
339 purple_notify_user_info_add_pair
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
,
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
,
370 #if PURPLE_VERSION_CHECK(3,0,0)
371 purple_notify_user_info_add_pair_html
373 purple_notify_user_info_add_pair
375 ((PurpleNotifyUserInfo
*) tooltip
, description
, value
);
378 void sipe_purple_add_buddy(PurpleConnection
*gc
,
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
);
395 purple_blist_rename_buddy(buddy
, uri
);
398 sipe_core_buddy_add(PURPLE_GC_TO_SIPE_CORE_PUBLIC
,
404 void sipe_purple_remove_buddy(PurpleConnection
*gc
,
408 SIPE_DEBUG_INFO("sipe_purple_remove_buddy[CB]: buddy:%s group:%s", buddy
? buddy
->name
: "", group
? group
->name
: "");
411 sipe_core_buddy_remove(PURPLE_GC_TO_SIPE_CORE_PUBLIC
,
413 group
? group
->name
: NULL
);
416 void sipe_purple_group_buddy(PurpleConnection
*gc
,
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
,
429 SIPE_DEBUG_INFO("sipe_purple_buddy_make_chat_leader_cb: buddy->name=%s",
431 sipe_core_conf_make_leader(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
436 static void sipe_purple_buddy_remove_from_chat_cb(PurpleBuddy
*buddy
,
439 SIPE_DEBUG_INFO("sipe_purple_buddy_remove_from_chat_cb: buddy->name=%s",
441 sipe_core_conf_remove_from(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
446 static void sipe_purple_buddy_invite_to_chat_cb(PurpleBuddy
*buddy
,
449 SIPE_DEBUG_INFO("sipe_purple_buddy_invite_to_chat_cb: buddy->name=%s",
451 sipe_core_chat_invite(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
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",
461 sipe_core_buddy_new_chat(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
465 static void sipe_purple_buddy_make_call_cb(PurpleBuddy
*buddy
,
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
,
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",
478 sipe_core_buddy_send_email(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
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
,
496 sipe_core_change_access_level_from_container(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC
,
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
,
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",
523 "partner-company.com",
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",
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
),
546 buddy
->account
, NULL
, NULL
, gc
);
549 typedef void (*buddy_menu_callback
)(PurpleBuddy
*buddy
,
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
)
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
,
571 enum sipe_buddy_menu_type type
,
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
]),
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
,
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
,
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
,
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
;
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
);
621 clone
= sipe_backend_buddy_add(sipe_public
,
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
,
639 tmp
= purple_status_get_id(status
);
640 purple_presence_set_status_active(purple_buddy_get_presence(clone
),
645 purple_prpl_got_user_status(clone
->account
,
653 sipe_core_buddy_add(sipe_public
,
658 static GList
*sipe_purple_copy_to_menu(GList
*menu
,
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
,
676 act
= purple_menu_action_new(purple_group_get_name(group
),
677 PURPLE_CALLBACK(sipe_purple_buddy_copy_to_cb
),
679 menu_groups
= g_list_prepend(menu_groups
, act
);
683 menu
= g_list_prepend(menu
,
684 purple_menu_action_new(_("Copy to"),
687 g_list_reverse(menu_groups
)));
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
,
698 menu
= sipe_purple_copy_to_menu(menu
, buddy
);
699 return(g_list_reverse(menu
));