diff --git a/Linphone/core/conference/ConferenceInfoCore.cpp b/Linphone/core/conference/ConferenceInfoCore.cpp index 38ec4b1b4..1a8aa40fb 100644 --- a/Linphone/core/conference/ConferenceInfoCore.cpp +++ b/Linphone/core/conference/ConferenceInfoCore.cpp @@ -180,7 +180,7 @@ void ConferenceInfoCore::setSelf(QSharedPointer me) { }); mConfInfoModelConnection->makeConnectToCore(&ConferenceInfoCore::lCancelConferenceInfo, [this]() { mConfInfoModelConnection->invokeToModel([this] { - if (Utils::isMe(mOrganizerAddress)) { + if (ToolModel::isMe(mOrganizerAddress)) { mConferenceInfoModel->cancelConference(); } }); diff --git a/Linphone/core/friend/FriendCore.cpp b/Linphone/core/friend/FriendCore.cpp index 39ed38727..9b24244f0 100644 --- a/Linphone/core/friend/FriendCore.cpp +++ b/Linphone/core/friend/FriendCore.cpp @@ -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 &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 me) { auto numbers = mFriendModel->getAddresses(); QList 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 me) { QList 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 newList) { @@ -535,7 +549,7 @@ void FriendCore::writeFromModel(const std::shared_ptr &model) { QList 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= & CardDAV + return getIsLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list= & + // CardDAV } diff --git a/Linphone/core/friend/FriendCore.hpp b/Linphone/core/friend/FriendCore.hpp index 3f36d0a63..a453b16a8 100644 --- a/Linphone/core/friend/FriendCore.hpp +++ b/Linphone/core/friend/FriendCore.hpp @@ -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; diff --git a/Linphone/core/participant/ParticipantCore.cpp b/Linphone/core/participant/ParticipantCore.cpp index 8ba57b6f3..617936114 100644 --- a/Linphone/core/participant/ParticipantCore.cpp +++ b/Linphone/core/participant/ParticipantCore.cpp @@ -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 &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 &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 { diff --git a/Linphone/core/participant/ParticipantCore.hpp b/Linphone/core/participant/ParticipantCore.hpp index 9a1912f43..b40359739 100644 --- a/Linphone/core/participant/ParticipantCore.hpp +++ b/Linphone/core/participant/ParticipantCore.hpp @@ -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 }; diff --git a/Linphone/model/object/SafeObject.cpp b/Linphone/model/object/SafeObject.cpp index 21e029147..306b055bb 100644 --- a/Linphone/model/object/SafeObject.cpp +++ b/Linphone/model/object/SafeObject.cpp @@ -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; } diff --git a/Linphone/model/object/SafeObject.hpp b/Linphone/model/object/SafeObject.hpp index 655ee2d7a..1a4c0a505 100644 --- a/Linphone/model/object/SafeObject.hpp +++ b/Linphone/model/object/SafeObject.hpp @@ -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); diff --git a/Linphone/model/object/VariantObject.cpp b/Linphone/model/object/VariantObject.cpp index cf36a0f98..b0b7fc5ab 100644 --- a/Linphone/model/object/VariantObject.cpp +++ b/Linphone/model/object/VariantObject.cpp @@ -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(); } diff --git a/Linphone/model/object/VariantObject.hpp b/Linphone/model/object/VariantObject.hpp index b86a60b5c..863262fc0 100644 --- a/Linphone/model/object/VariantObject.hpp +++ b/Linphone/model/object/VariantObject.hpp @@ -54,6 +54,7 @@ public: QVariant getValue() const; void requestValue(); + void setDefaultValue(QVariant value); QSharedPointer mCoreObject, mModelObject; QSharedPointer> mConnection; diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 092f39169..273f62101 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -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) { diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index deb97f719..e4b93b603 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -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); diff --git a/Linphone/view/Control/Display/Contact/Avatar.qml b/Linphone/view/Control/Display/Contact/Avatar.qml index e77ed39b5..341e0fef0 100644 --- a/Linphone/view/Control/Display/Contact/Avatar.qml +++ b/Linphone/view/Control/Display/Contact/Avatar.qml @@ -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 diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index 135a23902..75507bb99 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -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 diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 8c67e1e22..c348ffc5f 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -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 } } } diff --git a/Linphone/view/Page/Window/AbstractWindow.qml b/Linphone/view/Page/Window/AbstractWindow.qml index d0ebfa8b7..f5e0587f4 100644 --- a/Linphone/view/Page/Window/AbstractWindow.qml +++ b/Linphone/view/Page/Window/AbstractWindow.qml @@ -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