calltree.c 21.6 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
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
	gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(histfilter));
156

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

  static void
call_mailbox( GtkWidget* widget , gpointer data )
{
Emmanuel Milou's avatar
Emmanuel Milou committed
162
163
164
165
166
  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;
167
168
169
  mailboxCall->to = g_strdup(g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX));
  mailboxCall->from = g_strconcat("\"Voicemail Box\" <>", NULL);
  mailboxCall->from = g_markup_printf_escaped("\"Voicemail\" <%s>",  mailboxCall->to);
Emmanuel Milou's avatar
Emmanuel Milou committed
170
171
172
173
174
175
176
177
  mailboxCall->callID = g_new0(gchar, 30);
  g_sprintf(mailboxCall->callID, "%d", rand());
  mailboxCall->accountID = g_strdup(current->accountID);
  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 );
178
179
}

Emmanuel Milou's avatar
Emmanuel Milou committed
180
  void 
181
toolbar_update_buttons ()
182
{
Emmanuel Milou's avatar
Emmanuel Milou committed
183
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
  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);
221
222
	g_object_ref(holdButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(holdButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
223
224
225
226
227
228
229
230
231
	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
232
233
	g_object_ref(callButton);
	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(callButton));
Emmanuel Milou's avatar
Emmanuel Milou committed
234
235
236
237
238
239
240
241
242
243
244
245
246
	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
247
	gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
248
	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), TRUE);
249
	gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);
Emmanuel Milou's avatar
Emmanuel Milou committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
	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);
    }
  }
272
273
}
/* Call back when the user click on a call in the list */
Emmanuel Milou's avatar
Emmanuel Milou committed
274
  static void 
275
selected(GtkTreeSelection *sel, void* data) 
276
{
Emmanuel Milou's avatar
Emmanuel Milou committed
277
278
279
  GtkTreeIter  iter;
  GValue val;
  GtkTreeModel *model = (GtkTreeModel*)active_calltree->store;
280

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

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

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

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

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

325

Emmanuel Milou's avatar
Emmanuel Milou committed
326
  GtkWidget * 
areversat's avatar
areversat committed
327
328
create_toolbar ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
329
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
  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;
409
410

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

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

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

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

Emmanuel Milou's avatar
Emmanuel Milou committed
424
425
426
  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
427

428
  tab->store = gtk_list_store_new (3, 
Emmanuel Milou's avatar
Emmanuel Milou committed
429
430
431
432
      GDK_TYPE_PIXBUF,// Icon 
      G_TYPE_STRING,  // Description
      G_TYPE_POINTER  // Pointer to the Object
      );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
433

Emmanuel Milou's avatar
Emmanuel Milou committed
434
435
436
437
438
  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);
439

440
  // Connect the popup menu
Emmanuel Milou's avatar
Emmanuel Milou committed
441
442
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
  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
476
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
477

Emmanuel Milou's avatar
Emmanuel Milou committed
478
  void 
479
update_call_tree_remove (calltab_t* tab, call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
480
{
Emmanuel Milou's avatar
Emmanuel Milou committed
481
482
483
484
485
486
487
488
489
490
491
492
493
  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;
494
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
495
496
497
498
499
500
501
502
503
504
505
506
507
508

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

Emmanuel Milou's avatar
Emmanuel Milou committed
511
  void 
512
update_call_tree (calltab_t* tab, call_t * c)
513
{
Emmanuel Milou's avatar
Emmanuel Milou committed
514
515
516
517
518
519
520
521
522
523
524
525
526
527
  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;
528
      gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
Emmanuel Milou's avatar
Emmanuel Milou committed
529
530
531
532
533
534
535
536

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

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

	if (pixbuf != NULL)
Emmanuel Milou's avatar
Emmanuel Milou committed
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
	  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
642
  gchar * description;
Emmanuel Milou's avatar
Emmanuel Milou committed
643
  gchar * date="";
Emmanuel Milou's avatar
Emmanuel Milou committed
644
645
  gchar * duration="";
  description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>", 
646
647
      call_get_number(c),
      call_get_name(c)); 
Emmanuel Milou's avatar
Emmanuel Milou committed
648
649
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

  
  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
684
685
686
687
688
    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
689
  }
690

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