blob: bfbafdd2471093046677d1d9f4e009d9592ec591 [file] [log] [blame]
/*
* Copyright (C) 2015-2018 Savoir-faire Linux Inc.
* Author: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU NewAccount Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU NewAccount Public License for more details.
*
* You should have received a copy of the GNU NewAccount Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "newaccountsettingsview.h"
// std
#include <string>
// GTK+ related
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib.h>
// Lrc
#include <api/newdevicemodel.h>
#include <api/contactmodel.h>
#include <api/contact.h>
#include <api/newaccountmodel.h>
#include <api/newcodecmodel.h>
// Ring client
#include "avatarmanipulation.h"
#include "defines.h"
#include "utils/files.h"
#include "usernameregistrationbox.h"
enum
{
PROP_RING_MAIN_WIN_PNT = 1,
};
struct _NewAccountSettingsView
{
GtkScrolledWindow parent;
};
struct _NewAccountSettingsViewClass
{
GtkScrolledWindowClass parent_class;
};
typedef struct _NewAccountSettingsViewPrivate NewAccountSettingsViewPrivate;
struct _NewAccountSettingsViewPrivate
{
AccountInfoPointer const *accountInfo_ = nullptr;
lrc::api::account::ConfProperties_t* currentProp_ = nullptr;
GSettings *settings;
GtkWidget* stack_account;
GtkWidget* general_settings_box;
GtkWidget* sip_account_enabled;
GtkWidget* account_enabled;
GtkWidget* sip_label_status;
GtkWidget* label_status;
GtkWidget* avatar_box;
GtkWidget* avatarmanipulation;
GtkWidget* entry_display_name;
GtkWidget* label_id;
GtkWidget* label_username;
GtkWidget* label_password;
GtkWidget* account_options_box;
GtkWidget* type_box;
GtkWidget* label_type_info;
GtkWidget* username_box;
GtkWidget* password_row;
GtkWidget* label_change_password;
GtkWidget* sip_info_box;
GtkWidget* entry_sip_hostname;
GtkWidget* entry_sip_username;
GtkWidget* entry_sip_password;
GtkWidget* entry_sip_proxy;
GtkWidget* entry_sip_voicemail;
GtkWidget* sip_enable_account;
GtkWidget* vbox_devices;
GtkWidget* list_devices;
GtkWidget* vbox_banned_contacts;
GtkWidget* scrolled_window_banned_contacts;
GtkWidget* list_banned_contacts;
GtkWidget* button_show_banned;
GtkWidget* vbox_change_password;
GtkWidget* entry_current_password;
GtkWidget* entry_new_password;
GtkWidget* entry_confirm_password;
GtkWidget* button_validate_password;
GtkWidget* label_error_change_password;
GtkWidget* change_password_dialog;
GtkWidget* button_export_account;
GtkWidget* button_delete_account;
GtkWidget* sip_button_delete_account;
GtkWidget* button_advanced_settings;
GtkWidget* advanced_settings_box;
GtkWidget* button_general_settings;
GtkWidget* allow_call_row;
GtkWidget* call_allow_button;
GtkWidget* auto_answer_button;
GtkWidget* custom_ringtone_button;
GtkWidget* filechooserbutton_custom_ringtone;
GtkWidget* box_name_server;
GtkWidget* entry_name_server;
GtkWidget* box_dht;
GtkWidget* entry_dht_proxy;
GtkWidget* dht_proxy_button;
GtkWidget* entry_bootstrap;
GtkWidget* sip_encrypt_media_row;
GtkWidget* sip_encrypt_media;
GtkWidget* sip_key_exchange_row;
GtkWidget* enable_sdes;
GtkWidget* sip_fallback_rtp_row;
GtkWidget* sip_fallback_rtp;
GtkWidget* sip_encrypt_negotiation;
GtkWidget* sip_enable_TLS;
GtkWidget* sip_verify_certs_server_row;
GtkWidget* sip_verify_certs_server;
GtkWidget* sip_verify_certs_client_row;
GtkWidget* sip_verify_certs_client;
GtkWidget* sip_require_incoming_tls_certs_row;
GtkWidget* sip_require_incoming_tls_certs;
GtkWidget* sip_tls_protocol_row;
GtkWidget* combobox_tls_protocol_method;
GtkWidget* sip_tls_server_name_row;
GtkWidget* entry_tls_server_name;
GtkWidget* sip_negotiation_timeout_row;
GtkWidget* spinbutton_negotiation_timeout;
GtkWidget* filechooserbutton_ca_list;
GtkWidget* filechooserbutton_certificate;
GtkWidget* filechooserbutton_private_key;
GtkWidget* entry_password;
GtkWidget* sip_registration_expire_row;
GtkWidget* spinbutton_registration_timeout;
GtkWidget* sip_network_interface_row;
GtkWidget* spinbutton_network_interface;
GtkWidget* upnp_button;
GtkWidget* switch_use_turn;
GtkWidget* entry_turnserver;
GtkWidget* entry_turnusername;
GtkWidget* entry_turnpassword;
GtkWidget* entry_turnrealm;
GtkWidget* switch_use_stun;
GtkWidget* entry_stunserver;
GtkWidget* box_published_address;
GtkWidget* button_custom_published;
GtkWidget* entry_published_address;
GtkWidget* spinbutton_published_port;
GtkWidget* list_video_codecs;
GtkWidget* button_up_video;
GtkWidget* button_down_video;
GtkWidget* switch_enable_video;
GtkWidget* list_audio_codecs;
GtkWidget* button_up_audio;
GtkWidget* button_down_audio;
GtkWidget* box_sdp_session;
GtkWidget* spinbutton_audio_rtp_min;
GtkWidget* spinbutton_audio_rtp_max;
GtkWidget* spinbutton_video_rtp_min;
GtkWidget* spinbutton_video_rtp_max;
// Link
GtkWidget* button_add_device;
/* generated_pin view */
GtkWidget* generated_pin;
GtkWidget* label_generated_pin;
GtkWidget* button_generated_pin_ok;
/* add_device view */
GtkWidget* add_device_box;
GtkWidget* button_export_on_the_ring;
GtkWidget* button_add_device_cancel;
GtkWidget* entry_password_export;
/* generating account spinner */
GtkWidget* vbox_generating_pin_spinner;
/* export on ring error */
GtkWidget* export_on_ring_error;
GtkWidget* label_export_on_ring_error;
GtkWidget* button_export_on_ring_error_ok;
QMetaObject::Connection new_device_added_connection;
QMetaObject::Connection device_updated_connection;
QMetaObject::Connection device_removed_connection;
QMetaObject::Connection banned_status_changed_connection;
QMetaObject::Connection export_on_ring_ended;
};
G_DEFINE_TYPE_WITH_PRIVATE(NewAccountSettingsView, new_account_settings_view, GTK_TYPE_SCROLLED_WINDOW);
#define NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NEW_ACCOUNT_SETTINGS_VIEW_TYPE, NewAccountSettingsViewPrivate))
static void draw_codecs(NewAccountSettingsView* view, int codecSelected = -1);
static void
new_account_settings_view_dispose(GObject *object)
{
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(object);
g_clear_object(&priv->settings);
if (priv->currentProp_) {
delete priv->currentProp_;
priv->currentProp_ = nullptr;
}
QObject::disconnect(priv->new_device_added_connection);
QObject::disconnect(priv->device_updated_connection);
QObject::disconnect(priv->device_removed_connection);
QObject::disconnect(priv->banned_status_changed_connection);
QObject::disconnect(priv->export_on_ring_ended);
// make sure the VideoWidget is destroyed
new_account_settings_view_show(NEW_ACCOUNT_SETTINGS_VIEW(object), FALSE);
G_OBJECT_CLASS(new_account_settings_view_parent_class)->dispose(object);
}
static void
new_account_settings_view_init(NewAccountSettingsView *self)
{
gtk_widget_init_template(GTK_WIDGET(self));
}
static void
new_account_settings_view_class_init(NewAccountSettingsViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->dispose = new_account_settings_view_dispose;
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(klass),
"/cx/ring/RingGnome/newaccountsettingsview.ui");
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, stack_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, general_settings_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, account_enabled);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_account_enabled);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_label_status);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_status);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, avatar_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_id);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_username);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_password);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_display_name);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, account_options_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, type_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_type_info);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, username_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, password_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_change_password);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_info_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_sip_hostname);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_sip_username);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_sip_password);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_sip_proxy);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_sip_voicemail);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_enable_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, vbox_devices);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, list_devices);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, vbox_banned_contacts);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, scrolled_window_banned_contacts);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, list_banned_contacts);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_show_banned);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_export_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_delete_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_button_delete_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_advanced_settings);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, advanced_settings_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_general_settings);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, allow_call_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, call_allow_button);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, auto_answer_button);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, custom_ringtone_button);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, filechooserbutton_custom_ringtone);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, box_name_server);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_name_server);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, box_dht);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_dht_proxy);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_bootstrap);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, dht_proxy_button);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_encrypt_media_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_encrypt_media);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_key_exchange_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, enable_sdes);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_fallback_rtp_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_fallback_rtp);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_encrypt_negotiation);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_enable_TLS);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_verify_certs_server_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_verify_certs_server);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_verify_certs_client_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_verify_certs_client);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_require_incoming_tls_certs_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_require_incoming_tls_certs);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_tls_protocol_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, combobox_tls_protocol_method);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_tls_server_name_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_tls_server_name);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_negotiation_timeout_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_negotiation_timeout);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, filechooserbutton_ca_list);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, filechooserbutton_certificate);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, filechooserbutton_private_key);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_password);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_registration_expire_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_registration_timeout);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, sip_network_interface_row);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_network_interface);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, upnp_button);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, switch_use_turn);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_turnserver);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_turnusername);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_turnpassword);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_turnrealm);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, switch_use_stun);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_stunserver);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, box_published_address);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_custom_published);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_published_address);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_published_port);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, list_video_codecs);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_up_video);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_down_video);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, switch_enable_video);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, list_audio_codecs);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_up_audio);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_down_audio);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, box_sdp_session);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_audio_rtp_min);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_audio_rtp_max);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_video_rtp_min);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, spinbutton_video_rtp_max);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_add_device);
// add_device view
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, add_device_box);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_export_on_the_ring);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_add_device_cancel);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, entry_password_export);
// generating pin spinner
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, vbox_generating_pin_spinner);
// export on ring error
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, export_on_ring_error);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_export_on_ring_error);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_export_on_ring_error_ok);
// generated_pin view
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, generated_pin);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, label_generated_pin);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), NewAccountSettingsView, button_generated_pin_ok);
}
static void
show_advanced_settings(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_show(GTK_WIDGET(priv->advanced_settings_box));
gtk_widget_hide(GTK_WIDGET(priv->general_settings_box));
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->advanced_settings_box);
}
static void
show_general_settings(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_hide(GTK_WIDGET(priv->advanced_settings_box));
gtk_widget_show(GTK_WIDGET(priv->general_settings_box));
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->general_settings_box);
}
static void
show_generated_pin_view(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_show(priv->generated_pin);
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->generated_pin);
}
static void
show_generating_pin_spinner(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_show(priv->vbox_generating_pin_spinner);
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->vbox_generating_pin_spinner);
}
static void
show_export_on_ring_error(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_show(priv->export_on_ring_error);
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->export_on_ring_error);
}
// Edit general
// TODO(sblin) expliquer le return false
static bool
is_config_ok(NewAccountSettingsView *view) {
g_return_val_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view), false);
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
if (!priv->currentProp_) {
g_debug("Can't get current properties for this account");
return false;
}
return true;
}
gboolean
update_display_name(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
(*priv->accountInfo_)->accountModel->setAlias((*priv->accountInfo_)->id, gtk_entry_get_text(GTK_ENTRY(priv->entry_display_name)));
new_account_settings_view_save_account(view);
return false;
}
gboolean
update_sip_hostname(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->currentProp_->hostname = gtk_entry_get_text(GTK_ENTRY(priv->entry_sip_hostname));
new_account_settings_view_save_account(view);
return false;
}
gboolean
update_sip_username(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->currentProp_->username = gtk_entry_get_text(GTK_ENTRY(priv->entry_sip_username));
new_account_settings_view_save_account(view);
return false;
}
gboolean
update_sip_password(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->currentProp_->password = gtk_entry_get_text(GTK_ENTRY(priv->entry_sip_password));
new_account_settings_view_save_account(view);
return false;
}
gboolean
update_sip_proxy(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->currentProp_->routeset = gtk_entry_get_text(GTK_ENTRY(priv->entry_sip_proxy));
new_account_settings_view_save_account(view);
return false;
}
gboolean
update_sip_voicemail(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->currentProp_->mailbox = gtk_entry_get_text(GTK_ENTRY(priv->entry_sip_voicemail));
new_account_settings_view_save_account(view);
return false;
}
// Device related
static GList*
get_row_iterator(GtkWidget* row)
{
auto box = gtk_bin_get_child(GTK_BIN(row));
return gtk_container_get_children(GTK_CONTAINER(box));
}
static GtkWidget*
get_button_from_row(GtkWidget* row)
{
auto* list_iterator = get_row_iterator(row);
auto current_child = g_list_last(list_iterator); // button
return GTK_WIDGET(current_child->data);
}
static GtkWidget*
get_devicename_from_row(GtkWidget* row)
{
auto* list_iterator = get_row_iterator(row);
auto* current_child = g_list_first(list_iterator); // image
current_child = g_list_next(current_child); // box infos
auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
current_child = g_list_first(box_devices_info); // device.name
return GTK_WIDGET(current_child->data);
}
static void
replace_name_from_row(GtkWidget* row, const std::string& name, const std::string& id)
{
// Remove previous informations
auto* list_iterator = get_row_iterator(row);
auto* box_info = g_list_next(g_list_first(list_iterator)); // box infos
auto* action_button = g_list_last(list_iterator);
auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(box_info->data));
auto* device_name = g_list_first(box_devices_info); // device.name
auto isEntryName = G_TYPE_CHECK_INSTANCE_TYPE(device_name->data, gtk_entry_get_type());
auto* label_id = g_list_next(box_devices_info); // device.name
gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(device_name->data));
gtk_container_remove(GTK_CONTAINER(box_info->data), GTK_WIDGET(label_id->data));
// Rebuild item
if (isEntryName) {
auto* new_label_name = gtk_label_new(name.c_str());
gtk_box_pack_start(GTK_BOX(box_info->data), new_label_name, true, true, 0);
gtk_widget_set_halign(new_label_name, GtkAlign::GTK_ALIGN_START);
auto* image = gtk_image_new_from_icon_name("emblem-system-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_button_set_image(GTK_BUTTON(action_button->data), image);
} else {
auto* entry_name = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry_name), name.c_str());
gtk_container_add(GTK_CONTAINER(box_info->data), entry_name);
auto* image = gtk_image_new_from_icon_name("document-save-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_button_set_image(GTK_BUTTON(action_button->data), image);
}
auto* new_label_id = gtk_label_new("");
std::string markup = "<span font_desc=\"7.0\">" + id + "</span>";
gtk_label_set_markup(GTK_LABEL(new_label_id), markup.c_str());
gtk_container_add(GTK_CONTAINER(box_info->data), new_label_id);
gtk_widget_show_all(GTK_WIDGET(box_info->data));
}
static std::string
get_id_from_row(GtkWidget* row)
{
auto* list_iterator = get_row_iterator(row);
auto* current_child = g_list_first(list_iterator); // image
current_child = g_list_next(current_child); // box infos
auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
current_child = g_list_last(box_devices_info); // device.id
return gtk_label_get_text(GTK_LABEL(current_child->data));
}
static std::string
get_contact_id_from_row(GtkWidget* row)
{
auto* list_iterator = get_row_iterator(row);
auto* current_child = g_list_first(list_iterator); // image
auto box_devices_info = gtk_container_get_children(GTK_CONTAINER(current_child->data));
current_child = g_list_last(box_devices_info); // device.id
return gtk_label_get_text(GTK_LABEL(current_child->data));
}
static void
save_name(GtkButton* button, NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
if (GTK_BUTTON(get_button_from_row(children)) == button) {
GtkWidget* nameWidget = get_devicename_from_row(children);
auto deviceId = get_id_from_row(children);
if (G_TYPE_CHECK_INSTANCE_TYPE(nameWidget, gtk_entry_get_type())) {
std::string newName = gtk_entry_get_text(GTK_ENTRY(nameWidget));
replace_name_from_row(children, newName, deviceId);
(*priv->accountInfo_)->deviceModel->setCurrentDeviceName(newName);
} else {
std::string newName = gtk_label_get_text(GTK_LABEL(nameWidget));
replace_name_from_row(children, newName, deviceId);
}
}
++row;
}
}
static void
revoke_device(GtkButton* button, NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
if (GTK_BUTTON(get_button_from_row(children)) == button) {
auto deviceId = get_id_from_row(children);
auto* password = "";
auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
auto* password_dialog = gtk_message_dialog_new(top_window,
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
_("Warning! This action will revoke the device!\nNote: this action cannot be undone."));
gtk_window_set_title(GTK_WINDOW(password_dialog), _("Enter password to revoke device"));
gtk_dialog_set_default_response(GTK_DIALOG(password_dialog), GTK_RESPONSE_OK);
auto* message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(password_dialog));
if (priv->currentProp_->archiveHasPassword) {
auto* password_entry = gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(password_entry), false);
gtk_entry_set_invisible_char(GTK_ENTRY(password_entry), '*');
gtk_box_pack_start(GTK_BOX(message_area), password_entry, true, true, 0);
gtk_widget_show_all(password_dialog);
auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
if (res == GTK_RESPONSE_OK) {
password = gtk_entry_get_text(GTK_ENTRY(password_entry));
(*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, password);
}
} else {
auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
if (res == GTK_RESPONSE_OK)
(*priv->accountInfo_)->deviceModel->revokeDevice(deviceId, "");
}
gtk_widget_destroy(password_dialog);
}
++row;
}
}
static void
add_device(NewAccountSettingsView *view, const lrc::api::Device& device)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* device_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_spacing(GTK_BOX(device_box), 10);
auto* image_computer = gtk_image_new_from_icon_name("computer-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_box_pack_start(GTK_BOX(device_box), GTK_WIDGET(image_computer), false, false, 0);
GtkStyleContext* context_box;
context_box = gtk_widget_get_style_context(GTK_WIDGET(device_box));
gtk_style_context_add_class(context_box, "boxitem");
// Fill with devices informations
auto* device_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
auto* label_name = gtk_label_new(device.name.c_str());
gtk_box_pack_start(GTK_BOX(device_info_box), label_name, false, false, 0);
gtk_widget_set_halign(label_name, GtkAlign::GTK_ALIGN_START);
auto* label_id = gtk_label_new("");
std::string markup = "<span font_desc=\"7.0\">" + device.id + "</span>";
gtk_label_set_markup(GTK_LABEL(label_id), markup.c_str());
gtk_box_pack_start(GTK_BOX(device_info_box), label_id, false, false, 0);
gtk_box_pack_start(GTK_BOX(device_box), device_info_box, false, false, 0);
// Add action button
auto image = gtk_image_new_from_icon_name("emblem-system-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
if (!device.isCurrent)
image = gtk_image_new_from_icon_name("dialog-error-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
auto* action_device_button = gtk_button_new();
gtk_button_set_relief(GTK_BUTTON(action_device_button), GTK_RELIEF_NONE);
gtk_widget_set_tooltip_text(action_device_button, device.isCurrent ? _("Edit name") : _("Revoke device"));
gtk_button_set_image(GTK_BUTTON(action_device_button), image);
GtkStyleContext* context;
context = gtk_widget_get_style_context(GTK_WIDGET(action_device_button));
gtk_style_context_add_class(context, "transparent-button");
std::string label_btn = "action_btn_" + device.id;
gtk_widget_set_name(action_device_button, label_btn.c_str());
g_signal_connect(action_device_button, "clicked", device.isCurrent ? G_CALLBACK(save_name) : G_CALLBACK(revoke_device), view);
gtk_box_pack_end(GTK_BOX(device_box), GTK_WIDGET(action_device_button), false, false, 0);
// Insert at the end of the list
gtk_list_box_insert(GTK_LIST_BOX(priv->list_devices), device_box, -1);
gtk_widget_set_halign(GTK_WIDGET(device_box), GTK_ALIGN_FILL);
}
static void
show_revokation_error_dialog(NewAccountSettingsView *view, const std::string& text)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
auto* error_dialog = gtk_message_dialog_new(top_window,
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
"%s", text.c_str());
gtk_window_set_title(GTK_WINDOW(error_dialog), _("Error when revoking device"));
gtk_dialog_set_default_response(GTK_DIALOG(error_dialog), GTK_RESPONSE_OK);
gtk_dialog_run(GTK_DIALOG(error_dialog));
gtk_widget_destroy(error_dialog);
}
// Banned contacts related
static void
on_show_banned(GtkToggleButton*, NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->button_show_banned));
if (active) {
auto image = gtk_image_new_from_icon_name("pan-up-symbolic", GTK_ICON_SIZE_BUTTON);
gtk_button_set_image(GTK_BUTTON(priv->button_show_banned), image);
gtk_widget_show_all(priv->scrolled_window_banned_contacts);
gtk_widget_show_all(priv->button_show_banned);
} else {
auto image = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
gtk_button_set_image(GTK_BUTTON(priv->button_show_banned), image);
gtk_widget_hide(priv->scrolled_window_banned_contacts);
}
}
static void
unban_contact(GtkButton* button, NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_banned_contacts), row))) {
if (GTK_BUTTON(get_button_from_row(children)) == button) {
auto contactId = get_contact_id_from_row(children);
auto contact = (*priv->accountInfo_)->contactModel->getContact(contactId);
(*priv->accountInfo_)->contactModel->addContact(contact);
}
++row;
}
}
static void
add_banned(NewAccountSettingsView *view, const std::string& contactUri)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* banned_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
auto contact = (*priv->accountInfo_)->contactModel->getContact(contactUri);
GtkStyleContext* context_box;
context_box = gtk_widget_get_style_context(GTK_WIDGET(banned_box));
gtk_style_context_add_class(context_box, "boxitem");
// Fill with devices informations
auto* contact_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
if (!contact.registeredName.empty()) {
auto* label_name = gtk_label_new(contact.registeredName.c_str());
gtk_widget_set_halign(label_name, GtkAlign::GTK_ALIGN_START);
gtk_box_pack_start(GTK_BOX(contact_info_box), label_name, FALSE, TRUE, 0);
}
auto* label_id = gtk_label_new(contactUri.c_str());
gtk_widget_set_halign(label_id, GtkAlign::GTK_ALIGN_START);
gtk_box_pack_start(GTK_BOX(contact_info_box), label_id, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(banned_box), contact_info_box, FALSE, TRUE, 0);
// Add action button
auto image = gtk_image_new_from_icon_name("contact-new-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
auto* action_banned_button = gtk_button_new();
gtk_button_set_relief(GTK_BUTTON(action_banned_button), GTK_RELIEF_NONE);
gtk_widget_set_tooltip_text(action_banned_button, _("Unban"));
gtk_button_set_image(GTK_BUTTON(action_banned_button), image);
GtkStyleContext* context;
context = gtk_widget_get_style_context(GTK_WIDGET(action_banned_button));
gtk_style_context_add_class(context, "transparent-button");
std::string label_btn = "action_btn_" + contactUri;
gtk_widget_set_name(action_banned_button, label_btn.c_str());
g_signal_connect(action_banned_button, "clicked", G_CALLBACK(unban_contact), view);
gtk_box_pack_end(GTK_BOX(banned_box), action_banned_button, FALSE, TRUE, 0);
// Insert at the end of the list
gtk_list_box_insert(GTK_LIST_BOX(priv->list_banned_contacts), banned_box, -1);
gtk_widget_set_halign(GTK_WIDGET(banned_box), GTK_ALIGN_FILL);
}
// Password
static void
reset_change_password(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_label_set_text(GTK_LABEL(priv->label_error_change_password), "");
gtk_widget_hide(GTK_WIDGET(priv->label_error_change_password));
gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
}
static void
change_password(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
std::string current_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_current_password));
std::string new_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_new_password));
std::string confirm_password = gtk_entry_get_text(GTK_ENTRY(priv->entry_confirm_password));
if (new_password != confirm_password) {
gtk_label_set_text(GTK_LABEL(priv->label_error_change_password), _("New password and its confirmation are different!"));
gtk_widget_show(GTK_WIDGET(priv->label_error_change_password));
return;
}
if ((*priv->accountInfo_)->accountModel->changeAccountPassword(
(*priv->accountInfo_)->id, current_password.c_str(), new_password.c_str())) {
priv->currentProp_->archiveHasPassword = new_password != "";
new_account_settings_view_save_account(view);
gtk_widget_destroy(priv->change_password_dialog);
} else {
gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
gtk_label_set_text(GTK_LABEL(priv->label_error_change_password), _("Incorrect password!"));
gtk_widget_show(GTK_WIDGET(priv->label_error_change_password));
}
}
static void
close_change_password_dialog(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_destroy(priv->change_password_dialog);
}
static void
show_change_password_dialog(GtkListBox*, GtkListBoxRow *row, NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
if (row != GTK_LIST_BOX_ROW(priv->password_row)) return;
auto* parent = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
GtkDialogFlags flags = (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT);
priv->change_password_dialog = gtk_dialog_new_with_buttons(_("Change password"), parent, flags, nullptr);
gtk_window_set_resizable(GTK_WINDOW(priv->change_password_dialog), FALSE);
GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(priv->change_password_dialog));
gtk_box_set_spacing(GTK_BOX(content_area), 10);
gtk_widget_set_size_request(content_area, 250, -1);
gtk_widget_set_margin_end(content_area, 25);
gtk_widget_set_margin_start(content_area, 25);
gtk_widget_set_margin_top(content_area, 25);
gtk_widget_set_margin_bottom(content_area, 25);
priv->vbox_change_password = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_set_spacing(GTK_BOX(priv->vbox_change_password), 10);
auto* label_informations = gtk_label_new(_("Note: this will change the password only on this device."));
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), label_informations);
priv->entry_current_password = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(priv->entry_current_password), _("Current password"));
gtk_entry_set_input_purpose(GTK_ENTRY(priv->entry_current_password), GTK_INPUT_PURPOSE_PASSWORD);
gtk_entry_set_visibility(GTK_ENTRY(priv->entry_current_password), 0);
gtk_entry_set_icon_from_icon_name(GTK_ENTRY(priv->entry_current_password), GTK_ENTRY_ICON_PRIMARY, "gtk-dialog-authentication");
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), priv->entry_current_password);
priv->entry_new_password = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(priv->entry_new_password), _("New password"));
gtk_entry_set_visibility(GTK_ENTRY(priv->entry_new_password), 0);
gtk_entry_set_input_purpose(GTK_ENTRY(priv->entry_new_password), GTK_INPUT_PURPOSE_PASSWORD);
gtk_entry_set_icon_from_icon_name(GTK_ENTRY(priv->entry_new_password), GTK_ENTRY_ICON_PRIMARY, "gtk-dialog-authentication");
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), priv->entry_new_password);
priv->entry_confirm_password = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(priv->entry_confirm_password), _("Confirm password"));
gtk_entry_set_visibility(GTK_ENTRY(priv->entry_confirm_password), 0);
gtk_entry_set_input_purpose(GTK_ENTRY(priv->entry_confirm_password), GTK_INPUT_PURPOSE_PASSWORD);
gtk_entry_set_icon_from_icon_name(GTK_ENTRY(priv->entry_confirm_password), GTK_ENTRY_ICON_PRIMARY, "gtk-dialog-authentication");
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), priv->entry_confirm_password);
auto* buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
priv->button_validate_password = gtk_button_new();
gtk_button_set_label(GTK_BUTTON(priv->button_validate_password), _("Change password"));
gtk_container_add(GTK_CONTAINER(buttons), priv->button_validate_password);
auto* close_button = gtk_button_new();
gtk_button_set_label(GTK_BUTTON(close_button), _("Cancel"));
gtk_container_add(GTK_CONTAINER(buttons), close_button);
gtk_box_set_homogeneous(GTK_BOX(buttons), true);
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), buttons);
priv->label_error_change_password = gtk_label_new("");
gtk_container_add(GTK_CONTAINER(priv->vbox_change_password), priv->label_error_change_password);
gtk_box_pack_start(GTK_BOX(content_area), priv->vbox_change_password, FALSE, TRUE, 0);
g_signal_connect_swapped(close_button, "clicked", G_CALLBACK(close_change_password_dialog), view);
g_signal_connect_swapped(priv->button_validate_password, "clicked", G_CALLBACK(change_password), view);
g_signal_connect_swapped(priv->entry_current_password, "changed", G_CALLBACK(reset_change_password), view);
g_signal_connect_swapped(priv->entry_new_password, "changed", G_CALLBACK(reset_change_password), view);
g_signal_connect_swapped(priv->entry_confirm_password, "changed", G_CALLBACK(reset_change_password), view);
GtkStyleContext* context_error_label;
context_error_label = gtk_widget_get_style_context(GTK_WIDGET(priv->label_error_change_password));
gtk_style_context_add_class(context_error_label, "red_label");
gtk_widget_show_all(content_area);
gtk_widget_set_visible(priv->entry_current_password, priv->currentProp_->archiveHasPassword);
gtk_widget_hide(priv->label_error_change_password);
gtk_window_present(GTK_WINDOW(priv->change_password_dialog));
gtk_widget_grab_focus(GTK_WIDGET(close_button));
}
// Export file
static void
choose_export_file(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
// Get preferred path
GtkWidget* dialog;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
gint res;
gchar* filename = nullptr;
dialog = gtk_file_chooser_dialog_new(_("Save File"),
GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))),
action,
_("_Cancel"),
GTK_RESPONSE_CANCEL,
_("_Save"),
GTK_RESPONSE_ACCEPT,
nullptr);
std::string alias = (*priv->accountInfo_)->profileInfo.alias;
std::string uri = alias.empty()? "export.gz" : alias + ".gz";
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), uri.c_str());
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
auto chooser = GTK_FILE_CHOOSER(dialog);
filename = gtk_file_chooser_get_filename(chooser);
}
gtk_widget_destroy(dialog);
if (!filename) return;
// export account
auto success = (*priv->accountInfo_)->accountModel->exportToFile((*priv->accountInfo_)->id, filename);
std::string label = success? _("Account exported!") : _("Export account failure.");
gtk_button_set_label(GTK_BUTTON(priv->button_export_account), label.c_str());
g_free(filename);
}
// Remove account
static void
remove_account(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* top_window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
auto* password_dialog = gtk_message_dialog_new(top_window,
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
_("Warning! This action will remove this account on this device!\nNote: this action cannot be undone. Also, your registered name can be lost!"));
gtk_window_set_title(GTK_WINDOW(password_dialog), _("Delete account"));
gtk_dialog_set_default_response(GTK_DIALOG(password_dialog), GTK_RESPONSE_OK);
auto res = gtk_dialog_run(GTK_DIALOG(password_dialog));
if (res == GTK_RESPONSE_OK)
(*priv->accountInfo_)->accountModel->removeAccount((*priv->accountInfo_)->id);
gtk_widget_destroy(password_dialog);
}
// Advanced settings
static void
update_allow_call(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->call_allow_button));
if (newState != priv->currentProp_->allowIncoming) {
priv->currentProp_->allowIncoming = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_auto_answer(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->auto_answer_button));
if (newState != priv->currentProp_->autoAnswer) {
priv->currentProp_->autoAnswer = newState;
new_account_settings_view_save_account(view);
}
}
static void
enable_custom_ringtone(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->custom_ringtone_button));
if (newState != priv->currentProp_->Ringtone.ringtoneEnabled) {
priv->currentProp_->Ringtone.ringtoneEnabled = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_custom_ringtone(GtkFileChooser *file_chooser, NewAccountSettingsView* view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* newState = gtk_file_chooser_get_filename(file_chooser);
if (newState != priv->currentProp_->Ringtone.ringtonePath) {
priv->currentProp_->Ringtone.ringtonePath = newState;
new_account_settings_view_save_account(view);
}
g_free(newState);
}
static gboolean
update_nameserver(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_name_server));
if (newState != priv->currentProp_->RingNS.uri) {
priv->currentProp_->RingNS.uri = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_dhtproxy(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_dht_proxy));
if (newState != priv->currentProp_->proxyServer) {
priv->currentProp_->proxyServer = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_bootstrap(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_bootstrap));
if (newState != priv->currentProp_->hostname) {
priv->currentProp_->hostname = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static void
enable_dhtproxy(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->dht_proxy_button));
if (newState != priv->currentProp_->proxyEnabled) {
priv->currentProp_->proxyEnabled = newState;
new_account_settings_view_save_account(view);
}
}
static void
set_encrypt_media_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_encrypt_media));
if (newState != priv->currentProp_->SRTP.enable) {
priv->currentProp_->SRTP.enable = newState;
new_account_settings_view_save_account(view);
}
}
static void
set_fallback_rtp_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_fallback_rtp));
if (newState != priv->currentProp_->SRTP.rtpFallback) {
priv->currentProp_->SRTP.rtpFallback = newState;
new_account_settings_view_save_account(view);
}
}
static void
set_sdes_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->enable_sdes)) ? lrc::api::account::KeyExchangeProtocol::SDES : lrc::api::account::KeyExchangeProtocol::NONE;
if (newState != priv->currentProp_->SRTP.keyExchange) {
priv->currentProp_->SRTP.keyExchange = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_ca_list(GtkFileChooser *file_chooser, NewAccountSettingsView* view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* newState = gtk_file_chooser_get_filename(file_chooser);
if (newState != priv->currentProp_->TLS.certificateListFile) {
priv->currentProp_->TLS.certificateListFile = newState;
new_account_settings_view_save_account(view);
}
g_free(newState);
}
static void
update_certificate(GtkFileChooser *file_chooser, NewAccountSettingsView* view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* newState = gtk_file_chooser_get_filename(file_chooser);
if (newState != priv->currentProp_->TLS.certificateFile) {
priv->currentProp_->TLS.certificateFile = newState;
new_account_settings_view_save_account(view);
}
g_free(newState);
}
static void
update_private_key(GtkFileChooser *file_chooser, NewAccountSettingsView* view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* newState = gtk_file_chooser_get_filename(file_chooser);
if (newState != priv->currentProp_->TLS.privateKeyFile) {
priv->currentProp_->TLS.privateKeyFile = newState;
new_account_settings_view_save_account(view);
}
g_free(newState);
}
static gboolean
update_password(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
if (newState != priv->currentProp_->TLS.password) {
priv->currentProp_->TLS.password = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_tls_server_name(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_tls_server_name));
if (newState != priv->currentProp_->TLS.serverName) {
priv->currentProp_->TLS.serverName = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static void
update_negotiation_timeout(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_negotiation_timeout));
if (newState != priv->currentProp_->TLS.negotiationTimeoutSec) {
priv->currentProp_->TLS.negotiationTimeoutSec = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_registration_timeout(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_registration_timeout));
if (newState != priv->currentProp_->Registration.expire) {
priv->currentProp_->Registration.expire = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_network_interface(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_network_interface));
if (newState != priv->currentProp_->localPort) {
priv->currentProp_->localPort = newState;
new_account_settings_view_save_account(view);
}
}
static void
enable_turn(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->switch_use_turn));
if (newState != priv->currentProp_->TURN.enable) {
priv->currentProp_->TURN.enable = newState;
new_account_settings_view_save_account(view);
}
}
static gboolean
update_turnserver(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_turnserver));
if (newState != priv->currentProp_->TURN.server) {
priv->currentProp_->TURN.server = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_turnpassword(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_turnpassword));
if (newState != priv->currentProp_->TURN.password) {
priv->currentProp_->TURN.password = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_turnusername(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_turnusername));
if (newState != priv->currentProp_->TURN.username) {
priv->currentProp_->TURN.username = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static gboolean
update_turnrealm(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_turnrealm));
if (newState != priv->currentProp_->TURN.realm) {
priv->currentProp_->TURN.realm = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static void
enable_stun(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->switch_use_stun));
if (newState != priv->currentProp_->STUN.enable) {
priv->currentProp_->STUN.enable = newState;
new_account_settings_view_save_account(view);
}
}
static gboolean
update_stunserver(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_stunserver));
if (newState != priv->currentProp_->STUN.server) {
priv->currentProp_->STUN.server = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static void
enable_upnp(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->upnp_button));
if (newState != priv->currentProp_->upnpEnabled) {
priv->currentProp_->upnpEnabled = newState;
new_account_settings_view_save_account(view);
}
}
static void
enable_custom_address(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = !gtk_switch_get_active(GTK_SWITCH(priv->button_custom_published));
if (newState != priv->currentProp_->publishedSameAsLocal) {
priv->currentProp_->publishedSameAsLocal = newState;
new_account_settings_view_save_account(view);
}
}
static gboolean
update_published_address(GtkWidget*, GdkEvent*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return false;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_entry_get_text(GTK_ENTRY(priv->entry_published_address));
if (newState != priv->currentProp_->publishedAddress) {
priv->currentProp_->publishedAddress = newState;
new_account_settings_view_save_account(view);
}
return false;
}
static void
update_published_port(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_published_port));
if (newState != priv->currentProp_->publishedPort) {
priv->currentProp_->publishedPort = newState;
new_account_settings_view_save_account(view);
}
}
static void
enable_video(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->switch_enable_video));
if (newState != priv->currentProp_->Video.videoEnabled) {
priv->currentProp_->Video.videoEnabled = newState;
new_account_settings_view_save_account(view);
}
}
static void
enable_codec(GObject* switch_btn, GParamSpec*, NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto id = g_object_get_data(switch_btn, "id");
if (id) {
if ((*priv->accountInfo_)->codecModel->enable(GPOINTER_TO_UINT(id),
gtk_switch_get_active(GTK_SWITCH(switch_btn)))) {
draw_codecs(view);
}
}
}
static void
set_account_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = false;
if ((*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::RING) {
newState = gtk_switch_get_active(GTK_SWITCH(priv->account_enabled));
} else {
newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_account_enabled));
}
if (newState != (*priv->accountInfo_)->enabled) {
(*priv->accountInfo_)->accountModel->enableAccount((*priv->accountInfo_)->id, newState);
new_account_settings_view_save_account(view);
}
}
static void
sip_TLS_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_enable_TLS));
if (newState != priv->currentProp_->TLS.enable) {
priv->currentProp_->TLS.enable = newState;
new_account_settings_view_save_account(view);
}
}
static void
sip_verify_certs_server_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_verify_certs_server));
if (newState != priv->currentProp_->TLS.verifyServer) {
priv->currentProp_->TLS.verifyServer = newState;
new_account_settings_view_save_account(view);
}
}
static void
sip_verify_certs_client_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_verify_certs_client));
if (newState != priv->currentProp_->TLS.verifyClient) {
priv->currentProp_->TLS.verifyClient = newState;
new_account_settings_view_save_account(view);
}
}
static void
sip_require_incoming_tls_certs_enabled(GObject*, GParamSpec*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_switch_get_active(GTK_SWITCH(priv->sip_require_incoming_tls_certs));
if (newState != priv->currentProp_->TLS.requireClientCertificate) {
priv->currentProp_->TLS.requireClientCertificate = newState;
new_account_settings_view_save_account(view);
}
}
static void
tls_method_changed(NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method));
if (!text) return;
std::string activeText = text;
auto newState = lrc::api::account::TlsMethod::DEFAULT;
if (activeText == "TLSv1") {
newState = lrc::api::account::TlsMethod::TLSv1;
} else if (activeText == "TLSv1.1") {
newState = lrc::api::account::TlsMethod::TLSv1_1;
} else if (activeText == "TLSv1.2") {
newState = lrc::api::account::TlsMethod::TLSv1_2;
}
if (newState != priv->currentProp_->TLS.method) {
priv->currentProp_->TLS.method = newState;
new_account_settings_view_save_account(view);
}
}
static void
remove_cb(GtkWidget *widget, gpointer user_data) {
gtk_container_remove(GTK_CONTAINER(user_data), widget);
}
static void
draw_codecs(NewAccountSettingsView* view, int codecSelected)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
// Clear video codecs
gtk_container_foreach(GTK_CONTAINER(priv->list_video_codecs), (GtkCallback)remove_cb, priv->list_video_codecs);
// Add video codecs
auto videoCodecs = (*priv->accountInfo_)->codecModel->getVideoCodecs();
GtkListBoxRow* row_selected = nullptr;
auto currentIdx = 0;
for (const auto& codec : videoCodecs) {
auto* codec_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_margin_end(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_start(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_top(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_bottom(GTK_WIDGET(codec_box), 10);
auto* label_name = gtk_label_new(codec.name.c_str());
gtk_container_add(GTK_CONTAINER(codec_box), label_name);
auto* switch_enabled = gtk_switch_new();
g_object_set_data(G_OBJECT(switch_enabled), "id", GUINT_TO_POINTER(codec.id));
g_signal_connect(switch_enabled, "notify::active", G_CALLBACK(enable_codec), view);
gtk_switch_set_active(GTK_SWITCH(switch_enabled), codec.enabled);
gtk_box_pack_end(GTK_BOX(codec_box), GTK_WIDGET(switch_enabled), false, false, 0);
gtk_list_box_insert(GTK_LIST_BOX(priv->list_video_codecs), codec_box, -1);
if (codecSelected != -1 && codec.id == codecSelected) {
row_selected = gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_video_codecs), currentIdx);
}
currentIdx += 1;
}
if (row_selected) {
gtk_list_box_select_row(GTK_LIST_BOX(priv->list_video_codecs), row_selected);
}
gtk_widget_show_all(priv->list_video_codecs);
gtk_switch_set_active(GTK_SWITCH(priv->switch_enable_video), priv->currentProp_->Video.videoEnabled);
// Clear audio codecs
gtk_container_foreach(GTK_CONTAINER(priv->list_audio_codecs), (GtkCallback)remove_cb, priv->list_audio_codecs);
// Add audio codecs
auto audioCodecs = (*priv->accountInfo_)->codecModel->getAudioCodecs();
row_selected = nullptr;
currentIdx = 0;
for (const auto& codec : audioCodecs) {
auto* codec_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_margin_end(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_start(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_top(GTK_WIDGET(codec_box), 10);
gtk_widget_set_margin_bottom(GTK_WIDGET(codec_box), 10);
auto* codec_info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign(codec_info_box, GtkAlign::GTK_ALIGN_START);
auto* label_name = gtk_label_new(codec.name.c_str());
gtk_widget_set_halign(label_name, GtkAlign::GTK_ALIGN_START);
gtk_container_add(GTK_CONTAINER(codec_info_box), label_name);
auto* label_samplerate = gtk_label_new("");
std::string markup = "<span font_desc=\"7.0\">" + codec.samplerate + " Hz</span>";
gtk_label_set_markup(GTK_LABEL(label_samplerate), markup.c_str());
gtk_container_add(GTK_CONTAINER(codec_info_box), label_samplerate);
gtk_container_add(GTK_CONTAINER(codec_box), codec_info_box);
auto* switch_enabled = gtk_switch_new();
gtk_switch_set_active(GTK_SWITCH(switch_enabled), codec.enabled);
g_object_set_data(G_OBJECT(switch_enabled), "id", GUINT_TO_POINTER(codec.id));
g_signal_connect(switch_enabled, "notify::active", G_CALLBACK(enable_codec), view); // TODO(sblin) spamming here!
gtk_box_pack_end(GTK_BOX(codec_box), GTK_WIDGET(switch_enabled), false, false, 0);
gtk_list_box_insert(GTK_LIST_BOX(priv->list_audio_codecs), codec_box, -1);
if (codecSelected != -1 && codec.id == codecSelected) {
row_selected = gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_audio_codecs), currentIdx);
}
currentIdx += 1;
}
if (row_selected) {
gtk_list_box_select_row(GTK_LIST_BOX(priv->list_audio_codecs), row_selected);
}
gtk_widget_show_all(priv->list_audio_codecs);
}
static void
up_video_priority_clicked(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(priv->list_video_codecs));
auto* children = gtk_container_get_children(GTK_CONTAINER(row));
if (children) {
auto* box = gtk_container_get_children(GTK_CONTAINER(g_list_first(children)->data));
auto* switch_btn = g_list_last(box)->data;
auto id = g_object_get_data(G_OBJECT(switch_btn), "id");
if (id) (*priv->accountInfo_)->codecModel->increasePriority(GPOINTER_TO_UINT(id), true);
draw_codecs(view, (int)GPOINTER_TO_UINT(id));
}
}
static void
down_video_priority_clicked(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(priv->list_video_codecs));
auto* children = gtk_container_get_children(GTK_CONTAINER(row));
if (children) {
auto* box = gtk_container_get_children(GTK_CONTAINER(g_list_first(children)->data));
auto* switch_btn = g_list_last(box)->data;
auto id = g_object_get_data(G_OBJECT(switch_btn), "id");
if (id) (*priv->accountInfo_)->codecModel->decreasePriority(GPOINTER_TO_UINT(id), true);
draw_codecs(view, (int)GPOINTER_TO_UINT(id));
}
}
static void
up_audio_priority_clicked(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(priv->list_audio_codecs));
auto* children = gtk_container_get_children(GTK_CONTAINER(row));
if (children) {
auto* box = gtk_container_get_children(GTK_CONTAINER(g_list_first(children)->data));
auto* switch_btn = g_list_last(box)->data;
auto id = g_object_get_data(G_OBJECT(switch_btn), "id");
if (id) (*priv->accountInfo_)->codecModel->increasePriority(GPOINTER_TO_UINT(id), false);
draw_codecs(view, (int)GPOINTER_TO_UINT(id));
}
}
static void
down_audio_priority_clicked(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(priv->list_audio_codecs));
auto* children = gtk_container_get_children(GTK_CONTAINER(row));
if (children) {
auto* box = gtk_container_get_children(GTK_CONTAINER(g_list_first(children)->data));
auto* switch_btn = g_list_last(box)->data;
auto id = g_object_get_data(G_OBJECT(switch_btn), "id");
if (id) (*priv->accountInfo_)->codecModel->decreasePriority(GPOINTER_TO_UINT(id), false);
draw_codecs(view, (int)GPOINTER_TO_UINT(id));
}
}
static void
update_audio_rtp_min(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_audio_rtp_min));
if (newState != priv->currentProp_->Audio.audioPortMin) {
priv->currentProp_->Audio.audioPortMin = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_audio_rtp_max(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_audio_rtp_max));
if (newState != priv->currentProp_->Audio.audioPortMax) {
priv->currentProp_->Audio.audioPortMax = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_video_rtp_min(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_video_rtp_min));
if (newState != priv->currentProp_->Video.videoPortMin) {
priv->currentProp_->Video.videoPortMin = newState;
new_account_settings_view_save_account(view);
}
}
static void
update_video_rtp_max(GtkWidget*, NewAccountSettingsView *view)
{
if (!is_config_ok(view)) return;
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto newState = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(priv->spinbutton_video_rtp_max));
if (newState != priv->currentProp_->Video.videoPortMax) {
priv->currentProp_->Video.videoPortMax = newState;
new_account_settings_view_save_account(view);
}
}
// Link device
static void
show_add_device_view(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
gtk_widget_hide(GTK_WIDGET(priv->general_settings_box));
gtk_widget_show(GTK_WIDGET(priv->add_device_box));
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), priv->add_device_box);
}
static void
export_on_the_ring_clicked(G_GNUC_UNUSED GtkButton *button, NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto* password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password_export));
std::string passwordStr = {};
if (password) {
passwordStr = password;
}
gtk_entry_set_text(GTK_ENTRY(priv->entry_password_export), "");
priv->export_on_ring_ended = QObject::connect(
(*priv->accountInfo_)->accountModel,
&lrc::api::NewAccountModel::exportOnRingEnded,
[=] (const std::string& accountID, lrc::api::account::ExportOnRingStatus status, const std::string& pin) {
if (accountID != (*priv->accountInfo_)->id) return;
QObject::disconnect(priv->export_on_ring_ended);
switch (status)
{
case lrc::api::account::ExportOnRingStatus::SUCCESS:
{
GtkStyleContext* context;
context = gtk_widget_get_style_context(GTK_WIDGET(priv->label_generated_pin));
gtk_style_context_add_class(context, "larger");
gtk_label_set_text(GTK_LABEL(priv->label_generated_pin), pin.c_str());
show_generated_pin_view(view);
break;
}
case lrc::api::account::ExportOnRingStatus::WRONG_PASSWORD:
{
gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Bad password"));
show_export_on_ring_error(view);
break;
}
case lrc::api::account::ExportOnRingStatus::NETWORK_ERROR:
{
gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Network error, try again"));
show_export_on_ring_error(view);
break;
}
default:
{
gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Unknown error"));
show_export_on_ring_error(view);
break;
}
}
}
);
show_generating_pin_spinner(view);
if (!(*priv->accountInfo_)->accountModel->exportOnRing((*priv->accountInfo_)->id, passwordStr))
{
QObject::disconnect(priv->export_on_ring_ended);
gtk_label_set_text(GTK_LABEL(priv->label_export_on_ring_error), _("Could not initiate export to the Ring, try again"));
g_debug("Could not initiate exportOnRing operation");
show_export_on_ring_error(view);
}
}
static void
build_settings_view(NewAccountSettingsView* view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
// CSS styles
auto provider = gtk_css_provider_new();
std::string css = ".transparent-button { margin-left: 0; border: 0; background-color: rgba(0,0,0,0); margin-right: 0; padding-right: 0;}";
css += ".transparent-button:hover { border: 0; background-color: rgba(0,0,0,0);}";
css += ".show-button { padding: 0;}";
css += ".boxitem { padding: 12px; }";
css += ".green_label { color: white; background: #27ae60; width: 100%; border-radius: 3px; padding: 5px;}";
css += ".red_label { color: white; background: #dc3a37; width: 100%; border-radius: 3px; padding: 5px;}";
css += ".button_red { color: white; background: #dc3a37; border: 0; }";
css += ".button_red:hover { background: #dc2719; }";
css += ".larger { font-size: 300%; }";
gtk_css_provider_load_from_data(provider, css.c_str(), -1, nullptr);
gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
GTK_STYLE_PROVIDER(provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
priv->new_device_added_connection = QObject::connect(
&*(*priv->accountInfo_)->deviceModel,
&lrc::api::NewDeviceModel::deviceAdded,
[view] (const std::string& id) {
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
// Retrieve added device
auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
if (device.id.empty()) {
g_debug("Can't add device with id: %s", device.id.c_str());
return;
}
// if exists, add to list
add_device(view, device);
gtk_widget_show_all(priv->list_devices);
});
priv->device_removed_connection = QObject::connect(
&*(*priv->accountInfo_)->deviceModel,
&lrc::api::NewDeviceModel::deviceRevoked,
[view] (const std::string& id, const lrc::api::NewDeviceModel::Status status) {
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
auto deviceId = get_id_from_row(children);
if (deviceId == id) {
switch (status) {
case lrc::api::NewDeviceModel::Status::SUCCESS:
// remove device's line
gtk_container_remove(GTK_CONTAINER(priv->list_devices), children);
return;
case lrc::api::NewDeviceModel::Status::WRONG_PASSWORD:
show_revokation_error_dialog(view, _("Error: wrong password!"));
break;
case lrc::api::NewDeviceModel::Status::UNKNOWN_DEVICE:
show_revokation_error_dialog(view, _("Error: unknown device!"));
break;
default:
g_debug("unknown status for revoked device. BUG?");
return;
}
}
++row;
}
});
priv->device_updated_connection = QObject::connect(
&*(*priv->accountInfo_)->deviceModel,
&lrc::api::NewDeviceModel::deviceUpdated,
[view] (const std::string& id) {
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
// Retrieve added device
auto device = (*priv->accountInfo_)->deviceModel->getDevice(id);
if (device.id.empty()) {
g_debug("Can't add device with id: %s", device.id.c_str());
return;
}
// if exists, update
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), row))) {
auto device_name = get_devicename_from_row(children);
auto deviceId = get_id_from_row(children);
if (deviceId == id) {
if (device.isCurrent) {
if (G_TYPE_CHECK_INSTANCE_TYPE(device_name, gtk_entry_get_type())) {
gtk_entry_set_text(GTK_ENTRY(device_name), device.name.c_str());
} else {
gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
}
} else {
gtk_label_set_text(GTK_LABEL(device_name), device.name.c_str());
}
}
++row;
}
g_debug("deviceUpdated signal received, but device not found");
});
priv->banned_status_changed_connection = QObject::connect(
&*(*priv->accountInfo_)->contactModel,
&lrc::api::ContactModel::bannedStatusChanged,
[view] (const std::string& contactUri, bool banned) {
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
if (banned) {
add_banned(view, contactUri);
} else {
auto row = 0;
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_banned_contacts), row))) {
auto uri = get_contact_id_from_row(children);
if (contactUri == uri)
gtk_container_remove(GTK_CONTAINER(priv->list_banned_contacts), children);
++row;
}
}
gtk_widget_show_all(priv->list_banned_contacts);
});
new_account_settings_view_update(view, false);
GtkStyleContext* context;
context = gtk_widget_get_style_context(GTK_WIDGET(priv->button_delete_account));
gtk_style_context_add_class(context, "button_red");
context = gtk_widget_get_style_context(GTK_WIDGET(priv->sip_button_delete_account));
gtk_style_context_add_class(context, "button_red");
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_custom_ringtone),
priv->currentProp_->Ringtone.ringtonePath.c_str());
g_signal_connect_swapped(priv->button_advanced_settings, "clicked", G_CALLBACK(show_advanced_settings), view);
g_signal_connect_swapped(priv->button_general_settings, "clicked", G_CALLBACK(show_general_settings), view);
g_signal_connect(priv->type_box, "row-activated", G_CALLBACK(show_change_password_dialog), view);
g_signal_connect(priv->account_enabled, "notify::active", G_CALLBACK(set_account_enabled), view);
g_signal_connect(priv->sip_account_enabled, "notify::active", G_CALLBACK(set_account_enabled), view);
g_signal_connect(priv->sip_enable_TLS, "notify::active", G_CALLBACK(sip_TLS_enabled), view);
g_signal_connect(priv->sip_verify_certs_server, "notify::active", G_CALLBACK(sip_verify_certs_server_enabled), view);
g_signal_connect(priv->sip_verify_certs_client, "notify::active", G_CALLBACK(sip_verify_certs_client_enabled), view);
g_signal_connect(priv->sip_require_incoming_tls_certs, "notify::active", G_CALLBACK(sip_require_incoming_tls_certs_enabled), view);
g_signal_connect(priv->button_show_banned, "toggled", G_CALLBACK(on_show_banned), view);
g_signal_connect(priv->entry_display_name, "focus-out-event", G_CALLBACK(update_display_name), view);
g_signal_connect(priv->entry_sip_hostname, "focus-out-event", G_CALLBACK(update_sip_hostname), view);
g_signal_connect(priv->entry_sip_username, "focus-out-event", G_CALLBACK(update_sip_username), view);
g_signal_connect(priv->entry_sip_password, "focus-out-event", G_CALLBACK(update_sip_password), view);
g_signal_connect(priv->entry_sip_proxy, "focus-out-event", G_CALLBACK(update_sip_proxy), view);
g_signal_connect_swapped(priv->button_export_account, "clicked", G_CALLBACK(choose_export_file), view);
g_signal_connect_swapped(priv->button_delete_account, "clicked", G_CALLBACK(remove_account), view);
g_signal_connect_swapped(priv->sip_button_delete_account, "clicked", G_CALLBACK(remove_account), view);
g_signal_connect(priv->call_allow_button, "notify::active", G_CALLBACK(update_allow_call), view);
g_signal_connect(priv->auto_answer_button, "notify::active", G_CALLBACK(update_auto_answer), view);
g_signal_connect(priv->custom_ringtone_button, "notify::active", G_CALLBACK(enable_custom_ringtone), view);
g_signal_connect(priv->filechooserbutton_custom_ringtone, "file-set", G_CALLBACK(update_custom_ringtone), view);
g_signal_connect(priv->entry_name_server, "focus-out-event", G_CALLBACK(update_nameserver), view);
g_signal_connect(priv->entry_dht_proxy, "focus-out-event", G_CALLBACK(update_dhtproxy), view);
g_signal_connect(priv->dht_proxy_button, "notify::active", G_CALLBACK(enable_dhtproxy), view);
g_signal_connect(priv->entry_bootstrap, "focus-out-event", G_CALLBACK(update_bootstrap), view);
g_signal_connect(priv->sip_encrypt_media, "notify::active", G_CALLBACK(set_encrypt_media_enabled), view);
g_signal_connect(priv->sip_fallback_rtp, "notify::active", G_CALLBACK(set_fallback_rtp_enabled), view);
g_signal_connect(priv->enable_sdes, "notify::active", G_CALLBACK(set_sdes_enabled), view);
g_signal_connect(priv->filechooserbutton_ca_list, "file-set", G_CALLBACK(update_ca_list), view);
g_signal_connect(priv->filechooserbutton_certificate, "file-set", G_CALLBACK(update_certificate), view);
g_signal_connect(priv->filechooserbutton_private_key, "file-set", G_CALLBACK(update_private_key), view);
g_signal_connect(priv->entry_password, "focus-out-event", G_CALLBACK(update_password), view);
g_signal_connect(priv->spinbutton_registration_timeout, "value-changed", G_CALLBACK(update_registration_timeout), view);
g_signal_connect(priv->spinbutton_negotiation_timeout, "value-changed", G_CALLBACK(update_negotiation_timeout), view);
g_signal_connect(priv->spinbutton_network_interface, "value-changed", G_CALLBACK(update_network_interface), view);
g_signal_connect(priv->entry_tls_server_name, "focus-out-event", G_CALLBACK(update_tls_server_name), view);
g_signal_connect(priv->upnp_button, "notify::active", G_CALLBACK(enable_upnp), view);
g_signal_connect(priv->switch_use_turn, "notify::active", G_CALLBACK(enable_turn), view);
g_signal_connect(priv->entry_turnserver, "focus-out-event", G_CALLBACK(update_turnserver), view);
g_signal_connect(priv->entry_turnusername, "focus-out-event", G_CALLBACK(update_turnusername), view);
g_signal_connect(priv->entry_turnpassword, "focus-out-event", G_CALLBACK(update_turnpassword), view);
g_signal_connect(priv->entry_turnrealm, "focus-out-event", G_CALLBACK(update_turnrealm), view);
g_signal_connect(priv->switch_use_stun, "notify::active", G_CALLBACK(enable_stun), view);
g_signal_connect(priv->entry_stunserver, "focus-out-event", G_CALLBACK(update_stunserver), view);
g_signal_connect(priv->button_custom_published, "notify::active", G_CALLBACK(enable_custom_address), view);
g_signal_connect(priv->entry_published_address, "focus-out-event", G_CALLBACK(update_published_address), view);
g_signal_connect(priv->spinbutton_published_port, "value-changed", G_CALLBACK(update_published_port), view);
g_signal_connect(priv->switch_enable_video, "notify::active", G_CALLBACK(enable_video), view);
g_signal_connect_swapped(priv->button_up_video, "clicked", G_CALLBACK(up_video_priority_clicked), view);
g_signal_connect_swapped(priv->button_down_video, "clicked", G_CALLBACK(down_video_priority_clicked), view);
g_signal_connect_swapped(priv->button_up_audio, "clicked", G_CALLBACK(up_audio_priority_clicked), view);
g_signal_connect_swapped(priv->button_down_audio, "clicked", G_CALLBACK(down_audio_priority_clicked), view);
g_signal_connect(priv->spinbutton_audio_rtp_min, "value-changed", G_CALLBACK(update_audio_rtp_min), view);
g_signal_connect(priv->spinbutton_audio_rtp_max, "value-changed", G_CALLBACK(update_audio_rtp_max), view);
g_signal_connect(priv->spinbutton_video_rtp_min, "value-changed", G_CALLBACK(update_video_rtp_min), view);
g_signal_connect(priv->spinbutton_video_rtp_max, "value-changed", G_CALLBACK(update_video_rtp_max), view);
g_signal_connect_swapped(priv->button_add_device, "clicked", G_CALLBACK(show_add_device_view), view);
g_signal_connect_swapped(priv->button_add_device_cancel, "clicked", G_CALLBACK(show_general_settings), view);
g_signal_connect(priv->button_export_on_the_ring, "clicked", G_CALLBACK(export_on_the_ring_clicked), view);
g_signal_connect_swapped(priv->button_generated_pin_ok, "clicked", G_CALLBACK(show_general_settings), view);
g_signal_connect_swapped(priv->button_export_on_ring_error_ok, "clicked", G_CALLBACK(show_general_settings), view);
}
void
new_account_settings_view_update(NewAccountSettingsView *view, gboolean reset_view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
if (!(*priv->accountInfo_)) {
g_debug("No specified account info");
return;
}
if (priv->currentProp_) {
delete priv->currentProp_;
priv->currentProp_ = nullptr;
}
try {
std::string accountId = (*priv->accountInfo_)->id;
priv->currentProp_ = new lrc::api::account::ConfProperties_t();
*priv->currentProp_ = (*priv->accountInfo_)->accountModel->getAccountConfig(accountId);
} catch (std::out_of_range& e) {
g_debug("Can't get acount config for current account");
return;
}
auto& label_status = priv->label_status;
if ((*priv->accountInfo_)->profileInfo.type != lrc::api::profile::Type::RING) {
label_status = priv->sip_label_status;
}
switch ((*priv->accountInfo_)->status)
{
case lrc::api::account::Status::INITIALIZING:
gtk_label_set_text(GTK_LABEL(label_status), _("Initializing…"));
break;
case lrc::api::account::Status::UNREGISTERED:
gtk_label_set_text(GTK_LABEL(label_status), _("Offline"));
break;
case lrc::api::account::Status::TRYING:
gtk_label_set_text(GTK_LABEL(label_status), _("Connecting…"));
break;
case lrc::api::account::Status::REGISTERED:
gtk_label_set_text(GTK_LABEL(label_status), _("Online"));
break;
case lrc::api::account::Status::INVALID:
default:
gtk_label_set_text(GTK_LABEL(label_status), _("Unknown status"));
break;
}
gtk_entry_set_text(GTK_ENTRY(priv->entry_display_name), (*priv->accountInfo_)->profileInfo.alias.c_str());
if ((*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::RING) {
gtk_switch_set_active(GTK_SWITCH(priv->account_enabled), (*priv->accountInfo_)->enabled);
gtk_widget_show_all(priv->vbox_devices);
gtk_widget_show_all(priv->vbox_banned_contacts);
gtk_widget_show_all(priv->username_box);
gtk_widget_hide(priv->sip_info_box);
gtk_widget_show(priv->button_export_account);
gtk_widget_show(priv->type_box);
gtk_widget_hide(priv->sip_enable_account);
gtk_widget_show_all(priv->account_options_box);
// Show ring id
gtk_label_set_text(GTK_LABEL(priv->label_type_info), (*priv->accountInfo_)->profileInfo.uri.c_str());
// Update export label
gtk_button_set_label(GTK_BUTTON(priv->button_export_account), _("Export account"));
// Build devices list
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_devices), 0)))
gtk_container_remove(GTK_CONTAINER(priv->list_devices), children);
auto devices = (*priv->accountInfo_)->deviceModel->getAllDevices();
for (const auto& device : devices)
add_device(view, device);
gtk_widget_set_halign(GTK_WIDGET(priv->list_devices), GTK_ALIGN_FILL);
gtk_widget_show_all(priv->list_devices);
// Build banned contacts list
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->button_show_banned), false);
gtk_label_set_text(GTK_LABEL(priv->label_change_password), (priv->currentProp_->archiveHasPassword)? _("••••••••") : _("no password set"));
auto image = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
gtk_button_set_image(GTK_BUTTON(priv->button_show_banned), image);
while (GtkWidget* children = GTK_WIDGET(gtk_list_box_get_row_at_index(GTK_LIST_BOX(priv->list_banned_contacts), 0)))
gtk_container_remove(GTK_CONTAINER(priv->list_banned_contacts), children);
for (const auto& contact : (*priv->accountInfo_)->contactModel->getBannedContacts())
add_banned(view, contact);
gtk_widget_hide(priv->scrolled_window_banned_contacts);
// Clear username box
auto* children = gtk_container_get_children(GTK_CONTAINER(priv->username_box));
if (!children) {
g_debug("No username label... abort");
}
auto* username_registration_widget = username_registration_box_new(*priv->accountInfo_, true);
gtk_widget_set_can_focus(username_registration_widget, true);
auto* current_child = g_list_first(children); // label
auto* ubox = g_list_next(current_child);
if (ubox) {
gtk_container_remove(GTK_CONTAINER(priv->username_box), GTK_WIDGET(ubox->data));
}
gtk_switch_set_active(GTK_SWITCH(priv->custom_ringtone_button), priv->currentProp_->Ringtone.ringtoneEnabled);
gtk_widget_set_sensitive(priv->filechooserbutton_custom_ringtone, priv->currentProp_->Ringtone.ringtoneEnabled);
gtk_box_pack_end(GTK_BOX(priv->username_box), GTK_WIDGET(username_registration_widget), false, false, 0);
gtk_widget_show(GTK_WIDGET(priv->username_box));
gtk_widget_show(GTK_WIDGET(username_registration_widget));
gtk_widget_show_all(priv->allow_call_row);
gtk_widget_show_all(priv->box_name_server);
gtk_widget_show_all(priv->box_dht);
gtk_widget_hide(priv->box_published_address);
gtk_widget_hide(priv->sip_encrypt_media_row);
gtk_widget_hide(priv->sip_key_exchange_row);
gtk_widget_hide(priv->sip_fallback_rtp_row);
gtk_widget_hide(priv->sip_encrypt_negotiation);
gtk_widget_hide(priv->sip_verify_certs_server_row);
gtk_widget_hide(priv->sip_tls_protocol_row);
gtk_widget_hide(priv->sip_tls_server_name_row);
gtk_widget_hide(priv->sip_negotiation_timeout_row);
gtk_widget_hide(priv->sip_verify_certs_client_row);
gtk_widget_hide(priv->sip_require_incoming_tls_certs_row);
gtk_widget_hide(priv->sip_registration_expire_row);
gtk_widget_hide(priv->sip_network_interface_row);
gtk_widget_hide(priv->box_sdp_session);
draw_codecs(view);
std::string label_id = gtk_label_get_text(GTK_LABEL(priv->label_id));
std::string label_username = gtk_label_get_text(GTK_LABEL(priv->label_username));
std::string label_password = gtk_label_get_text(GTK_LABEL(priv->label_password));
auto max_width = label_id.size();
max_width = std::max(max_width, label_username.size());
max_width = std::max(max_width, label_password.size());
gtk_label_set_width_chars(GTK_LABEL(priv->label_id), max_width + 1);
gtk_label_set_width_chars(GTK_LABEL(priv->label_username), max_width + 1);
gtk_label_set_width_chars(GTK_LABEL(priv->label_password), max_width + 1);
} else {
gtk_switch_set_active(GTK_SWITCH(priv->sip_account_enabled), (*priv->accountInfo_)->enabled);
gtk_widget_show(priv->sip_info_box);
gtk_widget_hide(priv->account_options_box);
gtk_widget_hide(priv->type_box);
gtk_widget_show_all(priv->sip_enable_account);
gtk_widget_hide(priv->vbox_devices);
gtk_widget_hide(priv->vbox_banned_contacts);
gtk_widget_hide(priv->button_export_account);
gtk_widget_hide(priv->username_box);
gtk_widget_hide(priv->allow_call_row);
gtk_widget_hide(priv->box_name_server);
gtk_widget_hide(priv->box_dht);
gtk_widget_show_all(priv->box_published_address);
gtk_widget_show_all(priv->sip_encrypt_negotiation);
gtk_widget_show_all(priv->sip_verify_certs_server_row);
gtk_widget_show_all(priv->sip_verify_certs_client_row);
gtk_widget_show_all(priv->sip_require_incoming_tls_certs_row);
gtk_widget_show_all(priv->sip_encrypt_media_row);
gtk_widget_show_all(priv->sip_tls_protocol_row);
gtk_widget_show_all(priv->sip_tls_server_name_row);
gtk_widget_show_all(priv->sip_negotiation_timeout_row);
gtk_widget_show_all(priv->sip_key_exchange_row);
gtk_widget_show_all(priv->sip_fallback_rtp_row);
gtk_widget_show_all(priv->sip_registration_expire_row);
gtk_widget_show_all(priv->sip_network_interface_row);
gtk_widget_show_all(priv->box_sdp_session);
gtk_switch_set_active(GTK_SWITCH(priv->sip_enable_TLS), priv->currentProp_->TLS.enable);
gtk_switch_set_active(GTK_SWITCH(priv->sip_verify_certs_server), priv->currentProp_->TLS.verifyServer);
gtk_switch_set_active(GTK_SWITCH(priv->sip_verify_certs_client), priv->currentProp_->TLS.verifyClient);
gtk_switch_set_active(GTK_SWITCH(priv->sip_require_incoming_tls_certs), priv->currentProp_->TLS.requireClientCertificate);
gtk_switch_set_active(GTK_SWITCH(priv->sip_encrypt_media), priv->currentProp_->SRTP.enable);
gtk_switch_set_active(GTK_SWITCH(priv->sip_fallback_rtp), priv->currentProp_->SRTP.rtpFallback);
gtk_widget_set_sensitive(GTK_WIDGET(priv->sip_fallback_rtp), priv->currentProp_->SRTP.enable);
gtk_switch_set_active(GTK_SWITCH(priv->enable_sdes), priv->currentProp_->SRTP.keyExchange == lrc::api::account::KeyExchangeProtocol::SDES);
gtk_widget_set_sensitive(GTK_WIDGET(priv->enable_sdes), priv->currentProp_->SRTP.enable);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_negotiation_timeout), priv->currentProp_->TLS.negotiationTimeoutSec);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_registration_timeout), priv->currentProp_->Registration.expire);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_network_interface), priv->currentProp_->localPort);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_audio_rtp_min), priv->currentProp_->Audio.audioPortMin);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_audio_rtp_max), priv->currentProp_->Audio.audioPortMax);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_video_rtp_min), priv->currentProp_->Video.videoPortMin);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_video_rtp_max), priv->currentProp_->Video.videoPortMax);
gtk_entry_set_text(GTK_ENTRY(priv->entry_tls_server_name), priv->currentProp_->TLS.serverName.c_str());
gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method));
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method), nullptr, "Default");
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method), nullptr, "TLSv1");
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method), nullptr, "TLSv1.1");
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(priv->combobox_tls_protocol_method), nullptr, "TLSv1.2");
switch (priv->currentProp_->TLS.method)
{
case lrc::api::account::TlsMethod::TLSv1:
gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combobox_tls_protocol_method), 1);
break;
case lrc::api::account::TlsMethod::TLSv1_1:
gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combobox_tls_protocol_method), 2);
break;
case lrc::api::account::TlsMethod::TLSv1_2:
gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combobox_tls_protocol_method), 3);
break;
case lrc::api::account::TlsMethod::DEFAULT:
default:
gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combobox_tls_protocol_method), 0);
break;
}
g_signal_connect_swapped(priv->combobox_tls_protocol_method, "changed", G_CALLBACK(tls_method_changed), view);
gtk_entry_set_text(GTK_ENTRY(priv->entry_sip_hostname), priv->currentProp_->hostname.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_sip_username), priv->currentProp_->username.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_sip_password), priv->currentProp_->password.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_sip_proxy), priv->currentProp_->routeset.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_sip_voicemail), priv->currentProp_->mailbox.c_str());
}
// advanced
gtk_switch_set_active(GTK_SWITCH(priv->call_allow_button), priv->currentProp_->allowIncoming);
gtk_switch_set_active(GTK_SWITCH(priv->auto_answer_button), priv->currentProp_->autoAnswer);
gtk_entry_set_text(GTK_ENTRY(priv->entry_name_server), priv->currentProp_->RingNS.uri.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_dht_proxy), priv->currentProp_->proxyServer.c_str());
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_dht_proxy), priv->currentProp_->proxyEnabled);
gtk_entry_set_text(GTK_ENTRY(priv->entry_bootstrap), priv->currentProp_->hostname.c_str());
gtk_switch_set_active(GTK_SWITCH(priv->dht_proxy_button), priv->currentProp_->proxyEnabled);
if (!priv->currentProp_->TLS.certificateListFile.empty())
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_ca_list), priv->currentProp_->TLS.certificateListFile.c_str());
if (!priv->currentProp_->TLS.certificateFile.empty())
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_certificate), priv->currentProp_->TLS.certificateFile.c_str());
if (!priv->currentProp_->TLS.privateKeyFile.empty())
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_private_key), priv->currentProp_->TLS.privateKeyFile.c_str());
if (!priv->currentProp_->TLS.password.empty())
gtk_entry_set_text(GTK_ENTRY(priv->entry_password), priv->currentProp_->TLS.password.c_str());
gtk_switch_set_active(GTK_SWITCH(priv->upnp_button), priv->currentProp_->upnpEnabled);
gtk_switch_set_active(GTK_SWITCH(priv->switch_use_turn), priv->currentProp_->TURN.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_turnserver), priv->currentProp_->TURN.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_turnusername), priv->currentProp_->TURN.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_turnpassword), priv->currentProp_->TURN.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_turnrealm), priv->currentProp_->TURN.enable);
gtk_entry_set_text(GTK_ENTRY(priv->entry_turnserver), priv->currentProp_->TURN.server.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_turnusername), priv->currentProp_->TURN.username.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_turnpassword), priv->currentProp_->TURN.password.c_str());
gtk_entry_set_text(GTK_ENTRY(priv->entry_turnrealm), priv->currentProp_->TURN.realm.c_str());
gtk_switch_set_active(GTK_SWITCH(priv->switch_use_stun), priv->currentProp_->STUN.enable);
gtk_entry_set_text(GTK_ENTRY(priv->entry_stunserver), priv->currentProp_->STUN.server.c_str());
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_stunserver), priv->currentProp_->STUN.enable);
gtk_switch_set_active(GTK_SWITCH(priv->button_custom_published), !priv->currentProp_->publishedSameAsLocal);
gtk_entry_set_text(GTK_ENTRY(priv->entry_published_address), priv->currentProp_->publishedAddress.c_str());
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_published_address), !priv->currentProp_->publishedSameAsLocal);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->spinbutton_published_port), priv->currentProp_->publishedPort);
gtk_widget_set_sensitive(GTK_WIDGET(priv->spinbutton_published_port), !priv->currentProp_->publishedSameAsLocal);
gtk_widget_set_sensitive(GTK_WIDGET(priv->filechooserbutton_ca_list), priv->currentProp_->TLS.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->filechooserbutton_certificate), priv->currentProp_->TLS.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->filechooserbutton_private_key), priv->currentProp_->TLS.enable);
gtk_widget_set_sensitive(GTK_WIDGET(priv->entry_password), priv->currentProp_->TLS.enable);
new_account_settings_view_show(view, true);
if (reset_view) {
show_general_settings(view);
}
}
void
new_account_settings_view_save_account(NewAccountSettingsView *view)
{
g_return_if_fail(IS_NEW_ACCOUNT_SETTINGS_VIEW(view));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
if (priv->currentProp_ && (*priv->accountInfo_))
(*priv->accountInfo_)->accountModel->setAccountConfig((*priv->accountInfo_)->id, *priv->currentProp_);
}
GtkWidget*
new_account_settings_view_new(AccountInfoPointer const & accountInfo)
{
gpointer view = g_object_new(NEW_ACCOUNT_SETTINGS_VIEW_TYPE, NULL);
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(view);
priv->accountInfo_ = &accountInfo;
if (*priv->accountInfo_) {
build_settings_view(NEW_ACCOUNT_SETTINGS_VIEW(view));
}
return reinterpret_cast<GtkWidget*>(view);
}
void
new_account_settings_view_show(NewAccountSettingsView *self, gboolean show_profile)
{
g_return_if_fail(NEW_ACCOUNT_SETTINGS_VIEW(self));
auto* priv = NEW_ACCOUNT_SETTINGS_VIEW_GET_PRIVATE(self);
if (priv->avatarmanipulation) {
gtk_container_remove(GTK_CONTAINER(priv->avatar_box), priv->avatarmanipulation);
priv->avatarmanipulation = nullptr;
}
if (show_profile) {
/* avatar manipulation widget */
priv->avatarmanipulation = avatar_manipulation_new(*priv->accountInfo_);
gtk_widget_set_halign(priv->avatar_box, GtkAlign::GTK_ALIGN_CENTER);
gtk_box_pack_start(GTK_BOX(priv->avatar_box), priv->avatarmanipulation, true, true, 0);
gtk_widget_set_visible(priv->avatarmanipulation, true);
}
}