core cleanup: start on the access levels control menu
[siplcs.git] / src / purple / purple-buddy.c
blobcfe370c270dcad32d07e2ad6458cbb43352dadcb
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 "version.h"
36 #include "sipe-common.h"
37 #include "sipe-backend.h"
38 #include "sipe-core.h"
39 #include "sipe-nls.h"
41 static GHashTable *info_to_property_table = NULL;
43 /** Property names to store in blist.xml */
44 #define ALIAS_PROP "alias"
45 #define EMAIL_PROP "email"
46 #define PHONE_PROP "phone"
47 #define PHONE_DISPLAY_PROP "phone-display"
48 #define PHONE_MOBILE_PROP "phone-mobile"
49 #define PHONE_MOBILE_DISPLAY_PROP "phone-mobile-display"
50 #define PHONE_HOME_PROP "phone-home"
51 #define PHONE_HOME_DISPLAY_PROP "phone-home-display"
52 #define PHONE_OTHER_PROP "phone-other"
53 #define PHONE_OTHER_DISPLAY_PROP "phone-other-display"
54 #define PHONE_CUSTOM1_PROP "phone-custom1"
55 #define PHONE_CUSTOM1_DISPLAY_PROP "phone-custom1-display"
56 #define SITE_PROP "site"
57 #define COMPANY_PROP "company"
58 #define DEPARTMENT_PROP "department"
59 #define TITLE_PROP "title"
60 #define OFFICE_PROP "office"
61 /** implies work address */
62 #define ADDRESS_STREET_PROP "address-street"
63 #define ADDRESS_CITY_PROP "address-city"
64 #define ADDRESS_STATE_PROP "address-state"
65 #define ADDRESS_ZIPCODE_PROP "address-zipcode"
66 #define ADDRESS_COUNTRYCODE_PROP "address-country-code"
68 #define ADD_PROP(key,value) g_hash_table_insert(info_to_property_table, (gpointer)key, value)
70 static void
71 init_property_hash(void)
73 info_to_property_table = g_hash_table_new(NULL, NULL);
75 ADD_PROP(SIPE_BUDDY_INFO_DISPLAY_NAME , ALIAS_PROP);
76 ADD_PROP(SIPE_BUDDY_INFO_EMAIL , EMAIL_PROP);
77 ADD_PROP(SIPE_BUDDY_INFO_WORK_PHONE , PHONE_PROP);
78 ADD_PROP(SIPE_BUDDY_INFO_WORK_PHONE_DISPLAY , PHONE_DISPLAY_PROP);
79 ADD_PROP(SIPE_BUDDY_INFO_SITE , SITE_PROP);
80 ADD_PROP(SIPE_BUDDY_INFO_COMPANY , COMPANY_PROP);
81 ADD_PROP(SIPE_BUDDY_INFO_DEPARTMENT , DEPARTMENT_PROP);
82 ADD_PROP(SIPE_BUDDY_INFO_JOB_TITLE , TITLE_PROP);
83 ADD_PROP(SIPE_BUDDY_INFO_OFFICE , OFFICE_PROP);
84 ADD_PROP(SIPE_BUDDY_INFO_STREET , ADDRESS_STREET_PROP);
85 ADD_PROP(SIPE_BUDDY_INFO_CITY , ADDRESS_CITY_PROP);
86 ADD_PROP(SIPE_BUDDY_INFO_STATE , ADDRESS_STATE_PROP);
87 ADD_PROP(SIPE_BUDDY_INFO_ZIPCODE , ADDRESS_ZIPCODE_PROP);
88 ADD_PROP(SIPE_BUDDY_INFO_COUNTRY , ADDRESS_COUNTRYCODE_PROP);
89 ADD_PROP(SIPE_BUDDY_INFO_MOBILE_PHONE , PHONE_MOBILE_PROP);
90 ADD_PROP(SIPE_BUDDY_INFO_MOBILE_PHONE_DISPLAY , PHONE_MOBILE_DISPLAY_PROP);
91 ADD_PROP(SIPE_BUDDY_INFO_HOME_PHONE , PHONE_HOME_PROP);
92 ADD_PROP(SIPE_BUDDY_INFO_HOME_PHONE_DISPLAY , PHONE_HOME_DISPLAY_PROP);
93 ADD_PROP(SIPE_BUDDY_INFO_OTHER_PHONE , PHONE_OTHER_PROP);
94 ADD_PROP(SIPE_BUDDY_INFO_OTHER_PHONE_DISPLAY , PHONE_OTHER_DISPLAY_PROP);
95 ADD_PROP(SIPE_BUDDY_INFO_CUSTOM1_PHONE , PHONE_CUSTOM1_PROP);
96 ADD_PROP(SIPE_BUDDY_INFO_CUSTOM1_PHONE_DISPLAY, PHONE_CUSTOM1_DISPLAY_PROP);
99 static gchar *
100 sipe_buddy_info_to_purple_property(sipe_buddy_info_fields info)
102 if (!info_to_property_table)
103 init_property_hash();
104 return g_hash_table_lookup(info_to_property_table, (gpointer)info);
107 sipe_backend_buddy sipe_backend_buddy_find(struct sipe_core_public *sipe_public,
108 const gchar *buddy_name,
109 const gchar *group_name)
111 struct sipe_backend_private *purple_private = sipe_public->backend_private;
112 PurpleGroup *purple_group;
114 if (group_name)
116 purple_group = purple_find_group(group_name);
117 if (!purple_group)
118 return NULL;
120 return purple_find_buddy_in_group(purple_private->account,
121 buddy_name,
122 purple_group);
123 } else {
124 return purple_find_buddy(purple_private->account,
125 buddy_name);
129 GSList* sipe_backend_buddy_find_all(struct sipe_core_public *sipe_public,
130 const gchar *buddy_name,
131 const gchar *group_name)
133 struct sipe_backend_private *purple_private = sipe_public->backend_private;
135 if (group_name)
137 SIPE_DEBUG_ERROR_NOFORMAT("Finding all buddies in a group not supported on purple");
138 return NULL;
141 return purple_find_buddies(purple_private->account, buddy_name);
144 gchar* sipe_backend_buddy_get_name(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
145 const sipe_backend_buddy who)
147 return g_strdup(((PurpleBuddy*)who)->name);
150 gchar* sipe_backend_buddy_get_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
151 const sipe_backend_buddy who)
153 return g_strdup(purple_buddy_get_alias(who));
156 gchar* sipe_backend_buddy_get_server_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
157 const sipe_backend_buddy who)
159 return g_strdup(purple_buddy_get_server_alias(who));
162 gchar *sipe_backend_buddy_get_local_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
163 const sipe_backend_buddy who)
165 return g_strdup(purple_buddy_get_local_alias(who));
168 gchar* sipe_backend_buddy_get_group_name(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
169 const sipe_backend_buddy who)
171 return g_strdup(purple_buddy_get_group((PurpleBuddy*)who)->name);
174 const gchar *sipe_backend_buddy_get_status(struct sipe_core_public *sipe_public,
175 const gchar *uri)
177 struct sipe_backend_private *purple_private = sipe_public->backend_private;
178 PurpleBuddy *pbuddy = purple_find_buddy(purple_private->account, uri);
179 const PurplePresence *presence = purple_buddy_get_presence(pbuddy);
180 const PurpleStatus *pstatus = purple_presence_get_active_status(presence);
181 return(purple_status_get_id(pstatus));
184 void sipe_backend_buddy_set_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
185 const sipe_backend_buddy who,
186 const gchar *alias)
188 purple_blist_alias_buddy(who, alias);
191 void sipe_backend_buddy_set_server_alias(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
192 const sipe_backend_buddy who,
193 const gchar *alias)
195 purple_blist_server_alias_buddy(who, alias);
198 gchar* sipe_backend_buddy_get_string(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
199 sipe_backend_buddy buddy,
200 const sipe_buddy_info_fields key)
202 PurpleBuddy *b = (PurpleBuddy*) buddy;
203 return g_strdup(purple_blist_node_get_string(&b->node, sipe_buddy_info_to_purple_property(key)));
206 void sipe_backend_buddy_set_string(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
207 sipe_backend_buddy buddy,
208 const sipe_buddy_info_fields key,
209 const gchar *val)
211 PurpleBuddy *b = (PurpleBuddy*) buddy;
212 purple_blist_node_set_string(&b->node, sipe_buddy_info_to_purple_property(key), val);
215 sipe_backend_buddy sipe_backend_buddy_add(struct sipe_core_public *sipe_public,
216 const gchar *name,
217 const gchar *alias,
218 const gchar *groupname)
220 struct sipe_backend_private *purple_private = sipe_public->backend_private;
221 PurpleBuddy *b;
222 PurpleGroup *purple_group = purple_find_group(groupname);
224 if (!purple_group)
225 return NULL;
227 b = purple_buddy_new(purple_private->account, name, alias);
228 purple_blist_add_buddy(b, NULL, purple_group, NULL);
229 return b;
232 void sipe_backend_buddy_remove(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
233 const sipe_backend_buddy who)
235 purple_blist_remove_buddy(who);
238 void sipe_backend_buddy_request_authorization(struct sipe_core_public *sipe_public,
239 const gchar *who,
240 const gchar *alias,
241 gboolean on_list,
242 sipe_backend_buddy_request_authorization_cb auth_cb,
243 sipe_backend_buddy_request_authorization_cb deny_cb,
244 gpointer data)
246 struct sipe_backend_private *purple_private = sipe_public->backend_private;
248 purple_account_request_authorization(
249 purple_private->account,
250 who,
251 _("you"), /* id */
252 alias,
253 NULL, /* message */
254 on_list,
255 auth_cb,
256 deny_cb,
257 data);
261 void sipe_backend_buddy_request_add(struct sipe_core_public *sipe_public,
262 const gchar *who,
263 const gchar *alias)
265 struct sipe_backend_private *purple_private = sipe_public->backend_private;
267 purple_account_request_add(purple_private->account,
268 who,
269 _("you"),
270 alias,
271 NULL);
275 gboolean sipe_backend_buddy_is_blocked(struct sipe_core_public *sipe_public,
276 const gchar *who)
278 struct sipe_backend_private *purple_private = sipe_public->backend_private;
280 return !purple_privacy_check(purple_private->account, who);
283 void sipe_backend_buddy_set_blocked_status(struct sipe_core_public *sipe_public,
284 const gchar *who,
285 gboolean blocked)
287 struct sipe_backend_private *purple_private = sipe_public->backend_private;
289 if (blocked) {
290 purple_privacy_deny_add(purple_private->account, who, TRUE);
291 } else {
292 purple_privacy_deny_remove(purple_private->account, who, TRUE);
295 /* stupid workaround to make pidgin re-render screen to reflect our changes */
296 SIPE_DEBUG_INFO_NOFORMAT("sipe_backend_buddy_set_blocked_status: forcefully refreshing screen.");
297 sipe_core_buddy_got_status(sipe_public,
298 who,
299 sipe_backend_buddy_get_status(sipe_public,
300 who));
303 void sipe_backend_buddy_set_status(struct sipe_core_public *sipe_public,
304 const gchar *who,
305 const gchar *status_id)
307 struct sipe_backend_private *purple_private = sipe_public->backend_private;
309 purple_prpl_got_user_status(purple_private->account, who, status_id, NULL);
312 gboolean sipe_backend_buddy_group_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
313 const gchar *group_name)
315 PurpleGroup * purple_group = purple_find_group(group_name);
316 if (!purple_group) {
317 purple_group = purple_group_new(group_name);
318 purple_blist_add_group(purple_group, NULL);
321 return (purple_group != NULL);
324 struct sipe_backend_buddy_info *sipe_backend_buddy_info_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public)
326 return((struct sipe_backend_buddy_info *)purple_notify_user_info_new());
329 void sipe_backend_buddy_info_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
330 struct sipe_backend_buddy_info *info,
331 const gchar *description,
332 const gchar *value)
334 #if PURPLE_VERSION_CHECK(3,0,0)
335 purple_notify_user_info_add_pair_html
336 #else
337 purple_notify_user_info_add_pair
338 #endif
339 ((PurpleNotifyUserInfo *) info, description, value);
342 void sipe_backend_buddy_info_break(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
343 struct sipe_backend_buddy_info *info)
345 purple_notify_user_info_add_section_break((PurpleNotifyUserInfo *) info);
348 void sipe_backend_buddy_info_finalize(struct sipe_core_public *sipe_public,
349 struct sipe_backend_buddy_info *info,
350 const gchar *uri)
352 struct sipe_backend_private *purple_private = sipe_public->backend_private;
354 /* show a buddy's user info in a nice dialog box */
355 purple_notify_userinfo(purple_private->gc,
356 uri, /* buddy's URI */
357 (PurpleNotifyUserInfo *) info,
358 NULL, /* callback called when dialog closed */
359 NULL); /* userdata for callback */
362 void sipe_backend_buddy_tooltip_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
363 struct sipe_backend_buddy_tooltip *tooltip,
364 const gchar *description,
365 const gchar *value)
367 #if PURPLE_VERSION_CHECK(3,0,0)
368 purple_notify_user_info_add_pair_html
369 #else
370 purple_notify_user_info_add_pair
371 #endif
372 ((PurpleNotifyUserInfo *) tooltip, description, value);
375 void sipe_purple_add_buddy(PurpleConnection *gc,
376 PurpleBuddy *buddy,
377 PurpleGroup *group)
379 SIPE_DEBUG_INFO("sipe_purple_add_buddy[CB]: buddy:%s group:%s",
380 buddy ? buddy->name : "",
381 group ? group->name : "");
383 /* libpurple can call us with undefined buddy or group */
384 if (buddy && group) {
386 * Buddy name must be lower case as we use
387 * purple_normalize_nocase() to compare
389 gchar *buddy_name = g_ascii_strdown(buddy->name, -1);
390 gchar *uri = sip_uri(buddy_name);
391 g_free(buddy_name);
392 purple_blist_rename_buddy(buddy, uri);
393 g_free(uri);
395 sipe_core_buddy_add(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
396 buddy->name,
397 group->name);
401 void sipe_purple_remove_buddy(PurpleConnection *gc,
402 PurpleBuddy *buddy,
403 PurpleGroup *group)
405 SIPE_DEBUG_INFO("sipe_purple_remove_buddy[CB]: buddy:%s group:%s", buddy ? buddy->name : "", group ? group->name : "");
406 if (!buddy) return;
408 sipe_core_buddy_remove(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
409 buddy->name,
410 group ? group->name : NULL);
413 void sipe_purple_group_buddy(PurpleConnection *gc,
414 const char *who,
415 const char *old_group_name,
416 const char *new_group_name)
418 sipe_core_buddy_group(PURPLE_GC_TO_SIPE_CORE_PUBLIC, who, old_group_name, new_group_name);
421 /* Buddy Menu Handling */
423 static void sipe_purple_buddy_make_chat_leader_cb(PurpleBuddy *buddy,
424 gpointer parameter)
426 SIPE_DEBUG_INFO("sipe_purple_buddy_make_chat_leader_cb: buddy->name=%s",
427 buddy->name);
428 sipe_core_conf_make_leader(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
429 parameter,
430 buddy->name);
433 static void sipe_purple_buddy_remove_from_chat_cb(PurpleBuddy *buddy,
434 gpointer parameter)
436 SIPE_DEBUG_INFO("sipe_purple_buddy_remove_from_chat_cb: buddy->name=%s",
437 buddy->name);
438 sipe_core_conf_remove_from(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
439 parameter,
440 buddy->name);
443 static void sipe_purple_buddy_invite_to_chat_cb(PurpleBuddy *buddy,
444 gpointer parameter)
446 SIPE_DEBUG_INFO("sipe_purple_buddy_invite_to_chat_cb: buddy->name=%s",
447 buddy->name);
448 sipe_core_chat_invite(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
449 parameter,
450 buddy->name);
453 static void sipe_purple_buddy_new_chat_cb(PurpleBuddy *buddy,
454 SIPE_UNUSED_PARAMETER gpointer parameter)
456 SIPE_DEBUG_INFO("sipe_purple_buddy_new_chat_cb: buddy->name=%s",
457 buddy->name);
458 sipe_core_buddy_new_chat(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
459 buddy->name);
462 static void sipe_purple_buddy_make_call_cb(PurpleBuddy *buddy,
463 gpointer parameter)
465 SIPE_DEBUG_INFO("sipe_purple_buddy_make_call_cb: buddy->name=%s", buddy->name);
466 sipe_core_buddy_make_call(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
467 parameter);
470 static void sipe_purple_buddy_send_email_cb(PurpleBuddy *buddy,
471 SIPE_UNUSED_PARAMETER gpointer parameter)
473 SIPE_DEBUG_INFO("sipe_purple_buddy_send_email_cb: buddy->name=%s",
474 buddy->name);
475 sipe_core_buddy_send_email(PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC,
476 buddy->name);
479 typedef void (*buddy_menu_callback)(PurpleBuddy *buddy,
480 gpointer parameter);
481 static const buddy_menu_callback callback_map[SIPE_BUDDY_MENU_TYPES] = {
482 /* SIPE_BUDDY_MENU_MAKE_CHAT_LEADER */ sipe_purple_buddy_make_chat_leader_cb,
483 /* SIPE_BUDDY_MENU_REMOVE_FROM_CHAT */ sipe_purple_buddy_remove_from_chat_cb,
484 /* SIPE_BUDDY_MENU_INVITE_TO_CHAT */ sipe_purple_buddy_invite_to_chat_cb,
485 /* SIPE_BUDDY_MENU_NEW_CHAT */ sipe_purple_buddy_new_chat_cb,
486 /* SIPE_BUDDY_MENU_MAKE_CALL */ sipe_purple_buddy_make_call_cb,
487 /* SIPE_BUDDY_MENU_SEND_EMAIL */ sipe_purple_buddy_send_email_cb,
490 struct sipe_backend_buddy_menu *sipe_backend_buddy_menu_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public)
492 return(NULL);
495 struct sipe_backend_buddy_menu *sipe_backend_buddy_menu_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
496 struct sipe_backend_buddy_menu *menu,
497 const gchar *label,
498 enum sipe_buddy_menu_type type,
499 gpointer parameter)
501 return((struct sipe_backend_buddy_menu *)
502 g_list_prepend((GList *) menu,
503 purple_menu_action_new(label,
504 PURPLE_CALLBACK(callback_map[type]),
505 parameter, NULL)));
508 struct sipe_backend_buddy_menu *sipe_backend_buddy_sub_menu_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
509 struct sipe_backend_buddy_menu *menu,
510 const gchar *label,
511 struct sipe_backend_buddy_menu *sub)
513 return((struct sipe_backend_buddy_menu *)
514 g_list_prepend((GList *) menu,
515 purple_menu_action_new(label,
516 NULL,
517 NULL,
518 (GList *) sub)));
521 static void sipe_purple_buddy_copy_to_cb(PurpleBlistNode *node,
522 const gchar *group_name)
524 struct sipe_core_public *sipe_public;
525 PurpleBuddy *buddy = (PurpleBuddy *)node;
526 PurpleGroup *group;
527 PurpleBuddy *clone;
529 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
531 sipe_public = PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC;
532 group = purple_find_group(group_name);
534 SIPE_DEBUG_INFO("sipe_purple_buddy_copy_to_cb: copying %s to %s",
535 buddy->name, group_name);
537 clone = purple_find_buddy_in_group(buddy->account, buddy->name, group);
538 if (!clone) {
539 clone = sipe_backend_buddy_add(sipe_public,
540 buddy->name,
541 buddy->alias,
542 group->name);
543 if (clone) {
544 const gchar *tmp;
545 const gchar *key;
546 const PurpleStatus *status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
548 tmp = purple_buddy_get_server_alias(buddy);
549 if (tmp) purple_blist_server_alias_buddy(clone, tmp);
551 key = sipe_buddy_info_to_purple_property(SIPE_BUDDY_INFO_EMAIL);
552 tmp = purple_blist_node_get_string(&buddy->node, key);
553 if (tmp) purple_blist_node_set_string(&clone->node,
554 key,
555 tmp);
557 tmp = purple_status_get_id(status);
558 purple_presence_set_status_active(purple_buddy_get_presence(clone),
559 tmp,
560 TRUE);
562 /* update UI */
563 purple_prpl_got_user_status(clone->account,
564 clone->name,
565 tmp,
566 NULL);
570 if (clone && group)
571 sipe_core_buddy_add(sipe_public,
572 clone->name,
573 group->name);
576 static GList *sipe_purple_copy_to_menu(GList *menu,
577 PurpleBuddy *buddy)
579 GList *menu_groups = NULL;
580 PurpleGroup *gr_parent = purple_buddy_get_group(buddy);
581 PurpleBlistNode *g_node;
583 for (g_node = purple_blist_get_root(); g_node; g_node = g_node->next) {
584 PurpleGroup *group = (PurpleGroup *)g_node;
585 PurpleMenuAction *act;
587 if ((g_node->type != PURPLE_BLIST_GROUP_NODE) ||
588 (group == gr_parent) ||
589 purple_find_buddy_in_group(buddy->account,
590 buddy->name,
591 group))
592 continue;
594 act = purple_menu_action_new(purple_group_get_name(group),
595 PURPLE_CALLBACK(sipe_purple_buddy_copy_to_cb),
596 group->name, NULL);
597 menu_groups = g_list_prepend(menu_groups, act);
600 if (menu_groups)
601 menu = g_list_prepend(menu,
602 purple_menu_action_new(_("Copy to"),
603 NULL,
604 NULL,
605 g_list_reverse(menu_groups)));
607 return(menu);
610 GList *sipe_purple_buddy_menu(PurpleBuddy *buddy)
612 struct sipe_core_public *sipe_public = PURPLE_BUDDY_TO_SIPE_CORE_PUBLIC;
613 GList *menu = (GList *) sipe_core_buddy_create_menu(sipe_public,
614 buddy->name,
615 NULL);
616 menu = sipe_purple_copy_to_menu(menu, buddy);
617 return(g_list_reverse(menu));
622 Local Variables:
623 mode: c
624 c-file-style: "bsd"
625 indent-tabs-mode: t
626 tab-width: 8
627 End: