29
29
* as that of the covered work.
33
32
#include "accountlistconfigdialog.h"
33
#include "str_utils.h"
34
34
#include "dbus/dbus.h"
35
35
#include "accountconfigdialog.h"
36
#include "accountlist.h"
36
37
#include "actions.h"
37
38
#include "mainwindow.h"
39
40
#include "unused.h"
40
41
#include "logger.h"
42
#include "gtk2_wrappers.h"
43
#include <glib/gi18n.h>
41
44
#include <string.h>
43
46
static const int CONTEXT_ID_REGISTRATION = 0;
45
static GtkWidget *addButton;
46
static GtkWidget *editButton;
47
static GtkWidget *deleteButton;
48
static GtkWidget *accountMoveDownButton;
49
static GtkWidget *accountMoveUpButton;
50
static GtkWidget * status_bar;
51
static GtkListStore * accountStore;
53
static GtkDialog * accountListDialog = NULL;
55
static account_t * selectedAccount = NULL;
48
static GtkWidget *edit_button;
49
static GtkWidget *delete_button;
50
static GtkWidget *move_down_button;
51
static GtkWidget *move_up_button;
52
static GtkWidget *account_list_status_bar;
53
static GtkListStore *account_store;
54
static GtkDialog *account_list_dialog;
56
56
// Account properties
58
58
COLUMN_ACCOUNT_ALIAS,
59
59
COLUMN_ACCOUNT_TYPE,
60
60
COLUMN_ACCOUNT_STATUS,
61
61
COLUMN_ACCOUNT_ACTIVE,
63
63
COLUMN_ACCOUNT_COUNT
69
static void delete_account_cb(void)
71
if (selectedAccount == NULL) {
72
ERROR("Config: Error: No selected account in delete action");
76
dbus_remove_account(selectedAccount->accountID);
83
static void edit_account_cb(void)
85
if (selectedAccount == NULL) {
86
ERROR("Config: Error: No selected account in edit action");
90
show_account_window(selectedAccount);
66
/* Get selected account ID from treeview
67
* @return copied selected_accountID, must be freed by caller */
69
get_selected_accountID(GtkTreeView *tree_view)
71
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
72
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
74
// Find selected iteration and create a copy
76
gtk_tree_selection_get_selected(selection, &model, &iter);
77
// The Gvalue will be initialized in the following function
79
memset(&val, 0, sizeof(val));
80
gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val);
82
gchar *selected_accountID = g_strdup(g_value_get_string(&val));
84
return selected_accountID;
88
find_account_in_account_store(const gchar *accountID, GtkTreeModel *model,
91
gboolean valid = gtk_tree_model_get_iter_first(model, iter);
92
gboolean found = FALSE;
93
while (valid && !found) {
95
gtk_tree_model_get(model, iter, COLUMN_ACCOUNT_ID, &id, -1);
96
if (g_strcmp0(id, accountID) == 0)
99
valid = gtk_tree_model_iter_next(model, iter);
106
static void delete_account_cb(GtkButton *button UNUSED, gpointer data)
108
gchar *selected_accountID = get_selected_accountID(data);
109
RETURN_IF_NULL(selected_accountID, "No selected account in delete action");
110
GtkTreeModel *model = GTK_TREE_MODEL(account_store);
112
if (find_account_in_account_store(selected_accountID, model, &iter))
113
gtk_list_store_remove(account_store, &iter);
115
dbus_remove_account(selected_accountID);
116
g_free(selected_accountID);
120
run_account_dialog(const gchar *selected_accountID)
122
account_t *account = account_list_get_by_id(selected_accountID);
123
GtkWidget *dialog = show_account_window(account);
124
update_account_from_dialog(dialog, account);
127
static void row_activated_cb(GtkTreeView *view,
128
GtkTreePath *path UNUSED,
129
GtkTreeViewColumn *col UNUSED,
130
gpointer user_data UNUSED)
132
gchar *selected_accountID = get_selected_accountID(view);
133
RETURN_IF_NULL(selected_accountID, "No selected account ID");
134
run_account_dialog(selected_accountID);
135
g_free(selected_accountID);
138
static void edit_account_cb(GtkButton *button UNUSED, gpointer data)
140
gchar *selected_accountID = get_selected_accountID(data);
141
RETURN_IF_NULL(selected_accountID, "No selected account ID");
142
run_account_dialog(selected_accountID);
143
g_free(selected_accountID);
146
static void account_store_add(GtkTreeIter *iter, account_t *account)
148
const gchar *enabled = account_lookup(account, ACCOUNT_ENABLED);
149
const gchar *type = account_lookup(account, ACCOUNT_TYPE);
150
DEBUG("Account is enabled :%s", enabled);
151
const gchar *state_name = account_state_name(account->state);
153
gtk_list_store_set(account_store, iter,
154
COLUMN_ACCOUNT_ALIAS, account_lookup(account, ACCOUNT_ALIAS),
155
COLUMN_ACCOUNT_TYPE, type,
156
COLUMN_ACCOUNT_STATUS, state_name,
157
COLUMN_ACCOUNT_ACTIVE, utf8_case_equal(enabled, "true"),
158
COLUMN_ACCOUNT_ID, account->accountID, -1);
162
* Fills the treelist with accounts, should be called whenever the account
165
static void account_store_fill()
167
RETURN_IF_NULL(account_list_dialog, "No account dialog");
168
gtk_list_store_clear(account_store);
170
// IP2IP account must be first
171
account_t *ip2ip = account_list_get_by_id(IP2IP_PROFILE);
172
ip2ip->state = ACCOUNT_STATE_IP2IP_READY;
173
RETURN_IF_NULL(ip2ip, "Could not find IP2IP account");
176
gtk_list_store_append(account_store, &iter);
178
account_store_add(&iter, ip2ip);
180
for (size_t i = 0; i < account_list_get_size(); ++i) {
181
account_t *a = account_list_get_nth(i);
182
RETURN_IF_NULL(a, "Account %d is NULL", i);
184
// we don't want to process the IP2IP twice
186
gtk_list_store_append(account_store, &iter);
187
account_store_add(&iter, a);
96
192
static void add_account_cb(void)
98
show_account_window(NULL);
102
* Fills the treelist with accounts
104
void account_list_config_dialog_fill()
106
if (accountListDialog == NULL) {
107
DEBUG("Config: No account dialog, returning");
113
gtk_list_store_clear(accountStore);
115
// IP2IP account must be first
116
account_t *a = account_list_get_by_id("IP2IP");
119
ERROR("Config: Error: Could not find IP2IP account");
123
gtk_list_store_append(accountStore, &iter);
125
DEBUG("Config: Filling accounts: Account is enabled :%s", g_hash_table_lookup(a->properties, ACCOUNT_ENABLED));
127
gtk_list_store_set(accountStore, &iter,
128
COLUMN_ACCOUNT_ALIAS, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS), // Name
129
COLUMN_ACCOUNT_TYPE, g_hash_table_lookup(a->properties, ACCOUNT_TYPE), // Protocol
130
COLUMN_ACCOUNT_STATUS, account_state_name(a->state), // Status
131
COLUMN_ACCOUNT_ACTIVE, (g_strcasecmp(g_hash_table_lookup(a->properties, ACCOUNT_ENABLED),"true") == 0) ? TRUE:FALSE, // Enable/Disable
132
COLUMN_ACCOUNT_DATA, a, // Pointer
135
for (size_t i = 0; i < account_list_get_size(); i++) {
136
a = account_list_get_nth(i);
139
ERROR("Config: Error: Account %d is NULL while parsing the list", i);
143
// we dont wnat to process account twice
144
if (g_strcmp0(a->accountID, "IP2IP") != 0) {
145
gtk_list_store_append(accountStore, &iter);
147
DEBUG("Config: Filling accounts: Account is enabled :%s", g_hash_table_lookup(a->properties, ACCOUNT_ENABLED));
149
gtk_list_store_set(accountStore, &iter,
150
COLUMN_ACCOUNT_ALIAS, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS), // Name
151
COLUMN_ACCOUNT_TYPE, g_hash_table_lookup(a->properties, ACCOUNT_TYPE), // Protocol
152
COLUMN_ACCOUNT_STATUS, account_state_name(a->state), // Status
153
COLUMN_ACCOUNT_ACTIVE, (g_strcasecmp(g_hash_table_lookup(a->properties, ACCOUNT_ENABLED),"true") == 0) ? TRUE:FALSE, // Enable/Disable
154
COLUMN_ACCOUNT_DATA, a, // Pointer
194
account_t *new_account = create_default_account();
195
account_list_add(new_account);
196
run_account_dialog(new_account->accountID);
197
account_store_fill();
164
204
select_account_cb(GtkTreeSelection *selection, GtkTreeModel *model)
166
206
GtkTreeIter iter;
170
memset(&val, 0, sizeof(val));
172
207
if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
173
selectedAccount = NULL;
174
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
175
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
176
gtk_widget_set_sensitive(GTK_WIDGET(editButton), FALSE);
177
gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
208
gtk_widget_set_sensitive(move_up_button, FALSE);
209
gtk_widget_set_sensitive(move_down_button, FALSE);
210
gtk_widget_set_sensitive(edit_button, FALSE);
211
gtk_widget_set_sensitive(delete_button, FALSE);
181
215
// The Gvalue will be initialized in the following function
182
gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_DATA, &val);
217
memset(&val, 0, sizeof(val));
218
gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val);
184
selectedAccount = (account_t*) g_value_get_pointer(&val);
220
gchar *selected_accountID = g_value_dup_string(&val);
185
221
g_value_unset(&val);
187
if (selectedAccount != NULL) {
188
gtk_widget_set_sensitive(GTK_WIDGET(editButton), TRUE);
190
if (g_strcasecmp(selectedAccount->accountID, IP2IP) != 0) {
191
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), TRUE);
192
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), TRUE);
193
gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), TRUE);
195
/* Update status bar about current registration state */
196
gtk_statusbar_pop(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION);
198
if (selectedAccount->protocol_state_description != NULL
199
&& selectedAccount->protocol_state_code != 0) {
201
gchar * response = g_strdup_printf(
202
_("Server returned \"%s\" (%d)"),
203
selectedAccount->protocol_state_description,
204
selectedAccount->protocol_state_code);
205
gchar * message = g_strconcat(
206
account_state_name(selectedAccount->state),
211
gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, message);
217
state = (gchar*) account_state_name(selectedAccount->state);
218
gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, state);
221
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
222
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
223
gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
223
DEBUG("Selected account has accountID %s", selected_accountID);
224
account_t *selected_account = account_list_get_by_id(selected_accountID);
225
RETURN_IF_NULL(selected_account, "Selected account is NULL");
227
gtk_widget_set_sensitive(edit_button, TRUE);
229
if (!account_is_IP2IP(selected_account)) {
230
gtk_widget_set_sensitive(move_up_button, TRUE);
231
gtk_widget_set_sensitive(move_down_button, TRUE);
232
gtk_widget_set_sensitive(delete_button, TRUE);
234
/* Update status bar about current registration state */
235
update_account_list_status_bar(selected_account);
237
gtk_widget_set_sensitive(move_up_button, FALSE);
238
gtk_widget_set_sensitive(move_down_button, FALSE);
239
gtk_widget_set_sensitive(delete_button, FALSE);
227
DEBUG("Selecting account in account window");
241
g_free(selected_accountID);
230
static void enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path, gpointer data)
245
enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path,
234
GtkTreePath *treePath;
239
248
// The IP2IP profile can't be disabled
240
if (g_strcasecmp(path, "0") == 0)
249
if (g_strcmp0(path, "0") == 0)
243
252
// Get pointer on object
244
treePath = gtk_tree_path_new_from_string(path);
245
model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
246
gtk_tree_model_get_iter(model, &iter, treePath);
247
gtk_tree_model_get(model, &iter,
248
COLUMN_ACCOUNT_ACTIVE, &enable,
249
COLUMN_ACCOUNT_DATA, &acc,
253
GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
254
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
256
gtk_tree_model_get_iter(model, &iter, tree_path);
259
gtk_tree_model_get(model, &iter, COLUMN_ACCOUNT_ACTIVE, &enable,
260
COLUMN_ACCOUNT_ID, &id, -1);
262
account_t *account = account_list_get_by_id(id);
252
264
enable = !enable;
254
DEBUG("Account is %d enabled", enable);
256
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
257
COLUMN_ACCOUNT_ACTIVE, enable,
267
gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_ACCOUNT_ACTIVE,
260
270
// Modify account state
261
gchar * registrationState;
264
registrationState = g_strdup("true");
266
registrationState = g_strdup("false");
268
DEBUG("Replacing with %s", registrationState);
269
g_hash_table_replace(acc->properties , g_strdup(ACCOUNT_ENABLED), registrationState);
271
dbus_send_register(acc->accountID, enable);
271
const gchar * enabled_str = enable ? "true" : "false";
272
DEBUG("Account is enabled: %s", enabled_str);
274
account_replace(account, ACCOUNT_ENABLED, enabled_str);
275
dbus_send_register(account->accountID, enable);
275
279
* Move account in list depending on direction and selected account
277
static void account_move(gboolean moveUp, gpointer data)
282
account_move(gboolean move_up, gpointer data)
284
// Get view, model and selection of account
285
GtkTreeView *tree_view = GTK_TREE_VIEW(data);
286
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
287
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
289
// Find selected iteration and create a copy
280
290
GtkTreeIter iter;
282
GtkTreeView *treeView;
284
GtkTreeSelection *selection;
285
GtkTreePath *treePath;
288
// Get view, model and selection of codec store
289
treeView = GTK_TREE_VIEW(data);
290
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
291
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
293
// Find selected iteration and create a copy
294
gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter);
295
iter2 = gtk_tree_iter_copy(&iter);
291
gtk_tree_selection_get_selected(selection, &model, &iter);
292
GtkTreeIter *iter_copy;
293
iter_copy = gtk_tree_iter_copy(&iter);
297
295
// Find path of iteration
298
path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(model), &iter);
296
gchar *path = gtk_tree_model_get_string_from_iter(model, &iter);
300
298
// The first real account in the list can't move up because of the IP2IP account
301
299
// It can still move down though
302
if (g_strcasecmp(path, "1") == 0 && moveUp)
300
if (g_strcmp0(path, "1") == 0 && move_up)
305
treePath = gtk_tree_path_new_from_string(path);
306
gint *indices = gtk_tree_path_get_indices(treePath);
307
gint indice = indices[0];
303
GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
304
gint *indices = gtk_tree_path_get_indices(tree_path);
305
const gint pos = indices[0];
309
307
// Depending on button direction get new path
311
gtk_tree_path_prev(treePath);
309
gtk_tree_path_prev(tree_path);
313
gtk_tree_path_next(treePath);
311
gtk_tree_path_next(tree_path);
315
gtk_tree_model_get_iter(model, &iter, treePath);
313
gtk_tree_model_get_iter(model, &iter, tree_path);
317
315
// Swap iterations if valid
318
316
if (gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), &iter))
319
gtk_list_store_swap(GTK_LIST_STORE(model), &iter, iter2);
317
gtk_list_store_swap(GTK_LIST_STORE(model), &iter, iter_copy);
321
319
// Scroll to new position
322
gtk_tree_view_scroll_to_cell(treeView, treePath, NULL, FALSE, 0, 0);
320
gtk_tree_view_scroll_to_cell(tree_view, tree_path, NULL, FALSE, 0, 0);
324
322
// Free resources
325
gtk_tree_path_free(treePath);
326
gtk_tree_iter_free(iter2);
323
gtk_tree_path_free(tree_path);
324
gtk_tree_iter_free(iter_copy);
329
327
// Perpetuate changes in account queue
331
account_list_move_up(indice);
329
account_list_move_up(pos);
333
account_list_move_down(indice);
331
account_list_move_down(pos);
336
333
// Set the order in the configuration file
337
334
gchar *ordered_account_list = account_list_get_ordered_list();
375
close_dialog_cb(GtkWidget * widget UNUSED,
376
gpointer data UNUSED)
378
gtk_dialog_response(GTK_DIALOG(accountListDialog), GTK_RESPONSE_ACCEPT);
382
void highlight_ip_profile(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED)
388
memset(&val, 0, sizeof(val));
389
gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_DATA, &val);
390
current = (account_t*) g_value_get_pointer(&val);
394
if (current != NULL) {
396
// Make the first line appear differently
397
(g_strcasecmp(current->accountID, IP2IP) == 0) ? g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_THIN,
398
"style", PANGO_STYLE_ITALIC,
399
"stretch", PANGO_STRETCH_ULTRA_EXPANDED,
402
g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_MEDIUM,
403
"style", PANGO_STYLE_NORMAL,
404
"stretch", PANGO_STRETCH_NORMAL,
410
void highlight_registration(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED)
416
memset(&val, 0, sizeof(val));
417
gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_DATA, &val);
418
current = (account_t*) g_value_get_pointer(&val);
422
if (current != NULL) {
423
if (g_strcasecmp(current->accountID, IP2IP) != 0) {
424
// Color the account state: green -> registered, otherwise red
425
(current->state == ACCOUNT_STATE_REGISTERED) ? g_object_set(G_OBJECT(rend), "foreground", "Dark Green", NULL) :
426
g_object_set(G_OBJECT(rend), "foreground", "Dark Red", NULL);
428
g_object_set(G_OBJECT(rend), "foreground", "Black", NULL);
372
close_dialog_cb(GtkWidget * widget UNUSED, gpointer data UNUSED)
374
gtk_dialog_response(GTK_DIALOG(account_list_dialog), GTK_RESPONSE_ACCEPT);
378
highlight_ip_profile(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend,
379
GtkTreeModel *tree_model, GtkTreeIter *iter,
380
gpointer data UNUSED)
383
memset(&val, 0, sizeof(val));
384
gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_ID, &val);
385
account_t *current = account_list_get_by_id(g_value_get_string(&val));
388
// Make the IP2IP account appear differently
390
if (account_is_IP2IP(current)) {
391
g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_THIN, "style",
392
PANGO_STYLE_ITALIC, "stretch",
393
PANGO_STRETCH_ULTRA_EXPANDED, "scale", 0.95, NULL);
395
g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_MEDIUM,
396
"style", PANGO_STYLE_NORMAL, "stretch",
397
PANGO_STRETCH_NORMAL, "scale", 1.0, NULL);
403
state_color(account_t *a)
405
if (!account_is_IP2IP(a))
406
if (a->state == ACCOUNT_STATE_REGISTERED)
415
highlight_registration(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend,
416
GtkTreeModel *tree_model, GtkTreeIter *iter,
417
gpointer data UNUSED)
420
memset(&val, 0, sizeof(val));
421
gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_ID, &val);
422
account_t *current = account_list_get_by_id(g_value_get_string(&val));
426
g_object_set(G_OBJECT(rend), "foreground", state_color(current), NULL);
434
430
* Account settings tab
436
GtkWidget* create_account_list(GtkDialog * dialog UNUSED)
433
create_account_list()
439
GtkWidget *table, *scrolledWindow, *buttonBox;
440
GtkCellRenderer *renderer;
441
GtkTreeView * treeView;
442
GtkTreeViewColumn *treeViewColumn;
443
GtkTreeSelection *treeSelection;
444
GtkRequisition requisition;
446
selectedAccount = NULL;
448
table = gtk_table_new(1, 2, FALSE/* homogeneous */);
435
GtkWidget *table = gtk_table_new(1, 2, FALSE /* homogeneous */);
449
436
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
450
437
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
452
scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
453
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
454
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_SHADOW_IN);
455
gtk_table_attach(GTK_TABLE(table), scrolledWindow, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
457
accountStore = gtk_list_store_new(COLUMN_ACCOUNT_COUNT,
458
G_TYPE_STRING, // Name
459
G_TYPE_STRING, // Protocol
460
G_TYPE_STRING, // Status
461
G_TYPE_BOOLEAN, // Enabled / Disabled
462
G_TYPE_POINTER // Pointer to the Object
465
account_list_config_dialog_fill();
467
treeView = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(accountStore)));
468
treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
469
g_signal_connect(G_OBJECT(treeSelection), "changed",
470
G_CALLBACK(select_account_cb),
473
renderer = gtk_cell_renderer_toggle_new();
474
treeViewColumn = gtk_tree_view_column_new_with_attributes("Enabled", renderer, "active", COLUMN_ACCOUNT_ACTIVE , NULL);
475
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
476
g_signal_connect(G_OBJECT(renderer) , "toggled" , G_CALLBACK(enable_account_cb), (gpointer) treeView);
478
// gtk_cell_renderer_toggle_set_activatable (renderer, FALSE);
439
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
440
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
441
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
442
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
444
gtk_table_attach(GTK_TABLE(table), scrolled_window, 0, 1, 0, 1,
445
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
447
account_store = gtk_list_store_new(COLUMN_ACCOUNT_COUNT,
448
G_TYPE_STRING, // Name
449
G_TYPE_STRING, // Protocol
450
G_TYPE_STRING, // Status
451
G_TYPE_BOOLEAN, // Enabled / Disabled
452
G_TYPE_STRING // AccountID
455
account_store_fill();
457
GtkTreeView * tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(account_store)));
458
GtkTreeSelection *tree_selection = gtk_tree_view_get_selection(tree_view);
459
g_signal_connect(G_OBJECT(tree_selection), "changed",
460
G_CALLBACK(select_account_cb), NULL);
462
GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
463
GtkTreeViewColumn *tree_view_column =
464
gtk_tree_view_column_new_with_attributes("Enabled", renderer, "active",
465
COLUMN_ACCOUNT_ACTIVE , NULL);
466
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
467
g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(enable_account_cb), tree_view);
480
469
renderer = gtk_cell_renderer_text_new();
481
treeViewColumn = gtk_tree_view_column_new_with_attributes("Alias",
483
"markup", COLUMN_ACCOUNT_ALIAS,
485
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
470
tree_view_column = gtk_tree_view_column_new_with_attributes("Alias",
473
COLUMN_ACCOUNT_ALIAS,
475
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
487
477
// A double click on the account line opens the window to edit the account
488
g_signal_connect(G_OBJECT(treeView) , "row-activated" , G_CALLBACK(edit_account_cb) , NULL);
489
gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
491
renderer = gtk_cell_renderer_text_new();
492
treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Protocol"),
494
"markup", COLUMN_ACCOUNT_TYPE,
496
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
497
gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
499
renderer = gtk_cell_renderer_text_new();
500
treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Status"),
502
"markup", COLUMN_ACCOUNT_STATUS,
504
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
478
g_signal_connect(G_OBJECT(tree_view), "row-activated", G_CALLBACK(row_activated_cb), NULL);
479
gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
480
highlight_ip_profile, NULL, NULL);
482
renderer = gtk_cell_renderer_text_new();
483
tree_view_column = gtk_tree_view_column_new_with_attributes(_("Protocol"),
488
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
489
gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
490
highlight_ip_profile, NULL, NULL);
492
renderer = gtk_cell_renderer_text_new();
493
tree_view_column = gtk_tree_view_column_new_with_attributes(_("Status"),
495
"markup", COLUMN_ACCOUNT_STATUS, NULL);
496
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
505
497
// Highlight IP profile
506
gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
498
gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
499
highlight_ip_profile, NULL, NULL);
507
500
// Highlight account registration state
508
gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_registration, NULL, NULL);
510
g_object_unref(G_OBJECT(accountStore));
512
gtk_container_add(GTK_CONTAINER(scrolledWindow), GTK_WIDGET(treeView));
501
gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
502
highlight_registration, NULL,
505
g_object_unref(G_OBJECT(account_store));
507
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(tree_view));
514
509
/* The buttons to press! */
515
buttonBox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
516
gtk_box_set_spacing(GTK_BOX(buttonBox), 10);
517
gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_START);
518
gtk_table_attach(GTK_TABLE(table), buttonBox, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
520
accountMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
521
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
522
gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveUpButton, FALSE, FALSE, 0);
523
g_signal_connect(G_OBJECT(accountMoveUpButton), "clicked", G_CALLBACK(account_move_up_cb), treeView);
525
accountMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
526
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
527
gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveDownButton, FALSE, FALSE, 0);
528
g_signal_connect(G_OBJECT(accountMoveDownButton), "clicked", G_CALLBACK(account_move_down_cb), treeView);
530
addButton = gtk_button_new_from_stock(GTK_STOCK_ADD);
531
g_signal_connect_swapped(G_OBJECT(addButton), "clicked",
510
GtkWidget *button_box = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
511
gtk_box_set_spacing(GTK_BOX(button_box), 10);
512
gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_START);
513
gtk_table_attach(GTK_TABLE(table), button_box, 1, 2, 0, 1,
514
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
516
move_up_button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
517
gtk_widget_set_sensitive(move_up_button, FALSE);
518
gtk_box_pack_start(GTK_BOX(button_box), move_up_button, FALSE, FALSE, 0);
519
g_signal_connect(G_OBJECT(move_up_button), "clicked",
520
G_CALLBACK(move_up_cb), tree_view);
522
move_down_button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
523
gtk_widget_set_sensitive(move_down_button, FALSE);
524
gtk_box_pack_start(GTK_BOX(button_box), move_down_button, FALSE, FALSE, 0);
525
g_signal_connect(G_OBJECT(move_down_button), "clicked",
526
G_CALLBACK(move_down_cb), tree_view);
528
GtkWidget *add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
529
g_signal_connect_swapped(G_OBJECT(add_button), "clicked",
532
530
G_CALLBACK(add_account_cb), NULL);
533
gtk_box_pack_start(GTK_BOX(buttonBox), addButton, FALSE, FALSE, 0);
535
editButton = gtk_button_new_from_stock(GTK_STOCK_EDIT);
536
gtk_widget_set_sensitive(GTK_WIDGET(editButton), FALSE);
537
g_signal_connect_swapped(G_OBJECT(editButton), "clicked",
538
G_CALLBACK(edit_account_cb), NULL);
539
gtk_box_pack_start(GTK_BOX(buttonBox), editButton, FALSE, FALSE, 0);
541
deleteButton = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
542
gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
543
g_signal_connect_swapped(G_OBJECT(deleteButton), "clicked",
544
G_CALLBACK(delete_account_cb), NULL);
545
gtk_box_pack_start(GTK_BOX(buttonBox), deleteButton, FALSE, FALSE, 0);
531
gtk_box_pack_start(GTK_BOX(button_box), add_button, FALSE, FALSE, 0);
533
edit_button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
534
gtk_widget_set_sensitive(edit_button, FALSE);
535
g_signal_connect(G_OBJECT(edit_button), "clicked", G_CALLBACK(edit_account_cb), tree_view);
536
gtk_box_pack_start(GTK_BOX(button_box), edit_button, FALSE, FALSE, 0);
538
delete_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
539
gtk_widget_set_sensitive(delete_button, FALSE);
540
g_signal_connect(G_OBJECT(delete_button), "clicked",
541
G_CALLBACK(delete_account_cb), tree_view);
542
gtk_box_pack_start(GTK_BOX(button_box), delete_button, FALSE, FALSE, 0);
547
544
/* help and close buttons */
548
545
GtkWidget * buttonHbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
549
gtk_table_attach(GTK_TABLE(table), buttonHbox, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
546
gtk_table_attach(GTK_TABLE(table), buttonHbox, 0, 2, 1, 2,
547
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
551
549
GtkWidget * helpButton = gtk_button_new_from_stock(GTK_STOCK_HELP);
552
550
g_signal_connect_swapped(G_OBJECT(helpButton), "clicked",
554
552
gtk_box_pack_start(GTK_BOX(buttonHbox), helpButton, FALSE, FALSE, 0);
556
554
GtkWidget * closeButton = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
557
g_signal_connect_swapped(G_OBJECT(closeButton), "clicked", G_CALLBACK(close_dialog_cb), NULL);
555
g_signal_connect_swapped(G_OBJECT(closeButton), "clicked",
556
G_CALLBACK(close_dialog_cb), NULL);
558
557
gtk_box_pack_start(GTK_BOX(buttonHbox), closeButton, FALSE, FALSE, 0);
560
559
gtk_widget_show_all(table);
561
// account_list_config_dialog_fill();
563
/* Resize the scrolledWindow for a better view */
564
gtk_widget_get_preferred_size(GTK_WIDGET(treeView), NULL, &requisition);
565
gtk_widget_set_size_request(GTK_WIDGET(scrolledWindow), requisition.width + 20, requisition.height);
561
/* Resize the scrolled window for a better view */
562
GtkRequisition requisition;
563
gtk_widget_get_preferred_size(GTK_WIDGET(tree_view), NULL, &requisition);
564
gtk_widget_set_size_request(scrolled_window, requisition.width + 20,
566
566
GtkRequisition requisitionButton;
567
gtk_widget_get_preferred_size(GTK_WIDGET(deleteButton), NULL, &requisitionButton);
568
gtk_widget_set_size_request(GTK_WIDGET(closeButton), requisitionButton.width, -1);
569
gtk_widget_set_size_request(GTK_WIDGET(helpButton), requisitionButton.width, -1);
567
gtk_widget_get_preferred_size(delete_button, NULL, &requisitionButton);
568
gtk_widget_set_size_request(closeButton, requisitionButton.width, -1);
569
gtk_widget_set_size_request(helpButton, requisitionButton.width, -1);
571
571
gtk_widget_show_all(table);
577
show_account_list_config_dialog(void)
579
accountListDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Accounts"),
580
GTK_WINDOW(get_main_window()),
581
GTK_DIALOG_DESTROY_WITH_PARENT,
576
void update_account_list_status_bar(account_t *account)
578
if (!account || !account_list_status_bar)
581
/* Update status bar about current registration state */
582
gtk_statusbar_pop(GTK_STATUSBAR(account_list_status_bar),
583
CONTEXT_ID_REGISTRATION);
585
const gchar *state_name = account_state_name(account->state);
586
if (account->protocol_state_description != NULL &&
587
account->protocol_state_code != 0) {
589
gchar * response = g_strdup_printf(_("Server returned \"%s\" (%d)"),
590
account->protocol_state_description,
591
account->protocol_state_code);
592
gchar * message = g_strconcat(state_name, ". ", response, NULL);
593
gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar),
594
CONTEXT_ID_REGISTRATION, message);
599
gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar),
600
CONTEXT_ID_REGISTRATION, state_name);
603
GtkTreeModel *model = GTK_TREE_MODEL(account_store);
605
if (find_account_in_account_store(account->accountID, model, &iter))
606
gtk_list_store_set(account_store, &iter, COLUMN_ACCOUNT_STATUS, state_name, -1);
609
void show_account_list_config_dialog(void)
611
account_list_dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Accounts"),
612
GTK_WINDOW(get_main_window()),
613
GTK_DIALOG_DESTROY_WITH_PARENT, NULL,
584
616
/* Set window properties */
585
gtk_container_set_border_width(GTK_CONTAINER(accountListDialog), 0);
586
gtk_window_set_resizable(GTK_WINDOW(accountListDialog), FALSE);
617
gtk_container_set_border_width(GTK_CONTAINER(account_list_dialog), 0);
618
gtk_window_set_resizable(GTK_WINDOW(account_list_dialog), FALSE);
588
620
GtkWidget *accountFrame = gnome_main_section_new(_("Configured Accounts"));
589
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(accountListDialog)),
621
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(account_list_dialog)),
590
622
accountFrame, TRUE, TRUE, 0);
591
623
gtk_widget_show(accountFrame);
593
625
/* Accounts tab */
594
GtkWidget *tab = create_account_list(accountListDialog);
626
GtkWidget *tab = create_account_list();
595
627
gtk_widget_show(tab);
596
628
gtk_container_add(GTK_CONTAINER(accountFrame), tab);
598
630
/* Status bar for the account list */
599
status_bar = gtk_statusbar_new();
600
gtk_widget_show (status_bar);
601
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area(accountListDialog)), status_bar, TRUE, TRUE, 0);
603
int number_accounts = account_list_get_registered_accounts();
605
if (number_accounts) {
631
account_list_status_bar = gtk_statusbar_new();
632
gtk_widget_show(account_list_status_bar);
633
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(account_list_dialog)), account_list_status_bar, TRUE, TRUE, 0);
635
const gint num_accounts = account_list_get_registered_accounts();
606
638
gchar * message = g_strdup_printf(n_("There is %d active account",
607
639
"There are %d active accounts",
608
number_accounts), number_accounts);
609
gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, message);
640
num_accounts), num_accounts);
641
gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar), CONTEXT_ID_REGISTRATION,
612
gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION,
645
gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar), CONTEXT_ID_REGISTRATION,
613
646
_("You have no active account"));
615
gtk_dialog_run(accountListDialog);
649
gtk_dialog_run(account_list_dialog);
617
651
status_bar_display_account();
619
gtk_widget_destroy(GTK_WIDGET(accountListDialog));
620
accountListDialog = NULL;
653
gtk_widget_destroy(GTK_WIDGET(account_list_dialog));
655
/* Invalidate static pointers */
656
account_list_dialog = NULL;
657
account_list_status_bar = NULL;
659
delete_button = NULL;
660
move_down_button = NULL;
661
move_up_button = NULL;
662
account_store = NULL;
621
664
update_actions();