Freeze fixes:

- Unstuck Friends processes.
- Unstuck interpret urls.
- Unstuck Utils functions that need Model to work. INVOKABLE should not block and use VariantObjects.
- rename file local constants.
- Upgrade SafeObject to have a default value after being construct.
- Fix isMe changes and updates.
- Remove restoreMode that is deprecated.
This commit is contained in:
Julien Wadel 2024-10-16 11:45:28 +02:00
parent 5f2cfde69b
commit df7f0a6bc6
15 changed files with 127 additions and 77 deletions

View file

@ -180,7 +180,7 @@ void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
});
mConfInfoModelConnection->makeConnectToCore(&ConferenceInfoCore::lCancelConferenceInfo, [this]() {
mConfInfoModelConnection->invokeToModel([this] {
if (Utils::isMe(mOrganizerAddress)) {
if (ToolModel::isMe(mOrganizerAddress)) {
mConferenceInfoModel->cancelConference();
}
});

View file

@ -20,15 +20,14 @@
#include "FriendCore.hpp"
#include "core/App.hpp"
#include "core/proxy/ListProxy.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp"
#include "tool/thread/SafeConnection.hpp"
DEFINE_ABSTRACT_OBJECT(FriendCore)
const QString addressLabel = FriendCore::tr("Adresse SIP");
const QString phoneLabel = FriendCore::tr("Téléphone");
const QString _addressLabel = FriendCore::tr("Adresse SIP");
const QString _phoneLabel = FriendCore::tr("Téléphone");
QVariant createFriendAddressVariant(const QString &label, const QString &address) {
QVariantMap map;
@ -73,7 +72,7 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
auto addresses = contact->getAddresses();
for (auto &address : addresses) {
mAddressList.append(
createFriendAddressVariant(addressLabel, Utils::coreStringToAppString(address->asStringUriOnly())));
createFriendAddressVariant(_addressLabel, Utils::coreStringToAppString(address->asStringUriOnly())));
}
mDefaultAddress =
contact->getAddress() ? Utils::coreStringToAppString(contact->getAddress()->asStringUriOnly()) : QString();
@ -176,8 +175,8 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
auto numbers = mFriendModel->getAddresses();
QList<QVariant> addr;
for (auto &num : numbers) {
addr.append(
createFriendAddressVariant(addressLabel, Utils::coreStringToAppString(num->asStringUriOnly())));
addr.append(createFriendAddressVariant(_addressLabel,
Utils::coreStringToAppString(num->asStringUriOnly())));
}
mFriendModelConnection->invokeToCore([this, addr]() { resetPhoneNumbers(addr); });
});
@ -186,7 +185,7 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
QList<QVariant> addr;
for (auto &num : numbers) {
addr.append(
createFriendAddressVariant(phoneLabel, Utils::coreStringToAppString(num->getPhoneNumber())));
createFriendAddressVariant(_phoneLabel, Utils::coreStringToAppString(num->getPhoneNumber())));
}
mFriendModelConnection->invokeToCore([this, addr]() { resetPhoneNumbers(addr); });
});
@ -353,15 +352,26 @@ QVariant FriendCore::getAddressAt(int index) const {
return mAddressList[index];
}
void FriendCore::setAddressAt(int index, const QString &label, QString address) {
void FriendCore::setAddressAt(int index, QString label, QString address) {
if (index < 0 || index >= mAddressList.count()) return;
auto map = mAddressList[index].toMap();
label = label.isEmpty() ? map["label"].toString() : label;
QString currentAddress = map["address"].toString();
if (Utils::isUsername(address)) {
address = Utils::interpretUrl(address);
}
auto oldLabel = map["label"].toString();
if (/*oldLabel != label || */ map["address"] != address) {
mAddressList.replace(index, createFriendAddressVariant(label.isEmpty() ? oldLabel : label, address));
mCoreModelConnection->invokeToModel([this, index, label, currentAddress, address]() {
auto linphoneAddr = ToolModel::interpretUrl(address);
QString interpretedAddr = Utils::coreStringToAppString(linphoneAddr->asStringUriOnly());
if (interpretedAddr != currentAddress) {
mCoreModelConnection->invokeToCore([this, index, label, interpretedAddr]() {
mAddressList.replace(index, createFriendAddressVariant(label, interpretedAddr));
emit addressChanged();
setIsSaved(false);
});
}
});
} else if (address != currentAddress) {
mAddressList.replace(index, createFriendAddressVariant(label, address));
emit addressChanged();
setIsSaved(false);
}
@ -377,14 +387,18 @@ void FriendCore::removeAddress(int index) {
void FriendCore::appendAddress(const QString &addr) {
if (addr.isEmpty()) return;
QString interpretedAddress = Utils::interpretUrl(addr);
auto linAddr = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(interpretedAddress));
if (!linAddr) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false);
else {
mAddressList.append(createFriendAddressVariant(addressLabel, interpretedAddress));
if (mDefaultAddress.isEmpty()) mDefaultAddress = interpretedAddress;
emit addressChanged();
}
mCoreModelConnection->invokeToModel([this, addr]() {
auto linphoneAddr = ToolModel::interpretUrl(addr);
QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : "";
mCoreModelConnection->invokeToCore([this, interpretedAddress]() {
if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false);
else {
mAddressList.append(createFriendAddressVariant(_addressLabel, interpretedAddress));
if (mDefaultAddress.isEmpty()) mDefaultAddress = interpretedAddress;
emit addressChanged();
}
});
});
}
void FriendCore::resetAddresses(QList<QVariant> newList) {
@ -535,7 +549,7 @@ void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &model) {
QList<QVariant> addresses;
for (auto &addr : model->getAddresses()) {
addresses.append(
createFriendAddressVariant(addressLabel, Utils::coreStringToAppString(addr->asStringUriOnly())));
createFriendAddressVariant(_addressLabel, Utils::coreStringToAppString(addr->asStringUriOnly())));
}
mAddressList = addresses;
@ -667,5 +681,6 @@ void FriendCore::setIsLdap(bool data) {
}
bool FriendCore::getReadOnly() const {
return getIsLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> & CardDAV
return getIsLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> &
// CardDAV
}

View file

@ -108,7 +108,7 @@ public:
QVariant getAddressAt(int index) const;
Q_INVOKABLE void appendAddress(const QString &addr);
Q_INVOKABLE void removeAddress(int index);
Q_INVOKABLE void setAddressAt(int index, const QString &label, QString address);
Q_INVOKABLE void setAddressAt(int index, QString label, QString address);
void setDefaultAddress(const QString &address);
QString getDefaultAddress() const;

View file

@ -25,6 +25,7 @@
#include "ParticipantCore.hpp"
// #include "ParticipantDeviceList.hpp"
#include "model/participant/ParticipantModel.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp"
// =============================================================================
@ -46,6 +47,7 @@ ParticipantCore::ParticipantCore(const std::shared_ptr<linphone::Participant> &p
if (participant) {
mAdminStatus = participant->isAdmin();
mSipAddress = Utils::coreStringToAppString(participant->getAddress()->asStringUriOnly());
mIsMe = ToolModel::isMe(mSipAddress);
mCreationTime = QDateTime::fromSecsSinceEpoch(participant->getCreationTime());
mDisplayName = Utils::coreStringToAppString(participant->getAddress()->getDisplayName());
if (mDisplayName.isEmpty())
@ -58,11 +60,8 @@ ParticipantCore::ParticipantCore(const std::shared_ptr<linphone::Participant> &p
map.insert("address", address);
mParticipantDevices.append(map);
}
}
// App::getInstance()->mEngine->setObjectOwnership(mParticipantDevices.get(),
// QQmlEngine::CppOwnership); // Managed by QSharedPointer
// connect(this, &ParticipantCore::deviceSecurityLevelChanged, mParticipantDevices.get(),
// &ParticipantDeviceListModel::securityLevelChanged);
} else mIsMe = false;
connect(this, &ParticipantCore::sipAddressChanged, this, &ParticipantCore::updateIsMe);
}
ParticipantCore::~ParticipantCore() {
@ -86,7 +85,20 @@ int ParticipantCore::getDeviceCount() const {
}
bool ParticipantCore::isMe() const {
return Utils::isMe(mSipAddress);
return mIsMe;
}
void ParticipantCore::setIsMe(bool isMe) {
if (mIsMe != isMe) {
mIsMe = isMe;
emit isMeChanged();
}
}
void ParticipantCore::updateIsMe() {
mParticipantConnection->invokeToModel([this, address = mSipAddress]() {
mParticipantConnection->invokeToCore([this, isMe = ToolModel::isMe(address)]() { setIsMe(isMe); });
});
}
QString ParticipantCore::getSipAddress() const {

View file

@ -41,7 +41,7 @@ class ParticipantCore : public QObject, public AbstractObject {
Q_PROPERTY(QString sipAddress READ getSipAddress WRITE setSipAddress NOTIFY sipAddressChanged)
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(bool isAdmin READ isAdmin WRITE setIsAdmin NOTIFY isAdminChanged)
Q_PROPERTY(bool isMe READ isMe CONSTANT)
Q_PROPERTY(bool isMe READ isMe NOTIFY isMeChanged)
Q_PROPERTY(QDateTime creationTime READ getCreationTime CONSTANT)
Q_PROPERTY(bool focus READ isFocus CONSTANT)
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
@ -64,6 +64,8 @@ public:
int getDeviceCount() const;
bool isMe() const;
void setIsMe(bool isMe);
void updateIsMe();
void setSipAddress(const QString &address);
void setDisplayName(const QString &name);
@ -85,6 +87,7 @@ signals:
void sipAddressChanged();
void isAdminChanged();
void isFocusChanged();
void isMeChanged();
void deviceCountChanged();
void invitingChanged();
void creationTimeChanged();
@ -109,6 +112,7 @@ private:
bool mAdminStatus;
bool mIsFocus;
int mSecurityLevel;
bool mIsMe;
DECLARE_ABSTRACT_OBJECT
};

View file

@ -33,7 +33,9 @@ SafeObject::SafeObject(QVariant defaultValue, QObject *parent) : mValue(defaultV
}
SafeObject::~SafeObject() {
}
void SafeObject::setDefaultValue(QVariant value) {
mValue = value;
}
QVariant SafeObject::getValue() const {
return mValue;
}

View file

@ -35,6 +35,7 @@ public:
QVariant getValue() const;
void onSetValue(QVariant value);
void setDefaultValue(QVariant value); // Don't send signal
signals:
void requestValue();
void setValue(QVariant value);

View file

@ -58,7 +58,9 @@ VariantObject::~VariantObject() {
QVariant VariantObject::getValue() const {
return mCoreObject->getValue();
}
void VariantObject::setDefaultValue(QVariant value) {
mCoreObject->setDefaultValue(value);
}
void VariantObject::requestValue() {
emit mCoreObject->requestValue();
}

View file

@ -54,6 +54,7 @@ public:
QVariant getValue() const;
void requestValue();
void setDefaultValue(QVariant value);
QSharedPointer<SafeObject> mCoreObject, mModelObject;
QSharedPointer<SafeConnection<SafeObject, SafeObject>> mConnection;

View file

@ -302,26 +302,32 @@ QString Utils::formatDateElapsedTime(const QDateTime &date) {
return QString::number(s) + " s";
}
QString Utils::interpretUrl(const QString &uri) {
QString address = uri;
if (!address.contains('@')) {
App::postModelBlock([&address, uri]() mutable {
auto addr = ToolModel::interpretUrl(uri);
if (addr) address = Utils::coreStringToAppString(addr->asStringUriOnly());
});
} else if (!address.startsWith("sip:")) {
address.prepend("sip:");
VariantObject *Utils::interpretUrl(QString uri) {
VariantObject *data = new VariantObject(uri);
if (!data) return nullptr;
data->makeRequest([uri]() -> QVariant {
QString address = uri;
auto addr = ToolModel::interpretUrl(uri);
if (addr) address = Utils::coreStringToAppString(addr->asStringUriOnly());
return QVariant(address);
});
if (!uri.contains('@')) {
data->requestValue();
} else if (!uri.startsWith("sip:")) {
uri.prepend("sip:");
data->setDefaultValue(uri);
}
return address;
return data;
}
bool Utils::isValidSIPAddress(const QString &uri) {
bool isValid = false;
App::postModelBlock([&isValid, uri]() mutable {
isValid = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(uri)) != nullptr;
VariantObject *Utils::isValidSIPAddress(QString uri) {
VariantObject *data = new VariantObject(QVariant(false));
if (!data) return nullptr;
data->makeRequest([uri]() -> QVariant {
return QVariant(linphone::Factory::get()->createAddress(Utils::appStringToCoreString(uri)) != nullptr);
});
return isValid;
data->requestValue();
return data;
}
bool Utils::isValidIPAddress(const QString &host) {
@ -345,18 +351,20 @@ bool Utils::isValidURL(const QString &url) {
return QUrl(url).isValid();
}
QString Utils::findAvatarByAddress(const QString &address) {
QString avatar;
App::postModelBlock([address, avatar]() mutable {
VariantObject *Utils::findAvatarByAddress(const QString &address) {
VariantObject *data = new VariantObject("");
if (!data) return nullptr;
data->makeRequest([address]() -> QVariant {
QString avatar;
auto defaultFriendList = CoreModel::getInstance()->getCore()->getDefaultFriendList();
if (!defaultFriendList) return;
if (!defaultFriendList) return QVariant();
auto linphoneAddr = ToolModel::interpretUrl(address);
auto linFriend = CoreModel::getInstance()->getCore()->findFriend(linphoneAddr);
if (linFriend) avatar = Utils::coreStringToAppString(linFriend->getPhoto());
return QVariant(avatar);
});
return avatar;
data->requestValue();
return data;
}
VariantObject *Utils::findFriendByAddress(const QString &address) {
@ -1328,17 +1336,17 @@ int Utils::getYear(const QDate &date) {
}
VariantObject *Utils::isMe(const QString &address) {
bool isMe = false;
VariantObject *data = new VariantObject();
VariantObject *data = new VariantObject(QVariant(false));
if (!data) return nullptr;
data->makeRequest([&isMe, address]() { return QVariant::fromValue(ToolModel::isMe(address)); });
data->makeRequest([address]() { return QVariant::fromValue(ToolModel::isMe(address)); });
data->requestValue();
return data;
}
bool Utils::isLocal(const QString &address) {
bool isLocal = false;
App::postModelSync([&isLocal, address]() { isLocal = ToolModel::isLocal(address); });
return isLocal;
VariantObject *Utils::isLocal(const QString &address) {
VariantObject *data = new VariantObject(QVariant(false));
data->makeRequest([address]() { return QVariant(ToolModel::isLocal(address)); });
data->requestValue();
return data;
}
bool Utils::isUsername(const QString &txt) {

View file

@ -113,17 +113,17 @@ public:
Q_INVOKABLE static QDateTime addYears(QDateTime date, int years);
Q_INVOKABLE static int timeOffset(QDateTime start, QDateTime end);
Q_INVOKABLE static int daysOffset(QDateTime start, QDateTime end);
Q_INVOKABLE static QString interpretUrl(const QString &uri);
Q_INVOKABLE static bool isValidSIPAddress(const QString &uri);
Q_INVOKABLE static VariantObject *interpretUrl(QString uri);
Q_INVOKABLE static VariantObject *isValidSIPAddress(QString uri);
Q_INVOKABLE static bool isValidIPAddress(const QString &host);
Q_INVOKABLE static bool isValidHostname(const QString &hostname);
Q_INVOKABLE static bool isValidURL(const QString &url);
Q_INVOKABLE static QString findAvatarByAddress(const QString &address);
Q_INVOKABLE static VariantObject *findAvatarByAddress(const QString &address);
Q_INVOKABLE static VariantObject *findFriendByAddress(const QString &address);
Q_INVOKABLE static VariantObject *getFriendAddressSecurityLevel(const QString &address);
static QString generateSavedFilename(const QString &from, const QString &to);
Q_INVOKABLE static VariantObject *isMe(const QString &address);
Q_INVOKABLE static bool isLocal(const QString &address);
Q_INVOKABLE static VariantObject *isLocal(const QString &address);
Q_INVOKABLE static bool isUsername(const QString &txt); // Regex check
static QString getCountryName(const QLocale::Territory &p_country);
Q_INVOKABLE static void useFetchConfig(const QString &configUrl);

View file

@ -32,9 +32,8 @@ Loader{
property bool haveAvatar: (account && account.core?.pictureUri || false)
|| (contact && contact.core.pictureUri)
|| computedAvatarUri.length != 0
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(_address)
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
property var avatarObj: UtilsCpp.findAvatarByAddress(_address)
property string computedAvatarUri: avatarObj ? avatarObj.value : ''
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
@ -69,8 +68,14 @@ Loader{
StackView {
id: stackView
initialItem: haveAvatar ? avatar : initials
initialItem: mainItem.haveAvatar ? avatar : initials
anchors.fill: parent
Connections{
target: mainItem
onHaveAvatarChanged: function(haveAvatar) {stackView.replace(haveAvatar ? avatar : initials, StackView.Immediate)}
}
Rectangle {
visible: mainItem.secured || mainItem.securityBreach
anchors.fill: stackView.currentItem

View file

@ -341,7 +341,8 @@ Item {
_address: magicSearchBar.text
}
Text {
text: UtilsCpp.interpretUrl(magicSearchBar.text)
property var urlObj: UtilsCpp.interpretUrl(magicSearchBar.text)
text: urlObj?.value
font {
pixelSize: 12 * DefaultStyle.dp
weight: 300 * DefaultStyle.dp

View file

@ -233,7 +233,6 @@ AbstractMainPage {
Binding on text {
when: searchBar.text.length !== 0
value: qsTr("Aucun appel correspondant")
restoreMode: Binding.RestoreBindingOrValue
}
}
ListView {
@ -497,7 +496,7 @@ AbstractMainPage {
}
Connections {
target: mainItem
function onCreateCallFromSearchBarRequested(){ UtilsCpp.createCall(UtilsCpp.interpretUrl(callContactsList.searchBar.text))}
function onCreateCallFromSearchBarRequested(){ UtilsCpp.createCall(callContactsList.searchBar.text)}
function onOpenNumPadRequest(){ if (!callContactsList.searchBar.numericPadButton.checked) callContactsList.searchBar.numericPadButton.checked = true}
}
Binding {
@ -505,7 +504,6 @@ AbstractMainPage {
property: "visible"
value: true
when: callContactsList.searchBar.numericPadButton.checked
restoreMode: Binding.RestoreValue
}
}
}

View file

@ -253,10 +253,11 @@ ApplicationWindow {
anchors.top: parent.top
anchors.left: parent.left
height: 50
width: 120
width: fpsText.implicitWidth
z: 100
visible: !SettingsCpp.hideFps
Text{
id: fpsText
font.bold: true
font.italic: true
font.pixelSize: 14 * DefaultStyle.dp