calltree.c 21.7 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>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
5
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
10
11
12
13
14
15
16
17
18
19
20
 *  (at your option) any later version.
 *                                                                                
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *                                                                              
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

21
#include <stdlib.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
22
#include <gtk/gtk.h>
23
#include <actions.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
24
25
#include <calltree.h>
#include <calllist.h>
26
#include <menus.h>
27
#include <dbus.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
28

29

30

31
GtkWidget   * toolbar;
Emmanuel Milou's avatar
Emmanuel Milou committed
32
GtkToolItem * pickupButton;
33
34
35
36
37
GtkToolItem * callButton;
GtkToolItem * hangupButton;
GtkToolItem * holdButton;
GtkToolItem * transfertButton;
GtkToolItem * unholdButton;
areversat's avatar
areversat committed
38
GtkToolItem * historyButton;
39
GtkToolItem * mailboxButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
40
guint transfertButtonConnId; //The button toggled signal connection ID
areversat's avatar
areversat committed
41
gboolean history_shown;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
42

43

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

  static gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
56
57
58
59
60
61
62
63
64
button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data)
{
  if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
  {
    show_popup_menu(widget,  event);
    return TRUE;
  }
  return FALSE;
}
65
/**
66
 * Make a call
67
 */
Emmanuel Milou's avatar
Emmanuel Milou committed
68
  static void 
69
call_button( GtkWidget *widget, gpointer   data )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
70
{
Emmanuel Milou's avatar
Emmanuel Milou committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  call_t * selectedCall;
  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){
    printf("Calling a called num\n");
    selectedCall = call_get_selected(active_calltree);
    if(!selectedCall->to){
      selectedCall->to = call_get_number(selectedCall);
      selectedCall->from = g_strconcat("\"\" <", selectedCall->to, ">",NULL);
    }
    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(historyButton), FALSE);
    printf("call : from : %s to %s\n", selectedCall->from, selectedCall->to);
    call_list_add(current_calls, selectedCall);
    update_call_tree_add(current_calls, selectedCall);
    sflphone_place_call(selectedCall);
  }else
    sflphone_new_call();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
89
90
}

91
/**
92
 * Hang up the line
93
 */
Emmanuel Milou's avatar
Emmanuel Milou committed
94
  static void 
95
hang_up( GtkWidget *widget, gpointer   data )
96
{
Emmanuel Milou's avatar
Emmanuel Milou committed
97
  sflphone_hang_up();
98
99
100
}

/**
101
 * Hold the line
102
 */
Emmanuel Milou's avatar
Emmanuel Milou committed
103
  static void 
104
hold( GtkWidget *widget, gpointer   data )
105
{
Emmanuel Milou's avatar
Emmanuel Milou committed
106
  sflphone_on_hold();
107
108
109
110
111
}

/**
 * Transfert the line
 */
Emmanuel Milou's avatar
Emmanuel Milou committed
112
  static void 
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
113
transfert  (GtkToggleToolButton *toggle_tool_button,
Emmanuel Milou's avatar
Emmanuel Milou committed
114
    gpointer             user_data)
115
{
Emmanuel Milou's avatar
Emmanuel Milou committed
116
117
118
119
120
121
122
123
124
  gboolean up = gtk_toggle_tool_button_get_active(toggle_tool_button);
  if(up)
  {
    sflphone_set_transfert();
  }
  else
  {
    sflphone_unset_transfert();
  }
125
126
}

127
128
129
/**
 * Unhold call
 */
Emmanuel Milou's avatar
Emmanuel Milou committed
130
  static void 
131
132
unhold( GtkWidget *widget, gpointer   data )
{
Emmanuel Milou's avatar
Emmanuel Milou committed
133
  sflphone_off_hold();
134
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
135

Emmanuel Milou's avatar
Emmanuel Milou committed
136
  static void
areversat's avatar
areversat committed
137
toggle_history(GtkToggleToolButton *toggle_tool_button,
Emmanuel Milou's avatar
Emmanuel Milou committed
138
    gpointer	user_data)
areversat's avatar
areversat committed
139
{
Emmanuel Milou's avatar
Emmanuel Milou committed
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  GtkTreeSelection *sel;
  if(history_shown){
    active_calltree = current_calls;
    gtk_widget_hide(history->tree);
    gtk_widget_show(current_calls->tree);
    history_shown = FALSE;
  }else{
    active_calltree = history;
    gtk_widget_hide(current_calls->tree);
    gtk_widget_show(history->tree);
    history_shown = TRUE;
  }
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (active_calltree->view));
  g_signal_emit_by_name(sel, "changed");
  toolbar_update_buttons();
155

areversat's avatar
areversat committed
156
}
157
158
159
160

  static void
call_mailbox( GtkWidget* widget , gpointer data )
{
Emmanuel Milou's avatar
Emmanuel Milou committed
161
162
163
164
165
  account_t* current = account_list_get_current();
  if( current == NULL ) // Should not happens
    return; 
  call_t* mailboxCall = g_new0( call_t , 1);
  mailboxCall->state = CALL_STATE_DIALING;
166
  mailboxCall->to = g_strdup(g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX));
167
  //mailboxCall->from = g_strconcat("\"Voicemail Box\" <>", NULL);
168
  mailboxCall->from = g_markup_printf_escaped("\"Voicemail\" <%s>",  mailboxCall->to);
Emmanuel Milou's avatar
Emmanuel Milou committed
169
170
171
  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
172
173
  mailboxCall->_start = 0;
  mailboxCall->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
174
175
176
177
178
  g_print("TO : %s\n" , mailboxCall->to);
  call_list_add( current_calls , mailboxCall );
  update_call_tree_add( current_calls , mailboxCall );    
  update_menus();
  sflphone_place_call( mailboxCall );
179
180
}

Emmanuel Milou's avatar
Emmanuel Milou committed
181
  void 
182
toolbar_update_buttons ()
183
{
Emmanuel Milou's avatar
Emmanuel Milou committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  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);
  g_object_ref(holdButton);
  g_object_ref(unholdButton);
  gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
  gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(unholdButton));
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), holdButton, 3);
  g_object_ref(callButton);
  g_object_ref(pickupButton);
  gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
  gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(pickupButton));
  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), callButton, 0);


  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)
  {
    switch(selectedCall->state) 
    {
      case CALL_STATE_INCOMING:
	gtk_widget_set_sensitive( GTK_WIDGET(pickupButton),     TRUE);
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),	TRUE);
	g_object_ref(callButton);	
	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);
222
223
	g_object_ref(holdButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
224
225
226
227
228
229
230
231
232
	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
233
234
	g_object_ref(callButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
235
236
237
238
239
240
241
242
243
244
245
246
247
	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);
	break;
      case CALL_STATE_BUSY:
      case CALL_STATE_FAILURE:
	gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
	break; 
      case CALL_STATE_TRANSFERT:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
248
	gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
249
	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), TRUE);
250
	gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
	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;
      default:
	g_warning("Should not happen!");
	break;
    }
  }
  else 
  {
    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);
    }
  }
273
274
}
/* Call back when the user click on a call in the list */
Emmanuel Milou's avatar
Emmanuel Milou committed
275
  static void 
276
selected(GtkTreeSelection *sel, void* data) 
277
{
Emmanuel Milou's avatar
Emmanuel Milou committed
278
279
280
  GtkTreeIter  iter;
  GValue val;
  GtkTreeModel *model = (GtkTreeModel*)active_calltree->store;
281

Emmanuel Milou's avatar
Emmanuel Milou committed
282
283
  if (! gtk_tree_selection_get_selected (sel, &model, &iter))
    return;
284

Emmanuel Milou's avatar
Emmanuel Milou committed
285
  val.g_type = 0;
286
  gtk_tree_model_get_value (model, &iter, 2, &val);
287

Emmanuel Milou's avatar
Emmanuel Milou committed
288
289
  call_select(active_calltree, (call_t*) g_value_get_pointer(&val));
  g_value_unset(&val);
290

Emmanuel Milou's avatar
Emmanuel Milou committed
291
  toolbar_update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
292
293
}

294
295
/* A row is activated when it is double clicked */
void  row_activated(GtkTreeView       *tree_view,
Emmanuel Milou's avatar
Emmanuel Milou committed
296
297
298
    GtkTreePath       *path,
    GtkTreeViewColumn *column,
    void * data) 
299
{
Emmanuel Milou's avatar
Emmanuel Milou committed
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  call_t * selectedCall = call_get_selected(current_calls);
  if (selectedCall)
  {
    switch(selectedCall->state)  
    {
      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;
    }
  }
324
}                  
325

326

Emmanuel Milou's avatar
Emmanuel Milou committed
327
  GtkWidget * 
areversat's avatar
areversat committed
328
329
create_toolbar ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
  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);

  image = gtk_image_new_from_file( ICONS_DIR "/call.svg");
  callButton = gtk_tool_button_new (image, _("Place a call"));
  gtk_widget_set_tooltip_text(GTK_WIDGET(callButton), _("Place a call"));
  g_signal_connect (G_OBJECT (callButton), "clicked",
      G_CALLBACK (call_button), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(callButton), -1);

  image = gtk_image_new_from_file( ICONS_DIR "/accept.svg");
  pickupButton = gtk_tool_button_new(image, _("Pick up"));
  gtk_widget_set_tooltip_text(GTK_WIDGET(pickupButton), _("Pick up"));
  gtk_widget_set_state( GTK_WIDGET(pickupButton), GTK_STATE_INSENSITIVE);
  g_signal_connect(G_OBJECT (pickupButton), "clicked", 
      G_CALLBACK (call_button), NULL);
  gtk_widget_show_all(GTK_WIDGET(pickupButton));

  image = gtk_image_new_from_file( ICONS_DIR "/hang_up.svg");
  hangupButton = gtk_tool_button_new (image, _("Hang up"));
  gtk_widget_set_tooltip_text(GTK_WIDGET(hangupButton), _("Hang up"));
  gtk_widget_set_state( GTK_WIDGET(hangupButton), GTK_STATE_INSENSITIVE);
  g_signal_connect (G_OBJECT (hangupButton), "clicked",
      G_CALLBACK (hang_up), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(hangupButton), -1);  

  image = gtk_image_new_from_file( ICONS_DIR "/unhold.svg");
  unholdButton = gtk_tool_button_new (image, _("Off Hold"));
  gtk_widget_set_tooltip_text(GTK_WIDGET(unholdButton), _("Off Hold"));
  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"));
  gtk_widget_set_tooltip_text(GTK_WIDGET(holdButton), _("On Hold"));
  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);
  gtk_widget_set_tooltip_text(GTK_WIDGET(transfertButton), _("Transfer"));
  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);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(transfertButton), -1);  

  image = gtk_image_new_from_file( ICONS_DIR "/history2.svg");
  historyButton = gtk_toggle_tool_button_new();
  gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(historyButton), image);
  gtk_widget_set_tooltip_text(GTK_WIDGET(historyButton), _("History"));
  gtk_tool_button_set_label(GTK_TOOL_BUTTON(historyButton), _("History"));
  g_signal_connect (G_OBJECT (historyButton), "toggled",
      G_CALLBACK (toggle_history), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(historyButton), -1);  
  history_shown = FALSE;
  active_calltree = current_calls;

  image = gtk_image_new_from_file( ICONS_DIR "/mailbox.svg");
  mailboxButton = gtk_tool_button_new( image , _("Voicemail box"));
  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 );
  gtk_widget_set_tooltip_text(GTK_WIDGET(mailboxButton), _("Voicemail box"));
  g_signal_connect (G_OBJECT (mailboxButton), "clicked",
      G_CALLBACK (call_mailbox), NULL);
  gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(mailboxButton), -1);

  return ret;
410
411

}  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
412

Emmanuel Milou's avatar
Emmanuel Milou committed
413
  void 
areversat's avatar
areversat committed
414
415
create_call_tree (calltab_t* tab)
{
Emmanuel Milou's avatar
Emmanuel Milou committed
416
417
418
419
  GtkWidget *sw;
  GtkCellRenderer *rend;
  GtkTreeViewColumn *col;
  GtkTreeSelection *sel;
420

Emmanuel Milou's avatar
Emmanuel Milou committed
421
  tab->tree = gtk_vbox_new(FALSE, 10); 
422

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

Emmanuel Milou's avatar
Emmanuel Milou committed
425
426
427
  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);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
428

429
  tab->store = gtk_list_store_new (3, 
Emmanuel Milou's avatar
Emmanuel Milou committed
430
      GDK_TYPE_PIXBUF,// Icon 
Emmanuel Milou's avatar
Emmanuel Milou committed
431

Emmanuel Milou's avatar
Emmanuel Milou committed
432
433
434
      G_TYPE_STRING,  // Description
      G_TYPE_POINTER  // Pointer to the Object
      );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
435

Emmanuel Milou's avatar
Emmanuel Milou committed
436
437
438
439
440
  tab->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(tab->store));
  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);
441

442
  // Connect the popup menu
Emmanuel Milou's avatar
Emmanuel Milou committed
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  g_signal_connect (G_OBJECT (tab->view), "popup-menu",
      G_CALLBACK (popup_menu), 
      NULL);
  g_signal_connect (G_OBJECT (tab->view), "button-press-event",
      G_CALLBACK (button_pressed), 
      NULL);

  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);

  gtk_widget_show(tab->tree); 

  //toolbar_update_buttons();

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
478
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
479

Emmanuel Milou's avatar
Emmanuel Milou committed
480
  void 
481
update_call_tree_remove (calltab_t* tab, call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
482
{
Emmanuel Milou's avatar
Emmanuel Milou committed
483
484
485
486
487
488
489
490
491
492
493
494
495
  GtkTreeIter iter;
  GValue val;
  call_t * iterCall;
  GtkListStore* store = tab->store;
  GtkWidget* view = tab->view;

  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;
496
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
497
498
499
500
501
502
503
504
505
506
507
508
509
510

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

Emmanuel Milou's avatar
Emmanuel Milou committed
513
  void 
514
update_call_tree (calltab_t* tab, call_t * c)
515
{
Emmanuel Milou's avatar
Emmanuel Milou committed
516
517
518
519
520
521
522
523
524
525
526
527
528
529
  GdkPixbuf *pixbuf;
  GtkTreeIter iter;
  GValue val;
  call_t * iterCall;
  GtkListStore* store = tab->store;
  GtkWidget* view = tab->view;

  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;
530
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
531
532
533
534
535
536
537
538

      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
539
540
	gchar * date="";
	gchar * duration="";
Emmanuel Milou's avatar
Emmanuel Milou committed
541
	if(c->state == CALL_STATE_TRANSFERT)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
542
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
543
544
545
	  description = g_markup_printf_escaped("<b>%s</b>\n"
	      "%s\n<i>Transfert to:</i> %s",  
	      call_get_number(c), 
546
	      call_get_name(c), 
Emmanuel Milou's avatar
Emmanuel Milou committed
547
548
549
550
	      c->to);
	}
	else
	{
551
552
553
	  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>", 
	      call_get_number(c),
	      call_get_name(c)); 
Emmanuel Milou's avatar
Emmanuel Milou committed
554
	}
555

556
557
	if( tab == current_calls )
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
	  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);
	      break;
	    default:
	      g_warning("Should not happen!");
	  }
584
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
585
586
	else
	{
587
588
589
	  switch(c->history_state)
	  {
	    case OUTGOING:
Emmanuel Milou's avatar
Emmanuel Milou committed
590
591
592
593
594
595
	      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);
596
597
	      break;
	    case MISSED:
Emmanuel Milou's avatar
Emmanuel Milou committed
598
599
	      g_print("Missed state\n");
	      pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/missed.svg", NULL);
600
601
	      break;
	    default:
Emmanuel Milou's avatar
Emmanuel Milou committed
602
603
	      g_print("No history state\n");  
	      break;
604
	  }
Emmanuel Milou's avatar
Emmanuel Milou committed
605
606
607
608
	  date = timestamp_get_call_date(); 
	  duration = process_call_duration(c);
	  description = g_strconcat( date , description , NULL);
	  description = g_strconcat( description, duration, NULL);
609
	}
610
611
612
	//Resize it
	if(pixbuf)
	{
Emmanuel Milou's avatar
Emmanuel Milou committed
613
614
615
616
	  if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32)
	  {
	    pixbuf =  gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR);
	  }
617
	}
Emmanuel Milou's avatar
Emmanuel Milou committed
618
619
620
621
	gtk_list_store_set(store, &iter,
	    0, pixbuf, // Icon
	    1, description, // Description
	    -1);
622
623

	if (pixbuf != NULL)
Emmanuel Milou's avatar
Emmanuel Milou committed
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
	  g_object_unref(G_OBJECT(pixbuf));

      } 
    }

  } 
  toolbar_update_buttons();
}

  void 
update_call_tree_add (calltab_t* tab, call_t * c)
{
  if( tab == history && ( call_list_get_size( tab ) > dbus_get_max_calls() ) )
    return;

  GdkPixbuf *pixbuf;
  GtkTreeIter iter;
  GtkTreeSelection* sel;

  // New call in the list
Emmanuel Milou's avatar
Emmanuel Milou committed
644
  gchar * description;
Emmanuel Milou's avatar
Emmanuel Milou committed
645
  gchar * date="";
Emmanuel Milou's avatar
Emmanuel Milou committed
646
647
  gchar * duration="";
  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>", 
648
649
      call_get_number(c),
      call_get_name(c)); 
Emmanuel Milou's avatar
Emmanuel Milou committed
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

  
  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:
	g_warning("Should not happen!");
    }
Emmanuel Milou's avatar
Emmanuel Milou committed
686
687
688
689
690
    date = timestamp_get_call_date(); 

	  duration = process_call_duration(c);
	  //g_print("call duration = %s\n" , duration);
    description = g_strconcat( date , description , NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
691
  }
692

Emmanuel Milou's avatar
Emmanuel Milou committed
693
694
695
696
697
698
699
700
701
702
  //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
703
      1, description, // Description
704
      2, c,      // Pointer
Emmanuel Milou's avatar
Emmanuel Milou committed
705
706
707
708
709
710
711
712
      -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
713
}