/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "app/paths/Paths.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "utils/Utils.hpp"
#include "utils/Constants.hpp"
#include "AssistantModel.hpp"
#ifdef ENABLE_OAUTH2
#include "components/authentication/OAuth2Model.hpp"
#endif
#ifdef ENABLE_QRCODE
#include
#endif
#include
#include
#include
#include
// =============================================================================
using namespace std;
class AssistantModel::Handlers : public linphone::AccountCreatorListener {
public:
Handlers (AssistantModel *assistant) {
mAssistant = assistant;
}
private:
void createAccount (const shared_ptr &creator) {
auto account = creator->createAccountInCore();
if(account){
AccountSettingsModel *accountSettingsModel = CoreManager::getInstance()->getAccountSettingsModel();
CoreManager::getInstance()->addingAccount(account->getParams());
auto accountParams = account->getParams()->clone();
auto natPolicy = accountParams->getNatPolicy();
if(natPolicy)
accountParams->setNatPolicy(natPolicy->clone());// Be sure to have a 'ref' entry on a nat_policy. When using default values, the 'ref' entry is lost where it should be pointing to default. We get one by cloning the policy.
if (accountSettingsModel->addOrUpdateAccount(account, accountParams)) {
accountSettingsModel->setDefaultAccount(account);
}
}
}
void onCreateAccount (
const shared_ptr & accountCreator,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreator::Status::AccountCreated){
emit mAssistant->createStatusChanged(QString(""));
}else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->createStatusChanged(tr("requestFailed"));
else if (status == linphone::AccountCreator::Status::ServerError)
emit mAssistant->createStatusChanged(tr("cannotSendSms"));
else
emit mAssistant->createStatusChanged(tr("accountAlreadyExists"));
}
mAssistant->setIsProcessing(false);
}
void onIsAccountExist (
const shared_ptr &creator,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreator::Status::AccountExist || status == linphone::AccountCreator::Status::AccountExistWithAlias) {
createAccount(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->loginStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->loginStatusChanged(tr("requestFailed"));
else
emit mAssistant->loginStatusChanged(tr("loginWithUsernameFailed"));
}
mAssistant->setIsProcessing(false);
}
virtual void onAccountCreationRequestToken(const std::shared_ptr & creator, linphone::AccountCreator::Status status, const std::string & response) override{
if( status == linphone::AccountCreator::Status::RequestOk){
QJsonDocument doc = QJsonDocument::fromJson(response.c_str());
bool error = false;
QVariantMap description = doc.toVariant().toMap();
if( description.contains("token") && description.contains("validation_url")){
QString url = description.value("validation_url").toString();
QString token = description.value("token").toString();
creator->setAccountCreationRequestToken(token.toStdString());
if(!QDesktopServices::openUrl(url)){
qCritical() << "Cannot open validation url for the account creation request token";
emit mAssistant->createStatusChanged("Cannot open validation url for the account creation request token");
mAssistant->setIsProcessing(false);
}else {
emit mAssistant->createStatusChanged("Waiting for validation at " + url);
creator->requestAccountCreationTokenUsingRequestToken();
}
}else{
qCritical() << "The answer of account creation request token doesn't have token and validation_url fields";
emit mAssistant->createStatusChanged("The answer of account creation request token doesn't have token and validation_url fields");
mAssistant->setIsProcessing(false);
}
}else{
qCritical() << "Cannot get request token for account creation (" << (int)status << ")";
emit mAssistant->createStatusChanged("Cannot get request token for account creation (" +QString::number((int)status) + ")");
mAssistant->setIsProcessing(false);
}
}
virtual void onAccountCreationTokenUsingRequestToken(const std::shared_ptr & creator, linphone::AccountCreator::Status status, const std::string & response) override{
if(status == linphone::AccountCreator::Status::RequestOk){
QJsonDocument doc = QJsonDocument::fromJson(response.c_str());
bool error = false;
QVariantMap description = doc.toVariant().toMap();
creator->setToken(description.value("token").toString().toStdString());
// it will automatically use the account creation token.
if (mAssistant->mUsePhoneNumber) {
emit mAssistant->createStatusChanged("Recovering account");
creator->recoverAccount();
}else{
emit mAssistant->createStatusChanged("Creating account");
creator->createAccount();
}
}else
QTimer::singleShot(2000, [creator](){
creator->requestAccountCreationTokenUsingRequestToken();
});
}
void onActivateAccount (
const shared_ptr &creator,
linphone::AccountCreator::Status status,
const string &
) override {
if (
status == linphone::AccountCreator::Status::AccountActivated ||
status == linphone::AccountCreator::Status::AccountAlreadyActivated
) {
if (creator->getEmail().empty())
createAccount(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->activateStatusChanged(tr("requestFailed"));
else
emit mAssistant->activateStatusChanged(tr("smsActivationFailed"));
}
}
void onIsAccountActivated (
const shared_ptr &creator,
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreator::Status::AccountActivated) {
createAccount(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->activateStatusChanged(tr("requestFailed"));
else
emit mAssistant->activateStatusChanged(tr("emailActivationFailed"));
}
mAssistant->setIsProcessing(false);
}
void onRecoverAccount (
const shared_ptr &accountCreator,
linphone::AccountCreator::Status status,
const string &response
) override {
if (status == linphone::AccountCreator::Status::RequestOk) {
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->recoverStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->recoverStatusChanged(tr("requestFailed"));
else if (status == linphone::AccountCreator::Status::ServerError)
emit mAssistant->recoverStatusChanged(tr("cannotSendSms"));
else
emit mAssistant->recoverStatusChanged(tr("loginWithPhoneNumberFailed"));
}
mAssistant->setIsProcessing(false);
}
virtual void onLoginLinphoneAccount(
const std::shared_ptr & creator,
linphone::AccountCreator::Status status,
const std::string & response) override {
if( status == linphone::AccountCreator::Status::RequestOk){
createAccount(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->activateStatusChanged(tr("requestFailed"));
else
emit mAssistant->activateStatusChanged(tr("smsActivationFailed"));
}
}
private:
AssistantModel *mAssistant;
};
// -----------------------------------------------------------------------------
AssistantModel::AssistantModel (QObject *parent) : QObject(parent) {
mHandlers = make_shared(this);
shared_ptr core = CoreManager::getInstance()->getCore();
connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::foundQRCode, this, &AssistantModel::onQRCodeFound);
mIsReadingQRCode = false;
mIsProcessing = false;
mAccountCreator = core->createAccountCreator(
core->getConfig()->getString("assistant", "xmlrpc_url", Constants::DefaultXmlrpcUri)
);
mAccountCreator->addListener(mHandlers);
connect(this, &AssistantModel::apiReceived, this, &AssistantModel::onApiReceived);
}
AssistantModel::~AssistantModel(){
setIsReadingQRCode(false);
#ifdef ENABLE_OAUTH2
if(oAuth2Model)
oAuth2Model->deleteLater();
oAuth2Model = nullptr;
#endif
}
// -----------------------------------------------------------------------------
void AssistantModel::activate () {
setIsProcessing(true);
if (mAccountCreator->getEmail().empty()){
if(mAccountCreator->getUsername().empty())
mAccountCreator->setUsername(mAccountCreator->getPhoneNumber());
mAccountCreator->loginLinphoneAccount();// It will detect if phone is an alias or not.
}else
mAccountCreator->isAccountActivated();
}
void AssistantModel::create () {
setIsProcessing(true);
emit createStatusChanged("Requesting validation url");
mAccountCreator->requestAccountCreationRequestToken();
}
void AssistantModel::login () {
setIsProcessing(true);
if(mAccountCreator->getUsername().empty())
mAccountCreator->setUsername(mAccountCreator->getPhoneNumber());
if (mUsePhoneNumber) {
emit createStatusChanged("Requesting validation url");
mAccountCreator->requestAccountCreationRequestToken();
return;
}
shared_ptr config(CoreManager::getInstance()->getCore()->getConfig());
if (!config->getString("assistant", "xmlrpc_url", "").empty()) {
mAccountCreator->isAccountExist();
return;
}
// No verification if no xmlrpc url.
auto account = mAccountCreator->createAccountInCore();
if(account){
AccountSettingsModel *accountSettingsModel = CoreManager::getInstance()->getAccountSettingsModel();
if (accountSettingsModel->addOrUpdateAccount(account, account->getParams()->clone())) {
accountSettingsModel->setDefaultAccount(account);
}
emit loginStatusChanged("");
return;
}
// Cannot create new account from account creator. Use addOtherSipAccount directly.
QVariantMap map;
map["sipDomain"] = Utils::coreStringToAppString(config->getString("assistant", "domain", ""));
map["username"] = getUsername();
map["password"] = getPassword();
map["transport"] = LinphoneEnums::toString(LinphoneEnums::fromLinphone(mAccountCreator->getTransport()));
emit loginStatusChanged(addOtherSipAccount(map) ? QString("") : tr("unableToAddAccount"));
setIsProcessing(false);
}
void AssistantModel::reset () {
mCountryCode = QString("");
mAccountCreator->reset();
emit emailChanged(QString(""), QString(""));
emit passwordChanged(QString(""), QString(""));
emit phoneNumberChanged(QString(""), QString(""));
emit usernameChanged(QString(""), QString(""));
}
// -----------------------------------------------------------------------------
bool AssistantModel::addOtherSipAccount (const QVariantMap &map) {
CoreManager *coreManager = CoreManager::getInstance();
shared_ptr factory = linphone::Factory::get();
shared_ptr core = coreManager->getCore();
std::shared_ptr account;
std::string accountIdKey = map["accountIdKey"].toString().toStdString();
if( accountIdKey != "")
account = core->getAccountByIdkey(accountIdKey);
shared_ptr accountParams;
if(account)
accountParams = account->getParams()->clone();
else
accountParams = core->createAccountParams();
const QString domain = map["sipDomain"].toString();
QString sipAddress = QStringLiteral("sip:%1@%2")
.arg(map["username"].toString()).arg(domain);
{
// Server address.
shared_ptr address = factory->createAddress(
Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain))
);
if(!address) {
qWarning() << QStringLiteral("Unable to create address from domain `%1`.")
.arg(domain);
return false;
}
const QString &transport(map["transport"].toString());
if (!transport.isEmpty()) {
LinphoneEnums::TransportType transportType;
LinphoneEnums::fromString(transport, &transportType);
address->setTransport(LinphoneEnums::toLinphone(transportType));
}
if (accountParams->setServerAddress(address)) {
qWarning() << QStringLiteral("Unable to add server address: `%1`.")
.arg(QString::fromStdString(address->asString()));
return false;
}
}
// Sip Address.
shared_ptr address = factory->createAddress(Utils::appStringToCoreString(sipAddress));
if (!address) {
qWarning() << QStringLiteral("Unable to create sip address object from: `%1`.").arg(sipAddress);
return false;
}
address->setDisplayName(Utils::appStringToCoreString(map["displayName"].toString()));
accountParams->setIdentityAddress(address);
// AuthInfo.
core->addAuthInfo(
factory->createAuthInfo(
address->getUsername(), // Username.
"", // User ID.
Utils::appStringToCoreString(map["password"].toString()), // Password.
"", // HA1.
"", // Realm.
address->getDomain() // Domain.
)
);
AccountSettingsModel *accountSettingsModel = coreManager->getAccountSettingsModel();
if (accountSettingsModel->addOrUpdateAccount(account, accountParams)) {
accountSettingsModel->setDefaultAccount(account);
return true;
}
return false;
}
void AssistantModel::createTestAccount(){
}
void AssistantModel::generateQRCode(){
#ifdef ENABLE_QRCODE
auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
flexiAPIClient
->accountProvision()
->then([this](FlexiAPIClient::Response response){
emit newQRCodeReceived(response.json()["provisioning_token"].asCString());
})
->error([this](FlexiAPIClient::Response response){
emit newQRCodeNotReceived(Utils::coreStringToAppString(response.body), response.code);
});
#endif
}
void AssistantModel::requestQRCode(){
#ifdef ENABLE_QRCODE
auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
flexiAPIClient
->accountAuthTokenCreate()
->then([this](FlexiAPIClient::Response response) {
mToken = response.json()["token"].asCString();
emit newQRCodeReceived(mToken);
QTimer::singleShot(5000, this, &AssistantModel::checkLinkingAccount);
})->error([this](FlexiAPIClient::Response response){
qWarning() << response.code << " => " << response.body.c_str();
emit newQRCodeNotReceived(Utils::coreStringToAppString(response.body), response.code);
});
#endif
}
void AssistantModel::readQRCode(){
setIsReadingQRCode(!mIsReadingQRCode);
}
void AssistantModel::newQRCodeNotReceivedTest(){
emit newQRCodeNotReceived("Cannot generate a provisioning key",0);
}
void AssistantModel::checkLinkingAccount(){
#ifdef ENABLE_QRCODE
auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
flexiAPIClient
->accountApiKeyFromAuthTokenGenerate(mToken.toStdString())
->then([this](FlexiAPIClient::Response response)mutable{
emit apiReceived(Utils::coreStringToAppString(response.json()["api_key"].asCString()));
})->error([this](FlexiAPIClient::Response){
QTimer::singleShot(5000, this, &AssistantModel::checkLinkingAccount);
});
#endif
}
void AssistantModel::onApiReceived(QString apiKey){
#ifdef ENABLE_QRCODE
auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
flexiAPIClient->setApiKey(Utils::appStringToCoreString(apiKey).c_str())
->accountProvision()
->then([this](FlexiAPIClient::Response response){
emit provisioningTokenReceived(response.json()["provisioning_token"].asCString());
})->error([this](FlexiAPIClient::Response response){
//it provisioningTokenReceived("token");
emit this->newQRCodeNotReceived("Cannot generate a provisioning key"+(response.body.empty() ? "" : " : " +Utils::coreStringToAppString(response.body)), response.code);
});
#endif
}
void AssistantModel::onQRCodeFound(const std::string & result){
setIsReadingQRCode(false);
emit qRCodeFound(Utils::coreStringToAppString(result));
}
void AssistantModel::attachAccount(const QString& token){
#ifdef ENABLE_QRCODE
auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
flexiAPIClient->
accountAuthTokenAttach(Utils::appStringToCoreString(token))
->then([this](FlexiAPIClient::Response response){
qWarning() << "Attached";
emit qRCodeAttached();
})
->error([this](FlexiAPIClient::Response response){
emit qRCodeNotAttached("Cannot attach"+ (response.body.empty() ? "" : " : " +Utils::coreStringToAppString(response.body)), response.code);
});
#endif
}
bool AssistantModel::isOAuth2Available(){
#ifdef ENABLE_OAUTH2
return OAuth2Model::isAvailable();
#else
return false;
#endif
}
void AssistantModel::requestOauth2(){
#ifdef ENABLE_OAUTH2
if(isOAuth2Available()){
if(oAuth2Model)
oAuth2Model->deleteLater();
oAuth2Model = new OAuth2Model();
connect(oAuth2Model, &OAuth2Model::requestFailed, this, &AssistantModel::oauth2RequestFailed);
connect(oAuth2Model, &OAuth2Model::statusChanged, this, &AssistantModel::oauth2StatusChanged);
connect(oAuth2Model, &OAuth2Model::authenticated, this, &AssistantModel::oauth2AuthenticationGranted);
oAuth2Model->grant();
}
#endif
}
// -----------------------------------------------------------------------------
QString AssistantModel::getEmail () const {
return Utils::coreStringToAppString(mAccountCreator->getEmail());
}
void AssistantModel::setEmail (const QString &email) {
shared_ptr config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (mAccountCreator->setEmail(Utils::appStringToCoreString(email))) {
case linphone::AccountCreator::EmailStatus::Ok:
break;
case linphone::AccountCreator::EmailStatus::Malformed:
error = tr("emailStatusMalformed");
break;
case linphone::AccountCreator::EmailStatus::InvalidCharacters:
error = tr("emailStatusMalformedInvalidCharacters");
break;
}
emit emailChanged(email, error);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getPassword () const {
return Utils::coreStringToAppString(mAccountCreator->getPassword());
}
void AssistantModel::setPassword (const QString &password) {
shared_ptr config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (mAccountCreator->setPassword(Utils::appStringToCoreString(password))) {
case linphone::AccountCreator::PasswordStatus::Ok:
break;
case linphone::AccountCreator::PasswordStatus::TooShort:
error = tr("passwordStatusTooShort").arg(config->getInt("assistant", "password_min_length", 1));
break;
case linphone::AccountCreator::PasswordStatus::TooLong:
error = tr("passwordStatusTooLong").arg(config->getInt("assistant", "password_max_length", -1));
break;
case linphone::AccountCreator::PasswordStatus::InvalidCharacters:
error = tr("passwordStatusInvalidCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "password_regex", "")));
break;
case linphone::AccountCreator::PasswordStatus::MissingCharacters:
error = tr("passwordStatusMissingCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "missing_characters", "")));
break;
}
emit passwordChanged(password, error);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getCountryCode () const {
return mCountryCode;
}
void AssistantModel::setCountryCode (const QString &countryCode) {
mCountryCode = countryCode;
mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(mPhoneNumber), Utils::appStringToCoreString(mCountryCode));
emit countryCodeChanged(countryCode);
emit computedPhoneNumberChanged();
}
// -----------------------------------------------------------------------------
bool AssistantModel::getUsePhoneNumber() const{
return mUsePhoneNumber;
}
void AssistantModel::setUsePhoneNumber(bool use) {
if(mUsePhoneNumber != use){
mUsePhoneNumber = use;
emit usePhoneNumberChanged();
}
}
QString AssistantModel::getPhoneNumber () const {
return mPhoneNumber;
}
QString AssistantModel::getComputedPhoneNumber () const{
return Utils::coreStringToAppString(mAccountCreator->getPhoneNumber());
}
void AssistantModel::setPhoneNumber (const QString &phoneNumber) {
shared_ptr config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (static_cast(
mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(phoneNumber), Utils::appStringToCoreString(mCountryCode))
)) {
case linphone::AccountCreator::PhoneNumberStatus::Ok:
break;
case linphone::AccountCreator::PhoneNumberStatus::Invalid:
error = tr("phoneNumberStatusInvalid");
break;
case linphone::AccountCreator::PhoneNumberStatus::TooShort:
error = tr("phoneNumberStatusTooShort");
break;
case linphone::AccountCreator::PhoneNumberStatus::TooLong:
error = tr("phoneNumberStatusTooLong");
break;
case linphone::AccountCreator::PhoneNumberStatus::InvalidCountryCode:
error = tr("phoneNumberStatusInvalidCountryCode");
break;
default:
break;
}
mPhoneNumber = phoneNumber;
emit phoneNumberChanged(phoneNumber, error);
emit computedPhoneNumberChanged();
}
QString AssistantModel::getPhoneCountryCode() const {
return mPhoneCountryCode;
}
void AssistantModel::setPhoneCountryCode(const QString &code) {
if( mPhoneCountryCode != code) {
mPhoneCountryCode = code;
emit phoneCountryCodeChanged();
}
}
// -----------------------------------------------------------------------------
QString AssistantModel::getUsername () const {
return Utils::coreStringToAppString(mAccountCreator->getUsername());
}
void AssistantModel::setUsername (const QString &username) {
emit usernameChanged(
username,
mapAccountCreatorUsernameStatusToString(
mAccountCreator->setUsername(Utils::appStringToCoreString(username))
)
);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getDisplayName () const {
return Utils::coreStringToAppString(mAccountCreator->getDisplayName());
}
void AssistantModel::setDisplayName (const QString &displayName) {
emit displayNameChanged(
displayName,
mapAccountCreatorUsernameStatusToString(
mAccountCreator->setDisplayName(Utils::appStringToCoreString(displayName))
)
);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getActivationCode () const {
return Utils::coreStringToAppString(mAccountCreator->getActivationCode());
}
void AssistantModel::setActivationCode (const QString &activationCode) {
mAccountCreator->setActivationCode(Utils::appStringToCoreString(activationCode));
emit activationCodeChanged(activationCode);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getConfigFilename () const {
return mConfigFilename;
}
void AssistantModel::setConfigFilename (const QString &configFilename) {
mConfigFilename = configFilename;
QString configPath = Utils::coreStringToAppString(Paths::getAssistantConfigDirPath()) + configFilename;
qInfo() << QStringLiteral("Set config on assistant: `%1`.").arg(configPath);
CoreManager::getInstance()->getCore()->getConfig()->loadFromXmlFile(
Utils::appStringToCoreString(configPath)
);
emit configFilenameChanged(configFilename);
}
bool AssistantModel::getIsReadingQRCode() const{
return mIsReadingQRCode;
}
void AssistantModel::setIsReadingQRCode(bool isReading){
if( mIsReadingQRCode != isReading){
if( CoreManager::getInstance()->getCore()->qrcodeVideoPreviewEnabled() != isReading){
CoreManager::getInstance()->getCore()->enableQrcodeVideoPreview(isReading);
//CoreManager::getInstance()->getCore()->enableVideoPreview(isReading);
}
mIsReadingQRCode = isReading;
emit isReadingQRCodeChanged();
}
}
bool AssistantModel::getIsProcessing() const{
return mIsProcessing;
}
void AssistantModel::setIsProcessing(bool isProcessing){
if(mIsProcessing != isProcessing){
mIsProcessing = isProcessing;
emit isProcessingChanged();
}
}
// -----------------------------------------------------------------------------
QString AssistantModel::mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const {
shared_ptr config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
switch (status) {
case linphone::AccountCreator::UsernameStatus::Ok:
break;
case linphone::AccountCreator::UsernameStatus::TooShort:
error = tr("usernameStatusTooShort").arg(config->getInt("assistant", "username_min_length", 1));
break;
case linphone::AccountCreator::UsernameStatus::TooLong:
error = tr("usernameStatusTooLong").arg(config->getInt("assistant", "username_max_length", -1));
break;
case linphone::AccountCreator::UsernameStatus::InvalidCharacters:
error = tr("usernameStatusInvalidCharacters")
.arg(Utils::coreStringToAppString(config->getString("assistant", "username_regex", "")));
break;
case linphone::AccountCreator::UsernameStatus::Invalid:
error = tr("usernameStatusInvalid");
break;
}
return error;
}