imwindow.c 8.81 KB
Newer Older
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
1
/*
2
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
 *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
 *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

#include <config.h>
#include <gtk/gtk.h>
#include <eel-gconf-extensions.h>
#include <sflphone_const.h>

#include <imwindow.h>
39
#include <contacts/calltab.h>
40
#include <contacts/calltab.h>
41
#include <sys/stat.h>
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
42 43

/** Local variables */
44 45
static GtkWidget *im_window = NULL;
static GtkWidget *im_notebook = NULL;
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
46

47 48 49 50 51 52 53 54 55 56 57

static void im_window_init();

static GtkWindow *im_window_get()
{
    if (im_window == NULL)
        im_window_init();

    return GTK_WINDOW(im_window);
}

58
static gboolean window_configure_cb (GtkWidget *wini UNUSED, GdkEventConfigure *event)
59 60
{
    int pos_x, pos_y;
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
61

62 63
    eel_gconf_set_integer (CONF_IM_WINDOW_WIDTH, event->width);
    eel_gconf_set_integer (CONF_IM_WINDOW_HEIGHT, event->height);
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
64

65
    gtk_window_get_position (im_window_get(), &pos_x, &pos_y);
66 67
    eel_gconf_set_integer (CONF_IM_WINDOW_POSITION_X, pos_x);
    eel_gconf_set_integer (CONF_IM_WINDOW_POSITION_Y, pos_y);
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
68

69
    return FALSE;
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
70 71 72 73 74
}

/**
 * Minimize the main window.
 */
75 76
static gboolean
on_delete (GtkWidget * widget UNUSED, gpointer data UNUSED)
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
77
{
78 79 80
    /* Only hide the main window that contains all the instant messaging instances */
    gtk_widget_hide (GTK_WIDGET (im_window_get()));
    return TRUE;
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
81 82
}

83
static void
84
on_switch_page (GtkNotebook *notebook, GtkNotebookPage *page UNUSED, guint page_num, gpointer userdata UNUSED)
Emmanuel Milou's avatar
Emmanuel Milou committed
85
{
86 87 88 89 90
    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);
Emmanuel Milou's avatar
Emmanuel Milou committed
91 92
}

93
static void
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
94 95
im_window_init()
{
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    const char *window_title = "SFLphone IM Client";
    int width, height, position_x, position_y;

    // Get configuration stored in gconf
    width = eel_gconf_get_integer (CONF_IM_WINDOW_WIDTH);

    if (width <= 0)
        width = 400;

    height = eel_gconf_get_integer (CONF_IM_WINDOW_HEIGHT);

    if (height <= 0)
        height = 500;

    position_x = eel_gconf_get_integer (CONF_IM_WINDOW_POSITION_X);
    position_y = eel_gconf_get_integer (CONF_IM_WINDOW_POSITION_Y);

    im_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width (GTK_CONTAINER (im_window), 0);
    gtk_window_set_title (GTK_WINDOW (im_window), window_title);
    gtk_window_set_default_size (GTK_WINDOW (im_window), width, height);
117 118 119
    struct stat st;
    if (!stat(LOGO, &st))
        gtk_window_set_default_icon_from_file (LOGO, NULL);
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
    gtk_window_set_position (GTK_WINDOW (im_window), GTK_WIN_POS_MOUSE);

    gtk_widget_set_name (im_window, "imwindow");

    GtkWidget *im_vbox = gtk_vbox_new (FALSE /*homogeneous*/, 0 /*spacing*/);
    im_notebook = gtk_notebook_new ();

    gtk_container_add (GTK_CONTAINER (im_window), im_vbox);
    gtk_box_pack_start (GTK_BOX (im_vbox), im_notebook, TRUE, TRUE, 0);
    gtk_widget_show (im_notebook);

    g_signal_connect (G_OBJECT (im_window), "delete-event", G_CALLBACK (on_delete), NULL);
    g_signal_connect_object (G_OBJECT (im_window), "configure-event", G_CALLBACK (window_configure_cb), NULL, 0);
    g_signal_connect (G_OBJECT (im_notebook), "switch-page", G_CALLBACK (on_switch_page), NULL);

    /* make sure that everything is visible */
    gtk_widget_show_all (im_window);

    // Restore position according to the configuration stored in gconf
    gtk_window_move (GTK_WINDOW (im_window), position_x, position_y);
140
    gtk_widget_set_visible(im_window, FALSE);
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
141 142
}

143 144 145 146 147 148
gboolean
im_window_is_active ()
{
    if (!im_window)
        return FALSE;
    else
149
        return gtk_window_is_active (GTK_WINDOW (im_window));
150 151 152 153 154
}

gboolean
im_window_is_visible ()
{
155
    return gtk_widget_get_visible(GTK_WIDGET(im_window_get()));
156 157
}

158
void
159
im_window_add (GtkWidget *widget)
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
160
{
161 162
    if (im_window_get()) {
        im_window_add_tab (widget);
163
        gtk_widget_show_all (GTK_WIDGET(im_window_get()));
164
    }
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
165 166
}

167 168 169
gint
im_window_get_nb_tabs()
{
170 171
    if (im_notebook != NULL)
        return gtk_notebook_get_n_pages (GTK_NOTEBOOK(im_notebook));
172 173 174 175
    else
        return 0;
}

176
static void
177
close_tab_cb (GtkButton *button UNUSED, gpointer userdata)
178
{
179 180
    /* We want here to close the current tab */
    im_window_remove_tab (GTK_WIDGET (userdata));
181

182 183
    /* If no tabs are opened anymore, close the IM window */
    // gtk_widget_destroy (im_window);
184 185
}

186 187 188 189 190 191 192 193
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);
}

194
void
195
im_window_add_tab (GtkWidget *widget)
196 197 198 199 200
{
    /* Cast the paramater */
    IMWidget *im = IM_WIDGET (widget);

    /* Fetch the call */
201
    callable_obj_t *im_widget_call = calllist_get_call (current_calls, im->call_id);
202
    conference_obj_t *im_widget_conf = conferencelist_get (current_calls, im->call_id);
203 204 205

    /* A container to include the tab label and the close button */
    GtkWidget *tab_Container = gtk_hbox_new (FALSE, 3);
206
    GtkWidget *tab_Label;
207
    im->tab = tab_Container;
208 209

    if (im_widget_call)
210
        tab_Label = gtk_label_new (*im_widget_call->_peer_name ? im_widget_call->_peer_name : im_widget_call->_peer_number);
211
    else if (im_widget_conf)
212
        tab_Label = gtk_label_new ("Conferencing");
213 214
    else
        tab_Label = gtk_label_new ("");
215

216 217 218 219 220 221 222 223 224 225 226 227
    GtkWidget *tab_CloseButton = gtk_button_new ();

    /* Pack it all */
    gtk_button_set_relief (GTK_BUTTON (tab_CloseButton), GTK_RELIEF_NONE);
    gtk_box_pack_start (GTK_BOX (tab_Container), tab_Label, TRUE, TRUE, 0);
    gtk_box_pack_start (GTK_BOX (tab_Container), tab_CloseButton, FALSE, FALSE, 0);
    gtk_container_add (GTK_CONTAINER (tab_CloseButton), gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));

    /* Connect a signal to the close button on each tab, to be able to close the tabs individually */
    g_signal_connect (tab_CloseButton, "clicked", G_CALLBACK (close_tab_cb), widget);

    /* Show it */
228
    gtk_widget_show_all (im_notebook);
229 230 231
    gtk_widget_show_all (tab_Container);

    /* Add the page to the notebook */
232
    guint tabIndex = gtk_notebook_append_page (GTK_NOTEBOOK (im_notebook), widget, tab_Container);
233 234

    /* TODO Switch to the newly opened tab. Still not working */
235
    DEBUG ("InstantMessaging: Switch to tab: %i", tabIndex);
236
    gtk_notebook_set_current_page (GTK_NOTEBOOK (im_notebook), -1);
237 238 239

    /* Decide whether or not displaying the tabs of the notebook */
    im_window_hide_show_tabs ();
Emmanuel Milou's avatar
Emmanuel Milou committed
240 241
}

242
void
243 244 245 246 247 248 249 250
im_window_show_tab (GtkWidget *widget)
{
    int pageIndex = gtk_notebook_page_num (GTK_NOTEBOOK (im_notebook), widget);

    if (pageIndex != -1)
        gtk_notebook_set_current_page (GTK_NOTEBOOK (im_notebook), pageIndex);
}

251
void
252
im_window_remove_tab (GtkWidget *widget)
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
253
{
254 255 256
    // Remove the widget from the window

    /* We want here to close the current tab */
257 258 259
    guint index = gtk_notebook_page_num (GTK_NOTEBOOK (im_notebook), GTK_WIDGET (widget));
    gtk_notebook_remove_page (GTK_NOTEBOOK (im_notebook), index);

260 261
    /* Need to do some memory clean up, so that we could re-open an Im widget for this call later. */
    IMWidget *im = IM_WIDGET (widget);
262
    callable_obj_t *call = calllist_get_call (current_calls, im->call_id);
263
    conference_obj_t *conf = conferencelist_get (current_calls, im->call_id);
264 265 266

    if (call)
        call->_im_widget = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
267

268
    if (conf)
269
        conf->_im_widget = NULL;
270

271 272
    /* Decide whether or not displaying the tabs of the notebook */
    im_window_hide_show_tabs ();
Jonas Fonseca's avatar
im  
Jonas Fonseca committed
273
}