calltree.c 27.8 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

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 * historyButton;
41
GtkToolItem * mailboxButton;
alexandresavard's avatar
alexandresavard committed
42
GtkToolItem * recButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
43
guint transfertButtonConnId; //The button toggled signal connection ID
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
44

45 46 47
/**
 * Show popup menu
 */
48
  static gboolean
49
popup_menu (GtkWidget *widget,
50
    gpointer   user_data UNUSED)
51 52 53
{
  show_popup_menu(widget, NULL);
  return TRUE;
54
}
Emmanuel Milou's avatar
Emmanuel Milou committed
55

Emmanuel Milou's avatar
Emmanuel Milou committed
56 57 58 59 60 61
  static gboolean
is_inserted( GtkWidget* button )
{
  return ( GTK_WIDGET(button)->parent == GTK_WIDGET( toolbar ) );
}

Emmanuel Milou's avatar
Emmanuel Milou committed
62
  static gboolean
Emmanuel Milou's avatar
Emmanuel Milou committed
63
button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUSED)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
64 65 66
{
  if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
  {
67 68 69 70 71 72 73 74 75 76
    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
77 78 79
  }
  return FALSE;
}
80
/**
81
 * Make a call
82
 */
83
  static void
84
call_button( GtkWidget *widget UNUSED, gpointer   data UNUSED)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
85
{
86
  call_t * selectedCall = call_get_selected(active_calltree);
87
  call_t* newCall =  g_new0 (call_t, 1);
Emmanuel Milou's avatar
Emmanuel Milou committed
88 89 90 91
  printf("Call button pressed\n");
  if(call_list_get_size(current_calls)>0)
    sflphone_pick_up();
  else if(call_list_get_size(active_calltree) > 0){
92 93 94
    if( selectedCall)
    {
      printf("Calling a called num\n");
95

96 97 98 99
      newCall->to = g_strdup(call_get_number(selectedCall));
      newCall->from = g_strconcat("\"\" <", call_get_number(selectedCall), ">",NULL);
      newCall->state = CALL_STATE_DIALING;
      newCall->callID = g_new0(gchar, 30);
100
      g_sprintf(newCall->callID, "%d", rand());
101 102
      newCall->_start = 0;
      newCall->_stop = 0;
103

104 105 106 107
      printf("call : from : %s to %s\n", newCall->from, newCall->to);
      call_list_add(current_calls, newCall);
      update_call_tree_add(current_calls, newCall);
      sflphone_place_call(newCall);
108
      switch_tab(current_calls);
109
    }
110 111 112
    else
    {
      sflphone_new_call();
113
      switch_tab(current_calls);
114 115 116 117
    }
  }
  else
  {
Emmanuel Milou's avatar
Emmanuel Milou committed
118
    sflphone_new_call();
119
    switch_tab(current_calls);
120
  }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
121 122
}

123
/**
124
 * Hang up the line
125
 */
126
  static void
127
hang_up( GtkWidget *widget UNUSED, gpointer   data UNUSED)
128
{
Emmanuel Milou's avatar
Emmanuel Milou committed
129
  sflphone_hang_up();
130 131 132
}

/**
133
 * Hold the line
134
 */
135
  static void
136
hold( GtkWidget *widget UNUSED, gpointer   data UNUSED)
137
{
Emmanuel Milou's avatar
Emmanuel Milou committed
138
  sflphone_on_hold();
139 140 141 142 143
}

/**
 * Transfert the line
 */
144
  static void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
145
transfert  (GtkToggleToolButton *toggle_tool_button,
146
    gpointer             user_data UNUSED )
147
{
Emmanuel Milou's avatar
Emmanuel Milou committed
148 149 150 151 152 153 154 155 156
  gboolean up = gtk_toggle_tool_button_get_active(toggle_tool_button);
  if(up)
  {
    sflphone_set_transfert();
  }
  else
  {
    sflphone_unset_transfert();
  }
157 158
}

159 160 161
/**
 * Unhold call
 */
162
  static void
163
unhold( GtkWidget *widget UNUSED, gpointer   data UNUSED)
164
{
Emmanuel Milou's avatar
Emmanuel Milou committed
165
  sflphone_off_hold();
166
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
167

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
  static void
toggle_current_calls(GtkToggleToolButton *toggle_tool_button UNUSED,
    gpointer  user_data UNUSED)
{
  GtkTreeSelection *sel;

  active_calltree = current_calls;
  gtk_widget_hide(history->tree);
  gtk_widget_hide(contacts->tree);
  gtk_widget_show(current_calls->tree);

  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_calltree->view));
  g_signal_emit_by_name(sel, "changed");
  toolbar_update_buttons();
}

Emmanuel Milou's avatar
Emmanuel Milou committed
184
  static void
185 186
toggle_history(GtkToggleToolButton *toggle_tool_button UNUSED,
    gpointer	user_data UNUSED)
areversat's avatar
areversat committed
187 188
{
	GtkTreeSelection *sel;
189

190 191 192 193
  active_calltree = history;
  gtk_widget_hide(current_calls->tree);
  gtk_widget_hide(contacts->tree);
  gtk_widget_show(history->tree);
194

areversat's avatar
areversat committed
195 196 197
	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_calltree->view));
	g_signal_emit_by_name(sel, "changed");
	toolbar_update_buttons();
198
	gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(histfilter));
199

200 201 202 203 204 205 206 207
}

  static void
toggle_contacts(GtkToggleToolButton *toggle_tool_button UNUSED,
    gpointer  user_data UNUSED)
{

  GtkTreeSelection *sel;
Julien Bonjean's avatar
Julien Bonjean committed
208 209
  GList *results;
  GList *i;
210
  char ext[30];
Julien Bonjean's avatar
Julien Bonjean committed
211

212 213 214 215 216 217
  // Reset previous results
  call_list_reset(contacts);
  reset_call_tree(contacts);

  // Do a synchronized search
  results = search_sync ("j", 50);
Julien Bonjean's avatar
Julien Bonjean committed
218 219 220

  if(results == NULL)
  {
221 222
    printf("No results\n");
    return ;
Julien Bonjean's avatar
Julien Bonjean committed
223
  }
224

Julien Bonjean's avatar
Julien Bonjean committed
225 226 227 228 229 230 231 232 233 234 235 236
  for (i = results; i != NULL; i = i->next)
  {
    Hit *entry;
    entry = i->data;
    if (i->data)
    {
      call_t * call;

      call = g_new0 (call_t, 1);
      call->accountID = g_strdup("Account:1235677223");
      call->callID = g_new0(gchar, 30);
      g_sprintf(call->callID, "%d", rand());
237 238
      sprintf(ext, "%d", rand()%100 + 100);
      call->from = g_strconcat("\"" , entry->text, "\"<", ext, ">", NULL);
Julien Bonjean's avatar
Julien Bonjean committed
239 240 241 242 243 244 245
      call->state = CALL_STATE_RECORD;
      call->history_state = OUTGOING;

      call_list_add (contacts, call);
      update_call_tree_add(contacts,call);
    }
  }
246

247
  active_calltree = contacts;
248 249 250 251
  gtk_widget_hide(current_calls->tree);
  gtk_widget_hide(history->tree);
  gtk_widget_show(contacts->tree);

252
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_calltree->view));
253 254 255
  g_signal_emit_by_name(sel, "changed");
  toolbar_update_buttons();

256
  //gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(contactfilter));
areversat's avatar
areversat committed
257
}
258 259

  static void
260
call_mailbox( GtkWidget* widget UNUSED, gpointer data UNUSED)
261
{
Emmanuel Milou's avatar
Emmanuel Milou committed
262 263
  account_t* current = account_list_get_current();
  if( current == NULL ) // Should not happens
264
    return;
Emmanuel Milou's avatar
Emmanuel Milou committed
265 266
  call_t* mailboxCall = g_new0( call_t , 1);
  mailboxCall->state = CALL_STATE_DIALING;
267
  mailboxCall->to = g_strdup(g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX));
Emmanuel Milou's avatar
Emmanuel Milou committed
268
  mailboxCall->from = g_markup_printf_escaped(_("\"Voicemail\" <%s>"),  mailboxCall->to);
Emmanuel Milou's avatar
Emmanuel Milou committed
269 270 271
  mailboxCall->callID = g_new0(gchar, 30);
  g_sprintf(mailboxCall->callID, "%d", rand());
  mailboxCall->accountID = g_strdup(current->accountID);
Emmanuel Milou's avatar
Emmanuel Milou committed
272 273
  mailboxCall->_start = 0;
  mailboxCall->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
274 275
  g_print("TO : %s\n" , mailboxCall->to);
  call_list_add( current_calls , mailboxCall );
276
  update_call_tree_add( current_calls , mailboxCall );
Emmanuel Milou's avatar
Emmanuel Milou committed
277 278
  update_menus();
  sflphone_place_call( mailboxCall );
279
  switch_tab(current_calls);
280 281
}

alexandresavard's avatar
alexandresavard committed
282 283 284 285 286


/**
 * Static rec_button
 */
287
static void
alexandresavard's avatar
alexandresavard committed
288 289 290 291 292 293
rec_button( GtkWidget *widget UNUSED, gpointer   data UNUSED)
{
  sflphone_rec_call();
}


294
  void
295
toolbar_update_buttons ()
296
{
Emmanuel Milou's avatar
Emmanuel Milou committed
297 298 299 300 301 302
  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
303
  gtk_widget_set_sensitive( GTK_WIDGET(recButton),        FALSE);
Emmanuel Milou's avatar
Emmanuel Milou committed
304 305
  g_object_ref(holdButton);
  g_object_ref(unholdButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
306 307
  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
308 309 310
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), holdButton, 3);
  g_object_ref(callButton);
  g_object_ref(pickupButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
311 312
  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
313
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), callButton, 0);
alexandresavard's avatar
alexandresavard committed
314
  //gtk_toolbar_insert(GTK_TOOLBAR(toolbar), recButton, 0);
Emmanuel Milou's avatar
Emmanuel Milou committed
315 316 317 318 319 320 321 322 323


  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)
  {
324
    switch(selectedCall->state)
Emmanuel Milou's avatar
Emmanuel Milou committed
325 326 327 328
    {
      case CALL_STATE_INCOMING:
	gtk_widget_set_sensitive( GTK_WIDGET(pickupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),	TRUE);
329
	g_object_ref(callButton);
Emmanuel Milou's avatar
Emmanuel Milou committed
330 331 332 333 334 335 336
	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);
337 338
	g_object_ref(holdButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
339 340 341 342 343 344 345 346 347
	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
348 349
	g_object_ref(callButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
350 351 352 353 354 355 356
	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
357
        gtk_widget_set_sensitive( GTK_WIDGET(recButton),        TRUE);
Emmanuel Milou's avatar
Emmanuel Milou committed
358 359 360 361
	break;
      case CALL_STATE_BUSY:
      case CALL_STATE_FAILURE:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
362
	break;
363
      case CALL_STATE_TRANSFERT:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
364
	gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
365
	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), TRUE);
366
	gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
367 368 369 370 371
	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;
372 373 374 375 376 377 378
      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
379 380 381 382 383
      default:
	g_warning("Should not happen!");
	break;
    }
  }
384
  else
Emmanuel Milou's avatar
Emmanuel Milou committed
385 386 387 388 389 390 391 392 393 394 395
  {
    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);
    }
  }
396
}
alexandresavard's avatar
alexandresavard committed
397 398 399



400
/* Call back when the user click on a call in the list */
401 402
  static void
selected(GtkTreeSelection *sel, void* data UNUSED )
403
{
Emmanuel Milou's avatar
Emmanuel Milou committed
404 405 406
  GtkTreeIter  iter;
  GValue val;
  GtkTreeModel *model = (GtkTreeModel*)active_calltree->store;
407

Emmanuel Milou's avatar
Emmanuel Milou committed
408 409
  if (! gtk_tree_selection_get_selected (sel, &model, &iter))
    return;
410

Emmanuel Milou's avatar
Emmanuel Milou committed
411
  val.g_type = 0;
412
  gtk_tree_model_get_value (model, &iter, 2, &val);
413

Emmanuel Milou's avatar
Emmanuel Milou committed
414 415
  call_select(active_calltree, (call_t*) g_value_get_pointer(&val));
  g_value_unset(&val);
416

Emmanuel Milou's avatar
Emmanuel Milou committed
417
  toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
418 419
}

420
/* A row is activated when it is double clicked */
421 422 423
void  row_activated(GtkTreeView       *tree_view UNUSED,
    GtkTreePath       *path UNUSED,
    GtkTreeViewColumn *column UNUSED,
424
    void * data UNUSED)
425
{
426 427 428 429 430
  g_print("double click action\n");
  call_t* selectedCall;
  call_t* newCall;
  selectedCall = call_get_selected( active_calltree );

Emmanuel Milou's avatar
Emmanuel Milou committed
431 432
  if (selectedCall)
  {
433 434
    // Get the right event from the right calltree
    if( active_calltree == current_calls )
Emmanuel Milou's avatar
Emmanuel Milou committed
435
    {
436
      switch(selectedCall->state)
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
      {
	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:
	  g_warning("Should not happen!");
	  break;
      }
Emmanuel Milou's avatar
Emmanuel Milou committed
456
    }
457
    // if history
458 459 460 461 462 463 464
    else
    {
      newCall = g_new0( call_t, 1 );
      newCall->to = g_strdup(call_get_number(selectedCall));
      newCall->from = g_strconcat("\"\" <", call_get_number(selectedCall), ">",NULL);
      newCall->state = CALL_STATE_DIALING;
      newCall->callID = g_new0(gchar, 30);
465
      g_sprintf(newCall->callID, "%d", rand());
466 467
      newCall->_start = 0;
      newCall->_stop = 0;
468 469
      printf("call : account : %s \n", selectedCall->accountID);
      newCall->accountID = selectedCall->accountID;
470 471 472 473
      printf("call : from : %s to %s\n", newCall->from, newCall->to);
      call_list_add(current_calls, newCall);
      update_call_tree_add(current_calls, newCall);
      sflphone_place_call(newCall);
474
      switch_tab(current_calls);
475 476 477
    }
  }
}
478

479
  GtkWidget *
areversat's avatar
areversat committed
480 481
create_toolbar ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
482 483 484 485 486 487 488 489 490
  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);

491 492
  image = gtk_image_new_from_file( ICONS_DIR "/call.svg");
  callButton = gtk_tool_button_new (image, _("Place a call"));
493
#if GTK_CHECK_VERSION(2,12,0)
494
  gtk_widget_set_tooltip_text(GTK_WIDGET(callButton), _("Place a call"));
495
#endif
496 497 498
  g_signal_connect (G_OBJECT (callButton), "clicked",
      G_CALLBACK (call_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(callButton), -1);
499

500 501
  image = gtk_image_new_from_file( ICONS_DIR "/accept.svg");
  pickupButton = gtk_tool_button_new(image, _("Pick up"));
502
#if GTK_CHECK_VERSION(2,12,0)
503
  gtk_widget_set_tooltip_text(GTK_WIDGET(pickupButton), _("Pick up"));
504
#endif
505
  gtk_widget_set_state( GTK_WIDGET(pickupButton), GTK_STATE_INSENSITIVE);
506
  g_signal_connect(G_OBJECT (pickupButton), "clicked",
507 508
      G_CALLBACK (call_button), NULL);
  gtk_widget_show_all(GTK_WIDGET(pickupButton));
509

510 511
  image = gtk_image_new_from_file( ICONS_DIR "/hang_up.svg");
  hangupButton = gtk_tool_button_new (image, _("Hang up"));
512
#if GTK_CHECK_VERSION(2,12,0)
513
  gtk_widget_set_tooltip_text(GTK_WIDGET(hangupButton), _("Hang up"));
514
#endif
515 516 517
  gtk_widget_set_state( GTK_WIDGET(hangupButton), GTK_STATE_INSENSITIVE);
  g_signal_connect (G_OBJECT (hangupButton), "clicked",
      G_CALLBACK (hang_up), NULL);
518
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(hangupButton), -1);
519

520 521
  image = gtk_image_new_from_file( ICONS_DIR "/unhold.svg");
  unholdButton = gtk_tool_button_new (image, _("Off Hold"));
522
#if GTK_CHECK_VERSION(2,12,0)
523
  gtk_widget_set_tooltip_text(GTK_WIDGET(unholdButton), _("Off Hold"));
524
#endif
525 526 527 528 529 530 531 532
  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"));
533
#if GTK_CHECK_VERSION(2,12,0)
534
  gtk_widget_set_tooltip_text(GTK_WIDGET(holdButton), _("On Hold"));
535
#endif
536 537 538 539 540 541 542 543
  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);
544
#if GTK_CHECK_VERSION(2,12,0)
545
  gtk_widget_set_tooltip_text(GTK_WIDGET(transfertButton), _("Transfer"));
546
#endif
547 548 549 550
  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);
551
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(transfertButton), -1);
552 553

  image = gtk_image_new_from_file( ICONS_DIR "/history2.svg");
554
  historyButton = gtk_tool_button_new(image, _("History"));
555
#if GTK_CHECK_VERSION(2,12,0)
556
  gtk_widget_set_tooltip_text(GTK_WIDGET(historyButton), _("History"));
557
#endif
558
  g_signal_connect (G_OBJECT (historyButton), "clicked",
559
      G_CALLBACK (toggle_history), NULL);
560
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(historyButton), -1);
561 562
  active_calltree = current_calls;

563 564
  image = gtk_image_new_from_file( ICONS_DIR "/contacts.svg");
  contactButton = gtk_tool_button_new(image, _("Contacts"));
565 566 567
#if GTK_CHECK_VERSION(2,12,0)
  gtk_widget_set_tooltip_text(GTK_WIDGET(contactButton), _("Contacts"));
#endif
568
  g_signal_connect (G_OBJECT (contactButton), "clicked",
569 570 571
      G_CALLBACK (toggle_contacts), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(contactButton), -1);

572
  image = gtk_image_new_from_file( ICONS_DIR "/mailbox.svg");
Emmanuel Milou's avatar
Emmanuel Milou committed
573
  mailboxButton = gtk_tool_button_new( image , _("Voicemail"));
574 575
  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 );
576
#if GTK_CHECK_VERSION(2,12,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
577
  gtk_widget_set_tooltip_text(GTK_WIDGET(mailboxButton), _("Voicemail"));
578
#endif
579 580 581
  g_signal_connect (G_OBJECT (mailboxButton), "clicked",
      G_CALLBACK (call_mailbox), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(mailboxButton), -1);
582

583

584 585 586
  //image = gtk_image_new_from_file( ICONS_DIR "/record.svg");
  //recButton = gtk_tool_button_new (image, _("Record a call"));
  recButton = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD);
alexandresavard's avatar
alexandresavard committed
587 588 589
#if GTK_CHECK_VERSION(2,12,0)
  gtk_widget_set_tooltip_text(GTK_WIDGET(recButton), _("Record a call"));
#endif
590
  gtk_widget_set_state( GTK_WIDGET(recButton), GTK_STATE_INSENSITIVE);
alexandresavard's avatar
alexandresavard committed
591 592 593 594 595
  g_signal_connect (G_OBJECT (recButton), "clicked",
      G_CALLBACK (rec_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(recButton), -1);


596
  return ret;
597

598
}
599
static gboolean
600
on_key_released (GtkWidget   *widget UNUSED,
601
                GdkEventKey *event,
602
                gpointer     user_data UNUSED)
603 604
{
  // If a modifier key is pressed, it's a shortcut, pass along
605
  if(event->state & GDK_CONTROL_MASK ||
606 607 608 609 610 611 612 613 614 615 616 617 618 619
     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
620

621 622 623 624 625 626 627 628 629
/**
 * Reset call tree
 */
  void
reset_call_tree (calltab_t* tab)
{
  gtk_list_store_clear (tab->store);
}

630
  void
areversat's avatar
areversat committed
631 632
create_call_tree (calltab_t* tab)
{
Emmanuel Milou's avatar
Emmanuel Milou committed
633 634 635 636
  GtkWidget *sw;
  GtkCellRenderer *rend;
  GtkTreeViewColumn *col;
  GtkTreeSelection *sel;
637

638
  tab->tree = gtk_vbox_new(FALSE, 10);
639

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

Emmanuel Milou's avatar
Emmanuel Milou committed
642 643 644
  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);
645
  g_signal_connect (G_OBJECT ( sw ), "key-release-event",G_CALLBACK (on_key_released), NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
646

647 648
  tab->store = gtk_list_store_new (3,
      GDK_TYPE_PIXBUF,// Icon
Emmanuel Milou's avatar
Emmanuel Milou committed
649 650 651
      G_TYPE_STRING,  // Description
      G_TYPE_POINTER  // Pointer to the Object
      );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
652

Emmanuel Milou's avatar
Emmanuel Milou committed
653
  tab->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(tab->store));
654
  gtk_tree_view_set_enable_search( GTK_TREE_VIEW(tab->view), FALSE);
Emmanuel Milou's avatar
Emmanuel Milou committed
655 656 657 658
  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);
659

660
  // Connect the popup menu
Emmanuel Milou's avatar
Emmanuel Milou committed
661
  g_signal_connect (G_OBJECT (tab->view), "popup-menu",
662
      G_CALLBACK (popup_menu),
Emmanuel Milou's avatar
Emmanuel Milou committed
663 664
      NULL);
  g_signal_connect (G_OBJECT (tab->view), "button-press-event",
665
      G_CALLBACK (button_pressed),
Emmanuel Milou's avatar
Emmanuel Milou committed
666 667
      NULL);

668

Emmanuel Milou's avatar
Emmanuel Milou committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
  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);

693
  gtk_widget_show(tab->tree);
Emmanuel Milou's avatar
Emmanuel Milou committed
694 695 696

  //toolbar_update_buttons();

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
697
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
698

699
  void
700
update_call_tree_remove (calltab_t* tab, call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
701
{
Emmanuel Milou's avatar
Emmanuel Milou committed
702 703 704 705 706 707 708 709 710 711 712 713
  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;
714
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
715 716 717 718 719 720 721 722 723 724 725 726 727 728

      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();
729
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
730

731
  void
732
update_call_tree (calltab_t* tab, call_t * c)
733
{
734 735
    g_print("update call tree\n");
  GdkPixbuf *pixbuf=NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
736 737 738 739 740 741 742 743 744 745 746 747
  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;
748
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
749 750 751 752 753 754 755 756

      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
757 758
	gchar * date="";
	gchar * duration="";
Emmanuel Milou's avatar
Emmanuel Milou committed
759
	if(c->state == CALL_STATE_TRANSFERT)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
760
	{
761 762 763
	  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
764 765 766 767
	      c->to);
	}
	else
	{
768
	  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>",
769
	      call_get_number(c),
770
	      call_get_name(c));
Emmanuel Milou's avatar
Emmanuel Milou committed
771
	}
772

773 774
	if( tab == current_calls )
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
	  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);
797 798 799
              break;
            case CALL_STATE_RECORD:
	      pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/rec_call.svg", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
800 801 802 803
	      break;
	    default:
	      g_warning("Should not happen!");
	  }
804
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
805 806
	else
	{
807 808 809
	  switch(c->history_state)
	  {
	    case OUTGOING:
Emmanuel Milou's avatar
Emmanuel Milou committed
810 811 812 813 814 815
	      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);
816 817
	      break;
	    case MISSED:
Emmanuel Milou's avatar
Emmanuel Milou committed
818 819
	      g_print("Missed state\n");
	      pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/missed.svg", NULL);
820 821
	      break;
	    default:
822
	      g_print("No history state\n");
Emmanuel Milou's avatar
Emmanuel Milou committed
823
	      break;
824
	  }
825
	  date = timestamp_get_call_date();
Emmanuel Milou's avatar
Emmanuel Milou committed
826
	  duration = process_call_duration(c);
827 828
	  duration = g_strconcat( date , duration , NULL);
	  description = g_strconcat( description , duration, NULL);
829
	}
830 831 832
	//Resize it
	if(pixbuf)
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
833 834 835 836
	  if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32)
	  {
	    pixbuf =  gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR);
	  }
837
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
838 839 840 841
	gtk_list_store_set(store, &iter,
	    0, pixbuf, // Icon
	    1, description, // Description
	    -1);
842 843

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

846
      }
Emmanuel Milou's avatar
Emmanuel Milou committed
847 848
    }

849
  }
Emmanuel Milou's avatar
Emmanuel Milou committed
850 851 852
  toolbar_update_buttons();
}

853
  void
Emmanuel Milou's avatar
Emmanuel Milou committed
854 855 856 857 858
update_call_tree_add (calltab_t* tab, call_t * c)
{
  if( tab == history && ( call_list_get_size( tab ) > dbus_get_max_calls() ) )
    return;

859
  GdkPixbuf *pixbuf=NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
860 861 862 863
  GtkTreeIter iter;
  GtkTreeSelection* sel;

  // New call in the list
Emmanuel Milou's avatar
Emmanuel Milou committed
864
  gchar * description;
Emmanuel Milou's avatar
Emmanuel Milou committed
865
  gchar * date="";
866
  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>",
867
      call_get_number(c),
868
      call_get_name(c));
Emmanuel Milou's avatar
Emmanuel Milou committed
869

870

Emmanuel Milou's avatar
Emmanuel Milou committed
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
  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:
	g_warning("Should not happen!");
    }
  }
  else{
    switch(c->history_state)
    {
      case INCOMING:
	pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/incoming.svg", NULL);
	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:
903
	g_warning("History - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
904
    }
905
    date = timestamp_get_call_date();
906 907 908 909
    if(tab == contacts)
      description = g_strconcat( description , NULL);
    else
      description = g_strconcat( date , description , NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
910
  }
911

Emmanuel Milou's avatar
Emmanuel Milou committed
912 913 914 915 916 917