Commit 3f096355 authored by Rafaël Carré's avatar Rafaël Carré

* #6929 : fix IM widget, cleanup

parent 21baf7b7
......@@ -384,10 +384,6 @@ sflphone_hang_up()
selectedCall->_state = CALL_STATE_DIALING;
time (&selectedCall->_time_stop);
//if ( (im_window_get_nb_tabs() > 1) && selectedCall->_im_widget &&
// ! (IM_WIDGET (selectedCall->_im_widget)->containText))
// im_window_remove_tab (selectedCall->_im_widget);
//else
im_widget_update_state (IM_WIDGET (selectedCall->_im_widget), FALSE);
break;
......@@ -436,7 +432,8 @@ sflphone_pick_up()
// if instant messaging window is visible, create new tab (deleted automatically if not used)
if (im_window_is_visible())
im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
if (!selectedCall->_im_widget)
selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
break;
case CALL_STATE_INCOMING:
......@@ -444,9 +441,9 @@ sflphone_pick_up()
calltree_update_call (history, selectedCall, NULL);
// if instant messaging window is visible, create new tab (deleted automatically if not used)
if (selectedCall->_im_widget && im_window_is_visible()) {
im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
}
if (im_window_is_visible())
if (!selectedCall->_im_widget)
selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
dbus_accept (selectedCall);
break;
......@@ -896,9 +893,7 @@ sflphone_detach_participant (const gchar* callID)
g_free (selectedCall->_confID);
selectedCall->_confID = NULL;
}
// Instant messaging widget should have been deactivated during the conference
if (selectedCall->_im_widget)
im_widget_update_state (IM_WIDGET (selectedCall->_im_widget), TRUE);
im_widget_update_state (IM_WIDGET (selectedCall->_im_widget), TRUE);
calltree_remove_call (current_calls, selectedCall, NULL);
calltree_add_call (current_calls, selectedCall, NULL);
dbus_detach_participant (selectedCall->_callID);
......
......@@ -122,17 +122,15 @@ voice_mail_cb (DBusGProxy *proxy UNUSED, const gchar* accountID, const guint nb,
static void
incoming_message_cb (DBusGProxy *proxy UNUSED, const gchar* callID UNUSED, const gchar *from, const gchar* msg, void * foo UNUSED)
{
DEBUG ("DBUS: Message \"%s\" from %s!", msg, from);
// do not display message if instant messaging is disabled
if (eel_gconf_key_exists (INSTANT_MESSAGING_ENABLED) && !eel_gconf_get_integer (INSTANT_MESSAGING_ENABLED))
return;
IMWidget **widget;
GtkWidget **widget;
gchar *id;
callable_obj_t *call = calllist_get_call (current_calls, callID);
if (call) {
widget = (IMWidget **) &call->_im_widget;
widget = &call->_im_widget;
id = call->_callID;
} else {
conference_obj_t *conf = conferencelist_get (current_calls, callID);
......@@ -140,12 +138,14 @@ incoming_message_cb (DBusGProxy *proxy UNUSED, const gchar* callID UNUSED, const
ERROR ("Message received, but no recipient found");
return;
}
widget = (IMWidget **) &conf->_im_widget;
widget = &conf->_im_widget;
id = conf->_confID;
}
if (im_widget_display (widget, msg, id, from))
im_widget_add_message (*widget, from, msg, 0);
if (!*widget)
*widget = im_widget_display(id);
im_widget_add_message (IM_WIDGET(*widget), from, msg, 0);
}
static void
......@@ -211,7 +211,7 @@ static void toggle_im(conference_obj_t *conf, gboolean activate)
{
for (GSList *part = conf->participant_list; part; part = g_slist_next (part)) {
callable_obj_t *call = calllist_get_call (current_calls, part->data);
if (call && call->_im_widget)
if (call)
im_widget_update_state (IM_WIDGET (call->_im_widget), activate);
}
}
......@@ -282,9 +282,7 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
// set when this call have been added to the conference
time(&call->_time_added);
// if a text widget is already created, disable it, use conference widget instead
if (call->_im_widget)
im_widget_update_state (IM_WIDGET (call->_im_widget), FALSE);
im_widget_update_state (IM_WIDGET (call->_im_widget), FALSE);
// if one of these participant is currently recording, the whole conference will be recorded
if(call->_state == CALL_STATE_RECORD)
......@@ -312,9 +310,7 @@ conference_removed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
conference_obj_t * c = conferencelist_get (current_calls, confID);
calltree_remove_conference (current_calls, c, NULL);
// deactivate instant messaging window for this conference
if (c->_im_widget)
im_widget_update_state (IM_WIDGET (c->_im_widget), FALSE);
im_widget_update_state (IM_WIDGET (c->_im_widget), FALSE);
// remove all participant for this conference
for (GSList *p = c->participant_list; p; p = conference_next_participant (p)) {
......@@ -324,9 +320,7 @@ conference_removed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
g_free (call->_confID);
call->_confID = NULL;
// if an instant messaging was previously disabled, enabled it
if (call->_im_widget)
im_widget_update_state (IM_WIDGET (call->_im_widget), TRUE);
im_widget_update_state(IM_WIDGET (call->_im_widget), TRUE);
}
}
......
......@@ -83,15 +83,11 @@ on_delete (GtkWidget * widget UNUSED, gpointer data UNUSED)
static void
on_switch_page (GtkNotebook *notebook, GtkNotebookPage *page UNUSED, guint page_num, gpointer userdata UNUSED)
{
guint index = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
GtkWidget *tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num);
// show the current widget
gtk_widget_grab_focus (tab);
gtk_widget_show_now (tab);
DEBUG ("InstantMessaging: switch to %i - current = %i\n", page_num, index);
}
static void
......@@ -141,6 +137,7 @@ im_window_init()
// Restore position according to the configuration stored in gconf
gtk_window_move (GTK_WINDOW (im_window), position_x, position_y);
gtk_widget_set_visible(im_window, FALSE);
}
gboolean
......@@ -155,28 +152,15 @@ im_window_is_active ()
gboolean
im_window_is_visible ()
{
return gtk_widget_get_visible (GTK_WIDGET(im_window_get()));
}
void
im_window_show ()
{
gtk_window_present (im_window_get ());
return gtk_widget_get_visible(GTK_WIDGET(im_window_get()));
}
void
im_window_add (GtkWidget *widget)
{
if (im_window_get()) {
/* Add the new tab to the notebook */
im_window_add_tab (widget);
/* Show it all */
gtk_widget_show_all (GTK_WIDGET(im_window_get()));
}
else {
ERROR ("InstantMessaging: Error: Could not create the main instant messaging window");
}
}
......@@ -199,6 +183,14 @@ close_tab_cb (GtkButton *button UNUSED, gpointer userdata)
// gtk_widget_destroy (im_window);
}
static void
im_window_hide_show_tabs ()
{
/* If only one tab is open, do not display the tab, only the content */
gtk_notebook_set_show_tabs(GTK_NOTEBOOK (im_notebook),
gtk_notebook_get_n_pages (GTK_NOTEBOOK (im_notebook)) != 1);
}
void
im_window_add_tab (GtkWidget *widget)
{
......@@ -247,17 +239,6 @@ im_window_add_tab (GtkWidget *widget)
im_window_hide_show_tabs ();
}
void
im_window_hide_show_tabs ()
{
/* If only one tab is open, do not display the tab, only the content */
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (im_notebook)) == 1) {
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (im_notebook), FALSE);
} else
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (im_notebook), TRUE);
}
void
im_window_show_tab (GtkWidget *widget)
{
......
......@@ -52,8 +52,6 @@ void im_window_add (GtkWidget *widget);
*/
void im_window_remove_tab (GtkWidget *widget);
void im_window_show ();
/**
* Return wether the instant messaging window have been created or not
*/
......@@ -75,11 +73,6 @@ gint im_window_get_nb_tabs (void);
*/
void im_window_add_tab (GtkWidget *widget);
/*! @function
@abstract Decide whether or not the notebook should display its tab. Display the tabs only if more than one tab is opened.
*/
void im_window_hide_show_tabs ();
/*! @function
@abstract Select the specified tab as current in instant messaging window
@param The tab to be set as current
......
......@@ -577,14 +577,16 @@ call_im(void* foo UNUSED)
conference_obj_t *selectedConf = calltab_get_selected_conf(current_calls);
if (calltab_get_selected_type(current_calls) == A_CALL) {
if (selectedCall)
im_widget_display((IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
else
if (selectedCall) {
if (!selectedCall->_im_widget)
selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
} else
WARN("Sorry. Instant messaging is not allowed outside a call\n");
} else {
if (selectedConf)
im_widget_display((IMWidget **) (&selectedConf->_im_widget), NULL, selectedConf->_confID, NULL);
else
if (selectedConf) {
if (!selectedConf->_im_widget)
selectedConf->_im_widget = im_widget_display(selectedConf->_confID);
} else
WARN("Sorry. Instant messaging is not allowed outside a call\n");
}
}
......
......@@ -35,6 +35,7 @@
#include <JavaScriptCore/JavaScript.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <assert.h>
#include "sflphone_const.h"
......@@ -44,84 +45,81 @@ static void
on_frame_loading_done (GObject *gobject UNUSED, GParamSpec *pspec UNUSED, gpointer user_data)
{
IMWidget *im = IM_WIDGET (user_data);
callable_obj_t *call;
conference_obj_t *conf;
if (im->first_message && im->first_message_from) {
switch (webkit_web_frame_get_load_status (WEBKIT_WEB_FRAME (im->web_frame))) {
case WEBKIT_LOAD_PROVISIONAL:
case WEBKIT_LOAD_COMMITTED:
break;
case WEBKIT_LOAD_FINISHED:
call = calllist_get_call (current_calls, im->call_id);
conf = conferencelist_get (current_calls, im->call_id);
if (call)
im_widget_add_message (im, im->first_message_from, im->first_message, 0);
if (conf)
im_widget_add_message (im, im->first_message_from, im->first_message, 0);
g_free (im->first_message);
g_free (im->first_message_from);
im->first_message = NULL;
im->first_message_from = NULL;
DEBUG ("InstantMessaging: JavaScrip loading frame finished");
break;
case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
// case WEBKIT_LOAD_FAILED: // only available in webkit-1.0-2
break;
case WEBKIT_LOAD_FAILED:
DEBUG("InstantMessaging: Webkit load failed");
break;
default:
ERROR("InstantMessaging: Error: Not a valid case in switch");
break;
}
}
if (!im->first_message || !im->first_message_from)
return;
switch (webkit_web_frame_get_load_status (WEBKIT_WEB_FRAME (im->web_frame))) {
case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
case WEBKIT_LOAD_PROVISIONAL:
case WEBKIT_LOAD_COMMITTED:
break;
case WEBKIT_LOAD_FINISHED:
if (calllist_get_call (current_calls, im->call_id))
im_widget_add_message (im, im->first_message_from, im->first_message, 0);
if (conferencelist_get (current_calls, im->call_id))
im_widget_add_message (im, im->first_message_from, im->first_message, 0);
g_free(im->first_message);
g_free(im->first_message_from);
im->first_message = NULL;
im->first_message_from = NULL;
break;
case WEBKIT_LOAD_FAILED:
DEBUG("InstantMessaging: Webkit load failed");
break;
}
}
gchar *
static gchar *
escape_single_quotes (const gchar *message)
{
gchar **ptr_token;
gchar *string = "";
gchar **ptr_token = g_strsplit(message, "'", 0);
gchar *string = g_strjoinv("\\'", ptr_token);
DEBUG ("InstantMessaging: message: %s", message);
g_strfreev(ptr_token);
return string;
}
if ( (ptr_token = g_strsplit (message, "'", 0))) {
string = g_strjoinv ("\\'", ptr_token);
}
static gchar*
im_widget_add_message_time ()
{
time_t now;
char str[100];
return string;
/* Compute the current time */
time (&now);
const struct tm* ptr = localtime (&now);
/* Get the time of the message. Format: HH:MM::SS */
strftime(str, sizeof(str), "%R", (const struct tm *) ptr);
return g_strdup(str);
}
void
im_widget_add_message (IMWidget *im, const gchar *from, const gchar *message, gint level)
{
if (im) {
assert(im);
/* Compute the date the message was sent */
gchar *msgtime = im_widget_add_message_time ();
/* Compute the date the message was sent */
gchar *msgtime = im_widget_add_message_time ();
/* Check for the message level */
gchar *css_class = (level == MESSAGE_LEVEL_ERROR) ? "error" : "";
gchar *css_class = (level == MESSAGE_LEVEL_ERROR) ? "error" : "";
gchar *message_escaped = escape_single_quotes (message);
gchar *message_escaped = escape_single_quotes (message);
/* Prepare and execute the Javascript code */
gchar *script = g_strdup_printf ("add_message('%s', '%s', '%s', '%s');", message_escaped, from, css_class, msgtime);
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (im->web_view), script);
/* Prepare and execute the Javascript code */
gchar *script = g_strdup_printf ("add_message('%s', '%s', '%s', '%s');", message_escaped, from, css_class, msgtime);
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (im->web_view), script);
/* Mark it as used */
im->containText = TRUE;
/* Mark it as used */
im->containText = TRUE;
/* Cleanup */
g_free (script);
g_free (message_escaped);
g_free (msgtime);
}
/* Cleanup */
g_free (script);
g_free (message_escaped);
g_free (msgtime);
}
static gboolean
......@@ -193,30 +191,9 @@ on_Textview_changed (GtkWidget *widget UNUSED, GdkEventKey *event, gpointer user
return FALSE;
}
gchar*
im_widget_add_message_time ()
{
time_t now;
unsigned char str[100];
/* Compute the current time */
(void) time (&now);
struct tm* ptr;
ptr = localtime (&now);
/* Get the time of the message. Format: HH:MM::SS */
strftime ( (char *) str, 100, "%R", (const struct tm *) ptr);
gchar *res = g_strdup ( (gchar *) str);
/* Return the new value */
return res;
}
void
im_widget_send_message (gchar *id, const gchar *message)
im_widget_send_message (const gchar *id, const gchar *message)
{
callable_obj_t *im_widget_call = calllist_get_call (current_calls, id);
conference_obj_t *im_widget_conf = conferencelist_get (current_calls, id);
......@@ -228,9 +205,7 @@ im_widget_send_message (gchar *id, const gchar *message)
if (im_widget_conf) {
dbus_send_text_message (id, message);
}
/* First check if the call is in CURRENT state, otherwise it could not be sent */
else if (im_widget_call) {
} else if (im_widget_call) {
if (im_widget_call->_type == CALL && (im_widget_call->_state == CALL_STATE_CURRENT ||
im_widget_call->_state == CALL_STATE_HOLD ||
im_widget_call->_state == CALL_STATE_RECORD)) {
......@@ -290,19 +265,6 @@ im_widget_init (IMWidget *im)
g_signal_connect (G_OBJECT (im->web_frame), "notify", G_CALLBACK (on_frame_loading_done), im);
}
GtkWidget *
im_widget_new()
{
return GTK_WIDGET (g_object_new (IM_WIDGET_TYPE, NULL));
}
GtkWidget *
im_widget_new_with_first_message (const gchar *message UNUSED)
{
return GTK_WIDGET (g_object_new (IM_WIDGET_TYPE, NULL));
}
GType
im_widget_get_type (void)
{
......@@ -332,66 +294,39 @@ im_widget_get_type (void)
return im_widget_type;
}
gboolean
im_widget_display (IMWidget **im, const gchar *message, const gchar *id, const gchar *from)
{
/* Work with a copy of the object */
// callable_obj_t *tmp = *call;
/* Use the widget for this specific call, if exists */
// if (tmp) {
IMWidget *imwidget = *im;// = IM_WIDGET (tmp->_im_widget);
if (!imwidget) {
DEBUG ("creating the im widget for this call\n");
/* Create the im object, first message must be created asynchronously */
if (message)
imwidget = IM_WIDGET (im_widget_new ());
else
imwidget = IM_WIDGET (im_widget_new_with_first_message (message));
/* Keep a reference on this object in the call struct */
// tmp->_im_widget = im;
// *call = tmp;
/* Update the widget with some useful call information: ie the call ID */
imwidget->call_id = (gchar *)id;
/* Create the GtkInfoBar, used to display call information, and status of the IM widget */
im_widget_infobar (imwidget);
/* Add it to the main instant messaging window */
im_window_add (GTK_WIDGET (imwidget));
/* Update the first message to appears at widget creation*/
if (message)
imwidget->first_message = g_strdup (message);
if (from)
imwidget->first_message_from = g_strdup (from);
*im = imwidget;
return FALSE;
} else {
DEBUG ("im widget exists for this call\n");
im_window_show ();
return TRUE;
static GtkWidget*
conf_state_image_widget (conference_state_t state)
{
switch (state) {
case CONFERENCE_STATE_ACTIVE_ATACHED:
case CONFERENCE_STATE_ACTIVE_DETACHED:
case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
case CONFERENCE_STATE_HOLD:
case CONFERENCE_STATE_HOLD_RECORD:
return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
default:
return gtk_image_new_from_stock(GTK_STOCK_FAIL, GTK_ICON_SIZE_LARGE_TOOLBAR);
}
}
// }
// return FALSE;
static GtkWidget*
call_state_image_widget (call_state_t state)
{
switch (state) {
case CALL_STATE_CURRENT:
case CALL_STATE_HOLD:
case CALL_STATE_RECORD:
return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
default:
return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
}
}
void
static void
im_widget_infobar (IMWidget *im)
{
/* Fetch the GTKInfoBar of this very IM Widget */
GtkWidget *infobar = im->info_bar;
GtkWidget *content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (infobar));
......@@ -405,7 +340,7 @@ im_widget_infobar (IMWidget *im)
if (im_widget_call)
msg1 = g_strdup_printf ("Calling %s %s", im_widget_call->_peer_number, im_widget_call->_peer_name);
else if (im_widget_conf)
msg1 = g_strdup_printf ("Conferencing"); // im_widget_conf->_confID);
msg1 = g_strdup_printf ("Conferencing");
else
msg1 = g_strdup ("");
......@@ -418,7 +353,6 @@ im_widget_infobar (IMWidget *im)
if (im_widget_conf)
im->info_state = conf_state_image_widget (im_widget_conf->_state);
/* Add a nice icon from our own icon factory */
GtkWidget *logoUser = gtk_image_new_from_stock (GTK_STOCK_USER, GTK_ICON_SIZE_LARGE_TOOLBAR);
/* Pack it all */
......@@ -426,76 +360,33 @@ im_widget_infobar (IMWidget *im)
gtk_container_add (GTK_CONTAINER (content_area), call_label);
gtk_container_add (GTK_CONTAINER (content_area), im->info_state);
/* Message level by default: INFO */
gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar), GTK_MESSAGE_INFO);
/* Show the info bar */
gtk_widget_show (infobar);
}
GtkWidget*
call_state_image_widget (call_state_t state)
GtkWidget *im_widget_display (const gchar *id)
{
IMWidget *imwidget = IM_WIDGET(g_object_new (IM_WIDGET_TYPE, NULL));
imwidget->call_id = id;
im_widget_infobar (imwidget);
im_window_add (GTK_WIDGET (imwidget));
GtkWidget *image;
switch (state) {
case CALL_STATE_CURRENT:
case CALL_STATE_HOLD:
case CALL_STATE_RECORD:
image = gtk_image_new_from_stock (GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
break;
default:
image = gtk_image_new_from_stock (GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
break;
}
return image;
return GTK_WIDGET(imwidget);
}
GtkWidget*
conf_state_image_widget (conference_state_t state)
{
GtkWidget *image;
switch (state) {
case CONFERENCE_STATE_ACTIVE_ATACHED:
case CONFERENCE_STATE_ACTIVE_DETACHED:
case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
case CONFERENCE_STATE_HOLD:
case CONFERENCE_STATE_HOLD_RECORD:
image = gtk_image_new_from_stock (GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
break;
default:
image = gtk_image_new_from_stock (GTK_STOCK_FAIL, GTK_ICON_SIZE_LARGE_TOOLBAR);