blob: 8fd605c76426976369b7e33d5c9ecc8c980edfab [file] [log] [blame]
Stepan Salenikovich61cbab02015-03-16 18:35:10 -04001/*
Stepan Salenikovichbe87d2c2016-01-25 14:14:34 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Stepan Salenikovich61cbab02015-03-16 18:35:10 -04003 * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040018 */
19
20#include "accountgeneraltab.h"
21
22#include <gtk/gtk.h>
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -040023#include <glib/gi18n.h>
aviau9bbb19b2016-05-16 15:53:44 -040024#include "models/gtkqtreemodel.h"
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040025#include <account.h>
aviau9bbb19b2016-05-16 15:53:44 -040026#include <bootstrapmodel.h>
27#include "defines.h"
28#include "utils/models.h"
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040029
30struct _AccountGeneralTab
31{
32 GtkBox parent;
33};
34
35struct _AccountGeneralTabClass
36{
37 GtkBoxClass parent_class;
38};
39
40typedef struct _AccountGeneralTabPrivate AccountGeneralTabPrivate;
41
42struct _AccountGeneralTabPrivate
43{
44 Account *account;
45 GtkWidget *grid_account;
46 GtkWidget *grid_parameters;
aviau9bbb19b2016-05-16 15:53:44 -040047 GtkWidget *treeview_bootstrap_servers;
Stepan Salenikovichbd029582015-03-24 11:00:56 -040048
49 QMetaObject::Connection account_updated;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040050};
51
52G_DEFINE_TYPE_WITH_PRIVATE(AccountGeneralTab, account_general_tab, GTK_TYPE_BOX);
53
54#define ACCOUNT_GENERAL_TAB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_GENERAL_TAB_TYPE, AccountGeneralTabPrivate))
55
56static void
57account_general_tab_dispose(GObject *object)
58{
Stepan Salenikovichbd029582015-03-24 11:00:56 -040059 AccountGeneralTab *view = ACCOUNT_GENERAL_TAB(object);
60 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
61
62 QObject::disconnect(priv->account_updated);
63
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040064 G_OBJECT_CLASS(account_general_tab_parent_class)->dispose(object);
65}
66
67static void
68account_general_tab_init(AccountGeneralTab *view)
69{
70 gtk_widget_init_template(GTK_WIDGET(view));
71}
72
73static void
74account_general_tab_class_init(AccountGeneralTabClass *klass)
75{
76 G_OBJECT_CLASS(klass)->dispose = account_general_tab_dispose;
77
78 gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
79 "/cx/ring/RingGnome/accountgeneraltab.ui");
80
81 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_account);
82 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_parameters);
83}
84
85static void
aviau9bbb19b2016-05-16 15:53:44 -040086remove_bootstrap_server(GtkWidget *item, AccountGeneralTab *view)
87{
88 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
89 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
90 auto row = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(item), "bootstrap-server-row"));
91 priv->account->bootstrapModel()->removeRows(row, 1);
92}
93
94static void
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040095account_alias_changed(GtkEditable *entry, AccountGeneralTab *view)
96{
97 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
98 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
99 priv->account->setAlias(QString(gtk_editable_get_chars(entry, 0, -1)));
Stepan Salenikovich75a39172015-07-10 13:21:08 -0400100 if (priv->account->protocol() == Account::Protocol::RING)
101 priv->account->setDisplayName(gtk_entry_get_text(GTK_ENTRY(entry)));
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400102}
103
104static void
105account_hostname_changed(GtkEditable *entry, AccountGeneralTab *view)
106{
107 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
108 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
109 priv->account->setHostname(QString(gtk_editable_get_chars(entry, 0, -1)));
110}
111
112static void
113account_username_changed(GtkEditable *entry, AccountGeneralTab *view)
114{
115 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
116 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
117 priv->account->setUsername(QString(gtk_editable_get_chars(entry, 0, -1)));
118}
119
120static void
121account_password_changed(GtkEditable *entry, AccountGeneralTab *view)
122{
123 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
124 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
125 priv->account->setPassword(QString(gtk_editable_get_chars(entry, 0, -1)));
126}
127
128static void
129show_password(GtkToggleButton *checkbutton, GtkEntry *entry)
130{
131 gtk_entry_set_visibility(GTK_ENTRY(entry), gtk_toggle_button_get_active(checkbutton));
132}
133
134static void
135account_proxy_changed(GtkEditable *entry, AccountGeneralTab *view)
136{
137 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
138 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
139 priv->account->setProxy(QString(gtk_editable_get_chars(entry, 0, -1)));
140}
141
142static void
143account_mailbox_changed(GtkEditable *entry, AccountGeneralTab *view)
144{
145 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
146 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
147 priv->account->setMailbox(QString(gtk_editable_get_chars(entry, 0, -1)));
148}
149
150static void
151auto_answer(GtkToggleButton *checkbutton, AccountGeneralTab *view)
152{
153 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
154 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
155 priv->account->setAutoAnswer(gtk_toggle_button_get_active(checkbutton));
156}
157
158static void
159upnp_enabled(GtkToggleButton *checkbutton, AccountGeneralTab *view)
160{
161 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
162 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
163 priv->account->setUpnpEnabled(gtk_toggle_button_get_active(checkbutton));
164}
165
Stepan Salenikovich96ee9a02015-04-28 10:23:13 -0400166static void
167dtmf_set_rtp(GtkToggleButton *toggle_rtp, AccountGeneralTab *view)
168{
169 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
170 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
171 if (gtk_toggle_button_get_active(toggle_rtp)) {
172 g_debug("set DTMF over RTP");
173 priv->account->setDTMFType(DtmfType::OverRtp);
174 } else {
175 g_debug("set DTMF over SIP");
176 priv->account->setDTMFType(DtmfType::OverSip);
177 }
178}
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400179
aviau9bbb19b2016-05-16 15:53:44 -0400180
181static void
182bootstrap_server_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, AccountGeneralTab *view)
183{
184 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
185 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
186
187 /* get iter which was clicked */
188 GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
189 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(priv->treeview_bootstrap_servers));
190 GtkTreeIter iter;
191 gtk_tree_model_get_iter(model, &iter, tree_path);
192
193 /* get qmodelindex from iter and set the model data */
194 auto column = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(renderer), "model-column"));
195 QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);
196 if (idx.isValid()) {
197 priv->account->bootstrapModel()->setData(
198 idx.sibling(idx.row(), column),
199 QVariant(new_text),
200 Qt::EditRole
201 );
202 }
203}
204
205static gboolean
206bootstrap_servers_popup_menu(G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event, AccountGeneralTab *view)
207{
208 g_return_val_if_fail(IS_ACCOUNT_GENERAL_TAB(view), FALSE);
209 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
210
211 /* check for right click */
212 if (event->button != BUTTON_RIGHT_CLICK || event->type != GDK_BUTTON_PRESS)
213 return FALSE;
214
215 GtkTreeIter iter;
216 GtkTreeModel *model;
217 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_bootstrap_servers));
218 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
219 return FALSE;
220
221 GtkWidget *menu = gtk_menu_new();
222 QModelIndex idx = get_index_from_selection(selection);
223
224 GtkWidget *remove_server_item = gtk_menu_item_new_with_mnemonic(_("_Remove server"));
225 gtk_menu_shell_append(GTK_MENU_SHELL(menu), remove_server_item);
226 g_object_set_data(G_OBJECT(remove_server_item), "bootstrap-server-row", GUINT_TO_POINTER(idx.row()));
227 g_signal_connect(remove_server_item,
228 "activate",
229 G_CALLBACK(remove_bootstrap_server),
230 view);
231
232 /* show menu */
233 gtk_widget_show_all(menu);
234 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
235
236 return TRUE; /* we handled the event */
237}
238
239
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400240static void
241build_tab_view(AccountGeneralTab *view)
242{
243 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
244 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
245
246 int grid_row = 0;
247 GtkWidget *label = NULL;
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400248
249 /* separate pointers for each so that we reference them in the account changed callback */
250 GtkWidget *entry_alias = NULL;
251 GtkWidget *entry_username = NULL;
252 GtkWidget *entry_hostname = NULL;
253 GtkWidget *entry_password = NULL;
254 GtkWidget *entry_proxy = NULL;
255 GtkWidget *entry_voicemail = NULL;
256 GtkWidget *checkbutton_autoanswer = NULL;
257 GtkWidget *checkbutton_upnp = NULL;
Stepan Salenikovich96ee9a02015-04-28 10:23:13 -0400258 GtkWidget *radiobutton_dtmf_rtp = NULL;
259 GtkWidget *radiobutton_dtmf_sip = NULL;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400260
261 /* build account grid */
262
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400263 /* account alias */
264 label = gtk_label_new(_("Alias"));
265 gtk_widget_set_halign(label, GTK_ALIGN_START);
266 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
267 entry_alias = gtk_entry_new();
268 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
269 gtk_widget_set_halign(entry_alias, GTK_ALIGN_START);
270 g_signal_connect(entry_alias, "changed", G_CALLBACK(account_alias_changed), view);
271 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_alias, 1, grid_row, 1, 1);
272 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400273
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400274 /* account type */
275 label = gtk_label_new(_("Type"));
276 gtk_widget_set_halign(label, GTK_ALIGN_START);
277 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400278
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400279 label = gtk_label_new("");
280 gtk_widget_set_halign(label, GTK_ALIGN_START);
281 switch (priv->account->protocol()) {
282 case Account::Protocol::SIP:
283 gtk_label_set_text(GTK_LABEL(label), "SIP");
284 break;
285 case Account::Protocol::IAX:
286 gtk_label_set_text(GTK_LABEL(label), "IAX");
287 break;
288 case Account::Protocol::RING:
289 gtk_label_set_text(GTK_LABEL(label), "RING");
290 break;
291 case Account::Protocol::COUNT__:
292 break;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400293 }
294
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400295 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 1, grid_row, 1, 1);
296 ++grid_row;
297
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400298 if (priv->account->protocol() == Account::Protocol::RING) {
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400299 label = gtk_label_new("RingID");
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400300 gtk_widget_set_halign(label, GTK_ALIGN_START);
301 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400302 entry_username = gtk_entry_new();
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400303 gtk_entry_set_placeholder_text(GTK_ENTRY(entry_username), _("auto-generating..."));
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400304 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
305 g_object_set(G_OBJECT(entry_username), "editable", FALSE, NULL);
306 g_object_set(G_OBJECT(entry_username), "max-width-chars", 50, NULL);
307 gtk_widget_override_font(entry_username, pango_font_description_from_string("monospace"));
308 gtk_entry_set_alignment(GTK_ENTRY(entry_username), 0.5);
309 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_username, 1, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400310 ++grid_row;
311 }
312
313 gtk_widget_show_all(priv->grid_account);
314
315 /* build parameters grid */
316 grid_row = 0;
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400317 if (priv->account->protocol() != Account::Protocol::RING) {
318 /* SIP and IAX have the same params */
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400319
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400320 /* host name */
321 label = gtk_label_new(_("Hostname"));
322 gtk_widget_set_halign(label, GTK_ALIGN_START);
323 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
324 entry_hostname = gtk_entry_new();
325 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
326 g_signal_connect(entry_hostname, "changed", G_CALLBACK(account_hostname_changed), view);
327 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_hostname, 1, grid_row, 1, 1);
328 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400329
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400330 /* user name */
331 label = gtk_label_new(_("Username"));
332 gtk_widget_set_halign(label, GTK_ALIGN_START);
333 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
334 entry_username = gtk_entry_new();
335 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
336 g_signal_connect(entry_username, "changed", G_CALLBACK(account_username_changed), view);
337 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_username, 1, grid_row, 1, 1);
338 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400339
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400340 /* password */
341 label = gtk_label_new(_("Password"));
342 gtk_widget_set_halign(label, GTK_ALIGN_START);
343 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
344 entry_password = gtk_entry_new();
345 gtk_entry_set_input_purpose(GTK_ENTRY(entry_password), GTK_INPUT_PURPOSE_PASSWORD);
346 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(entry_password), GTK_ENTRY_ICON_PRIMARY, "dialog-password");
347 gtk_entry_set_visibility(GTK_ENTRY(entry_password), FALSE);
348 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
349 g_signal_connect(entry_password, "changed", G_CALLBACK(account_password_changed), view);
350 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_password, 1, grid_row, 1, 1);
351 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400352
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400353 /* show password */
354 GtkWidget *checkbutton = gtk_check_button_new_with_label(_("Show password"));
355 gtk_grid_attach(GTK_GRID(priv->grid_parameters), checkbutton, 1, grid_row, 1, 1);
356 g_signal_connect(checkbutton, "toggled", G_CALLBACK(show_password), entry_password);
357 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400358
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400359 /* proxy */
360 label = gtk_label_new(_("Proxy"));
361 gtk_widget_set_halign(label, GTK_ALIGN_START);
362 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
363 entry_proxy = gtk_entry_new();
364 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
365 g_signal_connect(entry_proxy, "changed", G_CALLBACK(account_proxy_changed), view);
366 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_proxy, 1, grid_row, 1, 1);
367 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400368
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400369 /* voicemail number */
370 label = gtk_label_new(_("Voicemail number"));
371 gtk_widget_set_halign(label, GTK_ALIGN_START);
372 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
373 entry_voicemail = gtk_entry_new();
374 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
375 g_signal_connect(entry_voicemail, "changed", G_CALLBACK(account_mailbox_changed), view);
376 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_voicemail, 1, grid_row, 1, 1);
377 ++grid_row;
378 } else {
379 /* RING account */
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400380
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400381 /* bootstrap */
aviau9bbb19b2016-05-16 15:53:44 -0400382 label = gtk_label_new(C_("The DHT bootstrap server url", "Bootstrap Servers"));
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400383 gtk_widget_set_halign(label, GTK_ALIGN_START);
384 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
aviau9bbb19b2016-05-16 15:53:44 -0400385 ++grid_row;
386
387 priv->treeview_bootstrap_servers = gtk_tree_view_new();
388 g_signal_connect(GTK_WIDGET(priv->treeview_bootstrap_servers),
389 "button-press-event",
390 G_CALLBACK(bootstrap_servers_popup_menu),
391 GTK_WIDGET(view));
392
393 auto bootstrap_servers_frame = gtk_frame_new(NULL);
394 gtk_container_add(GTK_CONTAINER(bootstrap_servers_frame), GTK_WIDGET(priv->treeview_bootstrap_servers));
395
396 auto bootstrap_servers_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
397 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(bootstrap_servers_scrolled_window), 200);
398 gtk_container_add(GTK_CONTAINER(bootstrap_servers_scrolled_window), bootstrap_servers_frame);
399
400 gtk_grid_attach(GTK_GRID(priv->grid_parameters), bootstrap_servers_scrolled_window, 0, grid_row, 2, 1);
401
402 auto *bootstrap_model = gtk_q_tree_model_new(
403 (QAbstractItemModel*) priv->account->bootstrapModel(),
404 2,
405 BootstrapModel::Columns::HOSTNAME, Qt::DisplayRole, G_TYPE_STRING,
406 BootstrapModel::Columns::PORT, Qt::DisplayRole, G_TYPE_STRING);
407
408 gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview_bootstrap_servers), GTK_TREE_MODEL(bootstrap_model));
409
410 GtkCellRenderer *renderer;
411 GtkTreeViewColumn *column;
412
413 renderer = gtk_cell_renderer_text_new();
414 g_object_set(renderer, "editable", true, NULL);
415 column = gtk_tree_view_column_new_with_attributes(_("Hostname"), renderer, "text", 0, NULL);
416 gtk_tree_view_column_set_expand(column, TRUE);
417 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_bootstrap_servers), column);
418 g_object_set_data(G_OBJECT(renderer), "model-column", GUINT_TO_POINTER(BootstrapModel::Columns::HOSTNAME));
419 g_signal_connect(renderer, "edited", G_CALLBACK(bootstrap_server_edited), view);
420
421 renderer = gtk_cell_renderer_text_new();
422 g_object_set(renderer, "editable", true, NULL);
423 column = gtk_tree_view_column_new_with_attributes(_("Port"), renderer, "text", 1, NULL);
424 gtk_tree_view_column_set_expand(column, TRUE);
425 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_bootstrap_servers), column);
426 g_object_set_data(G_OBJECT(renderer), "model-column", GUINT_TO_POINTER(BootstrapModel::Columns::PORT));
427 g_signal_connect(renderer, "edited", G_CALLBACK(bootstrap_server_edited), view);
428
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400429 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400430 }
431
432 /* auto answer */
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400433 checkbutton_autoanswer = gtk_check_button_new_with_label(_("Auto-answer calls"));
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400434 gtk_widget_set_halign(checkbutton_autoanswer, GTK_ALIGN_START);
435 gtk_grid_attach(GTK_GRID(priv->grid_parameters), checkbutton_autoanswer, 0, grid_row, 1, 1);
436 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_autoanswer), priv->account->isAutoAnswer());
437 g_signal_connect(checkbutton_autoanswer, "toggled", G_CALLBACK(auto_answer), view);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400438 ++grid_row;
439
440 /* upnp */
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400441 checkbutton_upnp = gtk_check_button_new_with_label(_("UPnP enabled"));
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400442 gtk_widget_set_halign(checkbutton_upnp, GTK_ALIGN_START);
443 gtk_grid_attach(GTK_GRID(priv->grid_parameters), checkbutton_upnp, 0, grid_row, 1, 1);
444 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_upnp), priv->account->isUpnpEnabled());
445 g_signal_connect(checkbutton_upnp, "toggled", G_CALLBACK(upnp_enabled), view);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400446 ++grid_row;
447
Stepan Salenikovich96ee9a02015-04-28 10:23:13 -0400448 /* DTMF tone type */
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400449 label = gtk_label_new(_("DTMF tone type:"));
Stepan Salenikovich96ee9a02015-04-28 10:23:13 -0400450 gtk_widget_set_halign(label, GTK_ALIGN_START);
451 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
452
453 GtkWidget *dtmf_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
454 gtk_button_box_set_layout(GTK_BUTTON_BOX(dtmf_box), GTK_BUTTONBOX_START);
455 gtk_box_set_spacing(GTK_BOX(dtmf_box), 10);
456 radiobutton_dtmf_rtp = gtk_radio_button_new_with_label(NULL, "RTP");
457 radiobutton_dtmf_sip = gtk_radio_button_new_with_label_from_widget(
458 GTK_RADIO_BUTTON(radiobutton_dtmf_rtp),
459 "SIP");
460 gtk_toggle_button_set_active(
461 priv->account->DTMFType() == DtmfType::OverRtp ?
462 GTK_TOGGLE_BUTTON(radiobutton_dtmf_rtp) : GTK_TOGGLE_BUTTON(radiobutton_dtmf_sip),
463 TRUE);
464 g_signal_connect(radiobutton_dtmf_rtp, "toggled", G_CALLBACK(dtmf_set_rtp), view);
465 gtk_box_pack_start(GTK_BOX(dtmf_box),
466 radiobutton_dtmf_rtp,
467 FALSE, TRUE, 0);
468 gtk_box_pack_start(GTK_BOX(dtmf_box),
469 radiobutton_dtmf_sip,
470 FALSE, TRUE, 0);
471 gtk_grid_attach(GTK_GRID(priv->grid_parameters), dtmf_box, 1, grid_row, 1, 1);
472 ++grid_row;
473
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400474 /* update account parameters if model is updated */
475 priv->account_updated = QObject::connect(
476 priv->account,
477 &Account::changed,
478 [=] () {
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400479 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
480 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400481
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400482 if (priv->account->protocol() != Account::Protocol::RING) {
aviau9bbb19b2016-05-16 15:53:44 -0400483 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400484 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
485 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
486 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400487 }
488
489 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_autoanswer), priv->account->isAutoAnswer());
490 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_upnp), priv->account->isUpnpEnabled());
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400491 gtk_toggle_button_set_active(
Stepan Salenikovich96ee9a02015-04-28 10:23:13 -0400492 priv->account->DTMFType() == DtmfType::OverRtp ?
493 GTK_TOGGLE_BUTTON(radiobutton_dtmf_rtp) : GTK_TOGGLE_BUTTON(radiobutton_dtmf_sip),
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400494 TRUE);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400495 }
496 );
497
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400498 gtk_widget_show_all(priv->grid_parameters);
499
500}
501
502GtkWidget *
503account_general_tab_new(Account *account)
504{
505 g_return_val_if_fail(account != NULL, NULL);
506
507 gpointer view = g_object_new(ACCOUNT_GENERAL_TAB_TYPE, NULL);
508
509 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
510 priv->account = account;
511
512 build_tab_view(ACCOUNT_GENERAL_TAB(view));
513
514 return (GtkWidget *)view;
515}