From 82e4da60ee59b6faf37f7ab14859ed06bdbffa81 Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Thu, 30 Jan 2025 10:06:06 +0100 Subject: [PATCH] try to fix #LINQT-1605 (CI needed to check the result) fix typo fix #LINQT-1570 bad username in participants device stickers, use participant address fix #LINQT-1626 remote address contains gruu in transfered call fix #LINQT-1621 ensure visible when error visible on form item --- Linphone/core/call/CallCore.cpp | 8 +- Linphone/core/conference/ConferenceCore.cpp | 84 ++++++++++++---- Linphone/core/conference/ConferenceCore.hpp | 16 ++- .../participant/ParticipantDeviceCore.cpp | 97 ++++++++++--------- Linphone/model/conference/ConferenceModel.cpp | 2 +- Linphone/model/conference/ConferenceModel.hpp | 3 +- Linphone/model/tool/ToolModel.cpp | 6 +- Linphone/model/tool/ToolModel.hpp | 2 +- Linphone/tool/Utils.cpp | 26 +++++ Linphone/tool/Utils.hpp | 5 +- .../Container/Call/ActiveSpeakerLayout.qml | 7 +- .../Control/Container/Call/CallGridLayout.qml | 4 + .../view/Control/Container/FormItemLayout.qml | 15 +++ Linphone/view/Control/Display/Sticker.qml | 6 +- .../view/Page/Form/Register/RegisterPage.qml | 2 +- .../Settings/AdvancedSettingsLayout.qml | 18 ++-- 16 files changed, 209 insertions(+), 92 deletions(-) diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index d5005e589..81fd6df4b 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -117,8 +117,10 @@ CallCore::CallCore(const std::shared_ptr &call) : QObject(nullpt mRemoteVideoEnabled = videoDirection == linphone::MediaDirection::SendOnly || videoDirection == linphone::MediaDirection::SendRecv; mState = LinphoneEnums::fromLinphone(call->getState()); - mRemoteAddress = Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()); - mRemoteUsername = Utils::coreStringToAppString(call->getRemoteAddress()->getUsername()); + auto remoteAddress = call->getRemoteAddress()->clone(); + remoteAddress->clean(); + mRemoteAddress = Utils::coreStringToAppString(remoteAddress->asStringUriOnly()); + mRemoteUsername = Utils::coreStringToAppString(remoteAddress->getUsername()); auto linphoneFriend = ToolModel::findFriendByAddress(mRemoteAddress); if (linphoneFriend) mRemoteName = Utils::coreStringToAppString( @@ -281,7 +283,7 @@ void CallCore::setSelf(QSharedPointer me) { }); mCallModelConnection->makeConnectToCore(&CallCore::lTransferCallToAnother, [this](QString uri) { mCallModelConnection->invokeToModel([this, uri]() { - auto linCall = ToolModel::interpretUri(uri); + auto linCall = ToolModel::getCallByRemoteAddress(uri); if (linCall) mCallModel->transferToAnother(linCall); }); }); diff --git a/Linphone/core/conference/ConferenceCore.cpp b/Linphone/core/conference/ConferenceCore.cpp index 3dcb93fab..a2c1327ce 100644 --- a/Linphone/core/conference/ConferenceCore.cpp +++ b/Linphone/core/conference/ConferenceCore.cpp @@ -41,7 +41,11 @@ ConferenceCore::ConferenceCore(const std::shared_ptr &conf mSubject = Utils::coreStringToAppString(conference->getSubject()); mParticipantDeviceCount = conference->getParticipantDeviceList().size(); auto activeSpeaker = conference->getActiveSpeakerParticipantDevice(); - if (activeSpeaker) mActiveSpeaker = ParticipantDeviceCore::create(activeSpeaker); + if (activeSpeaker) { + mActiveSpeakerDevice = ParticipantDeviceCore::create(activeSpeaker); + auto participant = conference->findParticipant(activeSpeaker->getAddress()); + if (participant) mActiveSpeaker = ParticipantCore::create(participant); + } mIsLocalScreenSharing = mConferenceModel->isLocalScreenSharing(); mIsScreenSharingEnabled = mConferenceModel->isScreenSharingEnabled(); mIsRecording = conference->isRecording(); @@ -59,9 +63,18 @@ void ConferenceCore::setSelf(QSharedPointer me) { mConferenceModelConnection = SafeConnection::create(me, mConferenceModel); mConferenceModelConnection->makeConnectToModel( &ConferenceModel::activeSpeakerParticipantDevice, - [this](const std::shared_ptr &participantDevice) { + [this](const std::shared_ptr &conference, + const std::shared_ptr &participantDevice) { auto device = ParticipantDeviceCore::create(participantDevice); - mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); }); + QSharedPointer participantCore; + if (participantDevice) { + auto participant = conference->findParticipant(participantDevice->getAddress()); + if (participant) participantCore = ParticipantCore::create(participant); + } + mConferenceModelConnection->invokeToCore([this, device, participantCore]() { + setActiveSpeaker(participantCore); + setActiveSpeakerDevice(device); + }); }); mConferenceModelConnection->makeConnectToModel( @@ -72,13 +85,24 @@ void ConferenceCore::setSelf(QSharedPointer me) { if (newState == linphone::Conference::State::Created && !mActiveSpeaker) { if (auto participantDevice = conference->getActiveSpeakerParticipantDevice()) { auto device = ParticipantDeviceCore::create(participantDevice); - mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); }); + QSharedPointer participantCore; + auto participant = conference->findParticipant(participantDevice->getAddress()); + if (participant) participantCore = ParticipantCore::create(participant); + mConferenceModelConnection->invokeToCore([this, device, participantCore]() { + setActiveSpeaker(participantCore); + setActiveSpeakerDevice(device); + }); } else if (conference->getParticipantDeviceList().size() > 1) { for (auto &device : conference->getParticipantDeviceList()) { if (!ToolModel::isMe(device->getAddress())) { - auto activeSpeaker = ParticipantDeviceCore::create(device); - mConferenceModelConnection->invokeToCore( - [this, activeSpeaker]() { setActiveSpeaker(activeSpeaker); }); + auto activeSpeakerDevice = ParticipantDeviceCore::create(device); + QSharedPointer participantCore; + auto participant = conference->findParticipant(device->getAddress()); + if (participant) participantCore = ParticipantCore::create(participant); + mConferenceModelConnection->invokeToCore([this, activeSpeakerDevice, participantCore]() { + setActiveSpeaker(participantCore); + setActiveSpeakerDevice(activeSpeakerDevice); + }); break; } } @@ -91,13 +115,25 @@ void ConferenceCore::setSelf(QSharedPointer me) { [this](const std::shared_ptr &conference, int count) { if (auto participantDevice = conference->getActiveSpeakerParticipantDevice()) { auto device = ParticipantDeviceCore::create(participantDevice); - mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); }); + QSharedPointer participantCore; + auto participant = conference->findParticipant(participantDevice->getAddress()); + if (participant) participantCore = ParticipantCore::create(participant); + setActiveSpeakerDevice(device); + mConferenceModelConnection->invokeToCore([this, device, participantCore]() { + setActiveSpeaker(participantCore); + setActiveSpeakerDevice(device); + }); } else if (conference->getParticipantDeviceList().size() > 1) { for (auto &device : conference->getParticipantDeviceList()) { if (!ToolModel::isMe(device->getAddress())) { auto activeSpeaker = ParticipantDeviceCore::create(device); - mConferenceModelConnection->invokeToCore( - [this, activeSpeaker]() { setActiveSpeaker(activeSpeaker); }); + QSharedPointer participantCore; + auto participant = conference->findParticipant(device->getAddress()); + if (participant) participantCore = ParticipantCore::create(participant); + mConferenceModelConnection->invokeToCore([this, activeSpeaker, participantCore]() { + setActiveSpeaker(participantCore); + setActiveSpeakerDevice(activeSpeaker); + }); break; } } @@ -193,22 +229,34 @@ std::shared_ptr ConferenceCore::getModel() const { return mConferenceModel; } -ParticipantDeviceCore *ConferenceCore::getActiveSpeaker() const { - return mActiveSpeaker.get(); +ParticipantDeviceCore *ConferenceCore::getActiveSpeakerDevice() const { + return mActiveSpeakerDevice.get(); } -ParticipantDeviceGui *ConferenceCore::getActiveSpeakerGui() const { - return mActiveSpeaker ? new ParticipantDeviceGui(mActiveSpeaker) : nullptr; +ParticipantGui *ConferenceCore::getActiveSpeakerGui() const { + return mActiveSpeaker ? new ParticipantGui(mActiveSpeaker) : nullptr; +} + +ParticipantDeviceGui *ConferenceCore::getActiveSpeakerDeviceGui() const { + return mActiveSpeakerDevice ? new ParticipantDeviceGui(mActiveSpeakerDevice) : nullptr; } ParticipantGui *ConferenceCore::getMeGui() const { return new ParticipantGui(mMe); } -void ConferenceCore::setActiveSpeaker(const QSharedPointer &device) { - if (mActiveSpeaker != device) { - mActiveSpeaker = device; - lDebug() << "Changing active speaker to " << device->getAddress(); +void ConferenceCore::setActiveSpeakerDevice(const QSharedPointer &device) { + if (mActiveSpeakerDevice != device) { + mActiveSpeakerDevice = device; + log().arg("Changing active speaker device to ").arg(device ? device->getAddress() : "None"); + emit activeSpeakerDeviceChanged(); + } +} + +void ConferenceCore::setActiveSpeaker(const QSharedPointer &participant) { + if (mActiveSpeaker != participant) { + mActiveSpeaker = participant; + log().arg("Changing active speaker to ").arg(participant ? participant->getSipAddress() : "None"); emit activeSpeakerChanged(); } } diff --git a/Linphone/core/conference/ConferenceCore.hpp b/Linphone/core/conference/ConferenceCore.hpp index 5eb39c896..b45299a3a 100644 --- a/Linphone/core/conference/ConferenceCore.hpp +++ b/Linphone/core/conference/ConferenceCore.hpp @@ -48,7 +48,9 @@ public: Q_PROPERTY(bool isScreenSharingEnabled MEMBER mIsScreenSharingEnabled WRITE setIsScreenSharingEnabled NOTIFY isScreenSharingEnabledChanged) Q_PROPERTY(int participantDeviceCount READ getParticipantDeviceCount NOTIFY participantDeviceCountChanged) - Q_PROPERTY(ParticipantDeviceGui *activeSpeaker READ getActiveSpeakerGui NOTIFY activeSpeakerChanged) + Q_PROPERTY(ParticipantGui *activeSpeaker READ getActiveSpeakerGui NOTIFY activeSpeakerChanged) + Q_PROPERTY( + ParticipantDeviceGui *activeSpeakerDevice READ getActiveSpeakerDeviceGui NOTIFY activeSpeakerDeviceChanged) Q_PROPERTY(ParticipantGui *me READ getMeGui) // Should be call from model Thread. Will be automatically in App thread after initialization @@ -69,10 +71,12 @@ public: bool isRecording() const; void setRecording(bool recording); - ParticipantDeviceCore *getActiveSpeaker() const; - ParticipantDeviceGui *getActiveSpeakerGui() const; + ParticipantDeviceCore *getActiveSpeakerDevice() const; + ParticipantDeviceGui *getActiveSpeakerDeviceGui() const; + ParticipantGui *getActiveSpeakerGui() const; + void setActiveSpeakerDevice(const QSharedPointer &device); + void setActiveSpeaker(const QSharedPointer &participant); ParticipantGui *getMeGui() const; - void setActiveSpeaker(const QSharedPointer &device); void setIsReady(bool state); @@ -89,6 +93,7 @@ signals: void isScreenSharingEnabledChanged(); void participantDeviceCountChanged(); void activeSpeakerChanged(); + void activeSpeakerDeviceChanged(); void subjectChanged(); void isRecordingChanged(); @@ -97,7 +102,8 @@ signals: private: QSharedPointer> mConferenceModelConnection; std::shared_ptr mConferenceModel; - QSharedPointer mActiveSpeaker; + QSharedPointer mActiveSpeaker; + QSharedPointer mActiveSpeakerDevice; QSharedPointer mMe; int mParticipantDeviceCount = 0; diff --git a/Linphone/core/participant/ParticipantDeviceCore.cpp b/Linphone/core/participant/ParticipantDeviceCore.cpp index b823b186e..a3d871be7 100644 --- a/Linphone/core/participant/ParticipantDeviceCore.cpp +++ b/Linphone/core/participant/ParticipantDeviceCore.cpp @@ -42,25 +42,27 @@ ParticipantDeviceCore::ParticipantDeviceCore(const std::shared_ptrmEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); mustBeInLinphoneThread(getClassName()); - mName = Utils::coreStringToAppString(device->getName()); - auto deviceAddress = device->getAddress(); - mUniqueAddress = Utils::coreStringToAppString(deviceAddress->asString()); - mAddress = Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); - mDisplayName = Utils::coreStringToAppString(deviceAddress->getDisplayName()); - if (mDisplayName.isEmpty()) { - mDisplayName = ToolModel::getDisplayName(mAddress); + if (device) { + mName = Utils::coreStringToAppString(device->getName()); + auto deviceAddress = device->getAddress(); + mUniqueAddress = Utils::coreStringToAppString(deviceAddress->asString()); + mAddress = Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); + mDisplayName = Utils::coreStringToAppString(deviceAddress->getDisplayName()); + if (mDisplayName.isEmpty()) { + mDisplayName = ToolModel::getDisplayName(mAddress); + } + mIsMuted = device->getIsMuted(); + mIsSpeaking = device->getIsSpeaking(); + mParticipantDeviceModel = Utils::makeQObject_ptr(device); + mParticipantDeviceModel->setSelf(mParticipantDeviceModel); + mState = LinphoneEnums::fromLinphone(device->getState()); + lDebug() << "Address = " << Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); + mIsLocal = ToolModel::findAccount(deviceAddress) != nullptr; // TODO set local + mIsVideoEnabled = mParticipantDeviceModel->isVideoEnabled(); + mIsPaused = device->getState() == linphone::ParticipantDevice::State::Left || + device->getState() == linphone::ParticipantDevice::State::OnHold; } - mIsMuted = device->getIsMuted(); mIsMe = isMe; - mIsSpeaking = device->getIsSpeaking(); - mParticipantDeviceModel = Utils::makeQObject_ptr(device); - mParticipantDeviceModel->setSelf(mParticipantDeviceModel); - mState = LinphoneEnums::fromLinphone(device->getState()); - lDebug() << "Address = " << Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); - mIsLocal = ToolModel::findAccount(deviceAddress) != nullptr; // TODO set local - mIsVideoEnabled = mParticipantDeviceModel->isVideoEnabled(); - mIsPaused = device->getState() == linphone::ParticipantDevice::State::Left || - device->getState() == linphone::ParticipantDevice::State::OnHold; } ParticipantDeviceCore::~ParticipantDeviceCore() { @@ -68,34 +70,39 @@ ParticipantDeviceCore::~ParticipantDeviceCore() { } void ParticipantDeviceCore::setSelf(QSharedPointer me) { - mParticipantDeviceModelConnection = - SafeConnection::create(me, mParticipantDeviceModel); - mParticipantDeviceModelConnection->makeConnectToModel( - &ParticipantDeviceModel::isSpeakingChanged, [this](bool speaking) { - mParticipantDeviceModelConnection->invokeToCore([this, speaking] { setIsSpeaking(speaking); }); - }); - mParticipantDeviceModelConnection->makeConnectToModel(&ParticipantDeviceModel::isMutedChanged, [this](bool muted) { - mParticipantDeviceModelConnection->invokeToCore([this, muted] { setIsMuted(muted); }); - }); - mParticipantDeviceModelConnection->makeConnectToModel( - &ParticipantDeviceModel::stateChanged, [this](LinphoneEnums::ParticipantDeviceState state) { - onStateChanged(state); - mParticipantDeviceModelConnection->invokeToCore( - [this, state, isVideoEnabled = mParticipantDeviceModel->isVideoEnabled()] { - setState(state); - setIsVideoEnabled(isVideoEnabled); - }); - }); - mParticipantDeviceModelConnection->makeConnectToModel( - &ParticipantDeviceModel::streamCapabilityChanged, [this](linphone::StreamType) { - auto videoEnabled = mParticipantDeviceModel->isVideoEnabled(); - mParticipantDeviceModelConnection->invokeToCore([this, videoEnabled] { setIsVideoEnabled(videoEnabled); }); - }); - mParticipantDeviceModelConnection->makeConnectToModel( - &ParticipantDeviceModel::streamAvailabilityChanged, [this](linphone::StreamType) { - auto videoEnabled = mParticipantDeviceModel->isVideoEnabled(); - mParticipantDeviceModelConnection->invokeToCore([this, videoEnabled] { setIsVideoEnabled(videoEnabled); }); - }); + if (mParticipantDeviceModel) { + mParticipantDeviceModelConnection = + SafeConnection::create(me, mParticipantDeviceModel); + mParticipantDeviceModelConnection->makeConnectToModel( + &ParticipantDeviceModel::isSpeakingChanged, [this](bool speaking) { + mParticipantDeviceModelConnection->invokeToCore([this, speaking] { setIsSpeaking(speaking); }); + }); + mParticipantDeviceModelConnection->makeConnectToModel( + &ParticipantDeviceModel::isMutedChanged, [this](bool muted) { + mParticipantDeviceModelConnection->invokeToCore([this, muted] { setIsMuted(muted); }); + }); + mParticipantDeviceModelConnection->makeConnectToModel( + &ParticipantDeviceModel::stateChanged, [this](LinphoneEnums::ParticipantDeviceState state) { + onStateChanged(state); + mParticipantDeviceModelConnection->invokeToCore( + [this, state, isVideoEnabled = mParticipantDeviceModel->isVideoEnabled()] { + setState(state); + setIsVideoEnabled(isVideoEnabled); + }); + }); + mParticipantDeviceModelConnection->makeConnectToModel( + &ParticipantDeviceModel::streamCapabilityChanged, [this](linphone::StreamType) { + auto videoEnabled = mParticipantDeviceModel->isVideoEnabled(); + mParticipantDeviceModelConnection->invokeToCore( + [this, videoEnabled] { setIsVideoEnabled(videoEnabled); }); + }); + mParticipantDeviceModelConnection->makeConnectToModel( + &ParticipantDeviceModel::streamAvailabilityChanged, [this](linphone::StreamType) { + auto videoEnabled = mParticipantDeviceModel->isVideoEnabled(); + mParticipantDeviceModelConnection->invokeToCore( + [this, videoEnabled] { setIsVideoEnabled(videoEnabled); }); + }); + } } QString ParticipantDeviceCore::getName() const { diff --git a/Linphone/model/conference/ConferenceModel.cpp b/Linphone/model/conference/ConferenceModel.cpp index 53767d299..82701eddd 100644 --- a/Linphone/model/conference/ConferenceModel.cpp +++ b/Linphone/model/conference/ConferenceModel.cpp @@ -173,7 +173,7 @@ void ConferenceModel::onActiveSpeakerParticipantDevice( const std::shared_ptr &participantDevice) { lDebug() << "onActiveSpeakerParticipantDevice: " << participantDevice->getAddress()->asString().c_str(); - emit activeSpeakerParticipantDevice(conference->getActiveSpeakerParticipantDevice()); + emit activeSpeakerParticipantDevice(conference, conference->getActiveSpeakerParticipantDevice()); } void ConferenceModel::onParticipantAdded(const std::shared_ptr &conference, diff --git a/Linphone/model/conference/ConferenceModel.hpp b/Linphone/model/conference/ConferenceModel.hpp index c630b4da4..cbd08da91 100644 --- a/Linphone/model/conference/ConferenceModel.hpp +++ b/Linphone/model/conference/ConferenceModel.hpp @@ -120,7 +120,8 @@ private: const std::shared_ptr &audioDevice) override; signals: - void activeSpeakerParticipantDevice(const std::shared_ptr &participantDevice); + void activeSpeakerParticipantDevice(const std::shared_ptr &conference, + const std::shared_ptr &participantDevice); void participantAdded(const std::shared_ptr &participant); void participantRemoved(const std::shared_ptr &participant); void participantAdminStatusChanged(const std::shared_ptr &participant); diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index 532366098..60666afa3 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -50,9 +50,9 @@ std::shared_ptr ToolModel::interpretUrl(const QString &addres return interpretedAddress; } -std::shared_ptr ToolModel::interpretUri(const QString &uri) { - auto remoteAddress = ToolModel::interpretUrl(uri); - if (remoteAddress) return CoreModel::getInstance()->getCore()->getCallByRemoteAddress2(remoteAddress); +std::shared_ptr ToolModel::getCallByRemoteAddress(const QString &remoteAddress) { + auto linAddress = ToolModel::interpretUrl(remoteAddress); + if (linAddress) return CoreModel::getInstance()->getCore()->getCallByRemoteAddress2(linAddress); else return nullptr; } diff --git a/Linphone/model/tool/ToolModel.hpp b/Linphone/model/tool/ToolModel.hpp index 9e89d402a..dea62383f 100644 --- a/Linphone/model/tool/ToolModel.hpp +++ b/Linphone/model/tool/ToolModel.hpp @@ -35,7 +35,7 @@ public: ~ToolModel(); static std::shared_ptr interpretUrl(const QString &address); - static std::shared_ptr interpretUri(const QString &uri); + static std::shared_ptr getCallByRemoteAddress(const QString &remoteAddress); static std::shared_ptr makeLinphoneNumber(const QString &label, const QString &number); static std::shared_ptr findAudioDevice(const QString &id, linphone::AudioDevice::Capabilities capability); diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 3577da46c..347a4603a 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -22,9 +22,11 @@ #include "core/App.hpp" #include "core/call/CallGui.hpp" +#include "core/conference/ConferenceCore.hpp" #include "core/conference/ConferenceInfoCore.hpp" #include "core/conference/ConferenceInfoGui.hpp" #include "core/friend/FriendGui.hpp" +#include "core/participant/ParticipantDeviceCore.hpp" #include "core/path/Paths.hpp" #include "core/payload-type/DownloadablePayloadTypeCore.hpp" #include "model/object/VariantObject.hpp" @@ -130,6 +132,30 @@ VariantObject *Utils::findLocalAccountByAddress(const QString &address) { return data; } +VariantObject *Utils::findParticipantFromDevice(QString conferenceAddress, QString deviceAddress) { + VariantObject *data = new VariantObject("findParticipantFromDevice"); + if (!data) return nullptr; + data->makeRequest([conferenceAddress, deviceAddress]() { + auto linCall = ToolModel::getCallByRemoteAddress(conferenceAddress); + if (linCall) { + auto linConf = linCall->getConference(); + if (linConf) { + auto linAddress = ToolModel::interpretUrl(deviceAddress); + if (linAddress) { + auto participant = linConf->findParticipant(linAddress); + if (participant) { + auto participantCore = ParticipantCore::create(participant); + return QVariant::fromValue(new ParticipantGui(participantCore)); + } + } + } + } + return QVariant(); + }); + data->requestValue(); + return data; +} + void Utils::createCall(const QString &sipAddress, QVariantMap options, LinphoneEnums::MediaEncryption mediaEncryption, diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index 283060f54..2fbd3a778 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -48,6 +48,8 @@ class QQuickWindow; class VariantObject; class CallGui; class ConferenceInfoGui; +class ConferenceCore; +class ParticipantDeviceCore; class DownloadablePayloadTypeCore; class Utils : public QObject, public AbstractObject { @@ -62,6 +64,7 @@ public: Q_INVOKABLE static QString getFamilyNameFromFullName(const QString &fullName); Q_INVOKABLE static QString getInitials(const QString &username); // Support UTF32 Q_INVOKABLE static VariantObject *findLocalAccountByAddress(const QString &address); + Q_INVOKABLE static VariantObject *findParticipantFromDevice(QString conferenceAddress, QString deviceAddress); Q_INVOKABLE static void createCall(const QString &sipAddress, @@ -69,9 +72,9 @@ public: LinphoneEnums::MediaEncryption mediaEncryption = LinphoneEnums::MediaEncryption::None, const QString &prepareTransfertAddress = "", const QHash &headers = {}); - Q_INVOKABLE static void openCallsWindow(CallGui *call); Q_INVOKABLE static void setupConference(ConferenceInfoGui *confGui); Q_INVOKABLE static QQuickWindow *getMainWindow(); + Q_INVOKABLE static void openCallsWindow(CallGui *call); Q_INVOKABLE static void showInformationPopup(const QString &title, const QString &description, bool isSuccess = true, diff --git a/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml b/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml index 0ec02d2e9..2c6deeb51 100644 --- a/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml +++ b/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml @@ -42,11 +42,12 @@ Item { previewEnabled: false call: mainItem.call displayAll: !mainItem.conference - participantDevice: mainItem.conference && mainItem.conference.core.activeSpeaker + participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice + participant: mainItem.conference && mainItem.conference.core.activeSpeaker property var address: participantDevice && participantDevice.core.address videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled) qmlName: 'AS' - securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch + securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false displayPresence: false Binding { target: mainItem @@ -77,6 +78,8 @@ Item { anchors.bottomMargin: 15 * DefaultStyle.dp// Spacing qmlName: 'S_'+index visible: parent.visible + property var participantObj: mainItem.call && $modelData ? UtilsCpp.findParticipantFromDevice(mainItem.call.core.remoteAddress, $modelData.core.address) : null + participant: participantObj ? participantObj.value : null participantDevice: $modelData displayAll: false displayPresence: false diff --git a/Linphone/view/Control/Container/Call/CallGridLayout.qml b/Linphone/view/Control/Container/Call/CallGridLayout.qml index 646ec0f2b..b7745df57 100644 --- a/Linphone/view/Control/Container/Call/CallGridLayout.qml +++ b/Linphone/view/Control/Container/Call/CallGridLayout.qml @@ -3,12 +3,14 @@ import QtQuick.Layouts import QtQml.Models import Linphone +import UtilsCpp // ============================================================================= Mosaic { id: grid property alias call: allDevices.currentCall + property ConferenceGui conference: call && call.core.conference || null property bool videoEnabled: true property int participantCount: gridModel.count @@ -47,6 +49,8 @@ Mosaic { displayAll: false displayPresence: false participantDevice: avatarCell.currentDevice + property var participantObj: (mainItem.call && avatarCell.currentDevice) ? UtilsCpp.findParticipantFromDevice(mainItem.call.core.remoteAddress, avatarCell.currentDevice.core.address) : null + participant: participantObj ? participantObj.value : null Component.onCompleted: console.log(qmlName + " is " +(call ? call.core.remoteAddress : currentDevice ? currentDevice.core.address : 'addr_NotDefined')) } } diff --git a/Linphone/view/Control/Container/FormItemLayout.qml b/Linphone/view/Control/Container/FormItemLayout.qml index c5c5ac6fb..acd212225 100644 --- a/Linphone/view/Control/Container/FormItemLayout.qml +++ b/Linphone/view/Control/Container/FormItemLayout.qml @@ -18,6 +18,21 @@ FocusScope{ function clearErrorText() { errorText.clear() } + + onErrorMessageChanged: if (errorMessage.length > 0) { + var item = mainItem + do { + var parentItem = item.parent + if (parentItem.contentItem) { + if (parentItem.contentY >= mainItem.y) + parentItem.contentY = mainItem.y; + else if (parentItem.contentY+height <= mainItem.y+mainItem.height) + parentItem.contentY = mainItem.y + mainItem.height - height; + } + item = parentItem + } while(item.parent != undefined && parentItem.contentItem === undefined) + } + ColumnLayout { id: layout spacing: 5 * DefaultStyle.dp diff --git a/Linphone/view/Control/Display/Sticker.qml b/Linphone/view/Control/Display/Sticker.qml index 604fb9b75..73f0e98d6 100644 --- a/Linphone/view/Control/Display/Sticker.qml +++ b/Linphone/view/Control/Display/Sticker.qml @@ -22,6 +22,7 @@ Item { property var callState: call && call.core.state || undefined property AccountGui account: null property ParticipantDeviceGui participantDevice: null + property ParticipantGui participant: null property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false property alias displayPresence: avatar.displayPresence property color color: DefaultStyle.grey_600 @@ -45,8 +46,8 @@ Item { property string localName: localNameObj ? localNameObj.value : "" property string displayName: account ? account.core.displayName - : participantDevice - ? participantDevice.core.displayName + : participant + ? participant.core.displayName : call ? previewEnabled ? localName @@ -161,7 +162,6 @@ Item { ColumnLayout { spacing: 0 visible: mainItem.displayAll && !mainItem.remoteIsPaused && !mainItem.conference - anchors.horizontalCenter: parent.horizontalCenter anchors.top: centerItem.bottom anchors.topMargin: 21 * DefaultStyle.dp anchors.left: parent.left diff --git a/Linphone/view/Page/Form/Register/RegisterPage.qml b/Linphone/view/Page/Form/Register/RegisterPage.qml index 573cea0ea..85ab663a9 100644 --- a/Linphone/view/Page/Form/Register/RegisterPage.qml +++ b/Linphone/view/Page/Form/Register/RegisterPage.qml @@ -19,7 +19,7 @@ LoginLayout { function onErrorInField(field, errorMessage) { console.log("set error message", errorMessage) if (field == "username") usernameItem.errorMessage = errorMessage - else if (field == "password") pwdItem.errorMessage = errorMessage + else if (field == "password") passwordItem.errorMessage = errorMessage else if (field == "phone") phoneNumberInput.errorMessage = errorMessage else if (field == "email") emailItem.errorMessage = errorMessage else otherErrorText.setText(errorMessage) diff --git a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml index 01f3c483c..d7dcc12a6 100644 --- a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml @@ -154,28 +154,30 @@ AbstractSettingsLayout { id: videoCodecsComponent ColumnLayout { spacing: 20 * DefaultStyle.dp - Repeater { - Layout.preferredHeight: implicitHeight + ListView { + Layout.preferredHeight: contentHeight + Layout.fillWidth: true model: PayloadTypeProxy { id: videoPayloadTypeProxy filterType: PayloadTypeProxy.Video | PayloadTypeProxy.NotDownloadable } - SwitchSetting { - Layout.fillWidth: true + delegate: SwitchSetting { + width: parent.width titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) subTitleText: modelData.core.encoderDescription propertyName: "enabled" propertyOwnerGui: modelData } } - Repeater { - Layout.preferredHeight: implicitHeight + ListView { + Layout.preferredHeight: contentHeight + Layout.fillWidth: true model: PayloadTypeProxy { id: downloadableVideoPayloadTypeProxy filterType: PayloadTypeProxy.Video | PayloadTypeProxy.Downloadable } - SwitchSetting { - Layout.fillWidth: true + delegate: SwitchSetting { + width: parent.width titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) subTitleText: modelData.core.encoderDescription onCheckedChanged: Utils.openCodecOnlineInstallerDialog(