Skip to content
Snippets Groups Projects
Commit 72a075df authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #10736: now able to join participants without globals

parent 4f901c39
No related branches found
No related tags found
No related merge requests found
...@@ -52,6 +52,13 @@ ...@@ -52,6 +52,13 @@
#include "imwindow.h" #include "imwindow.h"
#include "searchbar.h" #include "searchbar.h"
typedef struct {
gchar *source_ID;
gchar *dest_ID;
} PopupData;
static PopupData *popup_data = NULL;
// Messages used in menu item // Messages used in menu item
static const gchar * const SFL_CREATE_CONFERENCE = "Create conference"; static const gchar * const SFL_CREATE_CONFERENCE = "Create conference";
static const gchar * const SFL_TRANSFER_CALL = "Transfer call to"; static const gchar * const SFL_TRANSFER_CALL = "Transfer call to";
...@@ -59,33 +66,19 @@ static const gchar * const SFL_TRANSFER_CALL = "Transfer call to"; ...@@ -59,33 +66,19 @@ static const gchar * const SFL_TRANSFER_CALL = "Transfer call to";
static GtkWidget *calltree_popupmenu = NULL; static GtkWidget *calltree_popupmenu = NULL;
static GtkWidget *calltree_menu_items = NULL; static GtkWidget *calltree_menu_items = NULL;
static CallType calltree_dest_type = A_INVALID;
static CallType calltree_source_type = A_INVALID;
static gchar *calltree_dest_call_id = NULL;
static gchar *calltree_source_call_id = NULL;
static gchar *calltree_source_call_id_for_drag = NULL;
static gchar *calltree_dest_path = NULL;
static gchar *calltree_source_path = NULL;
static gchar *calltree_source_path_for_drag = NULL;
static gint calltree_dest_path_depth = -1;
static gint calltree_source_path_depth = -1;
static gint calltree_source_path_depth_for_drag = -1;
static callable_obj_t *calltree_dest_call = NULL;
static callable_obj_t *calltree_source_call = NULL; static callable_obj_t *calltree_source_call = NULL;
static callable_obj_t *calltree_source_call_for_drag = NULL;
static conference_obj_t *calltree_dest_conf = NULL;
static conference_obj_t *calltree_source_conf = NULL; static conference_obj_t *calltree_source_conf = NULL;
static void drag_data_get_cb(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint target_type, guint etime, gpointer user_data);
static void drag_end_cb(GtkWidget *, GdkDragContext *, gpointer);
static void drag_data_received_cb(GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint, gpointer); static void drag_data_received_cb(GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint, gpointer);
static void drag_history_received_cb(GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint, gpointer); static void drag_history_received_cb(GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint, gpointer);
static void menuitem_response(gchar *str); static void menuitem_response(gchar * string);
static GtkTargetEntry target_list[] = {
{ "MY_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 }
};
static const guint n_targets = G_N_ELEMENTS(target_list);
enum { enum {
COLUMN_ACCOUNT_PIXBUF = 0, COLUMN_ACCOUNT_PIXBUF = 0,
...@@ -450,16 +443,13 @@ calltree_create(calltab_t* tab, int searchbar_type) ...@@ -450,16 +443,13 @@ calltree_create(calltab_t* tab, int searchbar_type)
if (g_strcmp0(tab->_name, CURRENT_CALLS) == 0) { if (g_strcmp0(tab->_name, CURRENT_CALLS) == 0) {
// Make calltree reordable for drag n drop // Make calltree reordable for drag n drop
gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tab->view), TRUE); //gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tab->view), TRUE);
// source widget drag n drop signals
g_signal_connect(G_OBJECT(tab->view), "drag_end", G_CALLBACK(drag_end_cb), NULL);
gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(tab->view), GDK_BUTTON1_MASK, target_list, n_targets, GDK_ACTION_DEFAULT | GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(tab->view), target_list, n_targets, GDK_ACTION_DEFAULT);
// destination widget drag n drop signals // destination widget drag n drop signals
g_signal_connect(G_OBJECT(tab->view), "drag_data_received", G_CALLBACK(drag_data_received_cb), NULL); g_signal_connect(G_OBJECT(tab->view), "drag_data_received", G_CALLBACK(drag_data_received_cb), NULL);
g_signal_connect(G_OBJECT(tab->view), "drag_data_get", G_CALLBACK(drag_data_get_cb), NULL);
calltree_popupmenu = gtk_menu_new(); calltree_popupmenu = gtk_menu_new();
calltree_menu_items = gtk_menu_item_new_with_label(SFL_TRANSFER_CALL); calltree_menu_items = gtk_menu_item_new_with_label(SFL_TRANSFER_CALL);
...@@ -1172,391 +1162,150 @@ gboolean calltree_update_clock(gpointer data UNUSED) ...@@ -1172,391 +1162,150 @@ gboolean calltree_update_clock(gpointer data UNUSED)
return TRUE; return TRUE;
} }
static gboolean
non_draggable_call(callable_obj_t *call)
{
return call->_state == CALL_STATE_DIALING ||
call->_state == CALL_STATE_INVALID ||
call->_state == CALL_STATE_FAILURE ||
call->_state == CALL_STATE_BUSY ||
call->_state == CALL_STATE_TRANSFER;
}
/** void drag_history_received_cb(GtkWidget *widget, GdkDragContext *context UNUSED, gint x UNUSED, gint y UNUSED, GtkSelectionData *selection_data UNUSED, guint info UNUSED, guint t UNUSED, gpointer data UNUSED)
* Source side drag signals
* The data to be dragged to
*/
static void
drag_data_get_cb(GtkWidget *widget, GdkDragContext *context,
GtkSelectionData *selection_data, guint target_type,
guint etime, gpointer user_data)
{ {
DEBUG("Drag data get callback"); g_signal_stop_emission_by_name(G_OBJECT(widget), "drag_data_received");
GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
GtkTreeSelection *sel = gtk_tree_view_get_selection(tree_view);
GtkTreeModel *model;
GtkTreeIter iter;
gtk_tree_selection_get_selected(sel, &model, &iter);
gchar *id;
gboolean is_conf;
gtk_tree_model_get(model, &iter, COLUMN_ID, &id, COLUMN_IS_CONFERENCE, &is_conf, -1);
calltree_source_type = is_conf ? A_CONFERENCE : A_CALL;
DEBUG("get_cb: source id is %s and it is %sa conference", id, is_conf ? "" : "not ");
/* Set selection data...it is not used yet but this is how the source should pass
* data to the received callback */
enum {BITS_PER_BYTE = 8};
gtk_selection_data_set(selection_data, NULL, BITS_PER_BYTE, (guchar*) id, strlen(id));
g_free(calltree_source_path_for_drag);
g_free(calltree_source_call_id_for_drag);
g_free(calltree_source_path);
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
calltree_source_path = gtk_tree_path_to_string(path);
calltree_source_path_depth = gtk_tree_path_get_depth(path);
calltree_source_path_for_drag = g_strdup(calltree_source_path);
calltree_source_call_id = g_strdup(id);
calltree_source_call_id_for_drag = g_strdup(id);
calltree_source_path_depth_for_drag = calltree_source_path_depth;
calltree_source_call_for_drag = calltree_source_call;
DEBUG("source_path %s, source_call_id %s, source_path_depth %d",
calltree_source_path, calltree_source_call_id, calltree_source_path_depth);
if(is_conf) {
calltree_source_call = NULL;
calltree_source_conf = conferencelist_get(active_calltree_tab, id);
if(calltree_source_conf == NULL) {
ERROR("Could not retreive conference from call tab");
}
}
else {
calltree_source_call = calllist_get_call(active_calltree_tab, id);
calltree_source_conf = NULL;
if(calltree_source_call == NULL) {
ERROR("Could not retreive call from call tab");
}
}
//g_free(id);
} }
static void undo_drag_call_action(callable_obj_t *call, GtkTreePath *spath) static void cleanup_popup_data(PopupData **data)
{ {
calltree_remove_call(current_calls_tab, call->_callID); if (data && *data) {
g_free((*data)->source_ID);
if (spath && calltree_source_call_for_drag->_confID) { g_free((*data)->dest_ID);
gtk_tree_path_up(spath); g_free(*data);
// conference for which this call is attached *data = 0;
GtkTreeIter parent;
gtk_tree_model_get_iter(GTK_TREE_MODEL(current_calls_tab->store), &parent, spath);
calltree_add_call(current_calls_tab, call, &parent);
} else {
calltree_add_call(current_calls_tab, call, NULL);
} }
calltree_dest_call = NULL;
} }
static void perform_action_after_drag(GtkTreeView *treeView)
{
GtkTreeModel *model = gtk_tree_view_get_model(treeView);
GtkTreePath *path = gtk_tree_path_new_from_string(calltree_dest_path);
GtkTreePath *dpath = gtk_tree_path_new_from_string(calltree_dest_path);
GtkTreePath *spath = gtk_tree_path_new_from_string(calltree_source_path_for_drag);
// Make sure drag n drop does not imply a dialing call for either source and dest call
if (calltree_source_call && (calltree_source_type == A_CALL)) {
DEBUG("Selected a call");
if (non_draggable_call(calltree_source_call)) { static gboolean
DEBUG("Selected an invalid call"); render_drop(GtkTreeModel *model, GtkTreePath *dest_path, GtkTreeViewDropPosition dest_pos,
undo_drag_call_action(calltree_source_call_for_drag, NULL); GtkTreeIter *source_iter)
return; {
} GtkTreeIter dest_iter;
if (!gtk_tree_model_get_iter(model, &dest_iter, dest_path)) {
if (calltree_dest_call && (calltree_dest_type == A_CALL)) { ERROR("Could not set dest iter");
return FALSE;
DEBUG("Dragged on a call");
if (non_draggable_call(calltree_dest_call)) {
DEBUG("Dragged on an invalid call");
undo_drag_call_action(calltree_source_call_for_drag, spath);
return;
}
}
}
// Make sure a conference is only dragged on another conference
if (calltree_source_conf && (calltree_source_type == A_CONFERENCE)) {
DEBUG("Selected a conference");
if (!calltree_dest_conf && (calltree_dest_type == A_CALL)) {
ERROR("Dragged a conference on a call, destination conference is NULL");
conference_obj_t* conf = calltree_source_conf;
calltree_remove_conference(current_calls_tab, conf);
calltree_add_conference_to_current_calls(conf);
calltree_dest_call = NULL;
return;
}
}
if (calltree_source_path_depth_for_drag == 1) {
if (calltree_dest_path_depth == 1) {
if (calltree_source_type == A_CALL && calltree_dest_type == A_CALL) {
DEBUG("Dragged a call on a call");
if (calltree_source_call_for_drag && calltree_dest_call) {
calltree_remove_call(current_calls_tab, calltree_source_call_for_drag->_callID);
calltree_add_call(current_calls_tab, calltree_source_call_for_drag, NULL);
// pop menu to determine if we actually create a conference or do a call transfer
gtk_menu_popup(GTK_MENU(calltree_popupmenu), NULL, NULL, NULL, NULL, 0, 0);
}
} else if (calltree_source_type == A_CALL && calltree_dest_type == A_CONFERENCE) {
DEBUG("Dragged a call on a conference");
if (!calltree_source_call_for_drag) {
ERROR("Dragged a NULL call on a conference");
return;
}
g_free(calltree_source_call_for_drag->_confID);
calltree_source_call_for_drag->_confID = g_strdup(calltree_dest_call_id);
g_free(calltree_source_call_for_drag->_historyConfID);
calltree_source_call_for_drag->_historyConfID = g_strdup(calltree_dest_call_id);
sflphone_add_participant(calltree_source_call_id_for_drag, calltree_dest_call_id);
} else if (calltree_source_type == A_CONFERENCE && calltree_dest_type == A_CALL) {
DEBUG("Dragged a conference on a call");
conference_obj_t* conf = calltree_source_conf;
calltree_remove_conference(current_calls_tab, conf);
calltree_add_conference_to_current_calls(conf);
} else if (calltree_source_type == A_CONFERENCE && calltree_dest_type == A_CONFERENCE) {
DEBUG("Dragged a conference on a conference");
if (gtk_tree_path_compare(dpath, spath) == 0) {
if (!current_calls_tab) {
ERROR("Error while joining the same conference");
return;
} }
DEBUG("Joined the same conference!"); GtkTreePath *source_path = gtk_tree_model_get_path(model, source_iter);
gtk_tree_view_expand_row(GTK_TREE_VIEW(current_calls_tab->view), path, FALSE); if (!gtk_tree_path_compare(source_path, dest_path)) {
} else { ERROR("invalid drop: source and dest are same");
if (!calltree_source_conf) { gtk_tree_path_free(source_path);
ERROR("Source conference is null while joining conferences"); return FALSE;
return; } else if (gtk_tree_path_is_ancestor(source_path, dest_path)) {
ERROR("invalid drop: source is ancestor of dest");
gtk_tree_path_free(source_path);
return FALSE;
} else if (gtk_tree_path_is_descendant(source_path, dest_path)) {
ERROR("invalid drop: source is descendant of dest");
gtk_tree_path_free(source_path);
return FALSE;
} }
gtk_tree_path_free(source_path);
if (!calltree_dest_conf) { GValue dest_val = G_VALUE_INIT;
ERROR("Dest conference is null while joining conferences"); gtk_tree_model_get_value(model, &dest_iter, COLUMN_ID, &dest_val);
return; const gchar *dest_ID = g_value_get_string(&dest_val);
} GValue source_val = G_VALUE_INIT;
gtk_tree_model_get_value(model, source_iter, COLUMN_ID, &source_val);
const gchar *source_ID = g_value_get_string(&source_val);
DEBUG("Joined conferences %s and %s!\n", calltree_dest_path, calltree_source_path); gboolean result;
dbus_join_conference(calltree_source_conf->_confID, calltree_dest_conf->_confID); switch (dest_pos) {
} case GTK_TREE_VIEW_DROP_BEFORE:
} else { DEBUG("DROP_BEFORE, ignoring for now");
ERROR("Unexpected drag and drop scenario"); result = FALSE;
// TODO: dragged a single call on a NULL element (should do nothing) break;
// TODO: dragged a conference on a NULL element (should do nothing) case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
} /* fallthrough */
} else if (calltree_dest_path_depth == 2) { case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
if (calltree_source_type == A_CALL && calltree_dest_type == A_CALL) { {
// TODO: dragged a call on a conference call DEBUG("DROP_INTO");
calltree_remove_call(current_calls_tab, calltree_source_call->_callID); GtkTreeIter iter_parent;
calltree_add_call(current_calls_tab, calltree_source_call, NULL); if (!gtk_tree_model_iter_parent(model, &iter_parent, &dest_iter)) {
if (is_conference(model, &dest_iter)) {
} else if (calltree_source_type == A_CONFERENCE && calltree_dest_type == A_CALL) { if (is_conference(model, source_iter)) {
// TODO: dragged a conference on a conference call DEBUG("dropped conference on conference, merging conferences");
calltree_remove_conference(current_calls_tab, calltree_source_conf); dbus_join_conference(source_ID, dest_ID);
calltree_add_conference_to_current_calls(calltree_source_conf);
} else {
ERROR("Unexpected drag and drop scenario");
// TODO: dragged a single call on a NULL element
// TODO: dragged a conference on a NULL element
}
} else { } else {
ERROR("Unexpected calltree dest path depth %d", calltree_dest_path_depth); DEBUG("dropped call on conference, adding a call to a conference");
sflphone_add_participant(source_ID, dest_ID);
} }
} else { } else {
if (calltree_dest_path_depth == 1) { DEBUG("Dropped call on call, creating new conference or transferring");
if (calltree_source_type == A_CALL && calltree_dest_type == A_CALL) { cleanup_popup_data(&popup_data);
DEBUG("Dragged a conference call on a call"); popup_data = g_new0(PopupData, 1);
sflphone_detach_participant(calltree_source_call_id); popup_data->source_ID = g_strdup(source_ID);
popup_data->dest_ID = g_strdup(dest_ID);
if (calltree_source_call && calltree_dest_call)
gtk_menu_popup(GTK_MENU(calltree_popupmenu), NULL, NULL, NULL, NULL, 0, 0); gtk_menu_popup(GTK_MENU(calltree_popupmenu), NULL, NULL, NULL, NULL, 0, 0);
} else if (calltree_source_type == A_CALL && calltree_dest_type == A_CONFERENCE) {
// dragged a conference call on a conference
sflphone_detach_participant(calltree_source_call_id);
if (calltree_source_call && calltree_dest_conf) {
DEBUG("Adding a participant, since dragged call on a conference");
sflphone_add_participant(calltree_source_call_id, calltree_dest_call_id);
} }
} else { } else {
DEBUG("Dragged a conference call on a NULL element"); callable_obj_t *dest_call = calllist_get_call(current_calls_tab, dest_ID);
sflphone_detach_participant(calltree_source_call_id); if (dest_call && dest_call->_confID) {
} DEBUG("dropped call on participant, adding a call to a conference");
} else if (calltree_dest_path_depth == 2) { sflphone_add_participant(source_ID, dest_call->_confID);
DEBUG("Dragged a conference call on another conference call (same conference)");
// TODO: dragged a conference call on another conference call (different conference)
gtk_tree_path_up(path);
// conference for which this call is attached
GtkTreeIter parent;
if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &parent, path)) {
ERROR("Could not find parent conference");
return;
}
gtk_tree_path_up(dpath);
gtk_tree_path_up(spath);
if (gtk_tree_path_compare(dpath, spath) == 0) {
DEBUG("Dragged a call in the same conference");
calltree_remove_call(current_calls_tab, calltree_source_call->_callID);
calltree_add_call(current_calls_tab, calltree_source_call, &parent);
gtk_widget_hide(calltree_menu_items);
gtk_menu_popup(GTK_MENU(calltree_popupmenu), NULL, NULL, NULL, NULL,
0, 0);
} else {
DEBUG("Dragged a conference call onto another conference call %s, %s", gtk_tree_path_to_string(dpath), gtk_tree_path_to_string(spath));
conference_obj_t *conf = NULL;
GtkTreeIter iter;
if (gtk_tree_model_get_iter(model, &iter, dpath)) {
if (is_conference(model, &iter)) {
gchar *id;
gtk_tree_model_get(model, &iter, COLUMN_ID, &id, -1);
conf = conferencelist_get(current_calls_tab, id);
g_free(id);
} }
} }
result = TRUE;
sflphone_detach_participant(calltree_source_call_id); break;
if (conf)
sflphone_add_participant(calltree_source_call_id, conf->_confID);
else
ERROR("Didn't find a conference!");
}
} else {
ERROR("Unexpected calltree dragged path depth");
// TODO: dragged a conference call on another conference call (different conference)
// TODO: dragged a conference call on a NULL element (same conference)
// TODO: dragged a conference call on a NULL element (different conference)
}
}
}
static void determine_drop_path(GtkTreeView *treeView) {
if (active_calltree_tab == history_tab) {
g_signal_stop_emission_by_name(G_OBJECT(treeView), "drag_data_received");
return;
}
GtkTreeModel* tree_model = gtk_tree_view_get_model(treeView);
GtkTreeViewDropPosition position;
GtkTreePath *drop_path;
gtk_tree_view_get_drag_dest_row(treeView, &drop_path, &position);
if (drop_path) {
gchar *drop_path_str = gtk_tree_path_to_string(drop_path);
DEBUG("Got drop path %s", drop_path_str);
g_free(drop_path_str);
GtkTreeIter iter;
gtk_tree_model_get_iter(tree_model, &iter, drop_path);
gchar *id;
gtk_tree_model_get(tree_model, &iter, COLUMN_ID, &id, -1);
if (is_conference(tree_model, &iter)) {
DEBUG("Destination is a conference");
calltree_dest_type = A_CONFERENCE;
calltree_dest_call = NULL;
} else {
DEBUG("Destination is a call");
calltree_dest_type = A_CALL;
calltree_dest_conf = NULL;
} }
DEBUG("Position %d", position);
switch (position) {
case GTK_TREE_VIEW_DROP_BEFORE:
/* fallthrough */
case GTK_TREE_VIEW_DROP_AFTER: case GTK_TREE_VIEW_DROP_AFTER:
g_free(calltree_dest_path); DEBUG("DROP_AFTER, ignoring for now");
calltree_dest_path = gtk_tree_path_to_string(drop_path); result = FALSE;
calltree_dest_path_depth = gtk_tree_path_get_depth(drop_path);
calltree_dest_call_id = NULL;
calltree_dest_call = NULL;
calltree_dest_conf = NULL;
break; break;
default:
case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: ERROR("Unexpected position");
/* fallthrough */ result = FALSE;
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
g_free(calltree_dest_path);
calltree_dest_path = gtk_tree_path_to_string(drop_path);
calltree_dest_path_depth = gtk_tree_path_get_depth(drop_path);
if (calltree_dest_type == A_CALL) {
calltree_dest_call_id = g_strdup(id);
calltree_dest_call = calllist_get_call(current_calls_tab, id);
} else {
calltree_dest_call_id = g_strdup(id);
calltree_dest_conf = conferencelist_get(current_calls_tab, id);
}
g_free(id);
break; break;
} }
g_value_unset(&dest_val);
g_value_unset(&source_val);
return result;
} }
void drag_data_received_cb(GtkWidget *widget, GdkDragContext *context, gint x UNUSED,
gint y UNUSED, GtkSelectionData *selection_data UNUSED, guint target_type UNUSED, guint etime, gpointer data UNUSED)
}
static void drag_end_cb(GtkWidget * widget, GdkDragContext * context UNUSED, gpointer data UNUSED)
{ {
perform_action_after_drag(GTK_TREE_VIEW(widget)); GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
GtkTreeModel *model = GTK_TREE_MODEL(gtk_tree_view_get_model(tree_view));
GtkTreeSelection *tree_selection = gtk_tree_view_get_selection(tree_view);
GtkTreeIter source_iter;
if (!gtk_tree_selection_get_selected(tree_selection, NULL, &source_iter)) {
ERROR("No tree element selected");
return;
} }
GtkTreePath *dest_path;
void drag_history_received_cb(GtkWidget *widget, GdkDragContext *context UNUSED, gint x UNUSED, gint y UNUSED, GtkSelectionData *selection_data UNUSED, guint info UNUSED, guint t UNUSED, gpointer data UNUSED) GtkTreeViewDropPosition dest_pos;
{ if (!gtk_tree_view_get_dest_row_at_pos(tree_view, x, y, &dest_path, &dest_pos)) {
g_signal_stop_emission_by_name(G_OBJECT(widget), "drag_data_received"); ERROR("No row at given position");
return;
} }
void drag_data_received_cb(GtkWidget *widget, GdkDragContext *context, gint x UNUSED, gboolean success = render_drop(model, dest_path, dest_pos, &source_iter);
gint y UNUSED, GtkSelectionData *selection_data, guint target_type UNUSED, guint etime, gpointer data UNUSED) if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_MOVE)
{ gtk_drag_finish(context, success, TRUE, etime);
determine_drop_path(GTK_TREE_VIEW(widget));
} }
/* Print a string when a menu item is selected */ /* Print a string when a menu item is selected */
static void menuitem_response(gchar * string) static void
menuitem_response(gchar * string)
{ {
if (g_strcmp0(string, SFL_CREATE_CONFERENCE) == 0) { if (g_strcmp0(string, SFL_CREATE_CONFERENCE) == 0) {
dbus_join_participant(calltree_source_call_for_drag->_callID, dbus_join_participant(popup_data->source_ID,
calltree_dest_call->_callID); popup_data->dest_ID);
calltree_remove_call(current_calls_tab, calltree_source_call->_callID); calltree_remove_call(current_calls_tab, popup_data->source_ID);
calltree_remove_call(current_calls_tab, calltree_dest_call->_callID); calltree_remove_call(current_calls_tab, popup_data->dest_ID);
} } else if (g_strcmp0(string, SFL_TRANSFER_CALL) == 0) {
else if (g_strcmp0(string, SFL_TRANSFER_CALL) == 0) { callable_obj_t * source_call = calllist_get_call(current_calls_tab, popup_data->source_ID);
callable_obj_t * dest_call = calllist_get_call(current_calls_tab, popup_data->dest_ID);
DEBUG("Transferring call %s, to %s", DEBUG("Transferring call %s, to %s",
calltree_source_call->_peer_number, source_call->_peer_number,
calltree_dest_call->_peer_number); dest_call->_peer_number);
dbus_attended_transfer(calltree_source_call, calltree_dest_call); dbus_attended_transfer(source_call, dest_call);
calltree_remove_call(current_calls_tab, calltree_source_call->_callID); calltree_remove_call(current_calls_tab, popup_data->source_ID);
} else } else
ERROR("Unknown option in menu %s", string); ERROR("Unknown option in menu %s", string);
...@@ -1564,6 +1313,8 @@ static void menuitem_response(gchar * string) ...@@ -1564,6 +1313,8 @@ static void menuitem_response(gchar * string)
// The create conference option will hide if tow call from the same conference are draged on each other // The create conference option will hide if tow call from the same conference are draged on each other
gtk_widget_show(calltree_menu_items); gtk_widget_show(calltree_menu_items);
cleanup_popup_data(&popup_data);
DEBUG("%s", string); DEBUG("%s", string);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment