calltree.c 28.9 KB
Newer Older
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1 2
/*
 *  Copyright (C) 2007 Savoir-Faire Linux inc.
3
 *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
4
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
5
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
6 7
 *  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
8
 *  the Free Software Foundation; either version 3 of the License, or
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
9
 *  (at your option) any later version.
10
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
11 12 13 14
 *  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.
15
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
16 17 18 19 20
 *  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.
 */

21
#include <stdlib.h>
22 23
#include <glib/gprintf.h>

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
24
#include <gtk/gtk.h>
25
#include <actions.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
26 27
#include <calltree.h>
#include <calllist.h>
28
#include <menus.h>
29
#include <dbus.h>
Julien Bonjean's avatar
Julien Bonjean committed
30
#include <contactlist/eds.h>
31
#include "addressbook-config.h"
32

33
GtkWidget   * toolbar;
Emmanuel Milou's avatar
Emmanuel Milou committed
34
GtkToolItem * pickupButton;
35 36 37 38 39
GtkToolItem * callButton;
GtkToolItem * hangupButton;
GtkToolItem * holdButton;
GtkToolItem * transfertButton;
GtkToolItem * unholdButton;
40
GtkToolItem * mailboxButton;
alexandresavard's avatar
alexandresavard committed
41
GtkToolItem * recButton;
42 43 44
GtkToolItem * historyButton;
GtkToolItem * contactButton;

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
45
guint transfertButtonConnId; //The button toggled signal connection ID
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
46

47 48 49 50 51 52 53 54 55 56
void
free_call_t (call_t *c)
{
    g_free (c->callID);
    g_free (c->accountID);
    g_free (c->from);
    g_free (c->to);
    g_free (c);
}

57 58 59
/**
 * Show popup menu
 */
60
  static gboolean
61
popup_menu (GtkWidget *widget,
62
    gpointer   user_data UNUSED)
63 64 65
{
  show_popup_menu(widget, NULL);
  return TRUE;
66
}
Emmanuel Milou's avatar
Emmanuel Milou committed
67

Emmanuel Milou's avatar
Emmanuel Milou committed
68 69 70 71 72 73
  static gboolean
is_inserted( GtkWidget* button )
{
  return ( GTK_WIDGET(button)->parent == GTK_WIDGET( toolbar ) );
}

Emmanuel Milou's avatar
Emmanuel Milou committed
74
  static gboolean
Emmanuel Milou's avatar
Emmanuel Milou committed
75
button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUSED)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
76 77 78
{
  if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
  {
79 80 81 82 83 84 85 86 87 88
    if( active_calltree == current_calls )
    {
      show_popup_menu(widget,  event);
      return TRUE;
    }
    else
    {
      show_popup_menu_history(widget,  event);
      return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
89 90 91
  }
  return FALSE;
}
92
/**
93
 * Make a call
94
 */
95
  static void
96
call_button( GtkWidget *widget UNUSED, gpointer   data UNUSED)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
97
{
98 99 100 101 102 103
  call_t * selectedCall;
  call_t* new_call;
  gchar *to, *from;

  selectedCall = call_get_selected(active_calltree);
  
Emmanuel Milou's avatar
Emmanuel Milou committed
104 105
  if(call_list_get_size(current_calls)>0)
    sflphone_pick_up();
106
  
Emmanuel Milou's avatar
Emmanuel Milou committed
107
  else if(call_list_get_size(active_calltree) > 0){
108 109 110
    if( selectedCall)
    {
      printf("Calling a called num\n");
111

112 113 114 115 116 117 118 119 120 121
      to = g_strdup(call_get_number(selectedCall));
      from = g_strconcat("\"\" <", call_get_number(selectedCall), ">",NULL);

      create_new_call (to, from, CALL_STATE_DIALING, "", &new_call);

      printf("call : from : %s to %s\n", new_call->from, new_call->to);

      call_list_add(current_calls, new_call);
      update_call_tree_add(current_calls, new_call);
      sflphone_place_call(new_call);
122
      display_calltree (current_calls);
123
    }
124 125 126
    else
    {
      sflphone_new_call();
127
      display_calltree(current_calls);
128 129 130 131
    }
  }
  else
  {
Emmanuel Milou's avatar
Emmanuel Milou committed
132
    sflphone_new_call();
133
    display_calltree(current_calls);
134
  }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
135 136
}

137
/**
138
 * Hang up the line
139
 */
140
  static void
141
hang_up( GtkWidget *widget UNUSED, gpointer   data UNUSED)
142
{
Emmanuel Milou's avatar
Emmanuel Milou committed
143
  sflphone_hang_up();
144 145 146
}

/**
147
 * Hold the line
148
 */
149
  static void
150
hold( GtkWidget *widget UNUSED, gpointer   data UNUSED)
151
{
Emmanuel Milou's avatar
Emmanuel Milou committed
152
  sflphone_on_hold();
153 154 155 156 157
}

/**
 * Transfert the line
 */
158
  static void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
159
transfert  (GtkToggleToolButton *toggle_tool_button,
160
    gpointer             user_data UNUSED )
161
{
Emmanuel Milou's avatar
Emmanuel Milou committed
162 163 164 165 166 167 168 169 170
  gboolean up = gtk_toggle_tool_button_get_active(toggle_tool_button);
  if(up)
  {
    sflphone_set_transfert();
  }
  else
  {
    sflphone_unset_transfert();
  }
171 172
}

173 174 175
/**
 * Unhold call
 */
176
  static void
177
unhold( GtkWidget *widget UNUSED, gpointer   data UNUSED)
178
{
Emmanuel Milou's avatar
Emmanuel Milou committed
179
  sflphone_off_hold();
180
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
181

182
static void toggle_button_cb (GtkToggleToolButton *widget, gpointer user_data)
areversat's avatar
areversat committed
183
{
184 185
    calltab_t * to_switch;
    gboolean toggle;
186

187 188
    to_switch = (calltab_t*) user_data;
    toggle = gtk_toggle_tool_button_get_active (widget);
Emmanuel Milou's avatar
Emmanuel Milou committed
189

190
    g_print ("%i\n", toggle);
Emmanuel Milou's avatar
Emmanuel Milou committed
191

192
    (toggle)? display_calltree (to_switch) : display_calltree (current_calls);
193 194
}

195

196
void create_new_entry_in_contactlist (gchar *contact_name, gchar *contact_phone, contact_type_t type, GdkPixbuf *photo){
197 198 199
   
    gchar *from;
    call_t *new_call;
200
    GdkPixbuf *pixbuf;
201 202

    /* Check if the information is valid */
203
    if (g_strcasecmp (contact_phone, EMPTY_ENTRY) != 0){
204 205
        from = g_strconcat("\"" , contact_name, "\"<", contact_phone, ">", NULL);
        create_new_call (from, from, CALL_STATE_DIALING, "", &new_call);
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228

        // Attach a pixbuf to a contact
        if (photo) {
            attach_thumbnail (new_call, photo);
        }
        else {
            switch (type) {
                case CONTACT_PHONE_BUSINESS:
                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/face-monkey.svg", NULL);
                    break;
                case CONTACT_PHONE_HOME:
                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/home.svg", NULL);
                    break;
                case CONTACT_PHONE_MOBILE:
                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/users.svg", NULL);
                    break;
                default:
                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/contact_default.svg", NULL);
                    break;
            }
            attach_thumbnail (new_call, pixbuf);
        }

229 230 231 232 233
        call_list_add (contacts, new_call);
        update_call_tree_add(contacts, new_call);
    }
}

234
  static void
235
call_mailbox( GtkWidget* widget UNUSED, gpointer data UNUSED)
236
{
Emmanuel Milou's avatar
Emmanuel Milou committed
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
    account_t* current;
    call_t *mailbox_call;
    gchar *to, *from, *account_id;

    current = account_list_get_current ();
    if( current == NULL ) // Should not happens
        return;
  
    to = g_strdup(g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX));
    from = g_markup_printf_escaped(_("\"Voicemail\" <%s>"),  to);
    account_id = g_strdup (current->accountID);
  
    create_new_call (to, from, CALL_STATE_DIALING, account_id, &mailbox_call);
    g_print("TO : %s\n" , mailbox_call->to);
    call_list_add( current_calls , mailbox_call );
    update_call_tree_add( current_calls , mailbox_call );
    update_menus();
    sflphone_place_call( mailbox_call );
255
    display_calltree(current_calls);
256 257
}

alexandresavard's avatar
alexandresavard committed
258 259 260 261 262


/**
 * Static rec_button
 */
263
static void
alexandresavard's avatar
alexandresavard committed
264 265 266 267 268 269
rec_button( GtkWidget *widget UNUSED, gpointer   data UNUSED)
{
  sflphone_rec_call();
}


270
  void
271
toolbar_update_buttons ()
272
{
Emmanuel Milou's avatar
Emmanuel Milou committed
273 274 275 276 277 278
  gtk_widget_set_sensitive( GTK_WIDGET(callButton),       FALSE);
  gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     FALSE);
  gtk_widget_set_sensitive( GTK_WIDGET(holdButton),       FALSE);
  gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  FALSE);
  gtk_widget_set_sensitive( GTK_WIDGET(mailboxButton) ,   FALSE);
  gtk_widget_set_sensitive( GTK_WIDGET(unholdButton),     FALSE);
alexandresavard's avatar
alexandresavard committed
279
  gtk_widget_set_sensitive( GTK_WIDGET(recButton),        FALSE);
Emmanuel Milou's avatar
Emmanuel Milou committed
280 281
  g_object_ref(holdButton);
  g_object_ref(unholdButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
282 283
  if( is_inserted( GTK_WIDGET(holdButton) ) )   gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
  if( is_inserted( GTK_WIDGET(unholdButton) ) )	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(unholdButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
284 285 286
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), holdButton, 3);
  g_object_ref(callButton);
  g_object_ref(pickupButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
287 288
  if( is_inserted( GTK_WIDGET(callButton) ) )	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
  if( is_inserted( GTK_WIDGET(pickupButton) ) )	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(pickupButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
289
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), callButton, 0);
alexandresavard's avatar
alexandresavard committed
290
  //gtk_toolbar_insert(GTK_TOOLBAR(toolbar), recButton, 0);
Emmanuel Milou's avatar
Emmanuel Milou committed
291 292 293 294 295 296 297 298 299


  gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
  gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), FALSE);
  gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);

  call_t * selectedCall = call_get_selected(active_calltree);
  if (selectedCall)
  {
300
    switch(selectedCall->state)
Emmanuel Milou's avatar
Emmanuel Milou committed
301 302 303 304
    {
      case CALL_STATE_INCOMING:
	gtk_widget_set_sensitive( GTK_WIDGET(pickupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),	TRUE);
305
	g_object_ref(callButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
306 307 308 309 310 311 312
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), pickupButton, 0);
	break;
      case CALL_STATE_HOLD:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(unholdButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
313 314
	g_object_ref(holdButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
315 316 317 318 319 320 321 322 323
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), unholdButton, 3);
	break;
      case CALL_STATE_RINGING:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(callButton),     TRUE);
	break;
      case CALL_STATE_DIALING:
	if( active_calltree != history )  gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(pickupButton),       TRUE);
Emmanuel Milou's avatar
Emmanuel Milou committed
324 325
	g_object_ref(callButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
326 327 328 329 330 331 332
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), pickupButton, 0);
	break;
      case CALL_STATE_CURRENT:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(holdButton),       TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
alexandresavard's avatar
alexandresavard committed
333
        gtk_widget_set_sensitive( GTK_WIDGET(recButton),        TRUE);
Emmanuel Milou's avatar
Emmanuel Milou committed
334 335 336 337
	break;
      case CALL_STATE_BUSY:
      case CALL_STATE_FAILURE:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
338
	break;
339
      case CALL_STATE_TRANSFERT:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
340
	gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
341
	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), TRUE);
342
	gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
343 344 345 346 347
	gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(holdButton),       TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  TRUE);
	break;
348 349 350 351 352 353 354
      case CALL_STATE_RECORD:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(holdButton),       TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
        gtk_widget_set_sensitive( GTK_WIDGET(recButton),        TRUE);
	break;
Emmanuel Milou's avatar
Emmanuel Milou committed
355
      default:
356
	g_warning("Toolbar update - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
357 358 359
	break;
    }
  }
360
  else
Emmanuel Milou's avatar
Emmanuel Milou committed
361 362 363 364 365 366 367 368 369 370 371
  {
    if( account_list_get_size() > 0 )
    {
      gtk_widget_set_sensitive( GTK_WIDGET(callButton), TRUE );
      gtk_widget_set_sensitive( GTK_WIDGET(mailboxButton), TRUE );
    }
    else
    {
      gtk_widget_set_sensitive( GTK_WIDGET(callButton), FALSE);
    }
  }
372
}
alexandresavard's avatar
alexandresavard committed
373 374 375



376
/* Call back when the user click on a call in the list */
377 378
  static void
selected(GtkTreeSelection *sel, void* data UNUSED )
379
{
Emmanuel Milou's avatar
Emmanuel Milou committed
380 381 382
  GtkTreeIter  iter;
  GValue val;
  GtkTreeModel *model = (GtkTreeModel*)active_calltree->store;
383

Emmanuel Milou's avatar
Emmanuel Milou committed
384 385
  if (! gtk_tree_selection_get_selected (sel, &model, &iter))
    return;
386

Emmanuel Milou's avatar
Emmanuel Milou committed
387
  val.g_type = 0;
388
  gtk_tree_model_get_value (model, &iter, 2, &val);
389

Emmanuel Milou's avatar
Emmanuel Milou committed
390 391
  call_select(active_calltree, (call_t*) g_value_get_pointer(&val));
  g_value_unset(&val);
392

Emmanuel Milou's avatar
Emmanuel Milou committed
393
  toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
394 395
}

396
/* A row is activated when it is double clicked */
397 398 399
void  row_activated(GtkTreeView       *tree_view UNUSED,
    GtkTreePath       *path UNUSED,
    GtkTreeViewColumn *column UNUSED,
400
    void * data UNUSED)
401
{
402 403
  g_print("double click action\n");
  call_t* selectedCall;
404 405
  call_t* new_call;
  gchar *to, *from, *account_id;
406 407
  selectedCall = call_get_selected( active_calltree );

Emmanuel Milou's avatar
Emmanuel Milou committed
408 409
  if (selectedCall)
  {
410 411
    // Get the right event from the right calltree
    if( active_calltree == current_calls )
Emmanuel Milou's avatar
Emmanuel Milou committed
412
    {
413
      switch(selectedCall->state)
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
      {
	case CALL_STATE_INCOMING:
	  dbus_accept(selectedCall);
	  break;
	case CALL_STATE_HOLD:
	  dbus_unhold(selectedCall);
	  break;
	case CALL_STATE_RINGING:
	case CALL_STATE_CURRENT:
	case CALL_STATE_BUSY:
	case CALL_STATE_FAILURE:
	  break;
	case CALL_STATE_DIALING:
	  sflphone_place_call (selectedCall);
	  break;
	default:
430
	  g_warning("Row activated - Should not happen!");
431 432
	  break;
      }
Emmanuel Milou's avatar
Emmanuel Milou committed
433
    }
434
    // if history
435 436
    else
    {
437 438 439 440 441 442 443 444 445
      to = g_strdup(call_get_number(selectedCall));
      from = g_strconcat("\"\" <", call_get_number(selectedCall), ">",NULL);
      account_id = g_strdup (selectedCall->accountID);

      create_new_call (to, from, CALL_STATE_DIALING, account_id, &new_call);

      call_list_add(current_calls, new_call);
      update_call_tree_add(current_calls, new_call);
      sflphone_place_call(new_call);
446
      display_calltree(current_calls);
447 448 449
    }
  }
}
450

451
  GtkWidget *
areversat's avatar
areversat committed
452 453
create_toolbar ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
454 455 456 457 458 459 460 461 462
  GtkWidget *ret;
  GtkWidget *image;

  ret = gtk_toolbar_new();
  toolbar = ret;

  gtk_toolbar_set_orientation(GTK_TOOLBAR(ret), GTK_ORIENTATION_HORIZONTAL);
  gtk_toolbar_set_style(GTK_TOOLBAR(ret), GTK_TOOLBAR_ICONS);

463 464
  image = gtk_image_new_from_file( ICONS_DIR "/call.svg");
  callButton = gtk_tool_button_new (image, _("Place a call"));
465
#if GTK_CHECK_VERSION(2,12,0)
466
  gtk_widget_set_tooltip_text(GTK_WIDGET(callButton), _("Place a call"));
467
#endif
468 469 470
  g_signal_connect (G_OBJECT (callButton), "clicked",
      G_CALLBACK (call_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(callButton), -1);
471

472 473
  image = gtk_image_new_from_file( ICONS_DIR "/accept.svg");
  pickupButton = gtk_tool_button_new(image, _("Pick up"));
474
#if GTK_CHECK_VERSION(2,12,0)
475
  gtk_widget_set_tooltip_text(GTK_WIDGET(pickupButton), _("Pick up"));
476
#endif
477
  gtk_widget_set_state( GTK_WIDGET(pickupButton), GTK_STATE_INSENSITIVE);
478
  g_signal_connect(G_OBJECT (pickupButton), "clicked",
479 480
      G_CALLBACK (call_button), NULL);
  gtk_widget_show_all(GTK_WIDGET(pickupButton));
481

482 483
  image = gtk_image_new_from_file( ICONS_DIR "/hang_up.svg");
  hangupButton = gtk_tool_button_new (image, _("Hang up"));
484
#if GTK_CHECK_VERSION(2,12,0)
485
  gtk_widget_set_tooltip_text(GTK_WIDGET(hangupButton), _("Hang up"));
486
#endif
487 488 489
  gtk_widget_set_state( GTK_WIDGET(hangupButton), GTK_STATE_INSENSITIVE);
  g_signal_connect (G_OBJECT (hangupButton), "clicked",
      G_CALLBACK (hang_up), NULL);
490
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(hangupButton), -1);
491

492 493
  image = gtk_image_new_from_file( ICONS_DIR "/unhold.svg");
  unholdButton = gtk_tool_button_new (image, _("Off Hold"));
494
#if GTK_CHECK_VERSION(2,12,0)
495
  gtk_widget_set_tooltip_text(GTK_WIDGET(unholdButton), _("Off Hold"));
496
#endif
497 498 499 500 501 502 503 504
  gtk_widget_set_state( GTK_WIDGET(unholdButton), GTK_STATE_INSENSITIVE);
  g_signal_connect (G_OBJECT (unholdButton), "clicked",
      G_CALLBACK (unhold), NULL);
  //gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(unholdButton), -1);
  gtk_widget_show_all(GTK_WIDGET(unholdButton));

  image = gtk_image_new_from_file( ICONS_DIR "/hold.svg");
  holdButton =  gtk_tool_button_new (image, _("On Hold"));
505
#if GTK_CHECK_VERSION(2,12,0)
506
  gtk_widget_set_tooltip_text(GTK_WIDGET(holdButton), _("On Hold"));
507
#endif
508 509 510 511 512 513 514 515
  gtk_widget_set_state( GTK_WIDGET(holdButton), GTK_STATE_INSENSITIVE);
  g_signal_connect (G_OBJECT (holdButton), "clicked",
      G_CALLBACK (hold), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(holdButton), -1);

  image = gtk_image_new_from_file( ICONS_DIR "/transfert.svg");
  transfertButton = gtk_toggle_tool_button_new ();
  gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(transfertButton), image);
516
#if GTK_CHECK_VERSION(2,12,0)
517
  gtk_widget_set_tooltip_text(GTK_WIDGET(transfertButton), _("Transfer"));
518
#endif
519 520 521 522
  gtk_tool_button_set_label(GTK_TOOL_BUTTON(transfertButton), _("Transfer"));
  gtk_widget_set_state( GTK_WIDGET(transfertButton), GTK_STATE_INSENSITIVE);
  transfertButtonConnId = g_signal_connect (G_OBJECT (transfertButton), "toggled",
      G_CALLBACK (transfert), NULL);
523
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(transfertButton), -1);
524 525

  image = gtk_image_new_from_file( ICONS_DIR "/history2.svg");
526 527
  historyButton = gtk_toggle_tool_button_new();
  gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (historyButton), image);
528
#if GTK_CHECK_VERSION(2,12,0)
529
  gtk_widget_set_tooltip_text(GTK_WIDGET(historyButton), _("History"));
530
#endif
531 532
  gtk_tool_button_set_label (GTK_TOOL_BUTTON (historyButton), _("History"));
  g_signal_connect (G_OBJECT (historyButton), "toggled", G_CALLBACK (toggle_button_cb), history);
533
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(historyButton), -1);
534 535
  active_calltree = current_calls;

536
  image = gtk_image_new_from_file( ICONS_DIR "/addressbook.svg");
537 538
  contactButton = gtk_toggle_tool_button_new();
  gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (contactButton), image);
539
#if GTK_CHECK_VERSION(2,12,0)
540
  gtk_widget_set_tooltip_text(GTK_WIDGET(contactButton), _("Address book"));
541
#endif
542 543
  gtk_tool_button_set_label (GTK_TOOL_BUTTON (contactButton), _("Address book"));
  g_signal_connect (G_OBJECT (contactButton), "toggled", G_CALLBACK (toggle_button_cb), contacts);
544 545
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(contactButton), -1);

546
  image = gtk_image_new_from_file( ICONS_DIR "/mailbox.svg");
Emmanuel Milou's avatar
Emmanuel Milou committed
547
  mailboxButton = gtk_tool_button_new( image , _("Voicemail"));
548 549
  gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mailboxButton), image);
  if( account_list_get_size() ==0 ) gtk_widget_set_state( GTK_WIDGET(mailboxButton), GTK_STATE_INSENSITIVE );
550
#if GTK_CHECK_VERSION(2,12,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
551
  gtk_widget_set_tooltip_text(GTK_WIDGET(mailboxButton), _("Voicemail"));
552
#endif
553 554 555
  g_signal_connect (G_OBJECT (mailboxButton), "clicked",
      G_CALLBACK (call_mailbox), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(mailboxButton), -1);
556

557
  recButton = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD);
alexandresavard's avatar
alexandresavard committed
558 559 560
#if GTK_CHECK_VERSION(2,12,0)
  gtk_widget_set_tooltip_text(GTK_WIDGET(recButton), _("Record a call"));
#endif
561
  gtk_widget_set_state( GTK_WIDGET(recButton), GTK_STATE_INSENSITIVE);
alexandresavard's avatar
alexandresavard committed
562 563 564 565 566
  g_signal_connect (G_OBJECT (recButton), "clicked",
      G_CALLBACK (rec_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(recButton), -1);


567
  return ret;
568

569
}
570
static gboolean
571
on_key_released (GtkWidget   *widget UNUSED,
572
                GdkEventKey *event,
573
                gpointer     user_data UNUSED)
574 575
{
  // If a modifier key is pressed, it's a shortcut, pass along
576
  if(event->state & GDK_CONTROL_MASK ||
577 578 579 580 581 582 583 584 585 586 587 588 589 590
     event->state & GDK_MOD1_MASK    ||
     event->keyval == 60             || // <
     event->keyval == 62             || // >
     event->keyval == 34             || // "
     event->keyval == 65361          || // left arrow
     event->keyval == 65363          || // right arrow
     event->keyval >= 65470          || // F-keys
     event->keyval == 32                // space
     )
    return FALSE;
  else
    sflphone_keypad(event->keyval, event->string);
  return TRUE;
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
591

592 593 594 595 596 597 598 599 600
/**
 * Reset call tree
 */
  void
reset_call_tree (calltab_t* tab)
{
  gtk_list_store_clear (tab->store);
}

601
  void
areversat's avatar
areversat committed
602 603
create_call_tree (calltab_t* tab)
{
Emmanuel Milou's avatar
Emmanuel Milou committed
604 605 606 607
  GtkWidget *sw;
  GtkCellRenderer *rend;
  GtkTreeViewColumn *col;
  GtkTreeSelection *sel;
608

609
  tab->tree = gtk_vbox_new(FALSE, 10);
610

Emmanuel Milou's avatar
Emmanuel Milou committed
611
  gtk_container_set_border_width (GTK_CONTAINER (tab->tree), 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
612

Emmanuel Milou's avatar
Emmanuel Milou committed
613 614 615
  sw = gtk_scrolled_window_new( NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
616
  g_signal_connect (G_OBJECT ( sw ), "key-release-event",G_CALLBACK (on_key_released), NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
617

618 619
  tab->store = gtk_list_store_new (3,
      GDK_TYPE_PIXBUF,// Icon
Emmanuel Milou's avatar
Emmanuel Milou committed
620 621 622
      G_TYPE_STRING,  // Description
      G_TYPE_POINTER  // Pointer to the Object
      );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
623

Emmanuel Milou's avatar
Emmanuel Milou committed
624
  tab->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(tab->store));
625
  gtk_tree_view_set_enable_search( GTK_TREE_VIEW(tab->view), FALSE);
Emmanuel Milou's avatar
Emmanuel Milou committed
626 627 628 629
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(tab->view), FALSE);
  g_signal_connect (G_OBJECT (tab->view), "row-activated",
      G_CALLBACK (row_activated),
      NULL);
630

631
  // Connect the popup menu
Emmanuel Milou's avatar
Emmanuel Milou committed
632
  g_signal_connect (G_OBJECT (tab->view), "popup-menu",
633
      G_CALLBACK (popup_menu),
Emmanuel Milou's avatar
Emmanuel Milou committed
634 635
      NULL);
  g_signal_connect (G_OBJECT (tab->view), "button-press-event",
636
      G_CALLBACK (button_pressed),
Emmanuel Milou's avatar
Emmanuel Milou committed
637 638
      NULL);

639

Emmanuel Milou's avatar
Emmanuel Milou committed
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
  rend = gtk_cell_renderer_pixbuf_new();
  col = gtk_tree_view_column_new_with_attributes ("Icon",
      rend,
      "pixbuf", 0,
      NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW(tab->view), col);

  rend = gtk_cell_renderer_text_new();
  col = gtk_tree_view_column_new_with_attributes ("Description",
      rend,
      "markup", 1,
      NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW(tab->view), col);

  g_object_unref(G_OBJECT(tab->store));
  gtk_container_add(GTK_CONTAINER(sw), tab->view);

  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tab->view));
  g_signal_connect (G_OBJECT (sel), "changed",
      G_CALLBACK (selected),
      NULL);

  gtk_box_pack_start(GTK_BOX(tab->tree), sw, TRUE, TRUE, 0);

664
  gtk_widget_show(tab->tree);
Emmanuel Milou's avatar
Emmanuel Milou committed
665 666 667

  //toolbar_update_buttons();

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
668
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
669

670
  void
671
update_call_tree_remove (calltab_t* tab, call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
672
{
Emmanuel Milou's avatar
Emmanuel Milou committed
673 674 675 676 677 678 679 680 681 682 683 684
  GtkTreeIter iter;
  GValue val;
  call_t * iterCall;
  GtkListStore* store = tab->store;

  int nbChild = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
  int i;
  for( i = 0; i < nbChild; i++)
  {
    if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i))
    {
      val.g_type = 0;
685
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
686 687 688 689 690 691 692 693 694 695 696 697 698 699

      iterCall = (call_t*) g_value_get_pointer(&val);
      g_value_unset(&val);

      if(iterCall == c)
      {
	gtk_list_store_remove(store, &iter);
      }
    }
  }
  call_t * selectedCall = call_get_selected(tab);
  if(selectedCall == c)
    call_select(tab, NULL);
  toolbar_update_buttons();
700
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
701

702
  void
703
update_call_tree (calltab_t* tab, call_t * c)
704
{
705 706
    g_print("update call tree\n");
  GdkPixbuf *pixbuf=NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
707 708 709 710 711 712 713 714 715 716 717 718
  GtkTreeIter iter;
  GValue val;
  call_t * iterCall;
  GtkListStore* store = tab->store;

  int nbChild = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
  int i;
  for( i = 0; i < nbChild; i++)
  {
    if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i))
    {
      val.g_type = 0;
719
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
720 721 722 723 724 725 726 727

      iterCall = (call_t*) g_value_get_pointer(&val);
      g_value_unset(&val);

      if(iterCall == c)
      {
	// Existing call in the list
	gchar * description;
Emmanuel Milou's avatar
Emmanuel Milou committed
728 729
	gchar * date="";
	gchar * duration="";
Emmanuel Milou's avatar
Emmanuel Milou committed
730
	if(c->state == CALL_STATE_TRANSFERT)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
731
	{
732 733 734
	  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>Transfert to:</i> %s",
	      call_get_number(c),
	      call_get_name(c),
Emmanuel Milou's avatar
Emmanuel Milou committed
735 736 737 738
	      c->to);
	}
	else
	{
739
	  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>",
740
	      call_get_number(c),
741
	      call_get_name(c));
Emmanuel Milou's avatar
Emmanuel Milou committed
742
	}
743

744 745
	if( tab == current_calls )
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
	  switch(c->state)
	  {
	    case CALL_STATE_HOLD:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/hold.svg", NULL);
	      break;
	    case CALL_STATE_RINGING:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL);
	      break;
	    case CALL_STATE_CURRENT:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
	      break;
	    case CALL_STATE_DIALING:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/dial.svg", NULL);
	      break;
	    case CALL_STATE_FAILURE:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/fail.svg", NULL);
	      break;
	    case CALL_STATE_BUSY:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/busy.svg", NULL);
	      break;
	    case CALL_STATE_TRANSFERT:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/transfert.svg", NULL);
768 769 770
              break;
            case CALL_STATE_RECORD:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/rec_call.svg", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
771 772
	      break;
	    default:
773
	      g_warning("Update calltree - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
774
	  }
775
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
776 777
	else
	{
778 779 780
	  switch(c->history_state)
	  {
	    case OUTGOING:
Emmanuel Milou's avatar
Emmanuel Milou committed
781 782 783 784 785 786
	      g_print("Outgoing state\n");
	      pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/outgoing.svg", NULL);
	      break;
	    case INCOMING:
	      g_print("Incoming state\n");
	      pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/incoming.svg", NULL);
787 788
	      break;
	    case MISSED:
Emmanuel Milou's avatar
Emmanuel Milou committed
789 790
	      g_print("Missed state\n");
	      pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/missed.svg", NULL);
791 792
	      break;
	    default:
793
	      g_print("No history state\n");
Emmanuel Milou's avatar
Emmanuel Milou committed
794
	      break;
795
	  }
796
	  date = timestamp_get_call_date();
Emmanuel Milou's avatar
Emmanuel Milou committed
797
	  duration = process_call_duration(c);
798 799
	  duration = g_strconcat( date , duration , NULL);
	  description = g_strconcat( description , duration, NULL);
800
	}
801 802 803
	//Resize it
	if(pixbuf)
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
804 805 806 807
	  if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32)
	  {
	    pixbuf =  gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR);
	  }
808
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
809 810 811 812
	gtk_list_store_set(store, &iter,
	    0, pixbuf, // Icon
	    1, description, // Description
	    -1);
813 814

	if (pixbuf != NULL)
Emmanuel Milou's avatar
Emmanuel Milou committed
815 816
	  g_object_unref(G_OBJECT(pixbuf));

817
      }
Emmanuel Milou's avatar
Emmanuel Milou committed
818 819
    }

820
  }
Emmanuel Milou's avatar
Emmanuel Milou committed
821 822 823
  toolbar_update_buttons();
}

824
  void
Emmanuel Milou's avatar
Emmanuel Milou committed
825 826 827 828 829
update_call_tree_add (calltab_t* tab, call_t * c)
{
  if( tab == history && ( call_list_get_size( tab ) > dbus_get_max_calls() ) )
    return;

830
  GdkPixbuf *pixbuf=NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
831 832 833 834
  GtkTreeIter iter;
  GtkTreeSelection* sel;

  // New call in the list
Emmanuel Milou's avatar
Emmanuel Milou committed
835
  gchar * description;
Emmanuel Milou's avatar
Emmanuel Milou committed
836
  gchar * date="";
837
  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>",
838
      call_get_number(c),
839
      call_get_name(c));
Emmanuel Milou's avatar
Emmanuel Milou committed
840

841

Emmanuel Milou's avatar
Emmanuel Milou committed
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
  gtk_list_store_prepend (tab->store, &iter);

  if( tab == current_calls )
  {
    switch(c->state)
    {
      case CALL_STATE_INCOMING:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL);
	break;
      case CALL_STATE_DIALING:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/dial.svg", NULL);
	break;
      case CALL_STATE_RINGING:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL);
	break;
      default:
858
	g_warning("Update calltree add - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
859 860
    }
  }
861 862

  else if (tab == history) {
Emmanuel Milou's avatar
Emmanuel Milou committed
863 864 865
    switch(c->history_state)
    {
      case INCOMING:
866
	    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/incoming.svg", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
867 868 869 870 871 872 873 874
	break;
      case OUTGOING:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/outgoing.svg", NULL);
	break;
      case MISSED:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/missed.svg", NULL);
	break;
      default:
875
	    g_warning("History - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
876
    }
877
    date = timestamp_get_call_date();
878 879 880 881
    description = g_strconcat( date , description , NULL);
  }

  else if (tab == contacts) {
882
    pixbuf = c->contact_thumbnail; 
883 884 885 886 887
    description = g_strconcat( description , NULL);
  }

  else {
        g_warning ("This widget doesn't exist - This is a bug in the application\n.");
Emmanuel Milou's avatar
Emmanuel Milou committed
888
  }
889

890

Emmanuel Milou's avatar
Emmanuel Milou committed
891 892 893 894 895 896 897 898 899 900
  //Resize it
  if(pixbuf)
  {
    if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32)
    {
      pixbuf =  gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR);
    }
  }
  gtk_list_store_set(tab->store, &iter,
      0, pixbuf, // Icon
Emmanuel Milou's avatar
Emmanuel Milou committed
901
      1, description, // Description
902
      2, c,      // Pointer
Emmanuel Milou's avatar
Emmanuel Milou committed
903 904 905 906 907 908 909 910
      -1);

  if (pixbuf != NULL)
    g_object_unref(G_OBJECT(pixbuf));

  sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tab->view));
  gtk_tree_selection_select_iter(GTK_TREE_SELECTION(sel), &iter);
  toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
911
}
912

Emmanuel Milou's avatar