configwindow.c 42.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@squidy.info>
4
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
5
6
 *  Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com>
 *  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
7
8
 *  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
9
 *  the Free Software Foundation; either version 3 of the License, or
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
10
 *  (at your option) any later version.
11
 *  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
12
13
14
15
 *  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.
16
 *  
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
17
18
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
19
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
20
 */
21

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
22
#include <accountlist.h>
23
24
#include <accountwindow.h>
#include <actions.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
25
26
27
#include <config.h>
#include <dbus.h>
#include <mainwindow.h>
28

29
#include <stdlib.h>
30
#include <stdio.h>
31

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
32
33
#include <gtk/gtk.h>

34
35
36
/**
 * Local variables
 */
37
gboolean dialogOpen = FALSE;
38
gboolean ringtoneEnabled = TRUE;
39

40
41
42
GtkListStore *accountStore;
GtkWidget *codecTreeView;		// View used instead of store to get access to selection
								// instead of keeping selected codec as a variable
43
44
GtkListStore *inputAudioPluginStore;
GtkListStore *outputAudioPluginStore;
45
46
GtkListStore *outputAudioDeviceManagerStore;
GtkListStore *inputAudioDeviceManagerStore;
47

48
49
50
GtkWidget *addButton;
GtkWidget *editButton;
GtkWidget *deleteButton;
51
//GtkWidget *defaultButton;
52
GtkWidget *restoreButton;
53
54
GtkWidget *accountMoveDownButton;
GtkWidget *accountMoveUpButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
55

56
57
GtkWidget *outputDeviceComboBox;
GtkWidget *inputDeviceComboBox;
58
GtkWidget *pluginComboBox;
59

60
61
GtkWidget *codecMoveUpButton;
GtkWidget *codecMoveDownButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
62

63
account_t *selectedAccount;
64

65
66
67
68
69
70
71
72
73
74
// Account properties
enum {
	COLUMN_ACCOUNT_ALIAS,
	COLUMN_ACCOUNT_TYPE,
	COLUMN_ACCOUNT_STATUS,
	COLUMN_ACCOUNT_ACTIVE,
	COLUMN_ACCOUNT_DATA,
	COLUMN_ACCOUNT_COUNT
};

75
76
77
78
79
80
81
82
83
84
// Codec properties ID
enum {
	COLUMN_CODEC_ACTIVE,
	COLUMN_CODEC_NAME,
	COLUMN_CODEC_FREQUENCY,
	COLUMN_CODEC_BITRATE,
	COLUMN_CODEC_BANDWIDTH,
	CODEC_COLUMN_COUNT
};

85
86
87
88
89
/**
 * Fills the treelist with accounts
 */
void
config_window_fill_account_list()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
90
{
91
92
93
94
	if(dialogOpen)
	{
		GtkTreeIter iter;

95
		gtk_list_store_clear(accountStore);
96
		int i;
97
		for(i = 0; i < account_list_get_size(); i++)
98
		{
99
			account_t * a = account_list_get_nth (i);
100
101
			if (a)
			{
102
			  g_print("fill account list : %s\n" , (gchar*)g_hash_table_lookup(a->properties, ACCOUNT_ENABLED));
103
104
				gtk_list_store_append (accountStore, &iter);
				gtk_list_store_set(accountStore, &iter,
105
106
107
108
109
						COLUMN_ACCOUNT_ALIAS, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS),  // Name
						COLUMN_ACCOUNT_TYPE, g_hash_table_lookup(a->properties, ACCOUNT_TYPE),   // Protocol
						COLUMN_ACCOUNT_STATUS, account_state_name(a->state),      // Status
						COLUMN_ACCOUNT_ACTIVE, (g_strcasecmp(g_hash_table_lookup(a->properties, ACCOUNT_ENABLED),"TRUE") == 0)? TRUE:FALSE,  // Enable/Disable
						COLUMN_ACCOUNT_DATA, a,   // Pointer
110
111
						-1);
			}
112
		}
113
114
115
116

		gtk_widget_set_sensitive( GTK_WIDGET(editButton),   FALSE);
		gtk_widget_set_sensitive( GTK_WIDGET(deleteButton), FALSE);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
117
}
118

119
120
/**
 * Fills the tree list with supported codecs
121
*/
122
void
123
124
config_window_fill_codec_list()
{
125
126
	if(dialogOpen)
	{
127
		GtkListStore *codecStore;
128
		GtkTreeIter iter;
129
130
131
		
		// Get model of view and clear it
		codecStore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView)));
132
133
		gtk_list_store_clear(codecStore);

134
135
		// Insert codecs
		int i;
136
137
		for(i = 0; i < codec_list_get_size(); i++)
		{
138
			codec_t *c = codec_list_get_nth(i);
139
140
141
142
143
			printf("%s\n", c->name);
			if(c)
			{
				gtk_list_store_append(codecStore, &iter);
				gtk_list_store_set(codecStore, &iter,
144
145
146
						COLUMN_CODEC_ACTIVE,	c->is_active,									// Active
						COLUMN_CODEC_NAME,		c->name,										// Name
						COLUMN_CODEC_FREQUENCY,	g_strdup_printf("%d kHz", c->sample_rate/1000),	// Frequency (kHz)
147
						COLUMN_CODEC_BITRATE,	g_strdup_printf("%.1f kbps", c->_bitrate),		// Bitrate (kbps)
148
						COLUMN_CODEC_BANDWIDTH,	g_strdup_printf("%.1f kbps", c->_bandwidth),	// Bandwidth (kpbs)
149
150
151
152
						-1);
			}
		}
	}
153
154
}

155
/**
156
 * Fill store with input audio plugins
157
 */
158
void
159
config_window_fill_input_audio_plugin_list()
160
{
161
162
163
164
	GtkTreeIter iter;
	gchar** list;
	gchar* managerName;

165
	gtk_list_store_clear(inputAudioPluginStore);
166
	
167
	// Call dbus to retreive list
168
	list = dbus_get_input_audio_plugin_list();
169
170
171
172
173
174
	
	// For each API name included in list
	int c = 0;
	for(managerName = list[c]; managerName != NULL; managerName = list[c])
	{
		c++;
175
176
		gtk_list_store_append(inputAudioPluginStore, &iter);
		gtk_list_store_set(inputAudioPluginStore, &iter, 0 , managerName, -1);
177
	}
178
}
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**
 * Fill store with output audio plugins
 */
void
config_window_fill_output_audio_plugin_list()
{
	GtkTreeIter iter;
	gchar** list;
	gchar* managerName;

	gtk_list_store_clear(outputAudioPluginStore);
	
	// Call dbus to retreive list
	list = dbus_get_output_audio_plugin_list();
	
	// For each API name included in list
	int c = 0;
	for(managerName = list[c]; managerName != NULL; managerName = list[c])
	{
		c++;
		gtk_list_store_append(outputAudioPluginStore, &iter);
		gtk_list_store_set(outputAudioPluginStore, &iter, 0 , managerName, -1);
	}
}
204
/**
205
 * Fill output audio device store
206
207
208
209
 */
void
config_window_fill_output_audio_device_list()
{
210
211
	GtkTreeIter iter;
	gchar** list;
212
	gchar** audioDevice;
213
	int index;
214
215

	gtk_list_store_clear(outputAudioDeviceManagerStore);
216
	
217
218
219
220
221
	// Call dbus to retreive list
	list = dbus_get_audio_output_device_list();
	
	// For each device name included in list
	int c = 0;
222
	for(audioDevice = list; *list ; list++)
223
	{
224
		index = dbus_get_audio_device_index( *list );
225
		gtk_list_store_append(outputAudioDeviceManagerStore, &iter);
226
		gtk_list_store_set(outputAudioDeviceManagerStore, &iter, 0, *list, 1, index, -1);
227
		c++;
228
	}
229
230
231
}

/**
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 * Select active output audio device
 */
void
select_active_output_audio_device()
{
	GtkTreeModel* model;
	GtkTreeIter iter;
	gchar** devices;
	int currentDeviceIndex;
	int deviceIndex;

	// Select active output device on server
	devices = dbus_get_current_audio_devices_index();
	currentDeviceIndex = atoi(devices[0]);
246
	printf(_("audio device index for output = %d\n"), currentDeviceIndex);
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
	model = gtk_combo_box_get_model(GTK_COMBO_BOX(outputDeviceComboBox));
	
	// Find the currently set output device
	gtk_tree_model_get_iter_first(model, &iter);
	do {
		gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1);
		if(deviceIndex == currentDeviceIndex)
		{
			// Set current iteration the active one
			gtk_combo_box_set_active_iter(GTK_COMBO_BOX(outputDeviceComboBox), &iter);
			return;
		}
	} while(gtk_tree_model_iter_next(model, &iter));

	// No index was found, select first one
	g_print("Warning : No active output device found");
	gtk_combo_box_set_active(GTK_COMBO_BOX(outputDeviceComboBox), 0);
}

/**
 * Fill input audio device store
268
269
270
271
 */
void
config_window_fill_input_audio_device_list()
{
272
273
	GtkTreeIter iter;
	gchar** list;
274
	gchar** audioDevice;
275
	int index ;
276
277
278
279
	gtk_list_store_clear(inputAudioDeviceManagerStore);
	
	// Call dbus to retreive list
	list = dbus_get_audio_input_device_list();
280
	
281
	// For each device name included in list
282
	//int c = 0;
283
	for(audioDevice = list; *list; list++)
284
	{
285
		index = dbus_get_audio_device_index( *list );
286
		gtk_list_store_append(inputAudioDeviceManagerStore, &iter);
287
288
		gtk_list_store_set(inputAudioDeviceManagerStore, &iter, 0, *list, 1, index, -1);
		//c++;
289
290
291
292
	}
}

/**
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 * Select active input audio device
 */
void
select_active_input_audio_device()
{
	GtkTreeModel* model;
	GtkTreeIter iter;
	gchar** devices;
	int currentDeviceIndex;
	int deviceIndex;

	// Select active input device on server
	devices = dbus_get_current_audio_devices_index();
	currentDeviceIndex = atoi(devices[1]);
	model = gtk_combo_box_get_model(GTK_COMBO_BOX(inputDeviceComboBox));
	
	// Find the currently set input device
	gtk_tree_model_get_iter_first(model, &iter);
	do {
		gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1);
		if(deviceIndex == currentDeviceIndex)
		{
			// Set current iteration the active one
			gtk_combo_box_set_active_iter(GTK_COMBO_BOX(inputDeviceComboBox), &iter);
			return;
		}
	} while(gtk_tree_model_iter_next(model, &iter));

	// No index was found, select first one
	g_print("Warning : No active input device found");
	gtk_combo_box_set_active(GTK_COMBO_BOX(inputDeviceComboBox), 0);
}

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
void
update_combo_box( gchar* plugin )
{
	// set insensitive the devices widget if the selected plugin is default
	if( g_strcasecmp( plugin , "default" ) == 0)
	{
	  gtk_widget_set_sensitive( GTK_WIDGET ( outputDeviceComboBox ) , FALSE );
	  gtk_widget_set_sensitive( GTK_WIDGET ( inputDeviceComboBox ) , FALSE );
	}
	else
	{
	  gtk_widget_set_sensitive( GTK_WIDGET ( outputDeviceComboBox ) , TRUE );
	  gtk_widget_set_sensitive( GTK_WIDGET ( inputDeviceComboBox ) , TRUE );
	}
}
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/**
 * Select the output audio plugin by calling the server
 */
static void
select_output_audio_plugin(GtkComboBox* widget, gpointer data)
{
	GtkTreeModel* model;
	GtkTreeIter iter;
	int comboBoxIndex;
	gchar* pluginName;
	
	comboBoxIndex = gtk_combo_box_get_active(widget);
	
	if(comboBoxIndex >= 0)
	{
		model = gtk_combo_box_get_model(widget);
		gtk_combo_box_get_active_iter(widget, &iter);
358
		gtk_tree_model_get(model, &iter, 0, &pluginName, -1);	
359
		dbus_set_output_audio_plugin(pluginName);
360
		update_combo_box( pluginName);
361
362
	}
}
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

/**
 * Select active output audio plugin
 */
void
select_active_output_audio_plugin()
{
	GtkTreeModel* model;
	GtkTreeIter iter;
	gchar* plugin;
	gchar* tmp;

	// Select active output device on server
	plugin = dbus_get_current_audio_output_plugin();
	tmp = plugin;
	model = gtk_combo_box_get_model(GTK_COMBO_BOX(pluginComboBox));
379
	  
380
	// Find the currently alsa plugin
381
382
383
	gtk_tree_model_get_iter_first(model, &iter);
	do {
		gtk_tree_model_get(model, &iter, 0, &plugin , -1);
384
		if( g_strcasecmp( tmp , plugin ) == 0 )
385
386
387
		{
			// Set current iteration the active one
			gtk_combo_box_set_active_iter(GTK_COMBO_BOX(pluginComboBox), &iter);
388
			update_combo_box( plugin );
389
390
391
392
393
			return;
		}
	} while(gtk_tree_model_iter_next(model, &iter));

	// No index was found, select first one
394
	g_print("Warning : No active output device found\n");
395
	gtk_combo_box_set_active(GTK_COMBO_BOX(pluginComboBox), 0);
396
	update_combo_box("default");
397
398
}

399

400
/**
401
 * Set the audio output device on the server with its index
402
403
 */
static void
404
select_audio_output_device(GtkComboBox* comboBox, gpointer data)
405
{
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
	GtkTreeModel* model;
	GtkTreeIter iter;
	int comboBoxIndex;
	int deviceIndex;
	
	comboBoxIndex = gtk_combo_box_get_active(comboBox);
	
	if(comboBoxIndex >= 0)
	{
		model = gtk_combo_box_get_model(comboBox);
		gtk_combo_box_get_active_iter(comboBox, &iter);
		gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1);
		
		dbus_set_audio_output_device(deviceIndex);
	}
421
422
423
}

/**
424
 * Set the audio input device on the server with its index
425
426
 */
static void
427
select_audio_input_device(GtkComboBox* comboBox, gpointer data)
428
{
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
	GtkTreeModel* model;
	GtkTreeIter iter;
	int comboBoxIndex;
	int deviceIndex;
	
	comboBoxIndex = gtk_combo_box_get_active(comboBox);
	
	if(comboBoxIndex >= 0)
	{
		model = gtk_combo_box_get_model(comboBox);
		gtk_combo_box_get_active_iter(comboBox, &iter);
		gtk_tree_model_get(model, &iter, 1, &deviceIndex, -1);
		
		dbus_set_audio_input_device(deviceIndex);
	}
444
445
446
447
448
449
450
451
452
}

/**
 * Refresh all audio settings
 */
static void
detect_all_audio_settings()
{
	// Update lists
453
454
	config_window_fill_output_audio_device_list();
	config_window_fill_input_audio_device_list();
455
	
456
	// Select active device in combo box
457
458
	//select_active_output_audio_device();
	//select_active_input_audio_device();
459
460
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
461
462
463
/**
 * Delete an account
 */
464
465
static void
delete_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
466
{
467
468
469
470
	if(selectedAccount)
	{
		dbus_remove_account(selectedAccount->accountID);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
471
472
473
}

/**
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
474
 * Edit an account
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
475
 */
476
477
static void
edit_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
478
{
479
480
481
482
	if(selectedAccount)
	{
		show_account_window(selectedAccount);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
483
484
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
485
486
487
/**
 * Add an account
 */
488
489
static void
add_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
490
{
491
492
493
	show_account_window(NULL);
}

494
495
496
int 
is_ringtone_enabled( void )
{
497
  return dbus_is_ringtone_enabled();  
498
499
}

Emmanuel Milou's avatar
Emmanuel Milou committed
500
501
502
503
504
505
void
start_hidden( void )
{
  dbus_start_hidden();
}

506
507
508
509
510
511
void
set_popup_mode( void )
{
  dbus_switch_popup_mode();
}

512
513
514
515
516
void 
ringtone_enabled( void )
{
  dbus_ringtone_enabled();  
}
517
518
519
520
521
522
523
524
525
526
527
528
529
530

void
ringtone_changed( GtkFileChooser *chooser , GtkLabel *label)
{
  gchar* tone = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( chooser ));
  dbus_set_ringtone_choice( tone );
}

gchar*
get_ringtone_choice( void )
{
  return dbus_get_ringtone_choice();
}

531
532
533
534
535
/**
 * Call back when the user click on an account in the list
 */
static void
select_account(GtkTreeSelection *selection, GtkTreeModel *model)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
536
{
537
	GtkTreeIter iter;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
538
	GValue val;
539

540
	if (!gtk_tree_selection_get_selected(selection, &model, &iter))
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
541
	{
542
		selectedAccount = NULL;
543
544
		gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
		gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
545
		return;
546
547
	}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
548
	val.g_type = G_TYPE_POINTER;
549
	gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_DATA, &val);
550

551
	selectedAccount = (account_t*)g_value_get_pointer(&val);
552
553
	g_value_unset(&val);

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
554
555
	if(selectedAccount)
	{
556
557
		gtk_widget_set_sensitive(GTK_WIDGET(editButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), TRUE);
558
559
		gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), TRUE);
560
561
	}
	g_print("select");
562
}
563

564
565
566
/**
 * Toggle move buttons on if a codec is selected, off elsewise
 */
567
static void
568
select_codec(GtkTreeSelection *selection, GtkTreeModel *model)
569
570
{
	GtkTreeIter iter;
571
572
573
	
	if(!gtk_tree_selection_get_selected(selection, &model, &iter))
	{
574
575
		gtk_widget_set_sensitive(GTK_WIDGET(codecMoveUpButton), FALSE);
		gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), FALSE);
576
577
578
	}
	else
	{
579
580
		gtk_widget_set_sensitive(GTK_WIDGET(codecMoveUpButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), TRUE);
581
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
582
583
}

584
/**
585
586
 * Toggle active value of codec on click and update changes to the deamon
 * and in configuration files
587
 */
588
static void
589
codec_active_toggled(GtkCellRendererToggle *renderer, gchar *path, gpointer data)
590
{
591
	GtkTreeIter iter;
592
593
	GtkTreePath *treePath;
	GtkTreeModel *model;
594
	gboolean active;
595
	char* name;
596
	
597
598
	// Get path of clicked codec active toggle box
	treePath = gtk_tree_path_new_from_string(path);
599
	model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
600
601
	gtk_tree_model_get_iter(model, &iter, treePath);

602
	// Get active value and name at iteration
603
	gtk_tree_model_get(model, &iter,
604
			COLUMN_CODEC_ACTIVE, &active,
605
			COLUMN_CODEC_NAME, &name,
606
			-1);
607
	
608
609
	printf("%s\n", name);

610
	// Toggle active value
611
612
613
	active = !active;
	
	// Store value
614
	gtk_list_store_set(GTK_LIST_STORE(model), &iter,
615
			COLUMN_CODEC_ACTIVE, active,
616
617
			-1);

618
	gtk_tree_path_free(treePath);
619
620
621
622
623
624

	// Modify codec queue to represent change	
	if(active)
		codec_set_active(name);
	else
		codec_set_inactive(name);
625
	
626
627
	// Perpetuate changes to the deamon
	codec_list_update_to_daemon();
628
629
}

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
static void
enable_account(GtkCellRendererToggle *rend , gchar* path,  gpointer data )
{
  GtkTreeIter iter;
  GtkTreePath *treePath;
  GtkTreeModel *model;
  gboolean enable;
  account_t* acc ;

  // Get path of clicked codec active toggle box
  treePath = gtk_tree_path_new_from_string(path);
  model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
  gtk_tree_model_get_iter(model, &iter, treePath);

  // Get pointer on object
  gtk_tree_model_get(model, &iter,
646
647
                      COLUMN_ACCOUNT_ACTIVE, &enable,
                      COLUMN_ACCOUNT_DATA, &acc,
648
649
650
651
652
                      -1);
  enable = !enable;

  // Store value
  gtk_list_store_set(GTK_LIST_STORE(model), &iter,
653
                     COLUMN_ACCOUNT_ACTIVE, enable,
654
655
656
657
658
                    -1);

  gtk_tree_path_free(treePath);

  // Modify account state       
659
  g_hash_table_replace( acc->properties , g_strdup(ACCOUNT_ENABLED) , g_strdup((enable == 1)? "TRUE":"FALSE"));
660
  dbus_send_register( acc->accountID , enable );
661
662
}

663
/**
664
 * Move codec in list depending on direction and selected codec and
665
 * update changes in the daemon list and the configuration files
666
667
 */
static void
668
codec_move(gboolean moveUp, gpointer data)
669
{
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
	GtkTreeIter iter;
	GtkTreeIter *iter2;
	GtkTreeView *treeView;
	GtkTreeModel *model;
	GtkTreeSelection *selection;
	GtkTreePath *treePath;
	gchar *path;
	
	// Get view, model and selection of codec store
	treeView = GTK_TREE_VIEW(data);
	model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
	
	// Find selected iteration and create a copy
	gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter);
	iter2 = gtk_tree_iter_copy(&iter);
	
	// Find path of iteration
	path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(model), &iter);
	treePath = gtk_tree_path_new_from_string(path);
690
691
692
	gint *indices = gtk_tree_path_get_indices(treePath);
	gint indice = indices[0];
	
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
	// Depending on button direction get new path
	if(moveUp)
		gtk_tree_path_prev(treePath);
	else
		gtk_tree_path_next(treePath);
	gtk_tree_model_get_iter(model, &iter, treePath);
	
	// Swap iterations if valid
	if(gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), &iter))
		gtk_list_store_swap(GTK_LIST_STORE(model), &iter, iter2);
	
	// Scroll to new position
	gtk_tree_view_scroll_to_cell(treeView, treePath, NULL, FALSE, 0, 0);
	
	// Free resources
	gtk_tree_path_free(treePath);
	gtk_tree_iter_free(iter2);
	g_free(path);
	
712
713
714
715
716
717
	// Perpetuate changes in codec queue
	if(moveUp)
		codec_list_move_codec_up(indice);
	else
		codec_list_move_codec_down(indice);
	
718
719
	// Perpetuate changes to the deamon
	codec_list_update_to_daemon();
720
721
}

722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
/**
 * Move account in list depending on direction and selected account
 */
static void
account_move(gboolean moveUp, gpointer data)
{
	GtkTreeIter iter;
	GtkTreeIter *iter2;
	GtkTreeView *treeView;
	GtkTreeModel *model;
	GtkTreeSelection *selection;
	GtkTreePath *treePath;
	gchar *path;
	
	// Get view, model and selection of codec store
	treeView = GTK_TREE_VIEW(data);
	model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
	
	// Find selected iteration and create a copy
	gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter);
	iter2 = gtk_tree_iter_copy(&iter);
	
	// Find path of iteration
	path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(model), &iter);
	treePath = gtk_tree_path_new_from_string(path);
	gint *indices = gtk_tree_path_get_indices(treePath);
	gint indice = indices[0];
	
	// Depending on button direction get new path
	if(moveUp)
		gtk_tree_path_prev(treePath);
	else
		gtk_tree_path_next(treePath);
	gtk_tree_model_get_iter(model, &iter, treePath);
	
	// Swap iterations if valid
	if(gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), &iter))
		gtk_list_store_swap(GTK_LIST_STORE(model), &iter, iter2);
	
	// Scroll to new position
	gtk_tree_view_scroll_to_cell(treeView, treePath, NULL, FALSE, 0, 0);
	
	// Free resources
	gtk_tree_path_free(treePath);
	gtk_tree_iter_free(iter2);
	g_free(path);
	
	// Perpetuate changes in account queue
	if(moveUp)
		account_list_move_up(indice);
	else
		account_list_move_down(indice);
}

777
778
779
/**
 * Called from move up codec button signal
 */
780
781
static void
codec_move_up(GtkButton *button, gpointer data)
782
{
783
784
  // Change tree view ordering and get indice changed
  codec_move(TRUE, data);
785
786
787
}

/**
788
 * Called from move down codec button signal
789
790
 */
static void
791
codec_move_down(GtkButton *button, gpointer data)
792
{
793
794
  // Change tree view ordering and get indice changed
  codec_move(FALSE, data);
795
796
797
}

/**
798
 * Called from move up account button signal
799
 */
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
static void
account_move_up(GtkButton *button, gpointer data)
{
  // Change tree view ordering and get indice changed
  account_move(TRUE, data);
}

/**
 * Called from move down account button signal
 */
static void
account_move_down(GtkButton *button, gpointer data)
{
  // Change tree view ordering and get indice changed
  account_move(FALSE, data);
815
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
816

817
818
819
GtkWidget*
create_codec_table()
{
820
821
822
	GtkWidget *ret;
	GtkWidget *scrolledWindow;
	GtkWidget *buttonBox;
823
	
824
825
826
827
	GtkListStore *codecStore;
	GtkCellRenderer *renderer;
	GtkTreeSelection *treeSelection;
	GtkTreeViewColumn *treeViewColumn;
828
829
830
831
832
833
834
835
836
	
	ret = gtk_hbox_new(FALSE, 10);
	gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
	
	scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_SHADOW_IN);
	
	gtk_box_pack_start(GTK_BOX(ret), scrolledWindow, TRUE, TRUE, 0);
837
	codecStore = gtk_list_store_new(CODEC_COLUMN_COUNT,
838
839
			G_TYPE_BOOLEAN,		// Active
			G_TYPE_STRING,		// Name
840
841
842
			G_TYPE_STRING,		// Frequency
			G_TYPE_STRING,		// Bit rate
			G_TYPE_STRING		// Bandwith
843
844
			);
	
845
846
	// Create codec tree view with list store
	codecTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(codecStore));
847
	
848
849
	// Get tree selection manager
	treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(codecTreeView));
850
851
	g_signal_connect(G_OBJECT(treeSelection), "changed",
			G_CALLBACK (select_codec),
852
			codecStore);
853
854
855
	
	// Active column
	renderer = gtk_cell_renderer_toggle_new();
856
	treeViewColumn = gtk_tree_view_column_new_with_attributes("", renderer, "active", COLUMN_CODEC_ACTIVE, NULL);
857
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
858
859
860

	// Toggle codec active property on clicked
	g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(codec_active_toggled), (gpointer)codecTreeView);
861
862
863
	
	// Name column
	renderer = gtk_cell_renderer_text_new();
864
	treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "markup", COLUMN_CODEC_NAME, NULL);
865
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
866
867
868
	
	// Bit rate column
	renderer = gtk_cell_renderer_text_new();
869
	treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Frequency"), renderer, "text", COLUMN_CODEC_FREQUENCY, NULL);
870
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
871
872
873
	
	// Bandwith column
	renderer = gtk_cell_renderer_text_new();
874
	treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Bitrate"), renderer, "text", COLUMN_CODEC_BITRATE, NULL);
875
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
876
877
878
	
	// Frequency column
	renderer = gtk_cell_renderer_text_new();
879
	treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Bandwidth"), renderer, "text", COLUMN_CODEC_BANDWIDTH, NULL);
880
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
881
882
	
	g_object_unref(G_OBJECT(codecStore));
883
	gtk_container_add(GTK_CONTAINER(scrolledWindow), codecTreeView);
884
885
886
887
888
889
	
	// Create button box
	buttonBox = gtk_vbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 10);
	gtk_box_pack_start(GTK_BOX(ret), buttonBox, FALSE, FALSE, 0);
	
890
891
892
893
	codecMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
	gtk_widget_set_sensitive(GTK_WIDGET(codecMoveUpButton), FALSE);
	gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveUpButton, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(codecMoveUpButton), "clicked", G_CALLBACK(codec_move_up), codecTreeView);
894
	
895
896
897
898
	codecMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
	gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), FALSE);
	gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveDownButton, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(codecMoveDownButton), "clicked", G_CALLBACK(codec_move_down), codecTreeView);
899
900
901
902
903
904
905
906
907
908
	
	config_window_fill_codec_list();

	return ret;
}

/**
 * Account settings tab
 */
GtkWidget *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
909
910
create_accounts_tab()
{
911
	GtkWidget *ret;
912
913
914
915
916
917
	GtkWidget *scrolledWindow;
	GtkWidget *treeView;
	GtkWidget *buttonBox;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *treeViewColumn;
	GtkTreeSelection *treeSelection;
918

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
919
920
921
	selectedAccount = NULL;

	ret = gtk_vbox_new(FALSE, 10); 
922
	gtk_container_set_border_width(GTK_CONTAINER (ret), 10);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
923

924
925
926
	scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_SHADOW_IN);
927
	gtk_box_pack_start(GTK_BOX(ret), scrolledWindow, TRUE, TRUE, 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
928

929
	accountStore = gtk_list_store_new(COLUMN_ACCOUNT_COUNT,
930
931
932
			G_TYPE_STRING,  // Name
			G_TYPE_STRING,  // Protocol
			G_TYPE_STRING,  // Status
933
			G_TYPE_BOOLEAN, // Enabled / Disabled
934
935
			G_TYPE_POINTER  // Pointer to the Object
			);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
936

937
938
939
	treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accountStore));
	treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW (treeView));
	g_signal_connect(G_OBJECT (treeSelection), "changed",
940
			G_CALLBACK (select_account),
941
			accountStore);
942

943
944
945
	renderer = gtk_cell_renderer_text_new();
	treeViewColumn = gtk_tree_view_column_new_with_attributes ("Alias",
			renderer,
946
			"markup", COLUMN_ACCOUNT_ALIAS,
947
			NULL);
948
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
949
	//gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, bold_if_default_account, NULL,NULL);
950
951
952
	
	// A double click on the account line opens the window to edit the account
	g_signal_connect( G_OBJECT( treeView ) , "row-activated" , G_CALLBACK( edit_account ) , NULL );
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
953

954
	renderer = gtk_cell_renderer_text_new();
955
	treeViewColumn = gtk_tree_view_column_new_with_attributes (_("Protocol"),
956
			renderer,
957
			"markup", COLUMN_ACCOUNT_TYPE,
958
			NULL);
959
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
960
	//gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, bold_if_default_account, NULL,NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
961

962
	renderer = gtk_cell_renderer_text_new();
963
	treeViewColumn = gtk_tree_view_column_new_with_attributes (_("Status"),
964
			renderer,
965
			"markup", COLUMN_ACCOUNT_STATUS,
966
			NULL);
967
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
968
	//gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, bold_if_default_account, NULL,NULL);
969
	
970
	renderer = gtk_cell_renderer_toggle_new();
971
	treeViewColumn = gtk_tree_view_column_new_with_attributes("", renderer, "active", COLUMN_ACCOUNT_ACTIVE , NULL);
972
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
973
	g_signal_connect( G_OBJECT(renderer) , "toggled" , G_CALLBACK(enable_account), (gpointer)treeView );
974

975
976
	g_object_unref(G_OBJECT(accountStore));
	gtk_container_add(GTK_CONTAINER(scrolledWindow), treeView);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
977

978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
	 // Create button box
        buttonBox = gtk_vbox_new(FALSE, 0);
        gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 10);
        gtk_box_pack_start(GTK_BOX(ret), buttonBox, FALSE, FALSE, 0);

        accountMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
        gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
        gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveUpButton, FALSE, FALSE, 0);
        g_signal_connect(G_OBJECT(accountMoveUpButton), "clicked", G_CALLBACK(account_move_up), treeView);

        accountMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
        gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
        gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveDownButton, FALSE, FALSE, 0);
        g_signal_connect(G_OBJECT(accountMoveDownButton), "clicked", G_CALLBACK(account_move_down), treeView);
	
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
993
	/* The buttons to press! */
994
995
	buttonBox = gtk_hbutton_box_new();
	gtk_box_set_spacing(GTK_BOX(buttonBox), 10); //GAIM_HIG_BOX_SPACE
996
	gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_CENTER);
997
998
	gtk_box_pack_start(GTK_BOX(ret), buttonBox, FALSE, FALSE, 0);
	gtk_widget_show (buttonBox); 
999

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1000
	addButton = gtk_button_new_from_stock (GTK_STOCK_ADD);