blob: 64ceeb413fe0be215692d113121094d90be33ee1 [file] [log] [blame]
Stepan Salenikovich61cbab02015-03-16 18:35:10 -04001/*
Guillaume Roguez77c579d2018-01-30 15:54:02 -05002 * Copyright (C) 2015-2018 Savoir-faire Linux Inc.
Sébastien Blin396212d2018-05-11 09:16:43 -04003 * Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com>
Sébastien Blin276202f2018-05-11 09:37:34 -04004 * Author: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
Sébastien Blin396212d2018-05-11 09:16:43 -04005 * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
Stepan Salenikovich61cbab02015-03-16 18:35:10 -04006 *
7 * This program is free software; you can redistribute it and/or modify
8 * 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
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040020 */
21
22#include "accountgeneraltab.h"
23
24#include <gtk/gtk.h>
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -040025#include <glib/gi18n.h>
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040026#include <account.h>
aviau9bbb19b2016-05-16 15:53:44 -040027#include "defines.h"
28#include "utils/models.h"
aviau2da3d9c2016-09-06 11:28:36 -040029#include "usernameregistrationbox.h"
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040030
Sébastien Blin396212d2018-05-11 09:16:43 -040031#include <api/newdevicemodel.h>
Sébastien Blin276202f2018-05-11 09:37:34 -040032#include <api/newaccountmodel.h>
33
Sébastien Blin396212d2018-05-11 09:16:43 -040034
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040035struct _AccountGeneralTab
36{
37 GtkBox parent;
38};
39
40struct _AccountGeneralTabClass
41{
42 GtkBoxClass parent_class;
43};
44
45typedef struct _AccountGeneralTabPrivate AccountGeneralTabPrivate;
46
47struct _AccountGeneralTabPrivate
48{
49 Account *account;
Sébastien Blin276202f2018-05-11 09:37:34 -040050 AccountInfoPointer const *accountInfo_;
51
Sébastien Blin396212d2018-05-11 09:16:43 -040052 GtkWidget* stack_account_general;
53 GtkWidget* account_general;
54
55 GtkWidget* grid_account;
Sébastien Blin1e191dc2018-02-28 11:14:34 -050056 GtkWidget* frame_parameters;
Sébastien Blin396212d2018-05-11 09:16:43 -040057 GtkWidget* grid_parameters;
Stepan Salenikovichbd029582015-03-24 11:00:56 -040058
Sébastien Blinc50a8a32017-09-22 10:13:12 -040059 GtkWidget* entry_current_password;
60 GtkWidget* entry_new_password;
61 GtkWidget* entry_confirm_password;
62 GtkWidget* button_validate_password;
63 GtkWidget* label_error_change_passowrd;
64
Sébastien Blinb5da5ab2018-02-27 16:46:20 -050065 GtkWidget* button_choose_file;
66 GtkWidget* label_export_informations;
67
Sébastien Blin396212d2018-05-11 09:16:43 -040068 GtkWidget* list_devices;
69 GtkWidget* vbox_devices;
70 GtkWidget* button_add_device;
71
72 /* generated_pin view */
73 GtkWidget* generated_pin;
74 GtkWidget* label_generated_pin;
75 GtkWidget* button_generated_pin_ok;
76
77 /* add_device view */
78 GtkWidget* add_device_box;
79 GtkWidget* button_export_on_the_ring;
80 GtkWidget* button_add_device_cancel;
81 GtkWidget* entry_password;
82
83 /* generating account spinner */
84 GtkWidget* vbox_generating_pin_spinner;
85
86 /* export on ring error */
87 GtkWidget* export_on_ring_error;
88 GtkWidget* label_export_on_ring_error;
89 GtkWidget* button_export_on_ring_error_ok;
90
Stepan Salenikovichbd029582015-03-24 11:00:56 -040091 QMetaObject::Connection account_updated;
Sébastien Blin396212d2018-05-11 09:16:43 -040092 QMetaObject::Connection new_device_added_connection;
93 QMetaObject::Connection device_updated_connection;
94 QMetaObject::Connection device_removed_connection;
95 QMetaObject::Connection export_on_ring_ended;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040096};
97
98G_DEFINE_TYPE_WITH_PRIVATE(AccountGeneralTab, account_general_tab, GTK_TYPE_BOX);
99
100#define ACCOUNT_GENERAL_TAB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_GENERAL_TAB_TYPE, AccountGeneralTabPrivate))
101
102static void
103account_general_tab_dispose(GObject *object)
104{
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400105 AccountGeneralTab *view = ACCOUNT_GENERAL_TAB(object);
106 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
107
108 QObject::disconnect(priv->account_updated);
Sébastien Blin396212d2018-05-11 09:16:43 -0400109 QObject::disconnect(priv->new_device_added_connection);
110 QObject::disconnect(priv->device_updated_connection);
111 QObject::disconnect(priv->device_removed_connection);
112 QObject::disconnect(priv->export_on_ring_ended);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400113
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400114 G_OBJECT_CLASS(account_general_tab_parent_class)->dispose(object);
115}
116
117static void
118account_general_tab_init(AccountGeneralTab *view)
119{
120 gtk_widget_init_template(GTK_WIDGET(view));
121}
122
123static void
124account_general_tab_class_init(AccountGeneralTabClass *klass)
125{
126 G_OBJECT_CLASS(klass)->dispose = account_general_tab_dispose;
127
128 gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
129 "/cx/ring/RingGnome/accountgeneraltab.ui");
130
Sébastien Blin396212d2018-05-11 09:16:43 -0400131 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, stack_account_general);
132 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, account_general);
133
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400134 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_account);
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500135 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, frame_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400136 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_parameters);
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400137
138 /* change password view */
139 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_current_password);
140 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_new_password);
141 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_confirm_password);
142 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_validate_password);
143 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_error_change_passowrd);
144
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500145 /* export account */
146 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_choose_file);
147 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_export_informations);
148
Sébastien Blin396212d2018-05-11 09:16:43 -0400149 // Devices
150 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, list_devices);
151 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, vbox_devices);
152 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_add_device);
153
154 // add_device view
155 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, add_device_box);
156 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_export_on_the_ring);
157 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_add_device_cancel);
158 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_password);
159
160 // generating pin spinner
161 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, vbox_generating_pin_spinner);
162
163 // export on ring error
164 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, export_on_ring_error);
165 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_export_on_ring_error);
166 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_export_on_ring_error_ok);
167
168 // generated_pin view
169 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, generated_pin);
170 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_generated_pin);
171 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_generated_pin_ok);
172}
173
174static void
175show_account_general_view(AccountGeneralTab *view)
176{
177 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
178 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
179 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->account_general);
180}
181
182static void
183show_add_device_view(AccountGeneralTab *view)
184{
185 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
186 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
187 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->add_device_box);
188}
189
190static void
191show_generated_pin_view(AccountGeneralTab *view)
192{
193 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
194 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
195 gtk_widget_show(priv->generated_pin);
196 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->generated_pin);
197}
198
199static void
200show_generating_pin_spinner(AccountGeneralTab *view)
201{
202 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
203 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
204 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->vbox_generating_pin_spinner);
205}
206
207static void
208show_export_on_ring_error(AccountGeneralTab *view)
209{
210 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
211 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
212 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->export_on_ring_error);
213}
214
215static void
216export_on_the_ring_clicked(G_GNUC_UNUSED GtkButton *button, AccountGeneralTab *view)
217{
218 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
219 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
220
221 auto password = QString(gtk_entry_get_text(GTK_ENTRY(priv->entry_password)));
222 gtk_entry_set_text(GTK_ENTRY(priv->entry_password), "");
223
224 priv->export_on_ring_ended = QObject::connect(
225 priv->account,
226 &Account::exportOnRingEnded,
227 [=] (Account::ExportOnRingStatus status, QString pin) {
228 QObject::disconnect(priv->export_on_ring_ended);
229 switch (status)
230 {
231 case Account::ExportOnRingStatus::SUCCESS:
232 {
233 gtk_label_set_text(GTK_LABEL(priv->label_generated_pin), pin.toStdString().c_str());
234 show_generated_pin_view(view);
235 break;
236 }
237 case Account::ExportOnRingStatus::WRONG_PASSWORD:
238 {
239 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Bad password"));
240 show_export_on_ring_error(view);
241 break;
242 }
243 case Account::ExportOnRingStatus::NETWORK_ERROR:
244 {
245 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Network error, try again"));
246 show_export_on_ring_error(view);
247 break;
248 }
249 }
250 }
251 );
252
253 show_generating_pin_spinner(view);
254 if (!priv->account->exportOnRing(password))
255 {
256 QObject::disconnect(priv->export_on_ring_ended);
257 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Could not initiate export to the Ring, try again"));
258 g_debug("Could not initiate exportOnRing operation");
259 show_export_on_ring_error(view);
260 }
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400261}
262
263static void
264account_alias_changed(GtkEditable *entry, AccountGeneralTab *view)
265{
266 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
267 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
268 priv->account->setAlias(QString(gtk_editable_get_chars(entry, 0, -1)));
Stepan Salenikovich75a39172015-07-10 13:21:08 -0400269 if (priv->account->protocol() == Account::Protocol::RING)
270 priv->account->setDisplayName(gtk_entry_get_text(GTK_ENTRY(entry)));
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400271}
272
273static void
274account_hostname_changed(GtkEditable *entry, AccountGeneralTab *view)
275{
276 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
277 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
278 priv->account->setHostname(QString(gtk_editable_get_chars(entry, 0, -1)));
279}
280
281static void
282account_username_changed(GtkEditable *entry, AccountGeneralTab *view)
283{
284 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
285 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
286 priv->account->setUsername(QString(gtk_editable_get_chars(entry, 0, -1)));
287}
288
289static void
290account_password_changed(GtkEditable *entry, AccountGeneralTab *view)
291{
292 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
293 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
294 priv->account->setPassword(QString(gtk_editable_get_chars(entry, 0, -1)));
295}
296
297static void
298show_password(GtkToggleButton *checkbutton, GtkEntry *entry)
299{
300 gtk_entry_set_visibility(GTK_ENTRY(entry), gtk_toggle_button_get_active(checkbutton));
301}
302
303static void
304account_proxy_changed(GtkEditable *entry, AccountGeneralTab *view)
305{
306 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
307 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
308 priv->account->setProxy(QString(gtk_editable_get_chars(entry, 0, -1)));
309}
310
311static void
312account_mailbox_changed(GtkEditable *entry, AccountGeneralTab *view)
313{
314 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
315 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
316 priv->account->setMailbox(QString(gtk_editable_get_chars(entry, 0, -1)));
317}
318
319static void
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400320reset_change_password(AccountGeneralTab *view)
321{
322 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
323 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
324 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), "");
325 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
326}
327
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500328static void
329choose_export_file(AccountGeneralTab *view)
330{
331 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
332 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
333 // Sauvegarder path
334 GtkWidget* dialog;
335 GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
336 gint res;
337 gchar* filename = nullptr;
338
339 dialog = gtk_file_chooser_dialog_new(_("Save File"),
340 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))),
341 action,
342 _("_Cancel"),
343 GTK_RESPONSE_CANCEL,
344 _("_Save"),
345 GTK_RESPONSE_ACCEPT,
346 nullptr);
347
348 std::string alias = priv->account->alias().toLocal8Bit().constData();
349 std::string uri = alias.empty()? "export.gz" : alias + ".gz";
350 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), uri.c_str());
351 res = gtk_dialog_run (GTK_DIALOG(dialog));
352
353 if (res == GTK_RESPONSE_ACCEPT) {
354 auto chooser = GTK_FILE_CHOOSER(dialog);
355 filename = gtk_file_chooser_get_filename(chooser);
356 }
357 gtk_widget_destroy (dialog);
358
359 if (!filename) return;
360
361 // export account
362 priv->account->exportToFile(filename);
363 // Set informations label
364 std::string label = std::string(_("File exported to destination: ")) + std::string(filename);
365 gtk_label_set_text(GTK_LABEL(priv->label_export_informations), label.c_str());
366}
367
Sébastien Blin396212d2018-05-11 09:16:43 -0400368static GList*
369get_row_iterator(GtkWidget* row)
370{
371 auto box = gtk_bin_get_child(GTK_BIN(row));
372 return gtk_container_get_children(GTK_CONTAINER(box));
373}
374
375static GtkWidget*
376get_button_from_row(GtkWidget* row)
377{
378 auto* list_iterator = get_row_iterator(row);
379 auto current_child = g_list_last(list_iterator); // button
380 return GTK_WIDGET(current_child->data);
381}
382
383static GtkWidget*
384get_name_from_row(GtkWidget* row)
385{
386 auto* list_iterator = get_row_iterator(row);
387 auto* current_child = g_list_first(list_iterator); // box infos
388 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
389 current_child = g_list_first(box_devices_info); // device.name
390 return GTK_WIDGET(current_child->data);
391}
392
393static void
394replace_name_from_row(GtkWidget* row, const std::string& name, const std::string& id)
395{
396 // Remove previous informations
397 auto* list_iterator = get_row_iterator(row);
398 auto* box_info = g_list_first(list_iterator); // box infos
399 auto* action_button = g_list_last(list_iterator);
400 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(box_info->data));
401 auto* device_name = g_list_first(box_devices_info); // device.name
402 auto isEntryName = G_TYPE_CHECK_INSTANCE_TYPE(device_name->data, gtk_entry_get_type());
403 auto* label_id = g_list_next(box_devices_info); // device.name
404 gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(device_name->data));
405 gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(label_id->data));
406
407 // Rebuild item
408 if (isEntryName) {
409 auto* new_label_name = gtk_label_new(name.c_str());
410 gtk_container_add(GTK_CONTAINER(box_info->data), new_label_name);
411 gtk_widget_set_halign(GTK_WIDGET(new_label_name), GTK_ALIGN_START);
412 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/edit");
413 gtk_button_set_image(GTK_BUTTON(action_button->data), image);
414 } else {
415 auto* entry_name = gtk_entry_new();
416 gtk_entry_set_text(GTK_ENTRY(entry_name), name.c_str());
417 gtk_container_add(GTK_CONTAINER(box_info->data), entry_name);
418 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/save");
419 gtk_button_set_image(GTK_BUTTON(action_button->data), image);
420 }
421 auto* new_label_id = gtk_label_new("");
422 std::string markup = "<span font_desc=\"7.0\">" + id + "</span>";
423 gtk_label_set_markup(GTK_LABEL(new_label_id), markup.c_str());
424 gtk_container_add(GTK_CONTAINER(box_info->data), new_label_id);
425 gtk_widget_show_all(GTK_WIDGET(box_info->data));
426}
427
428static std::string
429get_id_from_row(GtkWidget* row)
430{
431 auto* list_iterator = get_row_iterator(row);
432 auto* current_child = g_list_first(list_iterator); // box infos
433 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
434 current_child = g_list_first(box_devices_info); // device.name
435 current_child = g_list_next(box_devices_info); // device.id
436 return gtk_label_get_text(GTK_LABEL(current_child->data));
437}
438
439static void
440save_name(GtkButton* button, AccountGeneralTab *view)
441{
442 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
443 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
444
445 auto row = 0;
446 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
447 if (GTK_BUTTON(get_button_from_row(children)) == button) {
448 GtkWidget* nameWidget = get_name_from_row(children);
449 auto deviceId = get_id_from_row(children);
450 if (G_TYPE_CHECK_INSTANCE_TYPE(nameWidget, gtk_entry_get_type())) {
451 std::string newName = gtk_entry_get_text(GTK_ENTRY(nameWidget));
452 replace_name_from_row(children, newName, deviceId);
453 (*priv->accountInfo_)->deviceModel->setCurrentDeviceName(newName);
454 } else {
455 std::string newName = gtk_label_get_text(GTK_LABEL(nameWidget));
456 replace_name_from_row(children, newName, deviceId);
457 }
458 }
459 ++row;
460 }
461}
462
463static void
464revoke_device(GtkButton* button, AccountGeneralTab *view)
465{
466 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
467 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
468
469 auto row = 0;
470 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
471 if (GTK_BUTTON(get_button_from_row(children)) == button) {
472 auto deviceId = get_id_from_row(children);
473 auto password = "";
474 auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
475 auto* password_dialog = gtk_message_dialog_new(top_window,
476 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
477 _("Warning! This action will revoke the device!\nNote: this action cannot be undone."));
478 gtk_window_set_title(GTK_WINDOW(password_dialog), _("Enter password to revoke device"));
479 gtk_dialog_set_default_response(GTK_DIALOG(password_dialog), GTK_RESPONSE_OK);
480
481 auto* message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(password_dialog));
482 if (priv->account->archiveHasPassword()) {
483 auto* password_entry = gtk_entry_new();
484 gtk_entry_set_visibility(GTK_ENTRY(password_entry), false);
485 gtk_entry_set_invisible_char(GTK_ENTRY(password_entry), '*');
486 gtk_box_pack_start(GTK_BOX(message_area), password_entry, true, true, 0);
487 gtk_widget_show_all(password_dialog);
488
489 auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
490 if (res == GTK_RESPONSE_OK) {
491 password = gtk_entry_get_text(GTK_ENTRY(password_entry));
492 (*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, password);
493 }
494 } else {
495 auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
496 if (res == GTK_RESPONSE_OK)
497 (*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, "");
498 }
499
500 gtk_widget_destroy(password_dialog);
501 }
502 ++row;
503 }
504}
505
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400506static void
507change_password(AccountGeneralTab *view)
508{
509 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
510 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
511
512 std::string current_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_current_password));
513 std::string new_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_new_password));
514 std::string confirm_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_confirm_password));
515 if (new_password != confirm_password) {
516 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), _("New password and its confirmation are different"));
517 return;
518 }
519 if (priv->account->changePassword(current_password.c_str(), new_password.c_str())) {
520 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), "");
521 gtk_entry_set_text(GTK_ENTRY(priv->entry_current_password), "");
522 gtk_entry_set_text(GTK_ENTRY(priv->entry_new_password), "");
523 gtk_entry_set_text(GTK_ENTRY(priv->entry_confirm_password), "");
524 // NOTE: can't use account->archiveHasPassword here, because the account is not updated.
525 gtk_widget_set_visible(priv->entry_current_password, !new_password.empty());
526 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Password changed!"));
527 } else {
528 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
529 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), _("Incorrect password"));
530 }
531
532}
533
534static void
Sébastien Blin396212d2018-05-11 09:16:43 -0400535add_device(AccountGeneralTab *view, const lrc::api::Device& device)
536{
537 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
538 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
539
540 auto* device_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
541
542 GtkStyleContext* context_box;
543 context_box = gtk_widget_get_style_context(GTK_WIDGET(device_box));
544 gtk_style_context_add_class(context_box, "device-box");
545 // Fill with devices informations
546 auto* device_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
547 auto* label_name = gtk_label_new(device.name.c_str());
548 gtk_container_add(GTK_CONTAINER(device_info_box), label_name);
549 gtk_widget_set_halign(GTK_WIDGET(label_name), GTK_ALIGN_START);
550 auto* label_id = gtk_label_new("");
551 std::string markup = "<span font_desc=\"7.0\">" + device.id + "</span>";
552 gtk_label_set_markup(GTK_LABEL(label_id), markup.c_str());
553 gtk_container_add(GTK_CONTAINER(device_info_box), label_id);
554 gtk_container_add(GTK_CONTAINER(device_box), device_info_box);
555 // Add action button
556 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/edit");
557 if (!device.isCurrent)
558 image = gtk_image_new_from_resource("/cx/ring/RingGnome/revoke");
559 auto* action_device_button = gtk_button_new();
560 gtk_widget_set_tooltip_text(action_device_button, device.isCurrent ? _("Save name") : _("Revoke device"));
561 gtk_button_set_image(GTK_BUTTON(action_device_button), image);
562 GtkStyleContext* context;
563 context = gtk_widget_get_style_context(GTK_WIDGET(action_device_button));
564 gtk_style_context_add_class(context, "transparent-button");
565 std::string label_btn = "action_btn_" + device.id;
566 gtk_widget_set_name(action_device_button, label_btn.c_str());
567 g_signal_connect(action_device_button, "clicked", device.isCurrent ? G_CALLBACK(save_name) : G_CALLBACK(revoke_device), view);
568 gtk_container_add(GTK_CONTAINER(device_box), action_device_button);
569 // Insert at the end of the list
570 gtk_list_box_insert(GTK_LIST_BOX(priv->list_devices), device_box, -1);
571}
572
573static void
574show_revokation_error_dialog(AccountGeneralTab *view, const std::string& text)
575{
576 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
577 auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
578 auto* error_dialog = gtk_message_dialog_new(top_window,
579 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
Sébastien Blincc92ae92018-06-07 11:43:00 -0400580 "%s", text.c_str());
Sébastien Blin396212d2018-05-11 09:16:43 -0400581 gtk_window_set_title(GTK_WINDOW(error_dialog), _("Error when revoking device"));
582 gtk_dialog_set_default_response(GTK_DIALOG(error_dialog), GTK_RESPONSE_OK);
583
584 gtk_dialog_run(GTK_DIALOG(error_dialog));
585 gtk_widget_destroy(error_dialog);
586}
587
588static void
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400589build_tab_view(AccountGeneralTab *view)
590{
591 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
592 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
593
Sébastien Blin396212d2018-05-11 09:16:43 -0400594 // CSS styles
595 auto provider = gtk_css_provider_new();
596 gtk_css_provider_load_from_data(provider,
597 ".transparent-button { margin-left: 10px; border: 0; background-color: rgba(0,0,0,0); margin-right: 0; padding-right: 0;}\
598 .device-box { padding: 12px; }",
599 -1, nullptr
600 );
601 gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
602 GTK_STYLE_PROVIDER(provider),
603 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
604
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400605 int grid_row = 0;
Sébastien Blin396212d2018-05-11 09:16:43 -0400606 GtkWidget* label = NULL;
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400607
608 /* separate pointers for each so that we reference them in the account changed callback */
Sébastien Blin396212d2018-05-11 09:16:43 -0400609 GtkWidget* entry_alias = NULL;
610 GtkWidget* entry_username = NULL;
611 GtkWidget* entry_hostname = NULL;
612 GtkWidget* entry_password = NULL;
613 GtkWidget* entry_proxy = NULL;
614 GtkWidget* entry_voicemail = NULL;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400615
616 /* build account grid */
617
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400618 /* account alias */
619 label = gtk_label_new(_("Alias"));
620 gtk_widget_set_halign(label, GTK_ALIGN_START);
621 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
622 entry_alias = gtk_entry_new();
623 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
624 gtk_widget_set_halign(entry_alias, GTK_ALIGN_START);
625 g_signal_connect(entry_alias, "changed", G_CALLBACK(account_alias_changed), view);
626 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_alias, 1, grid_row, 1, 1);
627 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400628
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400629 /* account type */
630 label = gtk_label_new(_("Type"));
631 gtk_widget_set_halign(label, GTK_ALIGN_START);
632 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400633
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400634 label = gtk_label_new("");
635 gtk_widget_set_halign(label, GTK_ALIGN_START);
636 switch (priv->account->protocol()) {
637 case Account::Protocol::SIP:
638 gtk_label_set_text(GTK_LABEL(label), "SIP");
639 break;
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400640 case Account::Protocol::RING:
641 gtk_label_set_text(GTK_LABEL(label), "RING");
642 break;
643 case Account::Protocol::COUNT__:
644 break;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400645 }
646
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400647 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 1, grid_row, 1, 1);
648 ++grid_row;
649
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400650 if (priv->account->protocol() == Account::Protocol::RING) {
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400651 label = gtk_label_new("RingID");
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400652 gtk_widget_set_halign(label, GTK_ALIGN_START);
653 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400654 entry_username = gtk_entry_new();
aviau2da3d9c2016-09-06 11:28:36 -0400655 gtk_widget_set_halign(entry_username, GTK_ALIGN_START);
Vladimir Stoiakin576bfb02018-09-04 00:11:13 +0300656 gtk_entry_set_placeholder_text(GTK_ENTRY(entry_username), _("auto-generating…"));
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400657 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
658 g_object_set(G_OBJECT(entry_username), "editable", FALSE, NULL);
659 g_object_set(G_OBJECT(entry_username), "max-width-chars", 50, NULL);
Houmin68293822017-05-16 12:13:55 +0800660 PangoAttrList *attrs = pango_attr_list_new();
661 PangoAttribute *font_desc = pango_attr_font_desc_new(pango_font_description_from_string("monospace"));
662 pango_attr_list_insert(attrs, font_desc);
663 gtk_entry_set_attributes(GTK_ENTRY(entry_username), attrs);
664 pango_attr_list_unref(attrs);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400665 gtk_entry_set_alignment(GTK_ENTRY(entry_username), 0.5);
666 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_username, 1, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400667 ++grid_row;
aviau2da3d9c2016-09-06 11:28:36 -0400668
aviauaf7d6bb2016-11-09 16:41:53 -0500669 label = gtk_label_new(_("Username"));
aviau2da3d9c2016-09-06 11:28:36 -0400670 gtk_widget_set_halign(label, GTK_ALIGN_START);
671 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Sébastien Blin79efc022018-06-29 11:11:09 -0400672 auto username_registration_box = username_registration_box_new(*priv->accountInfo_, TRUE);
aviau2da3d9c2016-09-06 11:28:36 -0400673 gtk_grid_attach(GTK_GRID(priv->grid_account), username_registration_box, 1, grid_row, 2, 2);
Sébastien Blin79efc022018-06-29 11:11:09 -0400674 gtk_widget_show(username_registration_box);
675
aviau2da3d9c2016-09-06 11:28:36 -0400676 grid_row+=2;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400677 }
678
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400679
680 /* build parameters grid */
681 grid_row = 0;
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400682 if (priv->account->protocol() != Account::Protocol::RING) {
Stepan Salenikovich1a468b92016-06-30 10:46:21 -0400683 /* SIP account */
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400684
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400685 /* host name */
686 label = gtk_label_new(_("Hostname"));
687 gtk_widget_set_halign(label, GTK_ALIGN_START);
688 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
689 entry_hostname = gtk_entry_new();
690 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
691 g_signal_connect(entry_hostname, "changed", G_CALLBACK(account_hostname_changed), view);
692 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_hostname, 1, grid_row, 1, 1);
693 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400694
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400695 /* user name */
696 label = gtk_label_new(_("Username"));
697 gtk_widget_set_halign(label, GTK_ALIGN_START);
698 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
699 entry_username = gtk_entry_new();
700 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
701 g_signal_connect(entry_username, "changed", G_CALLBACK(account_username_changed), view);
702 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_username, 1, grid_row, 1, 1);
703 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400704
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400705 /* password */
706 label = gtk_label_new(_("Password"));
707 gtk_widget_set_halign(label, GTK_ALIGN_START);
708 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
709 entry_password = gtk_entry_new();
710 gtk_entry_set_input_purpose(GTK_ENTRY(entry_password), GTK_INPUT_PURPOSE_PASSWORD);
711 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(entry_password), GTK_ENTRY_ICON_PRIMARY, "dialog-password");
712 gtk_entry_set_visibility(GTK_ENTRY(entry_password), FALSE);
713 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
714 g_signal_connect(entry_password, "changed", G_CALLBACK(account_password_changed), view);
715 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_password, 1, grid_row, 1, 1);
716 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400717
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400718 /* show password */
Sébastien Blin396212d2018-05-11 09:16:43 -0400719 GtkWidget* checkbutton = gtk_check_button_new_with_label(_("Show password"));
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400720 gtk_grid_attach(GTK_GRID(priv->grid_parameters), checkbutton, 1, grid_row, 1, 1);
721 g_signal_connect(checkbutton, "toggled", G_CALLBACK(show_password), entry_password);
722 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400723
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400724 /* proxy */
725 label = gtk_label_new(_("Proxy"));
726 gtk_widget_set_halign(label, GTK_ALIGN_START);
727 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
728 entry_proxy = gtk_entry_new();
729 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
730 g_signal_connect(entry_proxy, "changed", G_CALLBACK(account_proxy_changed), view);
731 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_proxy, 1, grid_row, 1, 1);
732 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400733
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400734 /* voicemail number */
735 label = gtk_label_new(_("Voicemail number"));
736 gtk_widget_set_halign(label, GTK_ALIGN_START);
737 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
738 entry_voicemail = gtk_entry_new();
739 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
740 g_signal_connect(entry_voicemail, "changed", G_CALLBACK(account_mailbox_changed), view);
741 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_voicemail, 1, grid_row, 1, 1);
742 ++grid_row;
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500743
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400744 } else {
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500745 gtk_widget_hide(priv->frame_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400746 }
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500747 gtk_widget_show_all(priv->grid_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400748
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400749 /* update account parameters if model is updated */
750 priv->account_updated = QObject::connect(
751 priv->account,
752 &Account::changed,
753 [=] () {
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400754 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
755 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400756
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400757 if (priv->account->protocol() != Account::Protocol::RING) {
aviau9bbb19b2016-05-16 15:53:44 -0400758 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400759 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
760 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
761 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400762 }
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400763 }
764 );
765
Sébastien Blin396212d2018-05-11 09:16:43 -0400766 priv->new_device_added_connection = QObject::connect(
767 &*(*priv->accountInfo_)->deviceModel,
768 &lrc::api::NewDeviceModel::deviceAdded,
769 [view] (const std::string& id) {
770 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
771 // Retrieve added device
772 auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
773 if (device.id.empty()) {
774 g_debug("Can't add device with id: %s", device.id.c_str());
775 return;
776 }
777 // if exists, add to list
778 add_device(view, device);
779 gtk_widget_show_all(priv->list_devices);
780 }
781 );
782
783 priv->device_removed_connection = QObject::connect(
784 &*(*priv->accountInfo_)->deviceModel,
785 &lrc::api::NewDeviceModel::deviceRevoked,
786 [view] (const std::string& id, const lrc::api::NewDeviceModel::Status status) {
787 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
788 auto row = 0;
789 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
790 auto deviceId = get_id_from_row(children);
791 if (deviceId == id) {
792 switch (status)
793 {
794 case lrc::api::NewDeviceModel::Status::SUCCESS:
795 // remove device's line
796 gtk_container_remove(GTK_CONTAINER(priv->list_devices), children);
797 return;
798 case lrc::api::NewDeviceModel::Status::WRONG_PASSWORD:
799 show_revokation_error_dialog(view, _("Error: wrong password!"));
800 break;
801 case lrc::api::NewDeviceModel::Status::UNKNOWN_DEVICE:
802 show_revokation_error_dialog(view, _("Error: unknown device!"));
803 break;
804 default:
805 g_debug("unknown status for revoked device. BUG?");
806 return;
807 }
808 }
809 ++row;
810 }
811 }
812 );
813
814 priv->device_updated_connection = QObject::connect(
815 &*(*priv->accountInfo_)->deviceModel,
816 &lrc::api::NewDeviceModel::deviceUpdated,
817 [view] (const std::string& id) {
818 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
819 // Retrieve added device
820 auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
821 if (device.id.empty()) {
822 g_debug("Can't add device with id: %s", device.id.c_str());
823 return;
824 }
825 // if exists, update
826 auto row = 0;
827 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
828 auto device_name = get_name_from_row(children);
829 auto deviceId = get_id_from_row(children);
830 if (deviceId == id) {
831 if (device.isCurrent) {
832 if (G_TYPE_CHECK_INSTANCE_TYPE(device_name, gtk_entry_get_type())) {
833 gtk_entry_set_text(GTK_ENTRY(device_name), device.name.c_str());
834 } else {
835 gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
836 }
837 } else {
838 gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
839 }
840 }
841 ++row;
842 }
843 g_debug("deviceUpdated signal received, but device not found");
844 }
845 );
846
847
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400848 g_signal_connect_swapped(priv->button_validate_password, "clicked", G_CALLBACK(change_password), view);
849 g_signal_connect_swapped(priv->entry_current_password, "changed", G_CALLBACK(reset_change_password), view);
850 g_signal_connect_swapped(priv->entry_new_password, "changed", G_CALLBACK(reset_change_password), view);
851 g_signal_connect_swapped(priv->entry_confirm_password, "changed", G_CALLBACK(reset_change_password), view);
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500852 g_signal_connect_swapped(priv->button_choose_file, "clicked", G_CALLBACK(choose_export_file), view);
Sébastien Blin396212d2018-05-11 09:16:43 -0400853 g_signal_connect_swapped(priv->button_add_device, "clicked", G_CALLBACK(show_add_device_view), view);
854 g_signal_connect_swapped(priv->button_add_device_cancel, "clicked", G_CALLBACK(show_account_general_view), view);
855 g_signal_connect(priv->button_export_on_the_ring, "clicked", G_CALLBACK(export_on_the_ring_clicked), view);
856 g_signal_connect_swapped(priv->button_generated_pin_ok, "clicked", G_CALLBACK(show_account_general_view), view);
857 g_signal_connect_swapped(priv->button_export_on_ring_error_ok, "clicked", G_CALLBACK(show_add_device_view), view);
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400858 gtk_widget_set_visible(priv->entry_current_password, priv->account->archiveHasPassword());
859
Sébastien Blin396212d2018-05-11 09:16:43 -0400860 if ((*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::RING) {
861 auto devices = (*priv->accountInfo_)->deviceModel->getAllDevices();
862 for (const auto& device : devices)
863 add_device(view, device);
864 gtk_widget_set_halign(GTK_WIDGET(priv->list_devices), GTK_ALIGN_CENTER);
865 gtk_widget_show_all(priv->list_devices);
866 } else {
867 gtk_widget_hide(priv->vbox_devices);
868 }
869
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400870}
871
Sébastien Blin396212d2018-05-11 09:16:43 -0400872GtkWidget*
Sébastien Blin276202f2018-05-11 09:37:34 -0400873account_general_tab_new(Account *account, AccountInfoPointer const & accountInfo)
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400874{
875 g_return_val_if_fail(account != NULL, NULL);
876
877 gpointer view = g_object_new(ACCOUNT_GENERAL_TAB_TYPE, NULL);
878
879 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
880 priv->account = account;
Sébastien Blin276202f2018-05-11 09:37:34 -0400881 priv->accountInfo_ = &accountInfo;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400882
883 build_tab_view(ACCOUNT_GENERAL_TAB(view));
884
Sébastien Blin396212d2018-05-11 09:16:43 -0400885 return (GtkWidget* )view;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400886}