blob: 4b867bd2757b0b1d8031c564114336b80a0a7b75 [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 <iostream>
32#include <api/newdevicemodel.h>
Sébastien Blin276202f2018-05-11 09:37:34 -040033#include <api/newaccountmodel.h>
34
Sébastien Blin396212d2018-05-11 09:16:43 -040035
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040036struct _AccountGeneralTab
37{
38 GtkBox parent;
39};
40
41struct _AccountGeneralTabClass
42{
43 GtkBoxClass parent_class;
44};
45
46typedef struct _AccountGeneralTabPrivate AccountGeneralTabPrivate;
47
48struct _AccountGeneralTabPrivate
49{
50 Account *account;
Sébastien Blin276202f2018-05-11 09:37:34 -040051 AccountInfoPointer const *accountInfo_;
52
Sébastien Blin396212d2018-05-11 09:16:43 -040053 GtkWidget* stack_account_general;
54 GtkWidget* account_general;
55
56 GtkWidget* grid_account;
Sébastien Blin1e191dc2018-02-28 11:14:34 -050057 GtkWidget* frame_parameters;
Sébastien Blin396212d2018-05-11 09:16:43 -040058 GtkWidget* grid_parameters;
Stepan Salenikovichbd029582015-03-24 11:00:56 -040059
Sébastien Blinc50a8a32017-09-22 10:13:12 -040060 GtkWidget* entry_current_password;
61 GtkWidget* entry_new_password;
62 GtkWidget* entry_confirm_password;
63 GtkWidget* button_validate_password;
64 GtkWidget* label_error_change_passowrd;
65
Sébastien Blinb5da5ab2018-02-27 16:46:20 -050066 GtkWidget* button_choose_file;
67 GtkWidget* label_export_informations;
68
Sébastien Blin396212d2018-05-11 09:16:43 -040069 GtkWidget* list_devices;
70 GtkWidget* vbox_devices;
71 GtkWidget* button_add_device;
72
73 /* generated_pin view */
74 GtkWidget* generated_pin;
75 GtkWidget* label_generated_pin;
76 GtkWidget* button_generated_pin_ok;
77
78 /* add_device view */
79 GtkWidget* add_device_box;
80 GtkWidget* button_export_on_the_ring;
81 GtkWidget* button_add_device_cancel;
82 GtkWidget* entry_password;
83
84 /* generating account spinner */
85 GtkWidget* vbox_generating_pin_spinner;
86
87 /* export on ring error */
88 GtkWidget* export_on_ring_error;
89 GtkWidget* label_export_on_ring_error;
90 GtkWidget* button_export_on_ring_error_ok;
91
Stepan Salenikovichbd029582015-03-24 11:00:56 -040092 QMetaObject::Connection account_updated;
Sébastien Blin396212d2018-05-11 09:16:43 -040093 QMetaObject::Connection new_device_added_connection;
94 QMetaObject::Connection device_updated_connection;
95 QMetaObject::Connection device_removed_connection;
96 QMetaObject::Connection export_on_ring_ended;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -040097};
98
99G_DEFINE_TYPE_WITH_PRIVATE(AccountGeneralTab, account_general_tab, GTK_TYPE_BOX);
100
101#define ACCOUNT_GENERAL_TAB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_GENERAL_TAB_TYPE, AccountGeneralTabPrivate))
102
103static void
104account_general_tab_dispose(GObject *object)
105{
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400106 AccountGeneralTab *view = ACCOUNT_GENERAL_TAB(object);
107 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
108
109 QObject::disconnect(priv->account_updated);
Sébastien Blin396212d2018-05-11 09:16:43 -0400110 QObject::disconnect(priv->new_device_added_connection);
111 QObject::disconnect(priv->device_updated_connection);
112 QObject::disconnect(priv->device_removed_connection);
113 QObject::disconnect(priv->export_on_ring_ended);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400114
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400115 G_OBJECT_CLASS(account_general_tab_parent_class)->dispose(object);
116}
117
118static void
119account_general_tab_init(AccountGeneralTab *view)
120{
121 gtk_widget_init_template(GTK_WIDGET(view));
122}
123
124static void
125account_general_tab_class_init(AccountGeneralTabClass *klass)
126{
127 G_OBJECT_CLASS(klass)->dispose = account_general_tab_dispose;
128
129 gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
130 "/cx/ring/RingGnome/accountgeneraltab.ui");
131
Sébastien Blin396212d2018-05-11 09:16:43 -0400132 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, stack_account_general);
133 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, account_general);
134
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400135 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_account);
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500136 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, frame_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400137 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, grid_parameters);
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400138
139 /* change password view */
140 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_current_password);
141 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_new_password);
142 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_confirm_password);
143 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_validate_password);
144 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_error_change_passowrd);
145
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500146 /* export account */
147 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_choose_file);
148 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_export_informations);
149
Sébastien Blin396212d2018-05-11 09:16:43 -0400150 // Devices
151 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, list_devices);
152 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, vbox_devices);
153 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_add_device);
154
155 // add_device view
156 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, add_device_box);
157 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_export_on_the_ring);
158 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_add_device_cancel);
159 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, entry_password);
160
161 // generating pin spinner
162 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, vbox_generating_pin_spinner);
163
164 // export on ring error
165 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, export_on_ring_error);
166 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_export_on_ring_error);
167 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_export_on_ring_error_ok);
168
169 // generated_pin view
170 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, generated_pin);
171 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, label_generated_pin);
172 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountGeneralTab, button_generated_pin_ok);
173}
174
175static void
176show_account_general_view(AccountGeneralTab *view)
177{
178 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
179 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
180 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->account_general);
181}
182
183static void
184show_add_device_view(AccountGeneralTab *view)
185{
186 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
187 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
188 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->add_device_box);
189}
190
191static void
192show_generated_pin_view(AccountGeneralTab *view)
193{
194 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
195 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
196 gtk_widget_show(priv->generated_pin);
197 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->generated_pin);
198}
199
200static void
201show_generating_pin_spinner(AccountGeneralTab *view)
202{
203 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
204 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
205 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->vbox_generating_pin_spinner);
206}
207
208static void
209show_export_on_ring_error(AccountGeneralTab *view)
210{
211 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
212 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
213 gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_general), priv->export_on_ring_error);
214}
215
216static void
217export_on_the_ring_clicked(G_GNUC_UNUSED GtkButton *button, AccountGeneralTab *view)
218{
219 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
220 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
221
222 auto password = QString(gtk_entry_get_text(GTK_ENTRY(priv->entry_password)));
223 gtk_entry_set_text(GTK_ENTRY(priv->entry_password), "");
224
225 priv->export_on_ring_ended = QObject::connect(
226 priv->account,
227 &Account::exportOnRingEnded,
228 [=] (Account::ExportOnRingStatus status, QString pin) {
229 QObject::disconnect(priv->export_on_ring_ended);
230 switch (status)
231 {
232 case Account::ExportOnRingStatus::SUCCESS:
233 {
234 gtk_label_set_text(GTK_LABEL(priv->label_generated_pin), pin.toStdString().c_str());
235 show_generated_pin_view(view);
236 break;
237 }
238 case Account::ExportOnRingStatus::WRONG_PASSWORD:
239 {
240 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Bad password"));
241 show_export_on_ring_error(view);
242 break;
243 }
244 case Account::ExportOnRingStatus::NETWORK_ERROR:
245 {
246 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Network error, try again"));
247 show_export_on_ring_error(view);
248 break;
249 }
250 }
251 }
252 );
253
254 show_generating_pin_spinner(view);
255 if (!priv->account->exportOnRing(password))
256 {
257 QObject::disconnect(priv->export_on_ring_ended);
258 gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Could not initiate export to the Ring, try again"));
259 g_debug("Could not initiate exportOnRing operation");
260 show_export_on_ring_error(view);
261 }
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400262}
263
264static void
265account_alias_changed(GtkEditable *entry, AccountGeneralTab *view)
266{
267 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
268 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
269 priv->account->setAlias(QString(gtk_editable_get_chars(entry, 0, -1)));
Stepan Salenikovich75a39172015-07-10 13:21:08 -0400270 if (priv->account->protocol() == Account::Protocol::RING)
271 priv->account->setDisplayName(gtk_entry_get_text(GTK_ENTRY(entry)));
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400272}
273
274static void
275account_hostname_changed(GtkEditable *entry, AccountGeneralTab *view)
276{
277 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
278 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
279 priv->account->setHostname(QString(gtk_editable_get_chars(entry, 0, -1)));
280}
281
282static void
283account_username_changed(GtkEditable *entry, AccountGeneralTab *view)
284{
285 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
286 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
287 priv->account->setUsername(QString(gtk_editable_get_chars(entry, 0, -1)));
288}
289
290static void
291account_password_changed(GtkEditable *entry, AccountGeneralTab *view)
292{
293 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
294 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
295 priv->account->setPassword(QString(gtk_editable_get_chars(entry, 0, -1)));
296}
297
298static void
299show_password(GtkToggleButton *checkbutton, GtkEntry *entry)
300{
301 gtk_entry_set_visibility(GTK_ENTRY(entry), gtk_toggle_button_get_active(checkbutton));
302}
303
304static void
305account_proxy_changed(GtkEditable *entry, AccountGeneralTab *view)
306{
307 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
308 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
309 priv->account->setProxy(QString(gtk_editable_get_chars(entry, 0, -1)));
310}
311
312static void
313account_mailbox_changed(GtkEditable *entry, AccountGeneralTab *view)
314{
315 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
316 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
317 priv->account->setMailbox(QString(gtk_editable_get_chars(entry, 0, -1)));
318}
319
320static void
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400321reset_change_password(AccountGeneralTab *view)
322{
323 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
324 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
325 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), "");
326 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
327}
328
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500329static void
330choose_export_file(AccountGeneralTab *view)
331{
332 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
333 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
334 // Sauvegarder path
335 GtkWidget* dialog;
336 GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
337 gint res;
338 gchar* filename = nullptr;
339
340 dialog = gtk_file_chooser_dialog_new(_("Save File"),
341 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))),
342 action,
343 _("_Cancel"),
344 GTK_RESPONSE_CANCEL,
345 _("_Save"),
346 GTK_RESPONSE_ACCEPT,
347 nullptr);
348
349 std::string alias = priv->account->alias().toLocal8Bit().constData();
350 std::string uri = alias.empty()? "export.gz" : alias + ".gz";
351 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), uri.c_str());
352 res = gtk_dialog_run (GTK_DIALOG(dialog));
353
354 if (res == GTK_RESPONSE_ACCEPT) {
355 auto chooser = GTK_FILE_CHOOSER(dialog);
356 filename = gtk_file_chooser_get_filename(chooser);
357 }
358 gtk_widget_destroy (dialog);
359
360 if (!filename) return;
361
362 // export account
363 priv->account->exportToFile(filename);
364 // Set informations label
365 std::string label = std::string(_("File exported to destination: ")) + std::string(filename);
366 gtk_label_set_text(GTK_LABEL(priv->label_export_informations), label.c_str());
367}
368
Sébastien Blin396212d2018-05-11 09:16:43 -0400369static GList*
370get_row_iterator(GtkWidget* row)
371{
372 auto box = gtk_bin_get_child(GTK_BIN(row));
373 return gtk_container_get_children(GTK_CONTAINER(box));
374}
375
376static GtkWidget*
377get_button_from_row(GtkWidget* row)
378{
379 auto* list_iterator = get_row_iterator(row);
380 auto current_child = g_list_last(list_iterator); // button
381 return GTK_WIDGET(current_child->data);
382}
383
384static GtkWidget*
385get_name_from_row(GtkWidget* row)
386{
387 auto* list_iterator = get_row_iterator(row);
388 auto* current_child = g_list_first(list_iterator); // box infos
389 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
390 current_child = g_list_first(box_devices_info); // device.name
391 return GTK_WIDGET(current_child->data);
392}
393
394static void
395replace_name_from_row(GtkWidget* row, const std::string& name, const std::string& id)
396{
397 // Remove previous informations
398 auto* list_iterator = get_row_iterator(row);
399 auto* box_info = g_list_first(list_iterator); // box infos
400 auto* action_button = g_list_last(list_iterator);
401 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(box_info->data));
402 auto* device_name = g_list_first(box_devices_info); // device.name
403 auto isEntryName = G_TYPE_CHECK_INSTANCE_TYPE(device_name->data, gtk_entry_get_type());
404 auto* label_id = g_list_next(box_devices_info); // device.name
405 gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(device_name->data));
406 gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(label_id->data));
407
408 // Rebuild item
409 if (isEntryName) {
410 auto* new_label_name = gtk_label_new(name.c_str());
411 gtk_container_add(GTK_CONTAINER(box_info->data), new_label_name);
412 gtk_widget_set_halign(GTK_WIDGET(new_label_name), GTK_ALIGN_START);
413 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/edit");
414 gtk_button_set_image(GTK_BUTTON(action_button->data), image);
415 } else {
416 auto* entry_name = gtk_entry_new();
417 gtk_entry_set_text(GTK_ENTRY(entry_name), name.c_str());
418 gtk_container_add(GTK_CONTAINER(box_info->data), entry_name);
419 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/save");
420 gtk_button_set_image(GTK_BUTTON(action_button->data), image);
421 }
422 auto* new_label_id = gtk_label_new("");
423 std::string markup = "<span font_desc=\"7.0\">" + id + "</span>";
424 gtk_label_set_markup(GTK_LABEL(new_label_id), markup.c_str());
425 gtk_container_add(GTK_CONTAINER(box_info->data), new_label_id);
426 gtk_widget_show_all(GTK_WIDGET(box_info->data));
427}
428
429static std::string
430get_id_from_row(GtkWidget* row)
431{
432 auto* list_iterator = get_row_iterator(row);
433 auto* current_child = g_list_first(list_iterator); // box infos
434 auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
435 current_child = g_list_first(box_devices_info); // device.name
436 current_child = g_list_next(box_devices_info); // device.id
437 return gtk_label_get_text(GTK_LABEL(current_child->data));
438}
439
440static void
441save_name(GtkButton* button, AccountGeneralTab *view)
442{
443 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
444 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
445
446 auto row = 0;
447 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
448 if (GTK_BUTTON(get_button_from_row(children)) == button) {
449 GtkWidget* nameWidget = get_name_from_row(children);
450 auto deviceId = get_id_from_row(children);
451 if (G_TYPE_CHECK_INSTANCE_TYPE(nameWidget, gtk_entry_get_type())) {
452 std::string newName = gtk_entry_get_text(GTK_ENTRY(nameWidget));
453 replace_name_from_row(children, newName, deviceId);
454 (*priv->accountInfo_)->deviceModel->setCurrentDeviceName(newName);
455 } else {
456 std::string newName = gtk_label_get_text(GTK_LABEL(nameWidget));
457 replace_name_from_row(children, newName, deviceId);
458 }
459 }
460 ++row;
461 }
462}
463
464static void
465revoke_device(GtkButton* button, AccountGeneralTab *view)
466{
467 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
468 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
469
470 auto row = 0;
471 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
472 if (GTK_BUTTON(get_button_from_row(children)) == button) {
473 auto deviceId = get_id_from_row(children);
474 auto password = "";
475 auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
476 auto* password_dialog = gtk_message_dialog_new(top_window,
477 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
478 _("Warning! This action will revoke the device!\nNote: this action cannot be undone."));
479 gtk_window_set_title(GTK_WINDOW(password_dialog), _("Enter password to revoke device"));
480 gtk_dialog_set_default_response(GTK_DIALOG(password_dialog), GTK_RESPONSE_OK);
481
482 auto* message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(password_dialog));
483 if (priv->account->archiveHasPassword()) {
484 auto* password_entry = gtk_entry_new();
485 gtk_entry_set_visibility(GTK_ENTRY(password_entry), false);
486 gtk_entry_set_invisible_char(GTK_ENTRY(password_entry), '*');
487 gtk_box_pack_start(GTK_BOX(message_area), password_entry, true, true, 0);
488 gtk_widget_show_all(password_dialog);
489
490 auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
491 if (res == GTK_RESPONSE_OK) {
492 password = gtk_entry_get_text(GTK_ENTRY(password_entry));
493 (*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, password);
494 }
495 } else {
496 auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
497 if (res == GTK_RESPONSE_OK)
498 (*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, "");
499 }
500
501 gtk_widget_destroy(password_dialog);
502 }
503 ++row;
504 }
505}
506
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400507static void
508change_password(AccountGeneralTab *view)
509{
510 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
511 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
512
513 std::string current_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_current_password));
514 std::string new_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_new_password));
515 std::string confirm_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_confirm_password));
516 if (new_password != confirm_password) {
517 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), _("New password and its confirmation are different"));
518 return;
519 }
520 if (priv->account->changePassword(current_password.c_str(), new_password.c_str())) {
521 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), "");
522 gtk_entry_set_text(GTK_ENTRY(priv->entry_current_password), "");
523 gtk_entry_set_text(GTK_ENTRY(priv->entry_new_password), "");
524 gtk_entry_set_text(GTK_ENTRY(priv->entry_confirm_password), "");
525 // NOTE: can't use account->archiveHasPassword here, because the account is not updated.
526 gtk_widget_set_visible(priv->entry_current_password, !new_password.empty());
527 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Password changed!"));
528 } else {
529 gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
530 gtk_label_set_text(GTK_LABEL(priv->label_error_change_passowrd), _("Incorrect password"));
531 }
532
533}
534
535static void
Sébastien Blin396212d2018-05-11 09:16:43 -0400536add_device(AccountGeneralTab *view, const lrc::api::Device& device)
537{
538 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
539 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
540
541 auto* device_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
542
543 GtkStyleContext* context_box;
544 context_box = gtk_widget_get_style_context(GTK_WIDGET(device_box));
545 gtk_style_context_add_class(context_box, "device-box");
546 // Fill with devices informations
547 auto* device_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
548 auto* label_name = gtk_label_new(device.name.c_str());
549 gtk_container_add(GTK_CONTAINER(device_info_box), label_name);
550 gtk_widget_set_halign(GTK_WIDGET(label_name), GTK_ALIGN_START);
551 auto* label_id = gtk_label_new("");
552 std::string markup = "<span font_desc=\"7.0\">" + device.id + "</span>";
553 gtk_label_set_markup(GTK_LABEL(label_id), markup.c_str());
554 gtk_container_add(GTK_CONTAINER(device_info_box), label_id);
555 gtk_container_add(GTK_CONTAINER(device_box), device_info_box);
556 // Add action button
557 auto image = gtk_image_new_from_resource("/cx/ring/RingGnome/edit");
558 if (!device.isCurrent)
559 image = gtk_image_new_from_resource("/cx/ring/RingGnome/revoke");
560 auto* action_device_button = gtk_button_new();
561 gtk_widget_set_tooltip_text(action_device_button, device.isCurrent ? _("Save name") : _("Revoke device"));
562 gtk_button_set_image(GTK_BUTTON(action_device_button), image);
563 GtkStyleContext* context;
564 context = gtk_widget_get_style_context(GTK_WIDGET(action_device_button));
565 gtk_style_context_add_class(context, "transparent-button");
566 std::string label_btn = "action_btn_" + device.id;
567 gtk_widget_set_name(action_device_button, label_btn.c_str());
568 g_signal_connect(action_device_button, "clicked", device.isCurrent ? G_CALLBACK(save_name) : G_CALLBACK(revoke_device), view);
569 gtk_container_add(GTK_CONTAINER(device_box), action_device_button);
570 // Insert at the end of the list
571 gtk_list_box_insert(GTK_LIST_BOX(priv->list_devices), device_box, -1);
572}
573
574static void
575show_revokation_error_dialog(AccountGeneralTab *view, const std::string& text)
576{
577 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
578 auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
579 auto* error_dialog = gtk_message_dialog_new(top_window,
580 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
Sébastien Blincc92ae92018-06-07 11:43:00 -0400581 "%s", text.c_str());
Sébastien Blin396212d2018-05-11 09:16:43 -0400582 gtk_window_set_title(GTK_WINDOW(error_dialog), _("Error when revoking device"));
583 gtk_dialog_set_default_response(GTK_DIALOG(error_dialog), GTK_RESPONSE_OK);
584
585 gtk_dialog_run(GTK_DIALOG(error_dialog));
586 gtk_widget_destroy(error_dialog);
587}
588
589static void
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400590build_tab_view(AccountGeneralTab *view)
591{
592 g_return_if_fail(IS_ACCOUNT_GENERAL_TAB(view));
593 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
594
Sébastien Blin396212d2018-05-11 09:16:43 -0400595 // CSS styles
596 auto provider = gtk_css_provider_new();
597 gtk_css_provider_load_from_data(provider,
598 ".transparent-button { margin-left: 10px; border: 0; background-color: rgba(0,0,0,0); margin-right: 0; padding-right: 0;}\
599 .device-box { padding: 12px; }",
600 -1, nullptr
601 );
602 gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
603 GTK_STYLE_PROVIDER(provider),
604 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
605
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400606 int grid_row = 0;
Sébastien Blin396212d2018-05-11 09:16:43 -0400607 GtkWidget* label = NULL;
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400608
609 /* separate pointers for each so that we reference them in the account changed callback */
Sébastien Blin396212d2018-05-11 09:16:43 -0400610 GtkWidget* entry_alias = NULL;
611 GtkWidget* entry_username = NULL;
612 GtkWidget* entry_hostname = NULL;
613 GtkWidget* entry_password = NULL;
614 GtkWidget* entry_proxy = NULL;
615 GtkWidget* entry_voicemail = NULL;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400616
617 /* build account grid */
618
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400619 /* account alias */
620 label = gtk_label_new(_("Alias"));
621 gtk_widget_set_halign(label, GTK_ALIGN_START);
622 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
623 entry_alias = gtk_entry_new();
624 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
625 gtk_widget_set_halign(entry_alias, GTK_ALIGN_START);
626 g_signal_connect(entry_alias, "changed", G_CALLBACK(account_alias_changed), view);
627 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_alias, 1, grid_row, 1, 1);
628 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400629
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400630 /* account type */
631 label = gtk_label_new(_("Type"));
632 gtk_widget_set_halign(label, GTK_ALIGN_START);
633 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400634
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400635 label = gtk_label_new("");
636 gtk_widget_set_halign(label, GTK_ALIGN_START);
637 switch (priv->account->protocol()) {
638 case Account::Protocol::SIP:
639 gtk_label_set_text(GTK_LABEL(label), "SIP");
640 break;
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400641 case Account::Protocol::RING:
642 gtk_label_set_text(GTK_LABEL(label), "RING");
643 break;
644 case Account::Protocol::COUNT__:
645 break;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400646 }
647
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400648 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 1, grid_row, 1, 1);
649 ++grid_row;
650
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400651 if (priv->account->protocol() == Account::Protocol::RING) {
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400652 label = gtk_label_new("RingID");
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400653 gtk_widget_set_halign(label, GTK_ALIGN_START);
654 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400655 entry_username = gtk_entry_new();
aviau2da3d9c2016-09-06 11:28:36 -0400656 gtk_widget_set_halign(entry_username, GTK_ALIGN_START);
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -0400657 gtk_entry_set_placeholder_text(GTK_ENTRY(entry_username), _("auto-generating..."));
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400658 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
659 g_object_set(G_OBJECT(entry_username), "editable", FALSE, NULL);
660 g_object_set(G_OBJECT(entry_username), "max-width-chars", 50, NULL);
Houmin68293822017-05-16 12:13:55 +0800661 PangoAttrList *attrs = pango_attr_list_new();
662 PangoAttribute *font_desc = pango_attr_font_desc_new(pango_font_description_from_string("monospace"));
663 pango_attr_list_insert(attrs, font_desc);
664 gtk_entry_set_attributes(GTK_ENTRY(entry_username), attrs);
665 pango_attr_list_unref(attrs);
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400666 gtk_entry_set_alignment(GTK_ENTRY(entry_username), 0.5);
667 gtk_grid_attach(GTK_GRID(priv->grid_account), entry_username, 1, grid_row, 1, 1);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400668 ++grid_row;
aviau2da3d9c2016-09-06 11:28:36 -0400669
aviauaf7d6bb2016-11-09 16:41:53 -0500670 label = gtk_label_new(_("Username"));
aviau2da3d9c2016-09-06 11:28:36 -0400671 gtk_widget_set_halign(label, GTK_ALIGN_START);
672 gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
Sébastien Blin79efc022018-06-29 11:11:09 -0400673 gtk_widget_show_all(priv->grid_account);
674
675 auto username_registration_box = username_registration_box_new(*priv->accountInfo_, TRUE);
aviau2da3d9c2016-09-06 11:28:36 -0400676 gtk_grid_attach(GTK_GRID(priv->grid_account), username_registration_box, 1, grid_row, 2, 2);
Sébastien Blin79efc022018-06-29 11:11:09 -0400677 gtk_widget_show(username_registration_box);
678
aviau2da3d9c2016-09-06 11:28:36 -0400679 grid_row+=2;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400680 }
681
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400682
683 /* build parameters grid */
684 grid_row = 0;
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400685 if (priv->account->protocol() != Account::Protocol::RING) {
Stepan Salenikovich1a468b92016-06-30 10:46:21 -0400686 /* SIP account */
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400687
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400688 /* host name */
689 label = gtk_label_new(_("Hostname"));
690 gtk_widget_set_halign(label, GTK_ALIGN_START);
691 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
692 entry_hostname = gtk_entry_new();
693 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
694 g_signal_connect(entry_hostname, "changed", G_CALLBACK(account_hostname_changed), view);
695 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_hostname, 1, grid_row, 1, 1);
696 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400697
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400698 /* user name */
699 label = gtk_label_new(_("Username"));
700 gtk_widget_set_halign(label, GTK_ALIGN_START);
701 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
702 entry_username = gtk_entry_new();
703 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
704 g_signal_connect(entry_username, "changed", G_CALLBACK(account_username_changed), view);
705 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_username, 1, grid_row, 1, 1);
706 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400707
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400708 /* password */
709 label = gtk_label_new(_("Password"));
710 gtk_widget_set_halign(label, GTK_ALIGN_START);
711 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
712 entry_password = gtk_entry_new();
713 gtk_entry_set_input_purpose(GTK_ENTRY(entry_password), GTK_INPUT_PURPOSE_PASSWORD);
714 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(entry_password), GTK_ENTRY_ICON_PRIMARY, "dialog-password");
715 gtk_entry_set_visibility(GTK_ENTRY(entry_password), FALSE);
716 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
717 g_signal_connect(entry_password, "changed", G_CALLBACK(account_password_changed), view);
718 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_password, 1, grid_row, 1, 1);
719 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400720
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400721 /* show password */
Sébastien Blin396212d2018-05-11 09:16:43 -0400722 GtkWidget* checkbutton = gtk_check_button_new_with_label(_("Show password"));
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400723 gtk_grid_attach(GTK_GRID(priv->grid_parameters), checkbutton, 1, grid_row, 1, 1);
724 g_signal_connect(checkbutton, "toggled", G_CALLBACK(show_password), entry_password);
725 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400726
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400727 /* proxy */
728 label = gtk_label_new(_("Proxy"));
729 gtk_widget_set_halign(label, GTK_ALIGN_START);
730 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
731 entry_proxy = gtk_entry_new();
732 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
733 g_signal_connect(entry_proxy, "changed", G_CALLBACK(account_proxy_changed), view);
734 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_proxy, 1, grid_row, 1, 1);
735 ++grid_row;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400736
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400737 /* voicemail number */
738 label = gtk_label_new(_("Voicemail number"));
739 gtk_widget_set_halign(label, GTK_ALIGN_START);
740 gtk_grid_attach(GTK_GRID(priv->grid_parameters), label, 0, grid_row, 1, 1);
741 entry_voicemail = gtk_entry_new();
742 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
743 g_signal_connect(entry_voicemail, "changed", G_CALLBACK(account_mailbox_changed), view);
744 gtk_grid_attach(GTK_GRID(priv->grid_parameters), entry_voicemail, 1, grid_row, 1, 1);
745 ++grid_row;
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500746
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400747 } else {
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500748 gtk_widget_hide(priv->frame_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400749 }
Sébastien Blin1e191dc2018-02-28 11:14:34 -0500750 gtk_widget_show_all(priv->grid_parameters);
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400751
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400752 /* update account parameters if model is updated */
753 priv->account_updated = QObject::connect(
754 priv->account,
755 &Account::changed,
756 [=] () {
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400757 gtk_entry_set_text(GTK_ENTRY(entry_alias), priv->account->alias().toLocal8Bit().constData());
758 gtk_entry_set_text(GTK_ENTRY(entry_username), priv->account->username().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400759
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400760 if (priv->account->protocol() != Account::Protocol::RING) {
aviau9bbb19b2016-05-16 15:53:44 -0400761 gtk_entry_set_text(GTK_ENTRY(entry_hostname), priv->account->hostname().toLocal8Bit().constData());
Stepan Salenikovichfea84052016-05-13 16:32:51 -0400762 gtk_entry_set_text(GTK_ENTRY(entry_password), priv->account->password().toLocal8Bit().constData());
763 gtk_entry_set_text(GTK_ENTRY(entry_proxy), priv->account->proxy().toLocal8Bit().constData());
764 gtk_entry_set_text(GTK_ENTRY(entry_voicemail), priv->account->mailbox().toLocal8Bit().constData());
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400765 }
Stepan Salenikovichbd029582015-03-24 11:00:56 -0400766 }
767 );
768
Sébastien Blin396212d2018-05-11 09:16:43 -0400769 priv->new_device_added_connection = QObject::connect(
770 &*(*priv->accountInfo_)->deviceModel,
771 &lrc::api::NewDeviceModel::deviceAdded,
772 [view] (const std::string& id) {
773 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
774 // Retrieve added device
775 auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
776 if (device.id.empty()) {
777 g_debug("Can't add device with id: %s", device.id.c_str());
778 return;
779 }
780 // if exists, add to list
781 add_device(view, device);
782 gtk_widget_show_all(priv->list_devices);
783 }
784 );
785
786 priv->device_removed_connection = QObject::connect(
787 &*(*priv->accountInfo_)->deviceModel,
788 &lrc::api::NewDeviceModel::deviceRevoked,
789 [view] (const std::string& id, const lrc::api::NewDeviceModel::Status status) {
790 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
791 auto row = 0;
792 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
793 auto deviceId = get_id_from_row(children);
794 if (deviceId == id) {
795 switch (status)
796 {
797 case lrc::api::NewDeviceModel::Status::SUCCESS:
798 // remove device's line
799 gtk_container_remove(GTK_CONTAINER(priv->list_devices), children);
800 return;
801 case lrc::api::NewDeviceModel::Status::WRONG_PASSWORD:
802 show_revokation_error_dialog(view, _("Error: wrong password!"));
803 break;
804 case lrc::api::NewDeviceModel::Status::UNKNOWN_DEVICE:
805 show_revokation_error_dialog(view, _("Error: unknown device!"));
806 break;
807 default:
808 g_debug("unknown status for revoked device. BUG?");
809 return;
810 }
811 }
812 ++row;
813 }
814 }
815 );
816
817 priv->device_updated_connection = QObject::connect(
818 &*(*priv->accountInfo_)->deviceModel,
819 &lrc::api::NewDeviceModel::deviceUpdated,
820 [view] (const std::string& id) {
821 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
822 // Retrieve added device
823 auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
824 if (device.id.empty()) {
825 g_debug("Can't add device with id: %s", device.id.c_str());
826 return;
827 }
828 // if exists, update
829 auto row = 0;
830 while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
831 auto device_name = get_name_from_row(children);
832 auto deviceId = get_id_from_row(children);
833 if (deviceId == id) {
834 if (device.isCurrent) {
835 if (G_TYPE_CHECK_INSTANCE_TYPE(device_name, gtk_entry_get_type())) {
836 gtk_entry_set_text(GTK_ENTRY(device_name), device.name.c_str());
837 } else {
838 gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
839 }
840 } else {
841 gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
842 }
843 }
844 ++row;
845 }
846 g_debug("deviceUpdated signal received, but device not found");
847 }
848 );
849
850
Sébastien Blinc50a8a32017-09-22 10:13:12 -0400851 g_signal_connect_swapped(priv->button_validate_password, "clicked", G_CALLBACK(change_password), view);
852 g_signal_connect_swapped(priv->entry_current_password, "changed", G_CALLBACK(reset_change_password), view);
853 g_signal_connect_swapped(priv->entry_new_password, "changed", G_CALLBACK(reset_change_password), view);
854 g_signal_connect_swapped(priv->entry_confirm_password, "changed", G_CALLBACK(reset_change_password), view);
Sébastien Blinb5da5ab2018-02-27 16:46:20 -0500855 g_signal_connect_swapped(priv->button_choose_file, "clicked", G_CALLBACK(choose_export_file), view);
Sébastien Blin396212d2018-05-11 09:16:43 -0400856 g_signal_connect_swapped(priv->button_add_device, "clicked", G_CALLBACK(show_add_device_view), view);
857 g_signal_connect_swapped(priv->button_add_device_cancel, "clicked", G_CALLBACK(show_account_general_view), view);
858 g_signal_connect(priv->button_export_on_the_ring, "clicked", G_CALLBACK(export_on_the_ring_clicked), view);
859 g_signal_connect_swapped(priv->button_generated_pin_ok, "clicked", G_CALLBACK(show_account_general_view), view);
860 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 -0400861 gtk_widget_set_visible(priv->entry_current_password, priv->account->archiveHasPassword());
862
Sébastien Blin396212d2018-05-11 09:16:43 -0400863 if ((*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::RING) {
864 auto devices = (*priv->accountInfo_)->deviceModel->getAllDevices();
865 for (const auto& device : devices)
866 add_device(view, device);
867 gtk_widget_set_halign(GTK_WIDGET(priv->list_devices), GTK_ALIGN_CENTER);
868 gtk_widget_show_all(priv->list_devices);
869 } else {
870 gtk_widget_hide(priv->vbox_devices);
871 }
872
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400873}
874
Sébastien Blin396212d2018-05-11 09:16:43 -0400875GtkWidget*
Sébastien Blin276202f2018-05-11 09:37:34 -0400876account_general_tab_new(Account *account, AccountInfoPointer const & accountInfo)
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400877{
878 g_return_val_if_fail(account != NULL, NULL);
879
880 gpointer view = g_object_new(ACCOUNT_GENERAL_TAB_TYPE, NULL);
881
882 AccountGeneralTabPrivate *priv = ACCOUNT_GENERAL_TAB_GET_PRIVATE(view);
883 priv->account = account;
Sébastien Blin276202f2018-05-11 09:37:34 -0400884 priv->accountInfo_ = &accountInfo;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400885
886 build_tab_view(ACCOUNT_GENERAL_TAB(view));
887
Sébastien Blin396212d2018-05-11 09:16:43 -0400888 return (GtkWidget* )view;
Stepan Salenikovich61cbab02015-03-16 18:35:10 -0400889}