account device list

This commit is contained in:
Gaelle Braud 2024-08-26 12:16:02 +02:00
parent 34f559b7d7
commit 680d398c36
20 changed files with 558 additions and 53 deletions

View file

@ -37,6 +37,7 @@
#include "core/account/AccountCore.hpp"
#include "core/account/AccountDeviceGui.hpp"
#include "core/account/AccountDeviceProxy.hpp"
#include "core/account/AccountProxy.hpp"
#include "core/call-history/CallHistoryProxy.hpp"
#include "core/call/CallCore.hpp"
@ -365,6 +366,7 @@ void App::initCppInterfaces() {
qmlRegisterUncreatableType<PhoneNumber>(Constants::MainQmlUri, 1, 0, "PhoneNumber", QLatin1String("Uncreatable"));
qmlRegisterType<AccountProxy>(Constants::MainQmlUri, 1, 0, "AccountProxy");
qmlRegisterType<AccountGui>(Constants::MainQmlUri, 1, 0, "AccountGui");
qmlRegisterType<AccountDeviceProxy>(Constants::MainQmlUri, 1, 0, "AccountDeviceProxy");
qmlRegisterType<AccountDeviceGui>(Constants::MainQmlUri, 1, 0, "AccountDeviceGui");
qmlRegisterUncreatableType<AccountCore>(Constants::MainQmlUri, 1, 0, "AccountCore", QLatin1String("Uncreatable"));
qmlRegisterUncreatableType<CallCore>(Constants::MainQmlUri, 1, 0, "CallCore", QLatin1String("Uncreatable"));

View file

@ -5,6 +5,8 @@ list(APPEND _LINPHONEAPP_SOURCES
core/account/AccountProxy.cpp
core/account/AccountDeviceCore.cpp
core/account/AccountDeviceGui.cpp
core/account/AccountDeviceList.cpp
core/account/AccountDeviceProxy.cpp
core/App.cpp
core/call/CallCore.cpp
core/call/CallGui.cpp

View file

@ -28,19 +28,20 @@ DEFINE_ABSTRACT_OBJECT(AccountDeviceCore)
AccountDeviceCore::AccountDeviceCore(QString name, QString userAgent, QDateTime last) : QObject(nullptr) {
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
mustBeInLinphoneThread(getClassName());
mDeviceName = name;
mUserAgent = userAgent;
mLastUpdateTimestamp = last;
}
QSharedPointer<AccountDeviceCore> AccountDeviceCore::createDummy(QString name, QString userAgent, QDateTime last) {
auto core = QSharedPointer<AccountDeviceCore>(new AccountDeviceCore(name,userAgent,last));
auto core = QSharedPointer<AccountDeviceCore>(new AccountDeviceCore(name, userAgent, last));
core->moveToThread(App::getInstance()->thread());
return core;
}
QSharedPointer<AccountDeviceCore> AccountDeviceCore::create(const std::shared_ptr<linphone::AccountDevice> &device) {
mustBeInLinphoneThread(Q_FUNC_INFO);
auto core = QSharedPointer<AccountDeviceCore>(new AccountDeviceCore(device));
core->moveToThread(App::getInstance()->thread());
return core;
@ -49,9 +50,9 @@ QSharedPointer<AccountDeviceCore> AccountDeviceCore::create(const std::shared_pt
AccountDeviceCore::AccountDeviceCore(const std::shared_ptr<linphone::AccountDevice> &device) : QObject(nullptr) {
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
mustBeInLinphoneThread(getClassName());
mAccountDeviceModel = Utils::makeQObject_ptr<AccountDeviceModel>(device);
mDeviceName = Utils::coreStringToAppString(device->getName());
mUserAgent = Utils::coreStringToAppString(device->getUserAgent());
mUserAgent = Utils::coreStringToAppString(device->getUserAgent());
mLastUpdateTimestamp = QDateTime::fromSecsSinceEpoch(device->getLastUpdateTimestamp());
}
@ -59,6 +60,6 @@ AccountDeviceCore::~AccountDeviceCore() {
mustBeInMainThread("~" + getClassName());
}
void AccountDeviceCore::removeDevice() {
// TODO (core thread)
}
const std::shared_ptr<AccountDeviceModel> &AccountDeviceCore::getModel() const {
return mAccountDeviceModel;
}

View file

@ -21,10 +21,11 @@
#ifndef ACCOUNT_DEVICE_CORE_H_
#define ACCOUNT_DEVICE_CORE_H_
#include "model/account/AccountDeviceModel.hpp"
#include "tool/AbstractObject.hpp"
#include <QDateTime>
#include <QObject>
#include <QSharedPointer>
#include <QDateTime>
#include "tool/AbstractObject.hpp"
#include <linphone++/linphone.hh>
class AccountDeviceCore : public QObject, public AbstractObject {
@ -35,24 +36,22 @@ class AccountDeviceCore : public QObject, public AbstractObject {
Q_PROPERTY(QDateTime lastUpdateTimestamp MEMBER mLastUpdateTimestamp CONSTANT)
public:
static QSharedPointer<AccountDeviceCore> create(const std::shared_ptr<linphone::AccountDevice> &device);
AccountDeviceCore(const std::shared_ptr<linphone::AccountDevice> &device);
AccountDeviceCore(QString name, QString userAgent, QDateTime last);
static QSharedPointer<AccountDeviceCore> createDummy(QString name, QString userAgent, QDateTime last);
~AccountDeviceCore();
Q_INVOKABLE void removeDevice();
const std::shared_ptr<AccountDeviceModel> &getModel() const;
private:
QString mDeviceName;
QString mUserAgent;
QDateTime mLastUpdateTimestamp;
std::shared_ptr<AccountDeviceModel> mAccountDeviceModel;
DECLARE_ABSTRACT_OBJECT
};
#endif

View file

@ -0,0 +1,189 @@
/*
* Copyright (c) 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 "AccountDeviceList.hpp"
#include "core/App.hpp"
#include "core/account/AccountDeviceGui.hpp"
#include "tool/Utils.hpp"
#include <QQmlApplicationEngine>
#include <algorithm>
DEFINE_ABSTRACT_OBJECT(AccountDeviceList)
QSharedPointer<AccountDeviceList> AccountDeviceList::create() {
auto model = QSharedPointer<AccountDeviceList>(new AccountDeviceList(), &QObject::deleteLater);
model->moveToThread(App::getInstance()->thread());
model->setSelf(model);
return model;
}
QSharedPointer<AccountDeviceList> AccountDeviceList::create(const std::shared_ptr<AccountModel> &accountModel) {
auto model = create();
model->setAccountModel(accountModel);
return model;
}
AccountDeviceList::AccountDeviceList() {
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
}
AccountDeviceList::~AccountDeviceList() {
}
QList<QSharedPointer<AccountDeviceCore>>
AccountDeviceList::buildDevices(const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
QList<QSharedPointer<AccountDeviceCore>> devices;
for (auto &device : devicesList) {
auto deviceCore = AccountDeviceCore::create(device);
devices << deviceCore;
}
return devices;
}
const std::shared_ptr<AccountModel> &AccountDeviceList::getAccountModel() const {
return mAccountModel;
}
void AccountDeviceList::setAccountModel(const std::shared_ptr<AccountModel> &accountModel) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mAccountModel != accountModel) {
mAccountModel = accountModel;
lDebug() << log().arg("Set account model") << mAccountModel.get();
// oldConnect.unlock();
refreshDevices();
// }
}
}
void AccountDeviceList::refreshDevices() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
beginResetModel();
clearData();
endResetModel();
if (mAccountModel) {
auto requestDeviceList = [this] {
if (!mAccountManagerServicesModelConnection) return;
mAccountManagerServicesModelConnection->invokeToModel([this]() {
auto identityAddress = mAccountModel->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountModel->getMonitor()->findAuthInfo();
qDebug() << "[AccountDeviceList] request devices for address" << identityAddress->asStringUriOnly();
mAccountManagerServicesModel->getDeviceList(identityAddress);
});
};
if (mIsComponentReady) {
requestDeviceList();
} else {
connect(this, &AccountDeviceList::componentReady, this, requestDeviceList, Qt::SingleShotConnection);
}
}
}
void AccountDeviceList::setDevices(QList<QSharedPointer<AccountDeviceCore>> devices) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
add(devices);
lDebug() << log().arg("Add %1 devices").arg(devices.size());
}
void AccountDeviceList::deleteDevice(AccountDeviceGui *deviceGui) {
auto requestDeviceDeletion = [this, deviceGui] {
if (!mAccountManagerServicesModelConnection) return;
auto deviceCore = deviceGui->getCore();
auto deviceModel = deviceCore->getModel();
mAccountManagerServicesModelConnection->invokeToModel([this, deviceModel]() {
auto linphoneDevice = deviceModel->getDevice();
auto identityAddress = mAccountModel->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountModel->getMonitor()->findAuthInfo();
qDebug() << "[AccountDeviceList] delete device" << linphoneDevice->getName() << "of address"
<< identityAddress->asStringUriOnly();
mAccountManagerServicesModel->deleteDevice(identityAddress, linphoneDevice);
});
};
if (mIsComponentReady) {
requestDeviceDeletion();
} else {
connect(this, &AccountDeviceList::componentReady, this, requestDeviceDeletion);
}
}
void AccountDeviceList::setSelf(QSharedPointer<AccountDeviceList> me) {
if (mCoreModelConnection) mCoreModelConnection->disconnect();
mCoreModelConnection = QSharedPointer<SafeConnection<AccountDeviceList, CoreModel>>(
new SafeConnection<AccountDeviceList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mCoreModelConnection->invokeToModel([=] {
auto core = CoreModel::getInstance()->getCore();
auto ams = core->createAccountManagerServices();
auto amsModel = Utils::makeQObject_ptr<AccountManagerServicesModel>(ams);
mCoreModelConnection->invokeToCore([this, amsModel, me]() {
mAccountManagerServicesModel = amsModel;
if (mAccountManagerServicesModelConnection) mAccountManagerServicesModelConnection->disconnect();
mAccountManagerServicesModelConnection =
QSharedPointer<SafeConnection<AccountDeviceList, AccountManagerServicesModel>>(
new SafeConnection<AccountDeviceList, AccountManagerServicesModel>(me,
mAccountManagerServicesModel),
&QObject::deleteLater);
mAccountManagerServicesModelConnection->makeConnectToModel(
&AccountManagerServicesModel::requestSuccessfull,
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
const std::string &data) {
if (request->getType() == linphone::AccountManagerServicesRequest::Type::DeleteDevice) {
mAccountManagerServicesModelConnection->invokeToCore([this] { refreshDevices(); });
}
});
mAccountManagerServicesModelConnection->makeConnectToModel(
&AccountManagerServicesModel::requestError,
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, int statusCode,
const std::string &errorMessage,
const std::shared_ptr<const linphone::Dictionary> &parameterErrors) {
lDebug() << "REQUEST ERROR" << errorMessage;
if (request->getType() == linphone::AccountManagerServicesRequest::Type::GetDevicesList) {
}
});
mAccountManagerServicesModelConnection->makeConnectToModel(
&AccountManagerServicesModel::devicesListFetched,
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) {
mAccountManagerServicesModelConnection->invokeToModel([this, request, devicesList]() {
if (request->getType() == linphone::AccountManagerServicesRequest::Type::GetDevicesList) {
QList<QSharedPointer<AccountDeviceCore>> devices;
for (auto &device : devicesList) {
auto deviceCore = AccountDeviceCore::create(device);
devices << deviceCore;
}
// auto devices = buildDevices(devicesList);
mAccountManagerServicesModelConnection->invokeToCore(
[this, devices]() { setDevices(devices); });
}
});
});
mIsComponentReady = true;
emit componentReady();
});
});
}
QVariant AccountDeviceList::data(const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= rowCount()) return QVariant();
if (role == Qt::DisplayRole)
return QVariant::fromValue(new AccountDeviceGui(mList[row].objectCast<AccountDeviceCore>()));
return QVariant();
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2021 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_DEVICE_LIST_H_
#define ACCOUNT_DEVICE_LIST_H_
#include "../proxy/ListProxy.hpp"
#include "AccountDeviceCore.hpp"
#include "core/account/AccountGui.hpp"
#include "model/account/AccountManagerServicesModel.hpp"
#include "model/account/AccountModel.hpp"
#include "tool/AbstractObject.hpp"
#include "tool/thread/SafeConnection.hpp"
class AccountDeviceGui;
class AccountDeviceList : public ListProxy, public AbstractObject {
Q_OBJECT
public:
static QSharedPointer<AccountDeviceList> create();
static QSharedPointer<AccountDeviceList> create(const std::shared_ptr<AccountModel> &accountModel);
AccountDeviceList();
~AccountDeviceList();
QList<QSharedPointer<AccountDeviceCore>>
buildDevices(const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
const std::shared_ptr<AccountModel> &getAccountModel() const;
void setAccountModel(const std::shared_ptr<AccountModel> &accountModel);
void refreshDevices();
void setDevices(QList<QSharedPointer<AccountDeviceCore>> devices);
void deleteDevice(AccountDeviceGui *deviceGui);
void setSelf(QSharedPointer<AccountDeviceList> me);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
signals:
void componentReady();
private:
std::shared_ptr<AccountModel> mAccountModel;
std::shared_ptr<AccountManagerServicesModel> mAccountManagerServicesModel;
QSharedPointer<SafeConnection<AccountDeviceList, AccountManagerServicesModel>>
mAccountManagerServicesModelConnection;
QSharedPointer<SafeConnection<AccountDeviceList, CoreModel>> mCoreModelConnection;
bool mIsComponentReady = false;
DECLARE_ABSTRACT_OBJECT
};
Q_DECLARE_METATYPE(QSharedPointer<AccountDeviceList>);
#endif // ACCOUNT_DEVICE_LIST_H_

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 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 "AccountDeviceProxy.hpp"
#include "AccountDeviceList.hpp"
#include "core/App.hpp"
#include "tool/Utils.hpp"
#include <QQmlApplicationEngine>
// =============================================================================
DEFINE_ABSTRACT_OBJECT(AccountDeviceProxy)
DEFINE_GUI_OBJECT(AccountDeviceProxy)
AccountDeviceProxy::AccountDeviceProxy(QObject *parent) : SortFilterProxy(parent) {
mAccountDeviceList = AccountDeviceList::create();
setSourceModel(mAccountDeviceList.get());
sort(0); //, Qt::DescendingOrder);
}
AccountDeviceProxy::~AccountDeviceProxy() {
setSourceModel(nullptr);
}
AccountGui *AccountDeviceProxy::getAccount() const {
return mAccount ? new AccountGui(mAccount) : nullptr;
}
void AccountDeviceProxy::setAccount(AccountGui *accountGui) {
auto currentAccountModel = mAccountDeviceList->getAccountModel();
auto accountCore = accountGui ? QSharedPointer<AccountCore>(accountGui->getCore()) : nullptr;
auto newModel = accountCore ? accountCore->getModel() : nullptr;
if (newModel != currentAccountModel) {
mAccount = accountCore;
mAccountDeviceList->setAccountModel(accountGui->getCore()->getModel());
emit accountChanged();
}
}
void AccountDeviceProxy::deleteDevice(AccountDeviceGui *device) {
mAccountDeviceList->deleteDevice(device);
}
bool AccountDeviceProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
return true;
}
bool AccountDeviceProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
auto deviceA = sourceModel()->data(left).value<AccountDeviceGui *>()->getCore();
auto deviceB = sourceModel()->data(right).value<AccountDeviceGui *>()->getCore();
return left.row() < right.row();
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 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_DEVICE_PROXY_MODEL_H_
#define ACCOUNT_DEVICE_PROXY_MODEL_H_
#include "../proxy/SortFilterProxy.hpp"
#include "core/account/AccountDeviceGui.hpp"
#include "core/account/AccountGui.hpp"
#include "core/call/CallGui.hpp"
#include "tool/AbstractObject.hpp"
class AccountDeviceList;
class AccountDeviceGui;
class AccountDeviceProxy : public SortFilterProxy, public AbstractObject {
Q_OBJECT
Q_PROPERTY(AccountGui *account READ getAccount WRITE setAccount NOTIFY accountChanged)
public:
DECLARE_GUI_OBJECT
AccountDeviceProxy(QObject *parent = Q_NULLPTR);
~AccountDeviceProxy();
AccountGui *getAccount() const;
void setAccount(AccountGui *accountGui);
Q_INVOKABLE void deleteDevice(AccountDeviceGui *device);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
signals:
void lUpdate();
void accountChanged();
private:
QSharedPointer<AccountCore> mAccount;
QString mSearchText;
QSharedPointer<AccountDeviceList> mAccountDeviceList;
QSharedPointer<SafeConnection<AccountDeviceProxy, CoreModel>> mCoreModelConnection;
DECLARE_ABSTRACT_OBJECT
};
#endif

View file

@ -48,8 +48,8 @@ void AccountProxy::setFilterText(const QString &filter) {
}
AccountGui *AccountProxy::getDefaultAccount() {
if (!mDefaultAccount) mDefaultAccount = dynamic_cast<AccountList *>(sourceModel())->getDefaultAccount();
return mDefaultAccount;
if (!mDefaultAccount) mDefaultAccount = dynamic_cast<AccountList *>(sourceModel())->getDefaultAccountCore();
return new AccountGui(mDefaultAccount);
}
void AccountProxy::setDefaultAccount(AccountGui *account) {

View file

@ -59,7 +59,7 @@ protected:
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
QString mFilterText;
AccountGui *mDefaultAccount = nullptr; // When null, a new UI object is build from List
QSharedPointer<AccountCore> mDefaultAccount; // When null, a new UI object is build from List
QSharedPointer<AccountList> mAccountList;
};

View file

@ -95,7 +95,7 @@ void ParticipantDeviceList::setConferenceModel(const std::shared_ptr<ConferenceM
if (mConferenceModel != conferenceModel) {
mConferenceModel = conferenceModel;
lDebug() << log().arg("Set Conference %1").arg((quint64)mConferenceModel.get());
if (mConferenceModelConnection->mCore.lock()) { // Unsure to get myself
if (mConferenceModelConnection->mCore.lock()) { // Ensure to get myself
auto oldConnect = mConferenceModelConnection->mCore; // Setself rebuild safepointer
setSelf(mConferenceModelConnection->mCore.mQData); // reset connections
oldConnect.unlock();

View file

@ -1,4 +1,5 @@
list(APPEND _LINPHONEAPP_SOURCES
model/account/AccountDeviceModel.cpp
model/account/AccountModel.cpp
model/account/AccountManager.cpp
model/account/AccountManagerServicesModel.cpp

View file

@ -0,0 +1,40 @@
/*
* 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 "AccountDeviceModel.hpp"
#include <QDebug>
#include "model/core/CoreModel.hpp"
DEFINE_ABSTRACT_OBJECT(AccountDeviceModel)
AccountDeviceModel::AccountDeviceModel(const std::shared_ptr<linphone::AccountDevice> &accountDevice, QObject *parent)
: accountDevice(accountDevice) {
mustBeInLinphoneThread(getClassName());
}
const std::shared_ptr<linphone::AccountDevice> AccountDeviceModel::getDevice() const {
return accountDevice;
}
AccountDeviceModel::~AccountDeviceModel() {
// mustBeInLinphoneThread("~" + getClassName());
}

View file

@ -0,0 +1,44 @@
/*
* 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_DEVICE_MODEL_H_
#define ACCOUNT_DEVICE_MODEL_H_
#include "model/listener/Listener.hpp"
#include "tool/AbstractObject.hpp"
#include <QObject>
#include <QTimer>
#include <linphone++/linphone.hh>
class AccountDeviceModel : public QObject, public AbstractObject {
Q_OBJECT
public:
AccountDeviceModel(const std::shared_ptr<linphone::AccountDevice> &accountDevice, QObject *parent = nullptr);
~AccountDeviceModel();
const std::shared_ptr<linphone::AccountDevice> getDevice() const;
private:
std::shared_ptr<linphone::AccountDevice> accountDevice;
DECLARE_ABSTRACT_OBJECT
};
#endif

View file

@ -85,7 +85,7 @@ bool AccountManager::login(QString username,
if (!displayName.isEmpty()) identity->setDisplayName(Utils::appStringToCoreString(displayName));
if (!domain.isEmpty()) {
identity->setDomain(Utils::appStringToCoreString(domain));
if (!domain.isEmpty() && QString::compare(domain, "sip.linphone.org")) {
if (QString::compare(domain, "sip.linphone.org")) {
params->setLimeServerUrl("");
auto serverAddress =
factory->createAddress(Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain)));
@ -314,4 +314,4 @@ void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::
}
}
emit registrationStateChanged(state);
}
}

View file

@ -40,7 +40,7 @@ public:
QString password,
QString displayName = QString(),
QString domain = QString(),
linphone::TransportType transportType = linphone::TransportType::Udp,
linphone::TransportType transportType = linphone::TransportType::Tls,
QString *errorMessage = nullptr);
std::shared_ptr<linphone::Account> createAccount(const QString &assistantFile);

View file

@ -98,4 +98,15 @@ void AccountManagerServicesModel::linkEmailToAccountUsingCode(
const std::shared_ptr<linphone::Address> &sipIdentityAddress, const std::string &code) {
auto req = mAccountManagerServices->createLinkEmailToAccountUsingCodeRequest(sipIdentityAddress, code);
setRequestAndSubmit(req);
}
}
void AccountManagerServicesModel::getDeviceList(const std::shared_ptr<const linphone::Address> &sipIdentityAddress) {
auto req = mAccountManagerServices->createGetDevicesListRequest(sipIdentityAddress);
setRequestAndSubmit(req);
}
void AccountManagerServicesModel::deleteDevice(const std::shared_ptr<const linphone::Address> &sipIdentityAddress,
const std::shared_ptr<linphone::AccountDevice> &device) {
auto req = mAccountManagerServices->createDeleteDeviceRequest(sipIdentityAddress, device);
setRequestAndSubmit(req);
}

View file

@ -50,6 +50,9 @@ public:
const std::string &code);
void linkEmailToAccountUsingCode(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
const std::string &code);
void getDeviceList(const std::shared_ptr<const linphone::Address> &sipIdentityAddress);
void deleteDevice(const std::shared_ptr<const linphone::Address> &sipIdentityAddress,
const std::shared_ptr<linphone::AccountDevice> &device);
void setRequestAndSubmit(const std::shared_ptr<linphone::AccountManagerServicesRequest> &request);

View file

@ -30,8 +30,8 @@ ApplicationWindow {
property var callback: requestDialog?.result
signal closePopup(int index)
onClosed: closePopup(index)
text: requestDialog.message
details: requestDialog.details
text: requestDialog?.message
details: requestDialog?.details
// For C++, requestDialog need to be call directly
onAccepted: requestDialog ? requestDialog.result(1) : callback(1)
onRejected: requestDialog ? requestDialog.result(0) : callback(0)

View file

@ -260,7 +260,7 @@ AbstractDetailsLayout {
color: DefaultStyle.main2_600
}
Text {
text: qsTr("La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous nutilisez plus. (TODO connecter API SDK quand dispo)")
text: qsTr("La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous nutilisez plus.")
font: Typography.p1s
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
@ -271,46 +271,55 @@ AbstractDetailsLayout {
Layout.fillHeight: true
}
}
Rectangle {
color: DefaultStyle.grey_100
RoundedBackgroundControl {
Layout.fillWidth: true
Layout.minimumHeight: account.core.devices.length * 133 * DefaultStyle.dp + (account.core.devices.length - 1) * 15 * DefaultStyle.dp + 2 * 21 * DefaultStyle.dp
radius: 15 * DefaultStyle.dp
Layout.fillHeight: true
// Layout.minimumHeight: account.core.devices.length * 133 * DefaultStyle.dp + (account.core.devices.length - 1) * 15 * DefaultStyle.dp + 2 * 21 * DefaultStyle.dp
Layout.rightMargin: 30 * DefaultStyle.dp
Layout.topMargin: 20 * DefaultStyle.dp
Layout.bottomMargin: 21 * DefaultStyle.dp
Layout.bottomMargin: 4 * DefaultStyle.dp
Layout.leftMargin: 44 * DefaultStyle.dp
ColumnLayout {
topPadding: 21 * DefaultStyle.dp
bottomPadding: 21 * DefaultStyle.dp
leftPadding: 17 * DefaultStyle.dp
rightPadding: 17 * DefaultStyle.dp
background: Rectangle {
anchors.fill: parent
anchors.bottomMargin: 21 * DefaultStyle.dp
color: DefaultStyle.grey_100
radius: 15 * DefaultStyle.dp
}
contentItem: ColumnLayout {
spacing: 15 * DefaultStyle.dp
Repeater {
id: devices
model: account.core.devices
Rectangle {
model: AccountDeviceProxy {
id: accountDeviceProxy
account: model
}
Control.Control{
Layout.fillWidth: true
Layout.preferredHeight: 133 * DefaultStyle.dp
Layout.topMargin: (index == 0 ? 21 : 0) * DefaultStyle.dp
Layout.leftMargin: 17 * DefaultStyle.dp
Layout.rightMargin: 17 * DefaultStyle.dp
color: 'white'
radius: 10 * DefaultStyle.dp
ColumnLayout {
anchors.topMargin: 26 * DefaultStyle.dp
anchors.bottomMargin: 26 * DefaultStyle.dp
anchors.centerIn: parent
height: 133 * DefaultStyle.dp
topPadding: 26 * DefaultStyle.dp
bottomPadding: 26 * DefaultStyle.dp
rightPadding: 36 * DefaultStyle.dp
leftPadding: 33 * DefaultStyle.dp
background: Rectangle {
anchors.fill: parent
color: DefaultStyle.grey_0
radius: 10 * DefaultStyle.dp
}
contentItem: ColumnLayout {
width: parent.width
spacing: 20 * DefaultStyle.dp
RowLayout {
Layout.rightMargin: 36 * DefaultStyle.dp
Layout.leftMargin: 33 * DefaultStyle.dp
spacing: 5 * DefaultStyle.dp
EffectImage {
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.main2_600
imageSource: modelData.core.userAgent.toLowerCase().includes('ios') || modelData.core.userAgent.toLowerCase().includes('android') ? AppIcons.mobile : AppIcons.desktop
imageSource: modelData.core.userAgent.toLowerCase().includes('ios') | modelData.core.userAgent.toLowerCase().includes('android') ? AppIcons.mobile : AppIcons.desktop
}
Text {
text: modelData.core.deviceName
@ -330,10 +339,10 @@ AbstractDetailsLayout {
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
qsTr("Supprimer ") + modelData.core.deviceName + " ?",
qsTr("Supprimer ") + modelData.core.deviceName + " ?", "",
function (confirmed) {
if (confirmed) {
modelData.core.removeDevice()
accountDeviceProxy.deleteDevice(modelData)
}
}
)
@ -341,8 +350,6 @@ AbstractDetailsLayout {
}
}
RowLayout {
Layout.rightMargin: 36 * DefaultStyle.dp
Layout.leftMargin: 33 * DefaultStyle.dp
spacing: 5 * DefaultStyle.dp
Text {
text: qsTr("Dernière connexion:")