register
This commit is contained in:
parent
16757d0a85
commit
5beb0b84d0
41 changed files with 1119 additions and 271 deletions
|
|
@ -58,6 +58,7 @@
|
||||||
#include "core/participant/ParticipantProxy.hpp"
|
#include "core/participant/ParticipantProxy.hpp"
|
||||||
#include "core/phone-number/PhoneNumber.hpp"
|
#include "core/phone-number/PhoneNumber.hpp"
|
||||||
#include "core/phone-number/PhoneNumberProxy.hpp"
|
#include "core/phone-number/PhoneNumberProxy.hpp"
|
||||||
|
#include "core/register/RegisterPage.hpp"
|
||||||
#include "core/screen/ScreenList.hpp"
|
#include "core/screen/ScreenList.hpp"
|
||||||
#include "core/screen/ScreenProxy.hpp"
|
#include "core/screen/ScreenProxy.hpp"
|
||||||
#include "core/search/MagicSearchProxy.hpp"
|
#include "core/search/MagicSearchProxy.hpp"
|
||||||
|
|
@ -294,8 +295,17 @@ void App::initCore() {
|
||||||
|
|
||||||
void App::initCppInterfaces() {
|
void App::initCppInterfaces() {
|
||||||
qmlRegisterSingletonType<LoginPage>(
|
qmlRegisterSingletonType<LoginPage>(
|
||||||
Constants::MainQmlUri, 1, 0, "LoginPageCpp",
|
Constants::MainQmlUri, 1, 0, "LoginPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
|
||||||
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new LoginPage(engine); });
|
static auto loginPage = new LoginPage(engine);
|
||||||
|
App::getInstance()->mEngine->setObjectOwnership(loginPage, QQmlEngine::CppOwnership);
|
||||||
|
return loginPage;
|
||||||
|
});
|
||||||
|
qmlRegisterSingletonType<RegisterPage>(
|
||||||
|
Constants::MainQmlUri, 1, 0, "RegisterPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
|
||||||
|
static RegisterPage *registerPage = new RegisterPage();
|
||||||
|
App::getInstance()->mEngine->setObjectOwnership(registerPage, QQmlEngine::CppOwnership);
|
||||||
|
return registerPage;
|
||||||
|
});
|
||||||
qmlRegisterSingletonType<Constants>(
|
qmlRegisterSingletonType<Constants>(
|
||||||
"ConstantsCpp", 1, 0, "ConstantsCpp",
|
"ConstantsCpp", 1, 0, "ConstantsCpp",
|
||||||
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new Constants(engine); });
|
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new Constants(engine); });
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ list(APPEND _LINPHONEAPP_SOURCES
|
||||||
core/phone-number/PhoneNumber.cpp
|
core/phone-number/PhoneNumber.cpp
|
||||||
core/phone-number/PhoneNumberList.cpp
|
core/phone-number/PhoneNumberList.cpp
|
||||||
core/phone-number/PhoneNumberProxy.cpp
|
core/phone-number/PhoneNumberProxy.cpp
|
||||||
|
core/register/RegisterPage.cpp
|
||||||
|
|
||||||
core/search/MagicSearchList.cpp
|
core/search/MagicSearchList.cpp
|
||||||
core/search/MagicSearchProxy.cpp
|
core/search/MagicSearchProxy.cpp
|
||||||
|
|
|
||||||
|
|
@ -71,14 +71,27 @@ void LoginPage::login(const QString &username, const QString &password) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case linphone::RegistrationState::Failed: {
|
case linphone::RegistrationState::Failed: {
|
||||||
emit accountManager->errorMessageChanged(*error);
|
emit accountManager->errorMessageChanged(*error);
|
||||||
accountManager->deleteLater();
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case linphone::RegistrationState::Ok: {
|
case linphone::RegistrationState::Ok: {
|
||||||
emit accountManager->errorMessageChanged("");
|
emit accountManager->errorMessageChanged("");
|
||||||
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case linphone::RegistrationState::Cleared: {
|
||||||
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case linphone::RegistrationState::Cleared:
|
|
||||||
case linphone::RegistrationState::None:
|
case linphone::RegistrationState::None:
|
||||||
case linphone::RegistrationState::Progress:
|
case linphone::RegistrationState::Progress:
|
||||||
case linphone::RegistrationState::Refreshing:
|
case linphone::RegistrationState::Refreshing:
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PhoneNumber.hpp"
|
#include "PhoneNumber.hpp"
|
||||||
|
#include "core/App.hpp"
|
||||||
#include "tool/Utils.hpp"
|
#include "tool/Utils.hpp"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
DEFINE_ABSTRACT_OBJECT(PhoneNumber)
|
DEFINE_ABSTRACT_OBJECT(PhoneNumber)
|
||||||
|
|
||||||
|
QSharedPointer<PhoneNumber> PhoneNumber::create(const std::shared_ptr<linphone::DialPlan> &dialPlan) {
|
||||||
|
auto sharedPointer = QSharedPointer<PhoneNumber>(new PhoneNumber(dialPlan), &QObject::deleteLater);
|
||||||
|
sharedPointer->moveToThread(App::getInstance()->thread());
|
||||||
|
return sharedPointer;
|
||||||
|
}
|
||||||
|
|
||||||
PhoneNumber::PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan) : QObject(nullptr) {
|
PhoneNumber::PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan) : QObject(nullptr) {
|
||||||
// Should be call from model Thread
|
// Should be call from model Thread
|
||||||
mustBeInLinphoneThread(getClassName());
|
mustBeInLinphoneThread(getClassName());
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class PhoneNumber : public QObject, public AbstractObject {
|
||||||
Q_PROPERTY(QString country MEMBER mCountry CONSTANT)
|
Q_PROPERTY(QString country MEMBER mCountry CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Should be call from model Thread. Will be automatically in App thread after initialization
|
static QSharedPointer<PhoneNumber> create(const std::shared_ptr<linphone::DialPlan> &dialPlan);
|
||||||
PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan);
|
PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan);
|
||||||
~PhoneNumber();
|
~PhoneNumber();
|
||||||
|
|
||||||
|
|
@ -47,6 +47,7 @@ public:
|
||||||
QString mInternationalCallPrefix;
|
QString mInternationalCallPrefix;
|
||||||
QString mCountry;
|
QString mCountry;
|
||||||
|
|
||||||
|
private:
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,22 +28,28 @@
|
||||||
|
|
||||||
DEFINE_ABSTRACT_OBJECT(PhoneNumberList)
|
DEFINE_ABSTRACT_OBJECT(PhoneNumberList)
|
||||||
|
|
||||||
|
QSharedPointer<PhoneNumberList> PhoneNumberList::create() {
|
||||||
|
auto model = QSharedPointer<PhoneNumberList>(new PhoneNumberList(), &QObject::deleteLater);
|
||||||
|
model->moveToThread(App::getInstance()->thread());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
PhoneNumberList::PhoneNumberList(QObject *parent) : ListProxy(parent) {
|
PhoneNumberList::PhoneNumberList(QObject *parent) : ListProxy(parent) {
|
||||||
mustBeInMainThread(getClassName());
|
mustBeInMainThread(getClassName());
|
||||||
App::postModelAsync([=]() {
|
App::postModelAsync([=]() {
|
||||||
// Model thread.
|
// Model thread.
|
||||||
auto dialPlans = linphone::Factory::get()->getDialPlans();
|
auto dialPlans = linphone::Factory::get()->getDialPlans();
|
||||||
QList<QSharedPointer<PhoneNumber>> numbers;
|
QList<QSharedPointer<PhoneNumber>> *numbers = new QList<QSharedPointer<PhoneNumber>>();
|
||||||
QVector<QVariantMap> results;
|
|
||||||
for (auto it : dialPlans) {
|
for (auto it : dialPlans) {
|
||||||
auto numberModel = QSharedPointer<PhoneNumber>::create(it);
|
auto numberModel = PhoneNumber::create(it);
|
||||||
numberModel->moveToThread(this->thread());
|
numbers->push_back(numberModel);
|
||||||
numbers.push_back(numberModel);
|
|
||||||
}
|
}
|
||||||
// Invoke for adding stuffs in caller thread
|
// Invoke for adding stuffs in caller thread
|
||||||
QMetaObject::invokeMethod(this, [this, numbers]() {
|
QMetaObject::invokeMethod(this, [this, numbers]() {
|
||||||
mustBeInMainThread(this->log().arg(Q_FUNC_INFO));
|
mustBeInMainThread(this->log().arg(Q_FUNC_INFO));
|
||||||
add(numbers);
|
resetData();
|
||||||
|
add(*numbers);
|
||||||
|
delete numbers;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@
|
||||||
class PhoneNumberList : public ListProxy, public AbstractObject {
|
class PhoneNumberList : public ListProxy, public AbstractObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
static QSharedPointer<PhoneNumberList> create();
|
||||||
PhoneNumberList(QObject *parent = Q_NULLPTR);
|
PhoneNumberList(QObject *parent = Q_NULLPTR);
|
||||||
~PhoneNumberList();
|
~PhoneNumberList();
|
||||||
|
|
||||||
|
private:
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,19 @@
|
||||||
|
|
||||||
#include "PhoneNumberProxy.hpp"
|
#include "PhoneNumberProxy.hpp"
|
||||||
#include "PhoneNumber.hpp"
|
#include "PhoneNumber.hpp"
|
||||||
#include "PhoneNumberList.hpp"
|
|
||||||
|
DEFINE_ABSTRACT_OBJECT(PhoneNumberProxy)
|
||||||
|
|
||||||
PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : SortFilterProxy(parent) {
|
PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||||
setSourceModel(new PhoneNumberList(this));
|
mPhoneNumberList = PhoneNumberList::create();
|
||||||
|
setSourceModel(mPhoneNumberList.get());
|
||||||
sort(0);
|
sort(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhoneNumberProxy::~PhoneNumberProxy() {
|
||||||
|
setSourceModel(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
QString PhoneNumberProxy::getFilterText() const {
|
QString PhoneNumberProxy::getFilterText() const {
|
||||||
return mFilterText;
|
return mFilterText;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,21 +22,24 @@
|
||||||
#define PHONE_NUMBER_PROXY_H_
|
#define PHONE_NUMBER_PROXY_H_
|
||||||
|
|
||||||
#include "../proxy/SortFilterProxy.hpp"
|
#include "../proxy/SortFilterProxy.hpp"
|
||||||
|
#include "PhoneNumberList.hpp"
|
||||||
|
#include "tool/AbstractObject.hpp"
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
class PhoneNumberProxy : public SortFilterProxy {
|
class PhoneNumberProxy : public SortFilterProxy, public AbstractObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PhoneNumberProxy(QObject *parent = Q_NULLPTR);
|
PhoneNumberProxy(QObject *parent = Q_NULLPTR);
|
||||||
|
~PhoneNumberProxy();
|
||||||
|
|
||||||
QString getFilterText() const;
|
QString getFilterText() const;
|
||||||
void setFilterText(const QString &filter);
|
void setFilterText(const QString &filter);
|
||||||
|
|
||||||
Q_INVOKABLE int findIndexByCountryCallingCode(const QString& countryCallingCode);
|
Q_INVOKABLE int findIndexByCountryCallingCode(const QString &countryCallingCode);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filterTextChanged();
|
void filterTextChanged();
|
||||||
|
|
@ -46,6 +49,10 @@ protected:
|
||||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
|
|
||||||
QString mFilterText;
|
QString mFilterText;
|
||||||
|
QSharedPointer<PhoneNumberList> mPhoneNumberList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
107
Linphone/core/register/RegisterPage.cpp
Normal file
107
Linphone/core/register/RegisterPage.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RegisterPage.hpp"
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "core/App.hpp"
|
||||||
|
|
||||||
|
#include "model/account/AccountManager.hpp"
|
||||||
|
|
||||||
|
DEFINE_ABSTRACT_OBJECT(RegisterPage)
|
||||||
|
|
||||||
|
RegisterPage::RegisterPage(QObject *parent) : QObject(parent) {
|
||||||
|
mustBeInMainThread(getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterPage::~RegisterPage() {
|
||||||
|
mustBeInMainThread("~" + getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterPage::registerNewAccount(const QString &username,
|
||||||
|
const QString &password,
|
||||||
|
const QString &email,
|
||||||
|
const QString &phoneNumber) {
|
||||||
|
App::postModelAsync([=]() {
|
||||||
|
// Create on Model thread.
|
||||||
|
// registrationFailed(error); });
|
||||||
|
AccountManager::RegisterType registerType;
|
||||||
|
QString address;
|
||||||
|
if (email.isEmpty()) {
|
||||||
|
registerType = AccountManager::RegisterType::PhoneNumber;
|
||||||
|
address = phoneNumber;
|
||||||
|
} else {
|
||||||
|
registerType = AccountManager::RegisterType::Email;
|
||||||
|
address = email;
|
||||||
|
}
|
||||||
|
auto accountManager = new AccountManager();
|
||||||
|
connect(accountManager, &AccountManager::newAccountCreationSucceed, this,
|
||||||
|
[this, registerType, address, accountManager](const QString &sipAddress) mutable {
|
||||||
|
App::postCoreAsync([this, registerType, address, sipAddress, accountManager]() {
|
||||||
|
emit newAccountCreationSucceed(registerType == AccountManager::RegisterType::Email, address,
|
||||||
|
sipAddress);
|
||||||
|
});
|
||||||
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(accountManager, &AccountManager::registerNewAccountFailed, this,
|
||||||
|
[this, accountManager](const QString &errorMessage) mutable {
|
||||||
|
App::postCoreAsync(
|
||||||
|
[this, errorMessage, accountManager]() { emit registerNewAccountFailed(errorMessage); });
|
||||||
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(accountManager, &AccountManager::errorInField, this,
|
||||||
|
[this, accountManager](const QString &field, const QString &errorMessage) mutable {
|
||||||
|
App::postCoreAsync([this, field, errorMessage]() { emit errorInField(field, errorMessage); });
|
||||||
|
if (accountManager) {
|
||||||
|
accountManager->deleteLater();
|
||||||
|
accountManager = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(accountManager, &AccountManager::tokenConversionSucceed, this,
|
||||||
|
[this, accountManager]() { App::postCoreAsync([this]() { emit tokenConversionSucceed(); }); });
|
||||||
|
accountManager->registerNewAccount(username, password, registerType, address);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterPage::linkNewAccountUsingCode(const QString &code,
|
||||||
|
bool registerWithEmail,
|
||||||
|
const QString &sipIdentityAddress) {
|
||||||
|
App::postModelAsync([=]() {
|
||||||
|
auto accountManager = new AccountManager();
|
||||||
|
connect(accountManager, &AccountManager::linkingNewAccountWithCodeSucceed, this, [this, accountManager]() {
|
||||||
|
App::postCoreAsync([this]() { emit linkingNewAccountWithCodeSucceed(); });
|
||||||
|
accountManager->deleteLater();
|
||||||
|
});
|
||||||
|
connect(accountManager, &AccountManager::linkingNewAccountWithCodeFailed, this,
|
||||||
|
[this, accountManager](const QString &errorMessage) {
|
||||||
|
App::postCoreAsync([this, errorMessage]() { emit linkingNewAccountWithCodeFailed(errorMessage); });
|
||||||
|
accountManager->deleteLater();
|
||||||
|
});
|
||||||
|
accountManager->linkNewAccountUsingCode(
|
||||||
|
code, registerWithEmail ? AccountManager::RegisterType::Email : AccountManager::RegisterType::PhoneNumber,
|
||||||
|
sipIdentityAddress);
|
||||||
|
});
|
||||||
|
}
|
||||||
68
Linphone/core/register/RegisterPage.hpp
Normal file
68
Linphone/core/register/RegisterPage.hpp
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGISTERPAGE_H_
|
||||||
|
#define REGISTERPAGE_H_
|
||||||
|
|
||||||
|
#include "tool/AbstractObject.hpp"
|
||||||
|
#include "tool/thread/SafeConnection.hpp"
|
||||||
|
#include <QObject>
|
||||||
|
#include <linphone++/linphone.hh>
|
||||||
|
|
||||||
|
class AccountManager;
|
||||||
|
class RegisterPage : public QObject, public AbstractObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterPage(QObject *parent = nullptr);
|
||||||
|
~RegisterPage();
|
||||||
|
|
||||||
|
// Q_PROPERTY(linphone::RegistrationState registrationState READ getRegistrationState NOTIFY
|
||||||
|
// registrationStateChanged) Q_PROPERTY(QString errorMessage READ getErrorMessage NOTIFY errorMessageChanged)
|
||||||
|
|
||||||
|
Q_INVOKABLE void registerNewAccount(const QString &username,
|
||||||
|
const QString &password,
|
||||||
|
const QString &email,
|
||||||
|
const QString &phoneNumber);
|
||||||
|
Q_INVOKABLE void
|
||||||
|
linkNewAccountUsingCode(const QString &code, bool registerWithEmail, const QString &sipIdentityAddress);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void registrationFailed(const QString &errorMessage);
|
||||||
|
void errorMessageChanged();
|
||||||
|
void newAccountCreationSucceed(bool withEmail, // false if creation with phone number
|
||||||
|
const QString &address,
|
||||||
|
const QString &sipIdentityAddress);
|
||||||
|
void registerNewAccountFailed(const QString &error);
|
||||||
|
void errorInField(const QString &field, const QString &error);
|
||||||
|
void tokenConversionSucceed();
|
||||||
|
void linkingNewAccountWithCodeSucceed();
|
||||||
|
void linkingNewAccountWithCodeFailed(const QString &error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
linphone::RegistrationState mRegistrationState = linphone::RegistrationState::None;
|
||||||
|
QSharedPointer<SafeConnection<RegisterPage, AccountManager>> mAccountManagerConnection;
|
||||||
|
std::shared_ptr<AccountManager> mAccountManager;
|
||||||
|
QString mErrorMessage;
|
||||||
|
|
||||||
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -3,6 +3,7 @@ backend=1
|
||||||
# 1 means FlexiAPI, 0 is XMLRPC
|
# 1 means FlexiAPI, 0 is XMLRPC
|
||||||
url=https://subscribe.linphone.org/api/
|
url=https://subscribe.linphone.org/api/
|
||||||
# replace above URL by https://staging-subscribe.linphone.org/api/ for testing
|
# replace above URL by https://staging-subscribe.linphone.org/api/ for testing
|
||||||
|
# url=https://flexisip-staging-master.linphone.org/api/
|
||||||
|
|
||||||
[alerts]
|
[alerts]
|
||||||
alerts_enabled=1
|
alerts_enabled=1
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
list(APPEND _LINPHONEAPP_SOURCES
|
list(APPEND _LINPHONEAPP_SOURCES
|
||||||
model/account/AccountModel.cpp
|
model/account/AccountModel.cpp
|
||||||
model/account/AccountManager.cpp
|
model/account/AccountManager.cpp
|
||||||
|
model/account/AccountManagerServicesModel.cpp
|
||||||
|
model/account/AccountManagerServicesRequestModel.cpp
|
||||||
|
|
||||||
model/call/CallModel.cpp
|
model/call/CallModel.cpp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,16 @@
|
||||||
#include "AccountManager.hpp"
|
#include "AccountManager.hpp"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
#include "core/path/Paths.hpp"
|
#include "core/path/Paths.hpp"
|
||||||
#include "model/core/CoreModel.hpp"
|
#include "model/core/CoreModel.hpp"
|
||||||
|
#include "model/tool/ToolModel.hpp"
|
||||||
#include "tool/Utils.hpp"
|
#include "tool/Utils.hpp"
|
||||||
|
|
||||||
DEFINE_ABSTRACT_OBJECT(AccountManager)
|
DEFINE_ABSTRACT_OBJECT(AccountManager)
|
||||||
|
|
@ -93,6 +99,172 @@ bool AccountManager::login(QString username, QString password, QString *errorMes
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccountManager::registerNewAccount(const QString &username,
|
||||||
|
const QString &password,
|
||||||
|
RegisterType type,
|
||||||
|
const QString ®isterAddress) {
|
||||||
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
|
if (!mAccountManagerServicesModel) {
|
||||||
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
|
auto ams = core->createAccountManagerServices();
|
||||||
|
mAccountManagerServicesModel = Utils::makeQObject_ptr<AccountManagerServicesModel>(ams);
|
||||||
|
}
|
||||||
|
connect(
|
||||||
|
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestSuccessfull, this,
|
||||||
|
[this, username, password, type, registerAddress](
|
||||||
|
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||||
|
if (request->getType() == linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken) {
|
||||||
|
QString verifyTokenUrl = Utils::coreStringToAppString(data);
|
||||||
|
qDebug() << "[AccountManager] request token succeed" << verifyTokenUrl;
|
||||||
|
|
||||||
|
QDesktopServices::openUrl(verifyTokenUrl);
|
||||||
|
auto creationToken = verifyTokenUrl.mid(verifyTokenUrl.lastIndexOf("/") + 1);
|
||||||
|
|
||||||
|
// QNetworkRequest req;
|
||||||
|
timer.setSingleShot(true);
|
||||||
|
timer.setInterval(2000);
|
||||||
|
QObject::connect(&timer, &QTimer::timeout, this, [this, creationToken]() {
|
||||||
|
mAccountManagerServicesModel->convertCreationRequestTokenIntoCreationToken(
|
||||||
|
Utils::appStringToCoreString(creationToken));
|
||||||
|
});
|
||||||
|
timer.start();
|
||||||
|
// req.setUrl(QUrl(verifyTokenUrl));
|
||||||
|
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::
|
||||||
|
AccountCreationTokenFromAccountCreationRequestToken) {
|
||||||
|
qDebug() << "[AccountManager] request token conversion succeed" << data;
|
||||||
|
emit tokenConversionSucceed();
|
||||||
|
timer.stop();
|
||||||
|
mAccountManagerServicesModel->createAccountUsingToken(Utils::appStringToCoreString(username),
|
||||||
|
Utils::appStringToCoreString(password), data);
|
||||||
|
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken) {
|
||||||
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
|
auto factory = linphone::Factory::get();
|
||||||
|
mCreatedSipAddress = Utils::coreStringToAppString(data);
|
||||||
|
auto createdSipIdentityAddress = ToolModel::interpretUrl(mCreatedSipAddress);
|
||||||
|
core->addAuthInfo(factory->createAuthInfo(Utils::appStringToCoreString(username), // Username.
|
||||||
|
"", // User ID.
|
||||||
|
Utils::appStringToCoreString(password), // Password.
|
||||||
|
"", // HA1.
|
||||||
|
"", // Realm.
|
||||||
|
createdSipIdentityAddress->getDomain() // Domain.
|
||||||
|
));
|
||||||
|
if (type == RegisterType::Email) {
|
||||||
|
qDebug() << "[AccountManager] creation succeed, email verification" << registerAddress;
|
||||||
|
mAccountManagerServicesModel->linkEmailByEmail(
|
||||||
|
ToolModel::interpretUrl(Utils::coreStringToAppString(data)),
|
||||||
|
Utils::appStringToCoreString(registerAddress));
|
||||||
|
} else {
|
||||||
|
qDebug() << "[AccountManager] creation succeed, sms verification" << registerAddress;
|
||||||
|
mAccountManagerServicesModel->linkPhoneNumberBySms(
|
||||||
|
ToolModel::interpretUrl(Utils::coreStringToAppString(data)),
|
||||||
|
Utils::appStringToCoreString(registerAddress));
|
||||||
|
}
|
||||||
|
} else if (request->getType() ==
|
||||||
|
linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail) {
|
||||||
|
qDebug() << "[AccountManager] send email succeed, link account using code";
|
||||||
|
emit newAccountCreationSucceed(mCreatedSipAddress, type, registerAddress);
|
||||||
|
mCreatedSipAddress.clear();
|
||||||
|
} else if (request->getType() ==
|
||||||
|
linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms) {
|
||||||
|
qDebug() << "[AccountManager] send phone number succeed, link account using code";
|
||||||
|
emit newAccountCreationSucceed(mCreatedSipAddress, type, registerAddress);
|
||||||
|
mCreatedSipAddress.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(
|
||||||
|
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestError, this,
|
||||||
|
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, int statusCode,
|
||||||
|
const std::string &errorMessage, const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||||
|
if (request->getType() == linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken) {
|
||||||
|
qDebug() << "[AccountManager] error creating request token :" << errorMessage;
|
||||||
|
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::
|
||||||
|
AccountCreationTokenFromAccountCreationRequestToken) {
|
||||||
|
qDebug() << "[AccountManager] error converting token into creation token :" << errorMessage;
|
||||||
|
if (parameterErrors) {
|
||||||
|
timer.stop();
|
||||||
|
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
} else {
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken) {
|
||||||
|
qDebug() << "[AccountManager] error creating account :" << errorMessage;
|
||||||
|
if (parameterErrors) {
|
||||||
|
for (const std::string &key : parameterErrors->getKeys()) {
|
||||||
|
emit errorInField(Utils::coreStringToAppString(key),
|
||||||
|
Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
} else if (request->getType() ==
|
||||||
|
linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail) {
|
||||||
|
qDebug() << "[AccountManager] error sending code to email" << errorMessage;
|
||||||
|
if (parameterErrors) {
|
||||||
|
for (const std::string &key : parameterErrors->getKeys()) {
|
||||||
|
emit errorInField(Utils::coreStringToAppString(key),
|
||||||
|
Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
} else if (request->getType() ==
|
||||||
|
linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms) {
|
||||||
|
qDebug() << "[AccountManager] error sending code to phone number" << errorMessage;
|
||||||
|
if (parameterErrors) {
|
||||||
|
for (const std::string &key : parameterErrors->getKeys()) {
|
||||||
|
emit errorInField(Utils::coreStringToAppString(key),
|
||||||
|
Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mAccountManagerServicesModel->requestToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManager::linkNewAccountUsingCode(const QString &code,
|
||||||
|
RegisterType registerType,
|
||||||
|
const QString &sipAddress) {
|
||||||
|
auto sipIdentityAddress = ToolModel::interpretUrl(sipAddress);
|
||||||
|
if (!mAccountManagerServicesModel) {
|
||||||
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
|
auto ams = core->createAccountManagerServices();
|
||||||
|
mAccountManagerServicesModel = Utils::makeQObject_ptr<AccountManagerServicesModel>(ams);
|
||||||
|
}
|
||||||
|
connect(
|
||||||
|
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestSuccessfull, this,
|
||||||
|
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||||
|
if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode) {
|
||||||
|
qDebug() << "[AccountManager] link email to account succeed" << data;
|
||||||
|
emit linkingNewAccountWithCodeSucceed();
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode) {
|
||||||
|
qDebug() << "[AccountManager] link phone number to account succeed" << data;
|
||||||
|
emit linkingNewAccountWithCodeSucceed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(
|
||||||
|
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestError, this,
|
||||||
|
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, int statusCode,
|
||||||
|
const std::string &errorMessage, const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||||
|
if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode) {
|
||||||
|
qDebug() << "[AccountManager] error linking email to account" << errorMessage;
|
||||||
|
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode) {
|
||||||
|
qDebug() << "[AccountManager] error linking phone number to account" << errorMessage;
|
||||||
|
}
|
||||||
|
emit linkingNewAccountWithCodeFailed(Utils::coreStringToAppString(errorMessage));
|
||||||
|
});
|
||||||
|
if (registerType == RegisterType::Email)
|
||||||
|
mAccountManagerServicesModel->linkEmailToAccountUsingCode(sipIdentityAddress,
|
||||||
|
Utils::appStringToCoreString(code));
|
||||||
|
else
|
||||||
|
mAccountManagerServicesModel->linkPhoneNumberToAccountUsingCode(sipIdentityAddress,
|
||||||
|
Utils::appStringToCoreString(code));
|
||||||
|
}
|
||||||
|
|
||||||
void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
||||||
linphone::RegistrationState state,
|
linphone::RegistrationState state,
|
||||||
const std::string &message) {
|
const std::string &message) {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@
|
||||||
#define ACCOUNT_MANAGER_H_
|
#define ACCOUNT_MANAGER_H_
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
#include <linphone++/linphone.hh>
|
#include <linphone++/linphone.hh>
|
||||||
|
|
||||||
|
#include "AccountManagerServicesModel.hpp"
|
||||||
|
#include "AccountManagerServicesRequestModel.hpp"
|
||||||
#include "AccountModel.hpp"
|
#include "AccountModel.hpp"
|
||||||
#include "tool/AbstractObject.hpp"
|
#include "tool/AbstractObject.hpp"
|
||||||
|
|
||||||
|
|
@ -34,18 +37,36 @@ public:
|
||||||
~AccountManager();
|
~AccountManager();
|
||||||
|
|
||||||
bool login(QString username, QString password, QString *errorMessage = nullptr);
|
bool login(QString username, QString password, QString *errorMessage = nullptr);
|
||||||
|
|
||||||
std::shared_ptr<linphone::Account> createAccount(const QString &assistantFile);
|
std::shared_ptr<linphone::Account> createAccount(const QString &assistantFile);
|
||||||
|
|
||||||
|
enum RegisterType { PhoneNumber = 0, Email = 1 };
|
||||||
|
void registerNewAccount(const QString &username,
|
||||||
|
const QString &password,
|
||||||
|
RegisterType type,
|
||||||
|
const QString ®isterAddress);
|
||||||
|
|
||||||
|
void linkNewAccountUsingCode(const QString &code, RegisterType registerType, const QString &sipAddress);
|
||||||
|
|
||||||
void onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
void onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
||||||
linphone::RegistrationState state,
|
linphone::RegistrationState state,
|
||||||
const std::string &message);
|
const std::string &message);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void registrationStateChanged(linphone::RegistrationState state);
|
void registrationStateChanged(linphone::RegistrationState state);
|
||||||
void errorMessageChanged(const QString &errorMessage);
|
void errorMessageChanged(const QString &errorMessage);
|
||||||
|
void newAccountCreationSucceed(QString sipAddress, RegisterType registerType, const QString ®isterAddress);
|
||||||
|
void registerNewAccountFailed(const QString &error);
|
||||||
|
void tokenConversionSucceed();
|
||||||
|
void errorInField(const QString &field, const QString &error);
|
||||||
|
void linkingNewAccountWithCodeSucceed();
|
||||||
|
void linkingNewAccountWithCodeFailed(const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<AccountModel> mAccountModel;
|
std::shared_ptr<AccountModel> mAccountModel;
|
||||||
|
std::shared_ptr<AccountManagerServicesModel> mAccountManagerServicesModel;
|
||||||
|
QTimer timer;
|
||||||
|
QString mCreatedSipAddress;
|
||||||
|
// std::shared_ptr<linphone::Address> mCreatedSipIdentityAddress;
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
101
Linphone/model/account/AccountManagerServicesModel.cpp
Normal file
101
Linphone/model/account/AccountManagerServicesModel.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AccountManagerServicesModel.hpp"
|
||||||
|
|
||||||
|
#include "core/path/Paths.hpp"
|
||||||
|
#include "model/core/CoreModel.hpp"
|
||||||
|
#include "tool/Utils.hpp"
|
||||||
|
#include "tool/providers/AvatarProvider.hpp"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
DEFINE_ABSTRACT_OBJECT(AccountManagerServicesModel)
|
||||||
|
|
||||||
|
AccountManagerServicesModel::AccountManagerServicesModel(
|
||||||
|
const std::shared_ptr<linphone::AccountManagerServices> &accountManagerServices, QObject *parent)
|
||||||
|
: mAccountManagerServices(accountManagerServices) {
|
||||||
|
mustBeInLinphoneThread(getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountManagerServicesModel::~AccountManagerServicesModel() {
|
||||||
|
mustBeInLinphoneThread("~" + getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::setRequestAndSubmit(
|
||||||
|
const std::shared_ptr<linphone::AccountManagerServicesRequest> &request) {
|
||||||
|
if (mRequest) {
|
||||||
|
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::requestSuccessfull, this, nullptr);
|
||||||
|
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::requestError, this, nullptr);
|
||||||
|
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::devicesListFetched, this, nullptr);
|
||||||
|
mRequest = nullptr;
|
||||||
|
}
|
||||||
|
mRequest = Utils::makeQObject_ptr<AccountManagerServicesRequestModel>(request);
|
||||||
|
mRequest->setSelf(mRequest);
|
||||||
|
connect(mRequest.get(), &AccountManagerServicesRequestModel::requestSuccessfull, this,
|
||||||
|
&AccountManagerServicesModel::requestSuccessfull);
|
||||||
|
connect(mRequest.get(), &AccountManagerServicesRequestModel::requestError, this,
|
||||||
|
&AccountManagerServicesModel::requestError);
|
||||||
|
connect(mRequest.get(), &AccountManagerServicesRequestModel::devicesListFetched, this,
|
||||||
|
&AccountManagerServicesModel::devicesListFetched);
|
||||||
|
mRequest->submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::requestToken() {
|
||||||
|
auto req = mAccountManagerServices->createGetAccountCreationRequestTokenRequest();
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::convertCreationRequestTokenIntoCreationToken(const std::string &token) {
|
||||||
|
auto req = mAccountManagerServices->createGetAccountCreationTokenFromRequestTokenRequest(token);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::createAccountUsingToken(const std::string &username,
|
||||||
|
const std::string &password,
|
||||||
|
const std::string &token,
|
||||||
|
const std::string &algorithm) {
|
||||||
|
auto req = mAccountManagerServices->createNewAccountUsingTokenRequest(username, password, algorithm, token);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::linkPhoneNumberBySms(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &phoneNumber) {
|
||||||
|
auto req = mAccountManagerServices->createSendPhoneNumberLinkingCodeBySmsRequest(sipIdentityAddress, phoneNumber);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::linkEmailByEmail(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &emailAddress) {
|
||||||
|
auto req = mAccountManagerServices->createSendEmailLinkingCodeByEmailRequest(sipIdentityAddress, emailAddress);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::linkPhoneNumberToAccountUsingCode(
|
||||||
|
const std::shared_ptr<linphone::Address> &sipIdentityAddress, const std::string &code) {
|
||||||
|
auto req = mAccountManagerServices->createLinkPhoneNumberToAccountUsingCodeRequest(sipIdentityAddress, code);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesModel::linkEmailToAccountUsingCode(
|
||||||
|
const std::shared_ptr<linphone::Address> &sipIdentityAddress, const std::string &code) {
|
||||||
|
auto req = mAccountManagerServices->createLinkEmailToAccountUsingCodeRequest(sipIdentityAddress, code);
|
||||||
|
setRequestAndSubmit(req);
|
||||||
|
}
|
||||||
72
Linphone/model/account/AccountManagerServicesModel.hpp
Normal file
72
Linphone/model/account/AccountManagerServicesModel.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ACCOUNT_MANAGER_SERVICES_MODEL_H_
|
||||||
|
#define ACCOUNT_MANAGER_SERVICES_MODEL_H_
|
||||||
|
|
||||||
|
#include "AccountManagerServicesRequestModel.hpp"
|
||||||
|
#include "model/listener/Listener.hpp"
|
||||||
|
#include "tool/AbstractObject.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <linphone++/linphone.hh>
|
||||||
|
|
||||||
|
class AccountManagerServicesModel : public QObject, public AbstractObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AccountManagerServicesModel(const std::shared_ptr<linphone::AccountManagerServices> &accountManagerServices,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
~AccountManagerServicesModel();
|
||||||
|
|
||||||
|
void requestToken();
|
||||||
|
void convertCreationRequestTokenIntoCreationToken(const std::string &token);
|
||||||
|
void createAccountUsingToken(const std::string &username,
|
||||||
|
const std::string &password,
|
||||||
|
const std::string &token,
|
||||||
|
const std::string &algorithm = "SHA-256");
|
||||||
|
void linkPhoneNumberBySms(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &phoneNumber);
|
||||||
|
void linkEmailByEmail(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &emailAddress);
|
||||||
|
|
||||||
|
void linkPhoneNumberToAccountUsingCode(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &code);
|
||||||
|
void linkEmailToAccountUsingCode(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||||
|
const std::string &code);
|
||||||
|
|
||||||
|
void setRequestAndSubmit(const std::shared_ptr<linphone::AccountManagerServicesRequest> &request);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void requestSuccessfull(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::string &data);
|
||||||
|
void requestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
int statusCode,
|
||||||
|
const std::string &errorMessage,
|
||||||
|
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors);
|
||||||
|
void devicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
std::shared_ptr<linphone::AccountManagerServices> mAccountManagerServices;
|
||||||
|
std::shared_ptr<AccountManagerServicesRequestModel> mRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AccountManagerServicesRequestModel.hpp"
|
||||||
|
|
||||||
|
#include "core/path/Paths.hpp"
|
||||||
|
#include "model/core/CoreModel.hpp"
|
||||||
|
#include "tool/Utils.hpp"
|
||||||
|
#include "tool/providers/AvatarProvider.hpp"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
DEFINE_ABSTRACT_OBJECT(AccountManagerServicesRequestModel)
|
||||||
|
|
||||||
|
AccountManagerServicesRequestModel::AccountManagerServicesRequestModel(
|
||||||
|
const std::shared_ptr<linphone::AccountManagerServicesRequest> &accountManagerServicesRequest, QObject *parent)
|
||||||
|
: ::Listener<linphone::AccountManagerServicesRequest, linphone::AccountManagerServicesRequestListener>(
|
||||||
|
accountManagerServicesRequest, parent) {
|
||||||
|
mustBeInLinphoneThread(getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountManagerServicesRequestModel::~AccountManagerServicesRequestModel() {
|
||||||
|
mustBeInLinphoneThread("~" + getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesRequestModel::submit() {
|
||||||
|
mMonitor->submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
linphone::AccountManagerServicesRequest::Type AccountManagerServicesRequestModel::getType() const {
|
||||||
|
return mMonitor->getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// LINPHONE
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void AccountManagerServicesRequestModel::onRequestSuccessful(
|
||||||
|
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||||
|
emit requestSuccessfull(request, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesRequestModel::onRequestError(
|
||||||
|
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
int statusCode,
|
||||||
|
const std::string &errorMessage,
|
||||||
|
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||||
|
emit requestError(request, statusCode, errorMessage, parameterErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManagerServicesRequestModel::onDevicesListFetched(
|
||||||
|
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) {
|
||||||
|
emit devicesListFetched(request, devicesList);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ACCOUNT_MANAGER_SERVICES_REQUEST_MODEL_H_
|
||||||
|
#define ACCOUNT_MANAGER_SERVICES_REQUEST_MODEL_H_
|
||||||
|
|
||||||
|
#include "model/listener/Listener.hpp"
|
||||||
|
#include "tool/AbstractObject.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <linphone++/linphone.hh>
|
||||||
|
|
||||||
|
class AccountManagerServicesRequestModel
|
||||||
|
: public ::Listener<linphone::AccountManagerServicesRequest, linphone::AccountManagerServicesRequestListener>,
|
||||||
|
public linphone::AccountManagerServicesRequestListener,
|
||||||
|
public AbstractObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AccountManagerServicesRequestModel(
|
||||||
|
const std::shared_ptr<linphone::AccountManagerServicesRequest> &accountManagerServicesRequest,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
~AccountManagerServicesRequestModel();
|
||||||
|
|
||||||
|
void submit();
|
||||||
|
linphone::AccountManagerServicesRequest::Type getType() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void requestSuccessfull(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::string &data);
|
||||||
|
void requestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
int statusCode,
|
||||||
|
const std::string &errorMessage,
|
||||||
|
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors);
|
||||||
|
void devicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// LINPHONE
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
virtual void onRequestSuccessful(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::string &data) override;
|
||||||
|
virtual void onRequestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
int statusCode,
|
||||||
|
const std::string &errorMessage,
|
||||||
|
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) override;
|
||||||
|
virtual void onDevicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||||
|
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <linphone++/linphone.hh>
|
#include <linphone++/linphone.hh>
|
||||||
|
|
||||||
|
#include "model/account/AccountManager.hpp"
|
||||||
#include "model/cli/CliModel.hpp"
|
#include "model/cli/CliModel.hpp"
|
||||||
#include "model/listener/Listener.hpp"
|
#include "model/listener/Listener.hpp"
|
||||||
#include "model/logger/LoggerModel.hpp"
|
#include "model/logger/LoggerModel.hpp"
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@
|
||||||
|
|
||||||
#include "LoggerListener.hpp"
|
#include "LoggerListener.hpp"
|
||||||
#include "LoggerModel.hpp"
|
#include "LoggerModel.hpp"
|
||||||
|
#include "model/setting/SettingsModel.hpp"
|
||||||
#include "tool/Constants.hpp"
|
#include "tool/Constants.hpp"
|
||||||
#include "tool/Utils.hpp"
|
#include "tool/Utils.hpp"
|
||||||
#include "model/setting/SettingsModel.hpp"
|
|
||||||
|
|
||||||
#include "core/logger/QtLogger.hpp"
|
#include "core/logger/QtLogger.hpp"
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
@ -127,7 +127,9 @@ void LoggerModel::applyConfig(const std::shared_ptr<linphone::Config> &config) {
|
||||||
const QString folder = SettingsModel::getLogsFolder(config);
|
const QString folder = SettingsModel::getLogsFolder(config);
|
||||||
linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder));
|
linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder));
|
||||||
enableFullLogs(SettingsModel::getFullLogsEnabled(config));
|
enableFullLogs(SettingsModel::getFullLogsEnabled(config));
|
||||||
enable(SettingsModel::getLogsEnabled(config));
|
// TODO : uncomment when it is possible to change the config from settings
|
||||||
|
// enable(SettingsModel::getLogsEnabled(config));
|
||||||
|
enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoggerModel::init() {
|
void LoggerModel::init() {
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SettingsModel.hpp"
|
#include "SettingsModel.hpp"
|
||||||
#include "model/core/CoreModel.hpp"
|
|
||||||
#include "tool/Utils.hpp"
|
|
||||||
#include "model/tool/ToolModel.hpp"
|
|
||||||
#include "core/path/Paths.hpp"
|
#include "core/path/Paths.hpp"
|
||||||
|
#include "model/core/CoreModel.hpp"
|
||||||
|
#include "model/tool/ToolModel.hpp"
|
||||||
|
#include "tool/Utils.hpp"
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
|
|
@ -63,18 +62,14 @@ QStringList SettingsModel::getVideoDevices() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SettingsModel::getVideoDevice () const {
|
QString SettingsModel::getVideoDevice() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return Utils::coreStringToAppString(
|
return Utils::coreStringToAppString(CoreModel::getInstance()->getCore()->getVideoDevice());
|
||||||
CoreModel::getInstance()->getCore()->getVideoDevice()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setVideoDevice (const QString &device) {
|
void SettingsModel::setVideoDevice(const QString &device) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
CoreModel::getInstance()->getCore()->setVideoDevice(
|
CoreModel::getInstance()->getCore()->setVideoDevice(Utils::appStringToCoreString(device));
|
||||||
Utils::appStringToCoreString(device)
|
|
||||||
);
|
|
||||||
emit videoDeviceChanged(device);
|
emit videoDeviceChanged(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,8 +89,8 @@ void SettingsModel::resetCaptureGraph() {
|
||||||
}
|
}
|
||||||
void SettingsModel::createCaptureGraph() {
|
void SettingsModel::createCaptureGraph() {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mSimpleCaptureGraph =
|
mSimpleCaptureGraph = new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()),
|
||||||
new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), Utils::appStringToCoreString(getPlaybackDevice()));
|
Utils::appStringToCoreString(getPlaybackDevice()));
|
||||||
mSimpleCaptureGraph->start();
|
mSimpleCaptureGraph->start();
|
||||||
emit captureGraphRunningChanged(getCaptureGraphRunning());
|
emit captureGraphRunningChanged(getCaptureGraphRunning());
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +130,7 @@ void SettingsModel::deleteCaptureGraph() {
|
||||||
mSimpleCaptureGraph = nullptr;
|
mSimpleCaptureGraph = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Force a call on the 'detect' method of all audio filters, updating new or removed devices
|
// Force a call on the 'detect' method of all audio filters, updating new or removed devices
|
||||||
void SettingsModel::accessCallSettings() {
|
void SettingsModel::accessCallSettings() {
|
||||||
// Audio
|
// Audio
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
|
|
@ -148,7 +143,8 @@ void SettingsModel::accessCallSettings() {
|
||||||
emit playbackGainChanged(getPlaybackGain());
|
emit playbackGainChanged(getPlaybackGain());
|
||||||
emit captureGainChanged(getCaptureGain());
|
emit captureGainChanged(getCaptureGain());
|
||||||
|
|
||||||
// Media cards must not be used twice (capture card + call) else we will get latencies issues and bad echo calibrations in call.
|
// Media cards must not be used twice (capture card + call) else we will get latencies issues and bad echo
|
||||||
|
// calibrations in call.
|
||||||
if (!getIsInCall()) {
|
if (!getIsInCall()) {
|
||||||
qDebug() << "Starting capture graph from accessing audio panel";
|
qDebug() << "Starting capture graph from accessing audio panel";
|
||||||
startCaptureGraph();
|
startCaptureGraph();
|
||||||
|
|
@ -193,8 +189,7 @@ void SettingsModel::setPlaybackGain(float gain) {
|
||||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||||
mSimpleCaptureGraph->setPlaybackGain(gain);
|
mSimpleCaptureGraph->setPlaybackGain(gain);
|
||||||
}
|
}
|
||||||
if((int)(oldGain*1000) != (int)(gain*1000))
|
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit playbackGainChanged(gain);
|
||||||
emit playbackGainChanged(gain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SettingsModel::getCaptureGain() const {
|
float SettingsModel::getCaptureGain() const {
|
||||||
|
|
@ -210,11 +205,10 @@ void SettingsModel::setCaptureGain(float gain) {
|
||||||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||||
mSimpleCaptureGraph->setCaptureGain(gain);
|
mSimpleCaptureGraph->setCaptureGain(gain);
|
||||||
}
|
}
|
||||||
if((int)(oldGain *1000) != (int)(gain *1000))
|
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit captureGainChanged(gain);
|
||||||
emit captureGainChanged(gain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SettingsModel::getCaptureDevices () const {
|
QStringList SettingsModel::getCaptureDevices() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
||||||
QStringList list;
|
QStringList list;
|
||||||
|
|
@ -226,7 +220,7 @@ QStringList SettingsModel::getCaptureDevices () const {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SettingsModel::getPlaybackDevices () const {
|
QStringList SettingsModel::getPlaybackDevices() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
||||||
QStringList list;
|
QStringList list;
|
||||||
|
|
@ -241,68 +235,64 @@ QStringList SettingsModel::getPlaybackDevices () const {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
QString SettingsModel::getCaptureDevice () const {
|
QString SettingsModel::getCaptureDevice() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
auto audioDevice = CoreModel::getInstance()->getCore()->getInputAudioDevice();
|
auto audioDevice = CoreModel::getInstance()->getCore()->getInputAudioDevice();
|
||||||
return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreModel::getInstance()->getCore()->getCaptureDevice());
|
return Utils::coreStringToAppString(audioDevice ? audioDevice->getId()
|
||||||
|
: CoreModel::getInstance()->getCore()->getCaptureDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setCaptureDevice (const QString &device) {
|
void SettingsModel::setCaptureDevice(const QString &device) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
std::string devId = Utils::appStringToCoreString(device);
|
std::string devId = Utils::appStringToCoreString(device);
|
||||||
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
||||||
auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr<linphone::AudioDevice> & audioItem) {
|
auto audioDevice =
|
||||||
return audioItem->getId() == devId;
|
find_if(list.cbegin(), list.cend(),
|
||||||
});
|
[&](const std::shared_ptr<linphone::AudioDevice> &audioItem) { return audioItem->getId() == devId; });
|
||||||
if(audioDevice != list.cend()){
|
if (audioDevice != list.cend()) {
|
||||||
CoreModel::getInstance()->getCore()->setCaptureDevice(devId);
|
CoreModel::getInstance()->getCore()->setCaptureDevice(devId);
|
||||||
CoreModel::getInstance()->getCore()->setInputAudioDevice(*audioDevice);
|
CoreModel::getInstance()->getCore()->setInputAudioDevice(*audioDevice);
|
||||||
emit captureDeviceChanged(device);
|
emit captureDeviceChanged(device);
|
||||||
resetCaptureGraph();
|
resetCaptureGraph();
|
||||||
}else
|
} else qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device;
|
||||||
qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
QString SettingsModel::getPlaybackDevice () const {
|
QString SettingsModel::getPlaybackDevice() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
auto audioDevice = CoreModel::getInstance()->getCore()->getOutputAudioDevice();
|
auto audioDevice = CoreModel::getInstance()->getCore()->getOutputAudioDevice();
|
||||||
return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreModel::getInstance()->getCore()->getPlaybackDevice());
|
return Utils::coreStringToAppString(audioDevice ? audioDevice->getId()
|
||||||
|
: CoreModel::getInstance()->getCore()->getPlaybackDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setPlaybackDevice (const QString &device) {
|
void SettingsModel::setPlaybackDevice(const QString &device) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
std::string devId = Utils::appStringToCoreString(device);
|
std::string devId = Utils::appStringToCoreString(device);
|
||||||
|
|
||||||
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
||||||
auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr<linphone::AudioDevice> & audioItem) {
|
auto audioDevice =
|
||||||
return audioItem->getId() == devId;
|
find_if(list.cbegin(), list.cend(),
|
||||||
});
|
[&](const std::shared_ptr<linphone::AudioDevice> &audioItem) { return audioItem->getId() == devId; });
|
||||||
if(audioDevice != list.cend()){
|
if (audioDevice != list.cend()) {
|
||||||
|
|
||||||
CoreModel::getInstance()->getCore()->setPlaybackDevice(devId);
|
CoreModel::getInstance()->getCore()->setPlaybackDevice(devId);
|
||||||
CoreModel::getInstance()->getCore()->setOutputAudioDevice(*audioDevice);
|
CoreModel::getInstance()->getCore()->setOutputAudioDevice(*audioDevice);
|
||||||
emit playbackDeviceChanged(device);
|
emit playbackDeviceChanged(device);
|
||||||
resetCaptureGraph();
|
resetCaptureGraph();
|
||||||
}else
|
} else qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device;
|
||||||
qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
QString SettingsModel::getRingerDevice () const {
|
QString SettingsModel::getRingerDevice() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return Utils::coreStringToAppString(
|
return Utils::coreStringToAppString(CoreModel::getInstance()->getCore()->getRingerDevice());
|
||||||
CoreModel::getInstance()->getCore()->getRingerDevice()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setRingerDevice (const QString &device) {
|
void SettingsModel::setRingerDevice(const QString &device) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
CoreModel::getInstance()->getCore()->setRingerDevice(
|
CoreModel::getInstance()->getCore()->setRingerDevice(Utils::appStringToCoreString(device));
|
||||||
Utils::appStringToCoreString(device)
|
|
||||||
);
|
|
||||||
emit ringerDeviceChanged(device);
|
emit ringerDeviceChanged(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,7 +300,7 @@ void SettingsModel::setRingerDevice (const QString &device) {
|
||||||
|
|
||||||
bool SettingsModel::getVideoEnabled() const {
|
bool SettingsModel::getVideoEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return CoreModel::getInstance()->getCore()->videoEnabled();
|
return CoreModel::getInstance()->getCore()->videoEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setVideoEnabled(const bool enabled) {
|
void SettingsModel::setVideoEnabled(const bool enabled) {
|
||||||
|
|
@ -323,33 +313,33 @@ void SettingsModel::setVideoEnabled(const bool enabled) {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool SettingsModel::getEchoCancellationEnabled () const {
|
bool SettingsModel::getEchoCancellationEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return CoreModel::getInstance()->getCore()->echoCancellationEnabled();
|
return CoreModel::getInstance()->getCore()->echoCancellationEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setEchoCancellationEnabled (bool status) {
|
void SettingsModel::setEchoCancellationEnabled(bool status) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
CoreModel::getInstance()->getCore()->enableEchoCancellation(status);
|
CoreModel::getInstance()->getCore()->enableEchoCancellation(status);
|
||||||
emit echoCancellationEnabledChanged(status);
|
emit echoCancellationEnabledChanged(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::startEchoCancellerCalibration(){
|
void SettingsModel::startEchoCancellerCalibration() {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
CoreModel::getInstance()->getCore()->startEchoCancellerCalibration();
|
CoreModel::getInstance()->getCore()->startEchoCancellerCalibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SettingsModel::getEchoCancellationCalibration()const {
|
int SettingsModel::getEchoCancellationCalibration() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return CoreModel::getInstance()->getCore()->getEchoCancellationCalibration();
|
return CoreModel::getInstance()->getCore()->getEchoCancellationCalibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsModel::getAutomaticallyRecordCallsEnabled () const {
|
bool SettingsModel::getAutomaticallyRecordCallsEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return !!mConfig->getInt(UiSection, "automatically_record_calls", 0);
|
return !!mConfig->getInt(UiSection, "automatically_record_calls", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setAutomaticallyRecordCallsEnabled (bool enabled) {
|
void SettingsModel::setAutomaticallyRecordCallsEnabled(bool enabled) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mConfig->setInt(UiSection, "automatically_record_calls", enabled);
|
mConfig->setInt(UiSection, "automatically_record_calls", enabled);
|
||||||
emit automaticallyRecordCallsEnabledChanged(enabled);
|
emit automaticallyRecordCallsEnabledChanged(enabled);
|
||||||
|
|
@ -359,12 +349,12 @@ void SettingsModel::setAutomaticallyRecordCallsEnabled (bool enabled) {
|
||||||
// VFS.
|
// VFS.
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
bool SettingsModel::getVfsEnabled () const {
|
bool SettingsModel::getVfsEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return !!mConfig->getInt(UiSection, "vfs_enabled", 0);
|
return !!mConfig->getInt(UiSection, "vfs_enabled", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setVfsEnabled (bool enabled) {
|
void SettingsModel::setVfsEnabled(bool enabled) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mConfig->setInt(UiSection, "vfs_enabled", enabled);
|
mConfig->setInt(UiSection, "vfs_enabled", enabled);
|
||||||
emit vfsEnabledChanged(enabled);
|
emit vfsEnabledChanged(enabled);
|
||||||
|
|
@ -374,69 +364,67 @@ void SettingsModel::setVfsEnabled (bool enabled) {
|
||||||
// Logs.
|
// Logs.
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
bool SettingsModel::getLogsEnabled () const {
|
bool SettingsModel::getLogsEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return getLogsEnabled(mConfig);
|
return getLogsEnabled(mConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setLogsEnabled (bool status) {
|
void SettingsModel::setLogsEnabled(bool status) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mConfig->setInt(UiSection, "logs_enabled", status);
|
mConfig->setInt(UiSection, "logs_enabled", status);
|
||||||
CoreModel::getInstance()->getLogger()->enable(status);
|
CoreModel::getInstance()->getLogger()->enable(status);
|
||||||
emit logsEnabledChanged(status);
|
emit logsEnabledChanged(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsModel::getFullLogsEnabled () const {
|
bool SettingsModel::getFullLogsEnabled() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return getFullLogsEnabled(mConfig);
|
return getFullLogsEnabled(mConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::setFullLogsEnabled (bool status) {
|
void SettingsModel::setFullLogsEnabled(bool status) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mConfig->setInt(UiSection, "full_logs_enabled", status);
|
mConfig->setInt(UiSection, "full_logs_enabled", status);
|
||||||
CoreModel::getInstance()->getLogger()->enableFullLogs(status);
|
CoreModel::getInstance()->getLogger()->enableFullLogs(status);
|
||||||
emit fullLogsEnabledChanged(status);
|
emit fullLogsEnabledChanged(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsModel::getLogsEnabled (const shared_ptr<linphone::Config> &config) {
|
bool SettingsModel::getLogsEnabled(const shared_ptr<linphone::Config> &config) {
|
||||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||||
return config ? config->getInt(UiSection, "logs_enabled", false) : true;
|
return config ? config->getInt(UiSection, "logs_enabled", false) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsModel::getFullLogsEnabled (const shared_ptr<linphone::Config> &config) {
|
bool SettingsModel::getFullLogsEnabled(const shared_ptr<linphone::Config> &config) {
|
||||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||||
return config ? config->getInt(UiSection, "full_logs_enabled", false) : false;
|
return config ? config->getInt(UiSection, "full_logs_enabled", false) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SettingsModel::getLogsFolder () const {
|
QString SettingsModel::getLogsFolder() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return getLogsFolder(mConfig);
|
return getLogsFolder(mConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SettingsModel::getLogsFolder (const shared_ptr<linphone::Config> &config) {
|
QString SettingsModel::getLogsFolder(const shared_ptr<linphone::Config> &config) {
|
||||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||||
return config
|
return config ? Utils::coreStringToAppString(config->getString(
|
||||||
? Utils::coreStringToAppString(config->getString(UiSection, "logs_folder", Utils::appStringToCoreString(Paths::getLogsDirPath())))
|
UiSection, "logs_folder", Utils::appStringToCoreString(Paths::getLogsDirPath())))
|
||||||
: Paths::getLogsDirPath();
|
: Paths::getLogsDirPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::cleanLogs () const {
|
void SettingsModel::cleanLogs() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
CoreModel::getInstance()->getCore()->resetLogCollection();
|
CoreModel::getInstance()->getCore()->resetLogCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsModel::sendLogs () const {
|
void SettingsModel::sendLogs() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
auto core = CoreModel::getInstance()->getCore();
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
qInfo() << QStringLiteral("Send logs to: `%1` from `%2`.")
|
qInfo() << QStringLiteral("Send logs to: `%1` from `%2`.")
|
||||||
.arg(Utils::coreStringToAppString(core->getLogCollectionUploadServerUrl()))
|
.arg(Utils::coreStringToAppString(core->getLogCollectionUploadServerUrl()))
|
||||||
.arg(Utils::coreStringToAppString(core->getLogCollectionPath()));
|
.arg(Utils::coreStringToAppString(core->getLogCollectionPath()));
|
||||||
core->uploadLogCollection();
|
core->uploadLogCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SettingsModel::getLogsEmail () const {
|
QString SettingsModel::getLogsEmail() const {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
return Utils::coreStringToAppString(
|
return Utils::coreStringToAppString(mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail));
|
||||||
mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public:
|
||||||
static constexpr char DownloadUrl[] = "https://www.linphone.org/technical-corner/linphone";
|
static constexpr char DownloadUrl[] = "https://www.linphone.org/technical-corner/linphone";
|
||||||
static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases";
|
static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases";
|
||||||
static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots";
|
static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots";
|
||||||
static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/login/email";
|
static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/recovery/email";
|
||||||
static constexpr char CguUrl[] = "https://www.linphone.org/general-terms";
|
static constexpr char CguUrl[] = "https://www.linphone.org/general-terms";
|
||||||
static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/privacy-policy";
|
static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/privacy-policy";
|
||||||
static constexpr char ContactUrl[] = "https://www.linphone.org/contact";
|
static constexpr char ContactUrl[] = "https://www.linphone.org/contact";
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,29 @@ LinphoneEnums::TransportType fromLinphone(const linphone::TransportType &type);
|
||||||
QString toString(const LinphoneEnums::TransportType &type);
|
QString toString(const LinphoneEnums::TransportType &type);
|
||||||
void fromString(const QString &transportType, LinphoneEnums::TransportType *transport);
|
void fromString(const QString &transportType, LinphoneEnums::TransportType *transport);
|
||||||
|
|
||||||
|
enum class AccountManagerServicesRequestType {
|
||||||
|
SendAccountCreationTokenByPush = int(linphone::AccountManagerServicesRequest::Type::SendAccountCreationTokenByPush),
|
||||||
|
AccountCreationRequestToken = int(linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken),
|
||||||
|
AccountCreationTokenFromAccountCreationRequestToken =
|
||||||
|
int(linphone::AccountManagerServicesRequest::Type::AccountCreationTokenFromAccountCreationRequestToken),
|
||||||
|
CreateAccountUsingToken = int(linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken),
|
||||||
|
SendPhoneNumberLinkingCodeBySms =
|
||||||
|
int(linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms),
|
||||||
|
LinkPhoneNumberUsingCode = int(linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode),
|
||||||
|
SendEmailLinkingCodeByEmail = int(linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail),
|
||||||
|
LinkEmailUsingCode = int(linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode),
|
||||||
|
GetDevicesList = int(linphone::AccountManagerServicesRequest::Type::GetDevicesList),
|
||||||
|
DeleteDevice = int(linphone::AccountManagerServicesRequest::Type::DeleteDevice),
|
||||||
|
GetCreationTokenAsAdmin = int(linphone::AccountManagerServicesRequest::Type::GetCreationTokenAsAdmin),
|
||||||
|
GetAccountInfoAsAdmin = int(linphone::AccountManagerServicesRequest::Type::GetAccountInfoAsAdmin),
|
||||||
|
DeleteAccountAsAdmin = int(linphone::AccountManagerServicesRequest::Type::DeleteAccountAsAdmin)
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(AccountManagerServicesRequestType)
|
||||||
|
|
||||||
|
// linphone::AccountManagerServicesRequest::Type toLinphone(const LinphoneEnums::AccountManagerServicesRequestType
|
||||||
|
// &type); LinphoneEnums::AccountManagerServicesRequestType fromLinphone(const
|
||||||
|
// linphone::AccountManagerServicesRequest::Type &type);
|
||||||
|
|
||||||
enum VideoSourceScreenSharingType {
|
enum VideoSourceScreenSharingType {
|
||||||
VideoSourceScreenSharingTypeArea = int(linphone::VideoSourceScreenSharingType::Area),
|
VideoSourceScreenSharingTypeArea = int(linphone::VideoSourceScreenSharingType::Area),
|
||||||
VideoSourceScreenSharingTypeDisplay = int(linphone::VideoSourceScreenSharingType::Display),
|
VideoSourceScreenSharingTypeDisplay = int(linphone::VideoSourceScreenSharingType::Display),
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,11 @@ bool Utils::copyToClipboard(const QString &text) {
|
||||||
return !clipboardText.isEmpty();
|
return !clipboardText.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Utils::getClipboardText() {
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
return clipboard->text();
|
||||||
|
}
|
||||||
|
|
||||||
QString Utils::getApplicationProduct() {
|
QString Utils::getApplicationProduct() {
|
||||||
// Note: Keep '-' as a separator between application name and application type
|
// Note: Keep '-' as a separator between application name and application type
|
||||||
return QString(APPLICATION_NAME "-Desktop").remove(' ') + "/" + QCoreApplication::applicationVersion();
|
return QString(APPLICATION_NAME "-Desktop").remove(' ') + "/" + QCoreApplication::applicationVersion();
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ public:
|
||||||
Q_INVOKABLE static QStringList generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode);
|
Q_INVOKABLE static QStringList generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode);
|
||||||
Q_INVOKABLE static int getRandomIndex(int size);
|
Q_INVOKABLE static int getRandomIndex(int size);
|
||||||
Q_INVOKABLE static bool copyToClipboard(const QString &text);
|
Q_INVOKABLE static bool copyToClipboard(const QString &text);
|
||||||
|
Q_INVOKABLE static QString getClipboardText();
|
||||||
Q_INVOKABLE static QString toDateString(QDateTime date, const QString &format = "");
|
Q_INVOKABLE static QString toDateString(QDateTime date, const QString &format = "");
|
||||||
Q_INVOKABLE static QString toDateString(QDate date, const QString &format = "");
|
Q_INVOKABLE static QString toDateString(QDate date, const QString &format = "");
|
||||||
Q_INVOKABLE static QString toDateDayString(const QDateTime &date);
|
Q_INVOKABLE static QString toDateDayString(const QDateTime &date);
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,10 @@ ApplicationWindow {
|
||||||
infoPopup.open()
|
infoPopup.open()
|
||||||
infoPopup.closePopup.connect(removeFromPopupLayout)
|
infoPopup.closePopup.connect(removeFromPopupLayout)
|
||||||
}
|
}
|
||||||
function showLoadingPopup(text) {
|
function showLoadingPopup(text, cancelButtonVisible) {
|
||||||
|
if (cancelButtonVisible == undefined) cancelButtonVisible = false
|
||||||
loadingPopup.text = text
|
loadingPopup.text = text
|
||||||
|
loadingPopup.cancelButtonVisible = cancelButtonVisible
|
||||||
loadingPopup.open()
|
loadingPopup.open()
|
||||||
}
|
}
|
||||||
function closeLoadingPopup() {
|
function closeLoadingPopup() {
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,12 @@ Rectangle {
|
||||||
color: DefaultStyle.grey_0
|
color: DefaultStyle.grey_0
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
// anchors.leftMargin: 119 * DefaultStyle.dp
|
// anchors.leftMargin: 119 * DefaultStyle.dp
|
||||||
anchors.top: parent.top
|
id: contentLayout
|
||||||
anchors.left: parent.left
|
// anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
// anchors.left: parent.left
|
||||||
anchors.bottom: bottomMountains.top
|
// anchors.right: parent.right
|
||||||
|
anchors.fill: parent
|
||||||
|
// anchors.bottom: bottomMountains.top
|
||||||
spacing: 0
|
spacing: 0
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -63,17 +65,16 @@ Rectangle {
|
||||||
id: centerLayout
|
id: centerLayout
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
z: 1
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: bottomMountains
|
||||||
|
source: AppIcons.belledonne
|
||||||
|
fillMode: Image.Stretch
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 108 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
|
||||||
id: bottomMountains
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: 108 * DefaultStyle.dp
|
|
||||||
source: AppIcons.belledonne
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,17 @@ AppWindow {
|
||||||
id: registerPage
|
id: registerPage
|
||||||
RegisterPage {
|
RegisterPage {
|
||||||
onReturnToLogin: mainWindowStackView.replace(loginPage)
|
onReturnToLogin: mainWindowStackView.replace(loginPage)
|
||||||
onRegisterCalled: (countryCode, phoneNumber, email) => {
|
onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("Veuillez valider le captcha sur la page web"), true)
|
||||||
mainWindowStackView.push(checkingPage, {"phoneNumber": phoneNumber, "email": email})
|
Connections {
|
||||||
|
target: RegisterPageCpp
|
||||||
|
onNewAccountCreationSucceed: (withEmail, address, sipIdentityAddress) => {
|
||||||
|
mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress})
|
||||||
|
}
|
||||||
|
onRegisterNewAccountFailed: (errorMessage) => {
|
||||||
|
mainWindow.showInformationPopup(qsTr("Erreur lors de la création"), errorMessage, false)
|
||||||
|
mainWindow.closeLoadingPopup()
|
||||||
|
}
|
||||||
|
onTokenConversionSucceed: mainWindow.closeLoadingPopup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +110,20 @@ AppWindow {
|
||||||
id: checkingPage
|
id: checkingPage
|
||||||
RegisterCheckingPage {
|
RegisterCheckingPage {
|
||||||
onReturnToRegister: mainWindowStackView.pop()
|
onReturnToRegister: mainWindowStackView.pop()
|
||||||
|
onSendCode: (code) => {
|
||||||
|
RegisterPageCpp.linkNewAccountUsingCode(code, registerWithEmail, sipIdentityAddress)
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: RegisterPageCpp
|
||||||
|
onLinkingNewAccountWithCodeSucceed: {
|
||||||
|
mainWindowStackView.replace(loginPage)
|
||||||
|
mainWindow.showInformationPopup(qsTr("Compte créé"), qsTr("Le compte a été créé avec succès. Vous pouvez maintenant vous connecter"), true)
|
||||||
|
}
|
||||||
|
onLinkingNewAccountWithCodeFailed: (errorMessage) => {
|
||||||
|
if (errorMessage.length === 0) errorMessage = qsTr("Erreur dans le code de validation")
|
||||||
|
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ Control.TextField {
|
||||||
height: inputSize
|
height: inputSize
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
overwriteMode: true
|
||||||
|
|
||||||
// just reserve the space for the background
|
// just reserve the space for the background
|
||||||
placeholderText: "0"
|
placeholderText: "0"
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,6 @@ Text {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
color: DefaultStyle.danger_500main
|
color: DefaultStyle.danger_500main
|
||||||
opacity: 0
|
opacity: 0
|
||||||
function displayText() {
|
|
||||||
mainItem.state = "Visible"
|
|
||||||
}
|
|
||||||
function hideText() {
|
|
||||||
mainItem.state = "Invisible"
|
|
||||||
}
|
|
||||||
font {
|
font {
|
||||||
pixelSize: 12 * DefaultStyle.dp
|
pixelSize: 12 * DefaultStyle.dp
|
||||||
weight: 300 * DefaultStyle.dp
|
weight: 300 * DefaultStyle.dp
|
||||||
|
|
@ -25,7 +19,7 @@ Text {
|
||||||
},
|
},
|
||||||
State{
|
State{
|
||||||
name:"Invisible"
|
name:"Invisible"
|
||||||
PropertyChanges{target: mainItem; opacity: 0.0}
|
PropertyChanges{target: mainItem; opacity: 0.0; text: ""}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
transitions: [
|
transitions: [
|
||||||
|
|
@ -34,7 +28,7 @@ Text {
|
||||||
to: "Invisible"
|
to: "Invisible"
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
duration: 1000
|
duration: 500
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -51,6 +45,8 @@ Text {
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (mainItem.text.length > 0) {
|
if (mainItem.text.length > 0) {
|
||||||
mainItem.state = "Visible"
|
mainItem.state = "Visible"
|
||||||
|
} else {
|
||||||
|
mainItem.state = "Invisible"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls as Control
|
import QtQuick.Controls as Control
|
||||||
import Linphone
|
import Linphone
|
||||||
|
import ConstantsCpp 1.0
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
|
|
@ -148,7 +148,7 @@ ColumnLayout {
|
||||||
weight: 600 * DefaultStyle.dp
|
weight: 600 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClicked: console.debug("[LoginForm]User: forgotten password button clicked")
|
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import Linphone
|
||||||
Popup {
|
Popup {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
property string text
|
property string text
|
||||||
|
property bool cancelButtonVisible: false
|
||||||
modal: true
|
modal: true
|
||||||
closePolicy: Control.Popup.NoAutoClose
|
closePolicy: Control.Popup.NoAutoClose
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
@ -15,6 +16,8 @@ Popup {
|
||||||
// onAboutToShow: width = contentText.implicitWidth
|
// onAboutToShow: width = contentText.implicitWidth
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
spacing: 15 * DefaultStyle.dp
|
spacing: 15 * DefaultStyle.dp
|
||||||
|
// width: childrenRect.width
|
||||||
|
// height: childrenRect.height
|
||||||
BusyIndicator{
|
BusyIndicator{
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.preferredWidth: 33 * DefaultStyle.dp
|
Layout.preferredWidth: 33 * DefaultStyle.dp
|
||||||
|
|
@ -28,5 +31,11 @@ Popup {
|
||||||
text: mainItem.text
|
text: mainItem.text
|
||||||
font.pixelSize: 14 * DefaultStyle.dp
|
font.pixelSize: 14 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
|
Button {
|
||||||
|
visible: mainItem.cancelButtonVisible
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: qsTr("Annuler")
|
||||||
|
onClicked: mainItem.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ import Linphone
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
property string label: ""
|
property string label: ""
|
||||||
readonly property string currentText: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
|
readonly property string currentText: combobox.model.getAt(combobox.currentIndex) ? "+" + combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
|
||||||
property string defaultCallingCode: ""
|
property string defaultCallingCode: ""
|
||||||
property bool enableBackgroundColors: false
|
property bool enableBackgroundColors: false
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ ColumnLayout {
|
||||||
id: listPopup
|
id: listPopup
|
||||||
y: combobox.height - 1
|
y: combobox.height - 1
|
||||||
width: 311 * DefaultStyle.dp
|
width: 311 * DefaultStyle.dp
|
||||||
height: 198 * DefaultStyle.dp
|
height: 250 * DefaultStyle.dp
|
||||||
|
|
||||||
contentItem: ListView {
|
contentItem: ListView {
|
||||||
id: listView
|
id: listView
|
||||||
|
|
@ -109,7 +109,9 @@ ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: PhoneNumberProxy{}
|
model: PhoneNumberProxy{}
|
||||||
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
|
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
|
||||||
highlightFollowsCurrentItem: true
|
keyNavigationEnabled: true
|
||||||
|
keyNavigationWraps: true
|
||||||
|
maximumFlickVelocity: 1500
|
||||||
highlight: Rectangle {
|
highlight: Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
@ -177,7 +179,7 @@ ColumnLayout {
|
||||||
color: DefaultStyle.main2_500main
|
color: DefaultStyle.main2_500main
|
||||||
visible: parent.containsMouse
|
visible: parent.containsMouse
|
||||||
}
|
}
|
||||||
onPressed: {
|
onClicked: {
|
||||||
combobox.currentIndex = index
|
combobox.currentIndex = index
|
||||||
listPopup.close()
|
listPopup.close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,15 @@ ColumnLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
|
|
||||||
property string label: ""
|
property string label: ""
|
||||||
property string errorMessage: ""
|
property alias errorMessage: errorText.text
|
||||||
property string placeholderText : ""
|
property string placeholderText : ""
|
||||||
property bool mandatory: false
|
property bool mandatory: false
|
||||||
|
property bool enableErrorText: true
|
||||||
property int textInputWidth: width
|
property int textInputWidth: width
|
||||||
property string initialPhoneNumber
|
property string initialPhoneNumber
|
||||||
readonly property string phoneNumber: textField.text
|
readonly property string phoneNumber: textField.text
|
||||||
readonly property string countryCode: combobox.currentText
|
readonly property string countryCode: combobox.currentText
|
||||||
|
property string defaultCallingCode
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
visible: label.length > 0
|
visible: label.length > 0
|
||||||
|
|
@ -26,52 +28,60 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
Layout.preferredWidth: mainItem.textInputWidth
|
Layout.preferredWidth: contentBackground.width
|
||||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
Layout.preferredHeight: contentBackground.height
|
||||||
radius: 63 * DefaultStyle.dp
|
Rectangle {
|
||||||
color: DefaultStyle.grey_100
|
id: contentBackground
|
||||||
border.color: mainItem.errorMessage.length > 0
|
width: mainItem.textInputWidth
|
||||||
? DefaultStyle.danger_500main
|
height: 49 * DefaultStyle.dp
|
||||||
: (textField.hasActiveFocus || combobox.hasActiveFocus)
|
radius: 63 * DefaultStyle.dp
|
||||||
? DefaultStyle.main1_500_main
|
color: DefaultStyle.grey_100
|
||||||
: DefaultStyle.grey_200
|
border.color: mainItem.errorMessage.length > 0
|
||||||
RowLayout {
|
? DefaultStyle.danger_500main
|
||||||
anchors.fill: parent
|
: (textField.hasActiveFocus || combobox.hasActiveFocus)
|
||||||
PhoneNumberComboBox {
|
? DefaultStyle.main1_500_main
|
||||||
id: combobox
|
: DefaultStyle.grey_200
|
||||||
implicitWidth: 110 * DefaultStyle.dp
|
RowLayout {
|
||||||
}
|
anchors.fill: parent
|
||||||
Rectangle {
|
PhoneNumberComboBox {
|
||||||
Layout.preferredWidth: 1 * DefaultStyle.dp
|
id: combobox
|
||||||
Layout.fillHeight: true
|
implicitWidth: 110 * DefaultStyle.dp
|
||||||
Layout.topMargin: 10 * DefaultStyle.dp
|
defaultCallingCode: mainItem.defaultCallingCode
|
||||||
Layout.bottomMargin: 10 * DefaultStyle.dp
|
}
|
||||||
color: DefaultStyle.main2_600
|
Rectangle {
|
||||||
}
|
Layout.preferredWidth: 1 * DefaultStyle.dp
|
||||||
TextField {
|
Layout.fillHeight: true
|
||||||
id: textField
|
Layout.topMargin: 10 * DefaultStyle.dp
|
||||||
Layout.fillWidth: true
|
Layout.bottomMargin: 10 * DefaultStyle.dp
|
||||||
placeholderText: mainItem.placeholderText
|
color: DefaultStyle.main2_600
|
||||||
background: Item{}
|
}
|
||||||
initialText: initialPhoneNumber
|
TextField {
|
||||||
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
|
id: textField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: mainItem.placeholderText
|
||||||
|
background: Item{}
|
||||||
|
initialText: initialPhoneNumber
|
||||||
|
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
ErrorText {
|
||||||
|
id: errorText
|
||||||
Text {
|
anchors.top: contentBackground.bottom
|
||||||
visible: mainItem.errorMessage.length > 0
|
// visible: mainItem.enableErrorText
|
||||||
verticalAlignment: Text.AlignVCenter
|
text: mainItem.errorMessage
|
||||||
text: mainItem.errorMessage
|
color: DefaultStyle.danger_500main
|
||||||
color: DefaultStyle.danger_500main
|
verticalAlignment: Text.AlignVCenter
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
font {
|
font {
|
||||||
pixelSize: 13 * DefaultStyle.dp
|
pixelSize: 13 * DefaultStyle.dp
|
||||||
family: DefaultStyle.defaultFont
|
family: DefaultStyle.defaultFont
|
||||||
bold: true
|
bold: true
|
||||||
|
}
|
||||||
|
Layout.preferredWidth: mainItem.textInputWidth
|
||||||
|
// Layout.preferredWidth: implicitWidth
|
||||||
}
|
}
|
||||||
Layout.preferredWidth: mainItem.textInputWidth
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ Control.TextField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
if (event.jey == Qt.Key_Control) mainItem.controlIsDown = true
|
if (event.key == Qt.Key_Control) mainItem.controlIsDown = true
|
||||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||||
enterPressed()
|
enterPressed()
|
||||||
if (mainItem.controlIsDown) {
|
if (mainItem.controlIsDown) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ ColumnLayout {
|
||||||
property string label: ""
|
property string label: ""
|
||||||
property bool mandatory: false
|
property bool mandatory: false
|
||||||
|
|
||||||
property string errorMessage: ""
|
property alias errorMessage: errorText.text
|
||||||
property bool enableErrorText: false
|
property bool enableErrorText: false
|
||||||
property bool errorTextVisible: errorText.opacity > 0
|
property bool errorTextVisible: errorText.opacity > 0
|
||||||
spacing: 5 * DefaultStyle.dp
|
spacing: 5 * DefaultStyle.dp
|
||||||
|
|
@ -32,16 +32,19 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: contentItem
|
Layout.preferredHeight: contentItem.height
|
||||||
Layout.preferredHeight: childrenRect.height
|
Layout.preferredWidth: contentItem.width
|
||||||
Layout.preferredWidth: childrenRect.width
|
Item {
|
||||||
|
id: contentItem
|
||||||
|
height: childrenRect.height
|
||||||
|
width: childrenRect.width
|
||||||
|
}
|
||||||
|
ErrorText {
|
||||||
|
id: errorText
|
||||||
|
anchors.top: contentItem.bottom
|
||||||
|
color: DefaultStyle.danger_500main
|
||||||
|
Layout.preferredWidth: implicitWidth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorText {
|
|
||||||
id: errorText
|
|
||||||
visible: mainItem.enableErrorText
|
|
||||||
text: mainItem.errorMessage
|
|
||||||
color: DefaultStyle.main2_600
|
|
||||||
Layout.preferredWidth: implicitWidth
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -104,6 +104,7 @@ LoginLayout {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Image {
|
Image {
|
||||||
|
z: -1
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 129 * DefaultStyle.dp
|
anchors.topMargin: 129 * DefaultStyle.dp
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,11 @@ import Linphone
|
||||||
LoginLayout {
|
LoginLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
signal returnToRegister()
|
signal returnToRegister()
|
||||||
property string phoneNumber
|
signal sendCode(string code)
|
||||||
property string email
|
property bool registerWithEmail
|
||||||
|
property string address
|
||||||
|
property string sipIdentityAddress
|
||||||
|
property string code
|
||||||
titleContent: [
|
titleContent: [
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 21 * DefaultStyle.dp
|
spacing: 21 * DefaultStyle.dp
|
||||||
|
|
@ -34,7 +36,7 @@ LoginLayout {
|
||||||
Text {
|
Text {
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
text: {
|
text: {
|
||||||
var completeString = (mainItem.email.length > 0) ? qsTr("email") : qsTr("numéro")
|
var completeString = mainItem.registerWithEmail ? qsTr("email") : qsTr("numéro")
|
||||||
text = qsTr("Inscription | Confirmer votre ") + completeString
|
text = qsTr("Inscription | Confirmer votre ") + completeString
|
||||||
}
|
}
|
||||||
font {
|
font {
|
||||||
|
|
@ -64,7 +66,7 @@ LoginLayout {
|
||||||
}
|
}
|
||||||
color: DefaultStyle.main2_700
|
color: DefaultStyle.main2_700
|
||||||
text: {
|
text: {
|
||||||
var completeString = (mainItem.email.length > 0) ? ("email \"" + mainItem.email + "\"") : ("phone number \"" + mainItem.phoneNumber + "\"")
|
var completeString = mainItem.registerWithEmail ? ("email \"") : ("phone number \"") + address + "\""
|
||||||
text = "We have sent a verification code on your " + completeString + " <br>Please enter the verification code below:"
|
text = "We have sent a verification code on your " + completeString + " <br>Please enter the verification code below:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,10 +80,12 @@ LoginLayout {
|
||||||
Layout.preferredHeight: height
|
Layout.preferredHeight: height
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
if (text.length > 0 ) {
|
if (text.length > 0 ) {
|
||||||
|
mainItem.code = mainItem.code.slice(0, index) + text + mainItem.code.slice(index)
|
||||||
if (index < 3)
|
if (index < 3)
|
||||||
nextItemInFocusChain(true).forceActiveFocus()
|
nextItemInFocusChain(true).forceActiveFocus()
|
||||||
else {
|
else {
|
||||||
// TODO : validate()
|
mainItem.sendCode(mainItem.code)
|
||||||
|
mainItem.code = ""
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,27 @@ import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls as Control
|
import QtQuick.Controls as Control
|
||||||
import Linphone
|
import Linphone
|
||||||
|
import UtilsCpp 1.0
|
||||||
|
import ConstantsCpp 1.0
|
||||||
|
|
||||||
LoginLayout {
|
LoginLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
signal returnToLogin()
|
signal returnToLogin()
|
||||||
signal registerCalled(countryCode: string, phoneNumber: string, email: string)
|
signal browserValidationRequested()
|
||||||
readonly property string countryCode: phoneNumberInput.countryCode
|
readonly property string countryCode: phoneNumberInput.countryCode
|
||||||
readonly property string phoneNumber: phoneNumberInput.phoneNumber
|
readonly property string phoneNumber: phoneNumberInput.phoneNumber
|
||||||
readonly property string email: emailInput.text
|
readonly property string email: emailInput.text
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: RegisterPageCpp
|
||||||
|
onErrorInField: (field, errorMessage) => {
|
||||||
|
if (field == "username") usernameItem.errorMessage = errorMessage
|
||||||
|
else if (field == "password") pwdItem.errorMessage = errorMessage
|
||||||
|
else if (field == "phone") phoneNumberInput.errorMessage = errorMessage
|
||||||
|
else if (field == "email") emailItem.errorMessage = errorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
titleContent: [
|
titleContent: [
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 21 * DefaultStyle.dp
|
spacing: 21 * DefaultStyle.dp
|
||||||
|
|
@ -80,11 +92,13 @@ LoginLayout {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 16 * DefaultStyle.dp
|
spacing: 16 * DefaultStyle.dp
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
|
id: usernameItem
|
||||||
label: qsTr("Username")
|
label: qsTr("Username")
|
||||||
mandatory: true
|
mandatory: true
|
||||||
contentItem: TextField {
|
contentItem: TextField {
|
||||||
id: usernameInput
|
id: usernameInput
|
||||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||||
|
backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -109,17 +123,22 @@ LoginLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
PhoneNumberInput {
|
PhoneNumberInput {
|
||||||
id: phoneNumberInput
|
id: phoneNumberInput
|
||||||
label: qsTr("Phone number")
|
property string completePhoneNumber: countryCode + phoneNumber
|
||||||
|
label: qsTr("Numéro de téléphone")
|
||||||
mandatory: true
|
mandatory: true
|
||||||
placeholderText: "Phone number"
|
placeholderText: "Phone number"
|
||||||
|
defaultCallingCode: "33"
|
||||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
|
id: emailItem
|
||||||
label: qsTr("Email")
|
label: qsTr("Email")
|
||||||
mandatory: true
|
mandatory: true
|
||||||
|
enableErrorText: true
|
||||||
contentItem: TextField {
|
contentItem: TextField {
|
||||||
id: emailInput
|
id: emailInput
|
||||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||||
|
backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -128,130 +147,147 @@ LoginLayout {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 5 * DefaultStyle.dp
|
spacing: 5 * DefaultStyle.dp
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
label: qsTr("Password")
|
id: passwordItem
|
||||||
|
label: qsTr("Mot de passe")
|
||||||
mandatory: true
|
mandatory: true
|
||||||
|
enableErrorText: true
|
||||||
contentItem: TextField {
|
contentItem: TextField {
|
||||||
id: pwdInput
|
id: pwdInput
|
||||||
hidden: true
|
hidden: true
|
||||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||||
}
|
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: qsTr("The password must contain 6 characters minimum")
|
|
||||||
font {
|
|
||||||
pixelSize: 12 * DefaultStyle.dp
|
|
||||||
weight: 300 * DefaultStyle.dp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 5 * DefaultStyle.dp
|
spacing: 5 * DefaultStyle.dp
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
label: qsTr("Confirm password")
|
label: qsTr("Confirmation mot de passe")
|
||||||
mandatory: true
|
mandatory: true
|
||||||
|
enableErrorText: true
|
||||||
contentItem: TextField {
|
contentItem: TextField {
|
||||||
id: confirmPwdInput
|
id: confirmPwdInput
|
||||||
hidden: true
|
hidden: true
|
||||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||||
}
|
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: qsTr("The password must contain 6 characters minimum")
|
|
||||||
font {
|
|
||||||
pixelSize: 12 * DefaultStyle.dp
|
|
||||||
weight: 300 * DefaultStyle.dp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
// ColumnLayout {
|
||||||
spacing: 18 * DefaultStyle.dp
|
// spacing: 18 * DefaultStyle.dp
|
||||||
|
// RowLayout {
|
||||||
|
// spacing: 10 * DefaultStyle.dp
|
||||||
|
// CheckBox {
|
||||||
|
// id: subscribeToNewsletterCheckBox
|
||||||
|
// }
|
||||||
|
// Text {
|
||||||
|
// text: qsTr("Je souhaite souscrire à la newletter Linphone.")
|
||||||
|
// font {
|
||||||
|
// pixelSize: 14 * DefaultStyle.dp
|
||||||
|
// weight: 400 * DefaultStyle.dp
|
||||||
|
// }
|
||||||
|
// MouseArea {
|
||||||
|
// anchors.fill: parent
|
||||||
|
// onClicked: subscribeToNewsletterCheckBox.toggle()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
RowLayout {
|
||||||
|
spacing: 10 * DefaultStyle.dp
|
||||||
|
CheckBox {
|
||||||
|
id: termsCheckBox
|
||||||
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 10 * DefaultStyle.dp
|
spacing: 0
|
||||||
CheckBox {
|
Layout.fillWidth: true
|
||||||
|
Text {
|
||||||
|
text: qsTr("J'accepte les ")
|
||||||
|
font {
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: termsCheckBox.toggle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr("I would like to suscribe to the newsletter")
|
font {
|
||||||
|
underline: true
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
text: qsTr("conditions d’utilisation")
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
onClicked: Qt.openUrlExternally(ConstantsCpp.CguUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: qsTr(" et la ")
|
||||||
font {
|
font {
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
weight: 400 * DefaultStyle.dp
|
weight: 400 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Text {
|
||||||
RowLayout {
|
font {
|
||||||
spacing: 10 * DefaultStyle.dp
|
underline: true
|
||||||
CheckBox {
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
id: termsCheckBox
|
weight: 400 * DefaultStyle.dp
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
spacing: 0
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Text {
|
|
||||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
|
||||||
text: qsTr("I accept the Terms and Conditions: ")
|
|
||||||
font {
|
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
|
||||||
weight: 400 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Text {
|
text: qsTr("politique de confidentialité.")
|
||||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
MouseArea {
|
||||||
font {
|
anchors.fill: parent
|
||||||
underline: true
|
hoverEnabled: true
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
weight: 400 * DefaultStyle.dp
|
onClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl)
|
||||||
}
|
|
||||||
text: qsTr("Read the Terms and Conditions.")
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
onClicked: console.log("TODO : display terms and conditions")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
|
||||||
text: qsTr("I accept the Privacy policy: ")
|
|
||||||
font {
|
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
|
||||||
weight: 400 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
|
||||||
font {
|
|
||||||
underline: true
|
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
|
||||||
weight: 400 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
text: qsTr("Read the Privacy policy.")
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
onClicked: console.log("TODO : display privacy policy")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
Button {
|
Button {
|
||||||
// enabled: termsCheckBox.checked && usernameInput.text.length != 0 && pwdInput.text.length != 0 && confirmPwdInput.text.length != 0
|
enabled: termsCheckBox.checked
|
||||||
// && (phoneNumberInput.phoneNumber.length != 0 || emailInput.text.length != 0)
|
|
||||||
leftPadding: 20 * DefaultStyle.dp
|
leftPadding: 20 * DefaultStyle.dp
|
||||||
rightPadding: 20 * DefaultStyle.dp
|
rightPadding: 20 * DefaultStyle.dp
|
||||||
topPadding: 11 * DefaultStyle.dp
|
topPadding: 11 * DefaultStyle.dp
|
||||||
bottomPadding: 11 * DefaultStyle.dp
|
bottomPadding: 11 * DefaultStyle.dp
|
||||||
text: qsTr("Register")
|
text: qsTr("Créer")
|
||||||
onClicked:{
|
onClicked:{
|
||||||
console.log("[RegisterPage] User: Call register with phone number", phoneNumberInput.phoneNumber)
|
if (usernameInput.text.length === 0) {
|
||||||
mainItem.registerCalled(phoneNumberInput.countryCode, phoneNumberInput.phoneNumber, emailInput.text)
|
console.log("ERROR username")
|
||||||
|
usernameItem.errorMessage = qsTr("Veuillez entrer un nom d'utilisateur")
|
||||||
|
} else if (pwdInput.text.length === 0) {
|
||||||
|
console.log("ERROR password")
|
||||||
|
passwordItem.errorMessage = qsTr("Veuillez entrer un mot de passe")
|
||||||
|
} else if (pwdInput.text != confirmPwdInput.text) {
|
||||||
|
console.log("ERROR confirm pwd")
|
||||||
|
passwordItem.errorMessage = qsTr("Les mots de passe sont différents")
|
||||||
|
} else if (bar.currentIndex === 0 && phoneNumberInput.phoneNumber.length === 0) {
|
||||||
|
console.log("ERROR phone number")
|
||||||
|
phoneNumberInput.errorMessage = qsTr("Veuillez entrer un numéro de téléphone")
|
||||||
|
} else if (bar.currentIndex === 1 && emailInput.text.length === 0) {
|
||||||
|
console.log("ERROR email")
|
||||||
|
emailItem.errorMessage = qsTr("Veuillez entrer un email")
|
||||||
|
} else {
|
||||||
|
console.log("[RegisterPage] User: Call register")
|
||||||
|
mainItem.browserValidationRequested()
|
||||||
|
if (bar.currentIndex === 0)
|
||||||
|
RegisterPageCpp.registerNewAccount(usernameInput.text, pwdInput.text, "", phoneNumberInput.completePhoneNumber)
|
||||||
|
else
|
||||||
|
RegisterPageCpp.registerNewAccount(usernameInput.text, pwdInput.text, emailInput.text, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Image {
|
Image {
|
||||||
|
z: -1
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 129 * DefaultStyle.dp
|
anchors.topMargin: 129 * DefaultStyle.dp
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,7 @@ LoginLayout {
|
||||||
clip: true
|
clip: true
|
||||||
},
|
},
|
||||||
Image {
|
Image {
|
||||||
|
z: -1
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 129 * DefaultStyle.dp
|
anchors.topMargin: 129 * DefaultStyle.dp
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue