Commit 61c19d18 authored by Sébastien Blin's avatar Sébastien Blin Committed by Andreas Traczyk

newaccountsettings: add a new account settings page

Link the account settings page to the new models in LRC.

** Summary changes **

+ Link AvatarManipulation to new models and change the size of the
widget
+ Redo the account combobox selector to show the avatar
+ Add the ability to see disabled accounts and linked conversations
+ Redo the whole accounts settings page and reorganize settings
+ Link the username registration widgets to new LRC
+ Add the ability to create SIP accounts from the wizard

Change-Id: I43b15d1279ce1e3c8dee97b46fa6317aba272635
Reviewed-by: Andreas Traczyk's avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent 79efc022
......@@ -294,6 +294,8 @@ SET( SRC_FILES
src/dialogs.c
src/mediasettingsview.h
src/mediasettingsview.cpp
src/newaccountsettingsview.h
src/newaccountsettingsview.cpp
src/generalsettingsview.h
src/generalsettingsview.cpp
src/backends/edscontactbackend.h
......
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<path d="M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z"/>
<path fill="none" d="M0,0h24v24H0V0z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"/>
</svg>
......@@ -29,6 +29,7 @@
<file alias="add">add.svg</file>
<file alias="reject">reject.svg</file>
<file alias="block">block.svg</file>
<file alias="block_black">block_black.svg</file>
<file alias="invite">ic_person_add_black_24px.svg</file>
<file alias="temporary-item">ic_search_black_48px.svg</file>
<file alias="audio_only_call_start">ic_call_black_24px.svg</file>
......@@ -39,5 +40,10 @@
<file alias="add-device">add-device.svg</file>
<file alias="devices">devices.svg</file>
<file alias="save">save.svg</file>
<file alias="settings">settings.svg</file>
<file alias="export">export.svg</file>
<file alias="account">account.svg</file>
<file alias="bottom_arrow">bottom_arrow.svg</file>
<file alias="up_arrow">up_arrow.svg</file>
</gresource>
</gresources>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="none" d="M0 0h20v20H0V0z"/>
<path d="M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
......@@ -29,6 +29,7 @@
#include <profile.h>
#include <accountmodel.h>
#include <personmodel.h>
#include "api/newaccountmodel.h"
// Ring Client
#include "utils/models.h"
......@@ -50,20 +51,25 @@ typedef struct _AccountCreationWizardPrivate AccountCreationWizardPrivate;
struct _AccountCreationWizardPrivate
{
AccountInfoPointer const *accountInfo_ = nullptr;
gchar* accountId;
gchar* username;
gchar* password;
gchar* avatar;
GtkWidget *stack_account_creation;
QMetaObject::Connection account_state_changed;
QMetaObject::Connection name_registration_ended;
gboolean username_available;
QString* password;
QString* username;
/* choose_account_type_vbox */
GtkWidget *choose_account_type_vbox;
GtkWidget *choose_account_type_ring_logo;
GtkWidget *button_new_account;
GtkWidget *button_existing_account;
GtkWidget *button_wizard_cancel;
GtkWidget *button_show_advanced;
GtkWidget *button_new_sip_account;
/* existing account */
GtkWidget *existing_account;
......@@ -148,6 +154,8 @@ account_creation_wizard_class_init(AccountCreationWizardClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, button_new_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, button_existing_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, button_wizard_cancel);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, button_show_advanced);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, button_new_sip_account);
/* existing account */
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountCreationWizard, existing_account);
......@@ -200,11 +208,12 @@ account_creation_wizard_class_init(AccountCreationWizardClass *klass)
G_TYPE_NONE, 0);
}
static void
show_error_view(AccountCreationWizard *view)
void
account_creation_show_error_view(AccountCreationWizard *view, const std::string& id)
{
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_creation), priv->error_view);
if (priv->accountId && id == priv->accountId)
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account_creation), priv->error_view);
}
static void
......@@ -236,146 +245,51 @@ create_ring_account(AccountCreationWizard *view,
gchar *pin,
gchar *archivePath)
{
g_return_val_if_fail(IS_ACCOUNT_CREATION_WIZARD(view), G_SOURCE_REMOVE);
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
// Copy password and alias, which will be used in our callbacks
priv->username = new QString(username);
priv->password = new QString(password);
priv->username = g_strdup(username);
priv->password = g_strdup(password);
std::string accountId = lrc::api::NewAccountModel::createNewAccount(
lrc::api::profile::Type::RING,
display_name? display_name : "",
archivePath? archivePath : "",
password? password : "",
pin? pin : "");
priv->accountId = g_strdup(accountId.c_str());
priv->avatar = g_strdup(avatar_manipulation_get_temporary(AVATAR_MANIPULATION(priv->avatar_manipulation)));
// NOTE: NewAccountModel::accountAdded will be triggered here and will call account_creation_wizard_account_added
g_object_ref(view); // ref so its not destroyed too early
/* create account and set UPnP enabled, as its not by default in the daemon */
Account *account = nullptr;
/* get profile (if so) */
auto profile = ProfileModel::instance().selectedProfile();
if (display_name && strlen(display_name) > 0) {
account = AccountModel::instance().add(display_name, Account::Protocol::RING);
if(profile && AccountModel::instance().size() == 1)
{
profile->person()->setFormattedName(display_name);
}
} else {
auto unknown_alias = C_("The default username / account alias, if none is set by the user", "Unknown");
account = AccountModel::instance().add(unknown_alias, Account::Protocol::RING);
if (profile && AccountModel::instance().size() == 1)
{
profile->person()->setFormattedName(unknown_alias);
}
}
g_object_ref(view); // ref so its not destroyed too early
/* Set the archive password */
account->setArchivePassword(password);
return G_SOURCE_REMOVE;
}
/* Set the archive pin (existng accounts) */
if(pin)
{
account->setArchivePin(pin);
void
account_creation_wizard_account_added(AccountCreationWizard *view, AccountInfoPointer const & accountInfo)
{
g_return_if_fail(IS_ACCOUNT_CREATION_WIZARD(view));
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
priv->accountInfo_ = &accountInfo;
if ((*priv->accountInfo_)->id != priv->accountId) {
// Not for this account. Abort
return;
}
if (archivePath)
{
account->setArchivePath(archivePath);
// Register username
if (priv->username) {
(*priv->accountInfo_)->accountModel->registerName(priv->accountId, priv->password, priv->username);
}
account->setDisplayName(display_name); // set the display name to the same as the alias
account->setUpnpEnabled(TRUE);
/* show error window if the account errors */
priv->account_state_changed = QObject::connect(
account,
&Account::stateChanged,
[=] (Account::RegistrationState state) {
switch(state)
{
case Account::RegistrationState::ERROR:
{
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
QObject::disconnect(priv->account_state_changed);
show_error_view(view);
g_object_unref(view);
break;
}
case Account::RegistrationState::READY:
case Account::RegistrationState::TRYING:
case Account::RegistrationState::UNREGISTERED:
{
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
QObject::disconnect(priv->account_state_changed);
account << Account::EditAction::RELOAD;
// Now try to register the username
if (priv->username && !priv->username->isEmpty() && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbutton_sign_up_blockchain)))
{
priv->name_registration_ended = QObject::connect(
account,
&Account::nameRegistrationEnded,
[=] (NameDirectory::RegisterNameStatus status, G_GNUC_UNUSED const QString& name) {
QObject::disconnect(priv->name_registration_ended);
switch(status)
{
case NameDirectory::RegisterNameStatus::INVALID_NAME:
case NameDirectory::RegisterNameStatus::WRONG_PASSWORD:
case NameDirectory::RegisterNameStatus::ALREADY_TAKEN:
case NameDirectory::RegisterNameStatus::NETWORK_ERROR:
{
could_not_register_username_dialog(view);
// Reload so that the username is displayed in the settings
account << Account::EditAction::RELOAD;
break;
}
case NameDirectory::RegisterNameStatus::SUCCESS:
{
// Reload so that the username is displayed in the settings
account << Account::EditAction::RELOAD;
break;
}
}
g_signal_emit(G_OBJECT(view), account_creation_wizard_signals[ACCOUNT_CREATION_COMPLETED], 0);
g_object_unref(view);
}
);
show_registering_on_blockchain_spinner(view);
bool register_name_result = account->registerName(*priv->password, *priv->username);
priv->username->clear();
priv->password->clear();
if (register_name_result == FALSE)
{
g_debug("Could not initialize registerName operation");
could_not_register_username_dialog(view);
QObject::disconnect(priv->name_registration_ended);
g_signal_emit(G_OBJECT(view), account_creation_wizard_signals[ACCOUNT_CREATION_COMPLETED], 0);
g_object_unref(view);
}
}
else
{
g_signal_emit(G_OBJECT(view), account_creation_wizard_signals[ACCOUNT_CREATION_COMPLETED], 0);
g_object_unref(view);
}
break;
}
case Account::RegistrationState::INITIALIZING:
case Account::RegistrationState::COUNT__:
{
// Keep waiting...
break;
}
}
// Set avatar if any.
if (priv->avatar) {
try {
(*priv->accountInfo_)->accountModel->setAvatar(priv->accountId, priv->avatar);
} catch (std::out_of_range&) {
g_warning("Can't set avatar for unknown account");
}
);
account->performAction(Account::EditAction::SAVE);
profile->save();
}
return G_SOURCE_REMOVE;
g_signal_emit(G_OBJECT(view), account_creation_wizard_signals[ACCOUNT_CREATION_COMPLETED], 0);
g_object_unref(view);
}
static gboolean
......@@ -519,6 +433,21 @@ wizard_cancel_clicked(G_GNUC_UNUSED GtkButton *button, AccountCreationWizard *vi
account_creation_wizard_cancel(view);
}
static void
show_advanced(G_GNUC_UNUSED GtkButton *button, AccountCreationWizard *view)
{
AccountCreationWizardPrivate *priv = ACCOUNT_CREATION_WIZARD_GET_PRIVATE(view);
gtk_widget_set_visible(GTK_WIDGET(priv->button_new_sip_account), !gtk_widget_is_visible(GTK_WIDGET(priv->button_new_sip_account)));
}
static void
create_new_sip_account(G_GNUC_UNUSED GtkButton *button, AccountCreationWizard *view)
{
lrc::api::NewAccountModel::createNewAccount(lrc::api::profile::Type::SIP, "SIP");
g_signal_emit(G_OBJECT(view), account_creation_wizard_signals[ACCOUNT_CREATION_COMPLETED], 0);
g_object_unref(view);
}
static void
entries_existing_account_changed(G_GNUC_UNUSED GtkEntry *entry, AccountCreationWizard *view)
{
......@@ -647,6 +576,8 @@ build_creation_wizard_view(AccountCreationWizard *view, gboolean show_cancel_but
g_signal_connect_swapped(priv->button_new_account, "clicked", G_CALLBACK(account_creation_wizard_show_preview), view);
g_signal_connect_swapped(priv->button_existing_account, "clicked", G_CALLBACK(show_existing_account), view);
g_signal_connect(priv->button_wizard_cancel, "clicked", G_CALLBACK(wizard_cancel_clicked), view);
g_signal_connect(priv->button_show_advanced, "clicked", G_CALLBACK(show_advanced), view);
g_signal_connect(priv->button_new_sip_account, "clicked", G_CALLBACK(create_new_sip_account), view);
/* account_creation signals */
g_signal_connect_swapped(priv->entry_username, "changed", G_CALLBACK(entries_new_account_changed), view);
......@@ -670,6 +601,16 @@ build_creation_wizard_view(AccountCreationWizard *view, gboolean show_cancel_but
g_signal_connect_swapped(priv->button_error_view_ok, "clicked", G_CALLBACK(show_choose_account_type), view);
show_choose_account_type(view);
auto provider = gtk_css_provider_new();
gtk_css_provider_load_from_data(provider,
".black { color: grey; font-size: 0.8em; }\
.transparent-button { margin-left: 10px; border: 0; background-color: rgba(0,0,0,0); margin-right: 0; padding-right: 0;}",
-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);
}
GtkWidget *
......
......@@ -21,6 +21,12 @@
#include <gtk/gtk.h>
#include <string>
#include <api/account.h>
#include "accountinfopointer.h"
G_BEGIN_DECLS
#define ACCOUNT_CREATION_WIZARD_TYPE (account_creation_wizard_get_type ())
......@@ -37,5 +43,7 @@ GtkWidget *account_creation_wizard_new (bool cancel_button);
void account_creation_wizard_show_preview (AccountCreationWizard *win, gboolean show_preview = TRUE);
void account_creation_wizard_cancel (AccountCreationWizard *win);
void account_creation_wizard_account_added (AccountCreationWizard *view, AccountInfoPointer const & accountInfo);
void account_creation_show_error_view (AccountCreationWizard *view, const std::string& id);
G_END_DECLS
......@@ -670,8 +670,6 @@ build_tab_view(AccountGeneralTab *view)
label = gtk_label_new(_("Username"));
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_grid_attach(GTK_GRID(priv->grid_account), label, 0, grid_row, 1, 1);
gtk_widget_show_all(priv->grid_account);
auto username_registration_box = username_registration_box_new(*priv->accountInfo_, TRUE);
gtk_grid_attach(GTK_GRID(priv->grid_account), username_registration_box, 1, grid_row, 2, 2);
gtk_widget_show(username_registration_box);
......
......@@ -21,10 +21,10 @@
#include "avatarmanipulation.h"
/* LRC */
#include <api/newaccountmodel.h>
#include <globalinstances.h>
#include <person.h>
#include <profile.h>
#include <profilemodel.h>
#include <video/configurationproxy.h>
#include <video/previewmanager.h>
#include <video/devicemodel.h>
......@@ -38,12 +38,12 @@
#include <glib/gi18n.h>
/* size of avatar */
static constexpr int AVATAR_WIDTH = 100; /* px */
static constexpr int AVATAR_HEIGHT = 100; /* px */
static constexpr int AVATAR_WIDTH = 150; /* px */
static constexpr int AVATAR_HEIGHT = 150; /* px */
/* size of video widget */
static constexpr int VIDEO_WIDTH = 300; /* px */
static constexpr int VIDEO_HEIGHT = 200; /* px */
static constexpr int VIDEO_WIDTH = 150; /* px */
static constexpr int VIDEO_HEIGHT = 150; /* px */
struct _AvatarManipulation
{
......@@ -59,6 +59,9 @@ typedef struct _AvatarManipulationPrivate AvatarManipulationPrivate;
struct _AvatarManipulationPrivate
{
AccountInfoPointer const *accountInfo_ = nullptr;
gchar* temporaryAvatar = nullptr;
GtkWidget *stack_avatar_manipulation;
GtkWidget *video_widget;
GtkWidget *box_views_and_controls;
......@@ -131,27 +134,39 @@ avatar_manipulation_finalize(GObject *object)
}
GtkWidget*
avatar_manipulation_new(void)
avatar_manipulation_new(AccountInfoPointer const & accountInfo)
{
// a profile must exist
g_return_val_if_fail(ProfileModel::instance().selectedProfile(), NULL);
gpointer view = g_object_new(AVATAR_MANIPULATION_TYPE, NULL);
auto* priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
priv->accountInfo_ = &accountInfo;
return (GtkWidget *)g_object_new(AVATAR_MANIPULATION_TYPE, NULL);
set_state(AVATAR_MANIPULATION(view), AVATAR_MANIPULATION_STATE_CURRENT);
return reinterpret_cast<GtkWidget*>(view);
}
GtkWidget*
avatar_manipulation_new_from_wizard(void)
{
auto self = avatar_manipulation_new();
// a profile must exist
gpointer view = g_object_new(AVATAR_MANIPULATION_TYPE, NULL);
/* in this mode, we want to automatically go to the PHOTO avatar state, unless one already exists */
if (!ProfileModel::instance().selectedProfile()->person()->photo().isValid()) {
// check if there is a camera
if (Video::DeviceModel::instance().rowCount() > 0)
set_state(AVATAR_MANIPULATION(self), AVATAR_MANIPULATION_STATE_PHOTO);
}
auto* priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
priv->accountInfo_ = nullptr;
set_state(AVATAR_MANIPULATION(view), AVATAR_MANIPULATION_STATE_CURRENT);
return self;
return reinterpret_cast<GtkWidget*>(view);
}
gchar*
avatar_manipulation_get_temporary(AvatarManipulation *view)
{
g_return_val_if_fail(IS_AVATAR_MANIPULATION(view), nullptr);
AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
return priv->temporaryAvatar;
}
static void
......@@ -215,17 +230,19 @@ set_state(AvatarManipulation *self, AvatarManipulationState state)
case AVATAR_MANIPULATION_STATE_CURRENT:
{
/* get the current or default profile avatar */
auto photo = GlobalInstances::pixmapManipulator().contactPhoto(
ProfileModel::instance().selectedProfile()->person(),
QSize(AVATAR_WIDTH, AVATAR_HEIGHT),
false);
std::shared_ptr<GdkPixbuf> pixbuf_photo = photo.value<std::shared_ptr<GdkPixbuf>>();
if (photo.isValid()) {
gtk_image_set_from_pixbuf (GTK_IMAGE(priv->image_avatar), pixbuf_photo.get());
} else {
g_warning("invlid pixbuf");
auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
auto photo = default_scaled;
if ((priv->accountInfo_ && (*priv->accountInfo_)) || priv->temporaryAvatar) {
auto photostr = priv->temporaryAvatar? priv->temporaryAvatar : (*priv->accountInfo_)->profileInfo.avatar;
QByteArray byteArray(photostr.c_str(), photostr.length());
QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
if (avatar.isValid()) {
photo = pixbuf_photo;
}
}
gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo.get());
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack_views), "page_avatar");
......@@ -341,9 +358,15 @@ set_avatar(AvatarManipulation *self)
QByteArray png_q_byte_array = QByteArray::fromRawData(png_buffer_signed, png_buffer_size).toBase64();
/* save in profile */
QVariant photo = GlobalInstances::pixmapManipulator().personPhoto(png_q_byte_array);
ProfileModel::instance().selectedProfile()->person()->setPhoto(photo);
ProfileModel::instance().selectedProfile()->save();
if (priv->accountInfo_ && (*priv->accountInfo_)) {
try {
(*priv->accountInfo_)->accountModel->setAvatar((*priv->accountInfo_)->id, png_q_byte_array.toStdString());
} catch (std::out_of_range&) {
g_warning("Can't set avatar for unknown account");
}
} else {
priv->temporaryAvatar = g_strdup(png_q_byte_array.toStdString().c_str());
}
g_free(png_buffer_signed);
g_object_unref(selector_pixbuf);
......
......@@ -21,6 +21,10 @@
#define _AVATARMANIPULATION_H
#include <gtk/gtk.h>
#include <api/account.h>
#include <api/profile.h>
#include "accountinfopointer.h"
G_BEGIN_DECLS
......@@ -53,12 +57,13 @@ typedef enum
} AvatarManipulationState;
GType avatar_manipulation_get_type (void) G_GNUC_CONST;
GtkWidget *avatar_manipulation_new (void);
GType avatar_manipulation_get_type (void) G_GNUC_CONST;
GtkWidget *avatar_manipulation_new (AccountInfoPointer const & accountInfo);
/* used from the account creation wizard */
GtkWidget *avatar_manipulation_new_from_wizard(void);
void avatar_manipulation_wizard_completed(AvatarManipulation *);
gchar* avatar_manipulation_get_temporary (AvatarManipulation *view);
G_END_DECLS
......
......@@ -26,8 +26,6 @@
// LRC
#include <person.h>
#include <profile.h>
#include <profilemodel.h>
#include <categorizedhistorymodel.h>
#include <media/recordingmodel.h>
......@@ -66,9 +64,6 @@ struct _GeneralSettingsViewPrivate
GtkWidget *checkbutton_searchentryplacescall;
GtkWidget *radiobutton_chatright;
GtkWidget *radiobutton_chatbottom;
GtkWidget *box_profil_settings;
GtkWidget *avatarmanipulation;
GtkWidget *profile_name;
GtkWidget *button_choose_downloads_directory;
/* history settings */
......@@ -98,9 +93,6 @@ general_settings_view_dispose(GObject *object)
g_clear_object(&priv->settings);
//make sure the VideoWidget is destroyed
general_settings_view_show_profile(GENERAL_SETTINGS_VIEW(object), FALSE);
G_OBJECT_CLASS(general_settings_view_parent_class)->dispose(object);
}
......@@ -330,7 +322,6 @@ general_settings_view_class_init(GeneralSettingsViewClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatbottom);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, adjustment_history_duration);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, button_clear_history);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, box_profil_settings);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, button_choose_downloads_directory);
general_settings_view_signals[CLEAR_ALL_HISTORY] = g_signal_new (
......@@ -382,49 +373,3 @@ general_settings_view_new(GtkWidget* ring_main_window_pointer)
return (GtkWidget *)view;
}
static void
change_profile_name(GtkEntry *entry)
{
auto profile = ProfileModel::instance().selectedProfile();
profile->person()->setFormattedName(gtk_entry_get_text(entry));
profile->save();
}
void
general_settings_view_show_profile(GeneralSettingsView *self, gboolean show_profile)
{
g_return_if_fail(GENERAL_SETTINGS_VIEW(self));
GeneralSettingsViewPrivate *priv = GENERAL_SETTINGS_VIEW_GET_PRIVATE(self);
/* We will construct and destroy the profile (AvatarManipulation widget) each time the profile
* should be visible and hidden, respectively. It is not the "prettiest" way of doing things,
* but this way we ensure 1. that the profile is updated correctly when it is shown and 2. that
* the VideoWidget inside is destroyed when it is not being shown.
*/
if (show_profile) {
/* avatar manipulation widget */
priv->avatarmanipulation = avatar_manipulation_new();
gtk_widget_set_halign(priv->box_profil_settings, GtkAlign::GTK_ALIGN_CENTER);
gtk_box_pack_start(GTK_BOX(priv->box_profil_settings), priv->avatarmanipulation, true, true, 0);
gtk_widget_set_visible(priv->avatarmanipulation, true);
/* print the profile name. as long as we have only one profil, profil name = person name (a.k.a formatedName) */
priv->profile_name = gtk_entry_new();