calltree.c 28.1 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
  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);
178
  printf("current calls toggle\n");
179 180 181 182 183 184

  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
185
  static void
186 187
toggle_history(GtkToggleToolButton *toggle_tool_button UNUSED,
    gpointer	user_data UNUSED)
areversat's avatar
areversat committed
188 189
{
	GtkTreeSelection *sel;
190

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

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

201 202 203 204 205 206 207 208
}

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

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

Julien Bonjean's avatar
Julien Bonjean committed
213 214
  printf("EDS : %s\n",gtk_entry_get_text(GTK_ENTRY(filter_entry)));

215 216 217 218 219
  // Reset previous results
  call_list_reset(contacts);
  reset_call_tree(contacts);

  // Do a synchronized search
Julien Bonjean's avatar
Julien Bonjean committed
220
  results = search_sync (gtk_entry_get_text(GTK_ENTRY(filter_entry)), 50);
Julien Bonjean's avatar
Julien Bonjean committed
221 222 223

  if(results == NULL)
  {
224 225
    printf("No results\n");
    return ;
Julien Bonjean's avatar
Julien Bonjean committed
226
  }
227

Julien Bonjean's avatar
Julien Bonjean committed
228 229 230 231 232 233 234 235 236 237 238 239
  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());
240 241
      sprintf(ext, "%d", rand()%100 + 100);
      call->from = g_strconcat("\"" , entry->text, "\"<", ext, ">", NULL);
Julien Bonjean's avatar
Julien Bonjean committed
242 243 244 245 246 247 248
      call->state = CALL_STATE_RECORD;
      call->history_state = OUTGOING;

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

250
  active_calltree = contacts;
251 252 253 254
  gtk_widget_hide(current_calls->tree);
  gtk_widget_hide(history->tree);
  gtk_widget_show(contacts->tree);

255
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_calltree->view));
256 257
  g_signal_emit_by_name(sel, "changed");
  toolbar_update_buttons();
areversat's avatar
areversat committed
258
}
259 260

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

alexandresavard's avatar
alexandresavard committed
283 284 285 286 287


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


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


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



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

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

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

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

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

421
/* A row is activated when it is double clicked */
422 423 424
void  row_activated(GtkTreeView       *tree_view UNUSED,
    GtkTreePath       *path UNUSED,
    GtkTreeViewColumn *column UNUSED,
425
    void * data UNUSED)
426
{
427 428 429 430 431
  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
432 433
  if (selectedCall)
  {
434 435
    // Get the right event from the right calltree
    if( active_calltree == current_calls )
Emmanuel Milou's avatar
Emmanuel Milou committed
436
    {
437
      switch(selectedCall->state)
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
      {
	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
457
    }
458
    // if history
459 460 461 462 463 464 465
    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);
466
      g_sprintf(newCall->callID, "%d", rand());
467 468
      newCall->_start = 0;
      newCall->_stop = 0;
469 470
      printf("call : account : %s \n", selectedCall->accountID);
      newCall->accountID = selectedCall->accountID;
471 472 473 474
      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);
475
      switch_tab(current_calls);
476 477 478
    }
  }
}
479

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

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

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

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

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

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

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

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

584

585 586 587
  //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
588 589 590
#if GTK_CHECK_VERSION(2,12,0)
  gtk_widget_set_tooltip_text(GTK_WIDGET(recButton), _("Record a call"));
#endif
591
  gtk_widget_set_state( GTK_WIDGET(recButton), GTK_STATE_INSENSITIVE);
alexandresavard's avatar
alexandresavard committed
592 593 594 595 596
  g_signal_connect (G_OBJECT (recButton), "clicked",
      G_CALLBACK (rec_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(recButton), -1);


597
  return ret;
598

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

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

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

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

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

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

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

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

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

669

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

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

  //toolbar_update_buttons();

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

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

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

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

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

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

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

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

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

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

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

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

871

Emmanuel Milou's avatar
Emmanuel Milou committed
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 903
  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:
904
	g_warning("History - Should not happen!");
Emmanuel Milou's avatar
Emmanuel Milou committed
905
    }
906
    date = timestamp_get_call_date();
907 908 909 910
    if(tab == contacts)
      description = g_strconcat( description , NULL);
    else
      description = g_strconcat( date , description , NULL);