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

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

GtkListStore * store;
27
28
GtkWidget *view;

29
30
GtkWidget * callButton;
GtkWidget * hangupButton;
31
GtkWidget * holdButton;
32
GtkWidget * transfertButton;
33
GtkWidget * unholdButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
34

35
/**
36
 * Make a call
37
38
 */
static void 
39
call_button( GtkWidget *widget, gpointer   data )
40
{
41
  call_t * selectedCall = call_get_selected();
42
  if(selectedCall)
43
  {
44
45
46
    switch(selectedCall->state)
    {
      case CALL_STATE_DIALING:
47
        sflphone_place_call (selectedCall);
48
49
50
51
        break;
      case CALL_STATE_INCOMING:
        dbus_accept (selectedCall);
        break;
52
53
54
      default:
        g_error("Should not happen!");
        break;
55
    }
56
57
58
59
  }
}

/**
60
 * Hang up the line
61
62
 */
static void 
63
hang_up( GtkWidget *widget, gpointer   data )
64
{
65
  call_t * selectedCall = call_get_selected();
66
  if(selectedCall)
67
  {
68
69
70
71
72
    switch(selectedCall->state)
    {
      case CALL_STATE_CURRENT:
      case CALL_STATE_HOLD:
      case CALL_STATE_DIALING:
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
73
      case CALL_STATE_RINGING:
74
75
76
77
78
        dbus_hang_up (selectedCall);
        break;
      case CALL_STATE_INCOMING:  
        dbus_refuse (selectedCall);
        break;
79
80
81
      default:
        g_error("Should not happen!");
        break;
82
    }
83
84
85
86
  }
}

/**
87
 * Hold the line
88
89
 */
static void 
90
hold( GtkWidget *widget, gpointer   data )
91
{
92
  call_t * selectedCall = call_get_selected();
93
  if(selectedCall)
94
  {
95
96
97
98
99
    switch(selectedCall->state)
    {
      case CALL_STATE_CURRENT:
        dbus_hold (selectedCall);
        break;
100
101
102
      default:
        g_error("Should not happen!");
        break;
103
    }
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  }
}

/**
 * Transfert the line
 */
static void 
transfert( GtkWidget *widget, gpointer   data )
{
  call_t * c = (call_t*) call_list_get_by_state (CALL_STATE_CURRENT);
  if(c)
  {
    dbus_transfert(c,"124");
  }
}

120
121
122
123
124
125
/**
 * Unhold call
 */
static void 
unhold( GtkWidget *widget, gpointer   data )
{
126
  call_t * selectedCall = call_get_selected();
127
128
129
130
131
132
133
  if(selectedCall)
  {
    switch(selectedCall->state)
    {
      case CALL_STATE_HOLD:
        dbus_unhold (selectedCall);
        break;
134
135
136
      default:
        g_error("Should not happen!");
        break;
137
138
139
140
141
142
143
144
145
146
147
      }
  }
}
void 
update_buttons ()
{
  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(unholdButton),     FALSE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
148
	
149
150
	call_t * selectedCall = call_get_selected();
  if(selectedCall)  // TODO Make this a switch
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
151
152
153
	{
	  if( selectedCall->state == CALL_STATE_INCOMING)
	  {
154
155
      gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
      gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
156
157
158
    }
    else if( selectedCall->state == CALL_STATE_HOLD)
	  {
159
      gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
160
      gtk_widget_set_sensitive( GTK_WIDGET(unholdButton),     TRUE);
161
162
163
164
    }
    else if( selectedCall->state == CALL_STATE_RINGING)
	  {
      gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
165
    }
166
167
168
    else if(selectedCall->state == CALL_STATE_DIALING)
    {
      gtk_widget_set_sensitive( GTK_WIDGET(callButton),       TRUE);
169
      gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
170
171
172
173
174
175
176
177
178
179
180
181
182
    }
    else if (selectedCall->state == CALL_STATE_CURRENT)
    {
      //gtk_widget_hide( callButton  );
      /* Hack : if hangupButton is put on the window in create_screen()
       * the hbox will request space for 4 buttons making the window larger than needed */
      //gtk_box_pack_start (GTK_BOX (hbox), hangupButton, TRUE /*expand*/, TRUE /*fill*/, 10 /*padding*/);
      //gtk_box_reorder_child(GTK_BOX (hbox), hangupButton, 0);
      gtk_widget_show( hangupButton );
      gtk_widget_set_sensitive( GTK_WIDGET(hangupButton),     TRUE);
      gtk_widget_set_sensitive( GTK_WIDGET(holdButton),       TRUE);
      gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  TRUE);
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
183
184
	  
	}
185
186
187
188
189
190
191
192
193
194
195
}
/* Call back when the user click on a call in the list */
static void 
selected(GtkTreeSelection *sel, GtkTreeModel *model) 
{
	GtkTreeIter  iter;
	GValue val;
	
	if (! gtk_tree_selection_get_selected (sel, &model, &iter))
		return;
  
196
	val.g_type = 0;
197
198
	gtk_tree_model_get_value (model, &iter, 2, &val);
	
199
	call_select((call_t*) g_value_get_pointer(&val));
200
  g_value_unset(&val);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
201
  
202
  update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
203
204
205
206
207
208
209
210
211
212
213
214
}


GtkWidget * 
create_call_tree (){
  GtkWidget *ret;
	GtkWidget *sw;
  GtkWidget *hbox;
	GtkWidget *image;
	GtkCellRenderer *rend;
	GtkTreeViewColumn *col;
	GtkTreeSelection *sel;
215
	
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
216
217
218
219
	ret = gtk_vbox_new(FALSE, 10); 
	gtk_container_set_border_width (GTK_CONTAINER (ret), 0);

	sw = gtk_scrolled_window_new( NULL, NULL);
220
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
221
222
223
224
225
226
227
228
229
230
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);

	store = gtk_list_store_new (3, 
	  GDK_TYPE_PIXBUF,// Icon 
	  G_TYPE_STRING,  // Description
	  G_TYPE_POINTER  // Pointer to the Object
	  );


	view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
231
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
	
  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(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(view), col);
	g_object_unref(G_OBJECT(store));
	gtk_container_add(GTK_CONTAINER(sw), view);

  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
  g_signal_connect (G_OBJECT (sel), "changed",
			  G_CALLBACK (selected),
			  store);
  
  /* Action button */     
255
  hbox = gtk_hbox_new (FALSE, 5);       
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
256
  
257
  callButton = gtk_button_new ();
258
259
260
261
  gtk_widget_set_state( GTK_WIDGET(callButton), GTK_STATE_INSENSITIVE);
  image = gtk_image_new_from_file( PIXMAPS_DIR "/call.svg");
  gtk_button_set_image(GTK_BUTTON(callButton), image);
  //gtk_button_set_image_position( button, GTK_POS_TOP);
262
  gtk_box_pack_start (GTK_BOX (hbox), callButton, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
263
  g_signal_connect (G_OBJECT (callButton), "clicked",
264
                    G_CALLBACK (call_button), NULL);
265

266
  hangupButton = gtk_button_new ();
267
268
  gtk_widget_hide( hangupButton );
  gtk_widget_set_state( GTK_WIDGET(hangupButton), GTK_STATE_INSENSITIVE);
269
  gtk_box_pack_start (GTK_BOX (hbox), hangupButton, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
270
271
272
273
274
  image = gtk_image_new_from_file( PIXMAPS_DIR "/hang_up.svg");
  gtk_button_set_image(GTK_BUTTON(hangupButton), image);
  //gtk_button_set_image_position( button, GTK_POS_TOP);
  g_signal_connect (G_OBJECT (hangupButton), "clicked",
                    G_CALLBACK (hang_up), NULL);
275
276
277
278
279
280
281
282
283
284
                      
  unholdButton = gtk_button_new ();
  image = gtk_image_new_from_file( PIXMAPS_DIR "/unhold.svg");
  gtk_button_set_image(GTK_BUTTON(unholdButton), image);
  gtk_widget_set_state( GTK_WIDGET(unholdButton), GTK_STATE_INSENSITIVE);
  gtk_box_pack_end (GTK_BOX (hbox), unholdButton, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
  g_signal_connect (G_OBJECT (unholdButton), "clicked",
                    G_CALLBACK (unhold), NULL);
             
  holdButton = gtk_button_new ();
285
286
  image = gtk_image_new_from_file( PIXMAPS_DIR "/hold.svg");
  gtk_button_set_image(GTK_BUTTON(holdButton), image);
287
288
  gtk_widget_set_state( GTK_WIDGET(holdButton), GTK_STATE_INSENSITIVE);
  gtk_box_pack_end (GTK_BOX (hbox), holdButton, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
289
290
291
  g_signal_connect (G_OBJECT (holdButton), "clicked",
                    G_CALLBACK (hold), NULL);

292
  transfertButton = gtk_button_new ();
293
294
  image = gtk_image_new_from_file( PIXMAPS_DIR "/transfert.svg");
  gtk_button_set_image(GTK_BUTTON(transfertButton), image);
295
296
  gtk_widget_set_state( GTK_WIDGET(transfertButton), GTK_STATE_INSENSITIVE);
  gtk_box_pack_end (GTK_BOX (hbox), transfertButton, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
297
298
  g_signal_connect (G_OBJECT (transfertButton), "clicked",
                    G_CALLBACK (transfert), NULL);
299
300
301
302
                    
  gtk_box_pack_start (GTK_BOX (ret), hbox, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
  gtk_box_pack_start(GTK_BOX(ret), sw, TRUE, TRUE, 0);
	
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
303
304
305
306
307
308
	gtk_widget_show(ret); 
	
	return ret;
	
}
void 
309
update_call_tree_remove (call_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
310
311
{
	GtkTreeIter iter;
312
313
	GValue val;
	call_t * iterCall;
314
 
315
316
317
318
319
320
	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))
	  {
321
	    val.g_type = 0;
322
323
324
325
326
327
328
329
330
331
332
    	gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
    	
    	iterCall = (call_t*) g_value_get_pointer(&val);
      g_value_unset(&val);
      
      if(iterCall == c)
      {
        gtk_list_store_remove(store, &iter);
      }
	  }
	}
333
	call_t * selectedCall = call_get_selected();
334
	if(selectedCall == c)
335
	  call_select(NULL);
336
337
	update_buttons();
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
338

339
340
341
342
343
344
345
346
347
void 
update_call_tree (call_t * c)
{
  GdkPixbuf *pixbuf;
  GtkTreeIter iter;
	GValue val;
	call_t * iterCall;
	
	int nbChild = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
348
  int i;
349
	for( i = 0; i < nbChild; i++)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
350
	{
351
352
	  if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i))
	  {
353
	    val.g_type = 0;
354
355
356
357
358
359
    	gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, 2, &val);
    	
    	iterCall = (call_t*) g_value_get_pointer(&val);
      g_value_unset(&val);
      
      if(iterCall == c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
360
      {
361
362
        // Existing call in the list
        gchar * markup;
363
        markup = g_markup_printf_escaped("<b>%s</b>\n"
364
365
366
    						    "%s", 
    						    call_get_name(c), 
    						    call_get_number(c));
367
    		    		
368
369
370
371
    		if (c->state == CALL_STATE_HOLD)
    		{
    		  pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/hold.svg", NULL);
    		}
372
    		else if (c->state == CALL_STATE_RINGING)
373
374
375
376
377
378
379
    		{
    		  pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/ring.svg", NULL);
    		}
    	  else if (c->state == CALL_STATE_CURRENT)
    		{
    		  pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/current.svg", NULL);
    		}
380
381
382
383
    	  else if (c->state == CALL_STATE_DIALING)
    		{
    		  pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/dial.svg", NULL);
    		}
384
385
    	  //Resize it
        if(pixbuf)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
386
        {
387
388
389
390
          if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32)
          {
            pixbuf =  gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR);
          }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
391
        }
392
    		gtk_list_store_set(store, &iter,
393
394
395
    				  0, pixbuf, // Icon
  		        1, markup, // Description
  		        -1);
396
397
398
399
400
401
    				   
    		if (pixbuf != NULL)
    			g_object_unref(G_OBJECT(pixbuf));
        
      } 
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
402
403
    
  } 
404
  update_buttons();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
405
	//return row_ref;
406
407
408
409
410
411
412
413

}

void 
update_call_tree_add (call_t * c)
{
  GdkPixbuf *pixbuf;
	GtkTreeIter iter;
414
	GtkTreeSelection* sel;
415
416
417

  // New call in the list
  gchar * markup;
418
  markup = g_markup_printf_escaped("<b>%s</b>\n"
419
420
421
  				    "%s", 
  				    call_get_name(c), 
  				    call_get_number(c));
422
  
423
424
  gtk_list_store_append (store, &iter);

425
  if (c->state == CALL_STATE_INCOMING)
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  {
    pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/ring.svg", NULL);
  }
  else if (c->state == CALL_STATE_DIALING)
  {
    pixbuf = gdk_pixbuf_new_from_file(PIXMAPS_DIR "/dial.svg", NULL);
  }
  //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(store, &iter,
  		   0, pixbuf, // Icon
  		   1, markup, // Description
  		   2, c,      // Pointer
  		   -1);
  		   
  if (pixbuf != NULL)
  	g_object_unref(G_OBJECT(pixbuf));

  //g_free(markup);
451
452
  sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
  gtk_tree_selection_select_iter(GTK_TREE_SELECTION(sel), &iter);
453
  update_buttons();
454
	//return row_ref;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
455
}