configwindow.c 24.2 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
30
#include <stdlib.h>

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

33
34
35
/**
 * Local variables
 */
36
gboolean dialogOpen = FALSE;
37

38
39
40
41
42
43
GtkListStore *accountStore;
GtkWidget *codecTreeView;		// View used instead of store to get access to selection
								// instead of keeping selected codec as a variable
GtkListStore *audioManagerStore;
GtkListStore *outputAudioDeviceManagerStore;
GtkListStore *inputAudioDeviceManagerStore;
44

45
46
47
48
49
GtkWidget *addButton;
GtkWidget *editButton;
GtkWidget *deleteButton;
GtkWidget *defaultButton;
GtkWidget *restoreButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
50

51
52
GtkWidget *moveUpButton;
GtkWidget *moveDownButton;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
53

54
account_t *selectedAccount;
55

56
57
58
59
60
61
62
63
64
65
// Codec properties ID
enum {
	COLUMN_CODEC_ACTIVE,
	COLUMN_CODEC_NAME,
	COLUMN_CODEC_FREQUENCY,
	COLUMN_CODEC_BITRATE,
	COLUMN_CODEC_BANDWIDTH,
	CODEC_COLUMN_COUNT
};

66
67
68
69
70
/**
 * Fills the treelist with accounts
 */
void
config_window_fill_account_list()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
71
{
72
73
74
75
	if(dialogOpen)
	{
		GtkTreeIter iter;

76
		gtk_list_store_clear(accountStore);
77
		int i;
78
		for(i = 0; i < account_list_get_size(); i++)
79
		{
80
			account_t * a = account_list_get_nth (i);
81
82
			if (a)
			{
83
84
				gtk_list_store_append (accountStore, &iter);
				gtk_list_store_set(accountStore, &iter,
85
86
87
88
89
90
						0, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS),  // Name
						1, g_hash_table_lookup(a->properties, ACCOUNT_TYPE),   // Protocol
						2, account_state_name(a->state),      // Status
						3, a,                                 // Pointer
						-1);
			}
91
		}
92
93
94
95
96

		gtk_widget_set_sensitive( GTK_WIDGET(editButton),   FALSE);
		gtk_widget_set_sensitive( GTK_WIDGET(deleteButton), FALSE);
		gtk_widget_set_sensitive( GTK_WIDGET(defaultButton), FALSE);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
97
}
98

99
100
101
/**
 * Fills the tree list with supported codecs
 */
102
void
103
104
config_window_fill_codec_list()
{
105
106
	if(dialogOpen)
	{
107
		GtkListStore *codecStore;
108
		GtkTreeIter iter;
109
110
111
		
		// Get model of view and clear it
		codecStore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView)));
112
113
		gtk_list_store_clear(codecStore);

114
115
		// Insert codecs
		int i;
116
117
		for(i = 0; i < codec_list_get_size(); i++)
		{
118
			codec_t *c = codec_list_get_nth(i);
119
120
121
122
123
			printf("%s\n", c->name);
			if(c)
			{
				gtk_list_store_append(codecStore, &iter);
				gtk_list_store_set(codecStore, &iter,
124
125
126
						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)
127
						COLUMN_CODEC_BITRATE,	g_strdup_printf("%.1f kbps", c->_bitrate),		// Bitrate (kbps)
128
						COLUMN_CODEC_BANDWIDTH,	g_strdup_printf("%.1f kbps", c->_bandwidth),	// Bandwidth (kpbs)
129
130
131
132
						-1);
			}
		}
	}
133
134
}

135
/**
136
 * TODO
137
 */
138
139
void
config_window_fill_audio_manager_list()
140
{
141
142
	
}
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

/**
 * TODO
 */
void
config_window_fill_output_audio_device_list()
{
	
}

/**
 * TODO
 */
void
config_window_fill_input_audio_device_list()
{
	
160
161
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
162
163
164
/**
 * Delete an account
 */
165
166
static void
delete_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
167
{
168
169
170
171
	if(selectedAccount)
	{
		dbus_remove_account(selectedAccount->accountID);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
172
173
174
}

/**
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
175
 * Edit an account
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
176
 */
177
178
static void
edit_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
179
{
180
181
182
183
	if(selectedAccount)
	{
		show_account_window(selectedAccount);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
184
185
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
186
187
188
/**
 * Add an account
 */
189
190
static void
add_account(GtkWidget *widget, gpointer data)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
191
{
192
193
194
195
196
197
	show_account_window(NULL);
}

/*
 * Should mark the account as default
 */
198
void
199
200
default_account(GtkWidget *widget, gpointer data)
{
201
	// set account as default
202
203
	if(selectedAccount)
	{
204
		account_list_set_default(selectedAccount->accountID);
205
		dbus_set_default_account(selectedAccount->accountID);
206
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
207
208
}

209
210
211
212
213
/**
 * 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
214
{
215
	GtkTreeIter iter;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
216
	GValue val;
217

218
	if (!gtk_tree_selection_get_selected(selection, &model, &iter))
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
219
	{
220
		selectedAccount = NULL;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
221
		return;
222
223
	}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
224
	val.g_type = G_TYPE_POINTER;
225
	gtk_tree_model_get_value(model, &iter, 3, &val);
226

227
	selectedAccount = (account_t*)g_value_get_pointer(&val);
228
229
	g_value_unset(&val);

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
230
231
	if(selectedAccount)
	{
232
233
234
		gtk_widget_set_sensitive(GTK_WIDGET(editButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(defaultButton), TRUE);
235
236
	}
	g_print("select");
237
}
238

239
240
241
/**
 * Toggle move buttons on if a codec is selected, off elsewise
 */
242
static void
243
select_codec(GtkTreeSelection *selection, GtkTreeModel *model)
244
245
{
	GtkTreeIter iter;
246
247
248
249
250
251
252
253
254
255
256
	
	if(!gtk_tree_selection_get_selected(selection, &model, &iter))
	{
		gtk_widget_set_sensitive(GTK_WIDGET(moveUpButton), FALSE);
		gtk_widget_set_sensitive(GTK_WIDGET(moveDownButton), FALSE);
	}
	else
	{
		gtk_widget_set_sensitive(GTK_WIDGET(moveUpButton), TRUE);
		gtk_widget_set_sensitive(GTK_WIDGET(moveDownButton), TRUE);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
257
258
}

259
/**
260
261
 * Toggle active value of codec on click and update changes to the deamon
 * and in configuration files
262
 */
263
static void
264
codec_active_toggled(GtkCellRendererToggle *renderer, gchar *path, gpointer data)
265
{
266
	GtkTreeIter iter;
267
268
	GtkTreePath *treePath;
	GtkTreeModel *model;
269
270
	gboolean active;
	
271
272
	// Get path of clicked codec active toggle box
	treePath = gtk_tree_path_new_from_string(path);
273
	model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
274
275
276
277
	gtk_tree_model_get_iter(model, &iter, treePath);

	// Get value at iteration
	gtk_tree_model_get(model, &iter,
278
			COLUMN_CODEC_ACTIVE, &active,
279
			-1);
280
	
281
	// Toggle active value
282
	gtk_list_store_set(GTK_LIST_STORE(model), &iter,
283
			COLUMN_CODEC_ACTIVE, !active,
284
285
			-1);

286
287
288
	gtk_tree_path_free(treePath);
	
	// TODO Perpetuate changes to the deamon
289
290
}

291
/**
292
293
 * Move codec in list depending on direction and selected codec and
 * update changes in the deamon list and the configuration files
294
295
 */
static void
296
moveCodec(gboolean moveUp, gpointer data)
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
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	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);

	// 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);
	
	// TODO Perpetuate changes to the deamon
	/* Update the gconf key
	codecs_data = gm_codecs_list_to_gm_conf_list (GTK_WIDGET (data));

	gm_conf_set_string_list (AUDIO_CODECS_KEY "list", codecs_data);

	g_slist_foreach (codecs_data, (GFunc) g_free, NULL);
	g_slist_free (codecs_data);
	*/
347
348
349
350
351
}

/**
 * Called from move up codec button signal
 */
352
353
void
moveCodecUp(GtkButton *button, gpointer data)
354
{
355
	moveCodec(TRUE, data);
356
357
358
}

/**
359
 * Called from move down codec button signal
360
361
 */
static void
362
moveCodecDown(GtkButton *button, gpointer data)
363
{
364
	moveCodec(FALSE, data);
365
366
367
368
369
}

/**
 * Select default account that is rendered in bold
 */
370
void
371
372
373
bold_if_default_account(GtkTreeViewColumn *col,
			GtkCellRenderer *rend,
			GtkTreeModel *tree_model,
374
375
376
			GtkTreeIter *iter,
			gpointer data)
{
377
	GValue val = { 0, };
378
	gtk_tree_model_get_value(tree_model, iter, 3, &val);
379
	account_t *current = (account_t*)g_value_get_pointer(&val);
380
	g_value_unset(&val);
381
382
	if(g_strcasecmp(current->accountID, account_list_get_default()) == 0)
		g_object_set(G_OBJECT(rend), "weight", 800, NULL);
383
384
385
	else
		g_object_set(G_OBJECT(rend), "weight", 400, NULL);
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
386

387
/**
388
 * TODO Action when restore default codecs is done
389
 */
390
391
392
void
default_codecs(GtkWidget* widget, gpointer data)
{
393
	GtkListStore *codecStore;
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
	int i = 0;
	int j = 0;
	gint * new_order;
	gchar ** default_list = (gchar**)dbus_default_codec_list();
	
	while(default_list[i] != NULL)
	{
		printf("%s\n", default_list[i]);
		i++;
	}
	i = 0;
	while(default_list[i] != NULL)
	{
		if(g_strcasecmp(codec_list_get_nth(0)->name, default_list[i]) == 0)
		{
			printf("%s %s\n",codec_list_get_nth(0)->name, default_list[i]);
			new_order[i] = 0;
		}
		else if(g_strcasecmp(codec_list_get_nth(1)->name, default_list[i]) == 0)
		{
			printf("%s %s\n",codec_list_get_nth(0)->name, default_list[0]);
			new_order[i] = 1;
		}	
		else
		{
			printf("%s %s\n",codec_list_get_nth(0)->name, default_list[0]);
			new_order[i] = 2;
		}
		printf("new_order[%i]=%i\n", i,j);
		i++;
424
425
426
	}
	codecStore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView)));
	gtk_list_store_reorder(codecStore, new_order);
427
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
428

429
430
431
432
433
434
/**
 * Create table widget for codecs
 */
GtkWidget*
create_codec_table()
{
435
436
437
	GtkWidget *ret;
	GtkWidget *scrolledWindow;
	GtkWidget *buttonBox;
438
	
439
440
441
442
	GtkListStore *codecStore;
	GtkCellRenderer *renderer;
	GtkTreeSelection *treeSelection;
	GtkTreeViewColumn *treeViewColumn;
443
444
445
446
447
448
449
450
451
	
	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);
452
	codecStore = gtk_list_store_new(CODEC_COLUMN_COUNT,
453
454
			G_TYPE_BOOLEAN,		// Active
			G_TYPE_STRING,		// Name
455
456
457
			G_TYPE_STRING,		// Frequency
			G_TYPE_STRING,		// Bit rate
			G_TYPE_STRING		// Bandwith
458
459
			);
	
460
461
	// Create codec tree view with list store
	codecTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(codecStore));
462
	
463
464
	// Get tree selection manager
	treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(codecTreeView));
465
466
	g_signal_connect(G_OBJECT(treeSelection), "changed",
			G_CALLBACK (select_codec),
467
			codecStore);
468
469
470
	
	// Active column
	renderer = gtk_cell_renderer_toggle_new();
471
	treeViewColumn = gtk_tree_view_column_new_with_attributes("", renderer, "active", COLUMN_CODEC_ACTIVE, NULL);
472
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
473
474
475

	// Toggle codec active property on clicked
	g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(codec_active_toggled), (gpointer)codecTreeView);
476
477
478
	
	// Name column
	renderer = gtk_cell_renderer_text_new();
479
	treeViewColumn = gtk_tree_view_column_new_with_attributes("Name", renderer, "markup", COLUMN_CODEC_NAME, NULL);
480
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
481
482
483
	
	// Bit rate column
	renderer = gtk_cell_renderer_text_new();
484
	treeViewColumn = gtk_tree_view_column_new_with_attributes("Frequency", renderer, "text", COLUMN_CODEC_FREQUENCY, NULL);
485
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
486
487
488
	
	// Bandwith column
	renderer = gtk_cell_renderer_text_new();
489
	treeViewColumn = gtk_tree_view_column_new_with_attributes("Bitrate", renderer, "text", COLUMN_CODEC_BITRATE, NULL);
490
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
491
492
493
	
	// Frequency column
	renderer = gtk_cell_renderer_text_new();
494
	treeViewColumn = gtk_tree_view_column_new_with_attributes("Bandwidth", renderer, "text", COLUMN_CODEC_BANDWIDTH, NULL);
495
	gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
496
497
	
	g_object_unref(G_OBJECT(codecStore));
498
	gtk_container_add(GTK_CONTAINER(scrolledWindow), codecTreeView);
499
500
501
502
503
504
	
	// 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);
	
505
506
	moveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
	gtk_widget_set_sensitive(GTK_WIDGET(moveUpButton), FALSE);
507
	gtk_box_pack_start(GTK_BOX(buttonBox), moveUpButton, FALSE, FALSE, 0);
508
	g_signal_connect(G_OBJECT(moveUpButton), "clicked", G_CALLBACK(moveCodecUp), codecTreeView);
509
	
510
511
	moveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
	gtk_widget_set_sensitive(GTK_WIDGET(moveDownButton), FALSE);
512
	gtk_box_pack_start(GTK_BOX(buttonBox), moveDownButton, FALSE, FALSE, 0);
513
	g_signal_connect(G_OBJECT(moveDownButton), "clicked", G_CALLBACK(moveCodecDown), codecTreeView);
514
515
516
517
518
519
520
521
522
523
	
	config_window_fill_codec_list();

	return ret;
}

/**
 * Account settings tab
 */
GtkWidget *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
524
525
create_accounts_tab()
{
526
	GtkWidget *ret;
527
528
529
530
531
532
	GtkWidget *scrolledWindow;
	GtkWidget *treeView;
	GtkWidget *buttonBox;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *treeViewColumn;
	GtkTreeSelection *treeSelection;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
533
	GtkWidget *label;
534

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
535
536
537
	selectedAccount = NULL;

	ret = gtk_vbox_new(FALSE, 10); 
538
	gtk_container_set_border_width(GTK_CONTAINER (ret), 10);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
539
540
541
542

	label = gtk_label_new("This is the list of accounts previously setup.");

	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
543
	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
544
545
	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);

546
	gtk_box_pack_start(GTK_BOX(ret), label, FALSE, FALSE, 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
547
548
	gtk_widget_show(label);

549
550
551
552
	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);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
553

554
	accountStore = gtk_list_store_new(4,
555
556
557
558
559
			G_TYPE_STRING,  // Name
			G_TYPE_STRING,  // Protocol
			G_TYPE_STRING,  // Status
			G_TYPE_POINTER  // Pointer to the Object
			);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
560

561
	treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accountStore));
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
562

563
564
	treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW (treeView));
	g_signal_connect(G_OBJECT (treeSelection), "changed",
565
			G_CALLBACK (select_account),
566
			accountStore);
567

568
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(accountStore),
569
570
			2, GTK_SORT_ASCENDING);

571
572
573
	renderer = gtk_cell_renderer_text_new();
	treeViewColumn = gtk_tree_view_column_new_with_attributes ("Alias",
			renderer,
574
575
			"markup", 0,
			NULL);
576
577
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
	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
578

579
580
581
	renderer = gtk_cell_renderer_text_new();
	treeViewColumn = gtk_tree_view_column_new_with_attributes ("Protocol",
			renderer,
582
583
			"markup", 1,
			NULL);
584
585
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
	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
586

587
588
589
	renderer = gtk_cell_renderer_text_new();
	treeViewColumn = gtk_tree_view_column_new_with_attributes ("Status",
			renderer,
590
591
			"markup", 2,
			NULL);
592
593
594
595
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeView), treeViewColumn);
	gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, bold_if_default_account, NULL,NULL);
	g_object_unref(G_OBJECT(accountStore));
	gtk_container_add(GTK_CONTAINER(scrolledWindow), treeView);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
596
597

	/* The buttons to press! */
598
599
600
601
602
	buttonBox = gtk_hbutton_box_new();
	gtk_box_set_spacing(GTK_BOX(buttonBox), 10); //GAIM_HIG_BOX_SPACE
	gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_START);
	gtk_box_pack_start(GTK_BOX(ret), buttonBox, FALSE, FALSE, 0);
	gtk_widget_show (buttonBox); 
603

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
604
	addButton = gtk_button_new_from_stock (GTK_STOCK_ADD);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
605
	g_signal_connect_swapped(G_OBJECT(addButton), "clicked",
606
			G_CALLBACK(add_account), NULL);
607
	gtk_box_pack_start(GTK_BOX(buttonBox), addButton, FALSE, FALSE, 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
608
	gtk_widget_show(addButton);
609

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
610
611
	editButton = gtk_button_new_from_stock (GTK_STOCK_EDIT);
	g_signal_connect_swapped(G_OBJECT(editButton), "clicked",
612
			G_CALLBACK(edit_account), NULL);
613
	gtk_box_pack_start(GTK_BOX(buttonBox), editButton, FALSE, FALSE, 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
614
615
616
617
	gtk_widget_show(editButton);
	
	deleteButton = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
	g_signal_connect_swapped(G_OBJECT(deleteButton), "clicked",
618
			G_CALLBACK(delete_account), NULL);
619
	gtk_box_pack_start(GTK_BOX(buttonBox), deleteButton, FALSE, FALSE, 0);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
620
621
	gtk_widget_show(deleteButton);
	
622
623
624
	defaultButton = gtk_button_new_with_mnemonic("Set as Default");
	g_signal_connect_swapped(G_OBJECT(defaultButton), "clicked", 
			G_CALLBACK(default_account), NULL);
625
	gtk_box_pack_start(GTK_BOX(buttonBox), defaultButton, FALSE, FALSE, 0);
626
627
	gtk_widget_show(defaultButton);

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
628
	gtk_widget_show_all(ret);
629

630
	config_window_fill_account_list();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
631
632
633
634

	return ret;
}

635
636
637
/**
 * Audio settings tab
 */
638
639
GtkWidget*
create_audio_tab ()
640
{
641
642
643
644
645
646
647
648
649
650
651
652
	GtkWidget *ret;
	
	GtkWidget *deviceLabel;
	GtkWidget *deviceBox;
	GtkWidget *deviceTable;
	GtkWidget *codecLabel;
	GtkWidget *codecBox;
	
	GtkWidget *titleLabel;
	GtkWidget *comboBox;
	GtkWidget *refreshButton;
	GtkCellRenderer *renderer;
653
654
	GtkTreeIter iter;
	
655
656
	GtkWidget *codecTable;
	
657
658
659
660
661
	// Main widget
	ret = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
    
    // Device section label
662
663
    deviceLabel = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(deviceLabel), "<b>Devices</b>");
664
665
666
667
668
669
670
671
672
673
674
675
	gtk_label_set_line_wrap(GTK_LABEL(deviceLabel), TRUE);
	gtk_misc_set_alignment(GTK_MISC(deviceLabel), 0, 0.5);
	gtk_label_set_justify(GTK_LABEL(deviceLabel), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start(GTK_BOX(ret), deviceLabel, FALSE, FALSE, 0);
	
    // Main device widget
	deviceBox = gtk_hbox_new(FALSE, 10);
	gtk_box_pack_start(GTK_BOX(ret), deviceBox, FALSE, FALSE, 0);
    
    // Main device widget
	deviceTable = gtk_table_new(4, 3, FALSE);
	gtk_table_set_col_spacing(GTK_TABLE(deviceTable), 0, 40);
676
	gtk_box_set_spacing(GTK_BOX(deviceTable), 0);
677
678
679
680
681
	gtk_box_pack_start(GTK_BOX(deviceBox), deviceTable, TRUE, TRUE, 0);
	gtk_widget_show(deviceTable);
	
	// Device : Audio manager
	// Create title label
682
	titleLabel = gtk_label_new("Audio manager");
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
    gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5);
	gtk_table_attach(GTK_TABLE(deviceTable), titleLabel, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
	gtk_widget_show(titleLabel);	
	// Set choices of audio managers
	audioManagerStore = gtk_list_store_new(1, G_TYPE_STRING);
	gtk_list_store_append(audioManagerStore, &iter);
	gtk_list_store_set(audioManagerStore, &iter, 0 , "ALSA", -1);
	comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(audioManagerStore));
	gtk_combo_box_set_active(GTK_COMBO_BOX(comboBox), 0);
	gtk_label_set_mnemonic_widget(GTK_LABEL(titleLabel), comboBox);
  	// Set rendering
	renderer = gtk_cell_renderer_text_new();
	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboBox), renderer, TRUE);
	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(comboBox), renderer, "text", 0, NULL);
	gtk_table_attach(GTK_TABLE(deviceTable), comboBox, 2, 3, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
	gtk_widget_show(comboBox);
	
	// Device : Output device
	// Create title label
	titleLabel = gtk_label_new("Output peripheral:");
    gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5);
    gtk_table_attach(GTK_TABLE(deviceTable), titleLabel, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
    gtk_widget_show(titleLabel);
	// Set choices of output devices
	outputAudioDeviceManagerStore = gtk_list_store_new(1, G_TYPE_STRING);
	gtk_list_store_append(outputAudioDeviceManagerStore, &iter);
	gtk_list_store_set(outputAudioDeviceManagerStore, &iter, 0 , "Default", -1);
	comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(outputAudioDeviceManagerStore));
	gtk_combo_box_set_active(GTK_COMBO_BOX(comboBox), 0);
  	gtk_label_set_mnemonic_widget(GTK_LABEL(titleLabel), comboBox);
  	// Set rendering
	renderer = gtk_cell_renderer_text_new();
	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboBox), renderer, TRUE);
	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(comboBox), renderer, "text", 0, NULL);
	gtk_table_attach(GTK_TABLE(deviceTable), comboBox, 2, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
	gtk_widget_show(comboBox);
	
	// Device : Input device
	// Create title label
	titleLabel = gtk_label_new("Input peripheral:");
    gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5);
    gtk_table_attach(GTK_TABLE(deviceTable), titleLabel, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
	gtk_widget_show(titleLabel);
	// Set choices of output devices
	inputAudioDeviceManagerStore = gtk_list_store_new(1, G_TYPE_STRING);
	gtk_list_store_append(inputAudioDeviceManagerStore, &iter);
	gtk_list_store_set(inputAudioDeviceManagerStore, &iter, 0 , "Default", -1);
	comboBox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(inputAudioDeviceManagerStore));
	gtk_combo_box_set_active(GTK_COMBO_BOX(comboBox), 0);
  	gtk_label_set_mnemonic_widget(GTK_LABEL(titleLabel), comboBox);
  	// Set rendering
	renderer = gtk_cell_renderer_text_new();
	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboBox), renderer, TRUE);
	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(comboBox), renderer, "text", 0, NULL);
    gtk_table_attach(GTK_TABLE(deviceTable), comboBox, 2, 3, 2, 3, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
	gtk_widget_show(comboBox);
739
740
741
	
	// Create detect button
	refreshButton = gtk_button_new_with_label("Detect all");
742
	gtk_button_set_image(GTK_BUTTON(refreshButton), gtk_image_new_from_stock(GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON));
743
744
	gtk_table_attach(GTK_TABLE(deviceTable), refreshButton, 3, 4, 0, 3, GTK_EXPAND, GTK_EXPAND, 0, 0);
	
745
    // Codec section label
746
747
    codecLabel = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(codecLabel), "<b>Codecs</b>");
748
749
750
751
752
753
754
755
756
757
758
759
760
    gtk_label_set_line_wrap(GTK_LABEL(codecLabel), TRUE);
    gtk_misc_set_alignment(GTK_MISC(codecLabel), 0, 0.5);
    gtk_label_set_justify(GTK_LABEL(codecLabel), GTK_JUSTIFY_LEFT);
    gtk_box_pack_start(GTK_BOX(ret), codecLabel, FALSE, FALSE, 0);
    gtk_widget_show(codecLabel);

    // Main codec widget
	codecBox = gtk_hbox_new(FALSE, 10);
	gtk_box_pack_start(GTK_BOX(ret), codecBox, FALSE, FALSE, 0);
	gtk_widget_show(codecBox);
	
	// Codec : List
	codecTable = create_codec_table();
761
	gtk_widget_set_size_request(GTK_WIDGET(codecTable), -1, 150);
762
763
764
765
766
767
768
769
770
771
772
773
774
	gtk_box_pack_start(GTK_BOX(codecBox), codecTable, TRUE, TRUE, 0);
	gtk_widget_show(codecTable);

	// Show all
	gtk_widget_show_all(ret);

	return ret;
}

/**
 * Show configuration window with tabs
 */
void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
775
776
show_config_window ()
{
777
778
779
780
781
782
783
784
785
786
787
788
789
	GtkDialog * dialog;
	GtkWidget * notebook;
	GtkWidget * tab;

	dialogOpen = TRUE;

	dialog = GTK_DIALOG(gtk_dialog_new_with_buttons ("Preferences",
				GTK_WINDOW(get_main_window()),
				GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_STOCK_CLOSE,
				GTK_RESPONSE_ACCEPT,
				NULL));

790
	// Set window properties
791
	gtk_dialog_set_has_separator(dialog, FALSE);
792
793
	gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 400);
	gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
794

795
	// Create tabs container
796
797
798
	notebook = gtk_notebook_new();
	gtk_box_pack_start(GTK_BOX (dialog->vbox), notebook, TRUE, TRUE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(notebook), 10);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
799
	gtk_widget_show(notebook);
800

801
	// Accounts tab
802
803
	tab = create_accounts_tab();
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new("Accounts"));
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
804
	gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
805
	
806
807
808
	// Audio tab
	tab = create_audio_tab();	
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new("Audio Settings"));
809
	gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
810

811
	gtk_dialog_run(dialog);
812
813

	dialogOpen = FALSE;
814

815
	gtk_widget_destroy(GTK_WIDGET(dialog));
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
816
}