core cleanup: move sipe_get_buddy_status() to backend
[siplcs.git] / src / core / sipe.c
blobf0f7a1e414427c44905c6c54f2a38d28513d1d57
1 /**
2 * @file sipe.c
4 *****************************************************************************
5 *** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ***
6 *** ***
7 *** THIS MODULE IS DEPECRATED ***
8 *** ***
9 *** DO NOT ADD ANY NEW CODE TO THIS MODULE ***
10 *** ***
11 *** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ***
12 *****************************************************************************
14 * pidgin-sipe
16 * Copyright (C) 2010-11 SIPE Project <http://sipe.sourceforge.net/>
17 * Copyright (C) 2010 pier11 <pier11@operamail.com>
18 * Copyright (C) 2009 Anibal Avelar <debianmx@gmail.com>
19 * Copyright (C) 2009 pier11 <pier11@operamail.com>
20 * Copyright (C) 2008 Novell, Inc., Anibal Avelar <debianmx@gmail.com>
21 * Copyright (C) 2007 Anibal Avelar <debianmx@gmail.com>
22 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
24 * ***
25 * Thanks to Google's Summer of Code Program and the helpful mentors
26 * ***
28 * Session-based SIP MESSAGE documentation:
29 * http://tools.ietf.org/html/draft-ietf-simple-im-session-00
31 * This program is free software; you can redistribute it and/or modify
32 * it under the terms of the GNU General Public License as published by
33 * the Free Software Foundation; either version 2 of the License, or
34 * (at your option) any later version.
36 * This program is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
41 * You should have received a copy of the GNU General Public License
42 * along with this program; if not, write to the Free Software
43 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
50 #include <time.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <errno.h>
54 #include <string.h>
55 #include <unistd.h>
57 #include <glib.h>
59 #include <libintl.h>
61 #include "sipe-common.h"
63 #include "account.h"
64 #include "blist.h"
65 #include "connection.h"
66 #include "conversation.h"
67 #include "ft.h"
68 #include "notify.h"
69 #include "plugin.h"
70 #include "privacy.h"
71 #include "request.h"
73 #include "core-depurple.h" /* Temporary for the core de-purple transition */
75 #include "http-conn.h"
76 #include "sipmsg.h"
77 #include "sip-csta.h"
78 #include "sip-soap.h"
79 #include "sipe-backend.h"
80 #include "sipe-buddy.h"
81 #include "sipe-cal.h"
82 #include "sipe-chat.h"
83 #include "sipe-conf.h"
84 #include "sipe-core.h"
85 #include "sipe-core-private.h"
86 #include "sipe-dialog.h"
87 #include "sipe-im.h"
88 #include "sipe-nls.h"
89 #include "sipe-ocs2007.h"
90 #include "sipe-session.h"
91 #include "sipe-status.h"
92 #include "sipe-utils.h"
94 #include "sipe.h"
96 void send_presence_status(struct sipe_core_private *sipe_private,
97 SIPE_UNUSED_PARAMETER gpointer unused)
99 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
100 PurpleStatus * status = purple_account_get_active_status(sip->account);
102 if (!status) return;
104 SIPE_DEBUG_INFO("send_presence_status: status: %s (%s)",
105 purple_status_get_id(status) ? purple_status_get_id(status) : "",
106 sipe_status_changed_by_user(sipe_private) ? "USER" : "MACHINE");
108 sipe_cal_presence_publish(sipe_private, FALSE);
111 /* temporary function */
112 void sipe_purple_setup(struct sipe_core_public *sipe_public,
113 PurpleConnection *gc)
115 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA;
116 sip->gc = gc;
117 sip->account = purple_connection_get_account(gc);
120 /** for Access levels menu */
121 #define INDENT_FMT " %s"
123 /** Member is indirectly belong to access level container.
124 * For example 'sameEnterprise' is in the container and user
125 * belongs to that same enterprise.
127 #define INDENT_MARKED_INHERITED_FMT "= %s"
129 static PurpleBuddy *
130 purple_blist_add_buddy_clone(PurpleGroup * group, PurpleBuddy * buddy)
132 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
133 PurpleBuddy *clone;
134 gchar *server_alias, *email;
135 const PurpleStatus *status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
137 clone = sipe_backend_buddy_add(SIPE_CORE_PUBLIC,
138 buddy->name,
139 buddy->alias,
140 group->name);
142 server_alias = sipe_backend_buddy_get_server_alias(SIPE_CORE_PUBLIC,
143 buddy);
144 if (server_alias) {
145 sipe_backend_buddy_set_server_alias(SIPE_CORE_PUBLIC,
146 clone,
147 server_alias);
148 g_free(server_alias);
151 email = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
152 buddy,
153 SIPE_BUDDY_INFO_EMAIL);
154 if (email) {
155 sipe_backend_buddy_set_string(SIPE_CORE_PUBLIC,
156 clone,
157 SIPE_BUDDY_INFO_EMAIL,
158 email);
159 g_free(email);
162 purple_presence_set_status_active(purple_buddy_get_presence(clone),
163 purple_status_get_id(status),
164 TRUE);
165 /* for UI to update */
166 sipe_backend_buddy_set_status(SIPE_CORE_PUBLIC,
167 buddy->name,
168 purple_status_get_id(status));
170 return clone;
173 static void
174 sipe_buddy_menu_copy_to_cb(PurpleBlistNode *node, const char *group_name)
176 PurpleBuddy *buddy, *b;
177 PurpleGroup * group = purple_find_group(group_name);
179 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
181 buddy = (PurpleBuddy *)node;
183 SIPE_DEBUG_INFO("sipe_buddy_menu_copy_to_cb: copying %s to %s",
184 buddy->name, group_name);
186 b = purple_find_buddy_in_group(buddy->account, buddy->name, group);
187 if (!b)
188 b = purple_blist_add_buddy_clone(group, buddy);
190 if (b && group) {
191 PurpleConnection *gc = purple_account_get_connection(b->account);
193 sipe_core_buddy_add(PURPLE_GC_TO_SIPE_CORE_PUBLIC,
194 b->name,
195 group->name);
199 static void
200 sipe_buddy_menu_chat_new_cb(PurpleBuddy *buddy)
202 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
204 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_new_cb: buddy->name=%s", buddy->name);
206 /* 2007+ conference */
207 if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007))
209 sipe_conf_add(sipe_private, buddy->name);
211 else /* 2005- multiparty chat */
213 gchar *self = sip_uri_self(sipe_private);
214 struct sip_session *session;
216 session = sipe_session_add_chat(sipe_private,
217 NULL,
218 TRUE,
219 self);
220 session->chat_session->backend = sipe_backend_chat_create(SIPE_CORE_PUBLIC,
221 session->chat_session,
222 session->chat_session->title,
223 self);
224 g_free(self);
226 sipe_im_invite(sipe_private, session, buddy->name, NULL, NULL, NULL, FALSE);
231 * For 2007+ conference only.
233 static void
234 sipe_buddy_menu_chat_make_leader_cb(PurpleBuddy *buddy,
235 struct sipe_chat_session *chat_session)
237 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
238 struct sip_session *session;
240 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_make_leader_cb: buddy->name=%s", buddy->name);
241 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_make_leader_cb: chat_title=%s", chat_session->title);
243 session = sipe_session_find_chat(sipe_private, chat_session);
245 sipe_conf_modify_user_role(sipe_private, session, buddy->name);
249 * For 2007+ conference only.
251 static void
252 sipe_buddy_menu_chat_remove_cb(PurpleBuddy *buddy,
253 struct sipe_chat_session *chat_session)
255 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
256 struct sip_session *session;
258 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_remove_cb: buddy->name=%s", buddy->name);
259 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_remove_cb: chat_title=%s", chat_session->title);
261 session = sipe_session_find_chat(sipe_private, chat_session);
263 sipe_conf_delete_user(sipe_private, session, buddy->name);
266 static void
267 sipe_buddy_menu_chat_invite_cb(PurpleBuddy *buddy,
268 struct sipe_chat_session *chat_session)
270 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
272 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_invite_cb: buddy->name=%s", buddy->name);
273 SIPE_DEBUG_INFO("sipe_buddy_menu_chat_invite_cb: chat_title=%s", chat_session->title);
275 sipe_core_chat_invite(SIPE_CORE_PUBLIC, chat_session, buddy->name);
278 static void
279 sipe_buddy_menu_make_call_cb(PurpleBuddy *buddy, const char *phone)
281 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
283 SIPE_DEBUG_INFO("sipe_buddy_menu_make_call_cb: buddy->name=%s", buddy->name);
284 if (phone) {
285 char *tel_uri = sip_to_tel_uri(phone);
287 SIPE_DEBUG_INFO("sipe_buddy_menu_make_call_cb: going to call number: %s", tel_uri ? tel_uri : "");
288 sip_csta_make_call(sipe_private, tel_uri);
290 g_free(tel_uri);
294 static void
295 sipe_buddy_menu_access_level_help_cb(PurpleBuddy *buddy)
297 /** Translators: replace with URL to localized page
298 * If it doesn't exist copy the original URL */
299 purple_notify_uri(buddy->account->gc, _("https://sourceforge.net/apps/mediawiki/sipe/index.php?title=Access_Levels"));
302 static void
303 sipe_buddy_menu_send_email_cb(PurpleBuddy *buddy)
305 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
306 gchar *email;
307 SIPE_DEBUG_INFO("sipe_buddy_menu_send_email_cb: buddy->name=%s", buddy->name);
309 email = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
310 buddy,
311 SIPE_BUDDY_INFO_EMAIL);
312 if (email)
314 char *command_line = g_strdup_printf(
315 #ifdef _WIN32
316 "cmd /c start"
317 #else
318 "xdg-email"
319 #endif
320 " mailto:%s", email);
321 SIPE_DEBUG_INFO("sipe_buddy_menu_send_email_cb: going to call email client: %s", command_line);
323 g_free(email);
324 g_spawn_command_line_async(command_line, NULL);
325 g_free(command_line);
327 else
329 SIPE_DEBUG_INFO("sipe_buddy_menu_send_email_cb: no email address stored for buddy=%s", buddy->name);
333 static void
334 sipe_buddy_menu_access_level_cb(PurpleBuddy *buddy,
335 struct sipe_container *container)
337 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
338 sipe_ocs2007_change_access_level_from_container(sipe_private,
339 container);
342 static GList *
343 sipe_get_access_control_menu(struct sipe_core_private *sipe_private,
344 const char* uri);
347 * A menu which appear when right-clicking on buddy in contact list.
349 GList *
350 sipe_buddy_menu(PurpleBuddy *buddy)
352 PurpleBlistNode *g_node;
353 PurpleGroup *gr_parent;
354 PurpleMenuAction *act;
355 GList *menu = NULL;
356 GList *menu_groups = NULL;
357 struct sipe_core_private *sipe_private = PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE;
358 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
359 gchar *email;
360 gchar *self = sip_uri_self(sipe_private);
362 SIPE_SESSION_FOREACH {
363 if (!sipe_strcase_equal(self, buddy->name) && session->chat_session)
365 struct sipe_chat_session *chat_session = session->chat_session;
366 gboolean is_conf = (chat_session->type == SIPE_CHAT_TYPE_CONFERENCE);
368 if (sipe_backend_chat_find(chat_session->backend, buddy->name))
370 gboolean conf_op = sipe_backend_chat_is_operator(chat_session->backend, self);
372 if (is_conf
373 && !sipe_backend_chat_is_operator(chat_session->backend, buddy->name) /* Not conf OP */
374 && conf_op) /* We are a conf OP */
376 gchar *label = g_strdup_printf(_("Make leader of '%s'"),
377 chat_session->title);
378 act = purple_menu_action_new(label,
379 PURPLE_CALLBACK(sipe_buddy_menu_chat_make_leader_cb),
380 chat_session, NULL);
381 g_free(label);
382 menu = g_list_prepend(menu, act);
385 if (is_conf
386 && conf_op) /* We are a conf OP */
388 gchar *label = g_strdup_printf(_("Remove from '%s'"),
389 chat_session->title);
390 act = purple_menu_action_new(label,
391 PURPLE_CALLBACK(sipe_buddy_menu_chat_remove_cb),
392 chat_session, NULL);
393 g_free(label);
394 menu = g_list_prepend(menu, act);
397 else
399 if (!is_conf
400 || (is_conf && !session->locked))
402 gchar *label = g_strdup_printf(_("Invite to '%s'"),
403 chat_session->title);
404 act = purple_menu_action_new(label,
405 PURPLE_CALLBACK(sipe_buddy_menu_chat_invite_cb),
406 chat_session, NULL);
407 g_free(label);
408 menu = g_list_prepend(menu, act);
412 } SIPE_SESSION_FOREACH_END;
414 act = purple_menu_action_new(_("New chat"),
415 PURPLE_CALLBACK(sipe_buddy_menu_chat_new_cb),
416 NULL, NULL);
417 menu = g_list_prepend(menu, act);
419 if (sip->csta && !sip->csta->line_status) {
420 gchar *phone;
421 gchar *phone_disp_str;
422 gchar *tmp = NULL;
423 /* work phone */
424 phone = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
425 buddy,
426 SIPE_BUDDY_INFO_WORK_PHONE);
427 phone_disp_str = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
428 buddy,
429 SIPE_BUDDY_INFO_WORK_PHONE_DISPLAY);
430 if (phone) {
431 gchar *label = g_strdup_printf(_("Work %s"),
432 phone_disp_str ? phone_disp_str : (tmp = sip_tel_uri_denormalize(phone)));
433 act = purple_menu_action_new(label, PURPLE_CALLBACK(sipe_buddy_menu_make_call_cb), (gpointer) phone, NULL);
434 g_free(tmp);
435 tmp = NULL;
436 g_free(label);
437 menu = g_list_prepend(menu, act);
438 g_free(phone);
440 g_free(phone_disp_str);
442 /* mobile phone */
443 phone = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
444 buddy,
445 SIPE_BUDDY_INFO_MOBILE_PHONE);
446 phone_disp_str = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
447 buddy,
448 SIPE_BUDDY_INFO_MOBILE_PHONE_DISPLAY);
449 if (phone) {
450 gchar *label = g_strdup_printf(_("Mobile %s"),
451 phone_disp_str ? phone_disp_str : (tmp = sip_tel_uri_denormalize(phone)));
452 act = purple_menu_action_new(label, PURPLE_CALLBACK(sipe_buddy_menu_make_call_cb), (gpointer) phone, NULL);
453 g_free(tmp);
454 tmp = NULL;
455 g_free(label);
456 menu = g_list_prepend(menu, act);
457 g_free(phone);
459 g_free(phone_disp_str);
461 /* home phone */
462 phone = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
463 buddy,
464 SIPE_BUDDY_INFO_HOME_PHONE);
465 phone_disp_str = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
466 buddy,
467 SIPE_BUDDY_INFO_HOME_PHONE_DISPLAY);
468 if (phone) {
469 gchar *label = g_strdup_printf(_("Home %s"),
470 phone_disp_str ? phone_disp_str : (tmp = sip_tel_uri_denormalize(phone)));
471 act = purple_menu_action_new(label, PURPLE_CALLBACK(sipe_buddy_menu_make_call_cb), (gpointer) phone, NULL);
472 g_free(tmp);
473 tmp = NULL;
474 g_free(label);
475 menu = g_list_prepend(menu, act);
476 g_free(phone);
478 g_free(phone_disp_str);
480 /* other phone */
481 phone = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
482 buddy,
483 SIPE_BUDDY_INFO_OTHER_PHONE);
484 phone_disp_str = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
485 buddy,
486 SIPE_BUDDY_INFO_OTHER_PHONE_DISPLAY);
487 if (phone) {
488 gchar *label = g_strdup_printf(_("Other %s"),
489 phone_disp_str ? phone_disp_str : (tmp = sip_tel_uri_denormalize(phone)));
490 act = purple_menu_action_new(label, PURPLE_CALLBACK(sipe_buddy_menu_make_call_cb), (gpointer) phone, NULL);
491 g_free(tmp);
492 tmp = NULL;
493 g_free(label);
494 menu = g_list_prepend(menu, act);
495 g_free(phone);
497 g_free(phone_disp_str);
499 /* custom1 phone */
500 phone = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
501 buddy,
502 SIPE_BUDDY_INFO_CUSTOM1_PHONE);
503 phone_disp_str = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
504 buddy,
505 SIPE_BUDDY_INFO_CUSTOM1_PHONE_DISPLAY);
506 if (phone) {
507 gchar *label = g_strdup_printf(_("Custom1 %s"),
508 phone_disp_str ? phone_disp_str : (tmp = sip_tel_uri_denormalize(phone)));
509 act = purple_menu_action_new(label, PURPLE_CALLBACK(sipe_buddy_menu_make_call_cb), (gpointer) phone, NULL);
510 g_free(tmp);
511 tmp = NULL;
512 g_free(label);
513 menu = g_list_prepend(menu, act);
514 g_free(phone);
516 g_free(phone_disp_str);
519 email = sipe_backend_buddy_get_string(SIPE_CORE_PUBLIC,
520 buddy,
521 SIPE_BUDDY_INFO_EMAIL);
522 if (email) {
523 act = purple_menu_action_new(_("Send email..."),
524 PURPLE_CALLBACK(sipe_buddy_menu_send_email_cb),
525 NULL, NULL);
526 menu = g_list_prepend(menu, act);
527 g_free(email);
530 /* Access Level */
531 if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007)) {
532 GList *menu_access_levels = sipe_get_access_control_menu(sipe_private, buddy->name);
534 act = purple_menu_action_new(_("Access level"),
535 NULL,
536 NULL, menu_access_levels);
537 menu = g_list_prepend(menu, act);
540 /* Copy to */
541 gr_parent = purple_buddy_get_group(buddy);
542 for (g_node = purple_blist_get_root(); g_node; g_node = g_node->next) {
543 PurpleGroup *group;
545 if (g_node->type != PURPLE_BLIST_GROUP_NODE)
546 continue;
548 group = (PurpleGroup *)g_node;
549 if (group == gr_parent)
550 continue;
552 if (purple_find_buddy_in_group(buddy->account, buddy->name, group))
553 continue;
555 act = purple_menu_action_new(purple_group_get_name(group),
556 PURPLE_CALLBACK(sipe_buddy_menu_copy_to_cb),
557 group->name, NULL);
558 menu_groups = g_list_prepend(menu_groups, act);
560 /* Coverity complains about RESOURCE_LEAK here - no idea how to fix it */
561 menu_groups = g_list_reverse(menu_groups);
563 act = purple_menu_action_new(_("Copy to"),
564 NULL,
565 NULL, menu_groups);
566 menu = g_list_prepend(menu, act);
568 menu = g_list_reverse(menu);
570 g_free(self);
571 return menu;
574 static void
575 sipe_ask_access_domain_cb(PurpleConnection *gc, PurpleRequestFields *fields)
577 struct sipe_core_private *sipe_private = PURPLE_GC_TO_SIPE_CORE_PRIVATE;
578 const char *domain = purple_request_fields_get_string(fields, "access_domain");
579 guint index = purple_request_fields_get_choice(fields, "container_id");
580 sipe_ocs2007_change_access_level_for_domain(sipe_private,
581 domain,
582 index);
585 static void
586 sipe_ask_access_domain(struct sipe_core_private *sipe_private)
588 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
589 PurpleAccount *account = sip->account;
590 PurpleConnection *gc = sip->gc;
591 PurpleRequestFields *fields;
592 PurpleRequestFieldGroup *g;
593 PurpleRequestField *f;
595 fields = purple_request_fields_new();
597 g = purple_request_field_group_new(NULL);
598 f = purple_request_field_string_new("access_domain", _("Domain"), "partner-company.com", FALSE);
599 purple_request_field_set_required(f, TRUE);
600 purple_request_field_group_add_field(g, f);
602 f = purple_request_field_choice_new("container_id", _("Access level"), 0);
603 purple_request_field_choice_add(f, _("Personal")); /* index 0 */
604 purple_request_field_choice_add(f, _("Team"));
605 purple_request_field_choice_add(f, _("Company"));
606 purple_request_field_choice_add(f, _("Public"));
607 purple_request_field_choice_add(f, _("Blocked")); /* index 4 */
608 purple_request_field_choice_set_default_value(f, 3); /* index */
609 purple_request_field_set_required(f, TRUE);
610 purple_request_field_group_add_field(g, f);
612 purple_request_fields_add_group(fields, g);
614 purple_request_fields(gc, _("Add new domain"),
615 _("Add new domain"), NULL, fields,
616 _("Add"), G_CALLBACK(sipe_ask_access_domain_cb),
617 _("Cancel"), NULL,
618 account, NULL, NULL, gc);
621 static void
622 sipe_buddy_menu_access_level_add_domain_cb(PurpleBuddy *buddy)
624 sipe_ask_access_domain(PURPLE_BUDDY_TO_SIPE_CORE_PRIVATE);
628 * Workaround for missing libpurple API to release resources allocated
629 * during blist_node_menu() callback. See also:
631 * <http://developer.pidgin.im/ticket/12597>
633 * We remember all memory blocks in a list and deallocate them when
635 * - the next time we enter the callback, or
636 * - the account is disconnected
638 * That means that after the buddy menu has been closed we have unused
639 * resources but at least we don't leak them anymore...
641 void sipe_blist_menu_free_containers(struct sipe_core_private *sipe_private)
643 GSList *entry = sipe_private->blist_menu_containers;
644 while (entry) {
645 sipe_ocs2007_free_container(entry->data);
646 entry = entry->next;
648 g_slist_free(sipe_private->blist_menu_containers);
649 sipe_private->blist_menu_containers = NULL;
652 static void
653 sipe_blist_menu_remember_container(struct sipe_core_private *sipe_private,
654 struct sipe_container *container)
656 sipe_private->blist_menu_containers = g_slist_prepend(sipe_private->blist_menu_containers,
657 container);
660 static GList *
661 sipe_get_access_levels_menu(struct sipe_core_private *sipe_private,
662 const char* member_type,
663 const char* member_value,
664 const gboolean extra_menu)
666 GList *menu_access_levels = NULL;
667 unsigned int i;
668 char *menu_name;
669 PurpleMenuAction *act;
670 struct sipe_container *container;
671 gboolean is_group_access = FALSE;
672 int container_id = sipe_ocs2007_find_access_level(sipe_private,
673 member_type,
674 member_value,
675 &is_group_access);
676 guint container_max = sipe_ocs2007_containers();
678 for (i = 1; i <= container_max; i++) {
679 /* to put Blocked level last in menu list.
680 * Blocked should remaim in the first place in the containers[] array.
682 unsigned int j = (i == container_max) ? 0 : i;
683 int container_j = sipe_ocs2007_container_id(j);
684 const gchar *acc_level_name = sipe_ocs2007_access_level_name(container_j);
686 container = sipe_ocs2007_create_container(j,
687 member_type,
688 member_value,
689 FALSE);
691 /* libpurple memory leak workaround */
692 sipe_blist_menu_remember_container(sipe_private, container);
694 /* current container/access level */
695 if (container_j == container_id) {
696 menu_name = is_group_access ?
697 g_strdup_printf(INDENT_MARKED_INHERITED_FMT, acc_level_name) :
698 g_strdup_printf(SIPE_OCS2007_INDENT_MARKED_FMT, acc_level_name);
699 } else {
700 menu_name = g_strdup_printf(INDENT_FMT, acc_level_name);
703 act = purple_menu_action_new(menu_name,
704 PURPLE_CALLBACK(sipe_buddy_menu_access_level_cb),
705 container, NULL);
706 g_free(menu_name);
707 menu_access_levels = g_list_prepend(menu_access_levels, act);
710 if (extra_menu && (container_id >= 0)) {
711 /* separator */
712 act = purple_menu_action_new(" --------------", NULL, NULL, NULL);
713 menu_access_levels = g_list_prepend(menu_access_levels, act);
715 if (!is_group_access) {
716 container = sipe_ocs2007_create_container(0,
717 member_type,
718 member_value,
719 TRUE);
721 /* libpurple memory leak workaround */
722 sipe_blist_menu_remember_container(sipe_private, container);
724 /* Translators: remove (clear) previously assigned access level */
725 menu_name = g_strdup_printf(INDENT_FMT, _("Unspecify"));
726 act = purple_menu_action_new(menu_name,
727 PURPLE_CALLBACK(sipe_buddy_menu_access_level_cb),
728 container, NULL);
729 g_free(menu_name);
730 menu_access_levels = g_list_prepend(menu_access_levels, act);
734 menu_access_levels = g_list_reverse(menu_access_levels);
735 return menu_access_levels;
738 static GList *
739 sipe_get_access_groups_menu(struct sipe_core_private *sipe_private)
741 GList *menu_access_groups = NULL;
742 PurpleMenuAction *act;
743 GSList *access_domains;
744 GSList *entry;
746 act = purple_menu_action_new(_("People in my company"),
747 NULL,
748 NULL, sipe_get_access_levels_menu(sipe_private, "sameEnterprise", NULL, FALSE));
749 menu_access_groups = g_list_prepend(menu_access_groups, act);
751 /* this is original name, don't edit */
752 act = purple_menu_action_new(_("People in domains connected with my company"),
753 NULL,
754 NULL, sipe_get_access_levels_menu(sipe_private, "federated", NULL, FALSE));
755 menu_access_groups = g_list_prepend(menu_access_groups, act);
757 act = purple_menu_action_new(_("People in public domains"),
758 NULL,
759 NULL, sipe_get_access_levels_menu(sipe_private, "publicCloud", NULL, TRUE));
760 menu_access_groups = g_list_prepend(menu_access_groups, act);
762 access_domains = sipe_ocs2007_get_access_domains(sipe_private);
763 entry = access_domains;
764 while (entry) {
765 gchar *domain = entry->data;
766 gchar *menu_name = g_strdup_printf(_("People at %s"), domain);
768 /* takes over ownership of entry->data (= domain) */
769 act = purple_menu_action_new(menu_name,
770 NULL,
771 NULL, sipe_get_access_levels_menu(sipe_private, "domain", domain, TRUE));
772 menu_access_groups = g_list_prepend(menu_access_groups, act);
773 g_free(menu_name);
775 entry = entry->next;
777 g_slist_free(access_domains);
779 /* separator */
780 /* People in domains connected with my company */
781 act = purple_menu_action_new("-------------------------------------------", NULL, NULL, NULL);
782 menu_access_groups = g_list_prepend(menu_access_groups, act);
784 act = purple_menu_action_new(_("Add new domain..."),
785 PURPLE_CALLBACK(sipe_buddy_menu_access_level_add_domain_cb),
786 NULL, NULL);
787 menu_access_groups = g_list_prepend(menu_access_groups, act);
789 menu_access_groups = g_list_reverse(menu_access_groups);
791 return menu_access_groups;
794 static GList *
795 sipe_get_access_control_menu(struct sipe_core_private *sipe_private,
796 const char* uri)
798 GList *menu_access_levels = NULL;
799 GList *menu_access_groups = NULL;
800 char *menu_name;
801 PurpleMenuAction *act;
803 /* libpurple memory leak workaround */
804 sipe_blist_menu_free_containers(sipe_private);
806 menu_access_levels = sipe_get_access_levels_menu(sipe_private, "user", sipe_get_no_sip_uri(uri), TRUE);
808 menu_access_groups = sipe_get_access_groups_menu(sipe_private);
810 menu_name = g_strdup_printf(INDENT_FMT, _("Access groups"));
811 act = purple_menu_action_new(menu_name,
812 NULL,
813 NULL, menu_access_groups);
814 g_free(menu_name);
815 menu_access_levels = g_list_append(menu_access_levels, act);
817 menu_name = g_strdup_printf(INDENT_FMT, _("Online help..."));
818 act = purple_menu_action_new(menu_name,
819 PURPLE_CALLBACK(sipe_buddy_menu_access_level_help_cb),
820 NULL, NULL);
821 g_free(menu_name);
822 menu_access_levels = g_list_append(menu_access_levels, act);
824 return menu_access_levels;
828 Local Variables:
829 mode: c
830 c-file-style: "bsd"
831 indent-tabs-mode: t
832 tab-width: 8
833 End: