Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
jami-daemon
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
savoirfairelinux
jami-daemon
Commits
72a075df
Commit
72a075df
authored
13 years ago
by
Tristan Matthews
Browse files
Options
Downloads
Patches
Plain Diff
* #10736: now able to join participants without globals
parent
4f901c39
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
gnome/src/contacts/calltree.c
+132
-381
132 additions, 381 deletions
gnome/src/contacts/calltree.c
with
132 additions
and
381 deletions
gnome/src/contacts/calltree.c
+
132
−
381
View file @
72a075df
...
@@ -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
,
GtkTreeP
at
h
*
sp
at
h
)
static
void
cleanup_popup_data
(
PopupD
at
a
*
*
d
at
a
)
{
{
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
->
_call
ID
);
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
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment